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.shaded.protobuf; 019 020import static org.junit.jupiter.api.Assertions.assertEquals; 021import static org.junit.jupiter.api.Assertions.assertNotNull; 022import static org.junit.jupiter.api.Assertions.assertTrue; 023 024import java.io.IOException; 025import java.lang.reflect.Method; 026import java.nio.ByteBuffer; 027import java.util.Collections; 028import java.util.List; 029import org.apache.hadoop.hbase.ArrayBackedTag; 030import org.apache.hadoop.hbase.ByteBufferKeyValue; 031import org.apache.hadoop.hbase.Cell; 032import org.apache.hadoop.hbase.CellBuilderType; 033import org.apache.hadoop.hbase.CellComparatorImpl; 034import org.apache.hadoop.hbase.ExtendedCell; 035import org.apache.hadoop.hbase.ExtendedCellBuilder; 036import org.apache.hadoop.hbase.ExtendedCellBuilderFactory; 037import org.apache.hadoop.hbase.HConstants; 038import org.apache.hadoop.hbase.KeyValue; 039import org.apache.hadoop.hbase.PrivateCellUtil; 040import org.apache.hadoop.hbase.Tag; 041import org.apache.hadoop.hbase.client.Append; 042import org.apache.hadoop.hbase.client.Delete; 043import org.apache.hadoop.hbase.client.Get; 044import org.apache.hadoop.hbase.client.Increment; 045import org.apache.hadoop.hbase.client.Put; 046import org.apache.hadoop.hbase.client.SlowLogParams; 047import org.apache.hadoop.hbase.io.TimeRange; 048import org.apache.hadoop.hbase.testclassification.SmallTests; 049import org.apache.hadoop.hbase.util.Bytes; 050import org.junit.jupiter.api.Test; 051 052import org.apache.hbase.thirdparty.com.google.common.collect.Lists; 053import org.apache.hbase.thirdparty.com.google.protobuf.Any; 054import org.apache.hbase.thirdparty.com.google.protobuf.ByteString; 055import org.apache.hbase.thirdparty.com.google.protobuf.BytesValue; 056import org.apache.hbase.thirdparty.com.google.protobuf.InvalidProtocolBufferException; 057 058import org.apache.hadoop.hbase.shaded.protobuf.generated.CellProtos; 059import org.apache.hadoop.hbase.shaded.protobuf.generated.ClientProtos; 060import org.apache.hadoop.hbase.shaded.protobuf.generated.ClientProtos.Column; 061import org.apache.hadoop.hbase.shaded.protobuf.generated.ClientProtos.MutationProto; 062import org.apache.hadoop.hbase.shaded.protobuf.generated.ClientProtos.MutationProto.ColumnValue; 063import org.apache.hadoop.hbase.shaded.protobuf.generated.ClientProtos.MutationProto.ColumnValue.QualifierValue; 064import org.apache.hadoop.hbase.shaded.protobuf.generated.ClientProtos.MutationProto.DeleteType; 065import org.apache.hadoop.hbase.shaded.protobuf.generated.ClientProtos.MutationProto.MutationType; 066import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos; 067import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos.NameBytesPair; 068import org.apache.hadoop.hbase.shaded.protobuf.generated.LockServiceProtos; 069import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos; 070import org.apache.hadoop.hbase.shaded.protobuf.generated.ProcedureProtos; 071import org.apache.hadoop.hbase.shaded.protobuf.generated.RegionServerStatusProtos; 072 073@org.junit.jupiter.api.Tag(SmallTests.TAG) 074public class TestProtobufUtil { 075 076 private static final String TAG_STR = "tag-1"; 077 private static final byte TAG_TYPE = (byte) 10; 078 private static final HBaseProtos.ServerName SERVER_NAME = 079 HBaseProtos.ServerName.newBuilder().setHostName("a.b.com").build(); 080 private static final HBaseProtos.RegionSpecifier REGION = 081 HBaseProtos.RegionSpecifier.newBuilder().setValue(ByteString.copyFromUtf8("test")) 082 .setType(HBaseProtos.RegionSpecifier.RegionSpecifierType.REGION_NAME).build(); 083 084 public TestProtobufUtil() { 085 } 086 087 @Test 088 public void testException() throws IOException { 089 NameBytesPair.Builder builder = NameBytesPair.newBuilder(); 090 final String omg = "OMG!!!"; 091 builder.setName("java.io.IOException"); 092 builder.setValue(ByteString.copyFrom(Bytes.toBytes(omg))); 093 Throwable t = ProtobufUtil.toException(builder.build()); 094 assertEquals(omg, t.getMessage()); 095 builder.clear(); 096 builder.setName("org.apache.hadoop.ipc.RemoteException"); 097 builder.setValue(ByteString.copyFrom(Bytes.toBytes(omg))); 098 t = ProtobufUtil.toException(builder.build()); 099 assertEquals(omg, t.getMessage()); 100 } 101 102 /** 103 * Test basic Get conversions. 104 * @throws IOException if the conversion to a {@link Get} fails 105 */ 106 @Test 107 public void testGet() throws IOException { 108 ClientProtos.Get.Builder getBuilder = ClientProtos.Get.newBuilder(); 109 getBuilder.setRow(ByteString.copyFromUtf8("row")); 110 Column.Builder columnBuilder = Column.newBuilder(); 111 columnBuilder.setFamily(ByteString.copyFromUtf8("f1")); 112 columnBuilder.addQualifier(ByteString.copyFromUtf8("c1")); 113 columnBuilder.addQualifier(ByteString.copyFromUtf8("c2")); 114 getBuilder.addColumn(columnBuilder.build()); 115 116 columnBuilder.clear(); 117 columnBuilder.setFamily(ByteString.copyFromUtf8("f2")); 118 getBuilder.addColumn(columnBuilder.build()); 119 getBuilder.setLoadColumnFamiliesOnDemand(true); 120 ClientProtos.Get proto = getBuilder.build(); 121 // default fields 122 assertEquals(1, proto.getMaxVersions()); 123 assertEquals(true, proto.getCacheBlocks()); 124 125 // set the default value for equal comparison 126 getBuilder = ClientProtos.Get.newBuilder(proto); 127 getBuilder.setMaxVersions(1); 128 getBuilder.setCacheBlocks(true); 129 getBuilder.setTimeRange(ProtobufUtil.toTimeRange(TimeRange.allTime())); 130 getBuilder.setQueryMetricsEnabled(false); 131 Get get = ProtobufUtil.toGet(proto); 132 assertEquals(getBuilder.build(), ProtobufUtil.toGet(get)); 133 } 134 135 /** 136 * Test Delete Mutate conversions. 137 * @throws IOException if the conversion to a {@link Delete} or a 138 * {@link org.apache.hadoop.hbase.client.Mutation} fails 139 */ 140 @Test 141 public void testDelete() throws IOException { 142 MutationProto.Builder mutateBuilder = MutationProto.newBuilder(); 143 mutateBuilder.setRow(ByteString.copyFromUtf8("row")); 144 mutateBuilder.setMutateType(MutationType.DELETE); 145 mutateBuilder.setTimestamp(111111); 146 ColumnValue.Builder valueBuilder = ColumnValue.newBuilder(); 147 valueBuilder.setFamily(ByteString.copyFromUtf8("f1")); 148 QualifierValue.Builder qualifierBuilder = QualifierValue.newBuilder(); 149 qualifierBuilder.setQualifier(ByteString.copyFromUtf8("c1")); 150 qualifierBuilder.setDeleteType(DeleteType.DELETE_ONE_VERSION); 151 qualifierBuilder.setTimestamp(111222); 152 valueBuilder.addQualifierValue(qualifierBuilder.build()); 153 qualifierBuilder.setQualifier(ByteString.copyFromUtf8("c2")); 154 qualifierBuilder.setDeleteType(DeleteType.DELETE_MULTIPLE_VERSIONS); 155 qualifierBuilder.setTimestamp(111333); 156 valueBuilder.addQualifierValue(qualifierBuilder.build()); 157 mutateBuilder.addColumnValue(valueBuilder.build()); 158 159 MutationProto proto = mutateBuilder.build(); 160 // default fields 161 assertEquals(MutationProto.Durability.USE_DEFAULT, proto.getDurability()); 162 163 // set the default value for equal comparison 164 mutateBuilder = MutationProto.newBuilder(proto); 165 mutateBuilder.setDurability(MutationProto.Durability.USE_DEFAULT); 166 167 Delete delete = ProtobufUtil.toDelete(proto); 168 169 // delete always have empty value, 170 // add empty value to the original mutate 171 for (ColumnValue.Builder column : mutateBuilder.getColumnValueBuilderList()) { 172 for (QualifierValue.Builder qualifier : column.getQualifierValueBuilderList()) { 173 qualifier.setValue(ByteString.EMPTY); 174 } 175 } 176 assertEquals(mutateBuilder.build(), ProtobufUtil.toMutation(MutationType.DELETE, delete)); 177 } 178 179 /** 180 * Test Put Mutate conversions. 181 * @throws IOException if the conversion to a {@link Put} or a 182 * {@link org.apache.hadoop.hbase.client.Mutation} fails 183 */ 184 @Test 185 public void testPut() throws IOException { 186 MutationProto.Builder mutateBuilder = MutationProto.newBuilder(); 187 mutateBuilder.setRow(ByteString.copyFromUtf8("row")); 188 mutateBuilder.setMutateType(MutationType.PUT); 189 mutateBuilder.setTimestamp(111111); 190 ColumnValue.Builder valueBuilder = ColumnValue.newBuilder(); 191 valueBuilder.setFamily(ByteString.copyFromUtf8("f1")); 192 QualifierValue.Builder qualifierBuilder = QualifierValue.newBuilder(); 193 qualifierBuilder.setQualifier(ByteString.copyFromUtf8("c1")); 194 qualifierBuilder.setValue(ByteString.copyFromUtf8("v1")); 195 valueBuilder.addQualifierValue(qualifierBuilder.build()); 196 qualifierBuilder.setQualifier(ByteString.copyFromUtf8("c2")); 197 qualifierBuilder.setValue(ByteString.copyFromUtf8("v2")); 198 qualifierBuilder.setTimestamp(222222); 199 valueBuilder.addQualifierValue(qualifierBuilder.build()); 200 mutateBuilder.addColumnValue(valueBuilder.build()); 201 202 MutationProto proto = mutateBuilder.build(); 203 // default fields 204 assertEquals(MutationProto.Durability.USE_DEFAULT, proto.getDurability()); 205 206 // set the default value for equal comparison 207 mutateBuilder = MutationProto.newBuilder(proto); 208 mutateBuilder.setDurability(MutationProto.Durability.USE_DEFAULT); 209 210 Put put = ProtobufUtil.toPut(proto); 211 212 // put value always use the default timestamp if no 213 // value level timestamp specified, 214 // add the timestamp to the original mutate 215 long timestamp = put.getTimestamp(); 216 for (ColumnValue.Builder column : mutateBuilder.getColumnValueBuilderList()) { 217 for (QualifierValue.Builder qualifier : column.getQualifierValueBuilderList()) { 218 if (!qualifier.hasTimestamp()) { 219 qualifier.setTimestamp(timestamp); 220 } 221 } 222 } 223 assertEquals(mutateBuilder.build(), ProtobufUtil.toMutation(MutationType.PUT, put)); 224 } 225 226 /** 227 * Test basic Scan conversions. 228 * @throws IOException if the conversion to a {@link org.apache.hadoop.hbase.client.Scan} fails 229 */ 230 @Test 231 public void testScan() throws IOException { 232 ClientProtos.Scan.Builder scanBuilder = ClientProtos.Scan.newBuilder(); 233 scanBuilder.setStartRow(ByteString.copyFromUtf8("row1")); 234 scanBuilder.setStopRow(ByteString.copyFromUtf8("row2")); 235 Column.Builder columnBuilder = Column.newBuilder(); 236 columnBuilder.setFamily(ByteString.copyFromUtf8("f1")); 237 columnBuilder.addQualifier(ByteString.copyFromUtf8("c1")); 238 columnBuilder.addQualifier(ByteString.copyFromUtf8("c2")); 239 scanBuilder.addColumn(columnBuilder.build()); 240 241 columnBuilder.clear(); 242 columnBuilder.setFamily(ByteString.copyFromUtf8("f2")); 243 scanBuilder.addColumn(columnBuilder.build()); 244 245 ClientProtos.Scan proto = scanBuilder.build(); 246 247 // Verify default values 248 assertEquals(1, proto.getMaxVersions()); 249 assertEquals(true, proto.getCacheBlocks()); 250 251 // Verify fields survive ClientProtos.Scan -> Scan -> ClientProtos.Scan 252 // conversion 253 scanBuilder = ClientProtos.Scan.newBuilder(proto); 254 scanBuilder.setMaxVersions(2); 255 scanBuilder.setCacheBlocks(false); 256 scanBuilder.setCaching(1024); 257 scanBuilder.setTimeRange(ProtobufUtil.toTimeRange(TimeRange.allTime())); 258 scanBuilder.setIncludeStopRow(false); 259 scanBuilder.setQueryMetricsEnabled(false); 260 ClientProtos.Scan expectedProto = scanBuilder.build(); 261 262 ClientProtos.Scan actualProto = ProtobufUtil.toScan(ProtobufUtil.toScan(expectedProto)); 263 assertEquals(expectedProto, actualProto); 264 } 265 266 @Test 267 public void testToCell() { 268 KeyValue kv1 = 269 new KeyValue(Bytes.toBytes("aaa"), Bytes.toBytes("f1"), Bytes.toBytes("q1"), new byte[30]); 270 KeyValue kv2 = 271 new KeyValue(Bytes.toBytes("bbb"), Bytes.toBytes("f1"), Bytes.toBytes("q1"), new byte[30]); 272 KeyValue kv3 = 273 new KeyValue(Bytes.toBytes("ccc"), Bytes.toBytes("f1"), Bytes.toBytes("q1"), new byte[30]); 274 byte[] arr = new byte[kv1.getLength() + kv2.getLength() + kv3.getLength()]; 275 System.arraycopy(kv1.getBuffer(), kv1.getOffset(), arr, 0, kv1.getLength()); 276 System.arraycopy(kv2.getBuffer(), kv2.getOffset(), arr, kv1.getLength(), kv2.getLength()); 277 System.arraycopy(kv3.getBuffer(), kv3.getOffset(), arr, kv1.getLength() + kv2.getLength(), 278 kv3.getLength()); 279 ByteBuffer dbb = ByteBuffer.allocateDirect(arr.length); 280 dbb.put(arr); 281 ByteBufferKeyValue offheapKV = new ByteBufferKeyValue(dbb, kv1.getLength(), kv2.getLength()); 282 CellProtos.Cell cell = ProtobufUtil.toCell(offheapKV, false); 283 Cell newOffheapKV = ProtobufUtil 284 .toCell(ExtendedCellBuilderFactory.create(CellBuilderType.SHALLOW_COPY), cell, false); 285 assertTrue(CellComparatorImpl.COMPARATOR.compare(offheapKV, newOffheapKV) == 0); 286 } 287 288 /** 289 * Test Increment Mutate conversions. 290 * @throws IOException if converting to an {@link Increment} or 291 * {@link org.apache.hadoop.hbase.client.Mutation} fails 292 */ 293 @Test 294 public void testIncrement() throws IOException { 295 296 MutationProto proto = getIncrementMutation(111111L); 297 // default fields 298 assertEquals(MutationProto.Durability.USE_DEFAULT, proto.getDurability()); 299 300 // set the default value for equal comparison 301 MutationProto.Builder mutateBuilder = MutationProto.newBuilder(proto); 302 mutateBuilder.setDurability(MutationProto.Durability.USE_DEFAULT); 303 304 Increment increment = ProtobufUtil.toIncrement(proto, null); 305 mutateBuilder.setTimestamp(increment.getTimestamp()); 306 mutateBuilder.setTimeRange(ProtobufUtil.toTimeRange(increment.getTimeRange())); 307 assertEquals(mutateBuilder.build(), ProtobufUtil.toMutation(MutationType.INCREMENT, increment)); 308 } 309 310 private MutationProto getIncrementMutation(Long timestamp) { 311 MutationProto.Builder mutateBuilder = MutationProto.newBuilder(); 312 mutateBuilder.setRow(ByteString.copyFromUtf8("row")); 313 mutateBuilder.setMutateType(MutationProto.MutationType.INCREMENT); 314 ColumnValue.Builder valueBuilder = ColumnValue.newBuilder(); 315 valueBuilder.setFamily(ByteString.copyFromUtf8("f1")); 316 QualifierValue.Builder qualifierBuilder = QualifierValue.newBuilder(); 317 qualifierBuilder.setQualifier(ByteString.copyFromUtf8("c1")); 318 qualifierBuilder.setValue(ByteString.copyFrom(Bytes.toBytes(11L))); 319 320 if (timestamp != null) { 321 qualifierBuilder.setTimestamp(timestamp); 322 } 323 324 valueBuilder.addQualifierValue(qualifierBuilder.build()); 325 qualifierBuilder.setQualifier(ByteString.copyFromUtf8("c2")); 326 qualifierBuilder.setValue(ByteString.copyFrom(Bytes.toBytes(22L))); 327 valueBuilder.addQualifierValue(qualifierBuilder.build()); 328 mutateBuilder.addColumnValue(valueBuilder.build()); 329 330 return mutateBuilder.build(); 331 } 332 333 /** 334 * Older clients may not send along a timestamp in the MutationProto. Check that we default 335 * correctly. 336 */ 337 @Test 338 public void testIncrementNoTimestamp() throws IOException { 339 MutationProto mutation = getIncrementMutation(null); 340 Increment increment = ProtobufUtil.toIncrement(mutation, null); 341 assertEquals(HConstants.LATEST_TIMESTAMP, increment.getTimestamp()); 342 increment.getFamilyCellMap().values().forEach(cells -> cells 343 .forEach(cell -> assertEquals(HConstants.LATEST_TIMESTAMP, cell.getTimestamp()))); 344 } 345 346 /** 347 * Test Append Mutate conversions. 348 * @throws IOException if converting to an {@link Append} fails 349 */ 350 @Test 351 public void testAppend() throws IOException { 352 MutationProto proto = getAppendMutation(111111L); 353 // default fields 354 assertEquals(MutationProto.Durability.USE_DEFAULT, proto.getDurability()); 355 356 // set the default value for equal comparison 357 MutationProto.Builder mutateBuilder = MutationProto.newBuilder(proto); 358 mutateBuilder.setDurability(MutationProto.Durability.USE_DEFAULT); 359 360 Append append = ProtobufUtil.toAppend(proto, null); 361 362 // append always use the latest timestamp, 363 // reset the timestamp to the original mutate 364 mutateBuilder.setTimestamp(append.getTimestamp()); 365 mutateBuilder.setTimeRange(ProtobufUtil.toTimeRange(append.getTimeRange())); 366 assertEquals(mutateBuilder.build(), ProtobufUtil.toMutation(MutationType.APPEND, append)); 367 } 368 369 /** 370 * Older clients may not send along a timestamp in the MutationProto. Check that we default 371 * correctly. 372 */ 373 @Test 374 public void testAppendNoTimestamp() throws IOException { 375 MutationProto mutation = getAppendMutation(null); 376 Append append = ProtobufUtil.toAppend(mutation, null); 377 assertEquals(HConstants.LATEST_TIMESTAMP, append.getTimestamp()); 378 append.getFamilyCellMap().values().forEach(cells -> cells 379 .forEach(cell -> assertEquals(HConstants.LATEST_TIMESTAMP, cell.getTimestamp()))); 380 } 381 382 private MutationProto getAppendMutation(Long timestamp) { 383 MutationProto.Builder mutateBuilder = MutationProto.newBuilder(); 384 mutateBuilder.setRow(ByteString.copyFromUtf8("row")); 385 mutateBuilder.setMutateType(MutationType.APPEND); 386 if (timestamp != null) { 387 mutateBuilder.setTimestamp(timestamp); 388 } 389 ColumnValue.Builder valueBuilder = ColumnValue.newBuilder(); 390 valueBuilder.setFamily(ByteString.copyFromUtf8("f1")); 391 QualifierValue.Builder qualifierBuilder = QualifierValue.newBuilder(); 392 qualifierBuilder.setQualifier(ByteString.copyFromUtf8("c1")); 393 qualifierBuilder.setValue(ByteString.copyFromUtf8("v1")); 394 if (timestamp != null) { 395 qualifierBuilder.setTimestamp(timestamp); 396 } 397 valueBuilder.addQualifierValue(qualifierBuilder.build()); 398 qualifierBuilder.setQualifier(ByteString.copyFromUtf8("c2")); 399 qualifierBuilder.setValue(ByteString.copyFromUtf8("v2")); 400 valueBuilder.addQualifierValue(qualifierBuilder.build()); 401 mutateBuilder.addColumnValue(valueBuilder.build()); 402 403 return mutateBuilder.build(); 404 } 405 406 private static ProcedureProtos.Procedure.Builder createProcedureBuilder(long procId) { 407 ProcedureProtos.Procedure.Builder builder = ProcedureProtos.Procedure.newBuilder(); 408 builder.setProcId(procId); 409 builder.setClassName("java.lang.Object"); 410 builder.setSubmittedTime(0); 411 builder.setState(ProcedureProtos.ProcedureState.RUNNABLE); 412 builder.setLastUpdate(0); 413 414 return builder; 415 } 416 417 private static ProcedureProtos.Procedure createProcedure(long procId) { 418 return createProcedureBuilder(procId).build(); 419 } 420 421 private static LockServiceProtos.LockedResource createLockedResource( 422 LockServiceProtos.LockedResourceType resourceType, String resourceName, 423 LockServiceProtos.LockType lockType, ProcedureProtos.Procedure exclusiveLockOwnerProcedure, 424 int sharedLockCount) { 425 LockServiceProtos.LockedResource.Builder build = LockServiceProtos.LockedResource.newBuilder(); 426 build.setResourceType(resourceType); 427 build.setResourceName(resourceName); 428 build.setLockType(lockType); 429 if (exclusiveLockOwnerProcedure != null) { 430 build.setExclusiveLockOwnerProcedure(exclusiveLockOwnerProcedure); 431 } 432 build.setSharedLockCount(sharedLockCount); 433 434 return build.build(); 435 } 436 437 @Test 438 public void testProcedureInfo() { 439 ProcedureProtos.Procedure.Builder builder = createProcedureBuilder(1); 440 ByteString stateBytes = ByteString.copyFrom(new byte[] { 65 }); 441 BytesValue state = BytesValue.newBuilder().setValue(stateBytes).build(); 442 builder.addStateMessage(Any.pack(state)); 443 ProcedureProtos.Procedure procedure = builder.build(); 444 445 String procJson = ProtobufUtil.toProcedureJson(Lists.newArrayList(procedure)); 446 assertEquals("[{" + "\"className\":\"java.lang.Object\"," + "\"procId\":\"1\"," 447 + "\"submittedTime\":\"0\"," + "\"state\":\"RUNNABLE\"," + "\"lastUpdate\":\"0\"," 448 + "\"stateMessage\":[{\"value\":\"QQ==\"}]" + "}]", procJson); 449 } 450 451 @Test 452 public void testServerLockInfo() { 453 LockServiceProtos.LockedResource resource = 454 createLockedResource(LockServiceProtos.LockedResourceType.SERVER, "server", 455 LockServiceProtos.LockType.SHARED, null, 2); 456 457 String lockJson = ProtobufUtil.toLockJson(Lists.newArrayList(resource)); 458 assertEquals("[{" + "\"resourceType\":\"SERVER\"," + "\"resourceName\":\"server\"," 459 + "\"lockType\":\"SHARED\"," + "\"sharedLockCount\":2" + "}]", lockJson); 460 } 461 462 @Test 463 public void testNamespaceLockInfo() { 464 LockServiceProtos.LockedResource resource = 465 createLockedResource(LockServiceProtos.LockedResourceType.NAMESPACE, "ns", 466 LockServiceProtos.LockType.EXCLUSIVE, createProcedure(2), 0); 467 468 String lockJson = ProtobufUtil.toLockJson(Lists.newArrayList(resource)); 469 assertEquals("[{" + "\"resourceType\":\"NAMESPACE\"," + "\"resourceName\":\"ns\"," 470 + "\"lockType\":\"EXCLUSIVE\"," + "\"exclusiveLockOwnerProcedure\":{" 471 + "\"className\":\"java.lang.Object\"," + "\"procId\":\"2\"," + "\"submittedTime\":\"0\"," 472 + "\"state\":\"RUNNABLE\"," + "\"lastUpdate\":\"0\"" + "}," + "\"sharedLockCount\":0" + "}]", 473 lockJson); 474 } 475 476 @Test 477 public void testTableLockInfo() { 478 LockServiceProtos.LockedResource resource = 479 createLockedResource(LockServiceProtos.LockedResourceType.TABLE, "table", 480 LockServiceProtos.LockType.SHARED, null, 2); 481 482 String lockJson = ProtobufUtil.toLockJson(Lists.newArrayList(resource)); 483 assertEquals("[{" + "\"resourceType\":\"TABLE\"," + "\"resourceName\":\"table\"," 484 + "\"lockType\":\"SHARED\"," + "\"sharedLockCount\":2" + "}]", lockJson); 485 } 486 487 @Test 488 public void testRegionLockInfo() { 489 LockServiceProtos.LockedResource resource = 490 createLockedResource(LockServiceProtos.LockedResourceType.REGION, "region", 491 LockServiceProtos.LockType.EXCLUSIVE, createProcedure(3), 0); 492 493 String lockJson = ProtobufUtil.toLockJson(Lists.newArrayList(resource)); 494 assertEquals("[{" + "\"resourceType\":\"REGION\"," + "\"resourceName\":\"region\"," 495 + "\"lockType\":\"EXCLUSIVE\"," + "\"exclusiveLockOwnerProcedure\":{" 496 + "\"className\":\"java.lang.Object\"," + "\"procId\":\"3\"," + "\"submittedTime\":\"0\"," 497 + "\"state\":\"RUNNABLE\"," + "\"lastUpdate\":\"0\"" + "}," + "\"sharedLockCount\":0" + "}]", 498 lockJson); 499 } 500 501 /** 502 * Test {@link ProtobufUtil#toCell(ExtendedCell, boolean)} and 503 * {@link ProtobufUtil#toCell(ExtendedCellBuilder, CellProtos.Cell, boolean)} conversion methods 504 * when it contains tags and encode/decode tags is set to true. 505 */ 506 @Test 507 public void testCellConversionWithTags() { 508 ExtendedCell cell = getCellWithTags(); 509 CellProtos.Cell protoCell = ProtobufUtil.toCell(cell, true); 510 assertNotNull(protoCell); 511 512 ExtendedCell decodedCell = getCellFromProtoResult(protoCell, true); 513 List<Tag> decodedTags = PrivateCellUtil.getTags(decodedCell); 514 assertEquals(1, decodedTags.size()); 515 Tag decodedTag = decodedTags.get(0); 516 assertEquals(TAG_TYPE, decodedTag.getType()); 517 assertEquals(TAG_STR, Tag.getValueAsString(decodedTag)); 518 } 519 520 private ExtendedCell getCellWithTags() { 521 Tag tag = new ArrayBackedTag(TAG_TYPE, TAG_STR); 522 ExtendedCellBuilder cellBuilder = ExtendedCellBuilderFactory.create(CellBuilderType.DEEP_COPY); 523 cellBuilder.setRow(Bytes.toBytes("row1")); 524 cellBuilder.setFamily(Bytes.toBytes("f1")); 525 cellBuilder.setQualifier(Bytes.toBytes("q1")); 526 cellBuilder.setValue(Bytes.toBytes("value1")); 527 cellBuilder.setType(Cell.Type.Delete); 528 cellBuilder.setTags(Collections.singletonList(tag)); 529 return cellBuilder.build(); 530 } 531 532 private ExtendedCell getCellFromProtoResult(CellProtos.Cell protoCell, boolean decodeTags) { 533 ExtendedCellBuilder decodedBuilder = 534 ExtendedCellBuilderFactory.create(CellBuilderType.DEEP_COPY); 535 return ProtobufUtil.toCell(decodedBuilder, protoCell, decodeTags); 536 } 537 538 /** 539 * Test {@link ProtobufUtil#toCell(Cell, boolean)} and 540 * {@link ProtobufUtil#toCell(ExtendedCellBuilder, CellProtos.Cell, boolean)} conversion methods 541 * when it contains tags and encode/decode tags is set to false. 542 */ 543 @Test 544 public void testCellConversionWithoutTags() { 545 ExtendedCell cell = getCellWithTags(); 546 CellProtos.Cell protoCell = ProtobufUtil.toCell(cell, false); 547 assertNotNull(protoCell); 548 549 ExtendedCell decodedCell = getCellFromProtoResult(protoCell, false); 550 List<Tag> decodedTags = PrivateCellUtil.getTags(decodedCell); 551 assertEquals(0, decodedTags.size()); 552 } 553 554 /** 555 * Test {@link ProtobufUtil#toCell(Cell, boolean)} and 556 * {@link ProtobufUtil#toCell(ExtendedCellBuilder, CellProtos.Cell, boolean)} conversion methods 557 * when it contains tags and encoding of tags is set to false and decoding of tags is set to true. 558 */ 559 @Test 560 public void testTagEncodeFalseDecodeTrue() { 561 ExtendedCell cell = getCellWithTags(); 562 CellProtos.Cell protoCell = ProtobufUtil.toCell(cell, false); 563 assertNotNull(protoCell); 564 565 ExtendedCell decodedCell = getCellFromProtoResult(protoCell, true); 566 List<Tag> decodedTags = PrivateCellUtil.getTags(decodedCell); 567 assertEquals(0, decodedTags.size()); 568 } 569 570 /** 571 * Test {@link ProtobufUtil#toCell(Cell, boolean)} and 572 * {@link ProtobufUtil#toCell(ExtendedCellBuilder, CellProtos.Cell, boolean)} conversion methods 573 * when it contains tags and encoding of tags is set to true and decoding of tags is set to false. 574 */ 575 @Test 576 public void testTagEncodeTrueDecodeFalse() { 577 ExtendedCell cell = getCellWithTags(); 578 CellProtos.Cell protoCell = ProtobufUtil.toCell(cell, true); 579 assertNotNull(protoCell); 580 581 ExtendedCell decodedCell = getCellFromProtoResult(protoCell, false); 582 List<Tag> decodedTags = PrivateCellUtil.getTags(decodedCell); 583 assertEquals(0, decodedTags.size()); 584 } 585 586 /** 587 * Used to confirm that we only consider truncatedMessage as EOF 588 */ 589 @Test 590 public void testIsEOF() throws Exception { 591 for (Method method : InvalidProtocolBufferException.class.getDeclaredMethods()) { 592 if ( 593 method.getParameterCount() == 0 594 && method.getReturnType() == InvalidProtocolBufferException.class 595 ) { 596 method.setAccessible(true); 597 InvalidProtocolBufferException e = (InvalidProtocolBufferException) method.invoke(null); 598 assertEquals(method.getName().equals("truncatedMessage"), ProtobufUtil.isEOF(e)); 599 } 600 } 601 } 602 603 @Test 604 public void testSlowLogParamsMutationProto() { 605 MutationProto mutationProto = 606 ClientProtos.MutationProto.newBuilder().setRow(ByteString.copyFromUtf8("row123")).build(); 607 608 SlowLogParams slowLogParams = ProtobufUtil.getSlowLogParams(mutationProto, false); 609 610 assertTrue(slowLogParams.getParams() 611 .contains(Bytes.toStringBinary(mutationProto.getRow().toByteArray()))); 612 } 613 614 @Test 615 public void testSlowLogParamsMutateRequest() { 616 MutationProto mutationProto = 617 ClientProtos.MutationProto.newBuilder().setRow(ByteString.copyFromUtf8("row123")).build(); 618 ClientProtos.MutateRequest mutateRequest = 619 ClientProtos.MutateRequest.newBuilder().setMutation(mutationProto) 620 .setRegion(HBaseProtos.RegionSpecifier.newBuilder() 621 .setType(HBaseProtos.RegionSpecifier.RegionSpecifierType.REGION_NAME) 622 .setValue(ByteString.EMPTY).build()) 623 .build(); 624 625 SlowLogParams slowLogParams = ProtobufUtil.getSlowLogParams(mutateRequest, false); 626 627 assertTrue(slowLogParams.getParams() 628 .contains(Bytes.toStringBinary(mutationProto.getRow().toByteArray()))); 629 } 630 631 @Test 632 public void testGetShortTextFormatNull() { 633 String actual = ProtobufUtil.getShortTextFormat(null); 634 assertNotNull(actual); 635 assertEquals("null", actual); 636 } 637 638 @Test 639 public void testGetShortTextFormatScanRequest() { 640 ClientProtos.ScanRequest.Builder builder = ClientProtos.ScanRequest.newBuilder(); 641 builder.setRegion(REGION); 642 ClientProtos.ScanRequest scanRequest = builder.build(); 643 644 String actual = ProtobufUtil.getShortTextFormat(scanRequest); 645 646 assertNotNull(actual); 647 assertEquals("region { type: REGION_NAME value: \"test\" }", actual); 648 } 649 650 @Test 651 public void testGetShortTextFormatRegionServerReportRequest() { 652 RegionServerStatusProtos.RegionServerReportRequest.Builder builder = 653 RegionServerStatusProtos.RegionServerReportRequest.newBuilder(); 654 builder.setServer(SERVER_NAME); 655 RegionServerStatusProtos.RegionServerReportRequest request = builder.build(); 656 657 String actual = ProtobufUtil.getShortTextFormat(request); 658 659 assertNotNull(actual); 660 assertEquals("server host_name: \"a.b.com\" load { numberOfRequests: 0 }", actual); 661 } 662 663 @Test 664 public void testGetShortTextFormatRegionServerStartupRequest() { 665 RegionServerStatusProtos.RegionServerStartupRequest.Builder builder = 666 RegionServerStatusProtos.RegionServerStartupRequest.newBuilder(); 667 builder.setPort(8080); 668 builder.setServerCurrentTime(111111L); 669 builder.setServerStartCode(15L); 670 builder.setUseThisHostnameInstead("some-host-name"); 671 RegionServerStatusProtos.RegionServerStartupRequest regionServerStartupRequest = 672 builder.build(); 673 674 String actual = ProtobufUtil.getShortTextFormat(regionServerStartupRequest); 675 676 assertNotNull(actual); 677 assertEquals("port: 8080 server_start_code: 15 server_current_time: 111111" 678 + " use_this_hostname_instead: \"some-host-name\"", actual); 679 } 680 681 @Test 682 public void testGetShortTextFormatMutationProto() { 683 MutationProto mutationProto = 684 ClientProtos.MutationProto.newBuilder().setRow(ByteString.copyFromUtf8("row123")).build(); 685 686 String actual = ProtobufUtil.getShortTextFormat(mutationProto); 687 688 assertNotNull(actual); 689 assertEquals("row=row123, type=APPEND", actual); 690 } 691 692 @Test 693 public void testGetShortTextFormatGetRequest() throws IOException { 694 ClientProtos.GetRequest getRequest = ClientProtos.GetRequest.newBuilder().setRegion(REGION) 695 .setGet(ProtobufUtil.toGet(new Get(Bytes.toBytes("foo")))).build(); 696 697 String actual = ProtobufUtil.getShortTextFormat(getRequest); 698 699 assertNotNull(actual); 700 assertEquals("region= test, row=foo", actual); 701 } 702 703 @Test 704 public void testGetShortTextFormatMultiRequest() throws IOException { 705 ClientProtos.Action action = ClientProtos.Action.newBuilder() 706 .setGet(ProtobufUtil.toGet(new Get(Bytes.toBytes("foo")))).build(); 707 ClientProtos.RegionAction regionAction = 708 ClientProtos.RegionAction.newBuilder().addAction(action).setRegion(REGION).build(); 709 710 ClientProtos.MultiRequest multiRequest = 711 ClientProtos.MultiRequest.newBuilder().addRegionAction(regionAction).build(); 712 713 String actual = ProtobufUtil.getShortTextFormat(multiRequest); 714 715 assertNotNull(actual); 716 assertEquals("region= test, for 1 action(s) and 1st row key=foo", actual); 717 } 718 719 @Test 720 public void testGetShortTextFormatMutateRequest() throws IOException { 721 ClientProtos.MutateRequest mutateRequest = ClientProtos.MutateRequest.newBuilder() 722 .setMutation( 723 ProtobufUtil.toMutation(MutationType.INCREMENT, new Increment(Bytes.toBytes("foo")))) 724 .setRegion(REGION).build(); 725 726 String actual = ProtobufUtil.getShortTextFormat(mutateRequest); 727 728 assertNotNull(actual); 729 assertEquals("region= test, row=foo", actual); 730 } 731 732 @Test 733 public void testGetShortTextFormatCoprocessorServiceRequest() { 734 ClientProtos.CoprocessorServiceCall call = ClientProtos.CoprocessorServiceCall.newBuilder() 735 .setRow(ByteString.copyFrom(Bytes.toBytes("foo"))).setMethodName("awesomeMethod") 736 .setServiceName("awesomeService") 737 .setRequest(ByteString.copyFrom(Bytes.toBytes("foo-request"))).build(); 738 739 ClientProtos.CoprocessorServiceRequest.Builder builder = 740 ClientProtos.CoprocessorServiceRequest.newBuilder(); 741 builder.setRegion(REGION); 742 builder.setCall(call); 743 ClientProtos.CoprocessorServiceRequest coprocessorServiceRequest = builder.build(); 744 745 String actual = ProtobufUtil.getShortTextFormat(coprocessorServiceRequest); 746 747 assertNotNull(actual); 748 assertEquals("coprocessorService= awesomeService:awesomeMethod", actual); 749 } 750 751 @Test 752 public void testGetShortTextFormatMoveRegionRequest() { 753 MasterProtos.MoveRegionRequest.Builder builder = MasterProtos.MoveRegionRequest.newBuilder(); 754 builder.setRegion(REGION); 755 builder.setDestServerName(SERVER_NAME); 756 MasterProtos.MoveRegionRequest moveRegionRequest = builder.build(); 757 758 String actual = ProtobufUtil.getShortTextFormat(moveRegionRequest); 759 760 assertNotNull(actual); 761 assertEquals( 762 "region { type: REGION_NAME value: \"test\" } dest_server_name { host_name: \"a.b.com\" }", 763 actual); 764 } 765}