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