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 if (scan.includeStopRow()) { 1083 scanBuilder.setIncludeStopRow(true); 1084 } 1085 if (scan.getReadType() != Scan.ReadType.DEFAULT) { 1086 scanBuilder.setReadType(toReadType(scan.getReadType())); 1087 } 1088 if (scan.isNeedCursorResult()) { 1089 scanBuilder.setNeedCursorResult(true); 1090 } 1091 return scanBuilder.build(); 1092 } 1093 1094 /** 1095 * Convert a protocol buffer Scan to a client Scan 1096 * 1097 * @param proto the protocol buffer Scan to convert 1098 * @return the converted client Scan 1099 * @throws IOException 1100 */ 1101 public static Scan toScan( 1102 final ClientProtos.Scan proto) throws IOException { 1103 byte[] startRow = HConstants.EMPTY_START_ROW; 1104 byte[] stopRow = HConstants.EMPTY_END_ROW; 1105 boolean includeStartRow = true; 1106 boolean includeStopRow = false; 1107 if (proto.hasStartRow()) { 1108 startRow = proto.getStartRow().toByteArray(); 1109 } 1110 if (proto.hasStopRow()) { 1111 stopRow = proto.getStopRow().toByteArray(); 1112 } 1113 if (proto.hasIncludeStartRow()) { 1114 includeStartRow = proto.getIncludeStartRow(); 1115 } 1116 if (proto.hasIncludeStopRow()) { 1117 includeStopRow = proto.getIncludeStopRow(); 1118 } else { 1119 // old client without this flag, we should consider start=end as a get. 1120 if (ClientUtil.areScanStartRowAndStopRowEqual(startRow, stopRow)) { 1121 includeStopRow = true; 1122 } 1123 } 1124 Scan scan = 1125 new Scan().withStartRow(startRow, includeStartRow).withStopRow(stopRow, includeStopRow); 1126 if (proto.hasCacheBlocks()) { 1127 scan.setCacheBlocks(proto.getCacheBlocks()); 1128 } 1129 if (proto.hasMaxVersions()) { 1130 scan.setMaxVersions(proto.getMaxVersions()); 1131 } 1132 if (proto.hasStoreLimit()) { 1133 scan.setMaxResultsPerColumnFamily(proto.getStoreLimit()); 1134 } 1135 if (proto.hasStoreOffset()) { 1136 scan.setRowOffsetPerColumnFamily(proto.getStoreOffset()); 1137 } 1138 if (proto.hasLoadColumnFamiliesOnDemand()) { 1139 scan.setLoadColumnFamiliesOnDemand(proto.getLoadColumnFamiliesOnDemand()); 1140 } 1141 if (proto.getCfTimeRangeCount() > 0) { 1142 for (HBaseProtos.ColumnFamilyTimeRange cftr : proto.getCfTimeRangeList()) { 1143 TimeRange timeRange = toTimeRange(cftr.getTimeRange()); 1144 scan.setColumnFamilyTimeRange(cftr.getColumnFamily().toByteArray(), 1145 timeRange.getMin(), timeRange.getMax()); 1146 } 1147 } 1148 if (proto.hasTimeRange()) { 1149 TimeRange timeRange = toTimeRange(proto.getTimeRange()); 1150 scan.setTimeRange(timeRange.getMin(), timeRange.getMax()); 1151 } 1152 if (proto.hasFilter()) { 1153 FilterProtos.Filter filter = proto.getFilter(); 1154 scan.setFilter(ProtobufUtil.toFilter(filter)); 1155 } 1156 if (proto.hasBatchSize()) { 1157 scan.setBatch(proto.getBatchSize()); 1158 } 1159 if (proto.hasMaxResultSize()) { 1160 scan.setMaxResultSize(proto.getMaxResultSize()); 1161 } 1162 if (proto.hasSmall()) { 1163 scan.setSmall(proto.getSmall()); 1164 } 1165 if (proto.hasAllowPartialResults()) { 1166 scan.setAllowPartialResults(proto.getAllowPartialResults()); 1167 } 1168 for (NameBytesPair attribute: proto.getAttributeList()) { 1169 scan.setAttribute(attribute.getName(), attribute.getValue().toByteArray()); 1170 } 1171 if (proto.getColumnCount() > 0) { 1172 for (Column column: proto.getColumnList()) { 1173 byte[] family = column.getFamily().toByteArray(); 1174 if (column.getQualifierCount() > 0) { 1175 for (ByteString qualifier: column.getQualifierList()) { 1176 scan.addColumn(family, qualifier.toByteArray()); 1177 } 1178 } else { 1179 scan.addFamily(family); 1180 } 1181 } 1182 } 1183 if (proto.hasReversed()) { 1184 scan.setReversed(proto.getReversed()); 1185 } 1186 if (proto.hasConsistency()) { 1187 scan.setConsistency(toConsistency(proto.getConsistency())); 1188 } 1189 if (proto.hasCaching()) { 1190 scan.setCaching(proto.getCaching()); 1191 } 1192 if (proto.hasMvccReadPoint()) { 1193 PackagePrivateFieldAccessor.setMvccReadPoint(scan, proto.getMvccReadPoint()); 1194 } 1195 if (scan.isSmall()) { 1196 scan.setReadType(Scan.ReadType.PREAD); 1197 } else if (proto.hasReadType()) { 1198 scan.setReadType(toReadType(proto.getReadType())); 1199 } 1200 if (proto.getNeedCursorResult()) { 1201 scan.setNeedCursorResult(true); 1202 } 1203 return scan; 1204 } 1205 1206 public static ClientProtos.Cursor toCursor(Cursor cursor) { 1207 ClientProtos.Cursor.Builder builder = ClientProtos.Cursor.newBuilder(); 1208 ClientProtos.Cursor.newBuilder().setRow(ByteString.copyFrom(cursor.getRow())); 1209 return builder.build(); 1210 } 1211 1212 public static ClientProtos.Cursor toCursor(Cell cell) { 1213 return ClientProtos.Cursor.newBuilder() 1214 .setRow(ByteString.copyFrom(cell.getRowArray(), cell.getRowOffset(), cell.getRowLength())) 1215 .build(); 1216 } 1217 1218 public static Cursor toCursor(ClientProtos.Cursor cursor) { 1219 return ClientUtil.createCursor(cursor.getRow().toByteArray()); 1220 } 1221 1222 /** 1223 * Create a protocol buffer Get based on a client Get. 1224 * 1225 * @param get the client Get 1226 * @return a protocol buffer Get 1227 * @throws IOException 1228 */ 1229 public static ClientProtos.Get toGet( 1230 final Get get) throws IOException { 1231 ClientProtos.Get.Builder builder = 1232 ClientProtos.Get.newBuilder(); 1233 builder.setRow(UnsafeByteOperations.unsafeWrap(get.getRow())); 1234 builder.setCacheBlocks(get.getCacheBlocks()); 1235 builder.setMaxVersions(get.getMaxVersions()); 1236 if (get.getFilter() != null) { 1237 builder.setFilter(ProtobufUtil.toFilter(get.getFilter())); 1238 } 1239 get.getColumnFamilyTimeRange().forEach((cf, timeRange) -> { 1240 builder.addCfTimeRange(HBaseProtos.ColumnFamilyTimeRange.newBuilder() 1241 .setColumnFamily(UnsafeByteOperations.unsafeWrap(cf)) 1242 .setTimeRange(toTimeRange(timeRange)) 1243 .build()); 1244 }); 1245 builder.setTimeRange(ProtobufUtil.toTimeRange(get.getTimeRange())); 1246 Map<String, byte[]> attributes = get.getAttributesMap(); 1247 if (!attributes.isEmpty()) { 1248 NameBytesPair.Builder attributeBuilder = NameBytesPair.newBuilder(); 1249 for (Map.Entry<String, byte[]> attribute: attributes.entrySet()) { 1250 attributeBuilder.setName(attribute.getKey()); 1251 attributeBuilder.setValue(UnsafeByteOperations.unsafeWrap(attribute.getValue())); 1252 builder.addAttribute(attributeBuilder.build()); 1253 } 1254 } 1255 if (get.hasFamilies()) { 1256 Column.Builder columnBuilder = Column.newBuilder(); 1257 Map<byte[], NavigableSet<byte[]>> families = get.getFamilyMap(); 1258 for (Map.Entry<byte[], NavigableSet<byte[]>> family: families.entrySet()) { 1259 NavigableSet<byte[]> qualifiers = family.getValue(); 1260 columnBuilder.setFamily(UnsafeByteOperations.unsafeWrap(family.getKey())); 1261 columnBuilder.clearQualifier(); 1262 if (qualifiers != null && qualifiers.size() > 0) { 1263 for (byte[] qualifier: qualifiers) { 1264 columnBuilder.addQualifier(UnsafeByteOperations.unsafeWrap(qualifier)); 1265 } 1266 } 1267 builder.addColumn(columnBuilder.build()); 1268 } 1269 } 1270 if (get.getMaxResultsPerColumnFamily() >= 0) { 1271 builder.setStoreLimit(get.getMaxResultsPerColumnFamily()); 1272 } 1273 if (get.getRowOffsetPerColumnFamily() > 0) { 1274 builder.setStoreOffset(get.getRowOffsetPerColumnFamily()); 1275 } 1276 if (get.isCheckExistenceOnly()){ 1277 builder.setExistenceOnly(true); 1278 } 1279 if (get.getConsistency() != null && get.getConsistency() != Consistency.STRONG) { 1280 builder.setConsistency(toConsistency(get.getConsistency())); 1281 } 1282 1283 Boolean loadColumnFamiliesOnDemand = get.getLoadColumnFamiliesOnDemandValue(); 1284 if (loadColumnFamiliesOnDemand != null) { 1285 builder.setLoadColumnFamiliesOnDemand(loadColumnFamiliesOnDemand); 1286 } 1287 return builder.build(); 1288 } 1289 1290 public static MutationProto toMutation(final MutationType type, final Mutation mutation) 1291 throws IOException { 1292 return toMutation(type, mutation, HConstants.NO_NONCE); 1293 } 1294 1295 /** 1296 * Create a protocol buffer Mutate based on a client Mutation 1297 * 1298 * @param type 1299 * @param mutation 1300 * @return a protobuf'd Mutation 1301 * @throws IOException 1302 */ 1303 public static MutationProto toMutation(final MutationType type, final Mutation mutation, 1304 final long nonce) throws IOException { 1305 return toMutation(type, mutation, MutationProto.newBuilder(), nonce); 1306 } 1307 1308 public static MutationProto toMutation(final MutationType type, final Mutation mutation, 1309 MutationProto.Builder builder) throws IOException { 1310 return toMutation(type, mutation, builder, HConstants.NO_NONCE); 1311 } 1312 1313 public static MutationProto toMutation(final MutationType type, final Mutation mutation, 1314 MutationProto.Builder builder, long nonce) 1315 throws IOException { 1316 builder = getMutationBuilderAndSetCommonFields(type, mutation, builder); 1317 if (nonce != HConstants.NO_NONCE) { 1318 builder.setNonce(nonce); 1319 } 1320 if (type == MutationType.INCREMENT) { 1321 builder.setTimeRange(ProtobufUtil.toTimeRange(((Increment) mutation).getTimeRange())); 1322 } 1323 if (type == MutationType.APPEND) { 1324 builder.setTimeRange(ProtobufUtil.toTimeRange(((Append) mutation).getTimeRange())); 1325 } 1326 ColumnValue.Builder columnBuilder = ColumnValue.newBuilder(); 1327 QualifierValue.Builder valueBuilder = QualifierValue.newBuilder(); 1328 for (Map.Entry<byte[],List<Cell>> family: mutation.getFamilyCellMap().entrySet()) { 1329 columnBuilder.clear(); 1330 columnBuilder.setFamily(UnsafeByteOperations.unsafeWrap(family.getKey())); 1331 for (Cell cell: family.getValue()) { 1332 valueBuilder.clear(); 1333 valueBuilder.setQualifier(UnsafeByteOperations.unsafeWrap( 1334 cell.getQualifierArray(), cell.getQualifierOffset(), cell.getQualifierLength())); 1335 valueBuilder.setValue(UnsafeByteOperations.unsafeWrap( 1336 cell.getValueArray(), cell.getValueOffset(), cell.getValueLength())); 1337 valueBuilder.setTimestamp(cell.getTimestamp()); 1338 if (type == MutationType.DELETE || (type == MutationType.PUT && CellUtil.isDelete(cell))) { 1339 KeyValue.Type keyValueType = KeyValue.Type.codeToType(cell.getTypeByte()); 1340 valueBuilder.setDeleteType(toDeleteType(keyValueType)); 1341 } 1342 columnBuilder.addQualifierValue(valueBuilder.build()); 1343 } 1344 builder.addColumnValue(columnBuilder.build()); 1345 } 1346 return builder.build(); 1347 } 1348 1349 /** 1350 * Create a protocol buffer MutationProto based on a client Mutation. Does NOT include data. 1351 * Understanding is that the Cell will be transported other than via protobuf. 1352 * @param type 1353 * @param mutation 1354 * @param builder 1355 * @return a protobuf'd Mutation 1356 * @throws IOException 1357 */ 1358 public static MutationProto toMutationNoData(final MutationType type, final Mutation mutation, 1359 final MutationProto.Builder builder) throws IOException { 1360 return toMutationNoData(type, mutation, builder, HConstants.NO_NONCE); 1361 } 1362 1363 /** 1364 * Create a protocol buffer MutationProto based on a client Mutation. Does NOT include data. 1365 * Understanding is that the Cell will be transported other than via protobuf. 1366 * @param type 1367 * @param mutation 1368 * @return a protobuf'd Mutation 1369 * @throws IOException 1370 */ 1371 public static MutationProto toMutationNoData(final MutationType type, final Mutation mutation) 1372 throws IOException { 1373 MutationProto.Builder builder = MutationProto.newBuilder(); 1374 return toMutationNoData(type, mutation, builder); 1375 } 1376 1377 public static MutationProto toMutationNoData(final MutationType type, final Mutation mutation, 1378 final MutationProto.Builder builder, long nonce) throws IOException { 1379 getMutationBuilderAndSetCommonFields(type, mutation, builder); 1380 builder.setAssociatedCellCount(mutation.size()); 1381 if (mutation instanceof Increment) { 1382 builder.setTimeRange(ProtobufUtil.toTimeRange(((Increment) mutation).getTimeRange())); 1383 } 1384 if (mutation instanceof Append) { 1385 builder.setTimeRange(ProtobufUtil.toTimeRange(((Append) mutation).getTimeRange())); 1386 } 1387 if (nonce != HConstants.NO_NONCE) { 1388 builder.setNonce(nonce); 1389 } 1390 return builder.build(); 1391 } 1392 1393 /** 1394 * Code shared by {@link #toMutation(MutationType, Mutation)} and 1395 * {@link #toMutationNoData(MutationType, Mutation)} 1396 * @param type 1397 * @param mutation 1398 * @return A partly-filled out protobuf'd Mutation. 1399 */ 1400 private static MutationProto.Builder getMutationBuilderAndSetCommonFields(final MutationType type, 1401 final Mutation mutation, MutationProto.Builder builder) { 1402 builder.setRow(UnsafeByteOperations.unsafeWrap(mutation.getRow())); 1403 builder.setMutateType(type); 1404 builder.setDurability(toDurability(mutation.getDurability())); 1405 builder.setTimestamp(mutation.getTimestamp()); 1406 Map<String, byte[]> attributes = mutation.getAttributesMap(); 1407 if (!attributes.isEmpty()) { 1408 NameBytesPair.Builder attributeBuilder = NameBytesPair.newBuilder(); 1409 for (Map.Entry<String, byte[]> attribute: attributes.entrySet()) { 1410 attributeBuilder.setName(attribute.getKey()); 1411 attributeBuilder.setValue(UnsafeByteOperations.unsafeWrap(attribute.getValue())); 1412 builder.addAttribute(attributeBuilder.build()); 1413 } 1414 } 1415 return builder; 1416 } 1417 1418 /** 1419 * Convert a client Result to a protocol buffer Result 1420 * 1421 * @param result the client Result to convert 1422 * @return the converted protocol buffer Result 1423 */ 1424 public static ClientProtos.Result toResult(final Result result) { 1425 if (result.getExists() != null) { 1426 return toResult(result.getExists(), result.isStale()); 1427 } 1428 1429 Cell[] cells = result.rawCells(); 1430 if (cells == null || cells.length == 0) { 1431 return result.isStale() ? EMPTY_RESULT_PB_STALE : EMPTY_RESULT_PB; 1432 } 1433 1434 ClientProtos.Result.Builder builder = ClientProtos.Result.newBuilder(); 1435 for (Cell c : cells) { 1436 builder.addCell(toCell(c)); 1437 } 1438 1439 builder.setStale(result.isStale()); 1440 builder.setPartial(result.mayHaveMoreCellsInRow()); 1441 1442 return builder.build(); 1443 } 1444 1445 /** 1446 * Convert a client Result to a protocol buffer Result 1447 * 1448 * @param existence the client existence to send 1449 * @return the converted protocol buffer Result 1450 */ 1451 public static ClientProtos.Result toResult(final boolean existence, boolean stale) { 1452 if (stale){ 1453 return existence ? EMPTY_RESULT_PB_EXISTS_TRUE_STALE : EMPTY_RESULT_PB_EXISTS_FALSE_STALE; 1454 } else { 1455 return existence ? EMPTY_RESULT_PB_EXISTS_TRUE : EMPTY_RESULT_PB_EXISTS_FALSE; 1456 } 1457 } 1458 1459 /** 1460 * Convert a client Result to a protocol buffer Result. 1461 * The pb Result does not include the Cell data. That is for transport otherwise. 1462 * 1463 * @param result the client Result to convert 1464 * @return the converted protocol buffer Result 1465 */ 1466 public static ClientProtos.Result toResultNoData(final Result result) { 1467 if (result.getExists() != null) return toResult(result.getExists(), result.isStale()); 1468 int size = result.size(); 1469 if (size == 0) return result.isStale() ? EMPTY_RESULT_PB_STALE : EMPTY_RESULT_PB; 1470 ClientProtos.Result.Builder builder = ClientProtos.Result.newBuilder(); 1471 builder.setAssociatedCellCount(size); 1472 builder.setStale(result.isStale()); 1473 return builder.build(); 1474 } 1475 1476 /** 1477 * Convert a protocol buffer Result to a client Result 1478 * 1479 * @param proto the protocol buffer Result to convert 1480 * @return the converted client Result 1481 */ 1482 public static Result toResult(final ClientProtos.Result proto) { 1483 if (proto.hasExists()) { 1484 if (proto.getStale()) { 1485 return proto.getExists() ? EMPTY_RESULT_EXISTS_TRUE_STALE :EMPTY_RESULT_EXISTS_FALSE_STALE; 1486 } 1487 return proto.getExists() ? EMPTY_RESULT_EXISTS_TRUE : EMPTY_RESULT_EXISTS_FALSE; 1488 } 1489 1490 List<CellProtos.Cell> values = proto.getCellList(); 1491 if (values.isEmpty()){ 1492 return proto.getStale() ? EMPTY_RESULT_STALE : EMPTY_RESULT; 1493 } 1494 1495 List<Cell> cells = new ArrayList<>(values.size()); 1496 ExtendedCellBuilder builder = ExtendedCellBuilderFactory.create(CellBuilderType.SHALLOW_COPY); 1497 for (CellProtos.Cell c : values) { 1498 cells.add(toCell(builder, c)); 1499 } 1500 return Result.create(cells, null, proto.getStale(), proto.getPartial()); 1501 } 1502 1503 /** 1504 * Convert a protocol buffer Result to a client Result 1505 * 1506 * @param proto the protocol buffer Result to convert 1507 * @param scanner Optional cell scanner. 1508 * @return the converted client Result 1509 * @throws IOException 1510 */ 1511 public static Result toResult(final ClientProtos.Result proto, final CellScanner scanner) 1512 throws IOException { 1513 List<CellProtos.Cell> values = proto.getCellList(); 1514 1515 if (proto.hasExists()) { 1516 if ((values != null && !values.isEmpty()) || 1517 (proto.hasAssociatedCellCount() && proto.getAssociatedCellCount() > 0)) { 1518 throw new IllegalArgumentException("bad proto: exists with cells is no allowed " + proto); 1519 } 1520 if (proto.getStale()) { 1521 return proto.getExists() ? EMPTY_RESULT_EXISTS_TRUE_STALE :EMPTY_RESULT_EXISTS_FALSE_STALE; 1522 } 1523 return proto.getExists() ? EMPTY_RESULT_EXISTS_TRUE : EMPTY_RESULT_EXISTS_FALSE; 1524 } 1525 1526 // TODO: Unit test that has some Cells in scanner and some in the proto. 1527 List<Cell> cells = null; 1528 if (proto.hasAssociatedCellCount()) { 1529 int count = proto.getAssociatedCellCount(); 1530 cells = new ArrayList<>(count + values.size()); 1531 for (int i = 0; i < count; i++) { 1532 if (!scanner.advance()) throw new IOException("Failed get " + i + " of " + count); 1533 cells.add(scanner.current()); 1534 } 1535 } 1536 1537 if (!values.isEmpty()){ 1538 if (cells == null) cells = new ArrayList<>(values.size()); 1539 ExtendedCellBuilder builder = ExtendedCellBuilderFactory.create(CellBuilderType.SHALLOW_COPY); 1540 for (CellProtos.Cell c: values) { 1541 cells.add(toCell(builder, c)); 1542 } 1543 } 1544 1545 return (cells == null || cells.isEmpty()) 1546 ? (proto.getStale() ? EMPTY_RESULT_STALE : EMPTY_RESULT) 1547 : Result.create(cells, null, proto.getStale()); 1548 } 1549 1550 1551 /** 1552 * Convert a ByteArrayComparable to a protocol buffer Comparator 1553 * 1554 * @param comparator the ByteArrayComparable to convert 1555 * @return the converted protocol buffer Comparator 1556 */ 1557 public static ComparatorProtos.Comparator toComparator(ByteArrayComparable comparator) { 1558 ComparatorProtos.Comparator.Builder builder = ComparatorProtos.Comparator.newBuilder(); 1559 builder.setName(comparator.getClass().getName()); 1560 builder.setSerializedComparator(UnsafeByteOperations.unsafeWrap(comparator.toByteArray())); 1561 return builder.build(); 1562 } 1563 1564 /** 1565 * Convert a protocol buffer Comparator to a ByteArrayComparable 1566 * 1567 * @param proto the protocol buffer Comparator to convert 1568 * @return the converted ByteArrayComparable 1569 */ 1570 @SuppressWarnings("unchecked") 1571 public static ByteArrayComparable toComparator(ComparatorProtos.Comparator proto) 1572 throws IOException { 1573 String type = proto.getName(); 1574 String funcName = "parseFrom"; 1575 byte [] value = proto.getSerializedComparator().toByteArray(); 1576 try { 1577 Class<?> c = Class.forName(type, true, ClassLoaderHolder.CLASS_LOADER); 1578 Method parseFrom = c.getMethod(funcName, byte[].class); 1579 if (parseFrom == null) { 1580 throw new IOException("Unable to locate function: " + funcName + " in type: " + type); 1581 } 1582 return (ByteArrayComparable)parseFrom.invoke(null, value); 1583 } catch (Exception e) { 1584 throw new IOException(e); 1585 } 1586 } 1587 1588 /** 1589 * Convert a protocol buffer Filter to a client Filter 1590 * 1591 * @param proto the protocol buffer Filter to convert 1592 * @return the converted Filter 1593 */ 1594 @SuppressWarnings("unchecked") 1595 public static Filter toFilter(FilterProtos.Filter proto) throws IOException { 1596 String type = proto.getName(); 1597 final byte [] value = proto.getSerializedFilter().toByteArray(); 1598 String funcName = "parseFrom"; 1599 try { 1600 Class<?> c = Class.forName(type, true, ClassLoaderHolder.CLASS_LOADER); 1601 Method parseFrom = c.getMethod(funcName, byte[].class); 1602 if (parseFrom == null) { 1603 throw new IOException("Unable to locate function: " + funcName + " in type: " + type); 1604 } 1605 return (Filter)parseFrom.invoke(c, value); 1606 } catch (Exception e) { 1607 // Either we couldn't instantiate the method object, or "parseFrom" failed. 1608 // In either case, let's not retry. 1609 throw new DoNotRetryIOException(e); 1610 } 1611 } 1612 1613 /** 1614 * Convert a client Filter to a protocol buffer Filter 1615 * 1616 * @param filter the Filter to convert 1617 * @return the converted protocol buffer Filter 1618 */ 1619 public static FilterProtos.Filter toFilter(Filter filter) throws IOException { 1620 FilterProtos.Filter.Builder builder = FilterProtos.Filter.newBuilder(); 1621 builder.setName(filter.getClass().getName()); 1622 builder.setSerializedFilter(UnsafeByteOperations.unsafeWrap(filter.toByteArray())); 1623 return builder.build(); 1624 } 1625 1626 /** 1627 * Convert a delete KeyValue type to protocol buffer DeleteType. 1628 * 1629 * @param type 1630 * @return protocol buffer DeleteType 1631 * @throws IOException 1632 */ 1633 public static DeleteType toDeleteType( 1634 KeyValue.Type type) throws IOException { 1635 switch (type) { 1636 case Delete: 1637 return DeleteType.DELETE_ONE_VERSION; 1638 case DeleteColumn: 1639 return DeleteType.DELETE_MULTIPLE_VERSIONS; 1640 case DeleteFamily: 1641 return DeleteType.DELETE_FAMILY; 1642 case DeleteFamilyVersion: 1643 return DeleteType.DELETE_FAMILY_VERSION; 1644 default: 1645 throw new IOException("Unknown delete type: " + type); 1646 } 1647 } 1648 1649 /** 1650 * Convert a protocol buffer DeleteType to delete KeyValue type. 1651 * 1652 * @param type The DeleteType 1653 * @return The type. 1654 * @throws IOException 1655 */ 1656 public static KeyValue.Type fromDeleteType( 1657 DeleteType type) throws IOException { 1658 switch (type) { 1659 case DELETE_ONE_VERSION: 1660 return KeyValue.Type.Delete; 1661 case DELETE_MULTIPLE_VERSIONS: 1662 return KeyValue.Type.DeleteColumn; 1663 case DELETE_FAMILY: 1664 return KeyValue.Type.DeleteFamily; 1665 case DELETE_FAMILY_VERSION: 1666 return KeyValue.Type.DeleteFamilyVersion; 1667 default: 1668 throw new IOException("Unknown delete type: " + type); 1669 } 1670 } 1671 1672 /** 1673 * Convert a stringified protocol buffer exception Parameter to a Java Exception 1674 * 1675 * @param parameter the protocol buffer Parameter to convert 1676 * @return the converted Exception 1677 * @throws IOException if failed to deserialize the parameter 1678 */ 1679 @SuppressWarnings("unchecked") 1680 public static Throwable toException(final NameBytesPair parameter) throws IOException { 1681 if (parameter == null || !parameter.hasValue()) return null; 1682 String desc = parameter.getValue().toStringUtf8(); 1683 String type = parameter.getName(); 1684 try { 1685 Class<? extends Throwable> c = 1686 (Class<? extends Throwable>)Class.forName(type, true, ClassLoaderHolder.CLASS_LOADER); 1687 Constructor<? extends Throwable> cn = null; 1688 try { 1689 cn = c.getDeclaredConstructor(String.class); 1690 return cn.newInstance(desc); 1691 } catch (NoSuchMethodException e) { 1692 // Could be a raw RemoteException. See HBASE-8987. 1693 cn = c.getDeclaredConstructor(String.class, String.class); 1694 return cn.newInstance(type, desc); 1695 } 1696 } catch (Exception e) { 1697 throw new IOException(e); 1698 } 1699 } 1700 1701// Start helpers for Client 1702 1703 @SuppressWarnings("unchecked") 1704 public static <T extends Service> T newServiceStub(Class<T> service, RpcChannel channel) 1705 throws Exception { 1706 return (T)Methods.call(service, null, "newStub", 1707 new Class[]{ RpcChannel.class }, new Object[]{ channel }); 1708 } 1709 1710// End helpers for Client 1711// Start helpers for Admin 1712 1713 /** 1714 * A helper to retrieve region info given a region name 1715 * using admin protocol. 1716 * 1717 * @param admin 1718 * @param regionName 1719 * @return the retrieved region info 1720 * @throws IOException 1721 */ 1722 public static org.apache.hadoop.hbase.client.RegionInfo getRegionInfo(final RpcController controller, 1723 final AdminService.BlockingInterface admin, final byte[] regionName) throws IOException { 1724 try { 1725 GetRegionInfoRequest request = 1726 RequestConverter.buildGetRegionInfoRequest(regionName); 1727 GetRegionInfoResponse response = 1728 admin.getRegionInfo(controller, request); 1729 return toRegionInfo(response.getRegionInfo()); 1730 } catch (ServiceException se) { 1731 throw getRemoteException(se); 1732 } 1733 } 1734 1735 public static List<org.apache.hadoop.hbase.RegionLoad> getRegionLoadInfo( 1736 GetRegionLoadResponse regionLoadResponse) { 1737 List<org.apache.hadoop.hbase.RegionLoad> regionLoadList = 1738 new ArrayList<>(regionLoadResponse.getRegionLoadsCount()); 1739 for (RegionLoad regionLoad : regionLoadResponse.getRegionLoadsList()) { 1740 regionLoadList.add(new org.apache.hadoop.hbase.RegionLoad(regionLoad)); 1741 } 1742 return regionLoadList; 1743 } 1744 1745 /** 1746 * A helper to close a region given a region name 1747 * using admin protocol. 1748 * 1749 * @param admin 1750 * @param regionName 1751 * @throws IOException 1752 */ 1753 public static void closeRegion(final RpcController controller, 1754 final AdminService.BlockingInterface admin, final ServerName server, final byte[] regionName) 1755 throws IOException { 1756 CloseRegionRequest closeRegionRequest = 1757 ProtobufUtil.buildCloseRegionRequest(server, regionName); 1758 try { 1759 admin.closeRegion(controller, closeRegionRequest); 1760 } catch (ServiceException se) { 1761 throw getRemoteException(se); 1762 } 1763 } 1764 1765 /** 1766 * A helper to warmup a region given a region name 1767 * using admin protocol 1768 * 1769 * @param admin 1770 * @param regionInfo 1771 * 1772 */ 1773 public static void warmupRegion(final RpcController controller, 1774 final AdminService.BlockingInterface admin, final org.apache.hadoop.hbase.client.RegionInfo regionInfo) throws IOException { 1775 1776 try { 1777 WarmupRegionRequest warmupRegionRequest = 1778 RequestConverter.buildWarmupRegionRequest(regionInfo); 1779 1780 admin.warmupRegion(controller, warmupRegionRequest); 1781 } catch (ServiceException e) { 1782 throw getRemoteException(e); 1783 } 1784 } 1785 1786 /** 1787 * A helper to open a region using admin protocol. 1788 * @param admin 1789 * @param region 1790 * @throws IOException 1791 */ 1792 public static void openRegion(final RpcController controller, 1793 final AdminService.BlockingInterface admin, ServerName server, final org.apache.hadoop.hbase.client.RegionInfo region) 1794 throws IOException { 1795 OpenRegionRequest request = 1796 RequestConverter.buildOpenRegionRequest(server, region, null); 1797 try { 1798 admin.openRegion(controller, request); 1799 } catch (ServiceException se) { 1800 throw ProtobufUtil.getRemoteException(se); 1801 } 1802 } 1803 1804 /** 1805 * A helper to get the all the online regions on a region 1806 * server using admin protocol. 1807 * 1808 * @param admin 1809 * @return a list of online region info 1810 * @throws IOException 1811 */ 1812 public static List<org.apache.hadoop.hbase.client.RegionInfo> getOnlineRegions(final AdminService.BlockingInterface admin) 1813 throws IOException { 1814 return getOnlineRegions(null, admin); 1815 } 1816 1817 /** 1818 * A helper to get the all the online regions on a region 1819 * server using admin protocol. 1820 * @return a list of online region info 1821 */ 1822 public static List<org.apache.hadoop.hbase.client.RegionInfo> getOnlineRegions(final RpcController controller, 1823 final AdminService.BlockingInterface admin) 1824 throws IOException { 1825 GetOnlineRegionRequest request = RequestConverter.buildGetOnlineRegionRequest(); 1826 GetOnlineRegionResponse response = null; 1827 try { 1828 response = admin.getOnlineRegion(controller, request); 1829 } catch (ServiceException se) { 1830 throw getRemoteException(se); 1831 } 1832 return getRegionInfos(response); 1833 } 1834 1835 /** 1836 * Get the list of region info from a GetOnlineRegionResponse 1837 * 1838 * @param proto the GetOnlineRegionResponse 1839 * @return the list of region info or empty if <code>proto</code> is null 1840 */ 1841 public static List<org.apache.hadoop.hbase.client.RegionInfo> getRegionInfos(final GetOnlineRegionResponse proto) { 1842 if (proto == null) return Collections.EMPTY_LIST; 1843 List<org.apache.hadoop.hbase.client.RegionInfo> regionInfos = new ArrayList<>(proto.getRegionInfoList().size()); 1844 for (RegionInfo regionInfo: proto.getRegionInfoList()) { 1845 regionInfos.add(toRegionInfo(regionInfo)); 1846 } 1847 return regionInfos; 1848 } 1849 1850 /** 1851 * A helper to get the info of a region server using admin protocol. 1852 * @return the server name 1853 */ 1854 public static ServerInfo getServerInfo(final RpcController controller, 1855 final AdminService.BlockingInterface admin) 1856 throws IOException { 1857 GetServerInfoRequest request = RequestConverter.buildGetServerInfoRequest(); 1858 try { 1859 GetServerInfoResponse response = admin.getServerInfo(controller, request); 1860 return response.getServerInfo(); 1861 } catch (ServiceException se) { 1862 throw getRemoteException(se); 1863 } 1864 } 1865 1866 /** 1867 * A helper to get the list of files of a column family 1868 * on a given region using admin protocol. 1869 * 1870 * @return the list of store files 1871 */ 1872 public static List<String> getStoreFiles(final AdminService.BlockingInterface admin, 1873 final byte[] regionName, final byte[] family) 1874 throws IOException { 1875 return getStoreFiles(null, admin, regionName, family); 1876 } 1877 1878 /** 1879 * A helper to get the list of files of a column family 1880 * on a given region using admin protocol. 1881 * 1882 * @return the list of store files 1883 */ 1884 public static List<String> getStoreFiles(final RpcController controller, 1885 final AdminService.BlockingInterface admin, final byte[] regionName, final byte[] family) 1886 throws IOException { 1887 GetStoreFileRequest request = 1888 ProtobufUtil.buildGetStoreFileRequest(regionName, family); 1889 try { 1890 GetStoreFileResponse response = admin.getStoreFile(controller, request); 1891 return response.getStoreFileList(); 1892 } catch (ServiceException se) { 1893 throw ProtobufUtil.getRemoteException(se); 1894 } 1895 } 1896 1897// End helpers for Admin 1898 1899 /* 1900 * Get the total (read + write) requests from a RegionLoad pb 1901 * @param rl - RegionLoad pb 1902 * @return total (read + write) requests 1903 */ 1904 public static long getTotalRequestsCount(RegionLoad rl) { 1905 if (rl == null) { 1906 return 0; 1907 } 1908 1909 return rl.getReadRequestsCount() + rl.getWriteRequestsCount(); 1910 } 1911 1912 1913 /** 1914 * @param m Message to get delimited pb serialization of (with pb magic prefix) 1915 */ 1916 public static byte [] toDelimitedByteArray(final Message m) throws IOException { 1917 // Allocate arbitrary big size so we avoid resizing. 1918 ByteArrayOutputStream baos = new ByteArrayOutputStream(4096); 1919 baos.write(ProtobufMagic.PB_MAGIC); 1920 m.writeDelimitedTo(baos); 1921 return baos.toByteArray(); 1922 } 1923 1924 /** 1925 * Find the HRegion encoded name based on a region specifier 1926 * 1927 * @param regionSpecifier the region specifier 1928 * @return the corresponding region's encoded name 1929 * @throws DoNotRetryIOException if the specifier type is unsupported 1930 */ 1931 public static String getRegionEncodedName( 1932 final RegionSpecifier regionSpecifier) throws DoNotRetryIOException { 1933 ByteString value = regionSpecifier.getValue(); 1934 RegionSpecifierType type = regionSpecifier.getType(); 1935 switch (type) { 1936 case REGION_NAME: 1937 return org.apache.hadoop.hbase.client.RegionInfo.encodeRegionName(value.toByteArray()); 1938 case ENCODED_REGION_NAME: 1939 return value.toStringUtf8(); 1940 default: 1941 throw new DoNotRetryIOException( 1942 "Unsupported region specifier type: " + type); 1943 } 1944 } 1945 1946 public static ScanMetrics toScanMetrics(final byte[] bytes) { 1947 MapReduceProtos.ScanMetrics pScanMetrics = null; 1948 try { 1949 pScanMetrics = MapReduceProtos.ScanMetrics.parseFrom(bytes); 1950 } catch (InvalidProtocolBufferException e) { 1951 // Ignored there are just no key values to add. 1952 } 1953 ScanMetrics scanMetrics = new ScanMetrics(); 1954 if (pScanMetrics != null) { 1955 for (HBaseProtos.NameInt64Pair pair : pScanMetrics.getMetricsList()) { 1956 if (pair.hasName() && pair.hasValue()) { 1957 scanMetrics.setCounter(pair.getName(), pair.getValue()); 1958 } 1959 } 1960 } 1961 return scanMetrics; 1962 } 1963 1964 public static MapReduceProtos.ScanMetrics toScanMetrics(ScanMetrics scanMetrics, boolean reset) { 1965 MapReduceProtos.ScanMetrics.Builder builder = MapReduceProtos.ScanMetrics.newBuilder(); 1966 Map<String, Long> metrics = scanMetrics.getMetricsMap(reset); 1967 for (Entry<String, Long> e : metrics.entrySet()) { 1968 HBaseProtos.NameInt64Pair nameInt64Pair = 1969 HBaseProtos.NameInt64Pair.newBuilder().setName(e.getKey()).setValue(e.getValue()).build(); 1970 builder.addMetrics(nameInt64Pair); 1971 } 1972 return builder.build(); 1973 } 1974 1975 /** 1976 * Unwraps an exception from a protobuf service into the underlying (expected) IOException. 1977 * This method will <strong>always</strong> throw an exception. 1978 * @param se the {@code ServiceException} instance to convert into an {@code IOException} 1979 */ 1980 public static void toIOException(ServiceException se) throws IOException { 1981 if (se == null) { 1982 throw new NullPointerException("Null service exception passed!"); 1983 } 1984 1985 Throwable cause = se.getCause(); 1986 if (cause != null && cause instanceof IOException) { 1987 throw (IOException)cause; 1988 } 1989 throw new IOException(se); 1990 } 1991 1992 public static CellProtos.Cell toCell(final Cell kv) { 1993 // Doing this is going to kill us if we do it for all data passed. 1994 // St.Ack 20121205 1995 CellProtos.Cell.Builder kvbuilder = CellProtos.Cell.newBuilder(); 1996 if (kv instanceof ByteBufferExtendedCell) { 1997 kvbuilder.setRow(wrap(((ByteBufferExtendedCell) kv).getRowByteBuffer(), 1998 ((ByteBufferExtendedCell) kv).getRowPosition(), kv.getRowLength())); 1999 kvbuilder.setFamily(wrap(((ByteBufferExtendedCell) kv).getFamilyByteBuffer(), 2000 ((ByteBufferExtendedCell) kv).getFamilyPosition(), kv.getFamilyLength())); 2001 kvbuilder.setQualifier(wrap(((ByteBufferExtendedCell) kv).getQualifierByteBuffer(), 2002 ((ByteBufferExtendedCell) kv).getQualifierPosition(), kv.getQualifierLength())); 2003 kvbuilder.setCellType(CellProtos.CellType.valueOf(kv.getTypeByte())); 2004 kvbuilder.setTimestamp(kv.getTimestamp()); 2005 kvbuilder.setValue(wrap(((ByteBufferExtendedCell) kv).getValueByteBuffer(), 2006 ((ByteBufferExtendedCell) kv).getValuePosition(), kv.getValueLength())); 2007 // TODO : Once tags become first class then we may have to set tags to kvbuilder. 2008 } else { 2009 kvbuilder.setRow( 2010 UnsafeByteOperations.unsafeWrap(kv.getRowArray(), kv.getRowOffset(), kv.getRowLength())); 2011 kvbuilder.setFamily(UnsafeByteOperations.unsafeWrap(kv.getFamilyArray(), kv.getFamilyOffset(), 2012 kv.getFamilyLength())); 2013 kvbuilder.setQualifier(UnsafeByteOperations.unsafeWrap(kv.getQualifierArray(), 2014 kv.getQualifierOffset(), kv.getQualifierLength())); 2015 kvbuilder.setCellType(CellProtos.CellType.valueOf(kv.getTypeByte())); 2016 kvbuilder.setTimestamp(kv.getTimestamp()); 2017 kvbuilder.setValue(UnsafeByteOperations.unsafeWrap(kv.getValueArray(), kv.getValueOffset(), 2018 kv.getValueLength())); 2019 } 2020 return kvbuilder.build(); 2021 } 2022 2023 private static ByteString wrap(ByteBuffer b, int offset, int length) { 2024 ByteBuffer dup = b.duplicate(); 2025 dup.position(offset); 2026 dup.limit(offset + length); 2027 return UnsafeByteOperations.unsafeWrap(dup); 2028 } 2029 2030 public static Cell toCell(ExtendedCellBuilder cellBuilder, final CellProtos.Cell cell) { 2031 return cellBuilder.clear() 2032 .setRow(cell.getRow().toByteArray()) 2033 .setFamily(cell.getFamily().toByteArray()) 2034 .setQualifier(cell.getQualifier().toByteArray()) 2035 .setTimestamp(cell.getTimestamp()) 2036 .setType((byte) cell.getCellType().getNumber()) 2037 .setValue(cell.getValue().toByteArray()) 2038 .build(); 2039 } 2040 2041 public static HBaseProtos.NamespaceDescriptor toProtoNamespaceDescriptor(NamespaceDescriptor ns) { 2042 HBaseProtos.NamespaceDescriptor.Builder b = 2043 HBaseProtos.NamespaceDescriptor.newBuilder() 2044 .setName(ByteString.copyFromUtf8(ns.getName())); 2045 for(Map.Entry<String, String> entry: ns.getConfiguration().entrySet()) { 2046 b.addConfiguration(HBaseProtos.NameStringPair.newBuilder() 2047 .setName(entry.getKey()) 2048 .setValue(entry.getValue())); 2049 } 2050 return b.build(); 2051 } 2052 2053 public static NamespaceDescriptor toNamespaceDescriptor(HBaseProtos.NamespaceDescriptor desc) { 2054 NamespaceDescriptor.Builder b = NamespaceDescriptor.create(desc.getName().toStringUtf8()); 2055 for (HBaseProtos.NameStringPair prop : desc.getConfigurationList()) { 2056 b.addConfiguration(prop.getName(), prop.getValue()); 2057 } 2058 return b.build(); 2059 } 2060 2061 public static CompactionDescriptor toCompactionDescriptor( 2062 org.apache.hadoop.hbase.client.RegionInfo info, byte[] family, 2063 List<Path> inputPaths, List<Path> outputPaths, Path storeDir) { 2064 return toCompactionDescriptor(info, null, family, inputPaths, outputPaths, storeDir); 2065 } 2066 2067 public static CompactionDescriptor toCompactionDescriptor( 2068 org.apache.hadoop.hbase.client.RegionInfo info, byte[] regionName, 2069 byte[] family, List<Path> inputPaths, List<Path> outputPaths, Path storeDir) { 2070 // compaction descriptor contains relative paths. 2071 // input / output paths are relative to the store dir 2072 // store dir is relative to region dir 2073 CompactionDescriptor.Builder builder = CompactionDescriptor.newBuilder() 2074 .setTableName(UnsafeByteOperations.unsafeWrap(info.getTable().toBytes())) 2075 .setEncodedRegionName(UnsafeByteOperations.unsafeWrap( 2076 regionName == null ? info.getEncodedNameAsBytes() : regionName)) 2077 .setFamilyName(UnsafeByteOperations.unsafeWrap(family)) 2078 .setStoreHomeDir(storeDir.getName()); //make relative 2079 for (Path inputPath : inputPaths) { 2080 builder.addCompactionInput(inputPath.getName()); //relative path 2081 } 2082 for (Path outputPath : outputPaths) { 2083 builder.addCompactionOutput(outputPath.getName()); 2084 } 2085 builder.setRegionName(UnsafeByteOperations.unsafeWrap(info.getRegionName())); 2086 return builder.build(); 2087 } 2088 2089 public static FlushDescriptor toFlushDescriptor(FlushAction action, org.apache.hadoop.hbase.client.RegionInfo hri, 2090 long flushSeqId, Map<byte[], List<Path>> committedFiles) { 2091 FlushDescriptor.Builder desc = FlushDescriptor.newBuilder() 2092 .setAction(action) 2093 .setEncodedRegionName(UnsafeByteOperations.unsafeWrap(hri.getEncodedNameAsBytes())) 2094 .setRegionName(UnsafeByteOperations.unsafeWrap(hri.getRegionName())) 2095 .setFlushSequenceNumber(flushSeqId) 2096 .setTableName(UnsafeByteOperations.unsafeWrap(hri.getTable().getName())); 2097 2098 for (Map.Entry<byte[], List<Path>> entry : committedFiles.entrySet()) { 2099 WALProtos.FlushDescriptor.StoreFlushDescriptor.Builder builder = 2100 WALProtos.FlushDescriptor.StoreFlushDescriptor.newBuilder() 2101 .setFamilyName(UnsafeByteOperations.unsafeWrap(entry.getKey())) 2102 .setStoreHomeDir(Bytes.toString(entry.getKey())); //relative to region 2103 if (entry.getValue() != null) { 2104 for (Path path : entry.getValue()) { 2105 builder.addFlushOutput(path.getName()); 2106 } 2107 } 2108 desc.addStoreFlushes(builder); 2109 } 2110 return desc.build(); 2111 } 2112 2113 public static RegionEventDescriptor toRegionEventDescriptor( 2114 EventType eventType, org.apache.hadoop.hbase.client.RegionInfo hri, long seqId, ServerName server, 2115 Map<byte[], List<Path>> storeFiles) { 2116 final byte[] tableNameAsBytes = hri.getTable().getName(); 2117 final byte[] encodedNameAsBytes = hri.getEncodedNameAsBytes(); 2118 final byte[] regionNameAsBytes = hri.getRegionName(); 2119 return toRegionEventDescriptor(eventType, 2120 tableNameAsBytes, 2121 encodedNameAsBytes, 2122 regionNameAsBytes, 2123 seqId, 2124 2125 server, 2126 storeFiles); 2127 } 2128 2129 public static RegionEventDescriptor toRegionEventDescriptor(EventType eventType, 2130 byte[] tableNameAsBytes, 2131 byte[] encodedNameAsBytes, 2132 byte[] regionNameAsBytes, 2133 long seqId, 2134 2135 ServerName server, 2136 Map<byte[], List<Path>> storeFiles) { 2137 RegionEventDescriptor.Builder desc = RegionEventDescriptor.newBuilder() 2138 .setEventType(eventType) 2139 .setTableName(UnsafeByteOperations.unsafeWrap(tableNameAsBytes)) 2140 .setEncodedRegionName(UnsafeByteOperations.unsafeWrap(encodedNameAsBytes)) 2141 .setRegionName(UnsafeByteOperations.unsafeWrap(regionNameAsBytes)) 2142 .setLogSequenceNumber(seqId) 2143 .setServer(toServerName(server)); 2144 2145 for (Entry<byte[], List<Path>> entry : storeFiles.entrySet()) { 2146 StoreDescriptor.Builder builder = StoreDescriptor.newBuilder() 2147 .setFamilyName(UnsafeByteOperations.unsafeWrap(entry.getKey())) 2148 .setStoreHomeDir(Bytes.toString(entry.getKey())); 2149 for (Path path : entry.getValue()) { 2150 builder.addStoreFile(path.getName()); 2151 } 2152 2153 desc.addStores(builder); 2154 } 2155 return desc.build(); 2156 } 2157 2158 /** 2159 * Return short version of Message toString'd, shorter than TextFormat#shortDebugString. 2160 * Tries to NOT print out data both because it can be big but also so we do not have data in our 2161 * logs. Use judiciously. 2162 * @param m 2163 * @return toString of passed <code>m</code> 2164 */ 2165 public static String getShortTextFormat(Message m) { 2166 if (m == null) return "null"; 2167 if (m instanceof ScanRequest) { 2168 // This should be small and safe to output. No data. 2169 return TextFormat.shortDebugString(m); 2170 } else if (m instanceof RegionServerReportRequest) { 2171 // Print a short message only, just the servername and the requests, not the full load. 2172 RegionServerReportRequest r = (RegionServerReportRequest)m; 2173 return "server " + TextFormat.shortDebugString(r.getServer()) + 2174 " load { numberOfRequests: " + r.getLoad().getNumberOfRequests() + " }"; 2175 } else if (m instanceof RegionServerStartupRequest) { 2176 // Should be small enough. 2177 return TextFormat.shortDebugString(m); 2178 } else if (m instanceof MutationProto) { 2179 return toShortString((MutationProto)m); 2180 } else if (m instanceof GetRequest) { 2181 GetRequest r = (GetRequest) m; 2182 return "region= " + getStringForByteString(r.getRegion().getValue()) + 2183 ", row=" + getStringForByteString(r.getGet().getRow()); 2184 } else if (m instanceof ClientProtos.MultiRequest) { 2185 ClientProtos.MultiRequest r = (ClientProtos.MultiRequest) m; 2186 // Get first set of Actions. 2187 ClientProtos.RegionAction actions = r.getRegionActionList().get(0); 2188 String row = actions.getActionCount() <= 0? "": 2189 getStringForByteString(actions.getAction(0).hasGet()? 2190 actions.getAction(0).getGet().getRow(): 2191 actions.getAction(0).getMutation().getRow()); 2192 return "region= " + getStringForByteString(actions.getRegion().getValue()) + 2193 ", for " + r.getRegionActionCount() + 2194 " actions and 1st row key=" + row; 2195 } else if (m instanceof ClientProtos.MutateRequest) { 2196 ClientProtos.MutateRequest r = (ClientProtos.MutateRequest) m; 2197 return "region= " + getStringForByteString(r.getRegion().getValue()) + 2198 ", row=" + getStringForByteString(r.getMutation().getRow()); 2199 } else if (m instanceof ClientProtos.CoprocessorServiceRequest) { 2200 ClientProtos.CoprocessorServiceRequest r = (ClientProtos.CoprocessorServiceRequest) m; 2201 return "coprocessorService= " + r.getCall().getServiceName() + ":" + r.getCall().getMethodName(); 2202 } 2203 return "TODO: " + m.getClass().toString(); 2204 } 2205 2206 private static String getStringForByteString(ByteString bs) { 2207 return Bytes.toStringBinary(bs.toByteArray()); 2208 } 2209 2210 /** 2211 * Print out some subset of a MutationProto rather than all of it and its data 2212 * @param proto Protobuf to print out 2213 * @return Short String of mutation proto 2214 */ 2215 static String toShortString(final MutationProto proto) { 2216 return "row=" + Bytes.toString(proto.getRow().toByteArray()) + 2217 ", type=" + proto.getMutateType().toString(); 2218 } 2219 2220 public static TableName toTableName(HBaseProtos.TableName tableNamePB) { 2221 return TableName.valueOf(tableNamePB.getNamespace().asReadOnlyByteBuffer(), 2222 tableNamePB.getQualifier().asReadOnlyByteBuffer()); 2223 } 2224 2225 public static HBaseProtos.TableName toProtoTableName(TableName tableName) { 2226 return HBaseProtos.TableName.newBuilder() 2227 .setNamespace(UnsafeByteOperations.unsafeWrap(tableName.getNamespace())) 2228 .setQualifier(UnsafeByteOperations.unsafeWrap(tableName.getQualifier())).build(); 2229 } 2230 2231 public static List<TableName> toTableNameList(List<HBaseProtos.TableName> tableNamesList) { 2232 if (tableNamesList == null) { 2233 return new ArrayList<>(); 2234 } 2235 return tableNamesList.stream().map(ProtobufUtil::toTableName).collect(Collectors.toList()); 2236 } 2237 2238 public static TableName[] getTableNameArray(List<HBaseProtos.TableName> tableNamesList) { 2239 if (tableNamesList == null) { 2240 return new TableName[0]; 2241 } 2242 TableName[] tableNames = new TableName[tableNamesList.size()]; 2243 for (int i = 0; i < tableNamesList.size(); i++) { 2244 tableNames[i] = toTableName(tableNamesList.get(i)); 2245 } 2246 return tableNames; 2247 } 2248 2249 /** 2250 * Convert a protocol buffer CellVisibility to a client CellVisibility 2251 * 2252 * @param proto 2253 * @return the converted client CellVisibility 2254 */ 2255 public static CellVisibility toCellVisibility(ClientProtos.CellVisibility proto) { 2256 if (proto == null) return null; 2257 return new CellVisibility(proto.getExpression()); 2258 } 2259 2260 /** 2261 * Convert a protocol buffer CellVisibility bytes to a client CellVisibility 2262 * 2263 * @param protoBytes 2264 * @return the converted client CellVisibility 2265 * @throws DeserializationException 2266 */ 2267 public static CellVisibility toCellVisibility(byte[] protoBytes) throws DeserializationException { 2268 if (protoBytes == null) return null; 2269 ClientProtos.CellVisibility.Builder builder = ClientProtos.CellVisibility.newBuilder(); 2270 ClientProtos.CellVisibility proto = null; 2271 try { 2272 ProtobufUtil.mergeFrom(builder, protoBytes); 2273 proto = builder.build(); 2274 } catch (IOException e) { 2275 throw new DeserializationException(e); 2276 } 2277 return toCellVisibility(proto); 2278 } 2279 2280 /** 2281 * Create a protocol buffer CellVisibility based on a client CellVisibility. 2282 * 2283 * @param cellVisibility 2284 * @return a protocol buffer CellVisibility 2285 */ 2286 public static ClientProtos.CellVisibility toCellVisibility(CellVisibility cellVisibility) { 2287 ClientProtos.CellVisibility.Builder builder = ClientProtos.CellVisibility.newBuilder(); 2288 builder.setExpression(cellVisibility.getExpression()); 2289 return builder.build(); 2290 } 2291 2292 /** 2293 * Convert a protocol buffer Authorizations to a client Authorizations 2294 * 2295 * @param proto 2296 * @return the converted client Authorizations 2297 */ 2298 public static Authorizations toAuthorizations(ClientProtos.Authorizations proto) { 2299 if (proto == null) return null; 2300 return new Authorizations(proto.getLabelList()); 2301 } 2302 2303 /** 2304 * Convert a protocol buffer Authorizations bytes to a client Authorizations 2305 * 2306 * @param protoBytes 2307 * @return the converted client Authorizations 2308 * @throws DeserializationException 2309 */ 2310 public static Authorizations toAuthorizations(byte[] protoBytes) throws DeserializationException { 2311 if (protoBytes == null) return null; 2312 ClientProtos.Authorizations.Builder builder = ClientProtos.Authorizations.newBuilder(); 2313 ClientProtos.Authorizations proto = null; 2314 try { 2315 ProtobufUtil.mergeFrom(builder, protoBytes); 2316 proto = builder.build(); 2317 } catch (IOException e) { 2318 throw new DeserializationException(e); 2319 } 2320 return toAuthorizations(proto); 2321 } 2322 2323 /** 2324 * Create a protocol buffer Authorizations based on a client Authorizations. 2325 * 2326 * @param authorizations 2327 * @return a protocol buffer Authorizations 2328 */ 2329 public static ClientProtos.Authorizations toAuthorizations(Authorizations authorizations) { 2330 ClientProtos.Authorizations.Builder builder = ClientProtos.Authorizations.newBuilder(); 2331 for (String label : authorizations.getLabels()) { 2332 builder.addLabel(label); 2333 } 2334 return builder.build(); 2335 } 2336 2337 /** 2338 * Convert a protocol buffer TimeUnit to a client TimeUnit 2339 * 2340 * @param proto 2341 * @return the converted client TimeUnit 2342 */ 2343 public static TimeUnit toTimeUnit(final HBaseProtos.TimeUnit proto) { 2344 switch (proto) { 2345 case NANOSECONDS: return TimeUnit.NANOSECONDS; 2346 case MICROSECONDS: return TimeUnit.MICROSECONDS; 2347 case MILLISECONDS: return TimeUnit.MILLISECONDS; 2348 case SECONDS: return TimeUnit.SECONDS; 2349 case MINUTES: return TimeUnit.MINUTES; 2350 case HOURS: return TimeUnit.HOURS; 2351 case DAYS: return TimeUnit.DAYS; 2352 } 2353 throw new RuntimeException("Invalid TimeUnit " + proto); 2354 } 2355 2356 /** 2357 * Convert a client TimeUnit to a protocol buffer TimeUnit 2358 * 2359 * @param timeUnit 2360 * @return the converted protocol buffer TimeUnit 2361 */ 2362 public static HBaseProtos.TimeUnit toProtoTimeUnit(final TimeUnit timeUnit) { 2363 switch (timeUnit) { 2364 case NANOSECONDS: return HBaseProtos.TimeUnit.NANOSECONDS; 2365 case MICROSECONDS: return HBaseProtos.TimeUnit.MICROSECONDS; 2366 case MILLISECONDS: return HBaseProtos.TimeUnit.MILLISECONDS; 2367 case SECONDS: return HBaseProtos.TimeUnit.SECONDS; 2368 case MINUTES: return HBaseProtos.TimeUnit.MINUTES; 2369 case HOURS: return HBaseProtos.TimeUnit.HOURS; 2370 case DAYS: return HBaseProtos.TimeUnit.DAYS; 2371 } 2372 throw new RuntimeException("Invalid TimeUnit " + timeUnit); 2373 } 2374 2375 /** 2376 * Convert a protocol buffer ThrottleType to a client ThrottleType 2377 * 2378 * @param proto 2379 * @return the converted client ThrottleType 2380 */ 2381 public static ThrottleType toThrottleType(final QuotaProtos.ThrottleType proto) { 2382 switch (proto) { 2383 case REQUEST_NUMBER: return ThrottleType.REQUEST_NUMBER; 2384 case REQUEST_SIZE: return ThrottleType.REQUEST_SIZE; 2385 case WRITE_NUMBER: return ThrottleType.WRITE_NUMBER; 2386 case WRITE_SIZE: return ThrottleType.WRITE_SIZE; 2387 case READ_NUMBER: return ThrottleType.READ_NUMBER; 2388 case READ_SIZE: return ThrottleType.READ_SIZE; 2389 } 2390 throw new RuntimeException("Invalid ThrottleType " + proto); 2391 } 2392 2393 /** 2394 * Convert a client ThrottleType to a protocol buffer ThrottleType 2395 * 2396 * @param type 2397 * @return the converted protocol buffer ThrottleType 2398 */ 2399 public static QuotaProtos.ThrottleType toProtoThrottleType(final ThrottleType type) { 2400 switch (type) { 2401 case REQUEST_NUMBER: return QuotaProtos.ThrottleType.REQUEST_NUMBER; 2402 case REQUEST_SIZE: return QuotaProtos.ThrottleType.REQUEST_SIZE; 2403 case WRITE_NUMBER: return QuotaProtos.ThrottleType.WRITE_NUMBER; 2404 case WRITE_SIZE: return QuotaProtos.ThrottleType.WRITE_SIZE; 2405 case READ_NUMBER: return QuotaProtos.ThrottleType.READ_NUMBER; 2406 case READ_SIZE: return QuotaProtos.ThrottleType.READ_SIZE; 2407 } 2408 throw new RuntimeException("Invalid ThrottleType " + type); 2409 } 2410 2411 /** 2412 * Convert a protocol buffer QuotaScope to a client QuotaScope 2413 * 2414 * @param proto 2415 * @return the converted client QuotaScope 2416 */ 2417 public static QuotaScope toQuotaScope(final QuotaProtos.QuotaScope proto) { 2418 switch (proto) { 2419 case CLUSTER: return QuotaScope.CLUSTER; 2420 case MACHINE: return QuotaScope.MACHINE; 2421 } 2422 throw new RuntimeException("Invalid QuotaScope " + proto); 2423 } 2424 2425 /** 2426 * Convert a client QuotaScope to a protocol buffer QuotaScope 2427 * 2428 * @param scope 2429 * @return the converted protocol buffer QuotaScope 2430 */ 2431 public static QuotaProtos.QuotaScope toProtoQuotaScope(final QuotaScope scope) { 2432 switch (scope) { 2433 case CLUSTER: return QuotaProtos.QuotaScope.CLUSTER; 2434 case MACHINE: return QuotaProtos.QuotaScope.MACHINE; 2435 } 2436 throw new RuntimeException("Invalid QuotaScope " + scope); 2437 } 2438 2439 /** 2440 * Convert a protocol buffer QuotaType to a client QuotaType 2441 * 2442 * @param proto 2443 * @return the converted client QuotaType 2444 */ 2445 public static QuotaType toQuotaScope(final QuotaProtos.QuotaType proto) { 2446 switch (proto) { 2447 case THROTTLE: return QuotaType.THROTTLE; 2448 case SPACE: return QuotaType.SPACE; 2449 } 2450 throw new RuntimeException("Invalid QuotaType " + proto); 2451 } 2452 2453 /** 2454 * Convert a client QuotaType to a protocol buffer QuotaType 2455 * 2456 * @param type 2457 * @return the converted protocol buffer QuotaType 2458 */ 2459 public static QuotaProtos.QuotaType toProtoQuotaScope(final QuotaType type) { 2460 switch (type) { 2461 case THROTTLE: return QuotaProtos.QuotaType.THROTTLE; 2462 case SPACE: return QuotaProtos.QuotaType.SPACE; 2463 default: throw new RuntimeException("Invalid QuotaType " + type); 2464 } 2465 } 2466 2467 /** 2468 * Converts a protocol buffer SpaceViolationPolicy to a client SpaceViolationPolicy. 2469 * 2470 * @param proto The protocol buffer space violation policy. 2471 * @return The corresponding client SpaceViolationPolicy. 2472 */ 2473 public static SpaceViolationPolicy toViolationPolicy( 2474 final QuotaProtos.SpaceViolationPolicy proto) { 2475 switch (proto) { 2476 case DISABLE: return SpaceViolationPolicy.DISABLE; 2477 case NO_WRITES_COMPACTIONS: return SpaceViolationPolicy.NO_WRITES_COMPACTIONS; 2478 case NO_WRITES: return SpaceViolationPolicy.NO_WRITES; 2479 case NO_INSERTS: return SpaceViolationPolicy.NO_INSERTS; 2480 } 2481 throw new RuntimeException("Invalid SpaceViolationPolicy " + proto); 2482 } 2483 2484 /** 2485 * Converts a client SpaceViolationPolicy to a protocol buffer SpaceViolationPolicy. 2486 * 2487 * @param policy The client SpaceViolationPolicy object. 2488 * @return The corresponding protocol buffer SpaceViolationPolicy. 2489 */ 2490 public static QuotaProtos.SpaceViolationPolicy toProtoViolationPolicy( 2491 final SpaceViolationPolicy policy) { 2492 switch (policy) { 2493 case DISABLE: return QuotaProtos.SpaceViolationPolicy.DISABLE; 2494 case NO_WRITES_COMPACTIONS: return QuotaProtos.SpaceViolationPolicy.NO_WRITES_COMPACTIONS; 2495 case NO_WRITES: return QuotaProtos.SpaceViolationPolicy.NO_WRITES; 2496 case NO_INSERTS: return QuotaProtos.SpaceViolationPolicy.NO_INSERTS; 2497 } 2498 throw new RuntimeException("Invalid SpaceViolationPolicy " + policy); 2499 } 2500 2501 /** 2502 * Build a protocol buffer TimedQuota 2503 * 2504 * @param limit the allowed number of request/data per timeUnit 2505 * @param timeUnit the limit time unit 2506 * @param scope the quota scope 2507 * @return the protocol buffer TimedQuota 2508 */ 2509 public static QuotaProtos.TimedQuota toTimedQuota(final long limit, final TimeUnit timeUnit, 2510 final QuotaScope scope) { 2511 return QuotaProtos.TimedQuota.newBuilder() 2512 .setSoftLimit(limit) 2513 .setTimeUnit(toProtoTimeUnit(timeUnit)) 2514 .setScope(toProtoQuotaScope(scope)) 2515 .build(); 2516 } 2517 2518 /** 2519 * Builds a protocol buffer SpaceQuota. 2520 * 2521 * @param limit The maximum space usage for the quota in bytes. 2522 * @param violationPolicy The policy to apply when the quota is violated. 2523 * @return The protocol buffer SpaceQuota. 2524 */ 2525 public static QuotaProtos.SpaceQuota toProtoSpaceQuota( 2526 final long limit, final SpaceViolationPolicy violationPolicy) { 2527 return QuotaProtos.SpaceQuota.newBuilder() 2528 .setSoftLimit(limit) 2529 .setViolationPolicy(toProtoViolationPolicy(violationPolicy)) 2530 .build(); 2531 } 2532 2533 /** 2534 * Generates a marker for the WAL so that we propagate the notion of a bulk region load 2535 * throughout the WAL. 2536 * 2537 * @param tableName The tableName into which the bulk load is being imported into. 2538 * @param encodedRegionName Encoded region name of the region which is being bulk loaded. 2539 * @param storeFiles A set of store files of a column family are bulk loaded. 2540 * @param storeFilesSize Map of store files and their lengths 2541 * @param bulkloadSeqId sequence ID (by a force flush) used to create bulk load hfile 2542 * name 2543 * @return The WAL log marker for bulk loads. 2544 */ 2545 public static WALProtos.BulkLoadDescriptor toBulkLoadDescriptor(TableName tableName, 2546 ByteString encodedRegionName, Map<byte[], List<Path>> storeFiles, 2547 Map<String, Long> storeFilesSize, long bulkloadSeqId) { 2548 BulkLoadDescriptor.Builder desc = 2549 BulkLoadDescriptor.newBuilder() 2550 .setTableName(ProtobufUtil.toProtoTableName(tableName)) 2551 .setEncodedRegionName(encodedRegionName).setBulkloadSeqNum(bulkloadSeqId); 2552 2553 for (Map.Entry<byte[], List<Path>> entry : storeFiles.entrySet()) { 2554 WALProtos.StoreDescriptor.Builder builder = StoreDescriptor.newBuilder() 2555 .setFamilyName(UnsafeByteOperations.unsafeWrap(entry.getKey())) 2556 .setStoreHomeDir(Bytes.toString(entry.getKey())); // relative to region 2557 for (Path path : entry.getValue()) { 2558 String name = path.getName(); 2559 builder.addStoreFile(name); 2560 Long size = storeFilesSize.get(name) == null ? (Long) 0L : storeFilesSize.get(name); 2561 builder.setStoreFileSizeBytes(size); 2562 } 2563 desc.addStores(builder); 2564 } 2565 2566 return desc.build(); 2567 } 2568 2569 /** 2570 * This version of protobuf's mergeDelimitedFrom avoid the hard-coded 64MB limit for decoding 2571 * buffers 2572 * @param builder current message builder 2573 * @param in Inputsream with delimited protobuf data 2574 * @throws IOException 2575 */ 2576 public static void mergeDelimitedFrom(Message.Builder builder, InputStream in) 2577 throws IOException { 2578 // This used to be builder.mergeDelimitedFrom(in); 2579 // but is replaced to allow us to bump the protobuf size limit. 2580 final int firstByte = in.read(); 2581 if (firstByte != -1) { 2582 final int size = CodedInputStream.readRawVarint32(firstByte, in); 2583 final InputStream limitedInput = ByteStreams.limit(in, size); 2584 final CodedInputStream codedInput = CodedInputStream.newInstance(limitedInput); 2585 codedInput.setSizeLimit(size); 2586 builder.mergeFrom(codedInput); 2587 codedInput.checkLastTagWas(0); 2588 } 2589 } 2590 2591 /** 2592 * This version of protobuf's mergeFrom avoids the hard-coded 64MB limit for decoding 2593 * buffers where the message size is known 2594 * @param builder current message builder 2595 * @param in InputStream containing protobuf data 2596 * @param size known size of protobuf data 2597 * @throws IOException 2598 */ 2599 public static void mergeFrom(Message.Builder builder, InputStream in, int size) 2600 throws IOException { 2601 final CodedInputStream codedInput = CodedInputStream.newInstance(in); 2602 codedInput.setSizeLimit(size); 2603 builder.mergeFrom(codedInput); 2604 codedInput.checkLastTagWas(0); 2605 } 2606 2607 /** 2608 * This version of protobuf's mergeFrom avoids the hard-coded 64MB limit for decoding 2609 * buffers where the message size is not known 2610 * @param builder current message builder 2611 * @param in InputStream containing protobuf data 2612 * @throws IOException 2613 */ 2614 public static void mergeFrom(Message.Builder builder, InputStream in) 2615 throws IOException { 2616 final CodedInputStream codedInput = CodedInputStream.newInstance(in); 2617 codedInput.setSizeLimit(Integer.MAX_VALUE); 2618 builder.mergeFrom(codedInput); 2619 codedInput.checkLastTagWas(0); 2620 } 2621 2622 /** 2623 * This version of protobuf's mergeFrom avoids the hard-coded 64MB limit for decoding 2624 * buffers when working with ByteStrings 2625 * @param builder current message builder 2626 * @param bs ByteString containing the 2627 * @throws IOException 2628 */ 2629 public static void mergeFrom(Message.Builder builder, ByteString bs) throws IOException { 2630 final CodedInputStream codedInput = bs.newCodedInput(); 2631 codedInput.setSizeLimit(bs.size()); 2632 builder.mergeFrom(codedInput); 2633 codedInput.checkLastTagWas(0); 2634 } 2635 2636 /** 2637 * This version of protobuf's mergeFrom avoids the hard-coded 64MB limit for decoding 2638 * buffers when working with byte arrays 2639 * @param builder current message builder 2640 * @param b byte array 2641 * @throws IOException 2642 */ 2643 public static void mergeFrom(Message.Builder builder, byte[] b) throws IOException { 2644 final CodedInputStream codedInput = CodedInputStream.newInstance(b); 2645 codedInput.setSizeLimit(b.length); 2646 builder.mergeFrom(codedInput); 2647 codedInput.checkLastTagWas(0); 2648 } 2649 2650 /** 2651 * This version of protobuf's mergeFrom avoids the hard-coded 64MB limit for decoding 2652 * buffers when working with byte arrays 2653 * @param builder current message builder 2654 * @param b byte array 2655 * @param offset 2656 * @param length 2657 * @throws IOException 2658 */ 2659 public static void mergeFrom(Message.Builder builder, byte[] b, int offset, int length) 2660 throws IOException { 2661 final CodedInputStream codedInput = CodedInputStream.newInstance(b, offset, length); 2662 codedInput.setSizeLimit(length); 2663 builder.mergeFrom(codedInput); 2664 codedInput.checkLastTagWas(0); 2665 } 2666 2667 public static void mergeFrom(Message.Builder builder, CodedInputStream codedInput, int length) 2668 throws IOException { 2669 codedInput.resetSizeCounter(); 2670 int prevLimit = codedInput.setSizeLimit(length); 2671 2672 int limit = codedInput.pushLimit(length); 2673 builder.mergeFrom(codedInput); 2674 codedInput.popLimit(limit); 2675 2676 codedInput.checkLastTagWas(0); 2677 codedInput.setSizeLimit(prevLimit); 2678 } 2679 2680 public static ReplicationLoadSink toReplicationLoadSink( 2681 ClusterStatusProtos.ReplicationLoadSink rls) { 2682 return new ReplicationLoadSink(rls.getAgeOfLastAppliedOp(), rls.getTimeStampsOfLastAppliedOp()); 2683 } 2684 2685 public static ReplicationLoadSource toReplicationLoadSource( 2686 ClusterStatusProtos.ReplicationLoadSource rls) { 2687 return new ReplicationLoadSource(rls.getPeerID(), rls.getAgeOfLastShippedOp(), 2688 rls.getSizeOfLogQueue(), rls.getTimeStampOfLastShippedOp(), rls.getReplicationLag()); 2689 } 2690 2691 /** 2692 * Get a protocol buffer VersionInfo 2693 * 2694 * @return the converted protocol buffer VersionInfo 2695 */ 2696 public static HBaseProtos.VersionInfo getVersionInfo() { 2697 HBaseProtos.VersionInfo.Builder builder = HBaseProtos.VersionInfo.newBuilder(); 2698 String version = VersionInfo.getVersion(); 2699 builder.setVersion(version); 2700 String[] components = version.split("\\."); 2701 if (components != null && components.length > 2) { 2702 builder.setVersionMajor(Integer.parseInt(components[0])); 2703 builder.setVersionMinor(Integer.parseInt(components[1])); 2704 } 2705 builder.setUrl(VersionInfo.getUrl()); 2706 builder.setRevision(VersionInfo.getRevision()); 2707 builder.setUser(VersionInfo.getUser()); 2708 builder.setDate(VersionInfo.getDate()); 2709 builder.setSrcChecksum(VersionInfo.getSrcChecksum()); 2710 return builder.build(); 2711 } 2712 2713 /** 2714 * Convert SecurityCapabilitiesResponse.Capability to SecurityCapability 2715 * @param capabilities capabilities returned in the SecurityCapabilitiesResponse message 2716 * @return the converted list of SecurityCapability elements 2717 */ 2718 public static List<SecurityCapability> toSecurityCapabilityList( 2719 List<MasterProtos.SecurityCapabilitiesResponse.Capability> capabilities) { 2720 List<SecurityCapability> scList = new ArrayList<>(capabilities.size()); 2721 for (MasterProtos.SecurityCapabilitiesResponse.Capability c: capabilities) { 2722 try { 2723 scList.add(SecurityCapability.valueOf(c.getNumber())); 2724 } catch (IllegalArgumentException e) { 2725 // Unknown capability, just ignore it. We don't understand the new capability 2726 // but don't care since by definition we cannot take advantage of it. 2727 } 2728 } 2729 return scList; 2730 } 2731 2732 public static TimeRange toTimeRange(HBaseProtos.TimeRange timeRange) { 2733 return timeRange == null ? 2734 TimeRange.allTime() : 2735 new TimeRange(timeRange.hasFrom() ? timeRange.getFrom() : 0, 2736 timeRange.hasTo() ? timeRange.getTo() : Long.MAX_VALUE); 2737 } 2738 2739 /** 2740 * Converts an ColumnFamilyDescriptor to ColumnFamilySchema 2741 * @param hcd the ColumnFamilySchema 2742 * @return Convert this instance to a the pb column family type 2743 */ 2744 public static ColumnFamilySchema toColumnFamilySchema(ColumnFamilyDescriptor hcd) { 2745 ColumnFamilySchema.Builder builder = ColumnFamilySchema.newBuilder(); 2746 builder.setName(UnsafeByteOperations.unsafeWrap(hcd.getName())); 2747 for (Map.Entry<Bytes, Bytes> e : hcd.getValues().entrySet()) { 2748 BytesBytesPair.Builder aBuilder = BytesBytesPair.newBuilder(); 2749 aBuilder.setFirst(UnsafeByteOperations.unsafeWrap(e.getKey().get())); 2750 aBuilder.setSecond(UnsafeByteOperations.unsafeWrap(e.getValue().get())); 2751 builder.addAttributes(aBuilder.build()); 2752 } 2753 for (Map.Entry<String, String> e : hcd.getConfiguration().entrySet()) { 2754 NameStringPair.Builder aBuilder = NameStringPair.newBuilder(); 2755 aBuilder.setName(e.getKey()); 2756 aBuilder.setValue(e.getValue()); 2757 builder.addConfiguration(aBuilder.build()); 2758 } 2759 return builder.build(); 2760 } 2761 2762 /** 2763 * Converts a ColumnFamilySchema to ColumnFamilyDescriptor 2764 * @param cfs the ColumnFamilySchema 2765 * @return An {@link ColumnFamilyDescriptor} made from the passed in <code>cfs</code> 2766 */ 2767 public static ColumnFamilyDescriptor toColumnFamilyDescriptor(final ColumnFamilySchema cfs) { 2768 // Use the empty constructor so we preserve the initial values set on construction for things 2769 // like maxVersion. Otherwise, we pick up wrong values on deserialization which makes for 2770 // unrelated-looking test failures that are hard to trace back to here. 2771 ColumnFamilyDescriptorBuilder builder 2772 = ColumnFamilyDescriptorBuilder.newBuilder(cfs.getName().toByteArray()); 2773 cfs.getAttributesList().forEach(a -> builder.setValue(a.getFirst().toByteArray(), a.getSecond().toByteArray())); 2774 cfs.getConfigurationList().forEach(a -> builder.setConfiguration(a.getName(), a.getValue())); 2775 return builder.build(); 2776 } 2777 2778 /** 2779 * Converts an TableDescriptor to TableSchema 2780 * @param htd the TableDescriptor 2781 * @return Convert the current {@link TableDescriptor} into a pb TableSchema instance. 2782 */ 2783 public static TableSchema toTableSchema(TableDescriptor htd) { 2784 TableSchema.Builder builder = TableSchema.newBuilder(); 2785 builder.setTableName(toProtoTableName(htd.getTableName())); 2786 for (Map.Entry<Bytes, Bytes> e : htd.getValues().entrySet()) { 2787 BytesBytesPair.Builder aBuilder = BytesBytesPair.newBuilder(); 2788 aBuilder.setFirst(UnsafeByteOperations.unsafeWrap(e.getKey().get())); 2789 aBuilder.setSecond(UnsafeByteOperations.unsafeWrap(e.getValue().get())); 2790 builder.addAttributes(aBuilder.build()); 2791 } 2792 for (ColumnFamilyDescriptor hcd : htd.getColumnFamilies()) { 2793 builder.addColumnFamilies(toColumnFamilySchema(hcd)); 2794 } 2795 return builder.build(); 2796 } 2797 2798 /** 2799 * Converts a TableSchema to TableDescriptor 2800 * @param ts A pb TableSchema instance. 2801 * @return An {@link TableDescriptor} made from the passed in pb <code>ts</code>. 2802 */ 2803 public static TableDescriptor toTableDescriptor(final TableSchema ts) { 2804 TableDescriptorBuilder builder 2805 = TableDescriptorBuilder.newBuilder(ProtobufUtil.toTableName(ts.getTableName())); 2806 ts.getColumnFamiliesList() 2807 .stream() 2808 .map(ProtobufUtil::toColumnFamilyDescriptor) 2809 .forEach(builder::setColumnFamily); 2810 ts.getAttributesList() 2811 .forEach(a -> builder.setValue(a.getFirst().toByteArray(), a.getSecond().toByteArray())); 2812 ts.getConfigurationList() 2813 .forEach(a -> builder.setValue(a.getName(), a.getValue())); 2814 return builder.build(); 2815 } 2816 2817 /** 2818 * Creates {@link CompactionState} from 2819 * {@link org.apache.hadoop.hbase.protobuf.generated.AdminProtos.GetRegionInfoResponse.CompactionState} 2820 * state 2821 * @param state the protobuf CompactionState 2822 * @return CompactionState 2823 */ 2824 public static CompactionState createCompactionState(GetRegionInfoResponse.CompactionState state) { 2825 return CompactionState.valueOf(state.toString()); 2826 } 2827 2828 public static GetRegionInfoResponse.CompactionState createCompactionState(CompactionState state) { 2829 return GetRegionInfoResponse.CompactionState.valueOf(state.toString()); 2830 } 2831 2832 public static Optional<Long> toOptionalTimestamp(MajorCompactionTimestampResponse resp) { 2833 long timestamp = resp.getCompactionTimestamp(); 2834 return timestamp == 0 ? Optional.empty() : Optional.of(timestamp); 2835 } 2836 2837 /** 2838 * Creates {@link org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.SnapshotDescription.Type} 2839 * from {@link SnapshotType} 2840 * @param type the SnapshotDescription type 2841 * @return the protobuf SnapshotDescription type 2842 */ 2843 public static SnapshotProtos.SnapshotDescription.Type 2844 createProtosSnapShotDescType(SnapshotType type) { 2845 return SnapshotProtos.SnapshotDescription.Type.valueOf(type.name()); 2846 } 2847 2848 /** 2849 * Creates {@link org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.SnapshotDescription.Type} 2850 * from the type of SnapshotDescription string 2851 * @param snapshotDesc string representing the snapshot description type 2852 * @return the protobuf SnapshotDescription type 2853 */ 2854 public static SnapshotProtos.SnapshotDescription.Type 2855 createProtosSnapShotDescType(String snapshotDesc) { 2856 return SnapshotProtos.SnapshotDescription.Type.valueOf(snapshotDesc.toUpperCase(Locale.ROOT)); 2857 } 2858 2859 /** 2860 * Creates {@link SnapshotType} from the type of 2861 * {@link org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.SnapshotDescription} 2862 * @param type the snapshot description type 2863 * @return the protobuf SnapshotDescription type 2864 */ 2865 public static SnapshotType createSnapshotType(SnapshotProtos.SnapshotDescription.Type type) { 2866 return SnapshotType.valueOf(type.toString()); 2867 } 2868 2869 /** 2870 * Convert from {@link SnapshotDescription} to 2871 * {@link org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.SnapshotDescription} 2872 * @param snapshotDesc the POJO SnapshotDescription 2873 * @return the protobuf SnapshotDescription 2874 */ 2875 public static SnapshotProtos.SnapshotDescription 2876 createHBaseProtosSnapshotDesc(SnapshotDescription snapshotDesc) { 2877 SnapshotProtos.SnapshotDescription.Builder builder = SnapshotProtos.SnapshotDescription.newBuilder(); 2878 if (snapshotDesc.getTableName() != null) { 2879 builder.setTable(snapshotDesc.getTableNameAsString()); 2880 } 2881 if (snapshotDesc.getName() != null) { 2882 builder.setName(snapshotDesc.getName()); 2883 } 2884 if (snapshotDesc.getOwner() != null) { 2885 builder.setOwner(snapshotDesc.getOwner()); 2886 } 2887 if (snapshotDesc.getCreationTime() != -1L) { 2888 builder.setCreationTime(snapshotDesc.getCreationTime()); 2889 } 2890 if (snapshotDesc.getVersion() != -1) { 2891 builder.setVersion(snapshotDesc.getVersion()); 2892 } 2893 builder.setType(ProtobufUtil.createProtosSnapShotDescType(snapshotDesc.getType())); 2894 SnapshotProtos.SnapshotDescription snapshot = builder.build(); 2895 return snapshot; 2896 } 2897 2898 /** 2899 * Convert from 2900 * {@link org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.SnapshotDescription} to 2901 * {@link SnapshotDescription} 2902 * @param snapshotDesc the protobuf SnapshotDescription 2903 * @return the POJO SnapshotDescription 2904 */ 2905 public static SnapshotDescription 2906 createSnapshotDesc(SnapshotProtos.SnapshotDescription snapshotDesc) { 2907 return new SnapshotDescription(snapshotDesc.getName(), 2908 snapshotDesc.hasTable() ? TableName.valueOf(snapshotDesc.getTable()) : null, 2909 createSnapshotType(snapshotDesc.getType()), snapshotDesc.getOwner(), 2910 snapshotDesc.getCreationTime(), snapshotDesc.getVersion()); 2911 } 2912 2913 public static RegionLoadStats createRegionLoadStats(ClientProtos.RegionLoadStats stats) { 2914 return new RegionLoadStats(stats.getMemStoreLoad(), stats.getHeapOccupancy(), 2915 stats.getCompactionPressure()); 2916 } 2917 2918 /** 2919 * @param msg 2920 * @return A String version of the passed in <code>msg</code> 2921 */ 2922 public static String toText(Message msg) { 2923 return TextFormat.shortDebugString(msg); 2924 } 2925 2926 public static byte [] toBytes(ByteString bs) { 2927 return bs.toByteArray(); 2928 } 2929 2930 /** 2931 * Contain ServiceException inside here. Take a callable that is doing our pb rpc and run it. 2932 * @throws IOException 2933 */ 2934 public static <T> T call(Callable<T> callable) throws IOException { 2935 try { 2936 return callable.call(); 2937 } catch (Exception e) { 2938 throw ProtobufUtil.handleRemoteException(e); 2939 } 2940 } 2941 2942 /** 2943 * Create a protocol buffer GetStoreFileRequest for a given region name 2944 * 2945 * @param regionName the name of the region to get info 2946 * @param family the family to get store file list 2947 * @return a protocol buffer GetStoreFileRequest 2948 */ 2949 public static GetStoreFileRequest 2950 buildGetStoreFileRequest(final byte[] regionName, final byte[] family) { 2951 GetStoreFileRequest.Builder builder = GetStoreFileRequest.newBuilder(); 2952 RegionSpecifier region = RequestConverter.buildRegionSpecifier( 2953 RegionSpecifierType.REGION_NAME, regionName); 2954 builder.setRegion(region); 2955 builder.addFamily(UnsafeByteOperations.unsafeWrap(family)); 2956 return builder.build(); 2957 } 2958 2959 /** 2960 * Create a CloseRegionRequest for a given region name 2961 * 2962 * @param regionName the name of the region to close 2963 * @return a CloseRegionRequest 2964 */ 2965 public static CloseRegionRequest buildCloseRegionRequest(ServerName server, 2966 final byte[] regionName) { 2967 return ProtobufUtil.buildCloseRegionRequest(server, regionName, null); 2968 } 2969 2970 public static CloseRegionRequest buildCloseRegionRequest(ServerName server, 2971 final byte[] regionName, ServerName destinationServer) { 2972 CloseRegionRequest.Builder builder = CloseRegionRequest.newBuilder(); 2973 RegionSpecifier region = RequestConverter.buildRegionSpecifier( 2974 RegionSpecifierType.REGION_NAME, regionName); 2975 builder.setRegion(region); 2976 if (destinationServer != null){ 2977 builder.setDestinationServer(toServerName(destinationServer)); 2978 } 2979 if (server != null) { 2980 builder.setServerStartCode(server.getStartcode()); 2981 } 2982 return builder.build(); 2983 } 2984 2985 public static ProcedureDescription buildProcedureDescription(String signature, String instance, 2986 Map<String, String> props) { 2987 ProcedureDescription.Builder builder = 2988 ProcedureDescription.newBuilder().setSignature(signature).setInstance(instance); 2989 if (props != null && !props.isEmpty()) { 2990 props.entrySet().forEach(entry -> builder.addConfiguration( 2991 NameStringPair.newBuilder().setName(entry.getKey()).setValue(entry.getValue()).build())); 2992 } 2993 return builder.build(); 2994 } 2995 2996 /** 2997 * Get a ServerName from the passed in data bytes. 2998 * @param data Data with a serialize server name in it; can handle the old style 2999 * servername where servername was host and port. Works too with data that 3000 * begins w/ the pb 'PBUF' magic and that is then followed by a protobuf that 3001 * has a serialized {@link ServerName} in it. 3002 * @return Returns null if <code>data</code> is null else converts passed data 3003 * to a ServerName instance. 3004 * @throws DeserializationException 3005 */ 3006 public static ServerName parseServerNameFrom(final byte [] data) throws DeserializationException { 3007 if (data == null || data.length <= 0) return null; 3008 if (ProtobufMagic.isPBMagicPrefix(data)) { 3009 int prefixLen = ProtobufMagic.lengthOfPBMagic(); 3010 try { 3011 ZooKeeperProtos.Master rss = 3012 ZooKeeperProtos.Master.PARSER.parseFrom(data, prefixLen, data.length - prefixLen); 3013 org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos.ServerName sn = 3014 rss.getMaster(); 3015 return ServerName.valueOf(sn.getHostName(), sn.getPort(), sn.getStartCode()); 3016 } catch (/*InvalidProtocolBufferException*/IOException e) { 3017 // A failed parse of the znode is pretty catastrophic. Rather than loop 3018 // retrying hoping the bad bytes will changes, and rather than change 3019 // the signature on this method to add an IOE which will send ripples all 3020 // over the code base, throw a RuntimeException. This should "never" happen. 3021 // Fail fast if it does. 3022 throw new DeserializationException(e); 3023 } 3024 } 3025 // The str returned could be old style -- pre hbase-1502 -- which was 3026 // hostname and port seperated by a colon rather than hostname, port and 3027 // startcode delimited by a ','. 3028 String str = Bytes.toString(data); 3029 int index = str.indexOf(ServerName.SERVERNAME_SEPARATOR); 3030 if (index != -1) { 3031 // Presume its ServerName serialized with versioned bytes. 3032 return ServerName.parseVersionedServerName(data); 3033 } 3034 // Presume it a hostname:port format. 3035 String hostname = Addressing.parseHostname(str); 3036 int port = Addressing.parsePort(str); 3037 return ServerName.valueOf(hostname, port, -1L); 3038 } 3039 3040 /** 3041 * Helper to convert the protobuf Procedure to JSON String 3042 * @return Convert the current Protocol Buffers Procedure to JSON String 3043 */ 3044 public static String toProcedureJson(List<ProcedureProtos.Procedure> procProtos) { 3045 JsonArray procJsons = new JsonArray(procProtos.size()); 3046 for (ProcedureProtos.Procedure procProto : procProtos) { 3047 try { 3048 JsonElement procJson = ProtobufMessageConverter.toJsonElement(procProto); 3049 procJsons.add(procJson); 3050 } catch (InvalidProtocolBufferException e) { 3051 procJsons.add(e.toString()); 3052 } 3053 } 3054 return procJsons.toString(); 3055 } 3056 3057 public static String toLockJson(List<LockServiceProtos.LockedResource> lockedResourceProtos) { 3058 JsonArray lockedResourceJsons = new JsonArray(lockedResourceProtos.size()); 3059 for (LockServiceProtos.LockedResource lockedResourceProto : lockedResourceProtos) { 3060 try { 3061 JsonElement lockedResourceJson = ProtobufMessageConverter.toJsonElement(lockedResourceProto); 3062 lockedResourceJsons.add(lockedResourceJson); 3063 } catch (InvalidProtocolBufferException e) { 3064 lockedResourceJsons.add(e.toString()); 3065 } 3066 } 3067 return lockedResourceJsons.toString(); 3068 } 3069 3070 /** 3071 * Convert a RegionInfo to a Proto RegionInfo 3072 * 3073 * @param info the RegionInfo to convert 3074 * @return the converted Proto RegionInfo 3075 */ 3076 public static HBaseProtos.RegionInfo toRegionInfo(final org.apache.hadoop.hbase.client.RegionInfo info) { 3077 if (info == null) return null; 3078 HBaseProtos.RegionInfo.Builder builder = HBaseProtos.RegionInfo.newBuilder(); 3079 builder.setTableName(ProtobufUtil.toProtoTableName(info.getTable())); 3080 builder.setRegionId(info.getRegionId()); 3081 if (info.getStartKey() != null) { 3082 builder.setStartKey(UnsafeByteOperations.unsafeWrap(info.getStartKey())); 3083 } 3084 if (info.getEndKey() != null) { 3085 builder.setEndKey(UnsafeByteOperations.unsafeWrap(info.getEndKey())); 3086 } 3087 builder.setOffline(info.isOffline()); 3088 builder.setSplit(info.isSplit()); 3089 builder.setReplicaId(info.getReplicaId()); 3090 return builder.build(); 3091 } 3092 3093 /** 3094 * Convert HBaseProto.RegionInfo to a RegionInfo 3095 * 3096 * @param proto the RegionInfo to convert 3097 * @return the converted RegionInfo 3098 */ 3099 public static org.apache.hadoop.hbase.client.RegionInfo toRegionInfo(final HBaseProtos.RegionInfo proto) { 3100 if (proto == null) return null; 3101 TableName tableName = ProtobufUtil.toTableName(proto.getTableName()); 3102 long regionId = proto.getRegionId(); 3103 int defaultReplicaId = org.apache.hadoop.hbase.client.RegionInfo.DEFAULT_REPLICA_ID; 3104 int replicaId = proto.hasReplicaId()? proto.getReplicaId(): defaultReplicaId; 3105 if (tableName.equals(TableName.META_TABLE_NAME) && replicaId == defaultReplicaId) { 3106 return RegionInfoBuilder.FIRST_META_REGIONINFO; 3107 } 3108 byte[] startKey = null; 3109 byte[] endKey = null; 3110 if (proto.hasStartKey()) { 3111 startKey = proto.getStartKey().toByteArray(); 3112 } 3113 if (proto.hasEndKey()) { 3114 endKey = proto.getEndKey().toByteArray(); 3115 } 3116 boolean split = false; 3117 if (proto.hasSplit()) { 3118 split = proto.getSplit(); 3119 } 3120 RegionInfoBuilder rib = RegionInfoBuilder.newBuilder(tableName) 3121 .setStartKey(startKey) 3122 .setEndKey(endKey) 3123 .setRegionId(regionId) 3124 .setReplicaId(replicaId) 3125 .setSplit(split); 3126 if (proto.hasOffline()) { 3127 rib.setOffline(proto.getOffline()); 3128 } 3129 return rib.build(); 3130 } 3131 3132 public static HBaseProtos.RegionLocation toRegionLocation(HRegionLocation loc) { 3133 HBaseProtos.RegionLocation.Builder builder = HBaseProtos.RegionLocation.newBuilder(); 3134 builder.setRegionInfo(toRegionInfo(loc.getRegion())); 3135 if (loc.getServerName() != null) { 3136 builder.setServerName(toServerName(loc.getServerName())); 3137 } 3138 builder.setSeqNum(loc.getSeqNum()); 3139 return builder.build(); 3140 } 3141 3142 public static HRegionLocation toRegionLocation(HBaseProtos.RegionLocation proto) { 3143 org.apache.hadoop.hbase.client.RegionInfo regionInfo = toRegionInfo(proto.getRegionInfo()); 3144 ServerName serverName = proto.hasServerName() ? toServerName(proto.getServerName()) : null; 3145 return new HRegionLocation(regionInfo, serverName, proto.getSeqNum()); 3146 } 3147 3148 public static List<SnapshotDescription> toSnapshotDescriptionList( 3149 GetCompletedSnapshotsResponse response, Pattern pattern) { 3150 return response.getSnapshotsList().stream().map(ProtobufUtil::createSnapshotDesc) 3151 .filter(snap -> pattern != null ? pattern.matcher(snap.getName()).matches() : true) 3152 .collect(Collectors.toList()); 3153 } 3154 3155 public static CacheEvictionStats toCacheEvictionStats( 3156 HBaseProtos.CacheEvictionStats stats) throws IOException{ 3157 CacheEvictionStatsBuilder builder = CacheEvictionStats.builder(); 3158 builder.withEvictedBlocks(stats.getEvictedBlocks()) 3159 .withMaxCacheSize(stats.getMaxCacheSize()); 3160 if (stats.getExceptionCount() > 0) { 3161 for (HBaseProtos.RegionExceptionMessage exception : stats.getExceptionList()) { 3162 HBaseProtos.RegionSpecifier rs = exception.getRegion(); 3163 byte[] regionName = rs.getValue().toByteArray(); 3164 builder.addException(regionName, ProtobufUtil.toException(exception.getException())); 3165 } 3166 } 3167 return builder.build(); 3168 } 3169 3170 public static HBaseProtos.CacheEvictionStats toCacheEvictionStats( 3171 CacheEvictionStats cacheEvictionStats) { 3172 HBaseProtos.CacheEvictionStats.Builder builder 3173 = HBaseProtos.CacheEvictionStats.newBuilder(); 3174 for (Map.Entry<byte[], Throwable> entry : cacheEvictionStats.getExceptions().entrySet()) { 3175 builder.addException( 3176 RegionExceptionMessage.newBuilder() 3177 .setRegion(RequestConverter.buildRegionSpecifier( 3178 RegionSpecifierType.REGION_NAME, entry.getKey())) 3179 .setException(ResponseConverter.buildException(entry.getValue())) 3180 .build() 3181 ); 3182 } 3183 return builder 3184 .setEvictedBlocks(cacheEvictionStats.getEvictedBlocks()) 3185 .setMaxCacheSize(cacheEvictionStats.getMaxCacheSize()) 3186 .build(); 3187 } 3188 3189 public static ClusterStatusProtos.ReplicationLoadSource toReplicationLoadSource( 3190 ReplicationLoadSource rls) { 3191 return ClusterStatusProtos.ReplicationLoadSource.newBuilder() 3192 .setPeerID(rls.getPeerID()) 3193 .setAgeOfLastShippedOp(rls.getAgeOfLastShippedOp()) 3194 .setSizeOfLogQueue((int) rls.getSizeOfLogQueue()) 3195 .setTimeStampOfLastShippedOp(rls.getTimestampOfLastShippedOp()) 3196 .setReplicationLag(rls.getReplicationLag()) 3197 .build(); 3198 } 3199 3200 public static ClusterStatusProtos.ReplicationLoadSink toReplicationLoadSink( 3201 ReplicationLoadSink rls) { 3202 return ClusterStatusProtos.ReplicationLoadSink.newBuilder() 3203 .setAgeOfLastAppliedOp(rls.getAgeOfLastAppliedOp()) 3204 .setTimeStampsOfLastAppliedOp(rls.getTimestampsOfLastAppliedOp()) 3205 .build(); 3206 } 3207 3208 public static HBaseProtos.TimeRange toTimeRange(TimeRange timeRange) { 3209 if (timeRange == null) { 3210 timeRange = TimeRange.allTime(); 3211 } 3212 return HBaseProtos.TimeRange.newBuilder().setFrom(timeRange.getMin()) 3213 .setTo(timeRange.getMax()) 3214 .build(); 3215 } 3216}