1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.mapreduce;
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
24 import java.io.ByteArrayOutputStream;
25 import java.io.DataOutputStream;
26 import java.io.IOException;
27 import java.util.ArrayList;
28 import java.util.HashMap;
29 import java.util.List;
30 import java.util.Map;
31
32 import org.apache.hadoop.classification.InterfaceAudience;
33 import org.apache.hadoop.conf.Configuration;
34 import org.apache.hadoop.hbase.KeyValue;
35 import org.apache.hadoop.hbase.KeyValue.Type;
36 import org.apache.hadoop.hbase.Tag;
37 import org.apache.hadoop.hbase.client.HTable;
38 import org.apache.hadoop.hbase.client.Result;
39 import org.apache.hadoop.hbase.client.ResultScanner;
40 import org.apache.hadoop.hbase.client.Scan;
41 import org.apache.hadoop.hbase.mapreduce.ImportTsv.TsvParser.BadTsvLineException;
42 import org.apache.hadoop.hbase.security.visibility.Authorizations;
43 import org.apache.hadoop.hbase.security.visibility.ExpressionExpander;
44 import org.apache.hadoop.hbase.security.visibility.ExpressionParser;
45 import org.apache.hadoop.hbase.security.visibility.ParseException;
46 import org.apache.hadoop.hbase.security.visibility.VisibilityUtils;
47 import org.apache.hadoop.hbase.security.visibility.expression.ExpressionNode;
48 import org.apache.hadoop.hbase.security.visibility.expression.LeafExpressionNode;
49 import org.apache.hadoop.hbase.security.visibility.expression.NonLeafExpressionNode;
50 import org.apache.hadoop.hbase.security.visibility.expression.Operator;
51 import org.apache.hadoop.hbase.util.Bytes;
52 import org.apache.hadoop.io.WritableUtils;
53
54
55
56
57
58
59
60 @InterfaceAudience.Private
61 public class LabelExpander {
62 private Configuration conf;
63 private ExpressionParser parser = new ExpressionParser();
64 private ExpressionExpander expander = new ExpressionExpander();
65
66 public LabelExpander(Configuration conf) {
67 this.conf = conf;
68 }
69
70 private Map<String, Integer> labels;
71
72
73
74 public List<Tag> createVisibilityTags(String visibilityLabelsExp) throws IOException,
75 BadTsvLineException {
76 ExpressionNode node = null;
77 try {
78 node = parser.parse(visibilityLabelsExp);
79 } catch (ParseException e) {
80 throw new BadTsvLineException(e.getMessage());
81 }
82 node = expander.expand(node);
83 List<Tag> tags = new ArrayList<Tag>();
84 ByteArrayOutputStream baos = new ByteArrayOutputStream();
85 DataOutputStream dos = new DataOutputStream(baos);
86 if (node.isSingleNode()) {
87 writeLabelOrdinalsToStream(node, dos);
88 tags.add(new Tag(VisibilityUtils.VISIBILITY_TAG_TYPE, baos.toByteArray()));
89 baos.reset();
90 } else {
91 NonLeafExpressionNode nlNode = (NonLeafExpressionNode) node;
92 if (nlNode.getOperator() == Operator.OR) {
93 for (ExpressionNode child : nlNode.getChildExps()) {
94 writeLabelOrdinalsToStream(child, dos);
95 tags.add(new Tag(VisibilityUtils.VISIBILITY_TAG_TYPE, baos.toByteArray()));
96 baos.reset();
97 }
98 } else {
99 writeLabelOrdinalsToStream(nlNode, dos);
100 tags.add(new Tag(VisibilityUtils.VISIBILITY_TAG_TYPE, baos.toByteArray()));
101 baos.reset();
102 }
103 }
104 return tags;
105 }
106
107 private void writeLabelOrdinalsToStream(ExpressionNode node, DataOutputStream dos)
108 throws IOException, BadTsvLineException {
109 if (node.isSingleNode()) {
110 String identifier = null;
111 int labelOrdinal = 0;
112 if (node instanceof LeafExpressionNode) {
113 identifier = ((LeafExpressionNode) node).getIdentifier();
114 if (this.labels.get(identifier) != null) {
115 labelOrdinal = this.labels.get(identifier);
116 }
117 } else {
118
119 LeafExpressionNode lNode = (LeafExpressionNode) ((NonLeafExpressionNode) node)
120 .getChildExps().get(0);
121 identifier = lNode.getIdentifier();
122 if (this.labels.get(identifier) != null) {
123 labelOrdinal = this.labels.get(identifier);
124 labelOrdinal = -1 * labelOrdinal;
125 }
126 }
127 if (labelOrdinal == 0) {
128 throw new BadTsvLineException("Invalid visibility label " + identifier);
129 }
130 WritableUtils.writeVInt(dos, labelOrdinal);
131 } else {
132 List<ExpressionNode> childExps = ((NonLeafExpressionNode) node).getChildExps();
133 for (ExpressionNode child : childExps) {
134 writeLabelOrdinalsToStream(child, dos);
135 }
136 }
137 }
138
139 private void createLabels() throws IOException {
140
141
142 HTable visibilityLabelsTable = null;
143 ResultScanner scanner = null;
144 try {
145 labels = new HashMap<String, Integer>();
146 visibilityLabelsTable = new HTable(conf, LABELS_TABLE_NAME.getName());
147 Scan scan = new Scan();
148 scan.setAuthorizations(new Authorizations(VisibilityUtils.SYSTEM_LABEL));
149 scan.addColumn(LABELS_TABLE_FAMILY, LABEL_QUALIFIER);
150 scanner = visibilityLabelsTable.getScanner(scan);
151 while (true) {
152 Result next = scanner.next();
153 if (next == null) {
154 break;
155 }
156 byte[] row = next.getRow();
157 byte[] value = next.getValue(LABELS_TABLE_FAMILY, LABEL_QUALIFIER);
158 labels.put(Bytes.toString(value), Bytes.toInt(row));
159 }
160 } finally {
161 try {
162 if (scanner != null) {
163 scanner.close();
164 }
165 } finally {
166 if (visibilityLabelsTable != null) {
167 visibilityLabelsTable.close();
168 }
169 }
170 }
171 }
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194 public KeyValue createKVFromCellVisibilityExpr(int rowKeyOffset, int rowKeyLength, byte[] family,
195 int familyOffset, int familyLength, byte[] qualifier, int qualifierOffset,
196 int qualifierLength, long ts, Type put, byte[] lineBytes, int columnOffset, int columnLength,
197 String cellVisibilityExpr) throws IOException, BadTsvLineException {
198 if(this.labels == null && cellVisibilityExpr != null) {
199 createLabels();
200 }
201 KeyValue kv = null;
202 if (cellVisibilityExpr != null) {
203
204 List<Tag> visibilityTags = createVisibilityTags(cellVisibilityExpr);
205 kv = new KeyValue(lineBytes, rowKeyOffset, rowKeyLength, family, familyOffset, familyLength,
206 qualifier, qualifierOffset, qualifierLength, ts, KeyValue.Type.Put, lineBytes, columnOffset,
207 columnLength, visibilityTags);
208 } else {
209 kv = new KeyValue(lineBytes, rowKeyOffset, rowKeyLength, family, familyOffset, familyLength,
210 qualifier, qualifierOffset, qualifierLength, ts, KeyValue.Type.Put, lineBytes, columnOffset,
211 columnLength);
212 }
213 return kv;
214 }
215 }