1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.client;
19
20 import static org.junit.Assert.assertEquals;
21 import static org.junit.Assert.assertNotNull;
22
23 import java.io.IOException;
24 import java.lang.reflect.Type;
25 import java.nio.ByteBuffer;
26 import java.util.Arrays;
27 import java.util.List;
28 import java.util.Map;
29
30 import org.apache.hadoop.hbase.Cell;
31 import org.apache.hadoop.hbase.CellUtil;
32 import org.apache.hadoop.hbase.HConstants;
33 import org.apache.hadoop.hbase.KeyValue;
34 import org.apache.hadoop.hbase.filter.BinaryComparator;
35 import org.apache.hadoop.hbase.filter.ColumnCountGetFilter;
36 import org.apache.hadoop.hbase.filter.ColumnPaginationFilter;
37 import org.apache.hadoop.hbase.filter.ColumnPrefixFilter;
38 import org.apache.hadoop.hbase.filter.ColumnRangeFilter;
39 import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp;
40 import org.apache.hadoop.hbase.filter.DependentColumnFilter;
41 import org.apache.hadoop.hbase.filter.FamilyFilter;
42 import org.apache.hadoop.hbase.filter.Filter;
43 import org.apache.hadoop.hbase.filter.FilterList;
44 import org.apache.hadoop.hbase.filter.FilterList.Operator;
45 import org.apache.hadoop.hbase.filter.FirstKeyOnlyFilter;
46 import org.apache.hadoop.hbase.filter.InclusiveStopFilter;
47 import org.apache.hadoop.hbase.filter.KeyOnlyFilter;
48 import org.apache.hadoop.hbase.filter.MultipleColumnPrefixFilter;
49 import org.apache.hadoop.hbase.filter.PageFilter;
50 import org.apache.hadoop.hbase.filter.PrefixFilter;
51 import org.apache.hadoop.hbase.filter.QualifierFilter;
52 import org.apache.hadoop.hbase.filter.RowFilter;
53 import org.apache.hadoop.hbase.filter.SingleColumnValueExcludeFilter;
54 import org.apache.hadoop.hbase.filter.SingleColumnValueFilter;
55 import org.apache.hadoop.hbase.filter.SkipFilter;
56 import org.apache.hadoop.hbase.filter.TimestampsFilter;
57 import org.apache.hadoop.hbase.filter.ValueFilter;
58 import org.apache.hadoop.hbase.filter.WhileMatchFilter;
59 import org.apache.hadoop.hbase.testclassification.SmallTests;
60 import org.apache.hadoop.hbase.util.BuilderStyleTest;
61 import org.apache.hadoop.hbase.util.Bytes;
62 import org.apache.hadoop.hbase.util.GsonUtil;
63 import org.apache.hbase.thirdparty.com.google.gson.Gson;
64 import org.apache.hbase.thirdparty.com.google.gson.reflect.TypeToken;
65 import org.junit.Assert;
66 import org.junit.Test;
67 import org.junit.experimental.categories.Category;
68
69
70
71
72
73 @Category(SmallTests.class)
74 public class TestOperation {
75 private static byte [] ROW = Bytes.toBytes("testRow");
76 private static byte [] FAMILY = Bytes.toBytes("testFamily");
77 private static byte [] QUALIFIER = Bytes.toBytes("testQualifier");
78 private static byte [] VALUE = Bytes.toBytes("testValue");
79
80 private static Gson GSON = GsonUtil.createGson().create();
81
82 private static List<Long> TS_LIST = Arrays.asList(2L, 3L, 5L);
83 private static TimestampsFilter TS_FILTER = new TimestampsFilter(TS_LIST);
84 private static String STR_TS_FILTER = TS_FILTER.getClass().getSimpleName() + " (3/3): [2, 3, 5]";
85
86 private static List<Long> L_TS_LIST = Arrays.asList(0L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L);
87 private static TimestampsFilter L_TS_FILTER = new TimestampsFilter(L_TS_LIST);
88 private static String STR_L_TS_FILTER =
89 L_TS_FILTER.getClass().getSimpleName() + " (5/11): [0, 1, 2, 3, 4]";
90
91 private static String COL_NAME_1 = "col1";
92 private static ColumnPrefixFilter COL_PRE_FILTER =
93 new ColumnPrefixFilter(Bytes.toBytes(COL_NAME_1));
94 private static String STR_COL_PRE_FILTER =
95 COL_PRE_FILTER.getClass().getSimpleName() + " " + COL_NAME_1;
96
97 private static String COL_NAME_2 = "col2";
98 private static ColumnRangeFilter CR_FILTER =
99 new ColumnRangeFilter(Bytes.toBytes(COL_NAME_1), true, Bytes.toBytes(COL_NAME_2), false);
100 private static String STR_CR_FILTER = CR_FILTER.getClass().getSimpleName()
101 + " [" + COL_NAME_1 + ", " + COL_NAME_2 + ")";
102
103 private static int COL_COUNT = 9;
104 private static ColumnCountGetFilter CCG_FILTER = new ColumnCountGetFilter(COL_COUNT);
105 private static String STR_CCG_FILTER = CCG_FILTER.getClass().getSimpleName() + " " + COL_COUNT;
106
107 private static int LIMIT = 3;
108 private static int OFFSET = 4;
109 private static ColumnPaginationFilter CP_FILTER = new ColumnPaginationFilter(LIMIT, OFFSET);
110 private static String STR_CP_FILTER = CP_FILTER.getClass().getSimpleName()
111 + " (" + LIMIT + ", " + OFFSET + ")";
112
113 private static String STOP_ROW_KEY = "stop";
114 private static InclusiveStopFilter IS_FILTER =
115 new InclusiveStopFilter(Bytes.toBytes(STOP_ROW_KEY));
116 private static String STR_IS_FILTER =
117 IS_FILTER.getClass().getSimpleName() + " " + STOP_ROW_KEY;
118
119 private static String PREFIX = "prefix";
120 private static PrefixFilter PREFIX_FILTER = new PrefixFilter(Bytes.toBytes(PREFIX));
121 private static String STR_PREFIX_FILTER = "PrefixFilter " + PREFIX;
122
123 private static byte[][] PREFIXES = { Bytes.toBytes("0"), Bytes.toBytes("1"), Bytes.toBytes("2") };
124 private static MultipleColumnPrefixFilter MCP_FILTER = new MultipleColumnPrefixFilter(PREFIXES);
125 private static String STR_MCP_FILTER =
126 MCP_FILTER.getClass().getSimpleName() + " (3/3): [0, 1, 2]";
127
128 private static byte[][] L_PREFIXES = {
129 Bytes.toBytes("0"), Bytes.toBytes("1"), Bytes.toBytes("2"), Bytes.toBytes("3"),
130 Bytes.toBytes("4"), Bytes.toBytes("5"), Bytes.toBytes("6"), Bytes.toBytes("7") };
131 private static MultipleColumnPrefixFilter L_MCP_FILTER =
132 new MultipleColumnPrefixFilter(L_PREFIXES);
133 private static String STR_L_MCP_FILTER =
134 L_MCP_FILTER.getClass().getSimpleName() + " (5/8): [0, 1, 2, 3, 4]";
135
136 private static int PAGE_SIZE = 9;
137 private static PageFilter PAGE_FILTER = new PageFilter(PAGE_SIZE);
138 private static String STR_PAGE_FILTER = PAGE_FILTER.getClass().getSimpleName() + " " + PAGE_SIZE;
139
140 private static SkipFilter SKIP_FILTER = new SkipFilter(L_TS_FILTER);
141 private static String STR_SKIP_FILTER =
142 SKIP_FILTER.getClass().getSimpleName() + " " + STR_L_TS_FILTER;
143
144 private static WhileMatchFilter WHILE_FILTER = new WhileMatchFilter(L_TS_FILTER);
145 private static String STR_WHILE_FILTER =
146 WHILE_FILTER.getClass().getSimpleName() + " " + STR_L_TS_FILTER;
147
148 private static KeyOnlyFilter KEY_ONLY_FILTER = new KeyOnlyFilter();
149 private static String STR_KEY_ONLY_FILTER = KEY_ONLY_FILTER.getClass().getSimpleName();
150
151 private static FirstKeyOnlyFilter FIRST_KEY_ONLY_FILTER = new FirstKeyOnlyFilter();
152 private static String STR_FIRST_KEY_ONLY_FILTER =
153 FIRST_KEY_ONLY_FILTER.getClass().getSimpleName();
154
155 private static CompareOp CMP_OP = CompareOp.EQUAL;
156 private static byte[] CMP_VALUE = Bytes.toBytes("value");
157 private static BinaryComparator BC = new BinaryComparator(CMP_VALUE);
158 private static DependentColumnFilter DC_FILTER =
159 new DependentColumnFilter(FAMILY, QUALIFIER, true, CMP_OP, BC);
160 private static String STR_DC_FILTER = String.format(
161 "%s (%s, %s, %s, %s, %s)", DC_FILTER.getClass().getSimpleName(),
162 Bytes.toStringBinary(FAMILY), Bytes.toStringBinary(QUALIFIER), true,
163 CMP_OP.name(), Bytes.toStringBinary(BC.getValue()));
164
165 private static FamilyFilter FAMILY_FILTER = new FamilyFilter(CMP_OP, BC);
166 private static String STR_FAMILY_FILTER =
167 FAMILY_FILTER.getClass().getSimpleName() + " (EQUAL, value)";
168
169 private static QualifierFilter QUALIFIER_FILTER = new QualifierFilter(CMP_OP, BC);
170 private static String STR_QUALIFIER_FILTER =
171 QUALIFIER_FILTER.getClass().getSimpleName() + " (EQUAL, value)";
172
173 private static RowFilter ROW_FILTER = new RowFilter(CMP_OP, BC);
174 private static String STR_ROW_FILTER = ROW_FILTER.getClass().getSimpleName() + " (EQUAL, value)";
175
176 private static ValueFilter VALUE_FILTER = new ValueFilter(CMP_OP, BC);
177 private static String STR_VALUE_FILTER =
178 VALUE_FILTER.getClass().getSimpleName() + " (EQUAL, value)";
179
180 private static SingleColumnValueFilter SCV_FILTER =
181 new SingleColumnValueFilter(FAMILY, QUALIFIER, CMP_OP, CMP_VALUE);
182 private static String STR_SCV_FILTER = String.format("%s (%s, %s, %s, %s)",
183 SCV_FILTER.getClass().getSimpleName(), Bytes.toStringBinary(FAMILY),
184 Bytes.toStringBinary(QUALIFIER), CMP_OP.name(),
185 Bytes.toStringBinary(CMP_VALUE));
186
187 private static SingleColumnValueExcludeFilter SCVE_FILTER =
188 new SingleColumnValueExcludeFilter(FAMILY, QUALIFIER, CMP_OP, CMP_VALUE);
189 private static String STR_SCVE_FILTER = String.format("%s (%s, %s, %s, %s)",
190 SCVE_FILTER.getClass().getSimpleName(), Bytes.toStringBinary(FAMILY),
191 Bytes.toStringBinary(QUALIFIER), CMP_OP.name(), Bytes.toStringBinary(CMP_VALUE));
192
193 private static FilterList AND_FILTER_LIST = new FilterList(
194 Operator.MUST_PASS_ALL, Arrays.asList((Filter) TS_FILTER, L_TS_FILTER, CR_FILTER));
195 private static String STR_AND_FILTER_LIST = String.format(
196 "%s AND (3/3): [%s, %s, %s]", AND_FILTER_LIST.getClass().getSimpleName(),
197 STR_TS_FILTER, STR_L_TS_FILTER, STR_CR_FILTER);
198
199 private static FilterList OR_FILTER_LIST = new FilterList(
200 Operator.MUST_PASS_ONE, Arrays.asList((Filter) TS_FILTER, L_TS_FILTER, CR_FILTER));
201 private static String STR_OR_FILTER_LIST = String.format(
202 "%s OR (3/3): [%s, %s, %s]", AND_FILTER_LIST.getClass().getSimpleName(),
203 STR_TS_FILTER, STR_L_TS_FILTER, STR_CR_FILTER);
204
205 private static FilterList L_FILTER_LIST = new FilterList(
206 Arrays.asList((Filter) TS_FILTER, L_TS_FILTER, CR_FILTER, COL_PRE_FILTER,
207 CCG_FILTER, CP_FILTER, PREFIX_FILTER, PAGE_FILTER));
208 private static String STR_L_FILTER_LIST = String.format(
209 "%s AND (5/8): [%s, %s, %s, %s, %s, %s]",
210 L_FILTER_LIST.getClass().getSimpleName(), STR_TS_FILTER, STR_L_TS_FILTER,
211 STR_CR_FILTER, STR_COL_PRE_FILTER, STR_CCG_FILTER, STR_CP_FILTER);
212
213 private static Filter[] FILTERS = {
214 TS_FILTER,
215 L_TS_FILTER,
216 COL_PRE_FILTER,
217 CP_FILTER,
218 CR_FILTER,
219 CCG_FILTER,
220 IS_FILTER,
221 PREFIX_FILTER,
222 PAGE_FILTER,
223 SKIP_FILTER,
224 WHILE_FILTER,
225 KEY_ONLY_FILTER,
226 FIRST_KEY_ONLY_FILTER,
227 MCP_FILTER,
228 L_MCP_FILTER,
229 DC_FILTER,
230 FAMILY_FILTER,
231 QUALIFIER_FILTER,
232 ROW_FILTER,
233 VALUE_FILTER,
234 SCV_FILTER,
235 SCVE_FILTER,
236 AND_FILTER_LIST,
237 OR_FILTER_LIST,
238 L_FILTER_LIST,
239 };
240
241 private static String[] FILTERS_INFO = {
242 STR_TS_FILTER,
243 STR_L_TS_FILTER,
244 STR_COL_PRE_FILTER,
245 STR_CP_FILTER,
246 STR_CR_FILTER,
247 STR_CCG_FILTER,
248 STR_IS_FILTER,
249 STR_PREFIX_FILTER,
250 STR_PAGE_FILTER,
251 STR_SKIP_FILTER,
252 STR_WHILE_FILTER,
253 STR_KEY_ONLY_FILTER,
254 STR_FIRST_KEY_ONLY_FILTER,
255 STR_MCP_FILTER,
256 STR_L_MCP_FILTER,
257 STR_DC_FILTER,
258 STR_FAMILY_FILTER,
259 STR_QUALIFIER_FILTER,
260 STR_ROW_FILTER,
261 STR_VALUE_FILTER,
262 STR_SCV_FILTER,
263 STR_SCVE_FILTER,
264 STR_AND_FILTER_LIST,
265 STR_OR_FILTER_LIST,
266 STR_L_FILTER_LIST,
267 };
268
269 static {
270 assertEquals("The sizes of static arrays do not match: "
271 + "[FILTERS: %d <=> FILTERS_INFO: %d]",
272 FILTERS.length, FILTERS_INFO.length);
273 }
274
275
276
277
278
279
280
281 @Test
282 public void testOperationJSON() throws IOException {
283
284 Scan scan = new Scan(ROW);
285 scan.addColumn(FAMILY, QUALIFIER);
286
287 String json = scan.toJSON();
288 Type typeOfHashMap = new TypeToken<Map<String, Object>>() {
289 }.getType();
290 Map<String, Object> parsedJSON = GSON.fromJson(json, typeOfHashMap);
291
292 assertEquals("startRow incorrect in Scan.toJSON()",
293 Bytes.toStringBinary(ROW), parsedJSON.get("startRow"));
294
295 List familyInfo = (List) ((Map) parsedJSON.get("families")).get(
296 Bytes.toStringBinary(FAMILY));
297 assertNotNull("Family absent in Scan.toJSON()", familyInfo);
298 assertEquals("Qualifier absent in Scan.toJSON()", 1, familyInfo.size());
299 assertEquals("Qualifier incorrect in Scan.toJSON()",
300 Bytes.toStringBinary(QUALIFIER),
301 familyInfo.get(0));
302
303
304 Get get = new Get(ROW);
305 get.addColumn(FAMILY, QUALIFIER);
306
307 json = get.toJSON();
308 parsedJSON = GSON.fromJson(json, typeOfHashMap);
309
310 assertEquals("row incorrect in Get.toJSON()",
311 Bytes.toStringBinary(ROW), parsedJSON.get("row"));
312
313 familyInfo = (List) ((Map) parsedJSON.get("families")).get(
314 Bytes.toStringBinary(FAMILY));
315 assertNotNull("Family absent in Get.toJSON()", familyInfo);
316 assertEquals("Qualifier absent in Get.toJSON()", 1, familyInfo.size());
317 assertEquals("Qualifier incorrect in Get.toJSON()",
318 Bytes.toStringBinary(QUALIFIER),
319 familyInfo.get(0));
320
321
322 Put put = new Put(ROW);
323 put.add(FAMILY, QUALIFIER, VALUE);
324
325 json = put.toJSON();
326 parsedJSON = GSON.fromJson(json, typeOfHashMap);
327
328 assertEquals("row absent in Put.toJSON()",
329 Bytes.toStringBinary(ROW), parsedJSON.get("row"));
330
331 familyInfo = (List) ((Map) parsedJSON.get("families")).get(
332 Bytes.toStringBinary(FAMILY));
333 assertNotNull("Family absent in Put.toJSON()", familyInfo);
334 assertEquals("KeyValue absent in Put.toJSON()", 1, familyInfo.size());
335 Map kvMap = (Map) familyInfo.get(0);
336 assertEquals("Qualifier incorrect in Put.toJSON()",
337 Bytes.toStringBinary(QUALIFIER),
338 kvMap.get("qualifier"));
339 assertEquals("Value length incorrect in Put.toJSON()",
340 VALUE.length, ((Number) kvMap.get("vlen")).intValue());
341
342
343 Delete delete = new Delete(ROW);
344 delete.deleteColumn(FAMILY, QUALIFIER);
345
346 json = delete.toJSON();
347 parsedJSON = GSON.fromJson(json, typeOfHashMap);
348
349 assertEquals("row absent in Delete.toJSON()",
350 Bytes.toStringBinary(ROW), parsedJSON.get("row"));
351
352 familyInfo = (List) ((Map) parsedJSON.get("families")).get(
353 Bytes.toStringBinary(FAMILY));
354 assertNotNull("Family absent in Delete.toJSON()", familyInfo);
355 assertEquals("KeyValue absent in Delete.toJSON()", 1, familyInfo.size());
356 kvMap = (Map) familyInfo.get(0);
357 assertEquals("Qualifier incorrect in Delete.toJSON()",
358 Bytes.toStringBinary(QUALIFIER), kvMap.get("qualifier"));
359 }
360
361 @Test
362 public void testPutCreationWithByteBuffer() {
363 Put p = new Put(ROW);
364 List<Cell> c = p.get(FAMILY, QUALIFIER);
365 Assert.assertEquals(0, c.size());
366 Assert.assertEquals(HConstants.LATEST_TIMESTAMP, p.getTimeStamp());
367
368 p.add(FAMILY, ByteBuffer.wrap(QUALIFIER), 1984L, ByteBuffer.wrap(VALUE));
369 c = p.get(FAMILY, QUALIFIER);
370 Assert.assertEquals(1, c.size());
371 Assert.assertEquals(1984L, c.get(0).getTimestamp());
372 Assert.assertArrayEquals(VALUE, CellUtil.cloneValue(c.get(0)));
373 Assert.assertEquals(HConstants.LATEST_TIMESTAMP, p.getTimeStamp());
374 Assert.assertEquals(0, KeyValue.COMPARATOR.compare(c.get(0), new KeyValue(c.get(0))));
375
376 p = new Put(ROW);
377 p.add(FAMILY, ByteBuffer.wrap(QUALIFIER), 2013L, null);
378 c = p.get(FAMILY, QUALIFIER);
379 Assert.assertEquals(1, c.size());
380 Assert.assertEquals(2013L, c.get(0).getTimestamp());
381 Assert.assertArrayEquals(new byte[]{}, CellUtil.cloneValue(c.get(0)));
382 Assert.assertEquals(HConstants.LATEST_TIMESTAMP, p.getTimeStamp());
383 Assert.assertEquals(0, KeyValue.COMPARATOR.compare(c.get(0), new KeyValue(c.get(0))));
384
385 p = new Put(ByteBuffer.wrap(ROW));
386 p.add(FAMILY, ByteBuffer.wrap(QUALIFIER), 2001L, null);
387 c = p.get(FAMILY, QUALIFIER);
388 Assert.assertEquals(1, c.size());
389 Assert.assertEquals(2001L, c.get(0).getTimestamp());
390 Assert.assertArrayEquals(new byte[]{}, CellUtil.cloneValue(c.get(0)));
391 Assert.assertArrayEquals(ROW, CellUtil.cloneRow(c.get(0)));
392 Assert.assertEquals(HConstants.LATEST_TIMESTAMP, p.getTimeStamp());
393 Assert.assertEquals(0, KeyValue.COMPARATOR.compare(c.get(0), new KeyValue(c.get(0))));
394
395 p = new Put(ByteBuffer.wrap(ROW), 1970L);
396 p.add(FAMILY, ByteBuffer.wrap(QUALIFIER), 2001L, null);
397 c = p.get(FAMILY, QUALIFIER);
398 Assert.assertEquals(1, c.size());
399 Assert.assertEquals(2001L, c.get(0).getTimestamp());
400 Assert.assertArrayEquals(new byte[]{}, CellUtil.cloneValue(c.get(0)));
401 Assert.assertArrayEquals(ROW, CellUtil.cloneRow(c.get(0)));
402 Assert.assertEquals(1970L, p.getTimeStamp());
403 Assert.assertEquals(0, KeyValue.COMPARATOR.compare(c.get(0), new KeyValue(c.get(0))));
404 }
405
406 @Test
407 @SuppressWarnings("rawtypes")
408 public void testOperationSubClassMethodsAreBuilderStyle() {
409
410
411
412
413
414
415
416
417
418
419
420
421 Class[] classes = new Class[] {
422 Operation.class,
423 OperationWithAttributes.class,
424 Mutation.class,
425 Query.class,
426 Delete.class,
427 Increment.class,
428 Append.class,
429 Put.class,
430 Get.class,
431 Scan.class};
432
433 BuilderStyleTest.assertClassesAreBuilderStyle(classes);
434 }
435 }