001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.client; 019 020import static org.junit.Assert.assertEquals; 021import static org.junit.Assert.assertNotNull; 022 023import java.io.IOException; 024import java.lang.reflect.Type; 025import java.nio.ByteBuffer; 026import java.util.Arrays; 027import java.util.List; 028import java.util.Map; 029import org.apache.hadoop.hbase.Cell; 030import org.apache.hadoop.hbase.CellComparatorImpl; 031import org.apache.hadoop.hbase.CellUtil; 032import org.apache.hadoop.hbase.HBaseClassTestRule; 033import org.apache.hadoop.hbase.HConstants; 034import org.apache.hadoop.hbase.KeyValue; 035import org.apache.hadoop.hbase.filter.BinaryComparator; 036import org.apache.hadoop.hbase.filter.ColumnCountGetFilter; 037import org.apache.hadoop.hbase.filter.ColumnPaginationFilter; 038import org.apache.hadoop.hbase.filter.ColumnPrefixFilter; 039import org.apache.hadoop.hbase.filter.ColumnRangeFilter; 040import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp; 041import org.apache.hadoop.hbase.filter.DependentColumnFilter; 042import org.apache.hadoop.hbase.filter.FamilyFilter; 043import org.apache.hadoop.hbase.filter.Filter; 044import org.apache.hadoop.hbase.filter.FilterList; 045import org.apache.hadoop.hbase.filter.FilterList.Operator; 046import org.apache.hadoop.hbase.filter.FirstKeyOnlyFilter; 047import org.apache.hadoop.hbase.filter.InclusiveStopFilter; 048import org.apache.hadoop.hbase.filter.KeyOnlyFilter; 049import org.apache.hadoop.hbase.filter.MultipleColumnPrefixFilter; 050import org.apache.hadoop.hbase.filter.PageFilter; 051import org.apache.hadoop.hbase.filter.PrefixFilter; 052import org.apache.hadoop.hbase.filter.QualifierFilter; 053import org.apache.hadoop.hbase.filter.RowFilter; 054import org.apache.hadoop.hbase.filter.SingleColumnValueExcludeFilter; 055import org.apache.hadoop.hbase.filter.SingleColumnValueFilter; 056import org.apache.hadoop.hbase.filter.SkipFilter; 057import org.apache.hadoop.hbase.filter.TimestampsFilter; 058import org.apache.hadoop.hbase.filter.ValueFilter; 059import org.apache.hadoop.hbase.filter.WhileMatchFilter; 060import org.apache.hadoop.hbase.testclassification.ClientTests; 061import org.apache.hadoop.hbase.testclassification.SmallTests; 062import org.apache.hadoop.hbase.util.BuilderStyleTest; 063import org.apache.hadoop.hbase.util.Bytes; 064import org.apache.hadoop.hbase.util.GsonUtil; 065import org.junit.Assert; 066import org.junit.ClassRule; 067import org.junit.Test; 068import org.junit.experimental.categories.Category; 069 070import org.apache.hbase.thirdparty.com.google.common.reflect.TypeToken; 071import org.apache.hbase.thirdparty.com.google.gson.Gson; 072import org.apache.hbase.thirdparty.com.google.gson.GsonBuilder; 073import org.apache.hbase.thirdparty.com.google.gson.LongSerializationPolicy; 074import org.apache.hbase.thirdparty.com.google.gson.ToNumberPolicy; 075 076/** 077 * Run tests that use the functionality of the Operation superclass for Puts, Gets, Deletes, Scans, 078 * and MultiPuts. 079 */ 080@Category({ ClientTests.class, SmallTests.class }) 081public class TestOperation { 082 @ClassRule 083 public static final HBaseClassTestRule CLASS_RULE = 084 HBaseClassTestRule.forClass(TestOperation.class); 085 086 private static byte[] ROW = Bytes.toBytes("testRow"); 087 private static byte[] FAMILY = Bytes.toBytes("testFamily"); 088 private static byte[] QUALIFIER = Bytes.toBytes("testQualifier"); 089 private static byte[] VALUE = Bytes.toBytes("testValue"); 090 091 private static Gson GSON = GsonUtil.createGson().create(); 092 093 private static List<Long> TS_LIST = Arrays.asList(2L, 3L, 5L); 094 private static TimestampsFilter TS_FILTER = new TimestampsFilter(TS_LIST); 095 private static String STR_TS_FILTER = TS_FILTER.getClass().getSimpleName() + " (3/3): [2, 3, 5]"; 096 097 private static List<Long> L_TS_LIST = Arrays.asList(0L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L); 098 private static TimestampsFilter L_TS_FILTER = new TimestampsFilter(L_TS_LIST); 099 private static String STR_L_TS_FILTER = 100 L_TS_FILTER.getClass().getSimpleName() + " (5/11): [0, 1, 2, 3, 4]"; 101 102 private static String COL_NAME_1 = "col1"; 103 private static ColumnPrefixFilter COL_PRE_FILTER = 104 new ColumnPrefixFilter(Bytes.toBytes(COL_NAME_1)); 105 private static String STR_COL_PRE_FILTER = 106 COL_PRE_FILTER.getClass().getSimpleName() + " " + COL_NAME_1; 107 108 private static String COL_NAME_2 = "col2"; 109 private static ColumnRangeFilter CR_FILTER = 110 new ColumnRangeFilter(Bytes.toBytes(COL_NAME_1), true, Bytes.toBytes(COL_NAME_2), false); 111 private static String STR_CR_FILTER = 112 CR_FILTER.getClass().getSimpleName() + " [" + COL_NAME_1 + ", " + COL_NAME_2 + ")"; 113 114 private static int COL_COUNT = 9; 115 private static ColumnCountGetFilter CCG_FILTER = new ColumnCountGetFilter(COL_COUNT); 116 private static String STR_CCG_FILTER = CCG_FILTER.getClass().getSimpleName() + " " + COL_COUNT; 117 118 private static int LIMIT = 3; 119 private static int OFFSET = 4; 120 private static ColumnPaginationFilter CP_FILTER = new ColumnPaginationFilter(LIMIT, OFFSET); 121 private static String STR_CP_FILTER = 122 CP_FILTER.getClass().getSimpleName() + " (" + LIMIT + ", " + OFFSET + ")"; 123 124 private static String STOP_ROW_KEY = "stop"; 125 private static InclusiveStopFilter IS_FILTER = 126 new InclusiveStopFilter(Bytes.toBytes(STOP_ROW_KEY)); 127 private static String STR_IS_FILTER = IS_FILTER.getClass().getSimpleName() + " " + STOP_ROW_KEY; 128 129 private static String PREFIX = "prefix"; 130 private static PrefixFilter PREFIX_FILTER = new PrefixFilter(Bytes.toBytes(PREFIX)); 131 private static String STR_PREFIX_FILTER = "PrefixFilter " + PREFIX; 132 133 private static byte[][] PREFIXES = { Bytes.toBytes("0"), Bytes.toBytes("1"), Bytes.toBytes("2") }; 134 private static MultipleColumnPrefixFilter MCP_FILTER = new MultipleColumnPrefixFilter(PREFIXES); 135 private static String STR_MCP_FILTER = 136 MCP_FILTER.getClass().getSimpleName() + " (3/3): [0, 1, 2]"; 137 138 private static byte[][] L_PREFIXES = 139 { Bytes.toBytes("0"), Bytes.toBytes("1"), Bytes.toBytes("2"), Bytes.toBytes("3"), 140 Bytes.toBytes("4"), Bytes.toBytes("5"), Bytes.toBytes("6"), Bytes.toBytes("7") }; 141 private static MultipleColumnPrefixFilter L_MCP_FILTER = 142 new MultipleColumnPrefixFilter(L_PREFIXES); 143 private static String STR_L_MCP_FILTER = 144 L_MCP_FILTER.getClass().getSimpleName() + " (5/8): [0, 1, 2, 3, 4]"; 145 146 private static int PAGE_SIZE = 9; 147 private static PageFilter PAGE_FILTER = new PageFilter(PAGE_SIZE); 148 private static String STR_PAGE_FILTER = PAGE_FILTER.getClass().getSimpleName() + " " + PAGE_SIZE; 149 150 private static SkipFilter SKIP_FILTER = new SkipFilter(L_TS_FILTER); 151 private static String STR_SKIP_FILTER = 152 SKIP_FILTER.getClass().getSimpleName() + " " + STR_L_TS_FILTER; 153 154 private static WhileMatchFilter WHILE_FILTER = new WhileMatchFilter(L_TS_FILTER); 155 private static String STR_WHILE_FILTER = 156 WHILE_FILTER.getClass().getSimpleName() + " " + STR_L_TS_FILTER; 157 158 private static KeyOnlyFilter KEY_ONLY_FILTER = new KeyOnlyFilter(); 159 private static String STR_KEY_ONLY_FILTER = KEY_ONLY_FILTER.getClass().getSimpleName(); 160 161 private static FirstKeyOnlyFilter FIRST_KEY_ONLY_FILTER = new FirstKeyOnlyFilter(); 162 private static String STR_FIRST_KEY_ONLY_FILTER = 163 FIRST_KEY_ONLY_FILTER.getClass().getSimpleName(); 164 165 private static CompareOp CMP_OP = CompareOp.EQUAL; 166 private static byte[] CMP_VALUE = Bytes.toBytes("value"); 167 private static BinaryComparator BC = new BinaryComparator(CMP_VALUE); 168 private static DependentColumnFilter DC_FILTER = 169 new DependentColumnFilter(FAMILY, QUALIFIER, true, CMP_OP, BC); 170 private static String STR_DC_FILTER = String.format("%s (%s, %s, %s, %s, %s)", 171 DC_FILTER.getClass().getSimpleName(), Bytes.toStringBinary(FAMILY), 172 Bytes.toStringBinary(QUALIFIER), true, CMP_OP.name(), Bytes.toStringBinary(BC.getValue())); 173 174 private static FamilyFilter FAMILY_FILTER = new FamilyFilter(CMP_OP, BC); 175 private static String STR_FAMILY_FILTER = 176 FAMILY_FILTER.getClass().getSimpleName() + " (EQUAL, value)"; 177 178 private static QualifierFilter QUALIFIER_FILTER = new QualifierFilter(CMP_OP, BC); 179 private static String STR_QUALIFIER_FILTER = 180 QUALIFIER_FILTER.getClass().getSimpleName() + " (EQUAL, value)"; 181 182 private static RowFilter ROW_FILTER = new RowFilter(CMP_OP, BC); 183 private static String STR_ROW_FILTER = ROW_FILTER.getClass().getSimpleName() + " (EQUAL, value)"; 184 185 private static ValueFilter VALUE_FILTER = new ValueFilter(CMP_OP, BC); 186 private static String STR_VALUE_FILTER = 187 VALUE_FILTER.getClass().getSimpleName() + " (EQUAL, value)"; 188 189 private static SingleColumnValueFilter SCV_FILTER = 190 new SingleColumnValueFilter(FAMILY, QUALIFIER, CMP_OP, CMP_VALUE); 191 private static String STR_SCV_FILTER = String.format("%s (%s, %s, %s, %s)", 192 SCV_FILTER.getClass().getSimpleName(), Bytes.toStringBinary(FAMILY), 193 Bytes.toStringBinary(QUALIFIER), CMP_OP.name(), Bytes.toStringBinary(CMP_VALUE)); 194 195 private static SingleColumnValueExcludeFilter SCVE_FILTER = 196 new SingleColumnValueExcludeFilter(FAMILY, QUALIFIER, CMP_OP, CMP_VALUE); 197 private static String STR_SCVE_FILTER = String.format("%s (%s, %s, %s, %s)", 198 SCVE_FILTER.getClass().getSimpleName(), Bytes.toStringBinary(FAMILY), 199 Bytes.toStringBinary(QUALIFIER), CMP_OP.name(), Bytes.toStringBinary(CMP_VALUE)); 200 201 private static FilterList AND_FILTER_LIST = new FilterList(Operator.MUST_PASS_ALL, 202 Arrays.asList((Filter) TS_FILTER, L_TS_FILTER, CR_FILTER)); 203 private static String STR_AND_FILTER_LIST = String.format("%s AND (3/3): [%s, %s, %s]", 204 AND_FILTER_LIST.getClass().getSimpleName(), STR_TS_FILTER, STR_L_TS_FILTER, STR_CR_FILTER); 205 206 private static FilterList OR_FILTER_LIST = new FilterList(Operator.MUST_PASS_ONE, 207 Arrays.asList((Filter) TS_FILTER, L_TS_FILTER, CR_FILTER)); 208 private static String STR_OR_FILTER_LIST = String.format("%s OR (3/3): [%s, %s, %s]", 209 AND_FILTER_LIST.getClass().getSimpleName(), STR_TS_FILTER, STR_L_TS_FILTER, STR_CR_FILTER); 210 211 private static FilterList L_FILTER_LIST = new FilterList(Arrays.asList((Filter) TS_FILTER, 212 L_TS_FILTER, CR_FILTER, COL_PRE_FILTER, CCG_FILTER, CP_FILTER, PREFIX_FILTER, PAGE_FILTER)); 213 private static String STR_L_FILTER_LIST = String.format("%s AND (5/8): [%s, %s, %s, %s, %s, %s]", 214 L_FILTER_LIST.getClass().getSimpleName(), STR_TS_FILTER, STR_L_TS_FILTER, STR_CR_FILTER, 215 STR_COL_PRE_FILTER, STR_CCG_FILTER, STR_CP_FILTER); 216 217 private static Filter[] FILTERS = { TS_FILTER, // TimestampsFilter 218 L_TS_FILTER, // TimestampsFilter 219 COL_PRE_FILTER, // ColumnPrefixFilter 220 CP_FILTER, // ColumnPaginationFilter 221 CR_FILTER, // ColumnRangeFilter 222 CCG_FILTER, // ColumnCountGetFilter 223 IS_FILTER, // InclusiveStopFilter 224 PREFIX_FILTER, // PrefixFilter 225 PAGE_FILTER, // PageFilter 226 SKIP_FILTER, // SkipFilter 227 WHILE_FILTER, // WhileMatchFilter 228 KEY_ONLY_FILTER, // KeyOnlyFilter 229 FIRST_KEY_ONLY_FILTER, // FirstKeyOnlyFilter 230 MCP_FILTER, // MultipleColumnPrefixFilter 231 L_MCP_FILTER, // MultipleColumnPrefixFilter 232 DC_FILTER, // DependentColumnFilter 233 FAMILY_FILTER, // FamilyFilter 234 QUALIFIER_FILTER, // QualifierFilter 235 ROW_FILTER, // RowFilter 236 VALUE_FILTER, // ValueFilter 237 SCV_FILTER, // SingleColumnValueFilter 238 SCVE_FILTER, // SingleColumnValueExcludeFilter 239 AND_FILTER_LIST, // FilterList 240 OR_FILTER_LIST, // FilterList 241 L_FILTER_LIST, // FilterList 242 }; 243 244 private static String[] FILTERS_INFO = { STR_TS_FILTER, // TimestampsFilter 245 STR_L_TS_FILTER, // TimestampsFilter 246 STR_COL_PRE_FILTER, // ColumnPrefixFilter 247 STR_CP_FILTER, // ColumnPaginationFilter 248 STR_CR_FILTER, // ColumnRangeFilter 249 STR_CCG_FILTER, // ColumnCountGetFilter 250 STR_IS_FILTER, // InclusiveStopFilter 251 STR_PREFIX_FILTER, // PrefixFilter 252 STR_PAGE_FILTER, // PageFilter 253 STR_SKIP_FILTER, // SkipFilter 254 STR_WHILE_FILTER, // WhileMatchFilter 255 STR_KEY_ONLY_FILTER, // KeyOnlyFilter 256 STR_FIRST_KEY_ONLY_FILTER, // FirstKeyOnlyFilter 257 STR_MCP_FILTER, // MultipleColumnPrefixFilter 258 STR_L_MCP_FILTER, // MultipleColumnPrefixFilter 259 STR_DC_FILTER, // DependentColumnFilter 260 STR_FAMILY_FILTER, // FamilyFilter 261 STR_QUALIFIER_FILTER, // QualifierFilter 262 STR_ROW_FILTER, // RowFilter 263 STR_VALUE_FILTER, // ValueFilter 264 STR_SCV_FILTER, // SingleColumnValueFilter 265 STR_SCVE_FILTER, // SingleColumnValueExcludeFilter 266 STR_AND_FILTER_LIST, // FilterList 267 STR_OR_FILTER_LIST, // FilterList 268 STR_L_FILTER_LIST, // FilterList 269 }; 270 271 static { 272 assertEquals("The sizes of static arrays do not match: " + "[FILTERS: %d <=> FILTERS_INFO: %d]", 273 FILTERS.length, FILTERS_INFO.length); 274 } 275 276 /** 277 * Test the client Operations' JSON encoding to ensure that produced JSON is parseable and that 278 * the details are present and not corrupted. 279 * @throws IOException if the JSON conversion fails 280 */ 281 @Test 282 public void testOperationJSON() throws IOException { 283 // produce a Scan Operation 284 Scan scan = new Scan(ROW); 285 scan.addColumn(FAMILY, QUALIFIER); 286 // get its JSON representation, and parse it 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 // check for the row 292 assertEquals("startRow incorrect in Scan.toJSON()", Bytes.toStringBinary(ROW), 293 parsedJSON.get("startRow")); 294 // check for the family and the qualifier. 295 List familyInfo = (List) ((Map) parsedJSON.get("families")).get(Bytes.toStringBinary(FAMILY)); 296 assertNotNull("Family absent in Scan.toJSON()", familyInfo); 297 assertEquals("Qualifier absent in Scan.toJSON()", 1, familyInfo.size()); 298 assertEquals("Qualifier incorrect in Scan.toJSON()", Bytes.toStringBinary(QUALIFIER), 299 familyInfo.get(0)); 300 301 // produce a Get Operation 302 Get get = new Get(ROW); 303 get.addColumn(FAMILY, QUALIFIER); 304 // get its JSON representation, and parse it 305 json = get.toJSON(); 306 parsedJSON = GSON.fromJson(json, typeOfHashMap); 307 // check for the row 308 assertEquals("row incorrect in Get.toJSON()", Bytes.toStringBinary(ROW), parsedJSON.get("row")); 309 // check for the family and the qualifier. 310 familyInfo = (List) ((Map) parsedJSON.get("families")).get(Bytes.toStringBinary(FAMILY)); 311 assertNotNull("Family absent in Get.toJSON()", familyInfo); 312 assertEquals("Qualifier absent in Get.toJSON()", 1, familyInfo.size()); 313 assertEquals("Qualifier incorrect in Get.toJSON()", Bytes.toStringBinary(QUALIFIER), 314 familyInfo.get(0)); 315 316 // produce a Put operation 317 Put put = new Put(ROW); 318 put.addColumn(FAMILY, QUALIFIER, VALUE); 319 // get its JSON representation, and parse it 320 json = put.toJSON(); 321 parsedJSON = GSON.fromJson(json, typeOfHashMap); 322 // check for the row 323 assertEquals("row absent in Put.toJSON()", Bytes.toStringBinary(ROW), parsedJSON.get("row")); 324 // check for the family and the qualifier. 325 familyInfo = (List) ((Map) parsedJSON.get("families")).get(Bytes.toStringBinary(FAMILY)); 326 assertNotNull("Family absent in Put.toJSON()", familyInfo); 327 assertEquals("KeyValue absent in Put.toJSON()", 1, familyInfo.size()); 328 Map kvMap = (Map) familyInfo.get(0); 329 assertEquals("Qualifier incorrect in Put.toJSON()", Bytes.toStringBinary(QUALIFIER), 330 kvMap.get("qualifier")); 331 assertEquals("Value length incorrect in Put.toJSON()", VALUE.length, 332 ((Number) kvMap.get("vlen")).intValue()); 333 334 // produce a Delete operation 335 Delete delete = new Delete(ROW); 336 delete.addColumn(FAMILY, QUALIFIER); 337 // get its JSON representation, and parse it 338 json = delete.toJSON(); 339 parsedJSON = GSON.fromJson(json, typeOfHashMap); 340 // check for the row 341 assertEquals("row absent in Delete.toJSON()", Bytes.toStringBinary(ROW), parsedJSON.get("row")); 342 // check for the family and the qualifier. 343 familyInfo = (List) ((Map) parsedJSON.get("families")).get(Bytes.toStringBinary(FAMILY)); 344 assertNotNull("Family absent in Delete.toJSON()", familyInfo); 345 assertEquals("KeyValue absent in Delete.toJSON()", 1, familyInfo.size()); 346 kvMap = (Map) familyInfo.get(0); 347 assertEquals("Qualifier incorrect in Delete.toJSON()", Bytes.toStringBinary(QUALIFIER), 348 kvMap.get("qualifier")); 349 } 350 351 /** 352 * Test the client Scan Operations' JSON encoding to ensure that produced JSON is parseable and 353 * that the details are present and not corrupted. 354 * @throws IOException if the JSON conversion fails 355 */ 356 @Test 357 public void testScanOperationToJSON() throws IOException { 358 // produce a Scan Operation 359 Scan scan = new Scan().withStartRow(ROW, true); 360 scan.addColumn(FAMILY, QUALIFIER); 361 scan.withStopRow(ROW, true); 362 scan.readVersions(5); 363 scan.setBatch(10); 364 scan.setAllowPartialResults(true); 365 scan.setMaxResultsPerColumnFamily(3); 366 scan.setRowOffsetPerColumnFamily(8); 367 scan.setCaching(20); 368 scan.setMaxResultSize(50); 369 scan.setCacheBlocks(true); 370 scan.setReversed(true); 371 scan.setTimeRange(1000, 2000); 372 scan.setAsyncPrefetch(true); 373 scan.setMvccReadPoint(123); 374 scan.setLimit(5); 375 scan.setReadType(Scan.ReadType.PREAD); 376 scan.setNeedCursorResult(true); 377 scan.setFilter(SCV_FILTER); 378 scan.setReplicaId(1); 379 scan.setConsistency(Consistency.STRONG); 380 scan.setLoadColumnFamiliesOnDemand(true); 381 scan.setColumnFamilyTimeRange(FAMILY, 2000, 3000); 382 scan.setPriority(10); 383 384 // get its JSON representation, and parse it 385 String json = scan.toJSON(); 386 Type typeOfHashMap = new TypeToken<Map<String, Object>>() { 387 }.getType(); 388 Gson gson = new GsonBuilder().setLongSerializationPolicy(LongSerializationPolicy.STRING) 389 .setObjectToNumberStrategy(ToNumberPolicy.LONG_OR_DOUBLE).create(); 390 Map<String, Object> parsedJSON = gson.fromJson(json, typeOfHashMap); 391 // check for the row 392 assertEquals("startRow incorrect in Scan.toJSON()", Bytes.toStringBinary(ROW), 393 parsedJSON.get("startRow")); 394 // check for the family and the qualifier. 395 List familyInfo = (List) ((Map) parsedJSON.get("families")).get(Bytes.toStringBinary(FAMILY)); 396 assertNotNull("Family absent in Scan.toJSON()", familyInfo); 397 assertEquals("Qualifier absent in Scan.toJSON()", 1, familyInfo.size()); 398 assertEquals("Qualifier incorrect in Scan.toJSON()", Bytes.toStringBinary(QUALIFIER), 399 familyInfo.get(0)); 400 assertEquals("stopRow incorrect in Scan.toJSON()", Bytes.toStringBinary(ROW), 401 parsedJSON.get("stopRow")); 402 assertEquals("includeStartRow incorrect in Scan.toJSON()", true, 403 parsedJSON.get("includeStartRow")); 404 assertEquals("includeStopRow incorrect in Scan.toJSON()", true, 405 parsedJSON.get("includeStopRow")); 406 assertEquals("maxVersions incorrect in Scan.toJSON()", 5L, parsedJSON.get("maxVersions")); 407 assertEquals("batch incorrect in Scan.toJSON()", 10L, parsedJSON.get("batch")); 408 assertEquals("allowPartialResults incorrect in Scan.toJSON()", true, 409 parsedJSON.get("allowPartialResults")); 410 assertEquals("storeLimit incorrect in Scan.toJSON()", 3L, parsedJSON.get("storeLimit")); 411 assertEquals("storeOffset incorrect in Scan.toJSON()", 8L, parsedJSON.get("storeOffset")); 412 assertEquals("caching incorrect in Scan.toJSON()", 20L, parsedJSON.get("caching")); 413 assertEquals("maxResultSize incorrect in Scan.toJSON()", "50", parsedJSON.get("maxResultSize")); 414 assertEquals("cacheBlocks incorrect in Scan.toJSON()", true, parsedJSON.get("cacheBlocks")); 415 assertEquals("reversed incorrect in Scan.toJSON()", true, parsedJSON.get("reversed")); 416 List trList = (List) parsedJSON.get("timeRange"); 417 assertEquals("timeRange incorrect in Scan.toJSON()", 2, trList.size()); 418 assertEquals("timeRange incorrect in Scan.toJSON()", "1000", trList.get(0)); 419 assertEquals("timeRange incorrect in Scan.toJSON()", "2000", trList.get(1)); 420 421 assertEquals("asyncPrefetch incorrect in Scan.toJSON()", true, parsedJSON.get("asyncPrefetch")); 422 assertEquals("mvccReadPoint incorrect in Scan.toJSON()", "123", 423 parsedJSON.get("mvccReadPoint")); 424 assertEquals("limit incorrect in Scan.toJSON()", 5L, parsedJSON.get("limit")); 425 assertEquals("readType incorrect in Scan.toJSON()", "PREAD", parsedJSON.get("readType")); 426 assertEquals("needCursorResult incorrect in Scan.toJSON()", true, 427 parsedJSON.get("needCursorResult")); 428 429 Map colFamTimeRange = (Map) parsedJSON.get("colFamTimeRangeMap"); 430 assertEquals("colFamTimeRangeMap incorrect in Scan.toJSON()", 1L, colFamTimeRange.size()); 431 List testFamily = (List) colFamTimeRange.get("testFamily"); 432 assertEquals("colFamTimeRangeMap incorrect in Scan.toJSON()", 2L, testFamily.size()); 433 assertEquals("colFamTimeRangeMap incorrect in Scan.toJSON()", "2000", testFamily.get(0)); 434 assertEquals("colFamTimeRangeMap incorrect in Scan.toJSON()", "3000", testFamily.get(1)); 435 436 assertEquals("targetReplicaId incorrect in Scan.toJSON()", 1L, 437 parsedJSON.get("targetReplicaId")); 438 assertEquals("consistency incorrect in Scan.toJSON()", "STRONG", parsedJSON.get("consistency")); 439 assertEquals("loadColumnFamiliesOnDemand incorrect in Scan.toJSON()", true, 440 parsedJSON.get("loadColumnFamiliesOnDemand")); 441 442 assertEquals("priority incorrect in Scan.toJSON()", 10L, parsedJSON.get("priority")); 443 444 } 445 446 @Test 447 public void testPutCreationWithByteBuffer() { 448 Put p = new Put(ROW); 449 List<Cell> c = p.get(FAMILY, QUALIFIER); 450 Assert.assertEquals(0, c.size()); 451 Assert.assertEquals(HConstants.LATEST_TIMESTAMP, p.getTimestamp()); 452 453 p.addColumn(FAMILY, ByteBuffer.wrap(QUALIFIER), 1984L, ByteBuffer.wrap(VALUE)); 454 c = p.get(FAMILY, QUALIFIER); 455 Assert.assertEquals(1, c.size()); 456 Assert.assertEquals(1984L, c.get(0).getTimestamp()); 457 Assert.assertArrayEquals(VALUE, CellUtil.cloneValue(c.get(0))); 458 Assert.assertEquals(HConstants.LATEST_TIMESTAMP, p.getTimestamp()); 459 Assert.assertEquals(0, CellComparatorImpl.COMPARATOR.compare(c.get(0), new KeyValue(c.get(0)))); 460 461 p = new Put(ROW); 462 p.addColumn(FAMILY, ByteBuffer.wrap(QUALIFIER), 2013L, null); 463 c = p.get(FAMILY, QUALIFIER); 464 Assert.assertEquals(1, c.size()); 465 Assert.assertEquals(2013L, c.get(0).getTimestamp()); 466 Assert.assertArrayEquals(new byte[] {}, CellUtil.cloneValue(c.get(0))); 467 Assert.assertEquals(HConstants.LATEST_TIMESTAMP, p.getTimestamp()); 468 Assert.assertEquals(0, CellComparatorImpl.COMPARATOR.compare(c.get(0), new KeyValue(c.get(0)))); 469 470 p = new Put(ByteBuffer.wrap(ROW)); 471 p.addColumn(FAMILY, ByteBuffer.wrap(QUALIFIER), 2001L, null); 472 c = p.get(FAMILY, QUALIFIER); 473 Assert.assertEquals(1, c.size()); 474 Assert.assertEquals(2001L, c.get(0).getTimestamp()); 475 Assert.assertArrayEquals(new byte[] {}, CellUtil.cloneValue(c.get(0))); 476 Assert.assertArrayEquals(ROW, CellUtil.cloneRow(c.get(0))); 477 Assert.assertEquals(HConstants.LATEST_TIMESTAMP, p.getTimestamp()); 478 Assert.assertEquals(0, CellComparatorImpl.COMPARATOR.compare(c.get(0), new KeyValue(c.get(0)))); 479 480 p = new Put(ByteBuffer.wrap(ROW), 1970L); 481 p.addColumn(FAMILY, ByteBuffer.wrap(QUALIFIER), 2001L, null); 482 c = p.get(FAMILY, QUALIFIER); 483 Assert.assertEquals(1, c.size()); 484 Assert.assertEquals(2001L, c.get(0).getTimestamp()); 485 Assert.assertArrayEquals(new byte[] {}, CellUtil.cloneValue(c.get(0))); 486 Assert.assertArrayEquals(ROW, CellUtil.cloneRow(c.get(0))); 487 Assert.assertEquals(1970L, p.getTimestamp()); 488 Assert.assertEquals(0, CellComparatorImpl.COMPARATOR.compare(c.get(0), new KeyValue(c.get(0)))); 489 } 490 491 @Test 492 @SuppressWarnings("rawtypes") 493 public void testOperationSubClassMethodsAreBuilderStyle() { 494 /* 495 * All Operation subclasses should have a builder style setup where setXXX/addXXX methods can be 496 * chainable together: . For example: Scan scan = new Scan() .setFoo(foo) .setBar(bar) 497 * .setBuz(buz) This test ensures that all methods starting with "set" returns the declaring 498 * object 499 */ 500 501 // TODO: We should ensure all subclasses of Operation is checked. 502 Class[] classes = new Class[] { Operation.class, OperationWithAttributes.class, Mutation.class, 503 Query.class, Delete.class, Increment.class, Append.class, Put.class, Get.class, Scan.class }; 504 505 BuilderStyleTest.assertClassesAreBuilderStyle(classes); 506 } 507 508 /** 509 * Test the client Get Operations' JSON encoding to ensure that produced JSON is parseable and 510 * that the details are present and not corrupted. 511 * @throws IOException if the JSON conversion fails 512 */ 513 @Test 514 public void testGetOperationToJSON() throws IOException { 515 // produce a Scan Operation 516 Get get = new Get(ROW); 517 get.addColumn(FAMILY, QUALIFIER); 518 get.readVersions(5); 519 get.setMaxResultsPerColumnFamily(3); 520 get.setRowOffsetPerColumnFamily(8); 521 get.setCacheBlocks(true); 522 get.setMaxResultsPerColumnFamily(5); 523 get.setRowOffsetPerColumnFamily(9); 524 get.setCheckExistenceOnly(true); 525 get.setTimeRange(1000, 2000); 526 get.setFilter(SCV_FILTER); 527 get.setReplicaId(1); 528 get.setConsistency(Consistency.STRONG); 529 get.setLoadColumnFamiliesOnDemand(true); 530 get.setColumnFamilyTimeRange(FAMILY, 2000, 3000); 531 get.setPriority(10); 532 533 // get its JSON representation, and parse it 534 String json = get.toJSON(); 535 Type typeOfHashMap = new TypeToken<Map<String, Object>>() { 536 }.getType(); 537 Gson gson = new GsonBuilder().setLongSerializationPolicy(LongSerializationPolicy.STRING) 538 .setObjectToNumberStrategy(ToNumberPolicy.LONG_OR_DOUBLE).create(); 539 Map<String, Object> parsedJSON = gson.fromJson(json, typeOfHashMap); 540 // check for the row 541 assertEquals("row incorrect in Get.toJSON()", Bytes.toStringBinary(ROW), parsedJSON.get("row")); 542 // check for the family and the qualifier. 543 List familyInfo = (List) ((Map) parsedJSON.get("families")).get(Bytes.toStringBinary(FAMILY)); 544 assertNotNull("Family absent in Get.toJSON()", familyInfo); 545 assertEquals("Qualifier absent in Get.toJSON()", 1, familyInfo.size()); 546 assertEquals("Qualifier incorrect in Get.toJSON()", Bytes.toStringBinary(QUALIFIER), 547 familyInfo.get(0)); 548 549 assertEquals("maxVersions incorrect in Get.toJSON()", 5L, parsedJSON.get("maxVersions")); 550 551 assertEquals("storeLimit incorrect in Get.toJSON()", 5L, parsedJSON.get("storeLimit")); 552 assertEquals("storeOffset incorrect in Get.toJSON()", 9L, parsedJSON.get("storeOffset")); 553 554 assertEquals("cacheBlocks incorrect in Get.toJSON()", true, parsedJSON.get("cacheBlocks")); 555 556 List trList = (List) parsedJSON.get("timeRange"); 557 assertEquals("timeRange incorrect in Get.toJSON()", 2, trList.size()); 558 assertEquals("timeRange incorrect in Get.toJSON()", "1000", trList.get(0)); 559 assertEquals("timeRange incorrect in Get.toJSON()", "2000", trList.get(1)); 560 561 Map colFamTimeRange = (Map) parsedJSON.get("colFamTimeRangeMap"); 562 assertEquals("colFamTimeRangeMap incorrect in Get.toJSON()", 1L, colFamTimeRange.size()); 563 List testFamily = (List) colFamTimeRange.get("testFamily"); 564 assertEquals("colFamTimeRangeMap incorrect in Get.toJSON()", 2L, testFamily.size()); 565 assertEquals("colFamTimeRangeMap incorrect in Get.toJSON()", "2000", testFamily.get(0)); 566 assertEquals("colFamTimeRangeMap incorrect in Get.toJSON()", "3000", testFamily.get(1)); 567 568 assertEquals("targetReplicaId incorrect in Get.toJSON()", 1L, 569 parsedJSON.get("targetReplicaId")); 570 assertEquals("consistency incorrect in Get.toJSON()", "STRONG", parsedJSON.get("consistency")); 571 assertEquals("loadColumnFamiliesOnDemand incorrect in Get.toJSON()", true, 572 parsedJSON.get("loadColumnFamiliesOnDemand")); 573 574 assertEquals("priority incorrect in Get.toJSON()", 10L, parsedJSON.get("priority")); 575 assertEquals("checkExistenceOnly incorrect in Get.toJSON()", true, 576 parsedJSON.get("checkExistenceOnly")); 577 578 } 579}