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 java.io.ByteArrayOutputStream; 021import java.io.IOException; 022import java.io.InputStream; 023import java.lang.reflect.Constructor; 024import java.lang.reflect.Method; 025import java.nio.ByteBuffer; 026import java.security.AccessController; 027import java.security.PrivilegedAction; 028import java.util.ArrayList; 029import java.util.Collections; 030import java.util.List; 031import java.util.Locale; 032import java.util.Map; 033import java.util.Map.Entry; 034import java.util.NavigableSet; 035import java.util.Optional; 036import java.util.concurrent.Callable; 037import java.util.concurrent.TimeUnit; 038import java.util.function.Function; 039import java.util.regex.Pattern; 040import java.util.stream.Collectors; 041 042import org.apache.commons.io.input.BoundedInputStream; 043import org.apache.hadoop.conf.Configuration; 044import org.apache.hadoop.fs.Path; 045import org.apache.hadoop.hbase.ByteBufferExtendedCell; 046import org.apache.hadoop.hbase.CacheEvictionStats; 047import org.apache.hadoop.hbase.CacheEvictionStatsBuilder; 048import org.apache.hadoop.hbase.Cell; 049import org.apache.hadoop.hbase.Cell.Type; 050import org.apache.hadoop.hbase.CellBuilderType; 051import org.apache.hadoop.hbase.CellScanner; 052import org.apache.hadoop.hbase.CellUtil; 053import org.apache.hadoop.hbase.DoNotRetryIOException; 054import org.apache.hadoop.hbase.ExtendedCellBuilder; 055import org.apache.hadoop.hbase.ExtendedCellBuilderFactory; 056import org.apache.hadoop.hbase.HBaseConfiguration; 057import org.apache.hadoop.hbase.HBaseIOException; 058import org.apache.hadoop.hbase.HConstants; 059import org.apache.hadoop.hbase.HRegionLocation; 060import org.apache.hadoop.hbase.KeyValue; 061import org.apache.hadoop.hbase.NamespaceDescriptor; 062import org.apache.hadoop.hbase.ServerName; 063import org.apache.hadoop.hbase.TableName; 064import org.apache.hadoop.hbase.client.Append; 065import org.apache.hadoop.hbase.client.ClientUtil; 066import org.apache.hadoop.hbase.client.ColumnFamilyDescriptor; 067import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder; 068import org.apache.hadoop.hbase.client.CompactionState; 069import org.apache.hadoop.hbase.client.Consistency; 070import org.apache.hadoop.hbase.client.Cursor; 071import org.apache.hadoop.hbase.client.Delete; 072import org.apache.hadoop.hbase.client.Durability; 073import org.apache.hadoop.hbase.client.Get; 074import org.apache.hadoop.hbase.client.Increment; 075import org.apache.hadoop.hbase.client.Mutation; 076import org.apache.hadoop.hbase.client.PackagePrivateFieldAccessor; 077import org.apache.hadoop.hbase.client.Put; 078import org.apache.hadoop.hbase.client.RegionInfoBuilder; 079import org.apache.hadoop.hbase.client.RegionLoadStats; 080import org.apache.hadoop.hbase.client.Result; 081import org.apache.hadoop.hbase.client.Scan; 082import org.apache.hadoop.hbase.client.SnapshotDescription; 083import org.apache.hadoop.hbase.client.SnapshotType; 084import org.apache.hadoop.hbase.client.TableDescriptor; 085import org.apache.hadoop.hbase.client.TableDescriptorBuilder; 086import org.apache.hadoop.hbase.client.metrics.ScanMetrics; 087import org.apache.hadoop.hbase.client.security.SecurityCapability; 088import org.apache.hadoop.hbase.exceptions.DeserializationException; 089import org.apache.hadoop.hbase.filter.ByteArrayComparable; 090import org.apache.hadoop.hbase.filter.Filter; 091import org.apache.hadoop.hbase.io.TimeRange; 092import org.apache.hadoop.hbase.protobuf.ProtobufMagic; 093import org.apache.hadoop.hbase.protobuf.ProtobufMessageConverter; 094import org.apache.hadoop.hbase.quotas.QuotaScope; 095import org.apache.hadoop.hbase.quotas.QuotaType; 096import org.apache.hadoop.hbase.quotas.SpaceViolationPolicy; 097import org.apache.hadoop.hbase.quotas.ThrottleType; 098import org.apache.hadoop.hbase.replication.ReplicationLoadSink; 099import org.apache.hadoop.hbase.replication.ReplicationLoadSource; 100import org.apache.hadoop.hbase.security.visibility.Authorizations; 101import org.apache.hadoop.hbase.security.visibility.CellVisibility; 102import org.apache.hadoop.hbase.util.Addressing; 103import org.apache.hadoop.hbase.util.Bytes; 104import org.apache.hadoop.hbase.util.DynamicClassLoader; 105import org.apache.hadoop.hbase.util.ExceptionUtil; 106import org.apache.hadoop.hbase.util.Methods; 107import org.apache.hadoop.hbase.util.VersionInfo; 108import org.apache.hadoop.ipc.RemoteException; 109import org.apache.yetus.audience.InterfaceAudience; 110 111import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting; 112import org.apache.hbase.thirdparty.com.google.common.io.ByteStreams; 113import org.apache.hbase.thirdparty.com.google.gson.JsonArray; 114import org.apache.hbase.thirdparty.com.google.gson.JsonElement; 115import org.apache.hbase.thirdparty.com.google.protobuf.ByteString; 116import org.apache.hbase.thirdparty.com.google.protobuf.CodedInputStream; 117import org.apache.hbase.thirdparty.com.google.protobuf.InvalidProtocolBufferException; 118import org.apache.hbase.thirdparty.com.google.protobuf.Message; 119import org.apache.hbase.thirdparty.com.google.protobuf.RpcChannel; 120import org.apache.hbase.thirdparty.com.google.protobuf.RpcController; 121import org.apache.hbase.thirdparty.com.google.protobuf.Service; 122import org.apache.hbase.thirdparty.com.google.protobuf.ServiceException; 123import org.apache.hbase.thirdparty.com.google.protobuf.TextFormat; 124import org.apache.hbase.thirdparty.com.google.protobuf.UnsafeByteOperations; 125import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.AdminService; 126import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.CloseRegionRequest; 127import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.GetOnlineRegionRequest; 128import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.GetOnlineRegionResponse; 129import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.GetRegionInfoRequest; 130import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.GetRegionInfoResponse; 131import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.GetRegionLoadResponse; 132import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.GetServerInfoRequest; 133import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.GetServerInfoResponse; 134import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.GetStoreFileRequest; 135import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.GetStoreFileResponse; 136import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.OpenRegionRequest; 137import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.ServerInfo; 138import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.WarmupRegionRequest; 139import org.apache.hadoop.hbase.shaded.protobuf.generated.CellProtos; 140import org.apache.hadoop.hbase.shaded.protobuf.generated.ClientProtos; 141import org.apache.hadoop.hbase.shaded.protobuf.generated.ClientProtos.Column; 142import org.apache.hadoop.hbase.shaded.protobuf.generated.ClientProtos.GetRequest; 143import org.apache.hadoop.hbase.shaded.protobuf.generated.ClientProtos.MutationProto; 144import org.apache.hadoop.hbase.shaded.protobuf.generated.ClientProtos.MutationProto.ColumnValue; 145import org.apache.hadoop.hbase.shaded.protobuf.generated.ClientProtos.MutationProto.ColumnValue.QualifierValue; 146import org.apache.hadoop.hbase.shaded.protobuf.generated.ClientProtos.MutationProto.DeleteType; 147import org.apache.hadoop.hbase.shaded.protobuf.generated.ClientProtos.MutationProto.MutationType; 148import org.apache.hadoop.hbase.shaded.protobuf.generated.ClientProtos.ScanRequest; 149import org.apache.hadoop.hbase.shaded.protobuf.generated.ClusterStatusProtos; 150import org.apache.hadoop.hbase.shaded.protobuf.generated.ClusterStatusProtos.RegionLoad; 151import org.apache.hadoop.hbase.shaded.protobuf.generated.ComparatorProtos; 152import org.apache.hadoop.hbase.shaded.protobuf.generated.FilterProtos; 153import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos; 154import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos.BytesBytesPair; 155import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos.ColumnFamilySchema; 156import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos.NameBytesPair; 157import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos.NameStringPair; 158import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos.ProcedureDescription; 159import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos.RegionExceptionMessage; 160import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos.RegionInfo; 161import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos.RegionSpecifier; 162import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos.RegionSpecifier.RegionSpecifierType; 163import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos.TableSchema; 164import org.apache.hadoop.hbase.shaded.protobuf.generated.LockServiceProtos; 165import org.apache.hadoop.hbase.shaded.protobuf.generated.MapReduceProtos; 166import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos; 167import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.CreateTableRequest; 168import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.GetCompletedSnapshotsResponse; 169import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.GetTableDescriptorsResponse; 170import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ListNamespaceDescriptorsResponse; 171import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ListTableDescriptorsByNamespaceResponse; 172import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.MajorCompactionTimestampResponse; 173import org.apache.hadoop.hbase.shaded.protobuf.generated.ProcedureProtos; 174import org.apache.hadoop.hbase.shaded.protobuf.generated.QuotaProtos; 175import org.apache.hadoop.hbase.shaded.protobuf.generated.RegionServerStatusProtos.RegionServerReportRequest; 176import org.apache.hadoop.hbase.shaded.protobuf.generated.RegionServerStatusProtos.RegionServerStartupRequest; 177import org.apache.hadoop.hbase.shaded.protobuf.generated.SnapshotProtos; 178import org.apache.hadoop.hbase.shaded.protobuf.generated.WALProtos; 179import org.apache.hadoop.hbase.shaded.protobuf.generated.WALProtos.BulkLoadDescriptor; 180import org.apache.hadoop.hbase.shaded.protobuf.generated.WALProtos.CompactionDescriptor; 181import org.apache.hadoop.hbase.shaded.protobuf.generated.WALProtos.FlushDescriptor; 182import org.apache.hadoop.hbase.shaded.protobuf.generated.WALProtos.FlushDescriptor.FlushAction; 183import org.apache.hadoop.hbase.shaded.protobuf.generated.WALProtos.RegionEventDescriptor; 184import org.apache.hadoop.hbase.shaded.protobuf.generated.WALProtos.RegionEventDescriptor.EventType; 185import org.apache.hadoop.hbase.shaded.protobuf.generated.WALProtos.StoreDescriptor; 186import org.apache.hadoop.hbase.shaded.protobuf.generated.ZooKeeperProtos; 187 188/** 189 * Protobufs utility. 190 * Be aware that a class named org.apache.hadoop.hbase.protobuf.ProtobufUtil (i.e. no 'shaded' in 191 * the package name) carries a COPY of a subset of this class for non-shaded 192 * users; e.g. Coprocessor Endpoints. If you make change in here, be sure to make change in 193 * the companion class too (not the end of the world, especially if you are adding new functionality 194 * but something to be aware of. 195 * @see ProtobufUtil 196 */ 197// TODO: Generate the non-shaded protobufutil from this one. 198@InterfaceAudience.Private // TODO: some clients (Hive, etc) use this class 199public final class ProtobufUtil { 200 private ProtobufUtil() { 201 } 202 203 /** 204 * Many results are simple: no cell, exists true or false. To save on object creations, 205 * we reuse them across calls. 206 */ 207 private final static Cell[] EMPTY_CELL_ARRAY = new Cell[]{}; 208 private final static Result EMPTY_RESULT = Result.create(EMPTY_CELL_ARRAY); 209 final static Result EMPTY_RESULT_EXISTS_TRUE = Result.create(null, true); 210 final static Result EMPTY_RESULT_EXISTS_FALSE = Result.create(null, false); 211 private final static Result EMPTY_RESULT_STALE = Result.create(EMPTY_CELL_ARRAY, null, true); 212 private final static Result EMPTY_RESULT_EXISTS_TRUE_STALE 213 = Result.create((Cell[])null, true, true); 214 private final static Result EMPTY_RESULT_EXISTS_FALSE_STALE 215 = Result.create((Cell[])null, false, true); 216 217 private final static ClientProtos.Result EMPTY_RESULT_PB; 218 private final static ClientProtos.Result EMPTY_RESULT_PB_EXISTS_TRUE; 219 private final static ClientProtos.Result EMPTY_RESULT_PB_EXISTS_FALSE; 220 private final static ClientProtos.Result EMPTY_RESULT_PB_STALE; 221 private final static ClientProtos.Result EMPTY_RESULT_PB_EXISTS_TRUE_STALE; 222 private final static ClientProtos.Result EMPTY_RESULT_PB_EXISTS_FALSE_STALE; 223 224 225 static { 226 ClientProtos.Result.Builder builder = ClientProtos.Result.newBuilder(); 227 228 builder.setExists(true); 229 builder.setAssociatedCellCount(0); 230 EMPTY_RESULT_PB_EXISTS_TRUE = builder.build(); 231 232 builder.setStale(true); 233 EMPTY_RESULT_PB_EXISTS_TRUE_STALE = builder.build(); 234 builder.clear(); 235 236 builder.setExists(false); 237 builder.setAssociatedCellCount(0); 238 EMPTY_RESULT_PB_EXISTS_FALSE = builder.build(); 239 builder.setStale(true); 240 EMPTY_RESULT_PB_EXISTS_FALSE_STALE = builder.build(); 241 242 builder.clear(); 243 builder.setAssociatedCellCount(0); 244 EMPTY_RESULT_PB = builder.build(); 245 builder.setStale(true); 246 EMPTY_RESULT_PB_STALE = builder.build(); 247 } 248 249 private static volatile boolean classLoaderLoaded = false; 250 251 /** 252 * Dynamic class loader to load filter/comparators 253 */ 254 private final static class ClassLoaderHolder { 255 private final static ClassLoader CLASS_LOADER; 256 257 static { 258 ClassLoader parent = ProtobufUtil.class.getClassLoader(); 259 Configuration conf = HBaseConfiguration.create(); 260 CLASS_LOADER = AccessController.doPrivileged((PrivilegedAction<ClassLoader>) 261 () -> new DynamicClassLoader(conf, parent) 262 ); 263 classLoaderLoaded = true; 264 } 265 } 266 267 @VisibleForTesting 268 public static boolean isClassLoaderLoaded() { 269 return classLoaderLoaded; 270 } 271 272 /** 273 * Prepend the passed bytes with four bytes of magic, {@link ProtobufMagic#PB_MAGIC}, 274 * to flag what follows as a protobuf in hbase. Prepend these bytes to all content written to 275 * znodes, etc. 276 * @param bytes Bytes to decorate 277 * @return The passed <code>bytes</code> with magic prepended (Creates a new 278 * byte array that is <code>bytes.length</code> plus {@link ProtobufMagic#PB_MAGIC}.length. 279 */ 280 public static byte [] prependPBMagic(final byte [] bytes) { 281 return Bytes.add(ProtobufMagic.PB_MAGIC, bytes); 282 } 283 284 /** 285 * @param bytes Bytes to check. 286 * @return True if passed <code>bytes</code> has {@link ProtobufMagic#PB_MAGIC} for a prefix. 287 */ 288 public static boolean isPBMagicPrefix(final byte [] bytes) { 289 return ProtobufMagic.isPBMagicPrefix(bytes); 290 } 291 292 /** 293 * @param bytes Bytes to check. 294 * @param offset offset to start at 295 * @param len length to use 296 * @return True if passed <code>bytes</code> has {@link ProtobufMagic#PB_MAGIC} for a prefix. 297 */ 298 public static boolean isPBMagicPrefix(final byte [] bytes, int offset, int len) { 299 return ProtobufMagic.isPBMagicPrefix(bytes, offset, len); 300 } 301 302 /** 303 * @param bytes bytes to check 304 * @throws DeserializationException if we are missing the pb magic prefix 305 */ 306 public static void expectPBMagicPrefix(final byte [] bytes) throws DeserializationException { 307 if (!isPBMagicPrefix(bytes)) { 308 throw new DeserializationException("Missing pb magic " + 309 Bytes.toString(ProtobufMagic.PB_MAGIC) + " prefix"); 310 } 311 } 312 313 /** 314 * @return Length of {@link ProtobufMagic#lengthOfPBMagic()} 315 */ 316 public static int lengthOfPBMagic() { 317 return ProtobufMagic.lengthOfPBMagic(); 318 } 319 320 public static ComparatorProtos.ByteArrayComparable toByteArrayComparable(final byte [] value) { 321 ComparatorProtos.ByteArrayComparable.Builder builder = 322 ComparatorProtos.ByteArrayComparable.newBuilder(); 323 if (value != null) builder.setValue(UnsafeByteOperations.unsafeWrap(value)); 324 return builder.build(); 325 } 326 327 /** 328 * Return the IOException thrown by the remote server wrapped in 329 * ServiceException as cause. 330 * 331 * @param se ServiceException that wraps IO exception thrown by the server 332 * @return Exception wrapped in ServiceException or 333 * a new IOException that wraps the unexpected ServiceException. 334 */ 335 public static IOException getRemoteException(ServiceException se) { 336 return makeIOExceptionOfException(se); 337 } 338 339 /** 340 * Like {@link #getRemoteException(ServiceException)} but more generic, able to handle more than 341 * just {@link ServiceException}. Prefer this method to 342 * {@link #getRemoteException(ServiceException)} because trying to 343 * contain direct protobuf references. 344 * @param e 345 */ 346 public static IOException handleRemoteException(Exception e) { 347 return makeIOExceptionOfException(e); 348 } 349 350 private static IOException makeIOExceptionOfException(Exception e) { 351 Throwable t = e; 352 if (e instanceof ServiceException) { 353 t = e.getCause(); 354 } 355 if (ExceptionUtil.isInterrupt(t)) { 356 return ExceptionUtil.asInterrupt(t); 357 } 358 if (t instanceof RemoteException) { 359 t = ((RemoteException)t).unwrapRemoteException(); 360 } 361 return t instanceof IOException? (IOException)t: new HBaseIOException(t); 362 } 363 364 /** 365 * Convert a ServerName to a protocol buffer ServerName 366 * 367 * @param serverName the ServerName to convert 368 * @return the converted protocol buffer ServerName 369 * @see #toServerName(org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos.ServerName) 370 */ 371 public static HBaseProtos.ServerName toServerName(final ServerName serverName) { 372 if (serverName == null) return null; 373 HBaseProtos.ServerName.Builder builder = 374 HBaseProtos.ServerName.newBuilder(); 375 builder.setHostName(serverName.getHostname()); 376 if (serverName.getPort() >= 0) { 377 builder.setPort(serverName.getPort()); 378 } 379 if (serverName.getStartcode() >= 0) { 380 builder.setStartCode(serverName.getStartcode()); 381 } 382 return builder.build(); 383 } 384 385 /** 386 * Convert a protocol buffer ServerName to a ServerName 387 * 388 * @param proto the protocol buffer ServerName to convert 389 * @return the converted ServerName 390 */ 391 public static ServerName toServerName(final HBaseProtos.ServerName proto) { 392 if (proto == null) return null; 393 String hostName = proto.getHostName(); 394 long startCode = -1; 395 int port = -1; 396 if (proto.hasPort()) { 397 port = proto.getPort(); 398 } 399 if (proto.hasStartCode()) { 400 startCode = proto.getStartCode(); 401 } 402 return ServerName.valueOf(hostName, port, startCode); 403 } 404 405 /** 406 * Convert a list of protocol buffer ServerName to a list of ServerName 407 * @param proto protocol buffer ServerNameList 408 * @return a list of ServerName 409 */ 410 public static List<ServerName> toServerNameList( 411 List<HBaseProtos.ServerName> proto) { 412 return proto.stream().map(ProtobufUtil::toServerName) 413 .collect(Collectors.toList()); 414 } 415 416 /** 417 * Get a list of NamespaceDescriptor from ListNamespaceDescriptorsResponse protobuf 418 * @param proto the ListNamespaceDescriptorsResponse 419 * @return a list of NamespaceDescriptor 420 */ 421 public static List<NamespaceDescriptor> toNamespaceDescriptorList( 422 ListNamespaceDescriptorsResponse proto) { 423 return proto.getNamespaceDescriptorList().stream().map(ProtobufUtil::toNamespaceDescriptor) 424 .collect(Collectors.toList()); 425 } 426 427 /** 428 * Get a list of TableDescriptor from GetTableDescriptorsResponse protobuf 429 * @param proto the GetTableDescriptorsResponse 430 * @return a list of TableDescriptor 431 */ 432 public static List<TableDescriptor> toTableDescriptorList(GetTableDescriptorsResponse proto) { 433 if (proto == null) { 434 return new ArrayList<>(); 435 } 436 return proto.getTableSchemaList().stream().map(ProtobufUtil::toTableDescriptor) 437 .collect(Collectors.toList()); 438 } 439 440 /** 441 * Get a list of TableDescriptor from ListTableDescriptorsByNamespaceResponse protobuf 442 * @param proto the ListTableDescriptorsByNamespaceResponse 443 * @return a list of TableDescriptor 444 */ 445 public static List<TableDescriptor> 446 toTableDescriptorList(ListTableDescriptorsByNamespaceResponse proto) { 447 if (proto == null) return new ArrayList<>(); 448 return proto.getTableSchemaList().stream().map(ProtobufUtil::toTableDescriptor) 449 .collect(Collectors.toList()); 450 } 451 452 /** 453 * get the split keys in form "byte [][]" from a CreateTableRequest proto 454 * 455 * @param proto the CreateTableRequest 456 * @return the split keys 457 */ 458 public static byte [][] getSplitKeysArray(final CreateTableRequest proto) { 459 byte [][] splitKeys = new byte[proto.getSplitKeysCount()][]; 460 for (int i = 0; i < proto.getSplitKeysCount(); ++i) { 461 splitKeys[i] = proto.getSplitKeys(i).toByteArray(); 462 } 463 return splitKeys; 464 } 465 466 /** 467 * Convert a protobuf Durability into a client Durability 468 */ 469 public static Durability toDurability( 470 final ClientProtos.MutationProto.Durability proto) { 471 switch(proto) { 472 case USE_DEFAULT: 473 return Durability.USE_DEFAULT; 474 case SKIP_WAL: 475 return Durability.SKIP_WAL; 476 case ASYNC_WAL: 477 return Durability.ASYNC_WAL; 478 case SYNC_WAL: 479 return Durability.SYNC_WAL; 480 case FSYNC_WAL: 481 return Durability.FSYNC_WAL; 482 default: 483 return Durability.USE_DEFAULT; 484 } 485 } 486 487 /** 488 * Convert a client Durability into a protbuf Durability 489 */ 490 public static ClientProtos.MutationProto.Durability toDurability( 491 final Durability d) { 492 switch(d) { 493 case USE_DEFAULT: 494 return ClientProtos.MutationProto.Durability.USE_DEFAULT; 495 case SKIP_WAL: 496 return ClientProtos.MutationProto.Durability.SKIP_WAL; 497 case ASYNC_WAL: 498 return ClientProtos.MutationProto.Durability.ASYNC_WAL; 499 case SYNC_WAL: 500 return ClientProtos.MutationProto.Durability.SYNC_WAL; 501 case FSYNC_WAL: 502 return ClientProtos.MutationProto.Durability.FSYNC_WAL; 503 default: 504 return ClientProtos.MutationProto.Durability.USE_DEFAULT; 505 } 506 } 507 508 /** 509 * Convert a protocol buffer Get to a client Get 510 * 511 * @param proto the protocol buffer Get to convert 512 * @return the converted client Get 513 * @throws IOException 514 */ 515 public static Get toGet(final ClientProtos.Get proto) throws IOException { 516 if (proto == null) return null; 517 byte[] row = proto.getRow().toByteArray(); 518 Get get = new Get(row); 519 if (proto.hasCacheBlocks()) { 520 get.setCacheBlocks(proto.getCacheBlocks()); 521 } 522 if (proto.hasMaxVersions()) { 523 get.setMaxVersions(proto.getMaxVersions()); 524 } 525 if (proto.hasStoreLimit()) { 526 get.setMaxResultsPerColumnFamily(proto.getStoreLimit()); 527 } 528 if (proto.hasStoreOffset()) { 529 get.setRowOffsetPerColumnFamily(proto.getStoreOffset()); 530 } 531 if (proto.getCfTimeRangeCount() > 0) { 532 for (HBaseProtos.ColumnFamilyTimeRange cftr : proto.getCfTimeRangeList()) { 533 TimeRange timeRange = toTimeRange(cftr.getTimeRange()); 534 get.setColumnFamilyTimeRange(cftr.getColumnFamily().toByteArray(), 535 timeRange.getMin(), timeRange.getMax()); 536 } 537 } 538 if (proto.hasTimeRange()) { 539 TimeRange timeRange = toTimeRange(proto.getTimeRange()); 540 get.setTimeRange(timeRange.getMin(), timeRange.getMax()); 541 } 542 if (proto.hasFilter()) { 543 FilterProtos.Filter filter = proto.getFilter(); 544 get.setFilter(ProtobufUtil.toFilter(filter)); 545 } 546 for (NameBytesPair attribute: proto.getAttributeList()) { 547 get.setAttribute(attribute.getName(), attribute.getValue().toByteArray()); 548 } 549 if (proto.getColumnCount() > 0) { 550 for (Column column: proto.getColumnList()) { 551 byte[] family = column.getFamily().toByteArray(); 552 if (column.getQualifierCount() > 0) { 553 for (ByteString qualifier: column.getQualifierList()) { 554 get.addColumn(family, qualifier.toByteArray()); 555 } 556 } else { 557 get.addFamily(family); 558 } 559 } 560 } 561 if (proto.hasExistenceOnly() && proto.getExistenceOnly()){ 562 get.setCheckExistenceOnly(true); 563 } 564 if (proto.hasConsistency()) { 565 get.setConsistency(toConsistency(proto.getConsistency())); 566 } 567 if (proto.hasLoadColumnFamiliesOnDemand()) { 568 get.setLoadColumnFamiliesOnDemand(proto.getLoadColumnFamiliesOnDemand()); 569 } 570 return get; 571 } 572 573 public static Consistency toConsistency(ClientProtos.Consistency consistency) { 574 switch (consistency) { 575 case STRONG : return Consistency.STRONG; 576 case TIMELINE : return Consistency.TIMELINE; 577 default : return Consistency.STRONG; 578 } 579 } 580 581 public static ClientProtos.Consistency toConsistency(Consistency consistency) { 582 switch (consistency) { 583 case STRONG : return ClientProtos.Consistency.STRONG; 584 case TIMELINE : return ClientProtos.Consistency.TIMELINE; 585 default : return ClientProtos.Consistency.STRONG; 586 } 587 } 588 589 /** 590 * Convert a protocol buffer Mutate to a Put. 591 * 592 * @param proto The protocol buffer MutationProto to convert 593 * @return A client Put. 594 * @throws IOException 595 */ 596 public static Put toPut(final MutationProto proto) 597 throws IOException { 598 return toPut(proto, null); 599 } 600 601 /** 602 * Convert a protocol buffer Mutate to a Put. 603 * 604 * @param proto The protocol buffer MutationProto to convert 605 * @param cellScanner If non-null, the Cell data that goes with this proto. 606 * @return A client Put. 607 * @throws IOException 608 */ 609 public static Put toPut(final MutationProto proto, final CellScanner cellScanner) 610 throws IOException { 611 // TODO: Server-side at least why do we convert back to the Client types? Why not just pb it? 612 MutationType type = proto.getMutateType(); 613 assert type == MutationType.PUT: type.name(); 614 long timestamp = proto.hasTimestamp()? proto.getTimestamp(): HConstants.LATEST_TIMESTAMP; 615 Put put = proto.hasRow() ? new Put(proto.getRow().toByteArray(), timestamp) : null; 616 int cellCount = proto.hasAssociatedCellCount()? proto.getAssociatedCellCount(): 0; 617 if (cellCount > 0) { 618 // The proto has metadata only and the data is separate to be found in the cellScanner. 619 if (cellScanner == null) { 620 throw new DoNotRetryIOException("Cell count of " + cellCount + " but no cellScanner: " + 621 toShortString(proto)); 622 } 623 for (int i = 0; i < cellCount; i++) { 624 if (!cellScanner.advance()) { 625 throw new DoNotRetryIOException("Cell count of " + cellCount + " but at index " + i + 626 " no cell returned: " + toShortString(proto)); 627 } 628 Cell cell = cellScanner.current(); 629 if (put == null) { 630 put = new Put(cell.getRowArray(), cell.getRowOffset(), cell.getRowLength(), timestamp); 631 } 632 put.add(cell); 633 } 634 } else { 635 if (put == null) { 636 throw new IllegalArgumentException("row cannot be null"); 637 } 638 // The proto has the metadata and the data itself 639 ExtendedCellBuilder cellBuilder = ExtendedCellBuilderFactory.create(CellBuilderType.SHALLOW_COPY); 640 for (ColumnValue column: proto.getColumnValueList()) { 641 byte[] family = column.getFamily().toByteArray(); 642 for (QualifierValue qv: column.getQualifierValueList()) { 643 if (!qv.hasValue()) { 644 throw new DoNotRetryIOException( 645 "Missing required field: qualifier value"); 646 } 647 long ts = timestamp; 648 if (qv.hasTimestamp()) { 649 ts = qv.getTimestamp(); 650 } 651 byte[] allTagsBytes; 652 if (qv.hasTags()) { 653 allTagsBytes = qv.getTags().toByteArray(); 654 if(qv.hasDeleteType()) { 655 put.add(cellBuilder.clear() 656 .setRow(proto.getRow().toByteArray()) 657 .setFamily(family) 658 .setQualifier(qv.hasQualifier() ? qv.getQualifier().toByteArray() : null) 659 .setTimestamp(ts) 660 .setType(fromDeleteType(qv.getDeleteType()).getCode()) 661 .setTags(allTagsBytes) 662 .build()); 663 } else { 664 put.add(cellBuilder.clear() 665 .setRow(put.getRow()) 666 .setFamily(family) 667 .setQualifier(qv.hasQualifier() ? qv.getQualifier().toByteArray() : null) 668 .setTimestamp(ts) 669 .setType(Cell.Type.Put) 670 .setValue(qv.hasValue() ? qv.getValue().toByteArray() : null) 671 .setTags(allTagsBytes) 672 .build()); 673 } 674 } else { 675 if(qv.hasDeleteType()) { 676 put.add(cellBuilder.clear() 677 .setRow(put.getRow()) 678 .setFamily(family) 679 .setQualifier(qv.hasQualifier() ? qv.getQualifier().toByteArray() : null) 680 .setTimestamp(ts) 681 .setType(fromDeleteType(qv.getDeleteType()).getCode()) 682 .build()); 683 } else{ 684 put.add(cellBuilder.clear() 685 .setRow(put.getRow()) 686 .setFamily(family) 687 .setQualifier(qv.hasQualifier() ? qv.getQualifier().toByteArray() : null) 688 .setTimestamp(ts) 689 .setType(Type.Put) 690 .setValue(qv.hasValue() ? qv.getValue().toByteArray() : null) 691 .build()); 692 } 693 } 694 } 695 } 696 } 697 put.setDurability(toDurability(proto.getDurability())); 698 for (NameBytesPair attribute: proto.getAttributeList()) { 699 put.setAttribute(attribute.getName(), attribute.getValue().toByteArray()); 700 } 701 return put; 702 } 703 704 /** 705 * Convert a protocol buffer Mutate to a Delete 706 * 707 * @param proto the protocol buffer Mutate to convert 708 * @return the converted client Delete 709 * @throws IOException 710 */ 711 public static Delete toDelete(final MutationProto proto) 712 throws IOException { 713 return toDelete(proto, null); 714 } 715 716 /** 717 * Convert a protocol buffer Mutate to a Delete 718 * 719 * @param proto the protocol buffer Mutate to convert 720 * @param cellScanner if non-null, the data that goes with this delete. 721 * @return the converted client Delete 722 * @throws IOException 723 */ 724 public static Delete toDelete(final MutationProto proto, final CellScanner cellScanner) 725 throws IOException { 726 MutationType type = proto.getMutateType(); 727 assert type == MutationType.DELETE : type.name(); 728 long timestamp = proto.hasTimestamp() ? proto.getTimestamp() : HConstants.LATEST_TIMESTAMP; 729 Delete delete = proto.hasRow() ? new Delete(proto.getRow().toByteArray(), timestamp) : null; 730 int cellCount = proto.hasAssociatedCellCount()? proto.getAssociatedCellCount(): 0; 731 if (cellCount > 0) { 732 // The proto has metadata only and the data is separate to be found in the cellScanner. 733 if (cellScanner == null) { 734 // TextFormat should be fine for a Delete since it carries no data, just coordinates. 735 throw new DoNotRetryIOException("Cell count of " + cellCount + " but no cellScanner: " + 736 TextFormat.shortDebugString(proto)); 737 } 738 for (int i = 0; i < cellCount; i++) { 739 if (!cellScanner.advance()) { 740 // TextFormat should be fine for a Delete since it carries no data, just coordinates. 741 throw new DoNotRetryIOException("Cell count of " + cellCount + " but at index " + i + 742 " no cell returned: " + TextFormat.shortDebugString(proto)); 743 } 744 Cell cell = cellScanner.current(); 745 if (delete == null) { 746 delete = 747 new Delete(cell.getRowArray(), cell.getRowOffset(), cell.getRowLength(), timestamp); 748 } 749 delete.add(cell); 750 } 751 } else { 752 if (delete == null) { 753 throw new IllegalArgumentException("row cannot be null"); 754 } 755 for (ColumnValue column: proto.getColumnValueList()) { 756 byte[] family = column.getFamily().toByteArray(); 757 for (QualifierValue qv: column.getQualifierValueList()) { 758 DeleteType deleteType = qv.getDeleteType(); 759 byte[] qualifier = null; 760 if (qv.hasQualifier()) { 761 qualifier = qv.getQualifier().toByteArray(); 762 } 763 long ts = HConstants.LATEST_TIMESTAMP; 764 if (qv.hasTimestamp()) { 765 ts = qv.getTimestamp(); 766 } 767 if (deleteType == DeleteType.DELETE_ONE_VERSION) { 768 delete.addColumn(family, qualifier, ts); 769 } else if (deleteType == DeleteType.DELETE_MULTIPLE_VERSIONS) { 770 delete.addColumns(family, qualifier, ts); 771 } else if (deleteType == DeleteType.DELETE_FAMILY_VERSION) { 772 delete.addFamilyVersion(family, ts); 773 } else { 774 delete.addFamily(family, ts); 775 } 776 } 777 } 778 } 779 delete.setDurability(toDurability(proto.getDurability())); 780 for (NameBytesPair attribute: proto.getAttributeList()) { 781 delete.setAttribute(attribute.getName(), attribute.getValue().toByteArray()); 782 } 783 return delete; 784 } 785 @FunctionalInterface 786 private interface ConsumerWithException <T, U> { 787 void accept(T t, U u) throws IOException; 788 } 789 790 private static <T extends Mutation> T toDelta(Function<Bytes, T> supplier, ConsumerWithException<T, Cell> consumer, 791 final MutationProto proto, final CellScanner cellScanner) throws IOException { 792 byte[] row = proto.hasRow() ? proto.getRow().toByteArray() : null; 793 T mutation = row == null ? null : supplier.apply(new Bytes(row)); 794 int cellCount = proto.hasAssociatedCellCount() ? proto.getAssociatedCellCount() : 0; 795 if (cellCount > 0) { 796 // The proto has metadata only and the data is separate to be found in the cellScanner. 797 if (cellScanner == null) { 798 throw new DoNotRetryIOException("Cell count of " + cellCount + " but no cellScanner: " + 799 toShortString(proto)); 800 } 801 for (int i = 0; i < cellCount; i++) { 802 if (!cellScanner.advance()) { 803 throw new DoNotRetryIOException("Cell count of " + cellCount + " but at index " + i + 804 " no cell returned: " + toShortString(proto)); 805 } 806 Cell cell = cellScanner.current(); 807 if (mutation == null) { 808 mutation = supplier.apply(new Bytes(cell.getRowArray(), cell.getRowOffset(), cell.getRowLength())); 809 } 810 consumer.accept(mutation, cell); 811 } 812 } else { 813 if (mutation == null) { 814 throw new IllegalArgumentException("row cannot be null"); 815 } 816 for (ColumnValue column : proto.getColumnValueList()) { 817 byte[] family = column.getFamily().toByteArray(); 818 for (QualifierValue qv : column.getQualifierValueList()) { 819 byte[] qualifier = qv.getQualifier().toByteArray(); 820 if (!qv.hasValue()) { 821 throw new DoNotRetryIOException( 822 "Missing required field: qualifier value"); 823 } 824 byte[] value = qv.getValue().toByteArray(); 825 byte[] tags = null; 826 if (qv.hasTags()) { 827 tags = qv.getTags().toByteArray(); 828 } 829 consumer.accept(mutation, ExtendedCellBuilderFactory.create(CellBuilderType.SHALLOW_COPY) 830 .setRow(mutation.getRow()) 831 .setFamily(family) 832 .setQualifier(qualifier) 833 .setTimestamp(qv.getTimestamp()) 834 .setType(KeyValue.Type.Put.getCode()) 835 .setValue(value) 836 .setTags(tags) 837 .build()); 838 } 839 } 840 } 841 mutation.setDurability(toDurability(proto.getDurability())); 842 for (NameBytesPair attribute : proto.getAttributeList()) { 843 mutation.setAttribute(attribute.getName(), attribute.getValue().toByteArray()); 844 } 845 return mutation; 846 } 847 848 /** 849 * Convert a protocol buffer Mutate to an Append 850 * @param cellScanner 851 * @param proto the protocol buffer Mutate to convert 852 * @return the converted client Append 853 * @throws IOException 854 */ 855 public static Append toAppend(final MutationProto proto, final CellScanner cellScanner) 856 throws IOException { 857 MutationType type = proto.getMutateType(); 858 assert type == MutationType.APPEND : type.name(); 859 Append append = toDelta((Bytes row) -> new Append(row.get(), row.getOffset(), row.getLength()), 860 Append::add, proto, cellScanner); 861 if (proto.hasTimeRange()) { 862 TimeRange timeRange = toTimeRange(proto.getTimeRange()); 863 append.setTimeRange(timeRange.getMin(), timeRange.getMax()); 864 } 865 return append; 866 } 867 868 /** 869 * Convert a protocol buffer Mutate to an Increment 870 * 871 * @param proto the protocol buffer Mutate to convert 872 * @return the converted client Increment 873 * @throws IOException 874 */ 875 public static Increment toIncrement(final MutationProto proto, final CellScanner cellScanner) 876 throws IOException { 877 MutationType type = proto.getMutateType(); 878 assert type == MutationType.INCREMENT : type.name(); 879 Increment increment = toDelta((Bytes row) -> new Increment(row.get(), row.getOffset(), row.getLength()), 880 Increment::add, proto, cellScanner); 881 if (proto.hasTimeRange()) { 882 TimeRange timeRange = toTimeRange(proto.getTimeRange()); 883 increment.setTimeRange(timeRange.getMin(), timeRange.getMax()); 884 } 885 return increment; 886 } 887 888 /** 889 * Convert a MutateRequest to Mutation 890 * 891 * @param proto the protocol buffer Mutate to convert 892 * @return the converted Mutation 893 * @throws IOException 894 */ 895 public static Mutation toMutation(final MutationProto proto) throws IOException { 896 MutationType type = proto.getMutateType(); 897 if (type == MutationType.APPEND) { 898 return toAppend(proto, null); 899 } 900 if (type == MutationType.DELETE) { 901 return toDelete(proto, null); 902 } 903 if (type == MutationType.PUT) { 904 return toPut(proto, null); 905 } 906 throw new IOException("Unknown mutation type " + type); 907 } 908 909 /** 910 * Convert a protocol buffer Mutate to a Get. 911 * @param proto the protocol buffer Mutate to convert. 912 * @param cellScanner 913 * @return the converted client get. 914 * @throws IOException 915 */ 916 public static Get toGet(final MutationProto proto, final CellScanner cellScanner) 917 throws IOException { 918 MutationType type = proto.getMutateType(); 919 assert type == MutationType.INCREMENT || type == MutationType.APPEND : type.name(); 920 byte[] row = proto.hasRow() ? proto.getRow().toByteArray() : null; 921 Get get = null; 922 int cellCount = proto.hasAssociatedCellCount() ? proto.getAssociatedCellCount() : 0; 923 if (cellCount > 0) { 924 // The proto has metadata only and the data is separate to be found in the cellScanner. 925 if (cellScanner == null) { 926 throw new DoNotRetryIOException("Cell count of " + cellCount + " but no cellScanner: " 927 + TextFormat.shortDebugString(proto)); 928 } 929 for (int i = 0; i < cellCount; i++) { 930 if (!cellScanner.advance()) { 931 throw new DoNotRetryIOException("Cell count of " + cellCount + " but at index " + i 932 + " no cell returned: " + TextFormat.shortDebugString(proto)); 933 } 934 Cell cell = cellScanner.current(); 935 if (get == null) { 936 get = new Get(CellUtil.cloneRow(cell)); 937 } 938 get.addColumn(CellUtil.cloneFamily(cell), CellUtil.cloneQualifier(cell)); 939 } 940 } else { 941 get = new Get(row); 942 for (ColumnValue column : proto.getColumnValueList()) { 943 byte[] family = column.getFamily().toByteArray(); 944 for (QualifierValue qv : column.getQualifierValueList()) { 945 byte[] qualifier = qv.getQualifier().toByteArray(); 946 if (!qv.hasValue()) { 947 throw new DoNotRetryIOException("Missing required field: qualifier value"); 948 } 949 get.addColumn(family, qualifier); 950 } 951 } 952 } 953 if (proto.hasTimeRange()) { 954 TimeRange timeRange = toTimeRange(proto.getTimeRange()); 955 get.setTimeRange(timeRange.getMin(), timeRange.getMax()); 956 } 957 for (NameBytesPair attribute : proto.getAttributeList()) { 958 get.setAttribute(attribute.getName(), attribute.getValue().toByteArray()); 959 } 960 return get; 961 } 962 963 public static ClientProtos.Scan.ReadType toReadType(Scan.ReadType readType) { 964 switch (readType) { 965 case DEFAULT: 966 return ClientProtos.Scan.ReadType.DEFAULT; 967 case STREAM: 968 return ClientProtos.Scan.ReadType.STREAM; 969 case PREAD: 970 return ClientProtos.Scan.ReadType.PREAD; 971 default: 972 throw new IllegalArgumentException("Unknown ReadType: " + readType); 973 } 974 } 975 976 public static Scan.ReadType toReadType(ClientProtos.Scan.ReadType readType) { 977 switch (readType) { 978 case DEFAULT: 979 return Scan.ReadType.DEFAULT; 980 case STREAM: 981 return Scan.ReadType.STREAM; 982 case PREAD: 983 return Scan.ReadType.PREAD; 984 default: 985 throw new IllegalArgumentException("Unknown ReadType: " + readType); 986 } 987 } 988 989 /** 990 * Convert a client Scan to a protocol buffer Scan 991 * 992 * @param scan the client Scan to convert 993 * @return the converted protocol buffer Scan 994 * @throws IOException 995 */ 996 public static ClientProtos.Scan toScan( 997 final Scan scan) throws IOException { 998 ClientProtos.Scan.Builder scanBuilder = 999 ClientProtos.Scan.newBuilder(); 1000 scanBuilder.setCacheBlocks(scan.getCacheBlocks()); 1001 if (scan.getBatch() > 0) { 1002 scanBuilder.setBatchSize(scan.getBatch()); 1003 } 1004 if (scan.getMaxResultSize() > 0) { 1005 scanBuilder.setMaxResultSize(scan.getMaxResultSize()); 1006 } 1007 if (scan.isSmall()) { 1008 scanBuilder.setSmall(scan.isSmall()); 1009 } 1010 if (scan.getAllowPartialResults()) { 1011 scanBuilder.setAllowPartialResults(scan.getAllowPartialResults()); 1012 } 1013 Boolean loadColumnFamiliesOnDemand = scan.getLoadColumnFamiliesOnDemandValue(); 1014 if (loadColumnFamiliesOnDemand != null) { 1015 scanBuilder.setLoadColumnFamiliesOnDemand(loadColumnFamiliesOnDemand); 1016 } 1017 scanBuilder.setMaxVersions(scan.getMaxVersions()); 1018 scan.getColumnFamilyTimeRange().forEach((cf, timeRange) -> { 1019 scanBuilder.addCfTimeRange(HBaseProtos.ColumnFamilyTimeRange.newBuilder() 1020 .setColumnFamily(UnsafeByteOperations.unsafeWrap(cf)) 1021 .setTimeRange(toTimeRange(timeRange)) 1022 .build()); 1023 }); 1024 scanBuilder.setTimeRange(ProtobufUtil.toTimeRange(scan.getTimeRange())); 1025 Map<String, byte[]> attributes = scan.getAttributesMap(); 1026 if (!attributes.isEmpty()) { 1027 NameBytesPair.Builder attributeBuilder = NameBytesPair.newBuilder(); 1028 for (Map.Entry<String, byte[]> attribute: attributes.entrySet()) { 1029 attributeBuilder.setName(attribute.getKey()); 1030 attributeBuilder.setValue(UnsafeByteOperations.unsafeWrap(attribute.getValue())); 1031 scanBuilder.addAttribute(attributeBuilder.build()); 1032 } 1033 } 1034 byte[] startRow = scan.getStartRow(); 1035 if (startRow != null && startRow.length > 0) { 1036 scanBuilder.setStartRow(UnsafeByteOperations.unsafeWrap(startRow)); 1037 } 1038 byte[] stopRow = scan.getStopRow(); 1039 if (stopRow != null && stopRow.length > 0) { 1040 scanBuilder.setStopRow(UnsafeByteOperations.unsafeWrap(stopRow)); 1041 } 1042 if (scan.hasFilter()) { 1043 scanBuilder.setFilter(ProtobufUtil.toFilter(scan.getFilter())); 1044 } 1045 if (scan.hasFamilies()) { 1046 Column.Builder columnBuilder = Column.newBuilder(); 1047 for (Map.Entry<byte[],NavigableSet<byte []>> 1048 family: scan.getFamilyMap().entrySet()) { 1049 columnBuilder.setFamily(UnsafeByteOperations.unsafeWrap(family.getKey())); 1050 NavigableSet<byte []> qualifiers = family.getValue(); 1051 columnBuilder.clearQualifier(); 1052 if (qualifiers != null && qualifiers.size() > 0) { 1053 for (byte [] qualifier: qualifiers) { 1054 columnBuilder.addQualifier(UnsafeByteOperations.unsafeWrap(qualifier)); 1055 } 1056 } 1057 scanBuilder.addColumn(columnBuilder.build()); 1058 } 1059 } 1060 if (scan.getMaxResultsPerColumnFamily() >= 0) { 1061 scanBuilder.setStoreLimit(scan.getMaxResultsPerColumnFamily()); 1062 } 1063 if (scan.getRowOffsetPerColumnFamily() > 0) { 1064 scanBuilder.setStoreOffset(scan.getRowOffsetPerColumnFamily()); 1065 } 1066 if (scan.isReversed()) { 1067 scanBuilder.setReversed(scan.isReversed()); 1068 } 1069 if (scan.getConsistency() == Consistency.TIMELINE) { 1070 scanBuilder.setConsistency(toConsistency(scan.getConsistency())); 1071 } 1072 if (scan.getCaching() > 0) { 1073 scanBuilder.setCaching(scan.getCaching()); 1074 } 1075 long mvccReadPoint = PackagePrivateFieldAccessor.getMvccReadPoint(scan); 1076 if (mvccReadPoint > 0) { 1077 scanBuilder.setMvccReadPoint(mvccReadPoint); 1078 } 1079 if (!scan.includeStartRow()) { 1080 scanBuilder.setIncludeStartRow(false); 1081 } 1082 scanBuilder.setIncludeStopRow(scan.includeStopRow()); 1083 if (scan.getReadType() != Scan.ReadType.DEFAULT) { 1084 scanBuilder.setReadType(toReadType(scan.getReadType())); 1085 } 1086 if (scan.isNeedCursorResult()) { 1087 scanBuilder.setNeedCursorResult(true); 1088 } 1089 return scanBuilder.build(); 1090 } 1091 1092 /** 1093 * Convert a protocol buffer Scan to a client Scan 1094 * 1095 * @param proto the protocol buffer Scan to convert 1096 * @return the converted client Scan 1097 * @throws IOException 1098 */ 1099 public static Scan toScan( 1100 final ClientProtos.Scan proto) throws IOException { 1101 byte[] startRow = HConstants.EMPTY_START_ROW; 1102 byte[] stopRow = HConstants.EMPTY_END_ROW; 1103 boolean includeStartRow = true; 1104 boolean includeStopRow = false; 1105 if (proto.hasStartRow()) { 1106 startRow = proto.getStartRow().toByteArray(); 1107 } 1108 if (proto.hasStopRow()) { 1109 stopRow = proto.getStopRow().toByteArray(); 1110 } 1111 if (proto.hasIncludeStartRow()) { 1112 includeStartRow = proto.getIncludeStartRow(); 1113 } 1114 if (proto.hasIncludeStopRow()) { 1115 includeStopRow = proto.getIncludeStopRow(); 1116 } else { 1117 // old client without this flag, we should consider start=end as a get. 1118 if (ClientUtil.areScanStartRowAndStopRowEqual(startRow, stopRow)) { 1119 includeStopRow = true; 1120 } 1121 } 1122 Scan scan = 1123 new Scan().withStartRow(startRow, includeStartRow).withStopRow(stopRow, includeStopRow); 1124 if (proto.hasCacheBlocks()) { 1125 scan.setCacheBlocks(proto.getCacheBlocks()); 1126 } 1127 if (proto.hasMaxVersions()) { 1128 scan.setMaxVersions(proto.getMaxVersions()); 1129 } 1130 if (proto.hasStoreLimit()) { 1131 scan.setMaxResultsPerColumnFamily(proto.getStoreLimit()); 1132 } 1133 if (proto.hasStoreOffset()) { 1134 scan.setRowOffsetPerColumnFamily(proto.getStoreOffset()); 1135 } 1136 if (proto.hasLoadColumnFamiliesOnDemand()) { 1137 scan.setLoadColumnFamiliesOnDemand(proto.getLoadColumnFamiliesOnDemand()); 1138 } 1139 if (proto.getCfTimeRangeCount() > 0) { 1140 for (HBaseProtos.ColumnFamilyTimeRange cftr : proto.getCfTimeRangeList()) { 1141 TimeRange timeRange = toTimeRange(cftr.getTimeRange()); 1142 scan.setColumnFamilyTimeRange(cftr.getColumnFamily().toByteArray(), 1143 timeRange.getMin(), timeRange.getMax()); 1144 } 1145 } 1146 if (proto.hasTimeRange()) { 1147 TimeRange timeRange = toTimeRange(proto.getTimeRange()); 1148 scan.setTimeRange(timeRange.getMin(), timeRange.getMax()); 1149 } 1150 if (proto.hasFilter()) { 1151 FilterProtos.Filter filter = proto.getFilter(); 1152 scan.setFilter(ProtobufUtil.toFilter(filter)); 1153 } 1154 if (proto.hasBatchSize()) { 1155 scan.setBatch(proto.getBatchSize()); 1156 } 1157 if (proto.hasMaxResultSize()) { 1158 scan.setMaxResultSize(proto.getMaxResultSize()); 1159 } 1160 if (proto.hasSmall()) { 1161 scan.setSmall(proto.getSmall()); 1162 } 1163 if (proto.hasAllowPartialResults()) { 1164 scan.setAllowPartialResults(proto.getAllowPartialResults()); 1165 } 1166 for (NameBytesPair attribute: proto.getAttributeList()) { 1167 scan.setAttribute(attribute.getName(), attribute.getValue().toByteArray()); 1168 } 1169 if (proto.getColumnCount() > 0) { 1170 for (Column column: proto.getColumnList()) { 1171 byte[] family = column.getFamily().toByteArray(); 1172 if (column.getQualifierCount() > 0) { 1173 for (ByteString qualifier: column.getQualifierList()) { 1174 scan.addColumn(family, qualifier.toByteArray()); 1175 } 1176 } else { 1177 scan.addFamily(family); 1178 } 1179 } 1180 } 1181 if (proto.hasReversed()) { 1182 scan.setReversed(proto.getReversed()); 1183 } 1184 if (proto.hasConsistency()) { 1185 scan.setConsistency(toConsistency(proto.getConsistency())); 1186 } 1187 if (proto.hasCaching()) { 1188 scan.setCaching(proto.getCaching()); 1189 } 1190 if (proto.hasMvccReadPoint()) { 1191 PackagePrivateFieldAccessor.setMvccReadPoint(scan, proto.getMvccReadPoint()); 1192 } 1193 if (scan.isSmall()) { 1194 scan.setReadType(Scan.ReadType.PREAD); 1195 } else if (proto.hasReadType()) { 1196 scan.setReadType(toReadType(proto.getReadType())); 1197 } 1198 if (proto.getNeedCursorResult()) { 1199 scan.setNeedCursorResult(true); 1200 } 1201 return scan; 1202 } 1203 1204 public static ClientProtos.Cursor toCursor(Cursor cursor) { 1205 ClientProtos.Cursor.Builder builder = ClientProtos.Cursor.newBuilder(); 1206 ClientProtos.Cursor.newBuilder().setRow(ByteString.copyFrom(cursor.getRow())); 1207 return builder.build(); 1208 } 1209 1210 public static ClientProtos.Cursor toCursor(Cell cell) { 1211 return ClientProtos.Cursor.newBuilder() 1212 .setRow(ByteString.copyFrom(cell.getRowArray(), cell.getRowOffset(), cell.getRowLength())) 1213 .build(); 1214 } 1215 1216 public static Cursor toCursor(ClientProtos.Cursor cursor) { 1217 return ClientUtil.createCursor(cursor.getRow().toByteArray()); 1218 } 1219 1220 /** 1221 * Create a protocol buffer Get based on a client Get. 1222 * 1223 * @param get the client Get 1224 * @return a protocol buffer Get 1225 * @throws IOException 1226 */ 1227 public static ClientProtos.Get toGet( 1228 final Get get) throws IOException { 1229 ClientProtos.Get.Builder builder = 1230 ClientProtos.Get.newBuilder(); 1231 builder.setRow(UnsafeByteOperations.unsafeWrap(get.getRow())); 1232 builder.setCacheBlocks(get.getCacheBlocks()); 1233 builder.setMaxVersions(get.getMaxVersions()); 1234 if (get.getFilter() != null) { 1235 builder.setFilter(ProtobufUtil.toFilter(get.getFilter())); 1236 } 1237 get.getColumnFamilyTimeRange().forEach((cf, timeRange) -> { 1238 builder.addCfTimeRange(HBaseProtos.ColumnFamilyTimeRange.newBuilder() 1239 .setColumnFamily(UnsafeByteOperations.unsafeWrap(cf)) 1240 .setTimeRange(toTimeRange(timeRange)) 1241 .build()); 1242 }); 1243 builder.setTimeRange(ProtobufUtil.toTimeRange(get.getTimeRange())); 1244 Map<String, byte[]> attributes = get.getAttributesMap(); 1245 if (!attributes.isEmpty()) { 1246 NameBytesPair.Builder attributeBuilder = NameBytesPair.newBuilder(); 1247 for (Map.Entry<String, byte[]> attribute: attributes.entrySet()) { 1248 attributeBuilder.setName(attribute.getKey()); 1249 attributeBuilder.setValue(UnsafeByteOperations.unsafeWrap(attribute.getValue())); 1250 builder.addAttribute(attributeBuilder.build()); 1251 } 1252 } 1253 if (get.hasFamilies()) { 1254 Column.Builder columnBuilder = Column.newBuilder(); 1255 Map<byte[], NavigableSet<byte[]>> families = get.getFamilyMap(); 1256 for (Map.Entry<byte[], NavigableSet<byte[]>> family: families.entrySet()) { 1257 NavigableSet<byte[]> qualifiers = family.getValue(); 1258 columnBuilder.setFamily(UnsafeByteOperations.unsafeWrap(family.getKey())); 1259 columnBuilder.clearQualifier(); 1260 if (qualifiers != null && qualifiers.size() > 0) { 1261 for (byte[] qualifier: qualifiers) { 1262 columnBuilder.addQualifier(UnsafeByteOperations.unsafeWrap(qualifier)); 1263 } 1264 } 1265 builder.addColumn(columnBuilder.build()); 1266 } 1267 } 1268 if (get.getMaxResultsPerColumnFamily() >= 0) { 1269 builder.setStoreLimit(get.getMaxResultsPerColumnFamily()); 1270 } 1271 if (get.getRowOffsetPerColumnFamily() > 0) { 1272 builder.setStoreOffset(get.getRowOffsetPerColumnFamily()); 1273 } 1274 if (get.isCheckExistenceOnly()){ 1275 builder.setExistenceOnly(true); 1276 } 1277 if (get.getConsistency() != null && get.getConsistency() != Consistency.STRONG) { 1278 builder.setConsistency(toConsistency(get.getConsistency())); 1279 } 1280 1281 Boolean loadColumnFamiliesOnDemand = get.getLoadColumnFamiliesOnDemandValue(); 1282 if (loadColumnFamiliesOnDemand != null) { 1283 builder.setLoadColumnFamiliesOnDemand(loadColumnFamiliesOnDemand); 1284 } 1285 return builder.build(); 1286 } 1287 1288 public static MutationProto toMutation(final MutationType type, final Mutation mutation) 1289 throws IOException { 1290 return toMutation(type, mutation, HConstants.NO_NONCE); 1291 } 1292 1293 /** 1294 * Create a protocol buffer Mutate based on a client Mutation 1295 * 1296 * @param type 1297 * @param mutation 1298 * @return a protobuf'd Mutation 1299 * @throws IOException 1300 */ 1301 public static MutationProto toMutation(final MutationType type, final Mutation mutation, 1302 final long nonce) throws IOException { 1303 return toMutation(type, mutation, MutationProto.newBuilder(), nonce); 1304 } 1305 1306 public static MutationProto toMutation(final MutationType type, final Mutation mutation, 1307 MutationProto.Builder builder) throws IOException { 1308 return toMutation(type, mutation, builder, HConstants.NO_NONCE); 1309 } 1310 1311 public static MutationProto toMutation(final MutationType type, final Mutation mutation, 1312 MutationProto.Builder builder, long nonce) 1313 throws IOException { 1314 builder = getMutationBuilderAndSetCommonFields(type, mutation, builder); 1315 if (nonce != HConstants.NO_NONCE) { 1316 builder.setNonce(nonce); 1317 } 1318 if (type == MutationType.INCREMENT) { 1319 builder.setTimeRange(ProtobufUtil.toTimeRange(((Increment) mutation).getTimeRange())); 1320 } 1321 if (type == MutationType.APPEND) { 1322 builder.setTimeRange(ProtobufUtil.toTimeRange(((Append) mutation).getTimeRange())); 1323 } 1324 ColumnValue.Builder columnBuilder = ColumnValue.newBuilder(); 1325 QualifierValue.Builder valueBuilder = QualifierValue.newBuilder(); 1326 for (Map.Entry<byte[],List<Cell>> family: mutation.getFamilyCellMap().entrySet()) { 1327 columnBuilder.clear(); 1328 columnBuilder.setFamily(UnsafeByteOperations.unsafeWrap(family.getKey())); 1329 for (Cell cell: family.getValue()) { 1330 valueBuilder.clear(); 1331 valueBuilder.setQualifier(UnsafeByteOperations.unsafeWrap( 1332 cell.getQualifierArray(), cell.getQualifierOffset(), cell.getQualifierLength())); 1333 valueBuilder.setValue(UnsafeByteOperations.unsafeWrap( 1334 cell.getValueArray(), cell.getValueOffset(), cell.getValueLength())); 1335 valueBuilder.setTimestamp(cell.getTimestamp()); 1336 if (type == MutationType.DELETE || (type == MutationType.PUT && CellUtil.isDelete(cell))) { 1337 KeyValue.Type keyValueType = KeyValue.Type.codeToType(cell.getTypeByte()); 1338 valueBuilder.setDeleteType(toDeleteType(keyValueType)); 1339 } 1340 columnBuilder.addQualifierValue(valueBuilder.build()); 1341 } 1342 builder.addColumnValue(columnBuilder.build()); 1343 } 1344 return builder.build(); 1345 } 1346 1347 /** 1348 * Create a protocol buffer MutationProto based on a client Mutation. Does NOT include data. 1349 * Understanding is that the Cell will be transported other than via protobuf. 1350 * @param type 1351 * @param mutation 1352 * @param builder 1353 * @return a protobuf'd Mutation 1354 * @throws IOException 1355 */ 1356 public static MutationProto toMutationNoData(final MutationType type, final Mutation mutation, 1357 final MutationProto.Builder builder) throws IOException { 1358 return toMutationNoData(type, mutation, builder, HConstants.NO_NONCE); 1359 } 1360 1361 /** 1362 * Create a protocol buffer MutationProto based on a client Mutation. Does NOT include data. 1363 * Understanding is that the Cell will be transported other than via protobuf. 1364 * @param type 1365 * @param mutation 1366 * @return a protobuf'd Mutation 1367 * @throws IOException 1368 */ 1369 public static MutationProto toMutationNoData(final MutationType type, final Mutation mutation) 1370 throws IOException { 1371 MutationProto.Builder builder = MutationProto.newBuilder(); 1372 return toMutationNoData(type, mutation, builder); 1373 } 1374 1375 public static MutationProto toMutationNoData(final MutationType type, final Mutation mutation, 1376 final MutationProto.Builder builder, long nonce) throws IOException { 1377 getMutationBuilderAndSetCommonFields(type, mutation, builder); 1378 builder.setAssociatedCellCount(mutation.size()); 1379 if (mutation instanceof Increment) { 1380 builder.setTimeRange(ProtobufUtil.toTimeRange(((Increment) mutation).getTimeRange())); 1381 } 1382 if (mutation instanceof Append) { 1383 builder.setTimeRange(ProtobufUtil.toTimeRange(((Append) mutation).getTimeRange())); 1384 } 1385 if (nonce != HConstants.NO_NONCE) { 1386 builder.setNonce(nonce); 1387 } 1388 return builder.build(); 1389 } 1390 1391 /** 1392 * Code shared by {@link #toMutation(MutationType, Mutation)} and 1393 * {@link #toMutationNoData(MutationType, Mutation)} 1394 * @param type 1395 * @param mutation 1396 * @return A partly-filled out protobuf'd Mutation. 1397 */ 1398 private static MutationProto.Builder getMutationBuilderAndSetCommonFields(final MutationType type, 1399 final Mutation mutation, MutationProto.Builder builder) { 1400 builder.setRow(UnsafeByteOperations.unsafeWrap(mutation.getRow())); 1401 builder.setMutateType(type); 1402 builder.setDurability(toDurability(mutation.getDurability())); 1403 builder.setTimestamp(mutation.getTimestamp()); 1404 Map<String, byte[]> attributes = mutation.getAttributesMap(); 1405 if (!attributes.isEmpty()) { 1406 NameBytesPair.Builder attributeBuilder = NameBytesPair.newBuilder(); 1407 for (Map.Entry<String, byte[]> attribute: attributes.entrySet()) { 1408 attributeBuilder.setName(attribute.getKey()); 1409 attributeBuilder.setValue(UnsafeByteOperations.unsafeWrap(attribute.getValue())); 1410 builder.addAttribute(attributeBuilder.build()); 1411 } 1412 } 1413 return builder; 1414 } 1415 1416 /** 1417 * Convert a client Result to a protocol buffer Result 1418 * 1419 * @param result the client Result to convert 1420 * @return the converted protocol buffer Result 1421 */ 1422 public static ClientProtos.Result toResult(final Result result) { 1423 if (result.getExists() != null) { 1424 return toResult(result.getExists(), result.isStale()); 1425 } 1426 1427 Cell[] cells = result.rawCells(); 1428 if (cells == null || cells.length == 0) { 1429 return result.isStale() ? EMPTY_RESULT_PB_STALE : EMPTY_RESULT_PB; 1430 } 1431 1432 ClientProtos.Result.Builder builder = ClientProtos.Result.newBuilder(); 1433 for (Cell c : cells) { 1434 builder.addCell(toCell(c)); 1435 } 1436 1437 builder.setStale(result.isStale()); 1438 builder.setPartial(result.mayHaveMoreCellsInRow()); 1439 1440 return builder.build(); 1441 } 1442 1443 /** 1444 * Convert a client Result to a protocol buffer Result 1445 * 1446 * @param existence the client existence to send 1447 * @return the converted protocol buffer Result 1448 */ 1449 public static ClientProtos.Result toResult(final boolean existence, boolean stale) { 1450 if (stale){ 1451 return existence ? EMPTY_RESULT_PB_EXISTS_TRUE_STALE : EMPTY_RESULT_PB_EXISTS_FALSE_STALE; 1452 } else { 1453 return existence ? EMPTY_RESULT_PB_EXISTS_TRUE : EMPTY_RESULT_PB_EXISTS_FALSE; 1454 } 1455 } 1456 1457 /** 1458 * Convert a client Result to a protocol buffer Result. 1459 * The pb Result does not include the Cell data. That is for transport otherwise. 1460 * 1461 * @param result the client Result to convert 1462 * @return the converted protocol buffer Result 1463 */ 1464 public static ClientProtos.Result toResultNoData(final Result result) { 1465 if (result.getExists() != null) return toResult(result.getExists(), result.isStale()); 1466 int size = result.size(); 1467 if (size == 0) return result.isStale() ? EMPTY_RESULT_PB_STALE : EMPTY_RESULT_PB; 1468 ClientProtos.Result.Builder builder = ClientProtos.Result.newBuilder(); 1469 builder.setAssociatedCellCount(size); 1470 builder.setStale(result.isStale()); 1471 return builder.build(); 1472 } 1473 1474 /** 1475 * Convert a protocol buffer Result to a client Result 1476 * 1477 * @param proto the protocol buffer Result to convert 1478 * @return the converted client Result 1479 */ 1480 public static Result toResult(final ClientProtos.Result proto) { 1481 if (proto.hasExists()) { 1482 if (proto.getStale()) { 1483 return proto.getExists() ? EMPTY_RESULT_EXISTS_TRUE_STALE :EMPTY_RESULT_EXISTS_FALSE_STALE; 1484 } 1485 return proto.getExists() ? EMPTY_RESULT_EXISTS_TRUE : EMPTY_RESULT_EXISTS_FALSE; 1486 } 1487 1488 List<CellProtos.Cell> values = proto.getCellList(); 1489 if (values.isEmpty()){ 1490 return proto.getStale() ? EMPTY_RESULT_STALE : EMPTY_RESULT; 1491 } 1492 1493 List<Cell> cells = new ArrayList<>(values.size()); 1494 ExtendedCellBuilder builder = ExtendedCellBuilderFactory.create(CellBuilderType.SHALLOW_COPY); 1495 for (CellProtos.Cell c : values) { 1496 cells.add(toCell(builder, c)); 1497 } 1498 return Result.create(cells, null, proto.getStale(), proto.getPartial()); 1499 } 1500 1501 /** 1502 * Convert a protocol buffer Result to a client Result 1503 * 1504 * @param proto the protocol buffer Result to convert 1505 * @param scanner Optional cell scanner. 1506 * @return the converted client Result 1507 * @throws IOException 1508 */ 1509 public static Result toResult(final ClientProtos.Result proto, final CellScanner scanner) 1510 throws IOException { 1511 List<CellProtos.Cell> values = proto.getCellList(); 1512 1513 if (proto.hasExists()) { 1514 if ((values != null && !values.isEmpty()) || 1515 (proto.hasAssociatedCellCount() && proto.getAssociatedCellCount() > 0)) { 1516 throw new IllegalArgumentException("bad proto: exists with cells is no allowed " + proto); 1517 } 1518 if (proto.getStale()) { 1519 return proto.getExists() ? EMPTY_RESULT_EXISTS_TRUE_STALE :EMPTY_RESULT_EXISTS_FALSE_STALE; 1520 } 1521 return proto.getExists() ? EMPTY_RESULT_EXISTS_TRUE : EMPTY_RESULT_EXISTS_FALSE; 1522 } 1523 1524 // TODO: Unit test that has some Cells in scanner and some in the proto. 1525 List<Cell> cells = null; 1526 if (proto.hasAssociatedCellCount()) { 1527 int count = proto.getAssociatedCellCount(); 1528 cells = new ArrayList<>(count + values.size()); 1529 for (int i = 0; i < count; i++) { 1530 if (!scanner.advance()) throw new IOException("Failed get " + i + " of " + count); 1531 cells.add(scanner.current()); 1532 } 1533 } 1534 1535 if (!values.isEmpty()){ 1536 if (cells == null) cells = new ArrayList<>(values.size()); 1537 ExtendedCellBuilder builder = ExtendedCellBuilderFactory.create(CellBuilderType.SHALLOW_COPY); 1538 for (CellProtos.Cell c: values) { 1539 cells.add(toCell(builder, c)); 1540 } 1541 } 1542 1543 return (cells == null || cells.isEmpty()) 1544 ? (proto.getStale() ? EMPTY_RESULT_STALE : EMPTY_RESULT) 1545 : Result.create(cells, null, proto.getStale()); 1546 } 1547 1548 1549 /** 1550 * Convert a ByteArrayComparable to a protocol buffer Comparator 1551 * 1552 * @param comparator the ByteArrayComparable to convert 1553 * @return the converted protocol buffer Comparator 1554 */ 1555 public static ComparatorProtos.Comparator toComparator(ByteArrayComparable comparator) { 1556 ComparatorProtos.Comparator.Builder builder = ComparatorProtos.Comparator.newBuilder(); 1557 builder.setName(comparator.getClass().getName()); 1558 builder.setSerializedComparator(UnsafeByteOperations.unsafeWrap(comparator.toByteArray())); 1559 return builder.build(); 1560 } 1561 1562 /** 1563 * Convert a protocol buffer Comparator to a ByteArrayComparable 1564 * 1565 * @param proto the protocol buffer Comparator to convert 1566 * @return the converted ByteArrayComparable 1567 */ 1568 @SuppressWarnings("unchecked") 1569 public static ByteArrayComparable toComparator(ComparatorProtos.Comparator proto) 1570 throws IOException { 1571 String type = proto.getName(); 1572 String funcName = "parseFrom"; 1573 byte [] value = proto.getSerializedComparator().toByteArray(); 1574 try { 1575 Class<?> c = Class.forName(type, true, ClassLoaderHolder.CLASS_LOADER); 1576 Method parseFrom = c.getMethod(funcName, byte[].class); 1577 if (parseFrom == null) { 1578 throw new IOException("Unable to locate function: " + funcName + " in type: " + type); 1579 } 1580 return (ByteArrayComparable)parseFrom.invoke(null, value); 1581 } catch (Exception e) { 1582 throw new IOException(e); 1583 } 1584 } 1585 1586 /** 1587 * Convert a protocol buffer Filter to a client Filter 1588 * 1589 * @param proto the protocol buffer Filter to convert 1590 * @return the converted Filter 1591 */ 1592 @SuppressWarnings("unchecked") 1593 public static Filter toFilter(FilterProtos.Filter proto) throws IOException { 1594 String type = proto.getName(); 1595 final byte [] value = proto.getSerializedFilter().toByteArray(); 1596 String funcName = "parseFrom"; 1597 try { 1598 Class<?> c = Class.forName(type, true, ClassLoaderHolder.CLASS_LOADER); 1599 Method parseFrom = c.getMethod(funcName, byte[].class); 1600 if (parseFrom == null) { 1601 throw new IOException("Unable to locate function: " + funcName + " in type: " + type); 1602 } 1603 return (Filter)parseFrom.invoke(c, value); 1604 } catch (Exception e) { 1605 // Either we couldn't instantiate the method object, or "parseFrom" failed. 1606 // In either case, let's not retry. 1607 throw new DoNotRetryIOException(e); 1608 } 1609 } 1610 1611 /** 1612 * Convert a client Filter to a protocol buffer Filter 1613 * 1614 * @param filter the Filter to convert 1615 * @return the converted protocol buffer Filter 1616 */ 1617 public static FilterProtos.Filter toFilter(Filter filter) throws IOException { 1618 FilterProtos.Filter.Builder builder = FilterProtos.Filter.newBuilder(); 1619 builder.setName(filter.getClass().getName()); 1620 builder.setSerializedFilter(UnsafeByteOperations.unsafeWrap(filter.toByteArray())); 1621 return builder.build(); 1622 } 1623 1624 /** 1625 * Convert a delete KeyValue type to protocol buffer DeleteType. 1626 * 1627 * @param type 1628 * @return protocol buffer DeleteType 1629 * @throws IOException 1630 */ 1631 public static DeleteType toDeleteType( 1632 KeyValue.Type type) throws IOException { 1633 switch (type) { 1634 case Delete: 1635 return DeleteType.DELETE_ONE_VERSION; 1636 case DeleteColumn: 1637 return DeleteType.DELETE_MULTIPLE_VERSIONS; 1638 case DeleteFamily: 1639 return DeleteType.DELETE_FAMILY; 1640 case DeleteFamilyVersion: 1641 return DeleteType.DELETE_FAMILY_VERSION; 1642 default: 1643 throw new IOException("Unknown delete type: " + type); 1644 } 1645 } 1646 1647 /** 1648 * Convert a protocol buffer DeleteType to delete KeyValue type. 1649 * 1650 * @param type The DeleteType 1651 * @return The type. 1652 * @throws IOException 1653 */ 1654 public static KeyValue.Type fromDeleteType( 1655 DeleteType type) throws IOException { 1656 switch (type) { 1657 case DELETE_ONE_VERSION: 1658 return KeyValue.Type.Delete; 1659 case DELETE_MULTIPLE_VERSIONS: 1660 return KeyValue.Type.DeleteColumn; 1661 case DELETE_FAMILY: 1662 return KeyValue.Type.DeleteFamily; 1663 case DELETE_FAMILY_VERSION: 1664 return KeyValue.Type.DeleteFamilyVersion; 1665 default: 1666 throw new IOException("Unknown delete type: " + type); 1667 } 1668 } 1669 1670 /** 1671 * Convert a stringified protocol buffer exception Parameter to a Java Exception 1672 * 1673 * @param parameter the protocol buffer Parameter to convert 1674 * @return the converted Exception 1675 * @throws IOException if failed to deserialize the parameter 1676 */ 1677 @SuppressWarnings("unchecked") 1678 public static Throwable toException(final NameBytesPair parameter) throws IOException { 1679 if (parameter == null || !parameter.hasValue()) return null; 1680 String desc = parameter.getValue().toStringUtf8(); 1681 String type = parameter.getName(); 1682 try { 1683 Class<? extends Throwable> c = 1684 (Class<? extends Throwable>)Class.forName(type, true, ClassLoaderHolder.CLASS_LOADER); 1685 Constructor<? extends Throwable> cn = null; 1686 try { 1687 cn = c.getDeclaredConstructor(String.class); 1688 return cn.newInstance(desc); 1689 } catch (NoSuchMethodException e) { 1690 // Could be a raw RemoteException. See HBASE-8987. 1691 cn = c.getDeclaredConstructor(String.class, String.class); 1692 return cn.newInstance(type, desc); 1693 } 1694 } catch (Exception e) { 1695 throw new IOException(e); 1696 } 1697 } 1698 1699// Start helpers for Client 1700 1701 @SuppressWarnings("unchecked") 1702 public static <T extends Service> T newServiceStub(Class<T> service, RpcChannel channel) 1703 throws Exception { 1704 return (T)Methods.call(service, null, "newStub", 1705 new Class[]{ RpcChannel.class }, new Object[]{ channel }); 1706 } 1707 1708// End helpers for Client 1709// Start helpers for Admin 1710 1711 /** 1712 * A helper to retrieve region info given a region name 1713 * using admin protocol. 1714 * 1715 * @param admin 1716 * @param regionName 1717 * @return the retrieved region info 1718 * @throws IOException 1719 */ 1720 public static org.apache.hadoop.hbase.client.RegionInfo getRegionInfo(final RpcController controller, 1721 final AdminService.BlockingInterface admin, final byte[] regionName) throws IOException { 1722 try { 1723 GetRegionInfoRequest request = 1724 RequestConverter.buildGetRegionInfoRequest(regionName); 1725 GetRegionInfoResponse response = 1726 admin.getRegionInfo(controller, request); 1727 return toRegionInfo(response.getRegionInfo()); 1728 } catch (ServiceException se) { 1729 throw getRemoteException(se); 1730 } 1731 } 1732 1733 public static List<org.apache.hadoop.hbase.RegionLoad> getRegionLoadInfo( 1734 GetRegionLoadResponse regionLoadResponse) { 1735 List<org.apache.hadoop.hbase.RegionLoad> regionLoadList = 1736 new ArrayList<>(regionLoadResponse.getRegionLoadsCount()); 1737 for (RegionLoad regionLoad : regionLoadResponse.getRegionLoadsList()) { 1738 regionLoadList.add(new org.apache.hadoop.hbase.RegionLoad(regionLoad)); 1739 } 1740 return regionLoadList; 1741 } 1742 1743 /** 1744 * A helper to close a region given a region name 1745 * using admin protocol. 1746 * 1747 * @param admin 1748 * @param regionName 1749 * @throws IOException 1750 */ 1751 public static void closeRegion(final RpcController controller, 1752 final AdminService.BlockingInterface admin, final ServerName server, final byte[] regionName) 1753 throws IOException { 1754 CloseRegionRequest closeRegionRequest = 1755 ProtobufUtil.buildCloseRegionRequest(server, regionName); 1756 try { 1757 admin.closeRegion(controller, closeRegionRequest); 1758 } catch (ServiceException se) { 1759 throw getRemoteException(se); 1760 } 1761 } 1762 1763 /** 1764 * A helper to warmup a region given a region name 1765 * using admin protocol 1766 * 1767 * @param admin 1768 * @param regionInfo 1769 * 1770 */ 1771 public static void warmupRegion(final RpcController controller, 1772 final AdminService.BlockingInterface admin, final org.apache.hadoop.hbase.client.RegionInfo regionInfo) throws IOException { 1773 1774 try { 1775 WarmupRegionRequest warmupRegionRequest = 1776 RequestConverter.buildWarmupRegionRequest(regionInfo); 1777 1778 admin.warmupRegion(controller, warmupRegionRequest); 1779 } catch (ServiceException e) { 1780 throw getRemoteException(e); 1781 } 1782 } 1783 1784 /** 1785 * A helper to open a region using admin protocol. 1786 * @param admin 1787 * @param region 1788 * @throws IOException 1789 */ 1790 public static void openRegion(final RpcController controller, 1791 final AdminService.BlockingInterface admin, ServerName server, final org.apache.hadoop.hbase.client.RegionInfo region) 1792 throws IOException { 1793 OpenRegionRequest request = 1794 RequestConverter.buildOpenRegionRequest(server, region, null); 1795 try { 1796 admin.openRegion(controller, request); 1797 } catch (ServiceException se) { 1798 throw ProtobufUtil.getRemoteException(se); 1799 } 1800 } 1801 1802 /** 1803 * A helper to get the all the online regions on a region 1804 * server using admin protocol. 1805 * 1806 * @param admin 1807 * @return a list of online region info 1808 * @throws IOException 1809 */ 1810 public static List<org.apache.hadoop.hbase.client.RegionInfo> getOnlineRegions(final AdminService.BlockingInterface admin) 1811 throws IOException { 1812 return getOnlineRegions(null, admin); 1813 } 1814 1815 /** 1816 * A helper to get the all the online regions on a region 1817 * server using admin protocol. 1818 * @return a list of online region info 1819 */ 1820 public static List<org.apache.hadoop.hbase.client.RegionInfo> getOnlineRegions(final RpcController controller, 1821 final AdminService.BlockingInterface admin) 1822 throws IOException { 1823 GetOnlineRegionRequest request = RequestConverter.buildGetOnlineRegionRequest(); 1824 GetOnlineRegionResponse response = null; 1825 try { 1826 response = admin.getOnlineRegion(controller, request); 1827 } catch (ServiceException se) { 1828 throw getRemoteException(se); 1829 } 1830 return getRegionInfos(response); 1831 } 1832 1833 /** 1834 * Get the list of region info from a GetOnlineRegionResponse 1835 * 1836 * @param proto the GetOnlineRegionResponse 1837 * @return the list of region info or empty if <code>proto</code> is null 1838 */ 1839 public static List<org.apache.hadoop.hbase.client.RegionInfo> getRegionInfos(final GetOnlineRegionResponse proto) { 1840 if (proto == null) return Collections.EMPTY_LIST; 1841 List<org.apache.hadoop.hbase.client.RegionInfo> regionInfos = new ArrayList<>(proto.getRegionInfoList().size()); 1842 for (RegionInfo regionInfo: proto.getRegionInfoList()) { 1843 regionInfos.add(toRegionInfo(regionInfo)); 1844 } 1845 return regionInfos; 1846 } 1847 1848 /** 1849 * A helper to get the info of a region server using admin protocol. 1850 * @return the server name 1851 */ 1852 public static ServerInfo getServerInfo(final RpcController controller, 1853 final AdminService.BlockingInterface admin) 1854 throws IOException { 1855 GetServerInfoRequest request = RequestConverter.buildGetServerInfoRequest(); 1856 try { 1857 GetServerInfoResponse response = admin.getServerInfo(controller, request); 1858 return response.getServerInfo(); 1859 } catch (ServiceException se) { 1860 throw getRemoteException(se); 1861 } 1862 } 1863 1864 /** 1865 * A helper to get the list of files of a column family 1866 * on a given region using admin protocol. 1867 * 1868 * @return the list of store files 1869 */ 1870 public static List<String> getStoreFiles(final AdminService.BlockingInterface admin, 1871 final byte[] regionName, final byte[] family) 1872 throws IOException { 1873 return getStoreFiles(null, admin, regionName, family); 1874 } 1875 1876 /** 1877 * A helper to get the list of files of a column family 1878 * on a given region using admin protocol. 1879 * 1880 * @return the list of store files 1881 */ 1882 public static List<String> getStoreFiles(final RpcController controller, 1883 final AdminService.BlockingInterface admin, final byte[] regionName, final byte[] family) 1884 throws IOException { 1885 GetStoreFileRequest request = 1886 ProtobufUtil.buildGetStoreFileRequest(regionName, family); 1887 try { 1888 GetStoreFileResponse response = admin.getStoreFile(controller, request); 1889 return response.getStoreFileList(); 1890 } catch (ServiceException se) { 1891 throw ProtobufUtil.getRemoteException(se); 1892 } 1893 } 1894 1895// End helpers for Admin 1896 1897 /* 1898 * Get the total (read + write) requests from a RegionLoad pb 1899 * @param rl - RegionLoad pb 1900 * @return total (read + write) requests 1901 */ 1902 public static long getTotalRequestsCount(RegionLoad rl) { 1903 if (rl == null) { 1904 return 0; 1905 } 1906 1907 return rl.getReadRequestsCount() + rl.getWriteRequestsCount(); 1908 } 1909 1910 1911 /** 1912 * @param m Message to get delimited pb serialization of (with pb magic prefix) 1913 */ 1914 public static byte [] toDelimitedByteArray(final Message m) throws IOException { 1915 // Allocate arbitrary big size so we avoid resizing. 1916 ByteArrayOutputStream baos = new ByteArrayOutputStream(4096); 1917 baos.write(ProtobufMagic.PB_MAGIC); 1918 m.writeDelimitedTo(baos); 1919 return baos.toByteArray(); 1920 } 1921 1922 /** 1923 * Find the HRegion encoded name based on a region specifier 1924 * 1925 * @param regionSpecifier the region specifier 1926 * @return the corresponding region's encoded name 1927 * @throws DoNotRetryIOException if the specifier type is unsupported 1928 */ 1929 public static String getRegionEncodedName( 1930 final RegionSpecifier regionSpecifier) throws DoNotRetryIOException { 1931 ByteString value = regionSpecifier.getValue(); 1932 RegionSpecifierType type = regionSpecifier.getType(); 1933 switch (type) { 1934 case REGION_NAME: 1935 return org.apache.hadoop.hbase.client.RegionInfo.encodeRegionName(value.toByteArray()); 1936 case ENCODED_REGION_NAME: 1937 return value.toStringUtf8(); 1938 default: 1939 throw new DoNotRetryIOException( 1940 "Unsupported region specifier type: " + type); 1941 } 1942 } 1943 1944 public static ScanMetrics toScanMetrics(final byte[] bytes) { 1945 MapReduceProtos.ScanMetrics pScanMetrics = null; 1946 try { 1947 pScanMetrics = MapReduceProtos.ScanMetrics.parseFrom(bytes); 1948 } catch (InvalidProtocolBufferException e) { 1949 // Ignored there are just no key values to add. 1950 } 1951 ScanMetrics scanMetrics = new ScanMetrics(); 1952 if (pScanMetrics != null) { 1953 for (HBaseProtos.NameInt64Pair pair : pScanMetrics.getMetricsList()) { 1954 if (pair.hasName() && pair.hasValue()) { 1955 scanMetrics.setCounter(pair.getName(), pair.getValue()); 1956 } 1957 } 1958 } 1959 return scanMetrics; 1960 } 1961 1962 public static MapReduceProtos.ScanMetrics toScanMetrics(ScanMetrics scanMetrics, boolean reset) { 1963 MapReduceProtos.ScanMetrics.Builder builder = MapReduceProtos.ScanMetrics.newBuilder(); 1964 Map<String, Long> metrics = scanMetrics.getMetricsMap(reset); 1965 for (Entry<String, Long> e : metrics.entrySet()) { 1966 HBaseProtos.NameInt64Pair nameInt64Pair = 1967 HBaseProtos.NameInt64Pair.newBuilder().setName(e.getKey()).setValue(e.getValue()).build(); 1968 builder.addMetrics(nameInt64Pair); 1969 } 1970 return builder.build(); 1971 } 1972 1973 /** 1974 * Unwraps an exception from a protobuf service into the underlying (expected) IOException. 1975 * This method will <strong>always</strong> throw an exception. 1976 * @param se the {@code ServiceException} instance to convert into an {@code IOException} 1977 */ 1978 public static void toIOException(ServiceException se) throws IOException { 1979 if (se == null) { 1980 throw new NullPointerException("Null service exception passed!"); 1981 } 1982 1983 Throwable cause = se.getCause(); 1984 if (cause != null && cause instanceof IOException) { 1985 throw (IOException)cause; 1986 } 1987 throw new IOException(se); 1988 } 1989 1990 public static CellProtos.Cell toCell(final Cell kv) { 1991 // Doing this is going to kill us if we do it for all data passed. 1992 // St.Ack 20121205 1993 CellProtos.Cell.Builder kvbuilder = CellProtos.Cell.newBuilder(); 1994 if (kv instanceof ByteBufferExtendedCell) { 1995 kvbuilder.setRow(wrap(((ByteBufferExtendedCell) kv).getRowByteBuffer(), 1996 ((ByteBufferExtendedCell) kv).getRowPosition(), kv.getRowLength())); 1997 kvbuilder.setFamily(wrap(((ByteBufferExtendedCell) kv).getFamilyByteBuffer(), 1998 ((ByteBufferExtendedCell) kv).getFamilyPosition(), kv.getFamilyLength())); 1999 kvbuilder.setQualifier(wrap(((ByteBufferExtendedCell) kv).getQualifierByteBuffer(), 2000 ((ByteBufferExtendedCell) kv).getQualifierPosition(), kv.getQualifierLength())); 2001 kvbuilder.setCellType(CellProtos.CellType.valueOf(kv.getTypeByte())); 2002 kvbuilder.setTimestamp(kv.getTimestamp()); 2003 kvbuilder.setValue(wrap(((ByteBufferExtendedCell) kv).getValueByteBuffer(), 2004 ((ByteBufferExtendedCell) kv).getValuePosition(), kv.getValueLength())); 2005 // TODO : Once tags become first class then we may have to set tags to kvbuilder. 2006 } else { 2007 kvbuilder.setRow( 2008 UnsafeByteOperations.unsafeWrap(kv.getRowArray(), kv.getRowOffset(), kv.getRowLength())); 2009 kvbuilder.setFamily(UnsafeByteOperations.unsafeWrap(kv.getFamilyArray(), kv.getFamilyOffset(), 2010 kv.getFamilyLength())); 2011 kvbuilder.setQualifier(UnsafeByteOperations.unsafeWrap(kv.getQualifierArray(), 2012 kv.getQualifierOffset(), kv.getQualifierLength())); 2013 kvbuilder.setCellType(CellProtos.CellType.valueOf(kv.getTypeByte())); 2014 kvbuilder.setTimestamp(kv.getTimestamp()); 2015 kvbuilder.setValue(UnsafeByteOperations.unsafeWrap(kv.getValueArray(), kv.getValueOffset(), 2016 kv.getValueLength())); 2017 } 2018 return kvbuilder.build(); 2019 } 2020 2021 private static ByteString wrap(ByteBuffer b, int offset, int length) { 2022 ByteBuffer dup = b.duplicate(); 2023 dup.position(offset); 2024 dup.limit(offset + length); 2025 return UnsafeByteOperations.unsafeWrap(dup); 2026 } 2027 2028 public static Cell toCell(ExtendedCellBuilder cellBuilder, final CellProtos.Cell cell) { 2029 return cellBuilder.clear() 2030 .setRow(cell.getRow().toByteArray()) 2031 .setFamily(cell.getFamily().toByteArray()) 2032 .setQualifier(cell.getQualifier().toByteArray()) 2033 .setTimestamp(cell.getTimestamp()) 2034 .setType((byte) cell.getCellType().getNumber()) 2035 .setValue(cell.getValue().toByteArray()) 2036 .build(); 2037 } 2038 2039 public static HBaseProtos.NamespaceDescriptor toProtoNamespaceDescriptor(NamespaceDescriptor ns) { 2040 HBaseProtos.NamespaceDescriptor.Builder b = 2041 HBaseProtos.NamespaceDescriptor.newBuilder() 2042 .setName(ByteString.copyFromUtf8(ns.getName())); 2043 for(Map.Entry<String, String> entry: ns.getConfiguration().entrySet()) { 2044 b.addConfiguration(HBaseProtos.NameStringPair.newBuilder() 2045 .setName(entry.getKey()) 2046 .setValue(entry.getValue())); 2047 } 2048 return b.build(); 2049 } 2050 2051 public static NamespaceDescriptor toNamespaceDescriptor(HBaseProtos.NamespaceDescriptor desc) { 2052 NamespaceDescriptor.Builder b = NamespaceDescriptor.create(desc.getName().toStringUtf8()); 2053 for (HBaseProtos.NameStringPair prop : desc.getConfigurationList()) { 2054 b.addConfiguration(prop.getName(), prop.getValue()); 2055 } 2056 return b.build(); 2057 } 2058 2059 public static CompactionDescriptor toCompactionDescriptor( 2060 org.apache.hadoop.hbase.client.RegionInfo info, byte[] family, 2061 List<Path> inputPaths, List<Path> outputPaths, Path storeDir) { 2062 return toCompactionDescriptor(info, null, family, inputPaths, outputPaths, storeDir); 2063 } 2064 2065 public static CompactionDescriptor toCompactionDescriptor( 2066 org.apache.hadoop.hbase.client.RegionInfo info, byte[] regionName, 2067 byte[] family, List<Path> inputPaths, List<Path> outputPaths, Path storeDir) { 2068 // compaction descriptor contains relative paths. 2069 // input / output paths are relative to the store dir 2070 // store dir is relative to region dir 2071 CompactionDescriptor.Builder builder = CompactionDescriptor.newBuilder() 2072 .setTableName(UnsafeByteOperations.unsafeWrap(info.getTable().toBytes())) 2073 .setEncodedRegionName(UnsafeByteOperations.unsafeWrap( 2074 regionName == null ? info.getEncodedNameAsBytes() : regionName)) 2075 .setFamilyName(UnsafeByteOperations.unsafeWrap(family)) 2076 .setStoreHomeDir(storeDir.getName()); //make relative 2077 for (Path inputPath : inputPaths) { 2078 builder.addCompactionInput(inputPath.getName()); //relative path 2079 } 2080 for (Path outputPath : outputPaths) { 2081 builder.addCompactionOutput(outputPath.getName()); 2082 } 2083 builder.setRegionName(UnsafeByteOperations.unsafeWrap(info.getRegionName())); 2084 return builder.build(); 2085 } 2086 2087 public static FlushDescriptor toFlushDescriptor(FlushAction action, org.apache.hadoop.hbase.client.RegionInfo hri, 2088 long flushSeqId, Map<byte[], List<Path>> committedFiles) { 2089 FlushDescriptor.Builder desc = FlushDescriptor.newBuilder() 2090 .setAction(action) 2091 .setEncodedRegionName(UnsafeByteOperations.unsafeWrap(hri.getEncodedNameAsBytes())) 2092 .setRegionName(UnsafeByteOperations.unsafeWrap(hri.getRegionName())) 2093 .setFlushSequenceNumber(flushSeqId) 2094 .setTableName(UnsafeByteOperations.unsafeWrap(hri.getTable().getName())); 2095 2096 for (Map.Entry<byte[], List<Path>> entry : committedFiles.entrySet()) { 2097 WALProtos.FlushDescriptor.StoreFlushDescriptor.Builder builder = 2098 WALProtos.FlushDescriptor.StoreFlushDescriptor.newBuilder() 2099 .setFamilyName(UnsafeByteOperations.unsafeWrap(entry.getKey())) 2100 .setStoreHomeDir(Bytes.toString(entry.getKey())); //relative to region 2101 if (entry.getValue() != null) { 2102 for (Path path : entry.getValue()) { 2103 builder.addFlushOutput(path.getName()); 2104 } 2105 } 2106 desc.addStoreFlushes(builder); 2107 } 2108 return desc.build(); 2109 } 2110 2111 public static RegionEventDescriptor toRegionEventDescriptor( 2112 EventType eventType, org.apache.hadoop.hbase.client.RegionInfo hri, long seqId, ServerName server, 2113 Map<byte[], List<Path>> storeFiles) { 2114 final byte[] tableNameAsBytes = hri.getTable().getName(); 2115 final byte[] encodedNameAsBytes = hri.getEncodedNameAsBytes(); 2116 final byte[] regionNameAsBytes = hri.getRegionName(); 2117 return toRegionEventDescriptor(eventType, 2118 tableNameAsBytes, 2119 encodedNameAsBytes, 2120 regionNameAsBytes, 2121 seqId, 2122 2123 server, 2124 storeFiles); 2125 } 2126 2127 public static RegionEventDescriptor toRegionEventDescriptor(EventType eventType, 2128 byte[] tableNameAsBytes, 2129 byte[] encodedNameAsBytes, 2130 byte[] regionNameAsBytes, 2131 long seqId, 2132 2133 ServerName server, 2134 Map<byte[], List<Path>> storeFiles) { 2135 RegionEventDescriptor.Builder desc = RegionEventDescriptor.newBuilder() 2136 .setEventType(eventType) 2137 .setTableName(UnsafeByteOperations.unsafeWrap(tableNameAsBytes)) 2138 .setEncodedRegionName(UnsafeByteOperations.unsafeWrap(encodedNameAsBytes)) 2139 .setRegionName(UnsafeByteOperations.unsafeWrap(regionNameAsBytes)) 2140 .setLogSequenceNumber(seqId) 2141 .setServer(toServerName(server)); 2142 2143 for (Entry<byte[], List<Path>> entry : storeFiles.entrySet()) { 2144 StoreDescriptor.Builder builder = StoreDescriptor.newBuilder() 2145 .setFamilyName(UnsafeByteOperations.unsafeWrap(entry.getKey())) 2146 .setStoreHomeDir(Bytes.toString(entry.getKey())); 2147 for (Path path : entry.getValue()) { 2148 builder.addStoreFile(path.getName()); 2149 } 2150 2151 desc.addStores(builder); 2152 } 2153 return desc.build(); 2154 } 2155 2156 /** 2157 * Return short version of Message toString'd, shorter than TextFormat#shortDebugString. 2158 * Tries to NOT print out data both because it can be big but also so we do not have data in our 2159 * logs. Use judiciously. 2160 * @param m 2161 * @return toString of passed <code>m</code> 2162 */ 2163 public static String getShortTextFormat(Message m) { 2164 if (m == null) return "null"; 2165 if (m instanceof ScanRequest) { 2166 // This should be small and safe to output. No data. 2167 return TextFormat.shortDebugString(m); 2168 } else if (m instanceof RegionServerReportRequest) { 2169 // Print a short message only, just the servername and the requests, not the full load. 2170 RegionServerReportRequest r = (RegionServerReportRequest)m; 2171 return "server " + TextFormat.shortDebugString(r.getServer()) + 2172 " load { numberOfRequests: " + r.getLoad().getNumberOfRequests() + " }"; 2173 } else if (m instanceof RegionServerStartupRequest) { 2174 // Should be small enough. 2175 return TextFormat.shortDebugString(m); 2176 } else if (m instanceof MutationProto) { 2177 return toShortString((MutationProto)m); 2178 } else if (m instanceof GetRequest) { 2179 GetRequest r = (GetRequest) m; 2180 return "region= " + getStringForByteString(r.getRegion().getValue()) + 2181 ", row=" + getStringForByteString(r.getGet().getRow()); 2182 } else if (m instanceof ClientProtos.MultiRequest) { 2183 ClientProtos.MultiRequest r = (ClientProtos.MultiRequest) m; 2184 2185 // Get the number of Actions 2186 int actionsCount = r.getRegionActionList() 2187 .stream() 2188 .mapToInt(ClientProtos.RegionAction::getActionCount) 2189 .sum(); 2190 2191 // Get first set of Actions. 2192 ClientProtos.RegionAction actions = r.getRegionActionList().get(0); 2193 String row = actions.getActionCount() <= 0? "": 2194 getStringForByteString(actions.getAction(0).hasGet()? 2195 actions.getAction(0).getGet().getRow(): 2196 actions.getAction(0).getMutation().getRow()); 2197 return "region= " + getStringForByteString(actions.getRegion().getValue()) + 2198 ", for " + actionsCount + " action(s) and 1st row key=" + row; 2199 } else if (m instanceof ClientProtos.MutateRequest) { 2200 ClientProtos.MutateRequest r = (ClientProtos.MutateRequest) m; 2201 return "region= " + getStringForByteString(r.getRegion().getValue()) + 2202 ", row=" + getStringForByteString(r.getMutation().getRow()); 2203 } else if (m instanceof ClientProtos.CoprocessorServiceRequest) { 2204 ClientProtos.CoprocessorServiceRequest r = (ClientProtos.CoprocessorServiceRequest) m; 2205 return "coprocessorService= " + r.getCall().getServiceName() + ":" + r.getCall().getMethodName(); 2206 } 2207 return "TODO: " + m.getClass().toString(); 2208 } 2209 2210 private static String getStringForByteString(ByteString bs) { 2211 return Bytes.toStringBinary(bs.toByteArray()); 2212 } 2213 2214 /** 2215 * Print out some subset of a MutationProto rather than all of it and its data 2216 * @param proto Protobuf to print out 2217 * @return Short String of mutation proto 2218 */ 2219 static String toShortString(final MutationProto proto) { 2220 return "row=" + Bytes.toString(proto.getRow().toByteArray()) + 2221 ", type=" + proto.getMutateType().toString(); 2222 } 2223 2224 public static TableName toTableName(HBaseProtos.TableName tableNamePB) { 2225 return TableName.valueOf(tableNamePB.getNamespace().asReadOnlyByteBuffer(), 2226 tableNamePB.getQualifier().asReadOnlyByteBuffer()); 2227 } 2228 2229 public static HBaseProtos.TableName toProtoTableName(TableName tableName) { 2230 return HBaseProtos.TableName.newBuilder() 2231 .setNamespace(UnsafeByteOperations.unsafeWrap(tableName.getNamespace())) 2232 .setQualifier(UnsafeByteOperations.unsafeWrap(tableName.getQualifier())).build(); 2233 } 2234 2235 public static List<TableName> toTableNameList(List<HBaseProtos.TableName> tableNamesList) { 2236 if (tableNamesList == null) { 2237 return new ArrayList<>(); 2238 } 2239 return tableNamesList.stream().map(ProtobufUtil::toTableName).collect(Collectors.toList()); 2240 } 2241 2242 public static TableName[] getTableNameArray(List<HBaseProtos.TableName> tableNamesList) { 2243 if (tableNamesList == null) { 2244 return new TableName[0]; 2245 } 2246 TableName[] tableNames = new TableName[tableNamesList.size()]; 2247 for (int i = 0; i < tableNamesList.size(); i++) { 2248 tableNames[i] = toTableName(tableNamesList.get(i)); 2249 } 2250 return tableNames; 2251 } 2252 2253 /** 2254 * Convert a protocol buffer CellVisibility to a client CellVisibility 2255 * 2256 * @param proto 2257 * @return the converted client CellVisibility 2258 */ 2259 public static CellVisibility toCellVisibility(ClientProtos.CellVisibility proto) { 2260 if (proto == null) return null; 2261 return new CellVisibility(proto.getExpression()); 2262 } 2263 2264 /** 2265 * Convert a protocol buffer CellVisibility bytes to a client CellVisibility 2266 * 2267 * @param protoBytes 2268 * @return the converted client CellVisibility 2269 * @throws DeserializationException 2270 */ 2271 public static CellVisibility toCellVisibility(byte[] protoBytes) throws DeserializationException { 2272 if (protoBytes == null) return null; 2273 ClientProtos.CellVisibility.Builder builder = ClientProtos.CellVisibility.newBuilder(); 2274 ClientProtos.CellVisibility proto = null; 2275 try { 2276 ProtobufUtil.mergeFrom(builder, protoBytes); 2277 proto = builder.build(); 2278 } catch (IOException e) { 2279 throw new DeserializationException(e); 2280 } 2281 return toCellVisibility(proto); 2282 } 2283 2284 /** 2285 * Create a protocol buffer CellVisibility based on a client CellVisibility. 2286 * 2287 * @param cellVisibility 2288 * @return a protocol buffer CellVisibility 2289 */ 2290 public static ClientProtos.CellVisibility toCellVisibility(CellVisibility cellVisibility) { 2291 ClientProtos.CellVisibility.Builder builder = ClientProtos.CellVisibility.newBuilder(); 2292 builder.setExpression(cellVisibility.getExpression()); 2293 return builder.build(); 2294 } 2295 2296 /** 2297 * Convert a protocol buffer Authorizations to a client Authorizations 2298 * 2299 * @param proto 2300 * @return the converted client Authorizations 2301 */ 2302 public static Authorizations toAuthorizations(ClientProtos.Authorizations proto) { 2303 if (proto == null) return null; 2304 return new Authorizations(proto.getLabelList()); 2305 } 2306 2307 /** 2308 * Convert a protocol buffer Authorizations bytes to a client Authorizations 2309 * 2310 * @param protoBytes 2311 * @return the converted client Authorizations 2312 * @throws DeserializationException 2313 */ 2314 public static Authorizations toAuthorizations(byte[] protoBytes) throws DeserializationException { 2315 if (protoBytes == null) return null; 2316 ClientProtos.Authorizations.Builder builder = ClientProtos.Authorizations.newBuilder(); 2317 ClientProtos.Authorizations proto = null; 2318 try { 2319 ProtobufUtil.mergeFrom(builder, protoBytes); 2320 proto = builder.build(); 2321 } catch (IOException e) { 2322 throw new DeserializationException(e); 2323 } 2324 return toAuthorizations(proto); 2325 } 2326 2327 /** 2328 * Create a protocol buffer Authorizations based on a client Authorizations. 2329 * 2330 * @param authorizations 2331 * @return a protocol buffer Authorizations 2332 */ 2333 public static ClientProtos.Authorizations toAuthorizations(Authorizations authorizations) { 2334 ClientProtos.Authorizations.Builder builder = ClientProtos.Authorizations.newBuilder(); 2335 for (String label : authorizations.getLabels()) { 2336 builder.addLabel(label); 2337 } 2338 return builder.build(); 2339 } 2340 2341 /** 2342 * Convert a protocol buffer TimeUnit to a client TimeUnit 2343 * 2344 * @param proto 2345 * @return the converted client TimeUnit 2346 */ 2347 public static TimeUnit toTimeUnit(final HBaseProtos.TimeUnit proto) { 2348 switch (proto) { 2349 case NANOSECONDS: return TimeUnit.NANOSECONDS; 2350 case MICROSECONDS: return TimeUnit.MICROSECONDS; 2351 case MILLISECONDS: return TimeUnit.MILLISECONDS; 2352 case SECONDS: return TimeUnit.SECONDS; 2353 case MINUTES: return TimeUnit.MINUTES; 2354 case HOURS: return TimeUnit.HOURS; 2355 case DAYS: return TimeUnit.DAYS; 2356 } 2357 throw new RuntimeException("Invalid TimeUnit " + proto); 2358 } 2359 2360 /** 2361 * Convert a client TimeUnit to a protocol buffer TimeUnit 2362 * 2363 * @param timeUnit 2364 * @return the converted protocol buffer TimeUnit 2365 */ 2366 public static HBaseProtos.TimeUnit toProtoTimeUnit(final TimeUnit timeUnit) { 2367 switch (timeUnit) { 2368 case NANOSECONDS: return HBaseProtos.TimeUnit.NANOSECONDS; 2369 case MICROSECONDS: return HBaseProtos.TimeUnit.MICROSECONDS; 2370 case MILLISECONDS: return HBaseProtos.TimeUnit.MILLISECONDS; 2371 case SECONDS: return HBaseProtos.TimeUnit.SECONDS; 2372 case MINUTES: return HBaseProtos.TimeUnit.MINUTES; 2373 case HOURS: return HBaseProtos.TimeUnit.HOURS; 2374 case DAYS: return HBaseProtos.TimeUnit.DAYS; 2375 } 2376 throw new RuntimeException("Invalid TimeUnit " + timeUnit); 2377 } 2378 2379 /** 2380 * Convert a protocol buffer ThrottleType to a client ThrottleType 2381 * 2382 * @param proto 2383 * @return the converted client ThrottleType 2384 */ 2385 public static ThrottleType toThrottleType(final QuotaProtos.ThrottleType proto) { 2386 switch (proto) { 2387 case REQUEST_NUMBER: return ThrottleType.REQUEST_NUMBER; 2388 case REQUEST_SIZE: return ThrottleType.REQUEST_SIZE; 2389 case WRITE_NUMBER: return ThrottleType.WRITE_NUMBER; 2390 case WRITE_SIZE: return ThrottleType.WRITE_SIZE; 2391 case READ_NUMBER: return ThrottleType.READ_NUMBER; 2392 case READ_SIZE: return ThrottleType.READ_SIZE; 2393 } 2394 throw new RuntimeException("Invalid ThrottleType " + proto); 2395 } 2396 2397 /** 2398 * Convert a client ThrottleType to a protocol buffer ThrottleType 2399 * 2400 * @param type 2401 * @return the converted protocol buffer ThrottleType 2402 */ 2403 public static QuotaProtos.ThrottleType toProtoThrottleType(final ThrottleType type) { 2404 switch (type) { 2405 case REQUEST_NUMBER: return QuotaProtos.ThrottleType.REQUEST_NUMBER; 2406 case REQUEST_SIZE: return QuotaProtos.ThrottleType.REQUEST_SIZE; 2407 case WRITE_NUMBER: return QuotaProtos.ThrottleType.WRITE_NUMBER; 2408 case WRITE_SIZE: return QuotaProtos.ThrottleType.WRITE_SIZE; 2409 case READ_NUMBER: return QuotaProtos.ThrottleType.READ_NUMBER; 2410 case READ_SIZE: return QuotaProtos.ThrottleType.READ_SIZE; 2411 } 2412 throw new RuntimeException("Invalid ThrottleType " + type); 2413 } 2414 2415 /** 2416 * Convert a protocol buffer QuotaScope to a client QuotaScope 2417 * 2418 * @param proto 2419 * @return the converted client QuotaScope 2420 */ 2421 public static QuotaScope toQuotaScope(final QuotaProtos.QuotaScope proto) { 2422 switch (proto) { 2423 case CLUSTER: return QuotaScope.CLUSTER; 2424 case MACHINE: return QuotaScope.MACHINE; 2425 } 2426 throw new RuntimeException("Invalid QuotaScope " + proto); 2427 } 2428 2429 /** 2430 * Convert a client QuotaScope to a protocol buffer QuotaScope 2431 * 2432 * @param scope 2433 * @return the converted protocol buffer QuotaScope 2434 */ 2435 public static QuotaProtos.QuotaScope toProtoQuotaScope(final QuotaScope scope) { 2436 switch (scope) { 2437 case CLUSTER: return QuotaProtos.QuotaScope.CLUSTER; 2438 case MACHINE: return QuotaProtos.QuotaScope.MACHINE; 2439 } 2440 throw new RuntimeException("Invalid QuotaScope " + scope); 2441 } 2442 2443 /** 2444 * Convert a protocol buffer QuotaType to a client QuotaType 2445 * 2446 * @param proto 2447 * @return the converted client QuotaType 2448 */ 2449 public static QuotaType toQuotaScope(final QuotaProtos.QuotaType proto) { 2450 switch (proto) { 2451 case THROTTLE: return QuotaType.THROTTLE; 2452 case SPACE: return QuotaType.SPACE; 2453 } 2454 throw new RuntimeException("Invalid QuotaType " + proto); 2455 } 2456 2457 /** 2458 * Convert a client QuotaType to a protocol buffer QuotaType 2459 * 2460 * @param type 2461 * @return the converted protocol buffer QuotaType 2462 */ 2463 public static QuotaProtos.QuotaType toProtoQuotaScope(final QuotaType type) { 2464 switch (type) { 2465 case THROTTLE: return QuotaProtos.QuotaType.THROTTLE; 2466 case SPACE: return QuotaProtos.QuotaType.SPACE; 2467 default: throw new RuntimeException("Invalid QuotaType " + type); 2468 } 2469 } 2470 2471 /** 2472 * Converts a protocol buffer SpaceViolationPolicy to a client SpaceViolationPolicy. 2473 * 2474 * @param proto The protocol buffer space violation policy. 2475 * @return The corresponding client SpaceViolationPolicy. 2476 */ 2477 public static SpaceViolationPolicy toViolationPolicy( 2478 final QuotaProtos.SpaceViolationPolicy proto) { 2479 switch (proto) { 2480 case DISABLE: return SpaceViolationPolicy.DISABLE; 2481 case NO_WRITES_COMPACTIONS: return SpaceViolationPolicy.NO_WRITES_COMPACTIONS; 2482 case NO_WRITES: return SpaceViolationPolicy.NO_WRITES; 2483 case NO_INSERTS: return SpaceViolationPolicy.NO_INSERTS; 2484 } 2485 throw new RuntimeException("Invalid SpaceViolationPolicy " + proto); 2486 } 2487 2488 /** 2489 * Converts a client SpaceViolationPolicy to a protocol buffer SpaceViolationPolicy. 2490 * 2491 * @param policy The client SpaceViolationPolicy object. 2492 * @return The corresponding protocol buffer SpaceViolationPolicy. 2493 */ 2494 public static QuotaProtos.SpaceViolationPolicy toProtoViolationPolicy( 2495 final SpaceViolationPolicy policy) { 2496 switch (policy) { 2497 case DISABLE: return QuotaProtos.SpaceViolationPolicy.DISABLE; 2498 case NO_WRITES_COMPACTIONS: return QuotaProtos.SpaceViolationPolicy.NO_WRITES_COMPACTIONS; 2499 case NO_WRITES: return QuotaProtos.SpaceViolationPolicy.NO_WRITES; 2500 case NO_INSERTS: return QuotaProtos.SpaceViolationPolicy.NO_INSERTS; 2501 } 2502 throw new RuntimeException("Invalid SpaceViolationPolicy " + policy); 2503 } 2504 2505 /** 2506 * Build a protocol buffer TimedQuota 2507 * 2508 * @param limit the allowed number of request/data per timeUnit 2509 * @param timeUnit the limit time unit 2510 * @param scope the quota scope 2511 * @return the protocol buffer TimedQuota 2512 */ 2513 public static QuotaProtos.TimedQuota toTimedQuota(final long limit, final TimeUnit timeUnit, 2514 final QuotaScope scope) { 2515 return QuotaProtos.TimedQuota.newBuilder() 2516 .setSoftLimit(limit) 2517 .setTimeUnit(toProtoTimeUnit(timeUnit)) 2518 .setScope(toProtoQuotaScope(scope)) 2519 .build(); 2520 } 2521 2522 /** 2523 * Builds a protocol buffer SpaceQuota. 2524 * 2525 * @param limit The maximum space usage for the quota in bytes. 2526 * @param violationPolicy The policy to apply when the quota is violated. 2527 * @return The protocol buffer SpaceQuota. 2528 */ 2529 public static QuotaProtos.SpaceQuota toProtoSpaceQuota( 2530 final long limit, final SpaceViolationPolicy violationPolicy) { 2531 return QuotaProtos.SpaceQuota.newBuilder() 2532 .setSoftLimit(limit) 2533 .setViolationPolicy(toProtoViolationPolicy(violationPolicy)) 2534 .build(); 2535 } 2536 2537 /** 2538 * Generates a marker for the WAL so that we propagate the notion of a bulk region load 2539 * throughout the WAL. 2540 * 2541 * @param tableName The tableName into which the bulk load is being imported into. 2542 * @param encodedRegionName Encoded region name of the region which is being bulk loaded. 2543 * @param storeFiles A set of store files of a column family are bulk loaded. 2544 * @param storeFilesSize Map of store files and their lengths 2545 * @param bulkloadSeqId sequence ID (by a force flush) used to create bulk load hfile 2546 * name 2547 * @return The WAL log marker for bulk loads. 2548 */ 2549 public static WALProtos.BulkLoadDescriptor toBulkLoadDescriptor(TableName tableName, 2550 ByteString encodedRegionName, Map<byte[], List<Path>> storeFiles, 2551 Map<String, Long> storeFilesSize, long bulkloadSeqId) { 2552 BulkLoadDescriptor.Builder desc = 2553 BulkLoadDescriptor.newBuilder() 2554 .setTableName(ProtobufUtil.toProtoTableName(tableName)) 2555 .setEncodedRegionName(encodedRegionName).setBulkloadSeqNum(bulkloadSeqId); 2556 2557 for (Map.Entry<byte[], List<Path>> entry : storeFiles.entrySet()) { 2558 WALProtos.StoreDescriptor.Builder builder = StoreDescriptor.newBuilder() 2559 .setFamilyName(UnsafeByteOperations.unsafeWrap(entry.getKey())) 2560 .setStoreHomeDir(Bytes.toString(entry.getKey())); // relative to region 2561 for (Path path : entry.getValue()) { 2562 String name = path.getName(); 2563 builder.addStoreFile(name); 2564 Long size = storeFilesSize.get(name) == null ? (Long) 0L : storeFilesSize.get(name); 2565 builder.setStoreFileSizeBytes(size); 2566 } 2567 desc.addStores(builder); 2568 } 2569 2570 return desc.build(); 2571 } 2572 2573 /** 2574 * This version of protobuf's mergeDelimitedFrom avoid the hard-coded 64MB limit for decoding 2575 * buffers 2576 * @param builder current message builder 2577 * @param in Inputsream with delimited protobuf data 2578 * @throws IOException 2579 */ 2580 public static void mergeDelimitedFrom(Message.Builder builder, InputStream in) 2581 throws IOException { 2582 // This used to be builder.mergeDelimitedFrom(in); 2583 // but is replaced to allow us to bump the protobuf size limit. 2584 final int firstByte = in.read(); 2585 if (firstByte != -1) { 2586 final int size = CodedInputStream.readRawVarint32(firstByte, in); 2587 final InputStream limitedInput = ByteStreams.limit(in, size); 2588 final CodedInputStream codedInput = CodedInputStream.newInstance(limitedInput); 2589 codedInput.setSizeLimit(size); 2590 builder.mergeFrom(codedInput); 2591 codedInput.checkLastTagWas(0); 2592 } 2593 } 2594 2595 /** 2596 * This version of protobuf's mergeFrom avoids the hard-coded 64MB limit for decoding 2597 * buffers where the message size is known 2598 * @param builder current message builder 2599 * @param in InputStream containing protobuf data 2600 * @param size known size of protobuf data 2601 * @throws IOException 2602 */ 2603 public static void mergeFrom(Message.Builder builder, InputStream in, int size) 2604 throws IOException { 2605 final CodedInputStream codedInput = CodedInputStream.newInstance(in); 2606 codedInput.setSizeLimit(size); 2607 builder.mergeFrom(codedInput); 2608 codedInput.checkLastTagWas(0); 2609 } 2610 2611 /** 2612 * This version of protobuf's mergeFrom avoids the hard-coded 64MB limit for decoding 2613 * buffers where the message size is not known 2614 * @param builder current message builder 2615 * @param in InputStream containing protobuf data 2616 * @throws IOException 2617 */ 2618 public static void mergeFrom(Message.Builder builder, InputStream in) 2619 throws IOException { 2620 final CodedInputStream codedInput = CodedInputStream.newInstance(in); 2621 codedInput.setSizeLimit(Integer.MAX_VALUE); 2622 builder.mergeFrom(codedInput); 2623 codedInput.checkLastTagWas(0); 2624 } 2625 2626 /** 2627 * This version of protobuf's mergeFrom avoids the hard-coded 64MB limit for decoding 2628 * buffers when working with ByteStrings 2629 * @param builder current message builder 2630 * @param bs ByteString containing the 2631 * @throws IOException 2632 */ 2633 public static void mergeFrom(Message.Builder builder, ByteString bs) throws IOException { 2634 final CodedInputStream codedInput = bs.newCodedInput(); 2635 codedInput.setSizeLimit(bs.size()); 2636 builder.mergeFrom(codedInput); 2637 codedInput.checkLastTagWas(0); 2638 } 2639 2640 /** 2641 * This version of protobuf's mergeFrom avoids the hard-coded 64MB limit for decoding 2642 * buffers when working with byte arrays 2643 * @param builder current message builder 2644 * @param b byte array 2645 * @throws IOException 2646 */ 2647 public static void mergeFrom(Message.Builder builder, byte[] b) throws IOException { 2648 final CodedInputStream codedInput = CodedInputStream.newInstance(b); 2649 codedInput.setSizeLimit(b.length); 2650 builder.mergeFrom(codedInput); 2651 codedInput.checkLastTagWas(0); 2652 } 2653 2654 /** 2655 * This version of protobuf's mergeFrom avoids the hard-coded 64MB limit for decoding 2656 * buffers when working with byte arrays 2657 * @param builder current message builder 2658 * @param b byte array 2659 * @param offset 2660 * @param length 2661 * @throws IOException 2662 */ 2663 public static void mergeFrom(Message.Builder builder, byte[] b, int offset, int length) 2664 throws IOException { 2665 final CodedInputStream codedInput = CodedInputStream.newInstance(b, offset, length); 2666 codedInput.setSizeLimit(length); 2667 builder.mergeFrom(codedInput); 2668 codedInput.checkLastTagWas(0); 2669 } 2670 2671 public static void mergeFrom(Message.Builder builder, CodedInputStream codedInput, int length) 2672 throws IOException { 2673 codedInput.resetSizeCounter(); 2674 int prevLimit = codedInput.setSizeLimit(length); 2675 2676 int limit = codedInput.pushLimit(length); 2677 builder.mergeFrom(codedInput); 2678 codedInput.popLimit(limit); 2679 2680 codedInput.checkLastTagWas(0); 2681 codedInput.setSizeLimit(prevLimit); 2682 } 2683 2684 public static ReplicationLoadSink toReplicationLoadSink( 2685 ClusterStatusProtos.ReplicationLoadSink rls) { 2686 return new ReplicationLoadSink(rls.getAgeOfLastAppliedOp(), rls.getTimeStampsOfLastAppliedOp()); 2687 } 2688 2689 public static ReplicationLoadSource toReplicationLoadSource( 2690 ClusterStatusProtos.ReplicationLoadSource rls) { 2691 return new ReplicationLoadSource(rls.getPeerID(), rls.getAgeOfLastShippedOp(), 2692 rls.getSizeOfLogQueue(), rls.getTimeStampOfLastShippedOp(), rls.getReplicationLag()); 2693 } 2694 2695 /** 2696 * Get a protocol buffer VersionInfo 2697 * 2698 * @return the converted protocol buffer VersionInfo 2699 */ 2700 public static HBaseProtos.VersionInfo getVersionInfo() { 2701 HBaseProtos.VersionInfo.Builder builder = HBaseProtos.VersionInfo.newBuilder(); 2702 String version = VersionInfo.getVersion(); 2703 builder.setVersion(version); 2704 String[] components = version.split("\\."); 2705 if (components != null && components.length > 2) { 2706 builder.setVersionMajor(Integer.parseInt(components[0])); 2707 builder.setVersionMinor(Integer.parseInt(components[1])); 2708 } 2709 builder.setUrl(VersionInfo.getUrl()); 2710 builder.setRevision(VersionInfo.getRevision()); 2711 builder.setUser(VersionInfo.getUser()); 2712 builder.setDate(VersionInfo.getDate()); 2713 builder.setSrcChecksum(VersionInfo.getSrcChecksum()); 2714 return builder.build(); 2715 } 2716 2717 /** 2718 * Convert SecurityCapabilitiesResponse.Capability to SecurityCapability 2719 * @param capabilities capabilities returned in the SecurityCapabilitiesResponse message 2720 * @return the converted list of SecurityCapability elements 2721 */ 2722 public static List<SecurityCapability> toSecurityCapabilityList( 2723 List<MasterProtos.SecurityCapabilitiesResponse.Capability> capabilities) { 2724 List<SecurityCapability> scList = new ArrayList<>(capabilities.size()); 2725 for (MasterProtos.SecurityCapabilitiesResponse.Capability c: capabilities) { 2726 try { 2727 scList.add(SecurityCapability.valueOf(c.getNumber())); 2728 } catch (IllegalArgumentException e) { 2729 // Unknown capability, just ignore it. We don't understand the new capability 2730 // but don't care since by definition we cannot take advantage of it. 2731 } 2732 } 2733 return scList; 2734 } 2735 2736 public static TimeRange toTimeRange(HBaseProtos.TimeRange timeRange) { 2737 return timeRange == null ? 2738 TimeRange.allTime() : 2739 new TimeRange(timeRange.hasFrom() ? timeRange.getFrom() : 0, 2740 timeRange.hasTo() ? timeRange.getTo() : Long.MAX_VALUE); 2741 } 2742 2743 /** 2744 * Converts an ColumnFamilyDescriptor to ColumnFamilySchema 2745 * @param hcd the ColumnFamilySchema 2746 * @return Convert this instance to a the pb column family type 2747 */ 2748 public static ColumnFamilySchema toColumnFamilySchema(ColumnFamilyDescriptor hcd) { 2749 ColumnFamilySchema.Builder builder = ColumnFamilySchema.newBuilder(); 2750 builder.setName(UnsafeByteOperations.unsafeWrap(hcd.getName())); 2751 for (Map.Entry<Bytes, Bytes> e : hcd.getValues().entrySet()) { 2752 BytesBytesPair.Builder aBuilder = BytesBytesPair.newBuilder(); 2753 aBuilder.setFirst(UnsafeByteOperations.unsafeWrap(e.getKey().get())); 2754 aBuilder.setSecond(UnsafeByteOperations.unsafeWrap(e.getValue().get())); 2755 builder.addAttributes(aBuilder.build()); 2756 } 2757 for (Map.Entry<String, String> e : hcd.getConfiguration().entrySet()) { 2758 NameStringPair.Builder aBuilder = NameStringPair.newBuilder(); 2759 aBuilder.setName(e.getKey()); 2760 aBuilder.setValue(e.getValue()); 2761 builder.addConfiguration(aBuilder.build()); 2762 } 2763 return builder.build(); 2764 } 2765 2766 /** 2767 * Converts a ColumnFamilySchema to ColumnFamilyDescriptor 2768 * @param cfs the ColumnFamilySchema 2769 * @return An {@link ColumnFamilyDescriptor} made from the passed in <code>cfs</code> 2770 */ 2771 public static ColumnFamilyDescriptor toColumnFamilyDescriptor(final ColumnFamilySchema cfs) { 2772 // Use the empty constructor so we preserve the initial values set on construction for things 2773 // like maxVersion. Otherwise, we pick up wrong values on deserialization which makes for 2774 // unrelated-looking test failures that are hard to trace back to here. 2775 ColumnFamilyDescriptorBuilder builder 2776 = ColumnFamilyDescriptorBuilder.newBuilder(cfs.getName().toByteArray()); 2777 cfs.getAttributesList().forEach(a -> builder.setValue(a.getFirst().toByteArray(), a.getSecond().toByteArray())); 2778 cfs.getConfigurationList().forEach(a -> builder.setConfiguration(a.getName(), a.getValue())); 2779 return builder.build(); 2780 } 2781 2782 /** 2783 * Converts an TableDescriptor to TableSchema 2784 * @param htd the TableDescriptor 2785 * @return Convert the current {@link TableDescriptor} into a pb TableSchema instance. 2786 */ 2787 public static TableSchema toTableSchema(TableDescriptor htd) { 2788 TableSchema.Builder builder = TableSchema.newBuilder(); 2789 builder.setTableName(toProtoTableName(htd.getTableName())); 2790 for (Map.Entry<Bytes, Bytes> e : htd.getValues().entrySet()) { 2791 BytesBytesPair.Builder aBuilder = BytesBytesPair.newBuilder(); 2792 aBuilder.setFirst(UnsafeByteOperations.unsafeWrap(e.getKey().get())); 2793 aBuilder.setSecond(UnsafeByteOperations.unsafeWrap(e.getValue().get())); 2794 builder.addAttributes(aBuilder.build()); 2795 } 2796 for (ColumnFamilyDescriptor hcd : htd.getColumnFamilies()) { 2797 builder.addColumnFamilies(toColumnFamilySchema(hcd)); 2798 } 2799 return builder.build(); 2800 } 2801 2802 /** 2803 * Converts a TableSchema to TableDescriptor 2804 * @param ts A pb TableSchema instance. 2805 * @return An {@link TableDescriptor} made from the passed in pb <code>ts</code>. 2806 */ 2807 public static TableDescriptor toTableDescriptor(final TableSchema ts) { 2808 TableDescriptorBuilder builder 2809 = TableDescriptorBuilder.newBuilder(ProtobufUtil.toTableName(ts.getTableName())); 2810 ts.getColumnFamiliesList() 2811 .stream() 2812 .map(ProtobufUtil::toColumnFamilyDescriptor) 2813 .forEach(builder::setColumnFamily); 2814 ts.getAttributesList() 2815 .forEach(a -> builder.setValue(a.getFirst().toByteArray(), a.getSecond().toByteArray())); 2816 ts.getConfigurationList() 2817 .forEach(a -> builder.setValue(a.getName(), a.getValue())); 2818 return builder.build(); 2819 } 2820 2821 /** 2822 * Creates {@link CompactionState} from 2823 * {@link org.apache.hadoop.hbase.protobuf.generated.AdminProtos.GetRegionInfoResponse.CompactionState} 2824 * state 2825 * @param state the protobuf CompactionState 2826 * @return CompactionState 2827 */ 2828 public static CompactionState createCompactionState(GetRegionInfoResponse.CompactionState state) { 2829 return CompactionState.valueOf(state.toString()); 2830 } 2831 2832 public static GetRegionInfoResponse.CompactionState createCompactionState(CompactionState state) { 2833 return GetRegionInfoResponse.CompactionState.valueOf(state.toString()); 2834 } 2835 2836 public static Optional<Long> toOptionalTimestamp(MajorCompactionTimestampResponse resp) { 2837 long timestamp = resp.getCompactionTimestamp(); 2838 return timestamp == 0 ? Optional.empty() : Optional.of(timestamp); 2839 } 2840 2841 /** 2842 * Creates {@link org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.SnapshotDescription.Type} 2843 * from {@link SnapshotType} 2844 * @param type the SnapshotDescription type 2845 * @return the protobuf SnapshotDescription type 2846 */ 2847 public static SnapshotProtos.SnapshotDescription.Type 2848 createProtosSnapShotDescType(SnapshotType type) { 2849 return SnapshotProtos.SnapshotDescription.Type.valueOf(type.name()); 2850 } 2851 2852 /** 2853 * Creates {@link org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.SnapshotDescription.Type} 2854 * from the type of SnapshotDescription string 2855 * @param snapshotDesc string representing the snapshot description type 2856 * @return the protobuf SnapshotDescription type 2857 */ 2858 public static SnapshotProtos.SnapshotDescription.Type 2859 createProtosSnapShotDescType(String snapshotDesc) { 2860 return SnapshotProtos.SnapshotDescription.Type.valueOf(snapshotDesc.toUpperCase(Locale.ROOT)); 2861 } 2862 2863 /** 2864 * Creates {@link SnapshotType} from the type of 2865 * {@link org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.SnapshotDescription} 2866 * @param type the snapshot description type 2867 * @return the protobuf SnapshotDescription type 2868 */ 2869 public static SnapshotType createSnapshotType(SnapshotProtos.SnapshotDescription.Type type) { 2870 return SnapshotType.valueOf(type.toString()); 2871 } 2872 2873 /** 2874 * Convert from {@link SnapshotDescription} to 2875 * {@link org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.SnapshotDescription} 2876 * @param snapshotDesc the POJO SnapshotDescription 2877 * @return the protobuf SnapshotDescription 2878 */ 2879 public static SnapshotProtos.SnapshotDescription 2880 createHBaseProtosSnapshotDesc(SnapshotDescription snapshotDesc) { 2881 SnapshotProtos.SnapshotDescription.Builder builder = SnapshotProtos.SnapshotDescription.newBuilder(); 2882 if (snapshotDesc.getTableName() != null) { 2883 builder.setTable(snapshotDesc.getTableNameAsString()); 2884 } 2885 if (snapshotDesc.getName() != null) { 2886 builder.setName(snapshotDesc.getName()); 2887 } 2888 if (snapshotDesc.getOwner() != null) { 2889 builder.setOwner(snapshotDesc.getOwner()); 2890 } 2891 if (snapshotDesc.getCreationTime() != -1L) { 2892 builder.setCreationTime(snapshotDesc.getCreationTime()); 2893 } 2894 if (snapshotDesc.getVersion() != -1) { 2895 builder.setVersion(snapshotDesc.getVersion()); 2896 } 2897 builder.setType(ProtobufUtil.createProtosSnapShotDescType(snapshotDesc.getType())); 2898 SnapshotProtos.SnapshotDescription snapshot = builder.build(); 2899 return snapshot; 2900 } 2901 2902 /** 2903 * Convert from 2904 * {@link org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.SnapshotDescription} to 2905 * {@link SnapshotDescription} 2906 * @param snapshotDesc the protobuf SnapshotDescription 2907 * @return the POJO SnapshotDescription 2908 */ 2909 public static SnapshotDescription 2910 createSnapshotDesc(SnapshotProtos.SnapshotDescription snapshotDesc) { 2911 return new SnapshotDescription(snapshotDesc.getName(), 2912 snapshotDesc.hasTable() ? TableName.valueOf(snapshotDesc.getTable()) : null, 2913 createSnapshotType(snapshotDesc.getType()), snapshotDesc.getOwner(), 2914 snapshotDesc.getCreationTime(), snapshotDesc.getVersion()); 2915 } 2916 2917 public static RegionLoadStats createRegionLoadStats(ClientProtos.RegionLoadStats stats) { 2918 return new RegionLoadStats(stats.getMemStoreLoad(), stats.getHeapOccupancy(), 2919 stats.getCompactionPressure()); 2920 } 2921 2922 /** 2923 * @param msg 2924 * @return A String version of the passed in <code>msg</code> 2925 */ 2926 public static String toText(Message msg) { 2927 return TextFormat.shortDebugString(msg); 2928 } 2929 2930 public static byte [] toBytes(ByteString bs) { 2931 return bs.toByteArray(); 2932 } 2933 2934 /** 2935 * Contain ServiceException inside here. Take a callable that is doing our pb rpc and run it. 2936 * @throws IOException 2937 */ 2938 public static <T> T call(Callable<T> callable) throws IOException { 2939 try { 2940 return callable.call(); 2941 } catch (Exception e) { 2942 throw ProtobufUtil.handleRemoteException(e); 2943 } 2944 } 2945 2946 /** 2947 * Create a protocol buffer GetStoreFileRequest for a given region name 2948 * 2949 * @param regionName the name of the region to get info 2950 * @param family the family to get store file list 2951 * @return a protocol buffer GetStoreFileRequest 2952 */ 2953 public static GetStoreFileRequest 2954 buildGetStoreFileRequest(final byte[] regionName, final byte[] family) { 2955 GetStoreFileRequest.Builder builder = GetStoreFileRequest.newBuilder(); 2956 RegionSpecifier region = RequestConverter.buildRegionSpecifier( 2957 RegionSpecifierType.REGION_NAME, regionName); 2958 builder.setRegion(region); 2959 builder.addFamily(UnsafeByteOperations.unsafeWrap(family)); 2960 return builder.build(); 2961 } 2962 2963 /** 2964 * Create a CloseRegionRequest for a given region name 2965 * 2966 * @param regionName the name of the region to close 2967 * @return a CloseRegionRequest 2968 */ 2969 public static CloseRegionRequest buildCloseRegionRequest(ServerName server, 2970 final byte[] regionName) { 2971 return ProtobufUtil.buildCloseRegionRequest(server, regionName, null); 2972 } 2973 2974 public static CloseRegionRequest buildCloseRegionRequest(ServerName server, 2975 final byte[] regionName, ServerName destinationServer) { 2976 CloseRegionRequest.Builder builder = CloseRegionRequest.newBuilder(); 2977 RegionSpecifier region = RequestConverter.buildRegionSpecifier( 2978 RegionSpecifierType.REGION_NAME, regionName); 2979 builder.setRegion(region); 2980 if (destinationServer != null){ 2981 builder.setDestinationServer(toServerName(destinationServer)); 2982 } 2983 if (server != null) { 2984 builder.setServerStartCode(server.getStartcode()); 2985 } 2986 return builder.build(); 2987 } 2988 2989 public static ProcedureDescription buildProcedureDescription(String signature, String instance, 2990 Map<String, String> props) { 2991 ProcedureDescription.Builder builder = 2992 ProcedureDescription.newBuilder().setSignature(signature).setInstance(instance); 2993 if (props != null && !props.isEmpty()) { 2994 props.entrySet().forEach(entry -> builder.addConfiguration( 2995 NameStringPair.newBuilder().setName(entry.getKey()).setValue(entry.getValue()).build())); 2996 } 2997 return builder.build(); 2998 } 2999 3000 /** 3001 * Get a ServerName from the passed in data bytes. 3002 * @param data Data with a serialize server name in it; can handle the old style 3003 * servername where servername was host and port. Works too with data that 3004 * begins w/ the pb 'PBUF' magic and that is then followed by a protobuf that 3005 * has a serialized {@link ServerName} in it. 3006 * @return Returns null if <code>data</code> is null else converts passed data 3007 * to a ServerName instance. 3008 * @throws DeserializationException 3009 */ 3010 public static ServerName parseServerNameFrom(final byte [] data) throws DeserializationException { 3011 if (data == null || data.length <= 0) return null; 3012 if (ProtobufMagic.isPBMagicPrefix(data)) { 3013 int prefixLen = ProtobufMagic.lengthOfPBMagic(); 3014 try { 3015 ZooKeeperProtos.Master rss = 3016 ZooKeeperProtos.Master.PARSER.parseFrom(data, prefixLen, data.length - prefixLen); 3017 org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos.ServerName sn = 3018 rss.getMaster(); 3019 return ServerName.valueOf(sn.getHostName(), sn.getPort(), sn.getStartCode()); 3020 } catch (/*InvalidProtocolBufferException*/IOException e) { 3021 // A failed parse of the znode is pretty catastrophic. Rather than loop 3022 // retrying hoping the bad bytes will changes, and rather than change 3023 // the signature on this method to add an IOE which will send ripples all 3024 // over the code base, throw a RuntimeException. This should "never" happen. 3025 // Fail fast if it does. 3026 throw new DeserializationException(e); 3027 } 3028 } 3029 // The str returned could be old style -- pre hbase-1502 -- which was 3030 // hostname and port seperated by a colon rather than hostname, port and 3031 // startcode delimited by a ','. 3032 String str = Bytes.toString(data); 3033 int index = str.indexOf(ServerName.SERVERNAME_SEPARATOR); 3034 if (index != -1) { 3035 // Presume its ServerName serialized with versioned bytes. 3036 return ServerName.parseVersionedServerName(data); 3037 } 3038 // Presume it a hostname:port format. 3039 String hostname = Addressing.parseHostname(str); 3040 int port = Addressing.parsePort(str); 3041 return ServerName.valueOf(hostname, port, -1L); 3042 } 3043 3044 /** 3045 * Helper to convert the protobuf Procedure to JSON String 3046 * @return Convert the current Protocol Buffers Procedure to JSON String 3047 */ 3048 public static String toProcedureJson(List<ProcedureProtos.Procedure> procProtos) { 3049 JsonArray procJsons = new JsonArray(procProtos.size()); 3050 for (ProcedureProtos.Procedure procProto : procProtos) { 3051 try { 3052 JsonElement procJson = ProtobufMessageConverter.toJsonElement(procProto); 3053 procJsons.add(procJson); 3054 } catch (InvalidProtocolBufferException e) { 3055 procJsons.add(e.toString()); 3056 } 3057 } 3058 return procJsons.toString(); 3059 } 3060 3061 public static String toLockJson(List<LockServiceProtos.LockedResource> lockedResourceProtos) { 3062 JsonArray lockedResourceJsons = new JsonArray(lockedResourceProtos.size()); 3063 for (LockServiceProtos.LockedResource lockedResourceProto : lockedResourceProtos) { 3064 try { 3065 JsonElement lockedResourceJson = ProtobufMessageConverter.toJsonElement(lockedResourceProto); 3066 lockedResourceJsons.add(lockedResourceJson); 3067 } catch (InvalidProtocolBufferException e) { 3068 lockedResourceJsons.add(e.toString()); 3069 } 3070 } 3071 return lockedResourceJsons.toString(); 3072 } 3073 3074 /** 3075 * Convert a RegionInfo to a Proto RegionInfo 3076 * 3077 * @param info the RegionInfo to convert 3078 * @return the converted Proto RegionInfo 3079 */ 3080 public static HBaseProtos.RegionInfo toRegionInfo(final org.apache.hadoop.hbase.client.RegionInfo info) { 3081 if (info == null) return null; 3082 HBaseProtos.RegionInfo.Builder builder = HBaseProtos.RegionInfo.newBuilder(); 3083 builder.setTableName(ProtobufUtil.toProtoTableName(info.getTable())); 3084 builder.setRegionId(info.getRegionId()); 3085 if (info.getStartKey() != null) { 3086 builder.setStartKey(UnsafeByteOperations.unsafeWrap(info.getStartKey())); 3087 } 3088 if (info.getEndKey() != null) { 3089 builder.setEndKey(UnsafeByteOperations.unsafeWrap(info.getEndKey())); 3090 } 3091 builder.setOffline(info.isOffline()); 3092 builder.setSplit(info.isSplit()); 3093 builder.setReplicaId(info.getReplicaId()); 3094 return builder.build(); 3095 } 3096 3097 /** 3098 * Convert HBaseProto.RegionInfo to a RegionInfo 3099 * 3100 * @param proto the RegionInfo to convert 3101 * @return the converted RegionInfo 3102 */ 3103 public static org.apache.hadoop.hbase.client.RegionInfo toRegionInfo(final HBaseProtos.RegionInfo proto) { 3104 if (proto == null) return null; 3105 TableName tableName = ProtobufUtil.toTableName(proto.getTableName()); 3106 long regionId = proto.getRegionId(); 3107 int defaultReplicaId = org.apache.hadoop.hbase.client.RegionInfo.DEFAULT_REPLICA_ID; 3108 int replicaId = proto.hasReplicaId()? proto.getReplicaId(): defaultReplicaId; 3109 if (tableName.equals(TableName.META_TABLE_NAME) && replicaId == defaultReplicaId) { 3110 return RegionInfoBuilder.FIRST_META_REGIONINFO; 3111 } 3112 byte[] startKey = null; 3113 byte[] endKey = null; 3114 if (proto.hasStartKey()) { 3115 startKey = proto.getStartKey().toByteArray(); 3116 } 3117 if (proto.hasEndKey()) { 3118 endKey = proto.getEndKey().toByteArray(); 3119 } 3120 boolean split = false; 3121 if (proto.hasSplit()) { 3122 split = proto.getSplit(); 3123 } 3124 RegionInfoBuilder rib = RegionInfoBuilder.newBuilder(tableName) 3125 .setStartKey(startKey) 3126 .setEndKey(endKey) 3127 .setRegionId(regionId) 3128 .setReplicaId(replicaId) 3129 .setSplit(split); 3130 if (proto.hasOffline()) { 3131 rib.setOffline(proto.getOffline()); 3132 } 3133 return rib.build(); 3134 } 3135 3136 public static HBaseProtos.RegionLocation toRegionLocation(HRegionLocation loc) { 3137 HBaseProtos.RegionLocation.Builder builder = HBaseProtos.RegionLocation.newBuilder(); 3138 builder.setRegionInfo(toRegionInfo(loc.getRegion())); 3139 if (loc.getServerName() != null) { 3140 builder.setServerName(toServerName(loc.getServerName())); 3141 } 3142 builder.setSeqNum(loc.getSeqNum()); 3143 return builder.build(); 3144 } 3145 3146 public static HRegionLocation toRegionLocation(HBaseProtos.RegionLocation proto) { 3147 org.apache.hadoop.hbase.client.RegionInfo regionInfo = toRegionInfo(proto.getRegionInfo()); 3148 ServerName serverName = proto.hasServerName() ? toServerName(proto.getServerName()) : null; 3149 return new HRegionLocation(regionInfo, serverName, proto.getSeqNum()); 3150 } 3151 3152 public static List<SnapshotDescription> toSnapshotDescriptionList( 3153 GetCompletedSnapshotsResponse response, Pattern pattern) { 3154 return response.getSnapshotsList().stream().map(ProtobufUtil::createSnapshotDesc) 3155 .filter(snap -> pattern != null ? pattern.matcher(snap.getName()).matches() : true) 3156 .collect(Collectors.toList()); 3157 } 3158 3159 public static CacheEvictionStats toCacheEvictionStats( 3160 HBaseProtos.CacheEvictionStats stats) throws IOException{ 3161 CacheEvictionStatsBuilder builder = CacheEvictionStats.builder(); 3162 builder.withEvictedBlocks(stats.getEvictedBlocks()) 3163 .withMaxCacheSize(stats.getMaxCacheSize()); 3164 if (stats.getExceptionCount() > 0) { 3165 for (HBaseProtos.RegionExceptionMessage exception : stats.getExceptionList()) { 3166 HBaseProtos.RegionSpecifier rs = exception.getRegion(); 3167 byte[] regionName = rs.getValue().toByteArray(); 3168 builder.addException(regionName, ProtobufUtil.toException(exception.getException())); 3169 } 3170 } 3171 return builder.build(); 3172 } 3173 3174 public static HBaseProtos.CacheEvictionStats toCacheEvictionStats( 3175 CacheEvictionStats cacheEvictionStats) { 3176 HBaseProtos.CacheEvictionStats.Builder builder 3177 = HBaseProtos.CacheEvictionStats.newBuilder(); 3178 for (Map.Entry<byte[], Throwable> entry : cacheEvictionStats.getExceptions().entrySet()) { 3179 builder.addException( 3180 RegionExceptionMessage.newBuilder() 3181 .setRegion(RequestConverter.buildRegionSpecifier( 3182 RegionSpecifierType.REGION_NAME, entry.getKey())) 3183 .setException(ResponseConverter.buildException(entry.getValue())) 3184 .build() 3185 ); 3186 } 3187 return builder 3188 .setEvictedBlocks(cacheEvictionStats.getEvictedBlocks()) 3189 .setMaxCacheSize(cacheEvictionStats.getMaxCacheSize()) 3190 .build(); 3191 } 3192 3193 public static ClusterStatusProtos.ReplicationLoadSource toReplicationLoadSource( 3194 ReplicationLoadSource rls) { 3195 return ClusterStatusProtos.ReplicationLoadSource.newBuilder() 3196 .setPeerID(rls.getPeerID()) 3197 .setAgeOfLastShippedOp(rls.getAgeOfLastShippedOp()) 3198 .setSizeOfLogQueue((int) rls.getSizeOfLogQueue()) 3199 .setTimeStampOfLastShippedOp(rls.getTimestampOfLastShippedOp()) 3200 .setReplicationLag(rls.getReplicationLag()) 3201 .build(); 3202 } 3203 3204 public static ClusterStatusProtos.ReplicationLoadSink toReplicationLoadSink( 3205 ReplicationLoadSink rls) { 3206 return ClusterStatusProtos.ReplicationLoadSink.newBuilder() 3207 .setAgeOfLastAppliedOp(rls.getAgeOfLastAppliedOp()) 3208 .setTimeStampsOfLastAppliedOp(rls.getTimestampsOfLastAppliedOp()) 3209 .build(); 3210 } 3211 3212 public static HBaseProtos.TimeRange toTimeRange(TimeRange timeRange) { 3213 if (timeRange == null) { 3214 timeRange = TimeRange.allTime(); 3215 } 3216 return HBaseProtos.TimeRange.newBuilder().setFrom(timeRange.getMin()) 3217 .setTo(timeRange.getMax()) 3218 .build(); 3219 } 3220}