You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by gi...@apache.org on 2026/06/22 23:56:03 UTC
(hbase-site) branch asf-site updated: Published site at c726596ae6d8ce0abe09f92a0cd631725c5d58a8.
This is an automated email from the ASF dual-hosted git repository.
asf-gitbox-commits pushed a commit to branch asf-site
in repository https://gitbox.apache.org/repos/asf/hbase-site.git
The following commit(s) were added to refs/heads/asf-site by this push:
new ec1bacfc326 Published site at c726596ae6d8ce0abe09f92a0cd631725c5d58a8.
ec1bacfc326 is described below
commit ec1bacfc326209de4ddb4ba9ef770288b8c30946
Author: HBase <de...@hbase.apache.org>
AuthorDate: Mon Jun 22 23:50:12 2026 +0000
Published site at c726596ae6d8ce0abe09f92a0cd631725c5d58a8.
---
apidocs/allclasses-index.html | 6 +
apidocs/index-all.html | 146 +-
apidocs/member-search-index.js | 2 +-
apidocs/org/apache/hadoop/hbase/UserMetrics.html | 14 +-
.../hbase/class-use/ExtendedCellScanner.html | 56 +-
.../apache/hadoop/hbase/codec/class-use/Codec.html | 5 +
.../hbase/ipc/class-use/RpcServer.CallCleanup.html | 23 +-
.../hadoop/hbase/ipc/class-use/RpcServer.html | 18 +
.../hadoop/hbase/ipc/class-use/ServerCall.html | 18 +
.../ServerRpcConnection.PreambleResponse.html} | 31 +-
.../{ServerCall.html => ServerRpcConnection.html} | 49 +-
.../apache/hadoop/hbase/ipc/package-summary.html | 8 +-
.../org/apache/hadoop/hbase/ipc/package-tree.html | 15 +
.../org/apache/hadoop/hbase/ipc/package-use.html | 6 +
.../hadoop/hbase/nio/class-use/ByteBuff.html | 32 +-
.../org/apache/hadoop/hbase/nio/package-use.html | 26 +-
.../class-use/MetricsUserSource.ClientMetrics.html | 12 +-
.../security/class-use/HBaseSaslRpcServer.html | 29 +-
.../hbase/security/class-use/SaslStatus.html | 27 +-
.../hadoop/hbase/security/class-use/User.html | 3 +
.../apache/hadoop/hbase/security/package-use.html | 6 +
apidocs/overview-tree.html | 2 +
.../hadoop/hbase/UserMetrics.ClientMetrics.html | 62 +-
.../org/apache/hadoop/hbase/UserMetrics.html | 62 +-
.../UserMetricsBuilder.ClientMetricsImpl.html | 272 +-
.../apache/hadoop/hbase/UserMetricsBuilder.html | 272 +-
.../org/apache/hadoop/hbase/hbtop/field/Field.html | 64 +-
.../hbase/hbtop/mode/ClientModeStrategy.html | 222 +-
.../ipc/RpcServer.BlockingServiceAndInterface.html | 214 +-
.../hadoop/hbase/ipc/RpcServer.CallCleanup.html | 214 +-
.../org/apache/hadoop/hbase/ipc/RpcServer.html | 214 +-
.../org/apache/hadoop/hbase/ipc/ServerCall.html | 696 +-
.../ipc/ServerRpcConnection.PreambleResponse.html | 742 +--
.../hadoop/hbase/ipc/ServerRpcConnection.html | 742 +--
.../hadoop/hbase/regionserver/HRegionServer.html | 4076 ++++++------
.../regionserver/MetricsUserAggregateImpl.html | 324 +-
.../MetricsUserSource.ClientMetrics.html | 71 +-
.../hbase/regionserver/MetricsUserSource.html | 71 +-
.../hbase/regionserver/MetricsUserSourceImpl.html | 460 +-
apidocs/type-search-index.js | 2 +-
books/apache-hbase-reference-guide-dark-mode.pdf | Bin 38919225 -> 38919224 bytes
books/apache-hbase-reference-guide.pdf | Bin 38809477 -> 38809487 bytes
checkstyle-aggregate.html | 16 +-
dependency-convergence.html | 2 +-
dependency-info.html | 2 +-
dependency-management.html | 2 +-
devapidocs/allclasses-index.html | 6874 ++++++++++----------
devapidocs/index-all.html | 91 +-
devapidocs/member-search-index.js | 2 +-
.../hadoop/hbase/UserMetrics.ClientMetrics.html | 40 +-
.../org/apache/hadoop/hbase/UserMetrics.html | 14 +-
.../UserMetricsBuilder.ClientMetricsImpl.html | 132 +-
.../hbase/UserMetricsBuilder.UserMetricsImpl.html | 20 +-
.../apache/hadoop/hbase/UserMetricsBuilder.html | 14 +-
.../org/apache/hadoop/hbase/hbtop/field/Field.html | 80 +-
.../hbase/hbtop/mode/ClientModeStrategy.html | 18 +-
.../apache/hadoop/hbase/ipc/NettyRpcServer.html | 2 +-
.../apache/hadoop/hbase/ipc/NettyServerCall.html | 2 +-
.../hadoop/hbase/ipc/NettyServerRpcConnection.html | 2 +-
.../org/apache/hadoop/hbase/ipc/RpcServer.html | 250 +-
.../org/apache/hadoop/hbase/ipc/ServerCall.html | 268 +-
.../ipc/ServerRpcConnection.ByteBuffByteInput.html | 18 +-
.../ipc/ServerRpcConnection.PreambleResponse.html | 14 +-
.../hadoop/hbase/ipc/ServerRpcConnection.html | 133 +-
.../apache/hadoop/hbase/ipc/SimpleRpcServer.html | 2 +-
.../apache/hadoop/hbase/ipc/SimpleServerCall.html | 15 +-
.../hbase/ipc/SimpleServerRpcConnection.html | 2 +-
.../hbase/ipc/class-use/ServerRpcConnection.html | 12 +
.../ipc/class-use/SimpleServerRpcConnection.html | 2 +-
.../HRegionServer.CompactionChecker.html | 14 +-
.../HRegionServer.MovedRegionInfo.html | 12 +-
.../HRegionServer.PeriodicMemStoreFlusher.html | 14 +-
.../HRegionServer.SystemExitWhenAbortTimeout.html | 6 +-
.../hadoop/hbase/regionserver/HRegionServer.html | 232 +-
...UserAggregateImpl.ClientConnectionContext.html} | 117 +-
.../regionserver/MetricsUserAggregateImpl.html | 118 +-
.../MetricsUserSource.ClientMetrics.html | 40 +-
.../hbase/regionserver/MetricsUserSource.html | 40 +-
.../MetricsUserSourceImpl.ClientMetricsImpl.html | 124 +-
.../hbase/regionserver/MetricsUserSourceImpl.html | 54 +-
...sUserAggregateImpl.ClientConnectionContext.html | 25 +-
.../class-use/MetricsUserSource.ClientMetrics.html | 12 +-
.../hadoop/hbase/regionserver/package-summary.html | 576 +-
.../hadoop/hbase/regionserver/package-tree.html | 1 +
.../hadoop/hbase/regionserver/package-use.html | 364 +-
devapidocs/overview-tree.html | 1 +
.../hadoop/hbase/UserMetrics.ClientMetrics.html | 62 +-
.../org/apache/hadoop/hbase/UserMetrics.html | 62 +-
.../UserMetricsBuilder.ClientMetricsImpl.html | 272 +-
.../hbase/UserMetricsBuilder.UserMetricsImpl.html | 272 +-
.../apache/hadoop/hbase/UserMetricsBuilder.html | 272 +-
.../org/apache/hadoop/hbase/hbtop/field/Field.html | 64 +-
.../hbase/hbtop/mode/ClientModeStrategy.html | 222 +-
.../ipc/RpcServer.BlockingServiceAndInterface.html | 214 +-
.../hadoop/hbase/ipc/RpcServer.CallCleanup.html | 214 +-
.../org/apache/hadoop/hbase/ipc/RpcServer.html | 214 +-
.../org/apache/hadoop/hbase/ipc/ServerCall.html | 696 +-
.../ipc/ServerRpcConnection.ByteBuffByteInput.html | 742 +--
.../ipc/ServerRpcConnection.PreambleResponse.html | 742 +--
.../hadoop/hbase/ipc/ServerRpcConnection.html | 742 +--
.../apache/hadoop/hbase/ipc/SimpleServerCall.html | 9 +-
.../HRegionServer.CompactionChecker.html | 4076 ++++++------
.../HRegionServer.MovedRegionInfo.html | 4076 ++++++------
.../HRegionServer.PeriodicMemStoreFlusher.html | 4076 ++++++------
.../HRegionServer.SystemExitWhenAbortTimeout.html | 4076 ++++++------
.../hadoop/hbase/regionserver/HRegionServer.html | 4076 ++++++------
...sUserAggregateImpl.ClientConnectionContext.html | 330 +
.../regionserver/MetricsUserAggregateImpl.html | 324 +-
.../MetricsUserSource.ClientMetrics.html | 71 +-
.../hbase/regionserver/MetricsUserSource.html | 71 +-
.../MetricsUserSourceImpl.ClientMetricsImpl.html | 460 +-
.../hbase/regionserver/MetricsUserSourceImpl.html | 460 +-
devapidocs/type-search-index.js | 2 +-
hbase-website/dependency-convergence.html | 2 +-
hbase-website/dependency-info.html | 2 +-
hbase-website/dependency-management.html | 2 +-
hbase-website/index.html | 2 +-
hbase-website/issue-management.html | 2 +-
hbase-website/licenses.html | 2 +-
hbase-website/mailing-lists.html | 2 +-
hbase-website/plugin-management.html | 2 +-
hbase-website/plugins.html | 2 +-
hbase-website/project-info.html | 2 +-
hbase-website/scm.html | 2 +-
hbase-website/summary.html | 2 +-
hbase-website/team.html | 2 +-
issue-management.html | 2 +-
licenses.html | 2 +-
mailing-lists.html | 2 +-
plugin-management.html | 2 +-
plugins.html | 2 +-
project-info.html | 2 +-
project-reports.html | 2 +-
scm.html | 2 +-
summary.html | 2 +-
team.html | 2 +-
testapidocs/allclasses-index.html | 3840 +++++------
testapidocs/index-all.html | 110 +-
testapidocs/member-search-index.js | 2 +-
.../class-use/HBaseParameterizedTestTemplate.html | 68 +-
.../hadoop/hbase/class-use/HBaseTestingUtil.html | 11 +-
.../hbase/class-use/TestUserMetricsBuilder.html | 32 +-
.../org/apache/hadoop/hbase/package-summary.html | 28 +-
.../org/apache/hadoop/hbase/package-tree.html | 1 +
.../class-use/MajorCompactionTestBase.html} | 34 +-
.../TestMajorCompactionDataBlockEncoding.html | 10 +-
.../class-use/TestMajorCompactionRequest.html | 10 +-
.../class-use/TestMajorCompactionWithDeletes.html | 10 +-
.../class-use/TestTimeBasedMajorCompaction.html | 10 +-
.../hadoop/hbase/regionserver/package-summary.html | 414 +-
.../hadoop/hbase/regionserver/package-tree.html | 10 +-
.../hadoop/hbase/regionserver/package-use.html | 42 +-
.../class-use/SyncReplicationTestBase.html | 5 +-
...SyncReplicationStandbyKillMaster.TransitCP.html | 10 +-
.../hadoop/hbase/replication/package-summary.html | 38 +-
.../hadoop/hbase/replication/package-tree.html | 3 +-
testapidocs/overview-tree.html | 14 +-
.../hadoop/hbase/TestUserMetricsBuilder.html | 132 +
.../org/apache/hadoop/hbase/hbtop/TestUtils.html | 815 +--
.../regionserver/MajorCompactionTestBase.html | 326 +
.../hbase/regionserver/TestMajorCompaction.html | 557 +-
.../TestMajorCompactionDataBlockEncoding.html | 146 +
.../regionserver/TestMajorCompactionRequest.html | 156 +
.../TestMajorCompactionWithDeletes.html | 180 +
.../regionserver/TestTimeBasedMajorCompaction.html | 168 +
...SyncReplicationStandbyKillMaster.TransitCP.html | 192 +
.../TestSyncReplicationStandbyKillMaster.html | 157 +-
testapidocs/type-search-index.js | 2 +-
testdevapidocs/allclasses-index.html | 5542 ++++++++--------
testdevapidocs/constant-values.html | 55 +-
testdevapidocs/index-all.html | 238 +-
testdevapidocs/member-search-index.js | 2 +-
.../hadoop/hbase/TestUserMetricsBuilder.html | 74 +-
.../class-use/HBaseParameterizedTestTemplate.html | 68 +-
.../hadoop/hbase/class-use/HBaseTestingUtil.html | 40 +-
.../hbase/class-use/TestUserMetricsBuilder.html | 32 +-
.../org/apache/hadoop/hbase/hbtop/TestUtils.html | 192 +-
...C.FailingSimpleRpcServer.FailingConnection.html | 438 +-
.../AbstractTestIPC.FailingSimpleRpcServer.html | 2 +-
.../FailingNettyRpcServer.FailingConnection.html | 410 +-
.../hadoop/hbase/ipc/FailingNettyRpcServer.html | 2 +-
.../org/apache/hadoop/hbase/ipc/package-tree.html | 8 +-
.../hbase/master/http/TestMasterStatusPage.html | 6 +-
.../org/apache/hadoop/hbase/package-summary.html | 38 +-
.../org/apache/hadoop/hbase/package-tree.html | 1 +
.../regionserver/MajorCompactionTestBase.html | 445 ++
.../hbase/regionserver/TestMajorCompaction.html | 451 +-
.../TestMajorCompactionDataBlockEncoding.html | 155 +-
.../regionserver/TestMajorCompactionRequest.html | 113 +-
.../TestMajorCompactionWithDeletes.html | 168 +-
.../regionserver/TestTimeBasedMajorCompaction.html | 65 +-
.../class-use/MajorCompactionTestBase.html | 34 +-
.../TestMajorCompactionDataBlockEncoding.html | 10 +-
.../class-use/TestMajorCompactionRequest.html | 10 +-
.../class-use/TestMajorCompactionWithDeletes.html | 10 +-
.../class-use/TestTimeBasedMajorCompaction.html | 10 +-
.../hadoop/hbase/regionserver/package-summary.html | 546 +-
.../hadoop/hbase/regionserver/package-tree.html | 10 +-
.../hadoop/hbase/regionserver/package-use.html | 116 +-
.../hbase/replication/SyncReplicationTestBase.html | 2 +-
.../SyncReplicationTestBaseNoBeforeAll.html | 2 +-
...SyncReplicationStandbyKillMaster.TransitCP.html | 220 +
.../TestSyncReplicationStandbyKillMaster.html | 87 +-
.../class-use/SyncReplicationTestBase.html | 5 +-
...SyncReplicationStandbyKillMaster.TransitCP.html | 10 +-
.../hadoop/hbase/replication/package-summary.html | 38 +-
.../hadoop/hbase/replication/package-tree.html | 3 +-
testdevapidocs/overview-tree.html | 22 +-
.../hadoop/hbase/TestUserMetricsBuilder.html | 132 +
.../org/apache/hadoop/hbase/hbtop/TestUtils.html | 815 +--
.../hbase/master/http/TestMasterStatusPage.html | 81 +-
.../regionserver/MajorCompactionTestBase.html | 326 +
.../hbase/regionserver/TestMajorCompaction.html | 557 +-
.../TestMajorCompactionDataBlockEncoding.html | 146 +
.../regionserver/TestMajorCompactionRequest.html | 156 +
.../TestMajorCompactionWithDeletes.html | 180 +
.../regionserver/TestTimeBasedMajorCompaction.html | 168 +
...SyncReplicationStandbyKillMaster.TransitCP.html | 192 +
.../TestSyncReplicationStandbyKillMaster.html | 157 +-
testdevapidocs/type-search-index.js | 2 +-
220 files changed, 34828 insertions(+), 31333 deletions(-)
diff --git a/apidocs/allclasses-index.html b/apidocs/allclasses-index.html
index 705e2c92af4..736c855fc8b 100644
--- a/apidocs/allclasses-index.html
+++ b/apidocs/allclasses-index.html
@@ -6742,6 +6742,12 @@ loadScripts(document, 'script');</script>
<div class="col-last odd-row-color all-classes-table all-classes-table-tab2">
<div class="block">Similar to <code>RegionReplicaUtil</code> but for the server side</div>
</div>
+<div class="col-first even-row-color all-classes-table all-classes-table-tab2">org.apache.hadoop.hbase.ipc.ServerRpcConnection</div>
+<div class="col-last even-row-color all-classes-table all-classes-table-tab2">
+<div class="block">Reads calls from a connection and queues them for handling.</div>
+</div>
+<div class="col-first odd-row-color all-classes-table all-classes-table-tab3">org.apache.hadoop.hbase.ipc.ServerRpcConnection.PreambleResponse</div>
+<div class="col-last odd-row-color all-classes-table all-classes-table-tab3"> </div>
<div class="col-first even-row-color all-classes-table all-classes-table-tab2">org.apache.hadoop.hbase.ipc.ServerRpcController</div>
<div class="col-last even-row-color all-classes-table all-classes-table-tab2">
<div class="block">Used for server-side protobuf RPC service invocations.</div>
diff --git a/apidocs/index-all.html b/apidocs/index-all.html
index 559a3be5ed6..e0d33341bf3 100644
--- a/apidocs/index-all.html
+++ b/apidocs/index-all.html
@@ -1115,6 +1115,8 @@ loadScripts(document, 'script');</script>
<dd> </dd>
<dt>addr - Variable in class org.apache.hadoop.hbase.ipc.AbstractRpcClient.RpcChannelImplementation</dt>
<dd> </dd>
+<dt>addr - Variable in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd> </dd>
<dt>addReaderThreads(int) - Method in class org.apache.hadoop.hbase.util.MultiThreadedReader</dt>
<dd> </dd>
<dt>addReaderThreads(int) - Method in class org.apache.hadoop.hbase.util.MultiThreadedReaderWithACL</dt>
@@ -2506,6 +2508,8 @@ loadScripts(document, 'script');</script>
<dd> </dd>
<dt>AUTH_SUCCESSFUL_FOR - Static variable in class org.apache.hadoop.hbase.ipc.RpcServer</dt>
<dd> </dd>
+<dt>authenticatedWithFallback - Variable in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd> </dd>
<dt>AUTHENTICATION - Enum constant in enum class org.apache.hadoop.hbase.security.SaslUtil.QualityOfProtection</dt>
<dd> </dd>
<dt>AUTHENTICATION - Static variable in class org.apache.hadoop.hbase.HBaseInterfaceAudience</dt>
@@ -5322,6 +5326,10 @@ loadScripts(document, 'script');</script>
</dd>
<dt>CallCancelledException(String) - Constructor for exception org.apache.hadoop.hbase.ipc.CallCancelledException</dt>
<dd> </dd>
+<dt>callCleanup - Variable in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd> </dd>
+<dt>callCleanupIfNeeded() - Method in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd> </dd>
<dt>callDroppedException() - Method in interface org.apache.hadoop.hbase.metrics.ExceptionTrackingSource</dt>
<dd> </dd>
<dt>callDroppedException() - Method in class org.apache.hadoop.hbase.metrics.ExceptionTrackingSourceImpl</dt>
@@ -7175,6 +7183,8 @@ loadScripts(document, 'script');</script>
<dd>
<div class="block">Set this key to <code>true</code> to enable table metrics collection of client requests.</div>
</dd>
+<dt>CLIENT_VERSION - Enum constant in enum class org.apache.hadoop.hbase.hbtop.field.Field</dt>
+<dd> </dd>
<dt>CLIENT_ZOOKEEPER_CLIENT_PORT - Static variable in class org.apache.hadoop.hbase.HConstants</dt>
<dd>
<div class="block">Client port of ZooKeeper for client to locate meta</div>
@@ -7202,6 +7212,8 @@ loadScripts(document, 'script');</script>
</dd>
<dt>clientCertificateChain - Variable in class org.apache.hadoop.hbase.ipc.ServerCall</dt>
<dd> </dd>
+<dt>clientCertificateChain - Variable in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd> </dd>
<dt>clientChannelClass() - Method in class org.apache.hadoop.hbase.util.NettyEventLoopGroupConfig</dt>
<dd> </dd>
<dt>org.apache.hadoop.hbase.client.ClientCoprocessorRpcController - Class in <a href="org/apache/hadoop/hbase/client/package-summary.html">org.apache.hadoop.hbase.client</a></dt>
@@ -7245,7 +7257,7 @@ loadScripts(document, 'script');</script>
<dd>
<div class="block">Implementations 'visit' a catalog table row.</div>
</dd>
-<dt>ClientMetricsImpl(String, long, long, long) - Constructor for class org.apache.hadoop.hbase.UserMetricsBuilder.ClientMetricsImpl</dt>
+<dt>ClientMetricsImpl(String, long, long, long, String, String, String, String) - Constructor for class org.apache.hadoop.hbase.UserMetricsBuilder.ClientMetricsImpl</dt>
<dd> </dd>
<dt>org.apache.hadoop.hbase.hbtop.mode.ClientModeStrategy - Class in <a href="org/apache/hadoop/hbase/hbtop/mode/package-summary.html">org.apache.hadoop.hbase.hbtop.mode</a></dt>
<dd>
@@ -7718,6 +7730,8 @@ loadScripts(document, 'script');</script>
<dd>
<div class="block">Closes the writer, in this case flush table commits.</div>
</dd>
+<dt>CLOSE - Enum constant in enum class org.apache.hadoop.hbase.ipc.ServerRpcConnection.PreambleResponse</dt>
+<dd> </dd>
<dt>CLOSE_METRIC_PREFIX - Static variable in interface org.apache.hadoop.hbase.master.MetricsAssignmentManagerSource</dt>
<dd> </dd>
<dt>CLOSE_WAIT_ABORT - Static variable in class org.apache.hadoop.hbase.regionserver.HRegion</dt>
@@ -8039,6 +8053,10 @@ loadScripts(document, 'script');</script>
<dd> </dd>
<dt>codec - Variable in class org.apache.hadoop.hbase.ipc.AbstractRpcClient</dt>
<dd> </dd>
+<dt>codec - Variable in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd>
+<div class="block">Codec the client asked use.</div>
+</dd>
<dt>org.apache.hadoop.hbase.codec.Codec - Interface in <a href="org/apache/hadoop/hbase/codec/package-summary.html">org.apache.hadoop.hbase.codec</a></dt>
<dd>
<div class="block">Encoder/Decoder for Cell.</div>
@@ -9245,6 +9263,10 @@ loadScripts(document, 'script');</script>
</dd>
<dt>compressionByName(String) - Static method in class org.apache.hadoop.hbase.io.hfile.HFileWriterImpl</dt>
<dd> </dd>
+<dt>compressionCodec - Variable in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd>
+<div class="block">Compression codec the client asked us use.</div>
+</dd>
<dt>compressionContext - Variable in class org.apache.hadoop.hbase.regionserver.wal.AbstractProtobufLogWriter</dt>
<dd> </dd>
<dt>org.apache.hadoop.hbase.regionserver.wal.CompressionContext - Class in <a href="org/apache/hadoop/hbase/regionserver/wal/package-summary.html">org.apache.hadoop.hbase.regionserver.wal</a></dt>
@@ -9677,6 +9699,8 @@ loadScripts(document, 'script');</script>
</dd>
<dt>connectionAttributes - Variable in class org.apache.hadoop.hbase.ipc.AbstractRpcClient</dt>
<dd> </dd>
+<dt>connectionAttributes - Variable in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd> </dd>
<dt>connectionCache - Variable in class org.apache.hadoop.hbase.thrift.HBaseServiceHandler</dt>
<dd> </dd>
<dt>org.apache.hadoop.hbase.util.ConnectionCache - Class in <a href="org/apache/hadoop/hbase/util/package-summary.html">org.apache.hadoop.hbase.util</a></dt>
@@ -9722,6 +9746,10 @@ loadScripts(document, 'script');</script>
<dd>
<div class="block">No public c.tors</div>
</dd>
+<dt>connectionHeader - Variable in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd> </dd>
+<dt>connectionHeaderRead - Variable in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd> </dd>
<dt>org.apache.hadoop.hbase.client.ConnectionRegistry - Interface in <a href="org/apache/hadoop/hbase/client/package-summary.html">org.apache.hadoop.hbase.client</a></dt>
<dd>
<div class="block">Registry for meta information needed for connection setup to a HBase cluster.</div>
@@ -9979,6 +10007,8 @@ loadScripts(document, 'script');</script>
<dd> </dd>
<dt>CONTEXT - Static variable in interface org.apache.hadoop.hbase.rest.MetricsRESTSource</dt>
<dd> </dd>
+<dt>CONTINUE - Enum constant in enum class org.apache.hadoop.hbase.ipc.ServerRpcConnection.PreambleResponse</dt>
+<dd> </dd>
<dt>control(String, long) - Method in class org.apache.hadoop.hbase.regionserver.throttle.NoLimitThroughputController</dt>
<dd> </dd>
<dt>control(String, long) - Method in class org.apache.hadoop.hbase.regionserver.throttle.PressureAwareThroughputController</dt>
@@ -11023,6 +11053,8 @@ loadScripts(document, 'script');</script>
<dd>
<div class="block">Creates the cache config.</div>
</dd>
+<dt>createCall(int, BlockingService, Descriptors.MethodDescriptor, RPCProtos.RequestHeader, Message, ExtendedCellScanner, long, InetAddress, int, RpcServer.CallCleanup) - Method in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd> </dd>
<dt>createCell(byte[], int, int) - Method in class org.apache.hadoop.hbase.codec.KeyValueCodec.ByteBuffKeyValueDecoder</dt>
<dd> </dd>
<dt>createCell(byte[], int, int) - Method in class org.apache.hadoop.hbase.codec.KeyValueCodecWithTags.ByteBuffKeyValueDecoder</dt>
@@ -15546,6 +15578,8 @@ loadScripts(document, 'script');</script>
</dd>
<dt>dispose(T) - Method in class org.apache.hadoop.hbase.http.jersey.SupplierFactoryAdapter</dt>
<dd> </dd>
+<dt>disposeSasl() - Method in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd> </dd>
<dt>divideForAvg(S, Long) - Method in class org.apache.hadoop.hbase.coprocessor.ColumnInterpreter</dt>
<dd>
<div class="block">used for computing average of <S> data values.</div>
@@ -15771,6 +15805,10 @@ loadScripts(document, 'script');</script>
<dd> </dd>
<dt>doPost(HttpServletRequest, HttpServletResponse) - Method in class org.apache.hadoop.hbase.thrift.ThriftHttpServlet</dt>
<dd> </dd>
+<dt>doRawSaslReply(SaslStatus, Writable, String, String) - Method in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd>
+<div class="block">No protobuf encoding of raw sasl messages</div>
+</dd>
<dt>doRealSeek(KeyValueScanner, ExtendedCell, boolean) - Static method in class org.apache.hadoop.hbase.regionserver.NonLazyKeyValueScanner</dt>
<dd> </dd>
<dt>doRegionCompactionPrep() - Method in class org.apache.hadoop.hbase.regionserver.HRegion</dt>
@@ -15792,6 +15830,8 @@ loadScripts(document, 'script');</script>
<dd> </dd>
<dt>doResizeIfNecessary() - Method in interface org.apache.hadoop.hbase.hbtop.terminal.Terminal</dt>
<dd> </dd>
+<dt>doRespond(RpcResponse) - Method in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd> </dd>
<dt>doSetup(Mapper.Context) - Method in class org.apache.hadoop.hbase.mapreduce.TsvImporterMapper</dt>
<dd>
<div class="block">Handles common parameter initialization that a subclass might want to leverage.</div>
@@ -22350,6 +22390,12 @@ loadScripts(document, 'script');</script>
<dd>
<div class="block">Get the list of client ports.</div>
</dd>
+<dt>getClientVersion() - Method in interface org.apache.hadoop.hbase.regionserver.MetricsUserSource.ClientMetrics</dt>
+<dd> </dd>
+<dt>getClientVersion() - Method in interface org.apache.hadoop.hbase.UserMetrics.ClientMetrics</dt>
+<dd> </dd>
+<dt>getClientVersion() - Method in class org.apache.hadoop.hbase.UserMetricsBuilder.ClientMetricsImpl</dt>
+<dd> </dd>
<dt>getClientVersionInfo() - Method in interface org.apache.hadoop.hbase.ipc.RpcCallContext</dt>
<dd>
<div class="block">Returns the client version info, or null if the information is not present</div>
@@ -23117,6 +23163,10 @@ loadScripts(document, 'script');</script>
<div class="deprecation-block"><span class="deprecated-label">Deprecated.</span></div>
<div class="block">Get a shared Connection to the cluster.</div>
</dd>
+<dt>getConnection() - Method in class org.apache.hadoop.hbase.ipc.ServerCall</dt>
+<dd>
+<div class="block">Get the ServerRpcConnection associated with this call.</div>
+</dd>
<dt>getConnection() - Method in class org.apache.hadoop.hbase.MockRegionServerServices</dt>
<dd> </dd>
<dt>getConnection() - Method in interface org.apache.hadoop.hbase.Server</dt>
@@ -23159,6 +23209,8 @@ loadScripts(document, 'script');</script>
<dd>
<div class="block">For test only.</div>
</dd>
+<dt>getConnectionHeader() - Method in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd> </dd>
<dt>getConnectionRegistry() - Method in class org.apache.hadoop.hbase.client.AsyncConnectionImpl</dt>
<dd> </dd>
<dt>getConnectionString() - Method in interface org.apache.hadoop.hbase.client.ConnectionRegistry</dt>
@@ -23459,6 +23511,11 @@ loadScripts(document, 'script');</script>
<div class="block">Just return the current rpc call if it is a <code>ServerCall</code> and also has <code>CellScanner</code>
attached.</div>
</dd>
+<dt>getCurrentServerRpcConnection() - Static method in class org.apache.hadoop.hbase.ipc.RpcServer</dt>
+<dd>
+<div class="block">Returns the ServerRpcConnection for the current RPC request or not present if no connection is
+ available.</div>
+</dd>
<dt>getCurrentSize() - Method in interface org.apache.hadoop.hbase.io.hfile.BlockCache</dt>
<dd>
<div class="block">Returns the occupied size of the block cache, in bytes.</div>
@@ -24384,6 +24441,8 @@ loadScripts(document, 'script');</script>
<dd>
<div class="block">Returns the Bloom filter error rate in the given configuration</div>
</dd>
+<dt>getErrorResponse(String, Exception) - Method in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd> </dd>
<dt>getErrors() - Method in class org.apache.hadoop.hbase.util.HBaseFsck</dt>
<dd>
<div class="deprecation-block"><span class="deprecated-label">Deprecated.</span></div>
@@ -25779,10 +25838,20 @@ loadScripts(document, 'script');</script>
<dd>
<div class="block">Returns the host name</div>
</dd>
+<dt>getHostAddress() - Method in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd> </dd>
+<dt>getHostAddress() - Method in interface org.apache.hadoop.hbase.regionserver.MetricsUserSource.ClientMetrics</dt>
+<dd> </dd>
+<dt>getHostAddress() - Method in interface org.apache.hadoop.hbase.UserMetrics.ClientMetrics</dt>
+<dd> </dd>
+<dt>getHostAddress() - Method in class org.apache.hadoop.hbase.UserMetricsBuilder.ClientMetricsImpl</dt>
+<dd> </dd>
<dt>getHostAndWeights() - Method in class org.apache.hadoop.hbase.HDFSBlocksDistribution</dt>
<dd>
<div class="block">Returns the hosts and their weights</div>
</dd>
+<dt>getHostInetAddress() - Method in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd> </dd>
<dt>getHostname() - Method in exception org.apache.hadoop.hbase.exceptions.RegionMovedException</dt>
<dd> </dd>
<dt>getHostname() - Method in class org.apache.hadoop.hbase.HRegionLocation</dt>
@@ -29598,11 +29667,11 @@ loadScripts(document, 'script');</script>
<dd> </dd>
<dt>getOrCreate(PoolMap.PoolResourceSupplier<R>) - Method in interface org.apache.hadoop.hbase.util.PoolMap.Pool</dt>
<dd> </dd>
-<dt>getOrCreateMetricsClient(String) - Method in interface org.apache.hadoop.hbase.regionserver.MetricsUserSource</dt>
+<dt>getOrCreateMetricsClient(String, String, String, String, String) - Method in interface org.apache.hadoop.hbase.regionserver.MetricsUserSource</dt>
<dd>
<div class="block">Create a instance of ClientMetrics if not present otherwise return the previous one</div>
</dd>
-<dt>getOrCreateMetricsClient(String) - Method in class org.apache.hadoop.hbase.regionserver.MetricsUserSourceImpl</dt>
+<dt>getOrCreateMetricsClient(String, String, String, String, String) - Method in class org.apache.hadoop.hbase.regionserver.MetricsUserSourceImpl</dt>
<dd> </dd>
<dt>getOrCreateMetricsUser(String) - Method in interface org.apache.hadoop.hbase.regionserver.MetricsUserAggregateSource</dt>
<dd>
@@ -31643,6 +31712,8 @@ loadScripts(document, 'script');</script>
</dd>
<dt>getRemotePort() - Method in class org.apache.hadoop.hbase.ipc.ServerCall</dt>
<dd> </dd>
+<dt>getRemotePort() - Method in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd> </dd>
<dt>getRemoteWALDir() - Method in class org.apache.hadoop.hbase.replication.ReplicationPeerConfig</dt>
<dd> </dd>
<dt>getRemoteWALFileSystem(Configuration, String) - Static method in class org.apache.hadoop.hbase.replication.ReplicationUtils</dt>
@@ -33102,6 +33173,12 @@ loadScripts(document, 'script');</script>
<dd> </dd>
<dt>getServiceInterface(List<RpcServer.BlockingServiceAndInterface>, String) - Static method in class org.apache.hadoop.hbase.ipc.RpcServer</dt>
<dd> </dd>
+<dt>getServiceName() - Method in interface org.apache.hadoop.hbase.regionserver.MetricsUserSource.ClientMetrics</dt>
+<dd> </dd>
+<dt>getServiceName() - Method in interface org.apache.hadoop.hbase.UserMetrics.ClientMetrics</dt>
+<dd> </dd>
+<dt>getServiceName() - Method in class org.apache.hadoop.hbase.UserMetricsBuilder.ClientMetricsImpl</dt>
+<dd> </dd>
<dt>getServiceName(Descriptors.ServiceDescriptor) - Static method in class org.apache.hadoop.hbase.ipc.CoprocessorRpcUtils</dt>
<dd>
<div class="block">Returns the name to use for coprocessor service calls.</div>
@@ -35564,10 +35641,16 @@ loadScripts(document, 'script');</script>
<dd> </dd>
<dt>getUserName() - Method in class org.apache.hadoop.hbase.quotas.QuotaSettings</dt>
<dd> </dd>
+<dt>getUserName() - Method in interface org.apache.hadoop.hbase.regionserver.MetricsUserSource.ClientMetrics</dt>
+<dd> </dd>
+<dt>getUserName() - Method in interface org.apache.hadoop.hbase.UserMetrics.ClientMetrics</dt>
+<dd> </dd>
<dt><a href="org/apache/hadoop/hbase/UserMetrics.html#getUserName()" class="member-name-link">getUserName()</a> - Method in interface org.apache.hadoop.hbase.<a href="org/apache/hadoop/hbase/UserMetrics.html" title="interface in org.apache.hadoop.hbase">UserMetrics</a></dt>
<dd>
<div class="block">Returns the user name</div>
</dd>
+<dt>getUserName() - Method in class org.apache.hadoop.hbase.UserMetricsBuilder.ClientMetricsImpl</dt>
+<dd> </dd>
<dt>getUserPermissions(GetUserPermissionsRequest) - Method in interface org.apache.hadoop.hbase.client.Admin</dt>
<dd>
<div class="block">Get the global/namespace/table permissions for user</div>
@@ -35892,6 +35975,8 @@ loadScripts(document, 'script');</script>
<dd> </dd>
<dt>getVersionedTail() - Method in class org.apache.hadoop.hbase.regionserver.CompactionPipeline</dt>
<dd> </dd>
+<dt>getVersionInfo() - Method in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd> </dd>
<dt>getVersionInfo() - Static method in class org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil</dt>
<dd>
<div class="block">Get a protocol buffer VersionInfo</div>
@@ -38979,6 +39064,10 @@ loadScripts(document, 'script');</script>
<dd> </dd>
<dt>HOST - Static variable in class org.apache.hadoop.hbase.zookeeper.MiniZooKeeperCluster</dt>
<dd> </dd>
+<dt>HOST_ADDRESS - Enum constant in enum class org.apache.hadoop.hbase.hbtop.field.Field</dt>
+<dd> </dd>
+<dt>hostAddress - Variable in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd> </dd>
<dt>HostAndWeight(String, long, long) - Constructor for class org.apache.hadoop.hbase.HDFSBlocksDistribution.HostAndWeight</dt>
<dd>
<div class="block">Constructor</div>
@@ -42004,6 +42093,8 @@ loadScripts(document, 'script');</script>
<div class="block">Check if the exception is something that indicates that we cannot contact/communicate with the
server.</div>
</dd>
+<dt>isConnectionOpen() - Method in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd> </dd>
<dt>isCorrectEncoder(DataBlockEncoder, short) - Static method in enum class org.apache.hadoop.hbase.io.encoding.DataBlockEncoding</dt>
<dd>
<div class="block">Check if given encoder has this id.</div>
@@ -56378,6 +56469,8 @@ service.</div>
<dd>
<div class="block">For backward compatibility.</div>
</dd>
+<dt>processOneRpc(ByteBuff) - Method in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd> </dd>
<dt>processOptions(String[]) - Method in class org.apache.hadoop.hbase.thrift.ThriftServer</dt>
<dd>
<div class="block">Parse the command line options to set parameters the conf.</div>
@@ -56412,6 +56505,13 @@ service.</div>
<dd> </dd>
<dt><a href="org/apache/hadoop/hbase/io/crypto/KeyStoreKeyProvider.html#processParameters(java.net.URI)" class="member-name-link">processParameters(URI)</a> - Method in class org.apache.hadoop.hbase.io.crypto.<a href="org/apache/hadoop/hbase/io/crypto/KeyStoreKeyProvider.html" title="class in org.apache.hadoop.hbase.io.crypto">KeyStoreKeyProvider</a></dt>
<dd> </dd>
+<dt>processPreamble(ByteBuffer) - Method in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd> </dd>
+<dt>processRequest(ByteBuff) - Method in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd>
+<div class="block">Has the request header and the request param and optionally encoded data buffer all in this one
+ array.</div>
+</dd>
<dt>processResult(int, String, Object) - Method in class org.apache.hadoop.hbase.coordination.ZKSplitLogManagerCoordination.DeleteAsyncCallback</dt>
<dd> </dd>
<dt>processResult(int, String, Object, byte[], Stat) - Method in class org.apache.hadoop.hbase.coordination.ZKSplitLogManagerCoordination.GetDataAsyncCallback</dt>
@@ -56509,6 +56609,8 @@ service.</div>
<dd> </dd>
<dt>provideHint - Variable in class org.apache.hadoop.hbase.filter.PrefixFilter</dt>
<dd> </dd>
+<dt>provider - Variable in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd> </dd>
<dt>providerId - Variable in class org.apache.hadoop.hbase.wal.AbstractWALProvider</dt>
<dd> </dd>
<dt>providers - Variable in class org.apache.hadoop.hbase.ipc.AbstractRpcClient</dt>
@@ -59507,6 +59609,8 @@ service.</div>
<dd> </dd>
<dt>remoteAddress - Variable in class org.apache.hadoop.hbase.ipc.ServerCall</dt>
<dd> </dd>
+<dt>remotePort - Variable in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd> </dd>
<dt>remoteProcedureComplete(long, long, Throwable, byte[]) - Method in class org.apache.hadoop.hbase.regionserver.HRegionServer</dt>
<dd> </dd>
<dt>remoteProcedureCompleted(long, byte[]) - Method in class org.apache.hadoop.hbase.master.HMaster</dt>
@@ -61401,6 +61505,8 @@ service.</div>
<dd> </dd>
<dt>RetryImmediatelyException(String) - Constructor for exception org.apache.hadoop.hbase.RetryImmediatelyException</dt>
<dd> </dd>
+<dt>retryImmediatelySupported - Variable in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd> </dd>
<dt>returnByteBuffDecompressor(ByteBuffDecompressor) - Static method in class org.apache.hadoop.hbase.io.compress.CodecPool</dt>
<dd> </dd>
<dt>returnByteBuffDecompressor(ByteBuffDecompressor) - Method in enum class org.apache.hadoop.hbase.io.compress.Compression.Algorithm</dt>
@@ -62043,6 +62149,8 @@ service.</div>
</dd>
<dt>rpcServer - Variable in class org.apache.hadoop.hbase.HBaseRpcServicesBase</dt>
<dd> </dd>
+<dt>rpcServer - Variable in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd> </dd>
<dt>org.apache.hadoop.hbase.ipc.RpcServer - Class in <a href="org/apache/hadoop/hbase/ipc/package-summary.html">org.apache.hadoop.hbase.ipc</a></dt>
<dd>
<div class="block">An RPC server that hosts protobuf described Services.</div>
@@ -62535,6 +62643,8 @@ service.</div>
<dd> </dd>
<dt>saslProviders - Variable in class org.apache.hadoop.hbase.ipc.RpcServer</dt>
<dd> </dd>
+<dt>saslServer - Variable in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd> </dd>
<dt>org.apache.hadoop.hbase.security.SaslStatus - Enum Class in <a href="org/apache/hadoop/hbase/security/package-summary.html">org.apache.hadoop.hbase.security</a></dt>
<dd> </dd>
<dt>org.apache.hadoop.hbase.security.SaslUnwrapHandler - Class in <a href="org/apache/hadoop/hbase/security/package-summary.html">org.apache.hadoop.hbase.security</a></dt>
@@ -63468,6 +63578,14 @@ service.</div>
<dd>
<div class="block">The server was removed from the cluster.</div>
</dd>
+<dt>org.apache.hadoop.hbase.ipc.ServerRpcConnection - Class in <a href="org/apache/hadoop/hbase/ipc/package-summary.html">org.apache.hadoop.hbase.ipc</a></dt>
+<dd>
+<div class="block">Reads calls from a connection and queues them for handling.</div>
+</dd>
+<dt>ServerRpcConnection(RpcServer) - Constructor for class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd> </dd>
+<dt>org.apache.hadoop.hbase.ipc.ServerRpcConnection.PreambleResponse - Enum Class in <a href="org/apache/hadoop/hbase/ipc/package-summary.html">org.apache.hadoop.hbase.ipc</a></dt>
+<dd> </dd>
<dt>org.apache.hadoop.hbase.ipc.ServerRpcController - Class in <a href="org/apache/hadoop/hbase/ipc/package-summary.html">org.apache.hadoop.hbase.ipc</a></dt>
<dd>
<div class="block">Used for server-side protobuf RPC service invocations.</div>
@@ -63526,12 +63644,16 @@ service.</div>
</dd>
<dt>service - Variable in class org.apache.hadoop.hbase.ipc.ServerCall</dt>
<dd> </dd>
+<dt>service - Variable in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd> </dd>
<dt>service(HttpServletRequest, HttpServletResponse) - Method in class org.apache.hadoop.hbase.rest.RESTServletContainer</dt>
<dd>
<div class="block">This container is used only if authentication and impersonation is enabled.</div>
</dd>
<dt>SERVICE_KEY - Static variable in class org.apache.hadoop.hbase.util.JSONMetricUtil</dt>
<dd> </dd>
+<dt>SERVICE_NAME - Enum constant in enum class org.apache.hadoop.hbase.hbtop.field.Field</dt>
+<dd> </dd>
<dt>org.apache.hadoop.hbase.client.ServiceCaller<S,<wbr>R> - Interface in <a href="org/apache/hadoop/hbase/client/package-summary.html">org.apache.hadoop.hbase.client</a></dt>
<dd>
<div class="block">Delegate to a protobuf rpc call.</div>
@@ -67988,6 +68110,8 @@ service.</div>
<dd> </dd>
<dt>SKIPFLUSH - Enum constant in enum class org.apache.hadoop.hbase.client.SnapshotType</dt>
<dd> </dd>
+<dt>skipInitialSaslHandshake - Variable in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd> </dd>
<dt>skipKVsNewerThanReadpoint() - Method in class org.apache.hadoop.hbase.regionserver.StoreFileScanner</dt>
<dd> </dd>
<dt>skipRegionManagementAction(String) - Method in class org.apache.hadoop.hbase.master.HMaster</dt>
@@ -70570,6 +70694,8 @@ service.</div>
</dd>
<dt>SUBSYSTEM_KEY - Static variable in class org.apache.hadoop.hbase.util.JSONMetricUtil</dt>
<dd> </dd>
+<dt>SUCCEED - Enum constant in enum class org.apache.hadoop.hbase.ipc.ServerRpcConnection.PreambleResponse</dt>
+<dd> </dd>
<dt>SUCCESS - Enum constant in enum class org.apache.hadoop.hbase.HConstants.OperationStatusCode</dt>
<dd> </dd>
<dt>SUCCESS - Enum constant in enum class org.apache.hadoop.hbase.master.SplitLogManager.TerminationStatus</dt>
@@ -73458,6 +73584,8 @@ service.</div>
<dd> </dd>
<dt>toString() - Method in class org.apache.hadoop.hbase.ipc.ServerCall</dt>
<dd> </dd>
+<dt>toString() - Method in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd> </dd>
<dt>toString() - Method in class org.apache.hadoop.hbase.KeyValue.KeyOnlyKeyValue</dt>
<dd> </dd>
<dt>toString() - Method in class org.apache.hadoop.hbase.KeyValue</dt>
@@ -74489,6 +74617,8 @@ service.</div>
</dl>
<h2 class="title" id="I:U">U</h2>
<dl class="index">
+<dt>ugi - Variable in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd> </dd>
<dt>ugi - Variable in class org.apache.hadoop.hbase.security.User</dt>
<dd> </dd>
<dt>unackedAppends - Variable in class org.apache.hadoop.hbase.regionserver.wal.AbstractFSWAL</dt>
@@ -76108,6 +76238,8 @@ service.</div>
<dd> </dd>
<dt>user - Variable in class org.apache.hadoop.hbase.ipc.ServerCall</dt>
<dd> </dd>
+<dt>user - Variable in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd> </dd>
<dt>org.apache.hadoop.hbase.security.User - Class in <a href="org/apache/hadoop/hbase/security/package-summary.html">org.apache.hadoop.hbase.security</a></dt>
<dd>
<div class="block">Wrapper to abstract out usage of user and group information in HBase.</div>
@@ -76122,6 +76254,8 @@ service.</div>
<dd> </dd>
<dt>USER_COUNT - Enum constant in enum class org.apache.hadoop.hbase.hbtop.field.Field</dt>
<dd> </dd>
+<dt>USER_NAME - Enum constant in enum class org.apache.hadoop.hbase.hbtop.field.Field</dt>
+<dd> </dd>
<dt>USER_REGION_COPROCESSOR_CONF_KEY - Static variable in class org.apache.hadoop.hbase.coprocessor.CoprocessorHost</dt>
<dd> </dd>
<dt>USER_SCAN - Enum constant in enum class org.apache.hadoop.hbase.regionserver.ScanType</dt>
@@ -76182,6 +76316,8 @@ service.</div>
<dd> </dd>
<dt>UserTableDirFilter(FileSystem) - Constructor for class org.apache.hadoop.hbase.util.FSUtils.UserTableDirFilter</dt>
<dd> </dd>
+<dt>useSasl - Variable in class org.apache.hadoop.hbase.ipc.ServerRpcConnection</dt>
+<dd> </dd>
<dt>useThisHostnameInstead - Variable in class org.apache.hadoop.hbase.HBaseServerBase</dt>
<dd>
<div class="block">hostname specified by hostname config</div>
@@ -76451,6 +76587,8 @@ service.</div>
<dd> </dd>
<dt>valueOf(String) - Static method in enum class org.apache.hadoop.hbase.io.Reference.Range</dt>
<dd> </dd>
+<dt>valueOf(String) - Static method in enum class org.apache.hadoop.hbase.ipc.ServerRpcConnection.PreambleResponse</dt>
+<dd> </dd>
<dt>valueOf(String) - Static method in enum class org.apache.hadoop.hbase.KeepDeletedCells</dt>
<dd> </dd>
<dt>valueOf(String) - Static method in enum class org.apache.hadoop.hbase.KeyValue.Type</dt>
@@ -76725,6 +76863,8 @@ service.</div>
<dd> </dd>
<dt>values() - Static method in enum class org.apache.hadoop.hbase.io.Reference.Range</dt>
<dd> </dd>
+<dt>values() - Static method in enum class org.apache.hadoop.hbase.ipc.ServerRpcConnection.PreambleResponse</dt>
+<dd> </dd>
<dt>values() - Static method in enum class org.apache.hadoop.hbase.KeepDeletedCells</dt>
<dd> </dd>
<dt>values() - Static method in enum class org.apache.hadoop.hbase.KeyValue.Type</dt>
diff --git a/apidocs/member-search-index.js b/apidocs/member-search-index.js
index 464f1b60cba..520422e2f60 100644
--- a/apidocs/member-search-index.js
+++ b/apidocs/member-search-index.js
@@ -1 +1 @@
-memberSearchIndex = [{"p":"org.apache.hadoop.hbase.filter","c":"ParseConstants","l":"A"},{"p":"org.apache.hadoop.hbase.master","c":"RegionState.State","l":"ABNORMALLY_CLOSED"},{"p":"org.apache.hadoop.hbase.coprocessor","c":"CoprocessorHost","l":"ABORT_ON_ERROR_KEY"},{"p":"org.apache.hadoop.hdfs","c":"DummyDFSOutputStream","l":"abort()"},{"p":"org.apache.hadoop.hbase","c":"Abortable","l":"abort(String)","u":"abort(java.lang.String)"},{"p":"org.apache.hadoop.hbase","c":"Abortable","l":"abo [...]
\ No newline at end of file
+memberSearchIndex = [{"p":"org.apache.hadoop.hbase.filter","c":"ParseConstants","l":"A"},{"p":"org.apache.hadoop.hbase.master","c":"RegionState.State","l":"ABNORMALLY_CLOSED"},{"p":"org.apache.hadoop.hbase.coprocessor","c":"CoprocessorHost","l":"ABORT_ON_ERROR_KEY"},{"p":"org.apache.hadoop.hdfs","c":"DummyDFSOutputStream","l":"abort()"},{"p":"org.apache.hadoop.hbase","c":"Abortable","l":"abort(String)","u":"abort(java.lang.String)"},{"p":"org.apache.hadoop.hbase","c":"Abortable","l":"abo [...]
\ No newline at end of file
diff --git a/apidocs/org/apache/hadoop/hbase/UserMetrics.html b/apidocs/org/apache/hadoop/hbase/UserMetrics.html
index 6c1d94d6bc5..0b97dacf5cc 100644
--- a/apidocs/org/apache/hadoop/hbase/UserMetrics.html
+++ b/apidocs/org/apache/hadoop/hbase/UserMetrics.html
@@ -160,28 +160,28 @@ loadScripts(document, 'script');</script>
<li>
<section class="detail" id="getUserName()">
<h3>getUserName</h3>
-<div class="member-signature"><span class="return-type">byte[]</span> <span class="element-name"><a href="../../../../src-html/org/apache/hadoop/hbase/UserMetrics.html#line-44">getUserName</a></span>()</div>
+<div class="member-signature"><span class="return-type">byte[]</span> <span class="element-name"><a href="../../../../src-html/org/apache/hadoop/hbase/UserMetrics.html#line-52">getUserName</a></span>()</div>
<div class="block">Returns the user name</div>
</section>
</li>
<li>
<section class="detail" id="getReadRequestCount()">
<h3>getReadRequestCount</h3>
-<div class="member-signature"><span class="return-type">long</span> <span class="element-name"><a href="../../../../src-html/org/apache/hadoop/hbase/UserMetrics.html#line-47">getReadRequestCount</a></span>()</div>
+<div class="member-signature"><span class="return-type">long</span> <span class="element-name"><a href="../../../../src-html/org/apache/hadoop/hbase/UserMetrics.html#line-55">getReadRequestCount</a></span>()</div>
<div class="block">Returns the number of read requests made by user</div>
</section>
</li>
<li>
<section class="detail" id="getWriteRequestCount()">
<h3>getWriteRequestCount</h3>
-<div class="member-signature"><span class="return-type">long</span> <span class="element-name"><a href="../../../../src-html/org/apache/hadoop/hbase/UserMetrics.html#line-50">getWriteRequestCount</a></span>()</div>
+<div class="member-signature"><span class="return-type">long</span> <span class="element-name"><a href="../../../../src-html/org/apache/hadoop/hbase/UserMetrics.html#line-58">getWriteRequestCount</a></span>()</div>
<div class="block">Returns the number of write requests made by user</div>
</section>
</li>
<li>
<section class="detail" id="getRequestCount()">
<h3>getRequestCount</h3>
-<div class="member-signature"><span class="modifiers">default</span> <span class="return-type">long</span> <span class="element-name"><a href="../../../../src-html/org/apache/hadoop/hbase/UserMetrics.html#line-56">getRequestCount</a></span>()</div>
+<div class="member-signature"><span class="modifiers">default</span> <span class="return-type">long</span> <span class="element-name"><a href="../../../../src-html/org/apache/hadoop/hbase/UserMetrics.html#line-64">getRequestCount</a></span>()</div>
<div class="block">Returns the number of write requests and read requests and coprocessor service requests made by
the user</div>
</section>
@@ -189,21 +189,21 @@ loadScripts(document, 'script');</script>
<li>
<section class="detail" id="getNameAsString()">
<h3>getNameAsString</h3>
-<div class="member-signature"><span class="modifiers">default</span> <span class="return-type"><a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a></span> <span class="element-name"><a href="../../../../src-html/org/apache/hadoop/hbase/UserMetrics.html#line-61">getNameAsString</a></span>()</div>
+<div class="member-signature"><span class="modifiers">default</span> <span class="return-type"><a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a></span> <span class="element-name"><a href="../../../../src-html/org/apache/hadoop/hbase/UserMetrics.html#line-69">getNameAsString</a></span>()</div>
<div class="block">Returns the user name as a string</div>
</section>
</li>
<li>
<section class="detail" id="getClientMetrics()">
<h3>getClientMetrics</h3>
-<div class="member-signature"><span class="return-type"><a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Map.html" title="class or interface in java.util" class="external-link">Map</a><<a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>,<wbr>org.apache.hadoop.hbase.UserMetrics.ClientMetrics></span> <span class="element-name"><a href=" [...]
+<div class="member-signature"><span class="return-type"><a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Map.html" title="class or interface in java.util" class="external-link">Map</a><<a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>,<wbr>org.apache.hadoop.hbase.UserMetrics.ClientMetrics></span> <span class="element-name"><a href=" [...]
<div class="block">Returns metrics per client(hostname)</div>
</section>
</li>
<li>
<section class="detail" id="getFilteredReadRequests()">
<h3>getFilteredReadRequests</h3>
-<div class="member-signature"><span class="return-type">long</span> <span class="element-name"><a href="../../../../src-html/org/apache/hadoop/hbase/UserMetrics.html#line-69">getFilteredReadRequests</a></span>()</div>
+<div class="member-signature"><span class="return-type">long</span> <span class="element-name"><a href="../../../../src-html/org/apache/hadoop/hbase/UserMetrics.html#line-77">getFilteredReadRequests</a></span>()</div>
<div class="block">Returns count of filtered read requests for a user</div>
</section>
</li>
diff --git a/apidocs/org/apache/hadoop/hbase/class-use/ExtendedCellScanner.html b/apidocs/org/apache/hadoop/hbase/class-use/ExtendedCellScanner.html
index e2d76ee1780..668e1020d91 100644
--- a/apidocs/org/apache/hadoop/hbase/class-use/ExtendedCellScanner.html
+++ b/apidocs/org/apache/hadoop/hbase/class-use/ExtendedCellScanner.html
@@ -282,51 +282,63 @@ loadScripts(document, 'script');</script>
<div class="table-header col-first">Modifier and Type</div>
<div class="table-header col-second">Method</div>
<div class="table-header col-last">Description</div>
-<div class="col-first even-row-color"><code>org.apache.hadoop.hbase.ipc.HBaseRpcController</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">RpcControllerFactory.</span><code>newController<wbr>(org.apache.hadoop.hbase.client.RegionInfo regionInfo,
- org.apache.hadoop.hbase.ExtendedCellScanner cellScanner)</code></div>
+<div class="col-first even-row-color"><code>abstract org.apache.hadoop.hbase.ipc.ServerCall<?></code></div>
+<div class="col-second even-row-color"><span class="type-name-label">ServerRpcConnection.</span><code>createCall<wbr>(int id,
+ org.apache.hbase.thirdparty.com.google.protobuf.BlockingService service,
+ org.apache.hbase.thirdparty.com.google.protobuf.Descriptors.MethodDescriptor md,
+ org.apache.hadoop.hbase.shaded.protobuf.generated.RPCProtos.RequestHeader header,
+ org.apache.hbase.thirdparty.com.google.protobuf.Message param,
+ org.apache.hadoop.hbase.ExtendedCellScanner cellScanner,
+ long size,
+ <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/net/InetAddress.html" title="class or interface in java.net" class="external-link">InetAddress</a> remoteAddress,
+ int timeout,
+ org.apache.hadoop.hbase.ipc.RpcServer.CallCleanup reqCleanup)</code></div>
<div class="col-last even-row-color"> </div>
<div class="col-first odd-row-color"><code>org.apache.hadoop.hbase.ipc.HBaseRpcController</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">RpcControllerFactory.</span><code>newController<wbr>(org.apache.hadoop.hbase.ExtendedCellScanner cellScanner)</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">RpcControllerFactory.</span><code>newController<wbr>(org.apache.hadoop.hbase.client.RegionInfo regionInfo,
+ org.apache.hadoop.hbase.ExtendedCellScanner cellScanner)</code></div>
<div class="col-last odd-row-color"> </div>
-<div class="col-first even-row-color"><code>void</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">DelegatingHBaseRpcController.</span><code>setCellScanner<wbr>(org.apache.hadoop.hbase.ExtendedCellScanner cellScanner)</code></div>
+<div class="col-first even-row-color"><code>org.apache.hadoop.hbase.ipc.HBaseRpcController</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">RpcControllerFactory.</span><code>newController<wbr>(org.apache.hadoop.hbase.ExtendedCellScanner cellScanner)</code></div>
<div class="col-last even-row-color"> </div>
<div class="col-first odd-row-color"><code>void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">HBaseRpcController.</span><code>setCellScanner<wbr>(org.apache.hadoop.hbase.ExtendedCellScanner cellScanner)</code></div>
-<div class="col-last odd-row-color">
+<div class="col-second odd-row-color"><span class="type-name-label">DelegatingHBaseRpcController.</span><code>setCellScanner<wbr>(org.apache.hadoop.hbase.ExtendedCellScanner cellScanner)</code></div>
+<div class="col-last odd-row-color"> </div>
+<div class="col-first even-row-color"><code>void</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">HBaseRpcController.</span><code>setCellScanner<wbr>(org.apache.hadoop.hbase.ExtendedCellScanner cellScanner)</code></div>
+<div class="col-last even-row-color">
<div class="block">Only used to send cells to rpc server, the returned cells should be set by
<code>HBaseRpcController.setDone(ExtendedCellScanner)</code>.</div>
</div>
-<div class="col-first even-row-color"><code>void</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">HBaseRpcControllerImpl.</span><code>setCellScanner<wbr>(org.apache.hadoop.hbase.ExtendedCellScanner cellScanner)</code></div>
-<div class="col-last even-row-color"> </div>
<div class="col-first odd-row-color"><code>void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">DelegatingHBaseRpcController.</span><code>setDone<wbr>(org.apache.hadoop.hbase.ExtendedCellScanner cellScanner)</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">HBaseRpcControllerImpl.</span><code>setCellScanner<wbr>(org.apache.hadoop.hbase.ExtendedCellScanner cellScanner)</code></div>
<div class="col-last odd-row-color"> </div>
<div class="col-first even-row-color"><code>void</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">HBaseRpcController.</span><code>setDone<wbr>(org.apache.hadoop.hbase.ExtendedCellScanner cellScanner)</code></div>
-<div class="col-last even-row-color">
+<div class="col-second even-row-color"><span class="type-name-label">DelegatingHBaseRpcController.</span><code>setDone<wbr>(org.apache.hadoop.hbase.ExtendedCellScanner cellScanner)</code></div>
+<div class="col-last even-row-color"> </div>
+<div class="col-first odd-row-color"><code>void</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">HBaseRpcController.</span><code>setDone<wbr>(org.apache.hadoop.hbase.ExtendedCellScanner cellScanner)</code></div>
+<div class="col-last odd-row-color">
<div class="block"><b>IMPORTANT:</b> always call this method if the call finished without any exception to tell
the <code>HBaseRpcController</code> that we are done.</div>
</div>
-<div class="col-first odd-row-color"><code>void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">HBaseRpcControllerImpl.</span><code>setDone<wbr>(org.apache.hadoop.hbase.ExtendedCellScanner cellScanner)</code></div>
-<div class="col-last odd-row-color"> </div>
<div class="col-first even-row-color"><code>void</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">RpcCall.</span><code>setResponse<wbr>(org.apache.hbase.thirdparty.com.google.protobuf.Message param,
+<div class="col-second even-row-color"><span class="type-name-label">HBaseRpcControllerImpl.</span><code>setDone<wbr>(org.apache.hadoop.hbase.ExtendedCellScanner cellScanner)</code></div>
+<div class="col-last even-row-color"> </div>
+<div class="col-first odd-row-color"><code>void</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">RpcCall.</span><code>setResponse<wbr>(org.apache.hbase.thirdparty.com.google.protobuf.Message param,
org.apache.hadoop.hbase.ExtendedCellScanner cells,
<a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Throwable.html" title="class or interface in java.lang" class="external-link">Throwable</a> errorThrowable,
<a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a> error)</code></div>
-<div class="col-last even-row-color">
+<div class="col-last odd-row-color">
<div class="block">Set the response resulting from this RPC call.</div>
</div>
-<div class="col-first odd-row-color"><code>void</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">ServerCall.</span><code>setResponse<wbr>(org.apache.hbase.thirdparty.com.google.protobuf.Message m,
+<div class="col-first even-row-color"><code>void</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">ServerCall.</span><code>setResponse<wbr>(org.apache.hbase.thirdparty.com.google.protobuf.Message m,
org.apache.hadoop.hbase.ExtendedCellScanner cells,
<a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Throwable.html" title="class or interface in java.lang" class="external-link">Throwable</a> t,
<a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a> errorMsg)</code></div>
-<div class="col-last odd-row-color"> </div>
+<div class="col-last even-row-color"> </div>
</div>
<div class="caption"><span>Constructors in <a href="../ipc/package-summary.html">org.apache.hadoop.hbase.ipc</a> with parameters of type org.apache.hadoop.hbase.ExtendedCellScanner in in </span></div>
<div class="summary-table three-column-summary">
diff --git a/apidocs/org/apache/hadoop/hbase/codec/class-use/Codec.html b/apidocs/org/apache/hadoop/hbase/codec/class-use/Codec.html
index 0727ec0dee8..18a37eecd51 100644
--- a/apidocs/org/apache/hadoop/hbase/codec/class-use/Codec.html
+++ b/apidocs/org/apache/hadoop/hbase/codec/class-use/Codec.html
@@ -113,6 +113,11 @@ loadScripts(document, 'script');</script>
<div class="col-first even-row-color"><code>protected final org.apache.hadoop.hbase.codec.Codec</code></div>
<div class="col-second even-row-color"><span class="type-name-label">AbstractRpcClient.</span><code>codec</code></div>
<div class="col-last even-row-color"> </div>
+<div class="col-first odd-row-color"><code>protected org.apache.hadoop.hbase.codec.Codec</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">ServerRpcConnection.</span><code>codec</code></div>
+<div class="col-last odd-row-color">
+<div class="block">Codec the client asked use.</div>
+</div>
</div>
<div class="caption"><span>Methods in <a href="../../ipc/package-summary.html">org.apache.hadoop.hbase.ipc</a> that return org.apache.hadoop.hbase.codec.Codec in in </span></div>
<div class="summary-table three-column-summary">
diff --git a/apidocs/org/apache/hadoop/hbase/ipc/class-use/RpcServer.CallCleanup.html b/apidocs/org/apache/hadoop/hbase/ipc/class-use/RpcServer.CallCleanup.html
index b8a159236b6..c7c11c0b978 100644
--- a/apidocs/org/apache/hadoop/hbase/ipc/class-use/RpcServer.CallCleanup.html
+++ b/apidocs/org/apache/hadoop/hbase/ipc/class-use/RpcServer.CallCleanup.html
@@ -71,7 +71,28 @@ loadScripts(document, 'script');</script>
<div class="table-header col-second">Field</div>
<div class="table-header col-last">Description</div>
<div class="col-first even-row-color"><code>protected org.apache.hadoop.hbase.ipc.RpcServer.CallCleanup</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">ServerCall.</span><code>reqCleanup</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">ServerRpcConnection.</span><code>callCleanup</code></div>
+<div class="col-last even-row-color"> </div>
+<div class="col-first odd-row-color"><code>protected org.apache.hadoop.hbase.ipc.RpcServer.CallCleanup</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">ServerCall.</span><code>reqCleanup</code></div>
+<div class="col-last odd-row-color"> </div>
+</div>
+<div class="caption"><span>Methods in <a href="../package-summary.html">org.apache.hadoop.hbase.ipc</a> with parameters of type org.apache.hadoop.hbase.ipc.RpcServer.CallCleanup in in </span></div>
+<div class="summary-table three-column-summary">
+<div class="table-header col-first">Modifier and Type</div>
+<div class="table-header col-second">Method</div>
+<div class="table-header col-last">Description</div>
+<div class="col-first even-row-color"><code>abstract org.apache.hadoop.hbase.ipc.ServerCall<?></code></div>
+<div class="col-second even-row-color"><span class="type-name-label">ServerRpcConnection.</span><code>createCall<wbr>(int id,
+ org.apache.hbase.thirdparty.com.google.protobuf.BlockingService service,
+ org.apache.hbase.thirdparty.com.google.protobuf.Descriptors.MethodDescriptor md,
+ org.apache.hadoop.hbase.shaded.protobuf.generated.RPCProtos.RequestHeader header,
+ org.apache.hbase.thirdparty.com.google.protobuf.Message param,
+ org.apache.hadoop.hbase.ExtendedCellScanner cellScanner,
+ long size,
+ <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/net/InetAddress.html" title="class or interface in java.net" class="external-link">InetAddress</a> remoteAddress,
+ int timeout,
+ org.apache.hadoop.hbase.ipc.RpcServer.CallCleanup reqCleanup)</code></div>
<div class="col-last even-row-color"> </div>
</div>
</section>
diff --git a/apidocs/org/apache/hadoop/hbase/ipc/class-use/RpcServer.html b/apidocs/org/apache/hadoop/hbase/ipc/class-use/RpcServer.html
index b8c6a4768d5..9c1fb2cdb35 100644
--- a/apidocs/org/apache/hadoop/hbase/ipc/class-use/RpcServer.html
+++ b/apidocs/org/apache/hadoop/hbase/ipc/class-use/RpcServer.html
@@ -99,6 +99,15 @@ loadScripts(document, 'script');</script>
</div>
</div>
</div>
+<div class="caption"><span>Fields in <a href="../package-summary.html">org.apache.hadoop.hbase.ipc</a> declared as org.apache.hadoop.hbase.ipc.RpcServer in in </span></div>
+<div class="summary-table three-column-summary">
+<div class="table-header col-first">Modifier and Type</div>
+<div class="table-header col-second">Field</div>
+<div class="table-header col-last">Description</div>
+<div class="col-first even-row-color"><code>protected final org.apache.hadoop.hbase.ipc.RpcServer</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">ServerRpcConnection.</span><code>rpcServer</code></div>
+<div class="col-last even-row-color"> </div>
+</div>
<div class="caption"><span>Methods in <a href="../package-summary.html">org.apache.hadoop.hbase.ipc</a> that return org.apache.hadoop.hbase.ipc.RpcServer in in </span></div>
<div class="summary-table three-column-summary">
<div class="table-header col-first">Modifier and Type</div>
@@ -122,6 +131,15 @@ loadScripts(document, 'script');</script>
boolean reservoirEnabled)</code></div>
<div class="col-last odd-row-color"> </div>
</div>
+<div class="caption"><span>Constructors in <a href="../package-summary.html">org.apache.hadoop.hbase.ipc</a> with parameters of type org.apache.hadoop.hbase.ipc.RpcServer in in </span></div>
+<div class="summary-table three-column-summary">
+<div class="table-header col-first">Modifier</div>
+<div class="table-header col-second">Constructor</div>
+<div class="table-header col-last">Description</div>
+<div class="col-first even-row-color"><code> </code></div>
+<div class="col-second even-row-color"><code>ServerRpcConnection<wbr>(org.apache.hadoop.hbase.ipc.RpcServer rpcServer)</code></div>
+<div class="col-last even-row-color"> </div>
+</div>
</section>
</li>
</ul>
diff --git a/apidocs/org/apache/hadoop/hbase/ipc/class-use/ServerCall.html b/apidocs/org/apache/hadoop/hbase/ipc/class-use/ServerCall.html
index 9c40e0aa68f..051c81b7775 100644
--- a/apidocs/org/apache/hadoop/hbase/ipc/class-use/ServerCall.html
+++ b/apidocs/org/apache/hadoop/hbase/ipc/class-use/ServerCall.html
@@ -67,6 +67,24 @@ loadScripts(document, 'script');</script>
<li>
<section class="detail" id="org.apache.hadoop.hbase.ipc">
<h2>Uses of org.apache.hadoop.hbase.ipc.ServerCall in <a href="../package-summary.html">org.apache.hadoop.hbase.ipc</a></h2>
+<div class="caption"><span>Methods in <a href="../package-summary.html">org.apache.hadoop.hbase.ipc</a> that return org.apache.hadoop.hbase.ipc.ServerCall in in </span></div>
+<div class="summary-table three-column-summary">
+<div class="table-header col-first">Modifier and Type</div>
+<div class="table-header col-second">Method</div>
+<div class="table-header col-last">Description</div>
+<div class="col-first even-row-color"><code>abstract org.apache.hadoop.hbase.ipc.ServerCall<?></code></div>
+<div class="col-second even-row-color"><span class="type-name-label">ServerRpcConnection.</span><code>createCall<wbr>(int id,
+ org.apache.hbase.thirdparty.com.google.protobuf.BlockingService service,
+ org.apache.hbase.thirdparty.com.google.protobuf.Descriptors.MethodDescriptor md,
+ org.apache.hadoop.hbase.shaded.protobuf.generated.RPCProtos.RequestHeader header,
+ org.apache.hbase.thirdparty.com.google.protobuf.Message param,
+ org.apache.hadoop.hbase.ExtendedCellScanner cellScanner,
+ long size,
+ <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/net/InetAddress.html" title="class or interface in java.net" class="external-link">InetAddress</a> remoteAddress,
+ int timeout,
+ org.apache.hadoop.hbase.ipc.RpcServer.CallCleanup reqCleanup)</code></div>
+<div class="col-last even-row-color"> </div>
+</div>
<div class="caption"><span>Methods in <a href="../package-summary.html">org.apache.hadoop.hbase.ipc</a> that return types with arguments of type org.apache.hadoop.hbase.ipc.ServerCall in in </span></div>
<div class="summary-table three-column-summary">
<div class="table-header col-first">Modifier and Type</div>
diff --git a/apidocs/org/apache/hadoop/hbase/security/class-use/SaslStatus.html b/apidocs/org/apache/hadoop/hbase/ipc/class-use/ServerRpcConnection.PreambleResponse.html
similarity index 65%
copy from apidocs/org/apache/hadoop/hbase/security/class-use/SaslStatus.html
copy to apidocs/org/apache/hadoop/hbase/ipc/class-use/ServerRpcConnection.PreambleResponse.html
index 4779e416cf7..1f0e3797f3f 100644
--- a/apidocs/org/apache/hadoop/hbase/security/class-use/SaslStatus.html
+++ b/apidocs/org/apache/hadoop/hbase/ipc/class-use/ServerRpcConnection.PreambleResponse.html
@@ -2,10 +2,10 @@
<html lang="en">
<head>
<!-- Generated by javadoc (17) -->
-<title>Uses of Enum Class org.apache.hadoop.hbase.security.SaslStatus (Apache HBase 4.0.0-alpha-1-SNAPSHOT API)</title>
+<title>Uses of Enum Class org.apache.hadoop.hbase.ipc.ServerRpcConnection.PreambleResponse (Apache HBase 4.0.0-alpha-1-SNAPSHOT API)</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
-<meta name="description" content="use: package: org.apache.hadoop.hbase.security, enum: SaslStatus">
+<meta name="description" content="use: package: org.apache.hadoop.hbase.ipc, class: ServerRpcConnection, enum: PreambleResponse">
<meta name="generator" content="javadoc/ClassUseWriter">
<link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style">
<link rel="stylesheet" type="text/css" href="../../../../../../script-dir/jquery-ui.min.css" title="Style">
@@ -49,31 +49,36 @@ loadScripts(document, 'script');</script>
<div class="flex-content">
<main role="main">
<div class="header">
-<h1 title="Uses of Enum Class org.apache.hadoop.hbase.security.SaslStatus" class="title">Uses of Enum Class<br>org.apache.hadoop.hbase.security.SaslStatus</h1>
+<h1 title="Uses of Enum Class org.apache.hadoop.hbase.ipc.ServerRpcConnection.PreambleResponse" class="title">Uses of Enum Class<br>org.apache.hadoop.hbase.ipc.ServerRpcConnection.PreambleResponse</h1>
</div>
-<div class="caption"><span>Packages that use org.apache.hadoop.hbase.security.SaslStatus</span></div>
+<div class="caption"><span>Packages that use org.apache.hadoop.hbase.ipc.ServerRpcConnection.PreambleResponse</span></div>
<div class="summary-table two-column-summary">
<div class="table-header col-first">Package</div>
<div class="table-header col-last">Description</div>
-<div class="col-first even-row-color"><a href="#org.apache.hadoop.hbase.security">org.apache.hadoop.hbase.security</a></div>
-<div class="col-last even-row-color"> </div>
+<div class="col-first even-row-color"><a href="#org.apache.hadoop.hbase.ipc">org.apache.hadoop.hbase.ipc</a></div>
+<div class="col-last even-row-color">
+<div class="block">Tools to help define network clients and servers.</div>
+</div>
</div>
<section class="class-uses">
<ul class="block-list">
<li>
-<section class="detail" id="org.apache.hadoop.hbase.security">
-<h2>Uses of org.apache.hadoop.hbase.security.SaslStatus in <a href="../package-summary.html">org.apache.hadoop.hbase.security</a></h2>
-<div class="caption"><span>Methods in <a href="../package-summary.html">org.apache.hadoop.hbase.security</a> that return org.apache.hadoop.hbase.security.SaslStatus in in </span></div>
+<section class="detail" id="org.apache.hadoop.hbase.ipc">
+<h2>Uses of org.apache.hadoop.hbase.ipc.ServerRpcConnection.PreambleResponse in <a href="../package-summary.html">org.apache.hadoop.hbase.ipc</a></h2>
+<div class="caption"><span>Methods in <a href="../package-summary.html">org.apache.hadoop.hbase.ipc</a> that return org.apache.hadoop.hbase.ipc.ServerRpcConnection.PreambleResponse in in </span></div>
<div class="summary-table three-column-summary">
<div class="table-header col-first">Modifier and Type</div>
<div class="table-header col-second">Method</div>
<div class="table-header col-last">Description</div>
-<div class="col-first even-row-color"><code>static org.apache.hadoop.hbase.security.SaslStatus</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">SaslStatus.</span><code>valueOf<wbr>(<a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a> name)</code></div>
+<div class="col-first even-row-color"><code>protected final org.apache.hadoop.hbase.ipc.ServerRpcConnection.PreambleResponse</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">ServerRpcConnection.</span><code>processPreamble<wbr>(<a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/nio/ByteBuffer.html" title="class or interface in java.nio" class="external-link">ByteBuffer</a> preambleBuffer)</code></div>
<div class="col-last even-row-color"> </div>
-<div class="col-first odd-row-color"><code>static org.apache.hadoop.hbase.security.SaslStatus[]</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">SaslStatus.</span><code>values()</code></div>
+<div class="col-first odd-row-color"><code>static org.apache.hadoop.hbase.ipc.ServerRpcConnection.PreambleResponse</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">ServerRpcConnection.PreambleResponse.</span><code>valueOf<wbr>(<a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a> name)</code></div>
<div class="col-last odd-row-color"> </div>
+<div class="col-first even-row-color"><code>static org.apache.hadoop.hbase.ipc.ServerRpcConnection.PreambleResponse[]</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">ServerRpcConnection.PreambleResponse.</span><code>values()</code></div>
+<div class="col-last even-row-color"> </div>
</div>
</section>
</li>
diff --git a/apidocs/org/apache/hadoop/hbase/ipc/class-use/ServerCall.html b/apidocs/org/apache/hadoop/hbase/ipc/class-use/ServerRpcConnection.html
similarity index 67%
copy from apidocs/org/apache/hadoop/hbase/ipc/class-use/ServerCall.html
copy to apidocs/org/apache/hadoop/hbase/ipc/class-use/ServerRpcConnection.html
index 9c40e0aa68f..5233941c537 100644
--- a/apidocs/org/apache/hadoop/hbase/ipc/class-use/ServerCall.html
+++ b/apidocs/org/apache/hadoop/hbase/ipc/class-use/ServerRpcConnection.html
@@ -2,10 +2,10 @@
<html lang="en">
<head>
<!-- Generated by javadoc (17) -->
-<title>Uses of Class org.apache.hadoop.hbase.ipc.ServerCall (Apache HBase 4.0.0-alpha-1-SNAPSHOT API)</title>
+<title>Uses of Class org.apache.hadoop.hbase.ipc.ServerRpcConnection (Apache HBase 4.0.0-alpha-1-SNAPSHOT API)</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
-<meta name="description" content="use: package: org.apache.hadoop.hbase.ipc, class: ServerCall">
+<meta name="description" content="use: package: org.apache.hadoop.hbase.ipc, class: ServerRpcConnection">
<meta name="generator" content="javadoc/ClassUseWriter">
<link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style">
<link rel="stylesheet" type="text/css" href="../../../../../../script-dir/jquery-ui.min.css" title="Style">
@@ -49,9 +49,9 @@ loadScripts(document, 'script');</script>
<div class="flex-content">
<main role="main">
<div class="header">
-<h1 title="Uses of Class org.apache.hadoop.hbase.ipc.ServerCall" class="title">Uses of Class<br>org.apache.hadoop.hbase.ipc.ServerCall</h1>
+<h1 title="Uses of Class org.apache.hadoop.hbase.ipc.ServerRpcConnection" class="title">Uses of Class<br>org.apache.hadoop.hbase.ipc.ServerRpcConnection</h1>
</div>
-<div class="caption"><span>Packages that use org.apache.hadoop.hbase.ipc.ServerCall</span></div>
+<div class="caption"><span>Packages that use org.apache.hadoop.hbase.ipc.ServerRpcConnection</span></div>
<div class="summary-table two-column-summary">
<div class="table-header col-first">Package</div>
<div class="table-header col-last">Description</div>
@@ -59,42 +59,43 @@ loadScripts(document, 'script');</script>
<div class="col-last even-row-color">
<div class="block">Tools to help define network clients and servers.</div>
</div>
-<div class="col-first odd-row-color"><a href="#org.apache.hadoop.hbase.regionserver.regionreplication">org.apache.hadoop.hbase.regionserver.regionreplication</a></div>
-<div class="col-last odd-row-color"> </div>
</div>
<section class="class-uses">
<ul class="block-list">
<li>
<section class="detail" id="org.apache.hadoop.hbase.ipc">
-<h2>Uses of org.apache.hadoop.hbase.ipc.ServerCall in <a href="../package-summary.html">org.apache.hadoop.hbase.ipc</a></h2>
-<div class="caption"><span>Methods in <a href="../package-summary.html">org.apache.hadoop.hbase.ipc</a> that return types with arguments of type org.apache.hadoop.hbase.ipc.ServerCall in in </span></div>
+<h2>Uses of org.apache.hadoop.hbase.ipc.ServerRpcConnection in <a href="../package-summary.html">org.apache.hadoop.hbase.ipc</a></h2>
+<div class="caption"><span>Classes in <a href="../package-summary.html">org.apache.hadoop.hbase.ipc</a> with type parameters of type org.apache.hadoop.hbase.ipc.ServerRpcConnection in in </span></div>
<div class="summary-table three-column-summary">
<div class="table-header col-first">Modifier and Type</div>
-<div class="table-header col-second">Method</div>
+<div class="table-header col-second">Class</div>
<div class="table-header col-last">Description</div>
-<div class="col-first even-row-color"><code>static <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Optional.html" title="class or interface in java.util" class="external-link">Optional</a><org.apache.hadoop.hbase.ipc.ServerCall<?>></code></div>
-<div class="col-second even-row-color"><span class="type-name-label">RpcServer.</span><code>getCurrentServerCallWithCellScanner()</code></div>
+<div class="col-first even-row-color"><code>class </code></div>
+<div class="col-second even-row-color"><code>org.apache.hadoop.hbase.ipc.ServerCall<T extends org.apache.hadoop.hbase.ipc.ServerRpcConnection></code></div>
<div class="col-last even-row-color">
-<div class="block">Just return the current rpc call if it is a <code>ServerCall</code> and also has <code>CellScanner</code>
- attached.</div>
+<div class="block">Datastructure that holds all necessary to a method invocation and then afterward, carries the
+ result.</div>
</div>
</div>
-</section>
-</li>
-<li>
-<section class="detail" id="org.apache.hadoop.hbase.regionserver.regionreplication">
-<h2>Uses of org.apache.hadoop.hbase.ipc.ServerCall in <a href="../../regionserver/regionreplication/package-summary.html">org.apache.hadoop.hbase.regionserver.regionreplication</a></h2>
-<div class="caption"><span>Methods in <a href="../../regionserver/regionreplication/package-summary.html">org.apache.hadoop.hbase.regionserver.regionreplication</a> with parameters of type org.apache.hadoop.hbase.ipc.ServerCall in in </span></div>
+<div class="caption"><span>Fields in <a href="../package-summary.html">org.apache.hadoop.hbase.ipc</a> declared as org.apache.hadoop.hbase.ipc.ServerRpcConnection in in </span></div>
+<div class="summary-table three-column-summary">
+<div class="table-header col-first">Modifier and Type</div>
+<div class="table-header col-second">Field</div>
+<div class="table-header col-last">Description</div>
+<div class="col-first even-row-color"><code>protected final T</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">ServerCall.</span><code>connection</code></div>
+<div class="col-last even-row-color"> </div>
+</div>
+<div class="caption"><span>Methods in <a href="../package-summary.html">org.apache.hadoop.hbase.ipc</a> that return types with arguments of type org.apache.hadoop.hbase.ipc.ServerRpcConnection in in </span></div>
<div class="summary-table three-column-summary">
<div class="table-header col-first">Modifier and Type</div>
<div class="table-header col-second">Method</div>
<div class="table-header col-last">Description</div>
-<div class="col-first even-row-color"><code>void</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">RegionReplicationSink.</span><code>add<wbr>(org.apache.hadoop.hbase.wal.WALKeyImpl key,
- org.apache.hadoop.hbase.wal.WALEdit edit,
- org.apache.hadoop.hbase.ipc.ServerCall<?> rpcCall)</code></div>
+<div class="col-first even-row-color"><code>static <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Optional.html" title="class or interface in java.util" class="external-link">Optional</a><org.apache.hadoop.hbase.ipc.ServerRpcConnection></code></div>
+<div class="col-second even-row-color"><span class="type-name-label">RpcServer.</span><code>getCurrentServerRpcConnection()</code></div>
<div class="col-last even-row-color">
-<div class="block">Add this edit to replication queue.</div>
+<div class="block">Returns the ServerRpcConnection for the current RPC request or not present if no connection is
+ available.</div>
</div>
</div>
</section>
diff --git a/apidocs/org/apache/hadoop/hbase/ipc/package-summary.html b/apidocs/org/apache/hadoop/hbase/ipc/package-summary.html
index 217901eac57..a07724c96c2 100644
--- a/apidocs/org/apache/hadoop/hbase/ipc/package-summary.html
+++ b/apidocs/org/apache/hadoop/hbase/ipc/package-summary.html
@@ -84,7 +84,7 @@ This is the hadoop copied local so can fix bugs and make hbase-specific optimiza
</li>
<li>
<div id="class-summary">
-<div class="table-tabs" role="tablist" aria-orientation="horizontal"><button id="class-summary-tab0" role="tab" aria-selected="true" aria-controls="class-summary.tabpanel" tabindex="0" onkeydown="switchTab(event)" onclick="show('class-summary', 'class-summary', 2)" class="active-table-tab">All Classes and Interfaces</button><button id="class-summary-tab1" role="tab" aria-selected="false" aria-controls="class-summary.tabpanel" tabindex="-1" onkeydown="switchTab(event)" onclick="show('clas [...]
+<div class="table-tabs" role="tablist" aria-orientation="horizontal"><button id="class-summary-tab0" role="tab" aria-selected="true" aria-controls="class-summary.tabpanel" tabindex="0" onkeydown="switchTab(event)" onclick="show('class-summary', 'class-summary', 2)" class="active-table-tab">All Classes and Interfaces</button><button id="class-summary-tab1" role="tab" aria-selected="false" aria-controls="class-summary.tabpanel" tabindex="-1" onkeydown="switchTab(event)" onclick="show('clas [...]
<div id="class-summary.tabpanel" role="tabpanel">
<div class="summary-table two-column-summary" aria-labelledby="class-summary-tab0">
<div class="table-header col-first">Class</div>
@@ -378,6 +378,12 @@ This is the hadoop copied local so can fix bugs and make hbase-specific optimiza
</div>
<div class="col-first odd-row-color class-summary class-summary-tab5">org.apache.hadoop.hbase.ipc.ServerNotRunningYetException</div>
<div class="col-last odd-row-color class-summary class-summary-tab5"> </div>
+<div class="col-first even-row-color class-summary class-summary-tab2">org.apache.hadoop.hbase.ipc.ServerRpcConnection</div>
+<div class="col-last even-row-color class-summary class-summary-tab2">
+<div class="block">Reads calls from a connection and queues them for handling.</div>
+</div>
+<div class="col-first odd-row-color class-summary class-summary-tab3">org.apache.hadoop.hbase.ipc.ServerRpcConnection.PreambleResponse</div>
+<div class="col-last odd-row-color class-summary class-summary-tab3"> </div>
<div class="col-first even-row-color class-summary class-summary-tab2">org.apache.hadoop.hbase.ipc.ServerRpcController</div>
<div class="col-last even-row-color class-summary class-summary-tab2">
<div class="block">Used for server-side protobuf RPC service invocations.</div>
diff --git a/apidocs/org/apache/hadoop/hbase/ipc/package-tree.html b/apidocs/org/apache/hadoop/hbase/ipc/package-tree.html
index 2fe25122157..e97a21fda2c 100644
--- a/apidocs/org/apache/hadoop/hbase/ipc/package-tree.html
+++ b/apidocs/org/apache/hadoop/hbase/ipc/package-tree.html
@@ -159,6 +159,7 @@ loadScripts(document, 'script');</script>
<li class="circle">org.apache.hadoop.hbase.ipc.RpcServer.BlockingServiceAndInterface</li>
<li class="circle">org.apache.hadoop.hbase.ipc.RpcServerFactory</li>
<li class="circle">org.apache.hadoop.hbase.ipc.ServerCall<T> (implements org.apache.hadoop.hbase.ipc.RpcCall)</li>
+<li class="circle">org.apache.hadoop.hbase.ipc.ServerRpcConnection (implements java.io.<a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/io/Closeable.html" title="class or interface in java.io" class="external-link">Closeable</a>)</li>
<li class="circle">org.apache.hadoop.hbase.ipc.ServerRpcController (implements org.apache.hbase.thirdparty.com.google.protobuf.RpcController)</li>
<li class="circle">java.lang.<a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Thread.html" class="type-name-link external-link" title="class or interface in java.lang">Thread</a> (implements java.lang.<a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Runnable.html" title="class or interface in java.lang" class="external-link">Runnable</a>)
<ul>
@@ -291,6 +292,20 @@ loadScripts(document, 'script');</script>
<li class="circle">org.apache.hadoop.hbase.ipc.QosPriority (implements java.lang.annotation.<a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/annotation/Annotation.html" title="class or interface in java.lang.annotation" class="external-link">Annotation</a>)</li>
</ul>
</section>
+<section class="hierarchy">
+<h2 title="Enum Class Hierarchy">Enum Class Hierarchy</h2>
+<ul>
+<li class="circle">java.lang.<a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Object.html" class="type-name-link external-link" title="class or interface in java.lang">Object</a>
+<ul>
+<li class="circle">java.lang.<a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Enum.html" class="type-name-link external-link" title="class or interface in java.lang">Enum</a><E> (implements java.lang.<a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Comparable.html" title="class or interface in java.lang" class="external-link">Comparable</a><T>, java.lang.constant.<a href="https://docs.oracle.com/en/java/javase/17/d [...]
+<ul>
+<li class="circle">org.apache.hadoop.hbase.ipc.ServerRpcConnection.PreambleResponse</li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+</section>
</main>
<footer role="contentinfo">
<hr>
diff --git a/apidocs/org/apache/hadoop/hbase/ipc/package-use.html b/apidocs/org/apache/hadoop/hbase/ipc/package-use.html
index 4beb2f7e75a..684926c8f53 100644
--- a/apidocs/org/apache/hadoop/hbase/ipc/package-use.html
+++ b/apidocs/org/apache/hadoop/hbase/ipc/package-use.html
@@ -265,6 +265,12 @@ loadScripts(document, 'script');</script>
<div class="block">Datastructure that holds all necessary to a method invocation and then afterward, carries the
result.</div>
</div>
+<div class="col-first odd-row-color"><a href="class-use/ServerRpcConnection.html#org.apache.hadoop.hbase.ipc">ServerRpcConnection</a></div>
+<div class="col-last odd-row-color">
+<div class="block">Reads calls from a connection and queues them for handling.</div>
+</div>
+<div class="col-first even-row-color"><a href="class-use/ServerRpcConnection.PreambleResponse.html#org.apache.hadoop.hbase.ipc">ServerRpcConnection.PreambleResponse</a></div>
+<div class="col-last even-row-color"> </div>
</div>
</section>
</li>
diff --git a/apidocs/org/apache/hadoop/hbase/nio/class-use/ByteBuff.html b/apidocs/org/apache/hadoop/hbase/nio/class-use/ByteBuff.html
index 771d46cb3e3..76682d0d262 100644
--- a/apidocs/org/apache/hadoop/hbase/nio/class-use/ByteBuff.html
+++ b/apidocs/org/apache/hadoop/hbase/nio/class-use/ByteBuff.html
@@ -70,12 +70,16 @@ loadScripts(document, 'script');</script>
</div>
<div class="col-first odd-row-color"><a href="#org.apache.hadoop.hbase.io.util">org.apache.hadoop.hbase.io.util</a></div>
<div class="col-last odd-row-color"> </div>
-<div class="col-first even-row-color"><a href="#org.apache.hadoop.hbase.nio">org.apache.hadoop.hbase.nio</a></div>
-<div class="col-last even-row-color"> </div>
-<div class="col-first odd-row-color"><a href="#org.apache.hadoop.hbase.regionserver.wal">org.apache.hadoop.hbase.regionserver.wal</a></div>
+<div class="col-first even-row-color"><a href="#org.apache.hadoop.hbase.ipc">org.apache.hadoop.hbase.ipc</a></div>
+<div class="col-last even-row-color">
+<div class="block">Tools to help define network clients and servers.</div>
+</div>
+<div class="col-first odd-row-color"><a href="#org.apache.hadoop.hbase.nio">org.apache.hadoop.hbase.nio</a></div>
<div class="col-last odd-row-color"> </div>
-<div class="col-first even-row-color"><a href="#org.apache.hadoop.hbase.util">org.apache.hadoop.hbase.util</a></div>
+<div class="col-first even-row-color"><a href="#org.apache.hadoop.hbase.regionserver.wal">org.apache.hadoop.hbase.regionserver.wal</a></div>
<div class="col-last even-row-color"> </div>
+<div class="col-first odd-row-color"><a href="#org.apache.hadoop.hbase.util">org.apache.hadoop.hbase.util</a></div>
+<div class="col-last odd-row-color"> </div>
</div>
<section class="class-uses">
<ul class="block-list">
@@ -403,6 +407,26 @@ loadScripts(document, 'script');</script>
</section>
</li>
<li>
+<section class="detail" id="org.apache.hadoop.hbase.ipc">
+<h2>Uses of org.apache.hadoop.hbase.nio.ByteBuff in <a href="../../ipc/package-summary.html">org.apache.hadoop.hbase.ipc</a></h2>
+<div class="caption"><span>Methods in <a href="../../ipc/package-summary.html">org.apache.hadoop.hbase.ipc</a> with parameters of type org.apache.hadoop.hbase.nio.ByteBuff in in </span></div>
+<div class="summary-table three-column-summary">
+<div class="table-header col-first">Modifier and Type</div>
+<div class="table-header col-second">Method</div>
+<div class="table-header col-last">Description</div>
+<div class="col-first even-row-color"><code>void</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">ServerRpcConnection.</span><code>processOneRpc<wbr>(org.apache.hadoop.hbase.nio.ByteBuff buf)</code></div>
+<div class="col-last even-row-color"> </div>
+<div class="col-first odd-row-color"><code>protected void</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">ServerRpcConnection.</span><code>processRequest<wbr>(org.apache.hadoop.hbase.nio.ByteBuff buf)</code></div>
+<div class="col-last odd-row-color">
+<div class="block">Has the request header and the request param and optionally encoded data buffer all in this one
+ array.</div>
+</div>
+</div>
+</section>
+</li>
+<li>
<section class="detail" id="org.apache.hadoop.hbase.nio">
<h2>Uses of org.apache.hadoop.hbase.nio.ByteBuff in <a href="../package-summary.html">org.apache.hadoop.hbase.nio</a></h2>
<div class="caption"><span>Subclasses of org.apache.hadoop.hbase.nio.ByteBuff in in <a href="../package-summary.html">org.apache.hadoop.hbase.nio</a></span></div>
diff --git a/apidocs/org/apache/hadoop/hbase/nio/package-use.html b/apidocs/org/apache/hadoop/hbase/nio/package-use.html
index 39f053d2c64..eb62a6f282a 100644
--- a/apidocs/org/apache/hadoop/hbase/nio/package-use.html
+++ b/apidocs/org/apache/hadoop/hbase/nio/package-use.html
@@ -70,12 +70,16 @@ loadScripts(document, 'script');</script>
</div>
<div class="col-first odd-row-color"><a href="#org.apache.hadoop.hbase.io.util">org.apache.hadoop.hbase.io.util</a></div>
<div class="col-last odd-row-color"> </div>
-<div class="col-first even-row-color"><a href="#org.apache.hadoop.hbase.nio">org.apache.hadoop.hbase.nio</a></div>
-<div class="col-last even-row-color"> </div>
-<div class="col-first odd-row-color"><a href="#org.apache.hadoop.hbase.regionserver.wal">org.apache.hadoop.hbase.regionserver.wal</a></div>
+<div class="col-first even-row-color"><a href="#org.apache.hadoop.hbase.ipc">org.apache.hadoop.hbase.ipc</a></div>
+<div class="col-last even-row-color">
+<div class="block">Tools to help define network clients and servers.</div>
+</div>
+<div class="col-first odd-row-color"><a href="#org.apache.hadoop.hbase.nio">org.apache.hadoop.hbase.nio</a></div>
<div class="col-last odd-row-color"> </div>
-<div class="col-first even-row-color"><a href="#org.apache.hadoop.hbase.util">org.apache.hadoop.hbase.util</a></div>
+<div class="col-first even-row-color"><a href="#org.apache.hadoop.hbase.regionserver.wal">org.apache.hadoop.hbase.regionserver.wal</a></div>
<div class="col-last even-row-color"> </div>
+<div class="col-first odd-row-color"><a href="#org.apache.hadoop.hbase.util">org.apache.hadoop.hbase.util</a></div>
+<div class="col-last odd-row-color"> </div>
</div>
<section class="package-uses">
<ul class="block-list">
@@ -173,6 +177,20 @@ loadScripts(document, 'script');</script>
</section>
</li>
<li>
+<section class="detail" id="org.apache.hadoop.hbase.ipc">
+<div class="caption"><span>Classes in <a href="package-summary.html">org.apache.hadoop.hbase.nio</a> used by <a href="../ipc/package-summary.html">org.apache.hadoop.hbase.ipc</a></span></div>
+<div class="summary-table two-column-summary">
+<div class="table-header col-first">Class</div>
+<div class="table-header col-last">Description</div>
+<div class="col-first even-row-color"><a href="class-use/ByteBuff.html#org.apache.hadoop.hbase.ipc">ByteBuff</a></div>
+<div class="col-last even-row-color">
+<div class="block">An abstract class that abstracts out as to how the byte buffers are used, either single or
+ multiple.</div>
+</div>
+</div>
+</section>
+</li>
+<li>
<section class="detail" id="org.apache.hadoop.hbase.nio">
<div class="caption"><span>Classes in <a href="package-summary.html">org.apache.hadoop.hbase.nio</a> used by <a href="package-summary.html">org.apache.hadoop.hbase.nio</a></span></div>
<div class="summary-table two-column-summary">
diff --git a/apidocs/org/apache/hadoop/hbase/regionserver/class-use/MetricsUserSource.ClientMetrics.html b/apidocs/org/apache/hadoop/hbase/regionserver/class-use/MetricsUserSource.ClientMetrics.html
index c45da0daf63..64a9d25160e 100644
--- a/apidocs/org/apache/hadoop/hbase/regionserver/class-use/MetricsUserSource.ClientMetrics.html
+++ b/apidocs/org/apache/hadoop/hbase/regionserver/class-use/MetricsUserSource.ClientMetrics.html
@@ -69,12 +69,20 @@ loadScripts(document, 'script');</script>
<div class="table-header col-second">Method</div>
<div class="table-header col-last">Description</div>
<div class="col-first even-row-color"><code>org.apache.hadoop.hbase.regionserver.MetricsUserSource.ClientMetrics</code></div>
-<div class="col-second even-row-color"><span class="type-name-label">MetricsUserSource.</span><code>getOrCreateMetricsClient<wbr>(<a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a> hostName)</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">MetricsUserSource.</span><code>getOrCreateMetricsClient<wbr>(<a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a> hostName,
+ <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a> hostAddress,
+ <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a> userName,
+ <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a> clientVersion,
+ <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a> serviceName)</code></div>
<div class="col-last even-row-color">
<div class="block">Create a instance of ClientMetrics if not present otherwise return the previous one</div>
</div>
<div class="col-first odd-row-color"><code>org.apache.hadoop.hbase.regionserver.MetricsUserSource.ClientMetrics</code></div>
-<div class="col-second odd-row-color"><span class="type-name-label">MetricsUserSourceImpl.</span><code>getOrCreateMetricsClient<wbr>(<a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a> client)</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">MetricsUserSourceImpl.</span><code>getOrCreateMetricsClient<wbr>(<a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a> client,
+ <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a> hostAddress,
+ <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a> userName,
+ <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a> clientVersion,
+ <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a> serviceName)</code></div>
<div class="col-last odd-row-color"> </div>
</div>
<div class="caption"><span>Methods in <a href="../package-summary.html">org.apache.hadoop.hbase.regionserver</a> that return types with arguments of type org.apache.hadoop.hbase.regionserver.MetricsUserSource.ClientMetrics in in </span></div>
diff --git a/apidocs/org/apache/hadoop/hbase/security/class-use/HBaseSaslRpcServer.html b/apidocs/org/apache/hadoop/hbase/security/class-use/HBaseSaslRpcServer.html
index 41f667e236c..cc838cdc98a 100644
--- a/apidocs/org/apache/hadoop/hbase/security/class-use/HBaseSaslRpcServer.html
+++ b/apidocs/org/apache/hadoop/hbase/security/class-use/HBaseSaslRpcServer.html
@@ -51,7 +51,34 @@ loadScripts(document, 'script');</script>
<div class="header">
<h1 title="Uses of Class org.apache.hadoop.hbase.security.HBaseSaslRpcServer" class="title">Uses of Class<br>org.apache.hadoop.hbase.security.HBaseSaslRpcServer</h1>
</div>
-No usage of org.apache.hadoop.hbase.security.HBaseSaslRpcServer</main>
+<div class="caption"><span>Packages that use org.apache.hadoop.hbase.security.HBaseSaslRpcServer</span></div>
+<div class="summary-table two-column-summary">
+<div class="table-header col-first">Package</div>
+<div class="table-header col-last">Description</div>
+<div class="col-first even-row-color"><a href="#org.apache.hadoop.hbase.ipc">org.apache.hadoop.hbase.ipc</a></div>
+<div class="col-last even-row-color">
+<div class="block">Tools to help define network clients and servers.</div>
+</div>
+</div>
+<section class="class-uses">
+<ul class="block-list">
+<li>
+<section class="detail" id="org.apache.hadoop.hbase.ipc">
+<h2>Uses of org.apache.hadoop.hbase.security.HBaseSaslRpcServer in <a href="../../ipc/package-summary.html">org.apache.hadoop.hbase.ipc</a></h2>
+<div class="caption"><span>Fields in <a href="../../ipc/package-summary.html">org.apache.hadoop.hbase.ipc</a> declared as org.apache.hadoop.hbase.security.HBaseSaslRpcServer in in </span></div>
+<div class="summary-table three-column-summary">
+<div class="table-header col-first">Modifier and Type</div>
+<div class="table-header col-second">Field</div>
+<div class="table-header col-last">Description</div>
+<div class="col-first even-row-color"><code>protected org.apache.hadoop.hbase.security.HBaseSaslRpcServer</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">ServerRpcConnection.</span><code>saslServer</code></div>
+<div class="col-last even-row-color"> </div>
+</div>
+</section>
+</li>
+</ul>
+</section>
+</main>
<footer role="contentinfo">
<hr>
<p class="legal-copy"><small>Copyright © 2007–2020 <a href="https://www.apache.org/">The Apache Software Foundation</a>. All rights reserved.</small></p>
diff --git a/apidocs/org/apache/hadoop/hbase/security/class-use/SaslStatus.html b/apidocs/org/apache/hadoop/hbase/security/class-use/SaslStatus.html
index 4779e416cf7..e7f0f839969 100644
--- a/apidocs/org/apache/hadoop/hbase/security/class-use/SaslStatus.html
+++ b/apidocs/org/apache/hadoop/hbase/security/class-use/SaslStatus.html
@@ -55,12 +55,35 @@ loadScripts(document, 'script');</script>
<div class="summary-table two-column-summary">
<div class="table-header col-first">Package</div>
<div class="table-header col-last">Description</div>
-<div class="col-first even-row-color"><a href="#org.apache.hadoop.hbase.security">org.apache.hadoop.hbase.security</a></div>
-<div class="col-last even-row-color"> </div>
+<div class="col-first even-row-color"><a href="#org.apache.hadoop.hbase.ipc">org.apache.hadoop.hbase.ipc</a></div>
+<div class="col-last even-row-color">
+<div class="block">Tools to help define network clients and servers.</div>
+</div>
+<div class="col-first odd-row-color"><a href="#org.apache.hadoop.hbase.security">org.apache.hadoop.hbase.security</a></div>
+<div class="col-last odd-row-color"> </div>
</div>
<section class="class-uses">
<ul class="block-list">
<li>
+<section class="detail" id="org.apache.hadoop.hbase.ipc">
+<h2>Uses of org.apache.hadoop.hbase.security.SaslStatus in <a href="../../ipc/package-summary.html">org.apache.hadoop.hbase.ipc</a></h2>
+<div class="caption"><span>Methods in <a href="../../ipc/package-summary.html">org.apache.hadoop.hbase.ipc</a> with parameters of type org.apache.hadoop.hbase.security.SaslStatus in in </span></div>
+<div class="summary-table three-column-summary">
+<div class="table-header col-first">Modifier and Type</div>
+<div class="table-header col-second">Method</div>
+<div class="table-header col-last">Description</div>
+<div class="col-first even-row-color"><code>protected final void</code></div>
+<div class="col-second even-row-color"><span class="type-name-label">ServerRpcConnection.</span><code>doRawSaslReply<wbr>(org.apache.hadoop.hbase.security.SaslStatus status,
+ org.apache.hadoop.io.Writable rv,
+ <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a> errorClass,
+ <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a> error)</code></div>
+<div class="col-last even-row-color">
+<div class="block">No protobuf encoding of raw sasl messages</div>
+</div>
+</div>
+</section>
+</li>
+<li>
<section class="detail" id="org.apache.hadoop.hbase.security">
<h2>Uses of org.apache.hadoop.hbase.security.SaslStatus in <a href="../package-summary.html">org.apache.hadoop.hbase.security</a></h2>
<div class="caption"><span>Methods in <a href="../package-summary.html">org.apache.hadoop.hbase.security</a> that return org.apache.hadoop.hbase.security.SaslStatus in in </span></div>
diff --git a/apidocs/org/apache/hadoop/hbase/security/class-use/User.html b/apidocs/org/apache/hadoop/hbase/security/class-use/User.html
index b4d552a33f2..fc282bb8901 100644
--- a/apidocs/org/apache/hadoop/hbase/security/class-use/User.html
+++ b/apidocs/org/apache/hadoop/hbase/security/class-use/User.html
@@ -386,6 +386,9 @@ loadScripts(document, 'script');</script>
<div class="col-first even-row-color"><code>protected final org.apache.hadoop.hbase.security.User</code></div>
<div class="col-second even-row-color"><span class="type-name-label">ServerCall.</span><code>user</code></div>
<div class="col-last even-row-color"> </div>
+<div class="col-first odd-row-color"><code>protected org.apache.hadoop.hbase.security.User</code></div>
+<div class="col-second odd-row-color"><span class="type-name-label">ServerRpcConnection.</span><code>user</code></div>
+<div class="col-last odd-row-color"> </div>
</div>
<div class="caption"><span>Methods in <a href="../../ipc/package-summary.html">org.apache.hadoop.hbase.ipc</a> that return types with arguments of type org.apache.hadoop.hbase.security.User in in </span></div>
<div class="summary-table three-column-summary">
diff --git a/apidocs/org/apache/hadoop/hbase/security/package-use.html b/apidocs/org/apache/hadoop/hbase/security/package-use.html
index 6a133d883fa..c5de1f8ba32 100644
--- a/apidocs/org/apache/hadoop/hbase/security/package-use.html
+++ b/apidocs/org/apache/hadoop/hbase/security/package-use.html
@@ -142,6 +142,12 @@ service.</div>
<div class="summary-table two-column-summary">
<div class="table-header col-first">Class</div>
<div class="table-header col-last">Description</div>
+<div class="col-first even-row-color"><a href="class-use/HBaseSaslRpcServer.html#org.apache.hadoop.hbase.ipc">HBaseSaslRpcServer</a></div>
+<div class="col-last even-row-color">
+<div class="block">A utility class that encapsulates SASL logic for RPC server.</div>
+</div>
+<div class="col-first odd-row-color"><a href="class-use/SaslStatus.html#org.apache.hadoop.hbase.ipc">SaslStatus</a></div>
+<div class="col-last odd-row-color"> </div>
<div class="col-first even-row-color"><a href="class-use/User.html#org.apache.hadoop.hbase.ipc">User</a></div>
<div class="col-last even-row-color">
<div class="block">Wrapper to abstract out usage of user and group information in HBase.</div>
diff --git a/apidocs/overview-tree.html b/apidocs/overview-tree.html
index 99456612ad6..5173c825e41 100644
--- a/apidocs/overview-tree.html
+++ b/apidocs/overview-tree.html
@@ -2214,6 +2214,7 @@ loadScripts(document, 'script');</script>
<li class="circle">org.apache.hadoop.hbase.ServerMetricsBuilder</li>
<li class="circle">org.apache.hadoop.hbase.ServerName (implements java.lang.<a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Comparable.html" title="class or interface in java.lang" class="external-link">Comparable</a><T>, java.io.<a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/io/Serializable.html" title="class or interface in java.io" class="external-link">Serializable</a>)</li>
<li class="circle">org.apache.hadoop.hbase.regionserver.ServerNonceManager</li>
+<li class="circle">org.apache.hadoop.hbase.ipc.ServerRpcConnection (implements java.io.<a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/io/Closeable.html" title="class or interface in java.io" class="external-link">Closeable</a>)</li>
<li class="circle">org.apache.hadoop.hbase.ipc.ServerRpcController (implements org.apache.hbase.thirdparty.com.google.protobuf.RpcController)</li>
<li class="circle">org.apache.hadoop.hbase.client.backoff.ServerStatistics</li>
<li class="circle">org.apache.hadoop.hbase.client.backoff.ServerStatistics.RegionStatistics</li>
@@ -3636,6 +3637,7 @@ loadScripts(document, 'script');</script>
<li class="circle">org.apache.hadoop.hbase.regionserver.ScanType</li>
<li class="circle">org.apache.hadoop.hbase.client.security.SecurityCapability</li>
<li class="circle">org.apache.hadoop.hbase.master.ServerManager.ServerLiveState</li>
+<li class="circle">org.apache.hadoop.hbase.ipc.ServerRpcConnection.PreambleResponse</li>
<li class="circle">org.apache.hadoop.hbase.ServerTask.State</li>
<li class="circle">org.apache.hadoop.hbase.client.ServerType</li>
<li class="circle">org.apache.hadoop.hbase.Size.Unit</li>
diff --git a/apidocs/src-html/org/apache/hadoop/hbase/UserMetrics.ClientMetrics.html b/apidocs/src-html/org/apache/hadoop/hbase/UserMetrics.ClientMetrics.html
index ed1ef6640b0..b25b281fcd0 100644
--- a/apidocs/src-html/org/apache/hadoop/hbase/UserMetrics.ClientMetrics.html
+++ b/apidocs/src-html/org/apache/hadoop/hbase/UserMetrics.ClientMetrics.html
@@ -51,36 +51,44 @@
<span class="source-line-no">038</span><span id="line-38"> long getWriteRequestsCount();</span>
<span class="source-line-no">039</span><span id="line-39"></span>
<span class="source-line-no">040</span><span id="line-40"> long getFilteredReadRequestsCount();</span>
-<span class="source-line-no">041</span><span id="line-41"> }</span>
-<span class="source-line-no">042</span><span id="line-42"></span>
-<span class="source-line-no">043</span><span id="line-43"> /** Returns the user name */</span>
-<span class="source-line-no">044</span><span id="line-44"> byte[] getUserName();</span>
+<span class="source-line-no">041</span><span id="line-41"></span>
+<span class="source-line-no">042</span><span id="line-42"> String getHostAddress();</span>
+<span class="source-line-no">043</span><span id="line-43"></span>
+<span class="source-line-no">044</span><span id="line-44"> String getUserName();</span>
<span class="source-line-no">045</span><span id="line-45"></span>
-<span class="source-line-no">046</span><span id="line-46"> /** Returns the number of read requests made by user */</span>
-<span class="source-line-no">047</span><span id="line-47"> long getReadRequestCount();</span>
-<span class="source-line-no">048</span><span id="line-48"></span>
-<span class="source-line-no">049</span><span id="line-49"> /** Returns the number of write requests made by user */</span>
-<span class="source-line-no">050</span><span id="line-50"> long getWriteRequestCount();</span>
-<span class="source-line-no">051</span><span id="line-51"></span>
-<span class="source-line-no">052</span><span id="line-52"> /**</span>
-<span class="source-line-no">053</span><span id="line-53"> * Returns the number of write requests and read requests and coprocessor service requests made by</span>
-<span class="source-line-no">054</span><span id="line-54"> * the user</span>
-<span class="source-line-no">055</span><span id="line-55"> */</span>
-<span class="source-line-no">056</span><span id="line-56"> default long getRequestCount() {</span>
-<span class="source-line-no">057</span><span id="line-57"> return getReadRequestCount() + getWriteRequestCount();</span>
-<span class="source-line-no">058</span><span id="line-58"> }</span>
+<span class="source-line-no">046</span><span id="line-46"> String getClientVersion();</span>
+<span class="source-line-no">047</span><span id="line-47"></span>
+<span class="source-line-no">048</span><span id="line-48"> String getServiceName();</span>
+<span class="source-line-no">049</span><span id="line-49"> }</span>
+<span class="source-line-no">050</span><span id="line-50"></span>
+<span class="source-line-no">051</span><span id="line-51"> /** Returns the user name */</span>
+<span class="source-line-no">052</span><span id="line-52"> byte[] getUserName();</span>
+<span class="source-line-no">053</span><span id="line-53"></span>
+<span class="source-line-no">054</span><span id="line-54"> /** Returns the number of read requests made by user */</span>
+<span class="source-line-no">055</span><span id="line-55"> long getReadRequestCount();</span>
+<span class="source-line-no">056</span><span id="line-56"></span>
+<span class="source-line-no">057</span><span id="line-57"> /** Returns the number of write requests made by user */</span>
+<span class="source-line-no">058</span><span id="line-58"> long getWriteRequestCount();</span>
<span class="source-line-no">059</span><span id="line-59"></span>
-<span class="source-line-no">060</span><span id="line-60"> /** Returns the user name as a string */</span>
-<span class="source-line-no">061</span><span id="line-61"> default String getNameAsString() {</span>
-<span class="source-line-no">062</span><span id="line-62"> return Bytes.toStringBinary(getUserName());</span>
-<span class="source-line-no">063</span><span id="line-63"> }</span>
-<span class="source-line-no">064</span><span id="line-64"></span>
-<span class="source-line-no">065</span><span id="line-65"> /** Returns metrics per client(hostname) */</span>
-<span class="source-line-no">066</span><span id="line-66"> Map<String, ClientMetrics> getClientMetrics();</span>
+<span class="source-line-no">060</span><span id="line-60"> /**</span>
+<span class="source-line-no">061</span><span id="line-61"> * Returns the number of write requests and read requests and coprocessor service requests made by</span>
+<span class="source-line-no">062</span><span id="line-62"> * the user</span>
+<span class="source-line-no">063</span><span id="line-63"> */</span>
+<span class="source-line-no">064</span><span id="line-64"> default long getRequestCount() {</span>
+<span class="source-line-no">065</span><span id="line-65"> return getReadRequestCount() + getWriteRequestCount();</span>
+<span class="source-line-no">066</span><span id="line-66"> }</span>
<span class="source-line-no">067</span><span id="line-67"></span>
-<span class="source-line-no">068</span><span id="line-68"> /** Returns count of filtered read requests for a user */</span>
-<span class="source-line-no">069</span><span id="line-69"> long getFilteredReadRequests();</span>
-<span class="source-line-no">070</span><span id="line-70">}</span>
+<span class="source-line-no">068</span><span id="line-68"> /** Returns the user name as a string */</span>
+<span class="source-line-no">069</span><span id="line-69"> default String getNameAsString() {</span>
+<span class="source-line-no">070</span><span id="line-70"> return Bytes.toStringBinary(getUserName());</span>
+<span class="source-line-no">071</span><span id="line-71"> }</span>
+<span class="source-line-no">072</span><span id="line-72"></span>
+<span class="source-line-no">073</span><span id="line-73"> /** Returns metrics per client(hostname) */</span>
+<span class="source-line-no">074</span><span id="line-74"> Map<String, ClientMetrics> getClientMetrics();</span>
+<span class="source-line-no">075</span><span id="line-75"></span>
+<span class="source-line-no">076</span><span id="line-76"> /** Returns count of filtered read requests for a user */</span>
+<span class="source-line-no">077</span><span id="line-77"> long getFilteredReadRequests();</span>
+<span class="source-line-no">078</span><span id="line-78">}</span>
diff --git a/apidocs/src-html/org/apache/hadoop/hbase/UserMetrics.html b/apidocs/src-html/org/apache/hadoop/hbase/UserMetrics.html
index 9ce68d58f4b..073d3c1754b 100644
--- a/apidocs/src-html/org/apache/hadoop/hbase/UserMetrics.html
+++ b/apidocs/src-html/org/apache/hadoop/hbase/UserMetrics.html
@@ -51,36 +51,44 @@
<span class="source-line-no">038</span><span id="line-38"> long getWriteRequestsCount();</span>
<span class="source-line-no">039</span><span id="line-39"></span>
<span class="source-line-no">040</span><span id="line-40"> long getFilteredReadRequestsCount();</span>
-<span class="source-line-no">041</span><span id="line-41"> }</span>
-<span class="source-line-no">042</span><span id="line-42"></span>
-<span class="source-line-no">043</span><span id="line-43"> /** Returns the user name */</span>
-<span class="source-line-no">044</span><span id="line-44"> byte[] getUserName();</span>
+<span class="source-line-no">041</span><span id="line-41"></span>
+<span class="source-line-no">042</span><span id="line-42"> String getHostAddress();</span>
+<span class="source-line-no">043</span><span id="line-43"></span>
+<span class="source-line-no">044</span><span id="line-44"> String getUserName();</span>
<span class="source-line-no">045</span><span id="line-45"></span>
-<span class="source-line-no">046</span><span id="line-46"> /** Returns the number of read requests made by user */</span>
-<span class="source-line-no">047</span><span id="line-47"> long getReadRequestCount();</span>
-<span class="source-line-no">048</span><span id="line-48"></span>
-<span class="source-line-no">049</span><span id="line-49"> /** Returns the number of write requests made by user */</span>
-<span class="source-line-no">050</span><span id="line-50"> long getWriteRequestCount();</span>
-<span class="source-line-no">051</span><span id="line-51"></span>
-<span class="source-line-no">052</span><span id="line-52"> /**</span>
-<span class="source-line-no">053</span><span id="line-53"> * Returns the number of write requests and read requests and coprocessor service requests made by</span>
-<span class="source-line-no">054</span><span id="line-54"> * the user</span>
-<span class="source-line-no">055</span><span id="line-55"> */</span>
-<span class="source-line-no">056</span><span id="line-56"> default long getRequestCount() {</span>
-<span class="source-line-no">057</span><span id="line-57"> return getReadRequestCount() + getWriteRequestCount();</span>
-<span class="source-line-no">058</span><span id="line-58"> }</span>
+<span class="source-line-no">046</span><span id="line-46"> String getClientVersion();</span>
+<span class="source-line-no">047</span><span id="line-47"></span>
+<span class="source-line-no">048</span><span id="line-48"> String getServiceName();</span>
+<span class="source-line-no">049</span><span id="line-49"> }</span>
+<span class="source-line-no">050</span><span id="line-50"></span>
+<span class="source-line-no">051</span><span id="line-51"> /** Returns the user name */</span>
+<span class="source-line-no">052</span><span id="line-52"> byte[] getUserName();</span>
+<span class="source-line-no">053</span><span id="line-53"></span>
+<span class="source-line-no">054</span><span id="line-54"> /** Returns the number of read requests made by user */</span>
+<span class="source-line-no">055</span><span id="line-55"> long getReadRequestCount();</span>
+<span class="source-line-no">056</span><span id="line-56"></span>
+<span class="source-line-no">057</span><span id="line-57"> /** Returns the number of write requests made by user */</span>
+<span class="source-line-no">058</span><span id="line-58"> long getWriteRequestCount();</span>
<span class="source-line-no">059</span><span id="line-59"></span>
-<span class="source-line-no">060</span><span id="line-60"> /** Returns the user name as a string */</span>
-<span class="source-line-no">061</span><span id="line-61"> default String getNameAsString() {</span>
-<span class="source-line-no">062</span><span id="line-62"> return Bytes.toStringBinary(getUserName());</span>
-<span class="source-line-no">063</span><span id="line-63"> }</span>
-<span class="source-line-no">064</span><span id="line-64"></span>
-<span class="source-line-no">065</span><span id="line-65"> /** Returns metrics per client(hostname) */</span>
-<span class="source-line-no">066</span><span id="line-66"> Map<String, ClientMetrics> getClientMetrics();</span>
+<span class="source-line-no">060</span><span id="line-60"> /**</span>
+<span class="source-line-no">061</span><span id="line-61"> * Returns the number of write requests and read requests and coprocessor service requests made by</span>
+<span class="source-line-no">062</span><span id="line-62"> * the user</span>
+<span class="source-line-no">063</span><span id="line-63"> */</span>
+<span class="source-line-no">064</span><span id="line-64"> default long getRequestCount() {</span>
+<span class="source-line-no">065</span><span id="line-65"> return getReadRequestCount() + getWriteRequestCount();</span>
+<span class="source-line-no">066</span><span id="line-66"> }</span>
<span class="source-line-no">067</span><span id="line-67"></span>
-<span class="source-line-no">068</span><span id="line-68"> /** Returns count of filtered read requests for a user */</span>
-<span class="source-line-no">069</span><span id="line-69"> long getFilteredReadRequests();</span>
-<span class="source-line-no">070</span><span id="line-70">}</span>
+<span class="source-line-no">068</span><span id="line-68"> /** Returns the user name as a string */</span>
+<span class="source-line-no">069</span><span id="line-69"> default String getNameAsString() {</span>
+<span class="source-line-no">070</span><span id="line-70"> return Bytes.toStringBinary(getUserName());</span>
+<span class="source-line-no">071</span><span id="line-71"> }</span>
+<span class="source-line-no">072</span><span id="line-72"></span>
+<span class="source-line-no">073</span><span id="line-73"> /** Returns metrics per client(hostname) */</span>
+<span class="source-line-no">074</span><span id="line-74"> Map<String, ClientMetrics> getClientMetrics();</span>
+<span class="source-line-no">075</span><span id="line-75"></span>
+<span class="source-line-no">076</span><span id="line-76"> /** Returns count of filtered read requests for a user */</span>
+<span class="source-line-no">077</span><span id="line-77"> long getFilteredReadRequests();</span>
+<span class="source-line-no">078</span><span id="line-78">}</span>
diff --git a/apidocs/src-html/org/apache/hadoop/hbase/UserMetricsBuilder.ClientMetricsImpl.html b/apidocs/src-html/org/apache/hadoop/hbase/UserMetricsBuilder.ClientMetricsImpl.html
index b59fada355a..b1e06be87d8 100644
--- a/apidocs/src-html/org/apache/hadoop/hbase/UserMetricsBuilder.ClientMetricsImpl.html
+++ b/apidocs/src-html/org/apache/hadoop/hbase/UserMetricsBuilder.ClientMetricsImpl.html
@@ -49,127 +49,161 @@
<span class="source-line-no">036</span><span id="line-36"> userLoad.getClientMetricsList().stream()</span>
<span class="source-line-no">037</span><span id="line-37"> .map(clientMetrics -> new ClientMetricsImpl(clientMetrics.getHostName(),</span>
<span class="source-line-no">038</span><span id="line-38"> clientMetrics.getReadRequestsCount(), clientMetrics.getWriteRequestsCount(),</span>
-<span class="source-line-no">039</span><span id="line-39"> clientMetrics.getFilteredRequestsCount()))</span>
-<span class="source-line-no">040</span><span id="line-40"> .forEach(builder::addClientMetris);</span>
-<span class="source-line-no">041</span><span id="line-41"> return builder.build();</span>
-<span class="source-line-no">042</span><span id="line-42"> }</span>
-<span class="source-line-no">043</span><span id="line-43"></span>
-<span class="source-line-no">044</span><span id="line-44"> public static ClusterStatusProtos.UserLoad toUserMetrics(UserMetrics userMetrics) {</span>
-<span class="source-line-no">045</span><span id="line-45"> ClusterStatusProtos.UserLoad.Builder builder =</span>
-<span class="source-line-no">046</span><span id="line-46"> ClusterStatusProtos.UserLoad.newBuilder().setUserName(userMetrics.getNameAsString());</span>
-<span class="source-line-no">047</span><span id="line-47"> userMetrics.getClientMetrics().values().stream()</span>
-<span class="source-line-no">048</span><span id="line-48"> .map(clientMetrics -> ClusterStatusProtos.ClientMetrics.newBuilder()</span>
-<span class="source-line-no">049</span><span id="line-49"> .setHostName(clientMetrics.getHostName())</span>
-<span class="source-line-no">050</span><span id="line-50"> .setWriteRequestsCount(clientMetrics.getWriteRequestsCount())</span>
-<span class="source-line-no">051</span><span id="line-51"> .setReadRequestsCount(clientMetrics.getReadRequestsCount())</span>
-<span class="source-line-no">052</span><span id="line-52"> .setFilteredRequestsCount(clientMetrics.getFilteredReadRequestsCount()).build())</span>
-<span class="source-line-no">053</span><span id="line-53"> .forEach(builder::addClientMetrics);</span>
-<span class="source-line-no">054</span><span id="line-54"> return builder.build();</span>
-<span class="source-line-no">055</span><span id="line-55"> }</span>
-<span class="source-line-no">056</span><span id="line-56"></span>
-<span class="source-line-no">057</span><span id="line-57"> public static UserMetricsBuilder newBuilder(byte[] name) {</span>
-<span class="source-line-no">058</span><span id="line-58"> return new UserMetricsBuilder(name);</span>
-<span class="source-line-no">059</span><span id="line-59"> }</span>
-<span class="source-line-no">060</span><span id="line-60"></span>
-<span class="source-line-no">061</span><span id="line-61"> private final byte[] name;</span>
-<span class="source-line-no">062</span><span id="line-62"> private Map<String, UserMetrics.ClientMetrics> clientMetricsMap = new HashMap<>();</span>
-<span class="source-line-no">063</span><span id="line-63"></span>
-<span class="source-line-no">064</span><span id="line-64"> private UserMetricsBuilder(byte[] name) {</span>
-<span class="source-line-no">065</span><span id="line-65"> this.name = name;</span>
-<span class="source-line-no">066</span><span id="line-66"> }</span>
-<span class="source-line-no">067</span><span id="line-67"></span>
-<span class="source-line-no">068</span><span id="line-68"> public UserMetricsBuilder addClientMetris(UserMetrics.ClientMetrics clientMetrics) {</span>
-<span class="source-line-no">069</span><span id="line-69"> clientMetricsMap.put(clientMetrics.getHostName(), clientMetrics);</span>
-<span class="source-line-no">070</span><span id="line-70"> return this;</span>
+<span class="source-line-no">039</span><span id="line-39"> clientMetrics.getFilteredRequestsCount(), clientMetrics.getHostAddress(),</span>
+<span class="source-line-no">040</span><span id="line-40"> clientMetrics.getUserName(), clientMetrics.getServiceName(),</span>
+<span class="source-line-no">041</span><span id="line-41"> clientMetrics.getClientVersion()))</span>
+<span class="source-line-no">042</span><span id="line-42"> .forEach(builder::addClientMetris);</span>
+<span class="source-line-no">043</span><span id="line-43"> return builder.build();</span>
+<span class="source-line-no">044</span><span id="line-44"> }</span>
+<span class="source-line-no">045</span><span id="line-45"></span>
+<span class="source-line-no">046</span><span id="line-46"> public static ClusterStatusProtos.UserLoad toUserMetrics(UserMetrics userMetrics) {</span>
+<span class="source-line-no">047</span><span id="line-47"> ClusterStatusProtos.UserLoad.Builder builder =</span>
+<span class="source-line-no">048</span><span id="line-48"> ClusterStatusProtos.UserLoad.newBuilder().setUserName(userMetrics.getNameAsString());</span>
+<span class="source-line-no">049</span><span id="line-49"> userMetrics.getClientMetrics().values().stream()</span>
+<span class="source-line-no">050</span><span id="line-50"> .map(clientMetrics -> ClusterStatusProtos.ClientMetrics.newBuilder()</span>
+<span class="source-line-no">051</span><span id="line-51"> .setHostName(clientMetrics.getHostName())</span>
+<span class="source-line-no">052</span><span id="line-52"> .setWriteRequestsCount(clientMetrics.getWriteRequestsCount())</span>
+<span class="source-line-no">053</span><span id="line-53"> .setReadRequestsCount(clientMetrics.getReadRequestsCount())</span>
+<span class="source-line-no">054</span><span id="line-54"> .setFilteredRequestsCount(clientMetrics.getFilteredReadRequestsCount())</span>
+<span class="source-line-no">055</span><span id="line-55"> .setHostAddress(clientMetrics.getHostAddress()).setUserName(clientMetrics.getUserName())</span>
+<span class="source-line-no">056</span><span id="line-56"> .setServiceName(clientMetrics.getServiceName())</span>
+<span class="source-line-no">057</span><span id="line-57"> .setClientVersion(clientMetrics.getClientVersion()).build())</span>
+<span class="source-line-no">058</span><span id="line-58"> .forEach(builder::addClientMetrics);</span>
+<span class="source-line-no">059</span><span id="line-59"> return builder.build();</span>
+<span class="source-line-no">060</span><span id="line-60"> }</span>
+<span class="source-line-no">061</span><span id="line-61"></span>
+<span class="source-line-no">062</span><span id="line-62"> public static UserMetricsBuilder newBuilder(byte[] name) {</span>
+<span class="source-line-no">063</span><span id="line-63"> return new UserMetricsBuilder(name);</span>
+<span class="source-line-no">064</span><span id="line-64"> }</span>
+<span class="source-line-no">065</span><span id="line-65"></span>
+<span class="source-line-no">066</span><span id="line-66"> private final byte[] name;</span>
+<span class="source-line-no">067</span><span id="line-67"> private Map<String, UserMetrics.ClientMetrics> clientMetricsMap = new HashMap<>();</span>
+<span class="source-line-no">068</span><span id="line-68"></span>
+<span class="source-line-no">069</span><span id="line-69"> private UserMetricsBuilder(byte[] name) {</span>
+<span class="source-line-no">070</span><span id="line-70"> this.name = name;</span>
<span class="source-line-no">071</span><span id="line-71"> }</span>
<span class="source-line-no">072</span><span id="line-72"></span>
-<span class="source-line-no">073</span><span id="line-73"> public UserMetrics build() {</span>
-<span class="source-line-no">074</span><span id="line-74"> return new UserMetricsImpl(name, clientMetricsMap);</span>
-<span class="source-line-no">075</span><span id="line-75"> }</span>
-<span class="source-line-no">076</span><span id="line-76"></span>
-<span class="source-line-no">077</span><span id="line-77"> public static class ClientMetricsImpl implements UserMetrics.ClientMetrics {</span>
-<span class="source-line-no">078</span><span id="line-78"> private final long filteredReadRequestsCount;</span>
-<span class="source-line-no">079</span><span id="line-79"> private final String hostName;</span>
-<span class="source-line-no">080</span><span id="line-80"> private final long readRequestCount;</span>
-<span class="source-line-no">081</span><span id="line-81"> private final long writeRequestCount;</span>
-<span class="source-line-no">082</span><span id="line-82"></span>
-<span class="source-line-no">083</span><span id="line-83"> public ClientMetricsImpl(String hostName, long readRequest, long writeRequest,</span>
-<span class="source-line-no">084</span><span id="line-84"> long filteredReadRequestsCount) {</span>
-<span class="source-line-no">085</span><span id="line-85"> this.hostName = hostName;</span>
-<span class="source-line-no">086</span><span id="line-86"> this.readRequestCount = readRequest;</span>
-<span class="source-line-no">087</span><span id="line-87"> this.writeRequestCount = writeRequest;</span>
-<span class="source-line-no">088</span><span id="line-88"> this.filteredReadRequestsCount = filteredReadRequestsCount;</span>
-<span class="source-line-no">089</span><span id="line-89"> }</span>
-<span class="source-line-no">090</span><span id="line-90"></span>
-<span class="source-line-no">091</span><span id="line-91"> @Override</span>
-<span class="source-line-no">092</span><span id="line-92"> public String getHostName() {</span>
-<span class="source-line-no">093</span><span id="line-93"> return hostName;</span>
-<span class="source-line-no">094</span><span id="line-94"> }</span>
-<span class="source-line-no">095</span><span id="line-95"></span>
-<span class="source-line-no">096</span><span id="line-96"> @Override</span>
-<span class="source-line-no">097</span><span id="line-97"> public long getReadRequestsCount() {</span>
-<span class="source-line-no">098</span><span id="line-98"> return readRequestCount;</span>
-<span class="source-line-no">099</span><span id="line-99"> }</span>
-<span class="source-line-no">100</span><span id="line-100"></span>
-<span class="source-line-no">101</span><span id="line-101"> @Override</span>
-<span class="source-line-no">102</span><span id="line-102"> public long getWriteRequestsCount() {</span>
-<span class="source-line-no">103</span><span id="line-103"> return writeRequestCount;</span>
-<span class="source-line-no">104</span><span id="line-104"> }</span>
-<span class="source-line-no">105</span><span id="line-105"></span>
-<span class="source-line-no">106</span><span id="line-106"> @Override</span>
-<span class="source-line-no">107</span><span id="line-107"> public long getFilteredReadRequestsCount() {</span>
-<span class="source-line-no">108</span><span id="line-108"> return filteredReadRequestsCount;</span>
-<span class="source-line-no">109</span><span id="line-109"> }</span>
-<span class="source-line-no">110</span><span id="line-110"> }</span>
-<span class="source-line-no">111</span><span id="line-111"></span>
-<span class="source-line-no">112</span><span id="line-112"> private static class UserMetricsImpl implements UserMetrics {</span>
-<span class="source-line-no">113</span><span id="line-113"> private final byte[] name;</span>
-<span class="source-line-no">114</span><span id="line-114"> private final Map<String, ClientMetrics> clientMetricsMap;</span>
-<span class="source-line-no">115</span><span id="line-115"></span>
-<span class="source-line-no">116</span><span id="line-116"> UserMetricsImpl(byte[] name, Map<String, ClientMetrics> clientMetricsMap) {</span>
-<span class="source-line-no">117</span><span id="line-117"> this.name = Preconditions.checkNotNull(name);</span>
-<span class="source-line-no">118</span><span id="line-118"> this.clientMetricsMap = clientMetricsMap;</span>
-<span class="source-line-no">119</span><span id="line-119"> }</span>
-<span class="source-line-no">120</span><span id="line-120"></span>
-<span class="source-line-no">121</span><span id="line-121"> @Override</span>
-<span class="source-line-no">122</span><span id="line-122"> public byte[] getUserName() {</span>
-<span class="source-line-no">123</span><span id="line-123"> return name;</span>
-<span class="source-line-no">124</span><span id="line-124"> }</span>
-<span class="source-line-no">125</span><span id="line-125"></span>
-<span class="source-line-no">126</span><span id="line-126"> @Override</span>
-<span class="source-line-no">127</span><span id="line-127"> public long getReadRequestCount() {</span>
-<span class="source-line-no">128</span><span id="line-128"> return clientMetricsMap.values().stream().map(c -> c.getReadRequestsCount()).reduce(0L,</span>
-<span class="source-line-no">129</span><span id="line-129"> Long::sum);</span>
-<span class="source-line-no">130</span><span id="line-130"> }</span>
-<span class="source-line-no">131</span><span id="line-131"></span>
-<span class="source-line-no">132</span><span id="line-132"> @Override</span>
-<span class="source-line-no">133</span><span id="line-133"> public long getWriteRequestCount() {</span>
-<span class="source-line-no">134</span><span id="line-134"> return clientMetricsMap.values().stream().map(c -> c.getWriteRequestsCount()).reduce(0L,</span>
-<span class="source-line-no">135</span><span id="line-135"> Long::sum);</span>
-<span class="source-line-no">136</span><span id="line-136"> }</span>
-<span class="source-line-no">137</span><span id="line-137"></span>
-<span class="source-line-no">138</span><span id="line-138"> @Override</span>
-<span class="source-line-no">139</span><span id="line-139"> public Map<String, ClientMetrics> getClientMetrics() {</span>
-<span class="source-line-no">140</span><span id="line-140"> return this.clientMetricsMap;</span>
-<span class="source-line-no">141</span><span id="line-141"> }</span>
-<span class="source-line-no">142</span><span id="line-142"></span>
-<span class="source-line-no">143</span><span id="line-143"> @Override</span>
-<span class="source-line-no">144</span><span id="line-144"> public long getFilteredReadRequests() {</span>
-<span class="source-line-no">145</span><span id="line-145"> return clientMetricsMap.values().stream().map(c -> c.getFilteredReadRequestsCount())</span>
-<span class="source-line-no">146</span><span id="line-146"> .reduce(0L, Long::sum);</span>
-<span class="source-line-no">147</span><span id="line-147"> }</span>
-<span class="source-line-no">148</span><span id="line-148"></span>
-<span class="source-line-no">149</span><span id="line-149"> @Override</span>
-<span class="source-line-no">150</span><span id="line-150"> public String toString() {</span>
-<span class="source-line-no">151</span><span id="line-151"> StringBuilder sb =</span>
-<span class="source-line-no">152</span><span id="line-152"> Strings.appendKeyValue(new StringBuilder(), "readRequestCount", this.getReadRequestCount());</span>
-<span class="source-line-no">153</span><span id="line-153"> Strings.appendKeyValue(sb, "writeRequestCount", this.getWriteRequestCount());</span>
-<span class="source-line-no">154</span><span id="line-154"> Strings.appendKeyValue(sb, "filteredReadRequestCount", this.getFilteredReadRequests());</span>
-<span class="source-line-no">155</span><span id="line-155"> return sb.toString();</span>
-<span class="source-line-no">156</span><span id="line-156"> }</span>
-<span class="source-line-no">157</span><span id="line-157"> }</span>
-<span class="source-line-no">158</span><span id="line-158"></span>
-<span class="source-line-no">159</span><span id="line-159">}</span>
+<span class="source-line-no">073</span><span id="line-73"> public UserMetricsBuilder addClientMetris(UserMetrics.ClientMetrics clientMetrics) {</span>
+<span class="source-line-no">074</span><span id="line-74"> clientMetricsMap.put(clientMetrics.getHostName(), clientMetrics);</span>
+<span class="source-line-no">075</span><span id="line-75"> return this;</span>
+<span class="source-line-no">076</span><span id="line-76"> }</span>
+<span class="source-line-no">077</span><span id="line-77"></span>
+<span class="source-line-no">078</span><span id="line-78"> public UserMetrics build() {</span>
+<span class="source-line-no">079</span><span id="line-79"> return new UserMetricsImpl(name, clientMetricsMap);</span>
+<span class="source-line-no">080</span><span id="line-80"> }</span>
+<span class="source-line-no">081</span><span id="line-81"></span>
+<span class="source-line-no">082</span><span id="line-82"> public static class ClientMetricsImpl implements UserMetrics.ClientMetrics {</span>
+<span class="source-line-no">083</span><span id="line-83"> private final long filteredReadRequestsCount;</span>
+<span class="source-line-no">084</span><span id="line-84"> private final String hostName;</span>
+<span class="source-line-no">085</span><span id="line-85"> private final long readRequestCount;</span>
+<span class="source-line-no">086</span><span id="line-86"> private final long writeRequestCount;</span>
+<span class="source-line-no">087</span><span id="line-87"> private final String hostAddress;</span>
+<span class="source-line-no">088</span><span id="line-88"> private final String userName;</span>
+<span class="source-line-no">089</span><span id="line-89"> private final String serviceName;</span>
+<span class="source-line-no">090</span><span id="line-90"> private final String clientVersion;</span>
+<span class="source-line-no">091</span><span id="line-91"></span>
+<span class="source-line-no">092</span><span id="line-92"> public ClientMetricsImpl(String hostName, long readRequest, long writeRequest,</span>
+<span class="source-line-no">093</span><span id="line-93"> long filteredReadRequestsCount, String hostAddress, String userName, String serviceName,</span>
+<span class="source-line-no">094</span><span id="line-94"> String clientVersion) {</span>
+<span class="source-line-no">095</span><span id="line-95"> this.hostName = hostName;</span>
+<span class="source-line-no">096</span><span id="line-96"> this.readRequestCount = readRequest;</span>
+<span class="source-line-no">097</span><span id="line-97"> this.writeRequestCount = writeRequest;</span>
+<span class="source-line-no">098</span><span id="line-98"> this.filteredReadRequestsCount = filteredReadRequestsCount;</span>
+<span class="source-line-no">099</span><span id="line-99"> this.hostAddress = hostAddress != null ? hostAddress : "Unknown";</span>
+<span class="source-line-no">100</span><span id="line-100"> this.userName = userName != null ? userName : "Unknown";</span>
+<span class="source-line-no">101</span><span id="line-101"> this.serviceName = serviceName != null ? serviceName : "Unknown";</span>
+<span class="source-line-no">102</span><span id="line-102"> this.clientVersion = clientVersion != null ? clientVersion : "Unknown";</span>
+<span class="source-line-no">103</span><span id="line-103"> }</span>
+<span class="source-line-no">104</span><span id="line-104"></span>
+<span class="source-line-no">105</span><span id="line-105"> @Override</span>
+<span class="source-line-no">106</span><span id="line-106"> public String getHostName() {</span>
+<span class="source-line-no">107</span><span id="line-107"> return hostName;</span>
+<span class="source-line-no">108</span><span id="line-108"> }</span>
+<span class="source-line-no">109</span><span id="line-109"></span>
+<span class="source-line-no">110</span><span id="line-110"> @Override</span>
+<span class="source-line-no">111</span><span id="line-111"> public long getReadRequestsCount() {</span>
+<span class="source-line-no">112</span><span id="line-112"> return readRequestCount;</span>
+<span class="source-line-no">113</span><span id="line-113"> }</span>
+<span class="source-line-no">114</span><span id="line-114"></span>
+<span class="source-line-no">115</span><span id="line-115"> @Override</span>
+<span class="source-line-no">116</span><span id="line-116"> public long getWriteRequestsCount() {</span>
+<span class="source-line-no">117</span><span id="line-117"> return writeRequestCount;</span>
+<span class="source-line-no">118</span><span id="line-118"> }</span>
+<span class="source-line-no">119</span><span id="line-119"></span>
+<span class="source-line-no">120</span><span id="line-120"> @Override</span>
+<span class="source-line-no">121</span><span id="line-121"> public long getFilteredReadRequestsCount() {</span>
+<span class="source-line-no">122</span><span id="line-122"> return filteredReadRequestsCount;</span>
+<span class="source-line-no">123</span><span id="line-123"> }</span>
+<span class="source-line-no">124</span><span id="line-124"></span>
+<span class="source-line-no">125</span><span id="line-125"> @Override</span>
+<span class="source-line-no">126</span><span id="line-126"> public String getHostAddress() {</span>
+<span class="source-line-no">127</span><span id="line-127"> return hostAddress;</span>
+<span class="source-line-no">128</span><span id="line-128"> }</span>
+<span class="source-line-no">129</span><span id="line-129"></span>
+<span class="source-line-no">130</span><span id="line-130"> @Override</span>
+<span class="source-line-no">131</span><span id="line-131"> public String getUserName() {</span>
+<span class="source-line-no">132</span><span id="line-132"> return userName;</span>
+<span class="source-line-no">133</span><span id="line-133"> }</span>
+<span class="source-line-no">134</span><span id="line-134"></span>
+<span class="source-line-no">135</span><span id="line-135"> @Override</span>
+<span class="source-line-no">136</span><span id="line-136"> public String getServiceName() {</span>
+<span class="source-line-no">137</span><span id="line-137"> return serviceName;</span>
+<span class="source-line-no">138</span><span id="line-138"> }</span>
+<span class="source-line-no">139</span><span id="line-139"></span>
+<span class="source-line-no">140</span><span id="line-140"> @Override</span>
+<span class="source-line-no">141</span><span id="line-141"> public String getClientVersion() {</span>
+<span class="source-line-no">142</span><span id="line-142"> return clientVersion;</span>
+<span class="source-line-no">143</span><span id="line-143"> }</span>
+<span class="source-line-no">144</span><span id="line-144"> }</span>
+<span class="source-line-no">145</span><span id="line-145"></span>
+<span class="source-line-no">146</span><span id="line-146"> private static class UserMetricsImpl implements UserMetrics {</span>
+<span class="source-line-no">147</span><span id="line-147"> private final byte[] name;</span>
+<span class="source-line-no">148</span><span id="line-148"> private final Map<String, ClientMetrics> clientMetricsMap;</span>
+<span class="source-line-no">149</span><span id="line-149"></span>
+<span class="source-line-no">150</span><span id="line-150"> UserMetricsImpl(byte[] name, Map<String, ClientMetrics> clientMetricsMap) {</span>
+<span class="source-line-no">151</span><span id="line-151"> this.name = Preconditions.checkNotNull(name);</span>
+<span class="source-line-no">152</span><span id="line-152"> this.clientMetricsMap = clientMetricsMap;</span>
+<span class="source-line-no">153</span><span id="line-153"> }</span>
+<span class="source-line-no">154</span><span id="line-154"></span>
+<span class="source-line-no">155</span><span id="line-155"> @Override</span>
+<span class="source-line-no">156</span><span id="line-156"> public byte[] getUserName() {</span>
+<span class="source-line-no">157</span><span id="line-157"> return name;</span>
+<span class="source-line-no">158</span><span id="line-158"> }</span>
+<span class="source-line-no">159</span><span id="line-159"></span>
+<span class="source-line-no">160</span><span id="line-160"> @Override</span>
+<span class="source-line-no">161</span><span id="line-161"> public long getReadRequestCount() {</span>
+<span class="source-line-no">162</span><span id="line-162"> return clientMetricsMap.values().stream().map(c -> c.getReadRequestsCount()).reduce(0L,</span>
+<span class="source-line-no">163</span><span id="line-163"> Long::sum);</span>
+<span class="source-line-no">164</span><span id="line-164"> }</span>
+<span class="source-line-no">165</span><span id="line-165"></span>
+<span class="source-line-no">166</span><span id="line-166"> @Override</span>
+<span class="source-line-no">167</span><span id="line-167"> public long getWriteRequestCount() {</span>
+<span class="source-line-no">168</span><span id="line-168"> return clientMetricsMap.values().stream().map(c -> c.getWriteRequestsCount()).reduce(0L,</span>
+<span class="source-line-no">169</span><span id="line-169"> Long::sum);</span>
+<span class="source-line-no">170</span><span id="line-170"> }</span>
+<span class="source-line-no">171</span><span id="line-171"></span>
+<span class="source-line-no">172</span><span id="line-172"> @Override</span>
+<span class="source-line-no">173</span><span id="line-173"> public Map<String, ClientMetrics> getClientMetrics() {</span>
+<span class="source-line-no">174</span><span id="line-174"> return this.clientMetricsMap;</span>
+<span class="source-line-no">175</span><span id="line-175"> }</span>
+<span class="source-line-no">176</span><span id="line-176"></span>
+<span class="source-line-no">177</span><span id="line-177"> @Override</span>
+<span class="source-line-no">178</span><span id="line-178"> public long getFilteredReadRequests() {</span>
+<span class="source-line-no">179</span><span id="line-179"> return clientMetricsMap.values().stream().map(c -> c.getFilteredReadRequestsCount())</span>
+<span class="source-line-no">180</span><span id="line-180"> .reduce(0L, Long::sum);</span>
+<span class="source-line-no">181</span><span id="line-181"> }</span>
+<span class="source-line-no">182</span><span id="line-182"></span>
+<span class="source-line-no">183</span><span id="line-183"> @Override</span>
+<span class="source-line-no">184</span><span id="line-184"> public String toString() {</span>
+<span class="source-line-no">185</span><span id="line-185"> StringBuilder sb =</span>
+<span class="source-line-no">186</span><span id="line-186"> Strings.appendKeyValue(new StringBuilder(), "readRequestCount", this.getReadRequestCount());</span>
+<span class="source-line-no">187</span><span id="line-187"> Strings.appendKeyValue(sb, "writeRequestCount", this.getWriteRequestCount());</span>
+<span class="source-line-no">188</span><span id="line-188"> Strings.appendKeyValue(sb, "filteredReadRequestCount", this.getFilteredReadRequests());</span>
+<span class="source-line-no">189</span><span id="line-189"> return sb.toString();</span>
+<span class="source-line-no">190</span><span id="line-190"> }</span>
+<span class="source-line-no">191</span><span id="line-191"> }</span>
+<span class="source-line-no">192</span><span id="line-192"></span>
+<span class="source-line-no">193</span><span id="line-193">}</span>
diff --git a/apidocs/src-html/org/apache/hadoop/hbase/UserMetricsBuilder.html b/apidocs/src-html/org/apache/hadoop/hbase/UserMetricsBuilder.html
index 3188086f344..a40dd4aea92 100644
--- a/apidocs/src-html/org/apache/hadoop/hbase/UserMetricsBuilder.html
+++ b/apidocs/src-html/org/apache/hadoop/hbase/UserMetricsBuilder.html
@@ -49,127 +49,161 @@
<span class="source-line-no">036</span><span id="line-36"> userLoad.getClientMetricsList().stream()</span>
<span class="source-line-no">037</span><span id="line-37"> .map(clientMetrics -> new ClientMetricsImpl(clientMetrics.getHostName(),</span>
<span class="source-line-no">038</span><span id="line-38"> clientMetrics.getReadRequestsCount(), clientMetrics.getWriteRequestsCount(),</span>
-<span class="source-line-no">039</span><span id="line-39"> clientMetrics.getFilteredRequestsCount()))</span>
-<span class="source-line-no">040</span><span id="line-40"> .forEach(builder::addClientMetris);</span>
-<span class="source-line-no">041</span><span id="line-41"> return builder.build();</span>
-<span class="source-line-no">042</span><span id="line-42"> }</span>
-<span class="source-line-no">043</span><span id="line-43"></span>
-<span class="source-line-no">044</span><span id="line-44"> public static ClusterStatusProtos.UserLoad toUserMetrics(UserMetrics userMetrics) {</span>
-<span class="source-line-no">045</span><span id="line-45"> ClusterStatusProtos.UserLoad.Builder builder =</span>
-<span class="source-line-no">046</span><span id="line-46"> ClusterStatusProtos.UserLoad.newBuilder().setUserName(userMetrics.getNameAsString());</span>
-<span class="source-line-no">047</span><span id="line-47"> userMetrics.getClientMetrics().values().stream()</span>
-<span class="source-line-no">048</span><span id="line-48"> .map(clientMetrics -> ClusterStatusProtos.ClientMetrics.newBuilder()</span>
-<span class="source-line-no">049</span><span id="line-49"> .setHostName(clientMetrics.getHostName())</span>
-<span class="source-line-no">050</span><span id="line-50"> .setWriteRequestsCount(clientMetrics.getWriteRequestsCount())</span>
-<span class="source-line-no">051</span><span id="line-51"> .setReadRequestsCount(clientMetrics.getReadRequestsCount())</span>
-<span class="source-line-no">052</span><span id="line-52"> .setFilteredRequestsCount(clientMetrics.getFilteredReadRequestsCount()).build())</span>
-<span class="source-line-no">053</span><span id="line-53"> .forEach(builder::addClientMetrics);</span>
-<span class="source-line-no">054</span><span id="line-54"> return builder.build();</span>
-<span class="source-line-no">055</span><span id="line-55"> }</span>
-<span class="source-line-no">056</span><span id="line-56"></span>
-<span class="source-line-no">057</span><span id="line-57"> public static UserMetricsBuilder newBuilder(byte[] name) {</span>
-<span class="source-line-no">058</span><span id="line-58"> return new UserMetricsBuilder(name);</span>
-<span class="source-line-no">059</span><span id="line-59"> }</span>
-<span class="source-line-no">060</span><span id="line-60"></span>
-<span class="source-line-no">061</span><span id="line-61"> private final byte[] name;</span>
-<span class="source-line-no">062</span><span id="line-62"> private Map<String, UserMetrics.ClientMetrics> clientMetricsMap = new HashMap<>();</span>
-<span class="source-line-no">063</span><span id="line-63"></span>
-<span class="source-line-no">064</span><span id="line-64"> private UserMetricsBuilder(byte[] name) {</span>
-<span class="source-line-no">065</span><span id="line-65"> this.name = name;</span>
-<span class="source-line-no">066</span><span id="line-66"> }</span>
-<span class="source-line-no">067</span><span id="line-67"></span>
-<span class="source-line-no">068</span><span id="line-68"> public UserMetricsBuilder addClientMetris(UserMetrics.ClientMetrics clientMetrics) {</span>
-<span class="source-line-no">069</span><span id="line-69"> clientMetricsMap.put(clientMetrics.getHostName(), clientMetrics);</span>
-<span class="source-line-no">070</span><span id="line-70"> return this;</span>
+<span class="source-line-no">039</span><span id="line-39"> clientMetrics.getFilteredRequestsCount(), clientMetrics.getHostAddress(),</span>
+<span class="source-line-no">040</span><span id="line-40"> clientMetrics.getUserName(), clientMetrics.getServiceName(),</span>
+<span class="source-line-no">041</span><span id="line-41"> clientMetrics.getClientVersion()))</span>
+<span class="source-line-no">042</span><span id="line-42"> .forEach(builder::addClientMetris);</span>
+<span class="source-line-no">043</span><span id="line-43"> return builder.build();</span>
+<span class="source-line-no">044</span><span id="line-44"> }</span>
+<span class="source-line-no">045</span><span id="line-45"></span>
+<span class="source-line-no">046</span><span id="line-46"> public static ClusterStatusProtos.UserLoad toUserMetrics(UserMetrics userMetrics) {</span>
+<span class="source-line-no">047</span><span id="line-47"> ClusterStatusProtos.UserLoad.Builder builder =</span>
+<span class="source-line-no">048</span><span id="line-48"> ClusterStatusProtos.UserLoad.newBuilder().setUserName(userMetrics.getNameAsString());</span>
+<span class="source-line-no">049</span><span id="line-49"> userMetrics.getClientMetrics().values().stream()</span>
+<span class="source-line-no">050</span><span id="line-50"> .map(clientMetrics -> ClusterStatusProtos.ClientMetrics.newBuilder()</span>
+<span class="source-line-no">051</span><span id="line-51"> .setHostName(clientMetrics.getHostName())</span>
+<span class="source-line-no">052</span><span id="line-52"> .setWriteRequestsCount(clientMetrics.getWriteRequestsCount())</span>
+<span class="source-line-no">053</span><span id="line-53"> .setReadRequestsCount(clientMetrics.getReadRequestsCount())</span>
+<span class="source-line-no">054</span><span id="line-54"> .setFilteredRequestsCount(clientMetrics.getFilteredReadRequestsCount())</span>
+<span class="source-line-no">055</span><span id="line-55"> .setHostAddress(clientMetrics.getHostAddress()).setUserName(clientMetrics.getUserName())</span>
+<span class="source-line-no">056</span><span id="line-56"> .setServiceName(clientMetrics.getServiceName())</span>
+<span class="source-line-no">057</span><span id="line-57"> .setClientVersion(clientMetrics.getClientVersion()).build())</span>
+<span class="source-line-no">058</span><span id="line-58"> .forEach(builder::addClientMetrics);</span>
+<span class="source-line-no">059</span><span id="line-59"> return builder.build();</span>
+<span class="source-line-no">060</span><span id="line-60"> }</span>
+<span class="source-line-no">061</span><span id="line-61"></span>
+<span class="source-line-no">062</span><span id="line-62"> public static UserMetricsBuilder newBuilder(byte[] name) {</span>
+<span class="source-line-no">063</span><span id="line-63"> return new UserMetricsBuilder(name);</span>
+<span class="source-line-no">064</span><span id="line-64"> }</span>
+<span class="source-line-no">065</span><span id="line-65"></span>
+<span class="source-line-no">066</span><span id="line-66"> private final byte[] name;</span>
+<span class="source-line-no">067</span><span id="line-67"> private Map<String, UserMetrics.ClientMetrics> clientMetricsMap = new HashMap<>();</span>
+<span class="source-line-no">068</span><span id="line-68"></span>
+<span class="source-line-no">069</span><span id="line-69"> private UserMetricsBuilder(byte[] name) {</span>
+<span class="source-line-no">070</span><span id="line-70"> this.name = name;</span>
<span class="source-line-no">071</span><span id="line-71"> }</span>
<span class="source-line-no">072</span><span id="line-72"></span>
-<span class="source-line-no">073</span><span id="line-73"> public UserMetrics build() {</span>
-<span class="source-line-no">074</span><span id="line-74"> return new UserMetricsImpl(name, clientMetricsMap);</span>
-<span class="source-line-no">075</span><span id="line-75"> }</span>
-<span class="source-line-no">076</span><span id="line-76"></span>
-<span class="source-line-no">077</span><span id="line-77"> public static class ClientMetricsImpl implements UserMetrics.ClientMetrics {</span>
-<span class="source-line-no">078</span><span id="line-78"> private final long filteredReadRequestsCount;</span>
-<span class="source-line-no">079</span><span id="line-79"> private final String hostName;</span>
-<span class="source-line-no">080</span><span id="line-80"> private final long readRequestCount;</span>
-<span class="source-line-no">081</span><span id="line-81"> private final long writeRequestCount;</span>
-<span class="source-line-no">082</span><span id="line-82"></span>
-<span class="source-line-no">083</span><span id="line-83"> public ClientMetricsImpl(String hostName, long readRequest, long writeRequest,</span>
-<span class="source-line-no">084</span><span id="line-84"> long filteredReadRequestsCount) {</span>
-<span class="source-line-no">085</span><span id="line-85"> this.hostName = hostName;</span>
-<span class="source-line-no">086</span><span id="line-86"> this.readRequestCount = readRequest;</span>
-<span class="source-line-no">087</span><span id="line-87"> this.writeRequestCount = writeRequest;</span>
-<span class="source-line-no">088</span><span id="line-88"> this.filteredReadRequestsCount = filteredReadRequestsCount;</span>
-<span class="source-line-no">089</span><span id="line-89"> }</span>
-<span class="source-line-no">090</span><span id="line-90"></span>
-<span class="source-line-no">091</span><span id="line-91"> @Override</span>
-<span class="source-line-no">092</span><span id="line-92"> public String getHostName() {</span>
-<span class="source-line-no">093</span><span id="line-93"> return hostName;</span>
-<span class="source-line-no">094</span><span id="line-94"> }</span>
-<span class="source-line-no">095</span><span id="line-95"></span>
-<span class="source-line-no">096</span><span id="line-96"> @Override</span>
-<span class="source-line-no">097</span><span id="line-97"> public long getReadRequestsCount() {</span>
-<span class="source-line-no">098</span><span id="line-98"> return readRequestCount;</span>
-<span class="source-line-no">099</span><span id="line-99"> }</span>
-<span class="source-line-no">100</span><span id="line-100"></span>
-<span class="source-line-no">101</span><span id="line-101"> @Override</span>
-<span class="source-line-no">102</span><span id="line-102"> public long getWriteRequestsCount() {</span>
-<span class="source-line-no">103</span><span id="line-103"> return writeRequestCount;</span>
-<span class="source-line-no">104</span><span id="line-104"> }</span>
-<span class="source-line-no">105</span><span id="line-105"></span>
-<span class="source-line-no">106</span><span id="line-106"> @Override</span>
-<span class="source-line-no">107</span><span id="line-107"> public long getFilteredReadRequestsCount() {</span>
-<span class="source-line-no">108</span><span id="line-108"> return filteredReadRequestsCount;</span>
-<span class="source-line-no">109</span><span id="line-109"> }</span>
-<span class="source-line-no">110</span><span id="line-110"> }</span>
-<span class="source-line-no">111</span><span id="line-111"></span>
-<span class="source-line-no">112</span><span id="line-112"> private static class UserMetricsImpl implements UserMetrics {</span>
-<span class="source-line-no">113</span><span id="line-113"> private final byte[] name;</span>
-<span class="source-line-no">114</span><span id="line-114"> private final Map<String, ClientMetrics> clientMetricsMap;</span>
-<span class="source-line-no">115</span><span id="line-115"></span>
-<span class="source-line-no">116</span><span id="line-116"> UserMetricsImpl(byte[] name, Map<String, ClientMetrics> clientMetricsMap) {</span>
-<span class="source-line-no">117</span><span id="line-117"> this.name = Preconditions.checkNotNull(name);</span>
-<span class="source-line-no">118</span><span id="line-118"> this.clientMetricsMap = clientMetricsMap;</span>
-<span class="source-line-no">119</span><span id="line-119"> }</span>
-<span class="source-line-no">120</span><span id="line-120"></span>
-<span class="source-line-no">121</span><span id="line-121"> @Override</span>
-<span class="source-line-no">122</span><span id="line-122"> public byte[] getUserName() {</span>
-<span class="source-line-no">123</span><span id="line-123"> return name;</span>
-<span class="source-line-no">124</span><span id="line-124"> }</span>
-<span class="source-line-no">125</span><span id="line-125"></span>
-<span class="source-line-no">126</span><span id="line-126"> @Override</span>
-<span class="source-line-no">127</span><span id="line-127"> public long getReadRequestCount() {</span>
-<span class="source-line-no">128</span><span id="line-128"> return clientMetricsMap.values().stream().map(c -> c.getReadRequestsCount()).reduce(0L,</span>
-<span class="source-line-no">129</span><span id="line-129"> Long::sum);</span>
-<span class="source-line-no">130</span><span id="line-130"> }</span>
-<span class="source-line-no">131</span><span id="line-131"></span>
-<span class="source-line-no">132</span><span id="line-132"> @Override</span>
-<span class="source-line-no">133</span><span id="line-133"> public long getWriteRequestCount() {</span>
-<span class="source-line-no">134</span><span id="line-134"> return clientMetricsMap.values().stream().map(c -> c.getWriteRequestsCount()).reduce(0L,</span>
-<span class="source-line-no">135</span><span id="line-135"> Long::sum);</span>
-<span class="source-line-no">136</span><span id="line-136"> }</span>
-<span class="source-line-no">137</span><span id="line-137"></span>
-<span class="source-line-no">138</span><span id="line-138"> @Override</span>
-<span class="source-line-no">139</span><span id="line-139"> public Map<String, ClientMetrics> getClientMetrics() {</span>
-<span class="source-line-no">140</span><span id="line-140"> return this.clientMetricsMap;</span>
-<span class="source-line-no">141</span><span id="line-141"> }</span>
-<span class="source-line-no">142</span><span id="line-142"></span>
-<span class="source-line-no">143</span><span id="line-143"> @Override</span>
-<span class="source-line-no">144</span><span id="line-144"> public long getFilteredReadRequests() {</span>
-<span class="source-line-no">145</span><span id="line-145"> return clientMetricsMap.values().stream().map(c -> c.getFilteredReadRequestsCount())</span>
-<span class="source-line-no">146</span><span id="line-146"> .reduce(0L, Long::sum);</span>
-<span class="source-line-no">147</span><span id="line-147"> }</span>
-<span class="source-line-no">148</span><span id="line-148"></span>
-<span class="source-line-no">149</span><span id="line-149"> @Override</span>
-<span class="source-line-no">150</span><span id="line-150"> public String toString() {</span>
-<span class="source-line-no">151</span><span id="line-151"> StringBuilder sb =</span>
-<span class="source-line-no">152</span><span id="line-152"> Strings.appendKeyValue(new StringBuilder(), "readRequestCount", this.getReadRequestCount());</span>
-<span class="source-line-no">153</span><span id="line-153"> Strings.appendKeyValue(sb, "writeRequestCount", this.getWriteRequestCount());</span>
-<span class="source-line-no">154</span><span id="line-154"> Strings.appendKeyValue(sb, "filteredReadRequestCount", this.getFilteredReadRequests());</span>
-<span class="source-line-no">155</span><span id="line-155"> return sb.toString();</span>
-<span class="source-line-no">156</span><span id="line-156"> }</span>
-<span class="source-line-no">157</span><span id="line-157"> }</span>
-<span class="source-line-no">158</span><span id="line-158"></span>
-<span class="source-line-no">159</span><span id="line-159">}</span>
+<span class="source-line-no">073</span><span id="line-73"> public UserMetricsBuilder addClientMetris(UserMetrics.ClientMetrics clientMetrics) {</span>
+<span class="source-line-no">074</span><span id="line-74"> clientMetricsMap.put(clientMetrics.getHostName(), clientMetrics);</span>
+<span class="source-line-no">075</span><span id="line-75"> return this;</span>
+<span class="source-line-no">076</span><span id="line-76"> }</span>
+<span class="source-line-no">077</span><span id="line-77"></span>
+<span class="source-line-no">078</span><span id="line-78"> public UserMetrics build() {</span>
+<span class="source-line-no">079</span><span id="line-79"> return new UserMetricsImpl(name, clientMetricsMap);</span>
+<span class="source-line-no">080</span><span id="line-80"> }</span>
+<span class="source-line-no">081</span><span id="line-81"></span>
+<span class="source-line-no">082</span><span id="line-82"> public static class ClientMetricsImpl implements UserMetrics.ClientMetrics {</span>
+<span class="source-line-no">083</span><span id="line-83"> private final long filteredReadRequestsCount;</span>
+<span class="source-line-no">084</span><span id="line-84"> private final String hostName;</span>
+<span class="source-line-no">085</span><span id="line-85"> private final long readRequestCount;</span>
+<span class="source-line-no">086</span><span id="line-86"> private final long writeRequestCount;</span>
+<span class="source-line-no">087</span><span id="line-87"> private final String hostAddress;</span>
+<span class="source-line-no">088</span><span id="line-88"> private final String userName;</span>
+<span class="source-line-no">089</span><span id="line-89"> private final String serviceName;</span>
+<span class="source-line-no">090</span><span id="line-90"> private final String clientVersion;</span>
+<span class="source-line-no">091</span><span id="line-91"></span>
+<span class="source-line-no">092</span><span id="line-92"> public ClientMetricsImpl(String hostName, long readRequest, long writeRequest,</span>
+<span class="source-line-no">093</span><span id="line-93"> long filteredReadRequestsCount, String hostAddress, String userName, String serviceName,</span>
+<span class="source-line-no">094</span><span id="line-94"> String clientVersion) {</span>
+<span class="source-line-no">095</span><span id="line-95"> this.hostName = hostName;</span>
+<span class="source-line-no">096</span><span id="line-96"> this.readRequestCount = readRequest;</span>
+<span class="source-line-no">097</span><span id="line-97"> this.writeRequestCount = writeRequest;</span>
+<span class="source-line-no">098</span><span id="line-98"> this.filteredReadRequestsCount = filteredReadRequestsCount;</span>
+<span class="source-line-no">099</span><span id="line-99"> this.hostAddress = hostAddress != null ? hostAddress : "Unknown";</span>
+<span class="source-line-no">100</span><span id="line-100"> this.userName = userName != null ? userName : "Unknown";</span>
+<span class="source-line-no">101</span><span id="line-101"> this.serviceName = serviceName != null ? serviceName : "Unknown";</span>
+<span class="source-line-no">102</span><span id="line-102"> this.clientVersion = clientVersion != null ? clientVersion : "Unknown";</span>
+<span class="source-line-no">103</span><span id="line-103"> }</span>
+<span class="source-line-no">104</span><span id="line-104"></span>
+<span class="source-line-no">105</span><span id="line-105"> @Override</span>
+<span class="source-line-no">106</span><span id="line-106"> public String getHostName() {</span>
+<span class="source-line-no">107</span><span id="line-107"> return hostName;</span>
+<span class="source-line-no">108</span><span id="line-108"> }</span>
+<span class="source-line-no">109</span><span id="line-109"></span>
+<span class="source-line-no">110</span><span id="line-110"> @Override</span>
+<span class="source-line-no">111</span><span id="line-111"> public long getReadRequestsCount() {</span>
+<span class="source-line-no">112</span><span id="line-112"> return readRequestCount;</span>
+<span class="source-line-no">113</span><span id="line-113"> }</span>
+<span class="source-line-no">114</span><span id="line-114"></span>
+<span class="source-line-no">115</span><span id="line-115"> @Override</span>
+<span class="source-line-no">116</span><span id="line-116"> public long getWriteRequestsCount() {</span>
+<span class="source-line-no">117</span><span id="line-117"> return writeRequestCount;</span>
+<span class="source-line-no">118</span><span id="line-118"> }</span>
+<span class="source-line-no">119</span><span id="line-119"></span>
+<span class="source-line-no">120</span><span id="line-120"> @Override</span>
+<span class="source-line-no">121</span><span id="line-121"> public long getFilteredReadRequestsCount() {</span>
+<span class="source-line-no">122</span><span id="line-122"> return filteredReadRequestsCount;</span>
+<span class="source-line-no">123</span><span id="line-123"> }</span>
+<span class="source-line-no">124</span><span id="line-124"></span>
+<span class="source-line-no">125</span><span id="line-125"> @Override</span>
+<span class="source-line-no">126</span><span id="line-126"> public String getHostAddress() {</span>
+<span class="source-line-no">127</span><span id="line-127"> return hostAddress;</span>
+<span class="source-line-no">128</span><span id="line-128"> }</span>
+<span class="source-line-no">129</span><span id="line-129"></span>
+<span class="source-line-no">130</span><span id="line-130"> @Override</span>
+<span class="source-line-no">131</span><span id="line-131"> public String getUserName() {</span>
+<span class="source-line-no">132</span><span id="line-132"> return userName;</span>
+<span class="source-line-no">133</span><span id="line-133"> }</span>
+<span class="source-line-no">134</span><span id="line-134"></span>
+<span class="source-line-no">135</span><span id="line-135"> @Override</span>
+<span class="source-line-no">136</span><span id="line-136"> public String getServiceName() {</span>
+<span class="source-line-no">137</span><span id="line-137"> return serviceName;</span>
+<span class="source-line-no">138</span><span id="line-138"> }</span>
+<span class="source-line-no">139</span><span id="line-139"></span>
+<span class="source-line-no">140</span><span id="line-140"> @Override</span>
+<span class="source-line-no">141</span><span id="line-141"> public String getClientVersion() {</span>
+<span class="source-line-no">142</span><span id="line-142"> return clientVersion;</span>
+<span class="source-line-no">143</span><span id="line-143"> }</span>
+<span class="source-line-no">144</span><span id="line-144"> }</span>
+<span class="source-line-no">145</span><span id="line-145"></span>
+<span class="source-line-no">146</span><span id="line-146"> private static class UserMetricsImpl implements UserMetrics {</span>
+<span class="source-line-no">147</span><span id="line-147"> private final byte[] name;</span>
+<span class="source-line-no">148</span><span id="line-148"> private final Map<String, ClientMetrics> clientMetricsMap;</span>
+<span class="source-line-no">149</span><span id="line-149"></span>
+<span class="source-line-no">150</span><span id="line-150"> UserMetricsImpl(byte[] name, Map<String, ClientMetrics> clientMetricsMap) {</span>
+<span class="source-line-no">151</span><span id="line-151"> this.name = Preconditions.checkNotNull(name);</span>
+<span class="source-line-no">152</span><span id="line-152"> this.clientMetricsMap = clientMetricsMap;</span>
+<span class="source-line-no">153</span><span id="line-153"> }</span>
+<span class="source-line-no">154</span><span id="line-154"></span>
+<span class="source-line-no">155</span><span id="line-155"> @Override</span>
+<span class="source-line-no">156</span><span id="line-156"> public byte[] getUserName() {</span>
+<span class="source-line-no">157</span><span id="line-157"> return name;</span>
+<span class="source-line-no">158</span><span id="line-158"> }</span>
+<span class="source-line-no">159</span><span id="line-159"></span>
+<span class="source-line-no">160</span><span id="line-160"> @Override</span>
+<span class="source-line-no">161</span><span id="line-161"> public long getReadRequestCount() {</span>
+<span class="source-line-no">162</span><span id="line-162"> return clientMetricsMap.values().stream().map(c -> c.getReadRequestsCount()).reduce(0L,</span>
+<span class="source-line-no">163</span><span id="line-163"> Long::sum);</span>
+<span class="source-line-no">164</span><span id="line-164"> }</span>
+<span class="source-line-no">165</span><span id="line-165"></span>
+<span class="source-line-no">166</span><span id="line-166"> @Override</span>
+<span class="source-line-no">167</span><span id="line-167"> public long getWriteRequestCount() {</span>
+<span class="source-line-no">168</span><span id="line-168"> return clientMetricsMap.values().stream().map(c -> c.getWriteRequestsCount()).reduce(0L,</span>
+<span class="source-line-no">169</span><span id="line-169"> Long::sum);</span>
+<span class="source-line-no">170</span><span id="line-170"> }</span>
+<span class="source-line-no">171</span><span id="line-171"></span>
+<span class="source-line-no">172</span><span id="line-172"> @Override</span>
+<span class="source-line-no">173</span><span id="line-173"> public Map<String, ClientMetrics> getClientMetrics() {</span>
+<span class="source-line-no">174</span><span id="line-174"> return this.clientMetricsMap;</span>
+<span class="source-line-no">175</span><span id="line-175"> }</span>
+<span class="source-line-no">176</span><span id="line-176"></span>
+<span class="source-line-no">177</span><span id="line-177"> @Override</span>
+<span class="source-line-no">178</span><span id="line-178"> public long getFilteredReadRequests() {</span>
+<span class="source-line-no">179</span><span id="line-179"> return clientMetricsMap.values().stream().map(c -> c.getFilteredReadRequestsCount())</span>
+<span class="source-line-no">180</span><span id="line-180"> .reduce(0L, Long::sum);</span>
+<span class="source-line-no">181</span><span id="line-181"> }</span>
+<span class="source-line-no">182</span><span id="line-182"></span>
+<span class="source-line-no">183</span><span id="line-183"> @Override</span>
+<span class="source-line-no">184</span><span id="line-184"> public String toString() {</span>
+<span class="source-line-no">185</span><span id="line-185"> StringBuilder sb =</span>
+<span class="source-line-no">186</span><span id="line-186"> Strings.appendKeyValue(new StringBuilder(), "readRequestCount", this.getReadRequestCount());</span>
+<span class="source-line-no">187</span><span id="line-187"> Strings.appendKeyValue(sb, "writeRequestCount", this.getWriteRequestCount());</span>
+<span class="source-line-no">188</span><span id="line-188"> Strings.appendKeyValue(sb, "filteredReadRequestCount", this.getFilteredReadRequests());</span>
+<span class="source-line-no">189</span><span id="line-189"> return sb.toString();</span>
+<span class="source-line-no">190</span><span id="line-190"> }</span>
+<span class="source-line-no">191</span><span id="line-191"> }</span>
+<span class="source-line-no">192</span><span id="line-192"></span>
+<span class="source-line-no">193</span><span id="line-193">}</span>
diff --git a/apidocs/src-html/org/apache/hadoop/hbase/hbtop/field/Field.html b/apidocs/src-html/org/apache/hadoop/hbase/hbtop/field/Field.html
index 3d4d2aeb3f0..b5f84327b71 100644
--- a/apidocs/src-html/org/apache/hadoop/hbase/hbtop/field/Field.html
+++ b/apidocs/src-html/org/apache/hadoop/hbase/hbtop/field/Field.html
@@ -71,47 +71,51 @@
<span class="source-line-no">058</span><span id="line-58"> MAX_HEAP_SIZE("MHEAP", "Max Heap Size", false, false, FieldValueType.SIZE),</span>
<span class="source-line-no">059</span><span id="line-59"> CLIENT_COUNT("#CLIENT", "Client Count", false, false, FieldValueType.INTEGER),</span>
<span class="source-line-no">060</span><span id="line-60"> USER_COUNT("#USER", "User Count", false, false, FieldValueType.INTEGER),</span>
-<span class="source-line-no">061</span><span id="line-61"> CLIENT("CLIENT", "Client Hostname", true, true, FieldValueType.STRING);</span>
-<span class="source-line-no">062</span><span id="line-62"></span>
-<span class="source-line-no">063</span><span id="line-63"> private final String header;</span>
-<span class="source-line-no">064</span><span id="line-64"> private final String description;</span>
-<span class="source-line-no">065</span><span id="line-65"> private final boolean autoAdjust;</span>
-<span class="source-line-no">066</span><span id="line-66"> private final boolean leftJustify;</span>
-<span class="source-line-no">067</span><span id="line-67"> private final FieldValueType fieldValueType;</span>
-<span class="source-line-no">068</span><span id="line-68"></span>
-<span class="source-line-no">069</span><span id="line-69"> Field(String header, String description, boolean autoAdjust, boolean leftJustify,</span>
-<span class="source-line-no">070</span><span id="line-70"> FieldValueType fieldValueType) {</span>
-<span class="source-line-no">071</span><span id="line-71"> this.header = Objects.requireNonNull(header);</span>
-<span class="source-line-no">072</span><span id="line-72"> this.description = Objects.requireNonNull(description);</span>
-<span class="source-line-no">073</span><span id="line-73"> this.autoAdjust = autoAdjust;</span>
-<span class="source-line-no">074</span><span id="line-74"> this.leftJustify = leftJustify;</span>
-<span class="source-line-no">075</span><span id="line-75"> this.fieldValueType = Objects.requireNonNull(fieldValueType);</span>
-<span class="source-line-no">076</span><span id="line-76"> }</span>
-<span class="source-line-no">077</span><span id="line-77"></span>
-<span class="source-line-no">078</span><span id="line-78"> public FieldValue newValue(Object value) {</span>
-<span class="source-line-no">079</span><span id="line-79"> return new FieldValue(value, fieldValueType);</span>
+<span class="source-line-no">061</span><span id="line-61"> CLIENT("CLIENT", "Client Hostname", true, true, FieldValueType.STRING),</span>
+<span class="source-line-no">062</span><span id="line-62"> HOST_ADDRESS("HADDR", "Client Host Address", true, true, FieldValueType.STRING),</span>
+<span class="source-line-no">063</span><span id="line-63"> CLIENT_VERSION("CVER", "Client Version", true, true, FieldValueType.STRING),</span>
+<span class="source-line-no">064</span><span id="line-64"> USER_NAME("USER", "User Name", true, true, FieldValueType.STRING),</span>
+<span class="source-line-no">065</span><span id="line-65"> SERVICE_NAME("SVC", "Service Name", true, true, FieldValueType.STRING);</span>
+<span class="source-line-no">066</span><span id="line-66"></span>
+<span class="source-line-no">067</span><span id="line-67"> private final String header;</span>
+<span class="source-line-no">068</span><span id="line-68"> private final String description;</span>
+<span class="source-line-no">069</span><span id="line-69"> private final boolean autoAdjust;</span>
+<span class="source-line-no">070</span><span id="line-70"> private final boolean leftJustify;</span>
+<span class="source-line-no">071</span><span id="line-71"> private final FieldValueType fieldValueType;</span>
+<span class="source-line-no">072</span><span id="line-72"></span>
+<span class="source-line-no">073</span><span id="line-73"> Field(String header, String description, boolean autoAdjust, boolean leftJustify,</span>
+<span class="source-line-no">074</span><span id="line-74"> FieldValueType fieldValueType) {</span>
+<span class="source-line-no">075</span><span id="line-75"> this.header = Objects.requireNonNull(header);</span>
+<span class="source-line-no">076</span><span id="line-76"> this.description = Objects.requireNonNull(description);</span>
+<span class="source-line-no">077</span><span id="line-77"> this.autoAdjust = autoAdjust;</span>
+<span class="source-line-no">078</span><span id="line-78"> this.leftJustify = leftJustify;</span>
+<span class="source-line-no">079</span><span id="line-79"> this.fieldValueType = Objects.requireNonNull(fieldValueType);</span>
<span class="source-line-no">080</span><span id="line-80"> }</span>
<span class="source-line-no">081</span><span id="line-81"></span>
-<span class="source-line-no">082</span><span id="line-82"> public String getHeader() {</span>
-<span class="source-line-no">083</span><span id="line-83"> return header;</span>
+<span class="source-line-no">082</span><span id="line-82"> public FieldValue newValue(Object value) {</span>
+<span class="source-line-no">083</span><span id="line-83"> return new FieldValue(value, fieldValueType);</span>
<span class="source-line-no">084</span><span id="line-84"> }</span>
<span class="source-line-no">085</span><span id="line-85"></span>
-<span class="source-line-no">086</span><span id="line-86"> public String getDescription() {</span>
-<span class="source-line-no">087</span><span id="line-87"> return description;</span>
+<span class="source-line-no">086</span><span id="line-86"> public String getHeader() {</span>
+<span class="source-line-no">087</span><span id="line-87"> return header;</span>
<span class="source-line-no">088</span><span id="line-88"> }</span>
<span class="source-line-no">089</span><span id="line-89"></span>
-<span class="source-line-no">090</span><span id="line-90"> public boolean isAutoAdjust() {</span>
-<span class="source-line-no">091</span><span id="line-91"> return autoAdjust;</span>
+<span class="source-line-no">090</span><span id="line-90"> public String getDescription() {</span>
+<span class="source-line-no">091</span><span id="line-91"> return description;</span>
<span class="source-line-no">092</span><span id="line-92"> }</span>
<span class="source-line-no">093</span><span id="line-93"></span>
-<span class="source-line-no">094</span><span id="line-94"> public boolean isLeftJustify() {</span>
-<span class="source-line-no">095</span><span id="line-95"> return leftJustify;</span>
+<span class="source-line-no">094</span><span id="line-94"> public boolean isAutoAdjust() {</span>
+<span class="source-line-no">095</span><span id="line-95"> return autoAdjust;</span>
<span class="source-line-no">096</span><span id="line-96"> }</span>
<span class="source-line-no">097</span><span id="line-97"></span>
-<span class="source-line-no">098</span><span id="line-98"> public FieldValueType getFieldValueType() {</span>
-<span class="source-line-no">099</span><span id="line-99"> return fieldValueType;</span>
+<span class="source-line-no">098</span><span id="line-98"> public boolean isLeftJustify() {</span>
+<span class="source-line-no">099</span><span id="line-99"> return leftJustify;</span>
<span class="source-line-no">100</span><span id="line-100"> }</span>
-<span class="source-line-no">101</span><span id="line-101">}</span>
+<span class="source-line-no">101</span><span id="line-101"></span>
+<span class="source-line-no">102</span><span id="line-102"> public FieldValueType getFieldValueType() {</span>
+<span class="source-line-no">103</span><span id="line-103"> return fieldValueType;</span>
+<span class="source-line-no">104</span><span id="line-104"> }</span>
+<span class="source-line-no">105</span><span id="line-105">}</span>
diff --git a/apidocs/src-html/org/apache/hadoop/hbase/hbtop/mode/ClientModeStrategy.html b/apidocs/src-html/org/apache/hadoop/hbase/hbtop/mode/ClientModeStrategy.html
index 4a9aeb30032..c7111da2117 100644
--- a/apidocs/src-html/org/apache/hadoop/hbase/hbtop/mode/ClientModeStrategy.html
+++ b/apidocs/src-html/org/apache/hadoop/hbase/hbtop/mode/ClientModeStrategy.html
@@ -61,114 +61,120 @@
<span class="source-line-no">048</span><span id="line-48"> new FieldInfo(Field.REQUEST_COUNT_PER_SECOND, 10, true),</span>
<span class="source-line-no">049</span><span id="line-49"> new FieldInfo(Field.READ_REQUEST_COUNT_PER_SECOND, 10, true),</span>
<span class="source-line-no">050</span><span id="line-50"> new FieldInfo(Field.WRITE_REQUEST_COUNT_PER_SECOND, 10, true),</span>
-<span class="source-line-no">051</span><span id="line-51"> new FieldInfo(Field.FILTERED_READ_REQUEST_COUNT_PER_SECOND, 10, true));</span>
-<span class="source-line-no">052</span><span id="line-52"> private final Map<String, RequestCountPerSecond> requestCountPerSecondMap = new HashMap<>();</span>
-<span class="source-line-no">053</span><span id="line-53"></span>
-<span class="source-line-no">054</span><span id="line-54"> ClientModeStrategy() {</span>
-<span class="source-line-no">055</span><span id="line-55"> }</span>
-<span class="source-line-no">056</span><span id="line-56"></span>
-<span class="source-line-no">057</span><span id="line-57"> @Override</span>
-<span class="source-line-no">058</span><span id="line-58"> public List<FieldInfo> getFieldInfos() {</span>
-<span class="source-line-no">059</span><span id="line-59"> return fieldInfos;</span>
-<span class="source-line-no">060</span><span id="line-60"> }</span>
-<span class="source-line-no">061</span><span id="line-61"></span>
-<span class="source-line-no">062</span><span id="line-62"> @Override</span>
-<span class="source-line-no">063</span><span id="line-63"> public Field getDefaultSortField() {</span>
-<span class="source-line-no">064</span><span id="line-64"> return Field.REQUEST_COUNT_PER_SECOND;</span>
-<span class="source-line-no">065</span><span id="line-65"> }</span>
-<span class="source-line-no">066</span><span id="line-66"></span>
-<span class="source-line-no">067</span><span id="line-67"> @Override</span>
-<span class="source-line-no">068</span><span id="line-68"> public List<Record> getRecords(ClusterMetrics clusterMetrics,</span>
-<span class="source-line-no">069</span><span id="line-69"> List<RecordFilter> pushDownFilters) {</span>
-<span class="source-line-no">070</span><span id="line-70"> List<Record> records = createRecords(clusterMetrics);</span>
-<span class="source-line-no">071</span><span id="line-71"> return aggregateRecordsAndAddDistinct(</span>
-<span class="source-line-no">072</span><span id="line-72"> ModeStrategyUtils.applyFilterAndGet(records, pushDownFilters), Field.CLIENT, Field.USER,</span>
-<span class="source-line-no">073</span><span id="line-73"> Field.USER_COUNT);</span>
-<span class="source-line-no">074</span><span id="line-74"> }</span>
-<span class="source-line-no">075</span><span id="line-75"></span>
-<span class="source-line-no">076</span><span id="line-76"> List<Record> createRecords(ClusterMetrics clusterMetrics) {</span>
-<span class="source-line-no">077</span><span id="line-77"> List<Record> ret = new ArrayList<>();</span>
-<span class="source-line-no">078</span><span id="line-78"> for (ServerMetrics serverMetrics : clusterMetrics.getLiveServerMetrics().values()) {</span>
-<span class="source-line-no">079</span><span id="line-79"> long lastReportTimestamp = serverMetrics.getLastReportTimestamp();</span>
-<span class="source-line-no">080</span><span id="line-80"> serverMetrics.getUserMetrics().values()</span>
-<span class="source-line-no">081</span><span id="line-81"> .forEach(um -> um.getClientMetrics().values()</span>
-<span class="source-line-no">082</span><span id="line-82"> .forEach(clientMetrics -> ret.add(createRecord(um.getNameAsString(), clientMetrics,</span>
-<span class="source-line-no">083</span><span id="line-83"> lastReportTimestamp, serverMetrics.getServerName().getServerName()))));</span>
-<span class="source-line-no">084</span><span id="line-84"> }</span>
-<span class="source-line-no">085</span><span id="line-85"> return ret;</span>
-<span class="source-line-no">086</span><span id="line-86"> }</span>
-<span class="source-line-no">087</span><span id="line-87"></span>
-<span class="source-line-no">088</span><span id="line-88"> /**</span>
-<span class="source-line-no">089</span><span id="line-89"> * Aggregate the records and count the unique values for the given distinctField</span>
-<span class="source-line-no">090</span><span id="line-90"> * @param records records to be processed</span>
-<span class="source-line-no">091</span><span id="line-91"> * @param groupBy Field on which group by needs to be done</span>
-<span class="source-line-no">092</span><span id="line-92"> * @param distinctField Field whose unique values needs to be counted</span>
-<span class="source-line-no">093</span><span id="line-93"> * @param uniqueCountAssignedTo a target field to which the unique count is assigned to</span>
-<span class="source-line-no">094</span><span id="line-94"> * @return aggregated records</span>
-<span class="source-line-no">095</span><span id="line-95"> */</span>
-<span class="source-line-no">096</span><span id="line-96"> List<Record> aggregateRecordsAndAddDistinct(List<Record> records, Field groupBy,</span>
-<span class="source-line-no">097</span><span id="line-97"> Field distinctField, Field uniqueCountAssignedTo) {</span>
-<span class="source-line-no">098</span><span id="line-98"> List<Record> result = new ArrayList<>();</span>
-<span class="source-line-no">099</span><span id="line-99"> records.stream().collect(Collectors.groupingBy(r -> r.get(groupBy))).values().forEach(val -> {</span>
-<span class="source-line-no">100</span><span id="line-100"> Set<FieldValue> distinctValues = new HashSet<>();</span>
-<span class="source-line-no">101</span><span id="line-101"> Map<Field, FieldValue> map = new HashMap<>();</span>
-<span class="source-line-no">102</span><span id="line-102"> for (Record record : val) {</span>
-<span class="source-line-no">103</span><span id="line-103"> for (Map.Entry<Field, FieldValue> field : record.entrySet()) {</span>
-<span class="source-line-no">104</span><span id="line-104"> if (distinctField.equals(field.getKey())) {</span>
-<span class="source-line-no">105</span><span id="line-105"> // We will not be adding the field in the new record whose distinct count is required</span>
-<span class="source-line-no">106</span><span id="line-106"> distinctValues.add(record.get(distinctField));</span>
-<span class="source-line-no">107</span><span id="line-107"> } else {</span>
-<span class="source-line-no">108</span><span id="line-108"> if (field.getKey().getFieldValueType() == FieldValueType.STRING) {</span>
-<span class="source-line-no">109</span><span id="line-109"> map.put(field.getKey(), field.getValue());</span>
-<span class="source-line-no">110</span><span id="line-110"> } else {</span>
-<span class="source-line-no">111</span><span id="line-111"> if (map.get(field.getKey()) == null) {</span>
-<span class="source-line-no">112</span><span id="line-112"> map.put(field.getKey(), field.getValue());</span>
-<span class="source-line-no">113</span><span id="line-113"> } else {</span>
-<span class="source-line-no">114</span><span id="line-114"> map.put(field.getKey(), map.get(field.getKey()).plus(field.getValue()));</span>
-<span class="source-line-no">115</span><span id="line-115"> }</span>
-<span class="source-line-no">116</span><span id="line-116"> }</span>
-<span class="source-line-no">117</span><span id="line-117"> }</span>
-<span class="source-line-no">118</span><span id="line-118"> }</span>
-<span class="source-line-no">119</span><span id="line-119"> }</span>
-<span class="source-line-no">120</span><span id="line-120"> // Add unique count field</span>
-<span class="source-line-no">121</span><span id="line-121"> map.put(uniqueCountAssignedTo, uniqueCountAssignedTo.newValue(distinctValues.size()));</span>
-<span class="source-line-no">122</span><span id="line-122"> result.add(</span>
-<span class="source-line-no">123</span><span id="line-123"> Record.ofEntries(map.entrySet().stream().map(k -> Record.entry(k.getKey(), k.getValue()))));</span>
-<span class="source-line-no">124</span><span id="line-124"> });</span>
-<span class="source-line-no">125</span><span id="line-125"> return result;</span>
-<span class="source-line-no">126</span><span id="line-126"> }</span>
-<span class="source-line-no">127</span><span id="line-127"></span>
-<span class="source-line-no">128</span><span id="line-128"> Record createRecord(String user, UserMetrics.ClientMetrics clientMetrics,</span>
-<span class="source-line-no">129</span><span id="line-129"> long lastReportTimestamp, String server) {</span>
-<span class="source-line-no">130</span><span id="line-130"> Record.Builder builder = Record.builder();</span>
-<span class="source-line-no">131</span><span id="line-131"> String client = clientMetrics.getHostName();</span>
-<span class="source-line-no">132</span><span id="line-132"> builder.put(Field.CLIENT, clientMetrics.getHostName());</span>
-<span class="source-line-no">133</span><span id="line-133"> String mapKey = client + "$" + user + "$" + server;</span>
-<span class="source-line-no">134</span><span id="line-134"> RequestCountPerSecond requestCountPerSecond = requestCountPerSecondMap.get(mapKey);</span>
-<span class="source-line-no">135</span><span id="line-135"> if (requestCountPerSecond == null) {</span>
-<span class="source-line-no">136</span><span id="line-136"> requestCountPerSecond = new RequestCountPerSecond();</span>
-<span class="source-line-no">137</span><span id="line-137"> requestCountPerSecondMap.put(mapKey, requestCountPerSecond);</span>
-<span class="source-line-no">138</span><span id="line-138"> }</span>
-<span class="source-line-no">139</span><span id="line-139"> requestCountPerSecond.refresh(lastReportTimestamp, clientMetrics.getReadRequestsCount(),</span>
-<span class="source-line-no">140</span><span id="line-140"> clientMetrics.getFilteredReadRequestsCount(), clientMetrics.getWriteRequestsCount());</span>
-<span class="source-line-no">141</span><span id="line-141"> builder.put(Field.REQUEST_COUNT_PER_SECOND, requestCountPerSecond.getRequestCountPerSecond());</span>
-<span class="source-line-no">142</span><span id="line-142"> builder.put(Field.READ_REQUEST_COUNT_PER_SECOND,</span>
-<span class="source-line-no">143</span><span id="line-143"> requestCountPerSecond.getReadRequestCountPerSecond());</span>
-<span class="source-line-no">144</span><span id="line-144"> builder.put(Field.WRITE_REQUEST_COUNT_PER_SECOND,</span>
-<span class="source-line-no">145</span><span id="line-145"> requestCountPerSecond.getWriteRequestCountPerSecond());</span>
-<span class="source-line-no">146</span><span id="line-146"> builder.put(Field.FILTERED_READ_REQUEST_COUNT_PER_SECOND,</span>
-<span class="source-line-no">147</span><span id="line-147"> requestCountPerSecond.getFilteredReadRequestCountPerSecond());</span>
-<span class="source-line-no">148</span><span id="line-148"> builder.put(Field.USER, user);</span>
-<span class="source-line-no">149</span><span id="line-149"> return builder.build();</span>
-<span class="source-line-no">150</span><span id="line-150"> }</span>
-<span class="source-line-no">151</span><span id="line-151"></span>
-<span class="source-line-no">152</span><span id="line-152"> @Override</span>
-<span class="source-line-no">153</span><span id="line-153"> public DrillDownInfo drillDown(Record selectedRecord) {</span>
-<span class="source-line-no">154</span><span id="line-154"> List<RecordFilter> initialFilters = Collections.singletonList(</span>
-<span class="source-line-no">155</span><span id="line-155"> RecordFilter.newBuilder(Field.CLIENT).doubleEquals(selectedRecord.get(Field.CLIENT)));</span>
-<span class="source-line-no">156</span><span id="line-156"> return new DrillDownInfo(Mode.USER, initialFilters);</span>
-<span class="source-line-no">157</span><span id="line-157"> }</span>
-<span class="source-line-no">158</span><span id="line-158">}</span>
+<span class="source-line-no">051</span><span id="line-51"> new FieldInfo(Field.FILTERED_READ_REQUEST_COUNT_PER_SECOND, 10, true),</span>
+<span class="source-line-no">052</span><span id="line-52"> new FieldInfo(Field.HOST_ADDRESS, 0, true), new FieldInfo(Field.USER_NAME, 0, true),</span>
+<span class="source-line-no">053</span><span id="line-53"> new FieldInfo(Field.CLIENT_VERSION, 0, true), new FieldInfo(Field.SERVICE_NAME, 0, true));</span>
+<span class="source-line-no">054</span><span id="line-54"> private final Map<String, RequestCountPerSecond> requestCountPerSecondMap = new HashMap<>();</span>
+<span class="source-line-no">055</span><span id="line-55"></span>
+<span class="source-line-no">056</span><span id="line-56"> ClientModeStrategy() {</span>
+<span class="source-line-no">057</span><span id="line-57"> }</span>
+<span class="source-line-no">058</span><span id="line-58"></span>
+<span class="source-line-no">059</span><span id="line-59"> @Override</span>
+<span class="source-line-no">060</span><span id="line-60"> public List<FieldInfo> getFieldInfos() {</span>
+<span class="source-line-no">061</span><span id="line-61"> return fieldInfos;</span>
+<span class="source-line-no">062</span><span id="line-62"> }</span>
+<span class="source-line-no">063</span><span id="line-63"></span>
+<span class="source-line-no">064</span><span id="line-64"> @Override</span>
+<span class="source-line-no">065</span><span id="line-65"> public Field getDefaultSortField() {</span>
+<span class="source-line-no">066</span><span id="line-66"> return Field.REQUEST_COUNT_PER_SECOND;</span>
+<span class="source-line-no">067</span><span id="line-67"> }</span>
+<span class="source-line-no">068</span><span id="line-68"></span>
+<span class="source-line-no">069</span><span id="line-69"> @Override</span>
+<span class="source-line-no">070</span><span id="line-70"> public List<Record> getRecords(ClusterMetrics clusterMetrics,</span>
+<span class="source-line-no">071</span><span id="line-71"> List<RecordFilter> pushDownFilters) {</span>
+<span class="source-line-no">072</span><span id="line-72"> List<Record> records = createRecords(clusterMetrics);</span>
+<span class="source-line-no">073</span><span id="line-73"> return aggregateRecordsAndAddDistinct(</span>
+<span class="source-line-no">074</span><span id="line-74"> ModeStrategyUtils.applyFilterAndGet(records, pushDownFilters), Field.CLIENT, Field.USER,</span>
+<span class="source-line-no">075</span><span id="line-75"> Field.USER_COUNT);</span>
+<span class="source-line-no">076</span><span id="line-76"> }</span>
+<span class="source-line-no">077</span><span id="line-77"></span>
+<span class="source-line-no">078</span><span id="line-78"> List<Record> createRecords(ClusterMetrics clusterMetrics) {</span>
+<span class="source-line-no">079</span><span id="line-79"> List<Record> ret = new ArrayList<>();</span>
+<span class="source-line-no">080</span><span id="line-80"> for (ServerMetrics serverMetrics : clusterMetrics.getLiveServerMetrics().values()) {</span>
+<span class="source-line-no">081</span><span id="line-81"> long lastReportTimestamp = serverMetrics.getLastReportTimestamp();</span>
+<span class="source-line-no">082</span><span id="line-82"> serverMetrics.getUserMetrics().values()</span>
+<span class="source-line-no">083</span><span id="line-83"> .forEach(um -> um.getClientMetrics().values()</span>
+<span class="source-line-no">084</span><span id="line-84"> .forEach(clientMetrics -> ret.add(createRecord(um.getNameAsString(), clientMetrics,</span>
+<span class="source-line-no">085</span><span id="line-85"> lastReportTimestamp, serverMetrics.getServerName().getServerName()))));</span>
+<span class="source-line-no">086</span><span id="line-86"> }</span>
+<span class="source-line-no">087</span><span id="line-87"> return ret;</span>
+<span class="source-line-no">088</span><span id="line-88"> }</span>
+<span class="source-line-no">089</span><span id="line-89"></span>
+<span class="source-line-no">090</span><span id="line-90"> /**</span>
+<span class="source-line-no">091</span><span id="line-91"> * Aggregate the records and count the unique values for the given distinctField</span>
+<span class="source-line-no">092</span><span id="line-92"> * @param records records to be processed</span>
+<span class="source-line-no">093</span><span id="line-93"> * @param groupBy Field on which group by needs to be done</span>
+<span class="source-line-no">094</span><span id="line-94"> * @param distinctField Field whose unique values needs to be counted</span>
+<span class="source-line-no">095</span><span id="line-95"> * @param uniqueCountAssignedTo a target field to which the unique count is assigned to</span>
+<span class="source-line-no">096</span><span id="line-96"> * @return aggregated records</span>
+<span class="source-line-no">097</span><span id="line-97"> */</span>
+<span class="source-line-no">098</span><span id="line-98"> List<Record> aggregateRecordsAndAddDistinct(List<Record> records, Field groupBy,</span>
+<span class="source-line-no">099</span><span id="line-99"> Field distinctField, Field uniqueCountAssignedTo) {</span>
+<span class="source-line-no">100</span><span id="line-100"> List<Record> result = new ArrayList<>();</span>
+<span class="source-line-no">101</span><span id="line-101"> records.stream().collect(Collectors.groupingBy(r -> r.get(groupBy))).values().forEach(val -> {</span>
+<span class="source-line-no">102</span><span id="line-102"> Set<FieldValue> distinctValues = new HashSet<>();</span>
+<span class="source-line-no">103</span><span id="line-103"> Map<Field, FieldValue> map = new HashMap<>();</span>
+<span class="source-line-no">104</span><span id="line-104"> for (Record record : val) {</span>
+<span class="source-line-no">105</span><span id="line-105"> for (Map.Entry<Field, FieldValue> field : record.entrySet()) {</span>
+<span class="source-line-no">106</span><span id="line-106"> if (distinctField.equals(field.getKey())) {</span>
+<span class="source-line-no">107</span><span id="line-107"> // We will not be adding the field in the new record whose distinct count is required</span>
+<span class="source-line-no">108</span><span id="line-108"> distinctValues.add(record.get(distinctField));</span>
+<span class="source-line-no">109</span><span id="line-109"> } else {</span>
+<span class="source-line-no">110</span><span id="line-110"> if (field.getKey().getFieldValueType() == FieldValueType.STRING) {</span>
+<span class="source-line-no">111</span><span id="line-111"> map.put(field.getKey(), field.getValue());</span>
+<span class="source-line-no">112</span><span id="line-112"> } else {</span>
+<span class="source-line-no">113</span><span id="line-113"> if (map.get(field.getKey()) == null) {</span>
+<span class="source-line-no">114</span><span id="line-114"> map.put(field.getKey(), field.getValue());</span>
+<span class="source-line-no">115</span><span id="line-115"> } else {</span>
+<span class="source-line-no">116</span><span id="line-116"> map.put(field.getKey(), map.get(field.getKey()).plus(field.getValue()));</span>
+<span class="source-line-no">117</span><span id="line-117"> }</span>
+<span class="source-line-no">118</span><span id="line-118"> }</span>
+<span class="source-line-no">119</span><span id="line-119"> }</span>
+<span class="source-line-no">120</span><span id="line-120"> }</span>
+<span class="source-line-no">121</span><span id="line-121"> }</span>
+<span class="source-line-no">122</span><span id="line-122"> // Add unique count field</span>
+<span class="source-line-no">123</span><span id="line-123"> map.put(uniqueCountAssignedTo, uniqueCountAssignedTo.newValue(distinctValues.size()));</span>
+<span class="source-line-no">124</span><span id="line-124"> result.add(</span>
+<span class="source-line-no">125</span><span id="line-125"> Record.ofEntries(map.entrySet().stream().map(k -> Record.entry(k.getKey(), k.getValue()))));</span>
+<span class="source-line-no">126</span><span id="line-126"> });</span>
+<span class="source-line-no">127</span><span id="line-127"> return result;</span>
+<span class="source-line-no">128</span><span id="line-128"> }</span>
+<span class="source-line-no">129</span><span id="line-129"></span>
+<span class="source-line-no">130</span><span id="line-130"> Record createRecord(String user, UserMetrics.ClientMetrics clientMetrics,</span>
+<span class="source-line-no">131</span><span id="line-131"> long lastReportTimestamp, String server) {</span>
+<span class="source-line-no">132</span><span id="line-132"> Record.Builder builder = Record.builder();</span>
+<span class="source-line-no">133</span><span id="line-133"> String client = clientMetrics.getHostName();</span>
+<span class="source-line-no">134</span><span id="line-134"> builder.put(Field.CLIENT, clientMetrics.getHostName());</span>
+<span class="source-line-no">135</span><span id="line-135"> String mapKey = client + "$" + user + "$" + server;</span>
+<span class="source-line-no">136</span><span id="line-136"> RequestCountPerSecond requestCountPerSecond = requestCountPerSecondMap.get(mapKey);</span>
+<span class="source-line-no">137</span><span id="line-137"> if (requestCountPerSecond == null) {</span>
+<span class="source-line-no">138</span><span id="line-138"> requestCountPerSecond = new RequestCountPerSecond();</span>
+<span class="source-line-no">139</span><span id="line-139"> requestCountPerSecondMap.put(mapKey, requestCountPerSecond);</span>
+<span class="source-line-no">140</span><span id="line-140"> }</span>
+<span class="source-line-no">141</span><span id="line-141"> requestCountPerSecond.refresh(lastReportTimestamp, clientMetrics.getReadRequestsCount(),</span>
+<span class="source-line-no">142</span><span id="line-142"> clientMetrics.getFilteredReadRequestsCount(), clientMetrics.getWriteRequestsCount());</span>
+<span class="source-line-no">143</span><span id="line-143"> builder.put(Field.REQUEST_COUNT_PER_SECOND, requestCountPerSecond.getRequestCountPerSecond());</span>
+<span class="source-line-no">144</span><span id="line-144"> builder.put(Field.READ_REQUEST_COUNT_PER_SECOND,</span>
+<span class="source-line-no">145</span><span id="line-145"> requestCountPerSecond.getReadRequestCountPerSecond());</span>
+<span class="source-line-no">146</span><span id="line-146"> builder.put(Field.WRITE_REQUEST_COUNT_PER_SECOND,</span>
+<span class="source-line-no">147</span><span id="line-147"> requestCountPerSecond.getWriteRequestCountPerSecond());</span>
+<span class="source-line-no">148</span><span id="line-148"> builder.put(Field.FILTERED_READ_REQUEST_COUNT_PER_SECOND,</span>
+<span class="source-line-no">149</span><span id="line-149"> requestCountPerSecond.getFilteredReadRequestCountPerSecond());</span>
+<span class="source-line-no">150</span><span id="line-150"> builder.put(Field.HOST_ADDRESS, clientMetrics.getHostAddress());</span>
+<span class="source-line-no">151</span><span id="line-151"> builder.put(Field.USER_NAME, clientMetrics.getUserName());</span>
+<span class="source-line-no">152</span><span id="line-152"> builder.put(Field.CLIENT_VERSION, clientMetrics.getClientVersion());</span>
+<span class="source-line-no">153</span><span id="line-153"> builder.put(Field.SERVICE_NAME, clientMetrics.getServiceName());</span>
+<span class="source-line-no">154</span><span id="line-154"> builder.put(Field.USER, user);</span>
+<span class="source-line-no">155</span><span id="line-155"> return builder.build();</span>
+<span class="source-line-no">156</span><span id="line-156"> }</span>
+<span class="source-line-no">157</span><span id="line-157"></span>
+<span class="source-line-no">158</span><span id="line-158"> @Override</span>
+<span class="source-line-no">159</span><span id="line-159"> public DrillDownInfo drillDown(Record selectedRecord) {</span>
+<span class="source-line-no">160</span><span id="line-160"> List<RecordFilter> initialFilters = Collections.singletonList(</span>
+<span class="source-line-no">161</span><span id="line-161"> RecordFilter.newBuilder(Field.CLIENT).doubleEquals(selectedRecord.get(Field.CLIENT)));</span>
+<span class="source-line-no">162</span><span id="line-162"> return new DrillDownInfo(Mode.USER, initialFilters);</span>
+<span class="source-line-no">163</span><span id="line-163"> }</span>
+<span class="source-line-no">164</span><span id="line-164">}</span>
diff --git a/apidocs/src-html/org/apache/hadoop/hbase/ipc/RpcServer.BlockingServiceAndInterface.html b/apidocs/src-html/org/apache/hadoop/hbase/ipc/RpcServer.BlockingServiceAndInterface.html
index 7c4dcefa514..f9fff7aeeca 100644
--- a/apidocs/src-html/org/apache/hadoop/hbase/ipc/RpcServer.BlockingServiceAndInterface.html
+++ b/apidocs/src-html/org/apache/hadoop/hbase/ipc/RpcServer.BlockingServiceAndInterface.html
@@ -848,104 +848,122 @@
<span class="source-line-no">835</span><span id="line-835"> }</span>
<span class="source-line-no">836</span><span id="line-836"></span>
<span class="source-line-no">837</span><span id="line-837"> /**</span>
-<span class="source-line-no">838</span><span id="line-838"> * @param serviceName Some arbitrary string that represents a 'service'.</span>
-<span class="source-line-no">839</span><span id="line-839"> * @param services Available service instances</span>
-<span class="source-line-no">840</span><span id="line-840"> * @return Matching BlockingServiceAndInterface pair</span>
-<span class="source-line-no">841</span><span id="line-841"> */</span>
-<span class="source-line-no">842</span><span id="line-842"> protected static BlockingServiceAndInterface getServiceAndInterface(</span>
-<span class="source-line-no">843</span><span id="line-843"> final List<BlockingServiceAndInterface> services, final String serviceName) {</span>
-<span class="source-line-no">844</span><span id="line-844"> for (BlockingServiceAndInterface bs : services) {</span>
-<span class="source-line-no">845</span><span id="line-845"> if (bs.getBlockingService().getDescriptorForType().getName().equals(serviceName)) {</span>
-<span class="source-line-no">846</span><span id="line-846"> return bs;</span>
-<span class="source-line-no">847</span><span id="line-847"> }</span>
-<span class="source-line-no">848</span><span id="line-848"> }</span>
-<span class="source-line-no">849</span><span id="line-849"> return null;</span>
-<span class="source-line-no">850</span><span id="line-850"> }</span>
-<span class="source-line-no">851</span><span id="line-851"></span>
-<span class="source-line-no">852</span><span id="line-852"> /**</span>
-<span class="source-line-no">853</span><span id="line-853"> * @param serviceName Some arbitrary string that represents a 'service'.</span>
-<span class="source-line-no">854</span><span id="line-854"> * @param services Available services and their service interfaces.</span>
-<span class="source-line-no">855</span><span id="line-855"> * @return Service interface class for <code>serviceName</code></span>
-<span class="source-line-no">856</span><span id="line-856"> */</span>
-<span class="source-line-no">857</span><span id="line-857"> protected static Class<?> getServiceInterface(final List<BlockingServiceAndInterface> services,</span>
-<span class="source-line-no">858</span><span id="line-858"> final String serviceName) {</span>
-<span class="source-line-no">859</span><span id="line-859"> BlockingServiceAndInterface bsasi = getServiceAndInterface(services, serviceName);</span>
-<span class="source-line-no">860</span><span id="line-860"> return bsasi == null ? null : bsasi.getServiceInterface();</span>
-<span class="source-line-no">861</span><span id="line-861"> }</span>
-<span class="source-line-no">862</span><span id="line-862"></span>
-<span class="source-line-no">863</span><span id="line-863"> /**</span>
-<span class="source-line-no">864</span><span id="line-864"> * @param serviceName Some arbitrary string that represents a 'service'.</span>
-<span class="source-line-no">865</span><span id="line-865"> * @param services Available services and their service interfaces.</span>
-<span class="source-line-no">866</span><span id="line-866"> * @return BlockingService that goes with the passed <code>serviceName</code></span>
-<span class="source-line-no">867</span><span id="line-867"> */</span>
-<span class="source-line-no">868</span><span id="line-868"> protected static BlockingService getService(final List<BlockingServiceAndInterface> services,</span>
-<span class="source-line-no">869</span><span id="line-869"> final String serviceName) {</span>
-<span class="source-line-no">870</span><span id="line-870"> BlockingServiceAndInterface bsasi = getServiceAndInterface(services, serviceName);</span>
-<span class="source-line-no">871</span><span id="line-871"> return bsasi == null ? null : bsasi.getBlockingService();</span>
-<span class="source-line-no">872</span><span id="line-872"> }</span>
-<span class="source-line-no">873</span><span id="line-873"></span>
-<span class="source-line-no">874</span><span id="line-874"> protected static MonitoredRPCHandler getStatus() {</span>
-<span class="source-line-no">875</span><span id="line-875"> // It is ugly the way we park status up in RpcServer. Let it be for now. TODO.</span>
-<span class="source-line-no">876</span><span id="line-876"> MonitoredRPCHandler status = RpcServer.MONITORED_RPC.get();</span>
-<span class="source-line-no">877</span><span id="line-877"> if (status != null) {</span>
-<span class="source-line-no">878</span><span id="line-878"> return status;</span>
-<span class="source-line-no">879</span><span id="line-879"> }</span>
-<span class="source-line-no">880</span><span id="line-880"> status = TaskMonitor.get().createRPCStatus(Thread.currentThread().getName());</span>
-<span class="source-line-no">881</span><span id="line-881"> status.pause("Waiting for a call");</span>
-<span class="source-line-no">882</span><span id="line-882"> RpcServer.MONITORED_RPC.set(status);</span>
-<span class="source-line-no">883</span><span id="line-883"> return status;</span>
-<span class="source-line-no">884</span><span id="line-884"> }</span>
-<span class="source-line-no">885</span><span id="line-885"></span>
-<span class="source-line-no">886</span><span id="line-886"> /**</span>
-<span class="source-line-no">887</span><span id="line-887"> * Returns the remote side ip address when invoked inside an RPC Returns null incase of an error.</span>
-<span class="source-line-no">888</span><span id="line-888"> */</span>
-<span class="source-line-no">889</span><span id="line-889"> public static InetAddress getRemoteIp() {</span>
-<span class="source-line-no">890</span><span id="line-890"> RpcCall call = CurCall.get();</span>
-<span class="source-line-no">891</span><span id="line-891"> if (call != null) {</span>
-<span class="source-line-no">892</span><span id="line-892"> return call.getRemoteAddress();</span>
-<span class="source-line-no">893</span><span id="line-893"> }</span>
-<span class="source-line-no">894</span><span id="line-894"> return null;</span>
-<span class="source-line-no">895</span><span id="line-895"> }</span>
-<span class="source-line-no">896</span><span id="line-896"></span>
-<span class="source-line-no">897</span><span id="line-897"> @Override</span>
-<span class="source-line-no">898</span><span id="line-898"> public RpcScheduler getScheduler() {</span>
-<span class="source-line-no">899</span><span id="line-899"> return scheduler;</span>
-<span class="source-line-no">900</span><span id="line-900"> }</span>
-<span class="source-line-no">901</span><span id="line-901"></span>
-<span class="source-line-no">902</span><span id="line-902"> @Override</span>
-<span class="source-line-no">903</span><span id="line-903"> public ByteBuffAllocator getByteBuffAllocator() {</span>
-<span class="source-line-no">904</span><span id="line-904"> return this.bbAllocator;</span>
-<span class="source-line-no">905</span><span id="line-905"> }</span>
-<span class="source-line-no">906</span><span id="line-906"></span>
-<span class="source-line-no">907</span><span id="line-907"> @Override</span>
-<span class="source-line-no">908</span><span id="line-908"> public void setRsRpcServices(RSRpcServices rsRpcServices) {</span>
-<span class="source-line-no">909</span><span id="line-909"> this.rsRpcServices = rsRpcServices;</span>
-<span class="source-line-no">910</span><span id="line-910"> }</span>
-<span class="source-line-no">911</span><span id="line-911"></span>
-<span class="source-line-no">912</span><span id="line-912"> @Override</span>
-<span class="source-line-no">913</span><span id="line-913"> public void setNamedQueueRecorder(NamedQueueRecorder namedQueueRecorder) {</span>
-<span class="source-line-no">914</span><span id="line-914"> this.namedQueueRecorder = namedQueueRecorder;</span>
-<span class="source-line-no">915</span><span id="line-915"> }</span>
-<span class="source-line-no">916</span><span id="line-916"></span>
-<span class="source-line-no">917</span><span id="line-917"> protected boolean needAuthorization() {</span>
-<span class="source-line-no">918</span><span id="line-918"> return authorize;</span>
-<span class="source-line-no">919</span><span id="line-919"> }</span>
-<span class="source-line-no">920</span><span id="line-920"></span>
-<span class="source-line-no">921</span><span id="line-921"> @RestrictedApi(explanation = "Should only be called in tests", link = "",</span>
-<span class="source-line-no">922</span><span id="line-922"> allowedOnPath = ".*/src/test/.*")</span>
-<span class="source-line-no">923</span><span id="line-923"> public List<BlockingServiceAndInterface> getServices() {</span>
-<span class="source-line-no">924</span><span id="line-924"> return services;</span>
-<span class="source-line-no">925</span><span id="line-925"> }</span>
-<span class="source-line-no">926</span><span id="line-926"></span>
-<span class="source-line-no">927</span><span id="line-927"> private void initializeCoprocessorHost(Configuration conf) {</span>
-<span class="source-line-no">928</span><span id="line-928"> this.cpHost = new RpcCoprocessorHost(conf);</span>
-<span class="source-line-no">929</span><span id="line-929"> }</span>
-<span class="source-line-no">930</span><span id="line-930"></span>
-<span class="source-line-no">931</span><span id="line-931"> @Override</span>
-<span class="source-line-no">932</span><span id="line-932"> public RpcCoprocessorHost getRpcCoprocessorHost() {</span>
-<span class="source-line-no">933</span><span id="line-933"> return cpHost;</span>
-<span class="source-line-no">934</span><span id="line-934"> }</span>
-<span class="source-line-no">935</span><span id="line-935">}</span>
+<span class="source-line-no">838</span><span id="line-838"> * Returns the ServerRpcConnection for the current RPC request or not present if no connection is</span>
+<span class="source-line-no">839</span><span id="line-839"> * available. This allows access to connection-level information such as the client's IP address,</span>
+<span class="source-line-no">840</span><span id="line-840"> * authentication details, codec configuration, etc.</span>
+<span class="source-line-no">841</span><span id="line-841"> * <p></span>
+<span class="source-line-no">842</span><span id="line-842"> * This method should only be called from within an RPC handler thread context.</span>
+<span class="source-line-no">843</span><span id="line-843"> * @return the current ServerRpcConnection, or Optional.empty() if called outside of an RPC</span>
+<span class="source-line-no">844</span><span id="line-844"> * context</span>
+<span class="source-line-no">845</span><span id="line-845"> */</span>
+<span class="source-line-no">846</span><span id="line-846"> public static Optional<ServerRpcConnection> getCurrentServerRpcConnection() {</span>
+<span class="source-line-no">847</span><span id="line-847"> Optional<RpcCall> call = getCurrentCall();</span>
+<span class="source-line-no">848</span><span id="line-848"> if (call.isPresent() && call.get() instanceof ServerCall) {</span>
+<span class="source-line-no">849</span><span id="line-849"> ServerCall<?> serverCall = (ServerCall<?>) call.get();</span>
+<span class="source-line-no">850</span><span id="line-850"> return Optional.ofNullable(serverCall.getConnection());</span>
+<span class="source-line-no">851</span><span id="line-851"> }</span>
+<span class="source-line-no">852</span><span id="line-852"> return Optional.empty();</span>
+<span class="source-line-no">853</span><span id="line-853"> }</span>
+<span class="source-line-no">854</span><span id="line-854"></span>
+<span class="source-line-no">855</span><span id="line-855"> /**</span>
+<span class="source-line-no">856</span><span id="line-856"> * @param serviceName Some arbitrary string that represents a 'service'.</span>
+<span class="source-line-no">857</span><span id="line-857"> * @param services Available service instances</span>
+<span class="source-line-no">858</span><span id="line-858"> * @return Matching BlockingServiceAndInterface pair</span>
+<span class="source-line-no">859</span><span id="line-859"> */</span>
+<span class="source-line-no">860</span><span id="line-860"> protected static BlockingServiceAndInterface getServiceAndInterface(</span>
+<span class="source-line-no">861</span><span id="line-861"> final List<BlockingServiceAndInterface> services, final String serviceName) {</span>
+<span class="source-line-no">862</span><span id="line-862"> for (BlockingServiceAndInterface bs : services) {</span>
+<span class="source-line-no">863</span><span id="line-863"> if (bs.getBlockingService().getDescriptorForType().getName().equals(serviceName)) {</span>
+<span class="source-line-no">864</span><span id="line-864"> return bs;</span>
+<span class="source-line-no">865</span><span id="line-865"> }</span>
+<span class="source-line-no">866</span><span id="line-866"> }</span>
+<span class="source-line-no">867</span><span id="line-867"> return null;</span>
+<span class="source-line-no">868</span><span id="line-868"> }</span>
+<span class="source-line-no">869</span><span id="line-869"></span>
+<span class="source-line-no">870</span><span id="line-870"> /**</span>
+<span class="source-line-no">871</span><span id="line-871"> * @param serviceName Some arbitrary string that represents a 'service'.</span>
+<span class="source-line-no">872</span><span id="line-872"> * @param services Available services and their service interfaces.</span>
+<span class="source-line-no">873</span><span id="line-873"> * @return Service interface class for <code>serviceName</code></span>
+<span class="source-line-no">874</span><span id="line-874"> */</span>
+<span class="source-line-no">875</span><span id="line-875"> protected static Class<?> getServiceInterface(final List<BlockingServiceAndInterface> services,</span>
+<span class="source-line-no">876</span><span id="line-876"> final String serviceName) {</span>
+<span class="source-line-no">877</span><span id="line-877"> BlockingServiceAndInterface bsasi = getServiceAndInterface(services, serviceName);</span>
+<span class="source-line-no">878</span><span id="line-878"> return bsasi == null ? null : bsasi.getServiceInterface();</span>
+<span class="source-line-no">879</span><span id="line-879"> }</span>
+<span class="source-line-no">880</span><span id="line-880"></span>
+<span class="source-line-no">881</span><span id="line-881"> /**</span>
+<span class="source-line-no">882</span><span id="line-882"> * @param serviceName Some arbitrary string that represents a 'service'.</span>
+<span class="source-line-no">883</span><span id="line-883"> * @param services Available services and their service interfaces.</span>
+<span class="source-line-no">884</span><span id="line-884"> * @return BlockingService that goes with the passed <code>serviceName</code></span>
+<span class="source-line-no">885</span><span id="line-885"> */</span>
+<span class="source-line-no">886</span><span id="line-886"> protected static BlockingService getService(final List<BlockingServiceAndInterface> services,</span>
+<span class="source-line-no">887</span><span id="line-887"> final String serviceName) {</span>
+<span class="source-line-no">888</span><span id="line-888"> BlockingServiceAndInterface bsasi = getServiceAndInterface(services, serviceName);</span>
+<span class="source-line-no">889</span><span id="line-889"> return bsasi == null ? null : bsasi.getBlockingService();</span>
+<span class="source-line-no">890</span><span id="line-890"> }</span>
+<span class="source-line-no">891</span><span id="line-891"></span>
+<span class="source-line-no">892</span><span id="line-892"> protected static MonitoredRPCHandler getStatus() {</span>
+<span class="source-line-no">893</span><span id="line-893"> // It is ugly the way we park status up in RpcServer. Let it be for now. TODO.</span>
+<span class="source-line-no">894</span><span id="line-894"> MonitoredRPCHandler status = RpcServer.MONITORED_RPC.get();</span>
+<span class="source-line-no">895</span><span id="line-895"> if (status != null) {</span>
+<span class="source-line-no">896</span><span id="line-896"> return status;</span>
+<span class="source-line-no">897</span><span id="line-897"> }</span>
+<span class="source-line-no">898</span><span id="line-898"> status = TaskMonitor.get().createRPCStatus(Thread.currentThread().getName());</span>
+<span class="source-line-no">899</span><span id="line-899"> status.pause("Waiting for a call");</span>
+<span class="source-line-no">900</span><span id="line-900"> RpcServer.MONITORED_RPC.set(status);</span>
+<span class="source-line-no">901</span><span id="line-901"> return status;</span>
+<span class="source-line-no">902</span><span id="line-902"> }</span>
+<span class="source-line-no">903</span><span id="line-903"></span>
+<span class="source-line-no">904</span><span id="line-904"> /**</span>
+<span class="source-line-no">905</span><span id="line-905"> * Returns the remote side ip address when invoked inside an RPC Returns null incase of an error.</span>
+<span class="source-line-no">906</span><span id="line-906"> */</span>
+<span class="source-line-no">907</span><span id="line-907"> public static InetAddress getRemoteIp() {</span>
+<span class="source-line-no">908</span><span id="line-908"> RpcCall call = CurCall.get();</span>
+<span class="source-line-no">909</span><span id="line-909"> if (call != null) {</span>
+<span class="source-line-no">910</span><span id="line-910"> return call.getRemoteAddress();</span>
+<span class="source-line-no">911</span><span id="line-911"> }</span>
+<span class="source-line-no">912</span><span id="line-912"> return null;</span>
+<span class="source-line-no">913</span><span id="line-913"> }</span>
+<span class="source-line-no">914</span><span id="line-914"></span>
+<span class="source-line-no">915</span><span id="line-915"> @Override</span>
+<span class="source-line-no">916</span><span id="line-916"> public RpcScheduler getScheduler() {</span>
+<span class="source-line-no">917</span><span id="line-917"> return scheduler;</span>
+<span class="source-line-no">918</span><span id="line-918"> }</span>
+<span class="source-line-no">919</span><span id="line-919"></span>
+<span class="source-line-no">920</span><span id="line-920"> @Override</span>
+<span class="source-line-no">921</span><span id="line-921"> public ByteBuffAllocator getByteBuffAllocator() {</span>
+<span class="source-line-no">922</span><span id="line-922"> return this.bbAllocator;</span>
+<span class="source-line-no">923</span><span id="line-923"> }</span>
+<span class="source-line-no">924</span><span id="line-924"></span>
+<span class="source-line-no">925</span><span id="line-925"> @Override</span>
+<span class="source-line-no">926</span><span id="line-926"> public void setRsRpcServices(RSRpcServices rsRpcServices) {</span>
+<span class="source-line-no">927</span><span id="line-927"> this.rsRpcServices = rsRpcServices;</span>
+<span class="source-line-no">928</span><span id="line-928"> }</span>
+<span class="source-line-no">929</span><span id="line-929"></span>
+<span class="source-line-no">930</span><span id="line-930"> @Override</span>
+<span class="source-line-no">931</span><span id="line-931"> public void setNamedQueueRecorder(NamedQueueRecorder namedQueueRecorder) {</span>
+<span class="source-line-no">932</span><span id="line-932"> this.namedQueueRecorder = namedQueueRecorder;</span>
+<span class="source-line-no">933</span><span id="line-933"> }</span>
+<span class="source-line-no">934</span><span id="line-934"></span>
+<span class="source-line-no">935</span><span id="line-935"> protected boolean needAuthorization() {</span>
+<span class="source-line-no">936</span><span id="line-936"> return authorize;</span>
+<span class="source-line-no">937</span><span id="line-937"> }</span>
+<span class="source-line-no">938</span><span id="line-938"></span>
+<span class="source-line-no">939</span><span id="line-939"> @RestrictedApi(explanation = "Should only be called in tests", link = "",</span>
+<span class="source-line-no">940</span><span id="line-940"> allowedOnPath = ".*/src/test/.*")</span>
+<span class="source-line-no">941</span><span id="line-941"> public List<BlockingServiceAndInterface> getServices() {</span>
+<span class="source-line-no">942</span><span id="line-942"> return services;</span>
+<span class="source-line-no">943</span><span id="line-943"> }</span>
+<span class="source-line-no">944</span><span id="line-944"></span>
+<span class="source-line-no">945</span><span id="line-945"> private void initializeCoprocessorHost(Configuration conf) {</span>
+<span class="source-line-no">946</span><span id="line-946"> this.cpHost = new RpcCoprocessorHost(conf);</span>
+<span class="source-line-no">947</span><span id="line-947"> }</span>
+<span class="source-line-no">948</span><span id="line-948"></span>
+<span class="source-line-no">949</span><span id="line-949"> @Override</span>
+<span class="source-line-no">950</span><span id="line-950"> public RpcCoprocessorHost getRpcCoprocessorHost() {</span>
+<span class="source-line-no">951</span><span id="line-951"> return cpHost;</span>
+<span class="source-line-no">952</span><span id="line-952"> }</span>
+<span class="source-line-no">953</span><span id="line-953">}</span>
diff --git a/apidocs/src-html/org/apache/hadoop/hbase/ipc/RpcServer.CallCleanup.html b/apidocs/src-html/org/apache/hadoop/hbase/ipc/RpcServer.CallCleanup.html
index 9c08cc84ce8..76832ab3ed3 100644
--- a/apidocs/src-html/org/apache/hadoop/hbase/ipc/RpcServer.CallCleanup.html
+++ b/apidocs/src-html/org/apache/hadoop/hbase/ipc/RpcServer.CallCleanup.html
@@ -848,104 +848,122 @@
<span class="source-line-no">835</span><span id="line-835"> }</span>
<span class="source-line-no">836</span><span id="line-836"></span>
<span class="source-line-no">837</span><span id="line-837"> /**</span>
-<span class="source-line-no">838</span><span id="line-838"> * @param serviceName Some arbitrary string that represents a 'service'.</span>
-<span class="source-line-no">839</span><span id="line-839"> * @param services Available service instances</span>
-<span class="source-line-no">840</span><span id="line-840"> * @return Matching BlockingServiceAndInterface pair</span>
-<span class="source-line-no">841</span><span id="line-841"> */</span>
-<span class="source-line-no">842</span><span id="line-842"> protected static BlockingServiceAndInterface getServiceAndInterface(</span>
-<span class="source-line-no">843</span><span id="line-843"> final List<BlockingServiceAndInterface> services, final String serviceName) {</span>
-<span class="source-line-no">844</span><span id="line-844"> for (BlockingServiceAndInterface bs : services) {</span>
-<span class="source-line-no">845</span><span id="line-845"> if (bs.getBlockingService().getDescriptorForType().getName().equals(serviceName)) {</span>
-<span class="source-line-no">846</span><span id="line-846"> return bs;</span>
-<span class="source-line-no">847</span><span id="line-847"> }</span>
-<span class="source-line-no">848</span><span id="line-848"> }</span>
-<span class="source-line-no">849</span><span id="line-849"> return null;</span>
-<span class="source-line-no">850</span><span id="line-850"> }</span>
-<span class="source-line-no">851</span><span id="line-851"></span>
-<span class="source-line-no">852</span><span id="line-852"> /**</span>
-<span class="source-line-no">853</span><span id="line-853"> * @param serviceName Some arbitrary string that represents a 'service'.</span>
-<span class="source-line-no">854</span><span id="line-854"> * @param services Available services and their service interfaces.</span>
-<span class="source-line-no">855</span><span id="line-855"> * @return Service interface class for <code>serviceName</code></span>
-<span class="source-line-no">856</span><span id="line-856"> */</span>
-<span class="source-line-no">857</span><span id="line-857"> protected static Class<?> getServiceInterface(final List<BlockingServiceAndInterface> services,</span>
-<span class="source-line-no">858</span><span id="line-858"> final String serviceName) {</span>
-<span class="source-line-no">859</span><span id="line-859"> BlockingServiceAndInterface bsasi = getServiceAndInterface(services, serviceName);</span>
-<span class="source-line-no">860</span><span id="line-860"> return bsasi == null ? null : bsasi.getServiceInterface();</span>
-<span class="source-line-no">861</span><span id="line-861"> }</span>
-<span class="source-line-no">862</span><span id="line-862"></span>
-<span class="source-line-no">863</span><span id="line-863"> /**</span>
-<span class="source-line-no">864</span><span id="line-864"> * @param serviceName Some arbitrary string that represents a 'service'.</span>
-<span class="source-line-no">865</span><span id="line-865"> * @param services Available services and their service interfaces.</span>
-<span class="source-line-no">866</span><span id="line-866"> * @return BlockingService that goes with the passed <code>serviceName</code></span>
-<span class="source-line-no">867</span><span id="line-867"> */</span>
-<span class="source-line-no">868</span><span id="line-868"> protected static BlockingService getService(final List<BlockingServiceAndInterface> services,</span>
-<span class="source-line-no">869</span><span id="line-869"> final String serviceName) {</span>
-<span class="source-line-no">870</span><span id="line-870"> BlockingServiceAndInterface bsasi = getServiceAndInterface(services, serviceName);</span>
-<span class="source-line-no">871</span><span id="line-871"> return bsasi == null ? null : bsasi.getBlockingService();</span>
-<span class="source-line-no">872</span><span id="line-872"> }</span>
-<span class="source-line-no">873</span><span id="line-873"></span>
-<span class="source-line-no">874</span><span id="line-874"> protected static MonitoredRPCHandler getStatus() {</span>
-<span class="source-line-no">875</span><span id="line-875"> // It is ugly the way we park status up in RpcServer. Let it be for now. TODO.</span>
-<span class="source-line-no">876</span><span id="line-876"> MonitoredRPCHandler status = RpcServer.MONITORED_RPC.get();</span>
-<span class="source-line-no">877</span><span id="line-877"> if (status != null) {</span>
-<span class="source-line-no">878</span><span id="line-878"> return status;</span>
-<span class="source-line-no">879</span><span id="line-879"> }</span>
-<span class="source-line-no">880</span><span id="line-880"> status = TaskMonitor.get().createRPCStatus(Thread.currentThread().getName());</span>
-<span class="source-line-no">881</span><span id="line-881"> status.pause("Waiting for a call");</span>
-<span class="source-line-no">882</span><span id="line-882"> RpcServer.MONITORED_RPC.set(status);</span>
-<span class="source-line-no">883</span><span id="line-883"> return status;</span>
-<span class="source-line-no">884</span><span id="line-884"> }</span>
-<span class="source-line-no">885</span><span id="line-885"></span>
-<span class="source-line-no">886</span><span id="line-886"> /**</span>
-<span class="source-line-no">887</span><span id="line-887"> * Returns the remote side ip address when invoked inside an RPC Returns null incase of an error.</span>
-<span class="source-line-no">888</span><span id="line-888"> */</span>
-<span class="source-line-no">889</span><span id="line-889"> public static InetAddress getRemoteIp() {</span>
-<span class="source-line-no">890</span><span id="line-890"> RpcCall call = CurCall.get();</span>
-<span class="source-line-no">891</span><span id="line-891"> if (call != null) {</span>
-<span class="source-line-no">892</span><span id="line-892"> return call.getRemoteAddress();</span>
-<span class="source-line-no">893</span><span id="line-893"> }</span>
-<span class="source-line-no">894</span><span id="line-894"> return null;</span>
-<span class="source-line-no">895</span><span id="line-895"> }</span>
-<span class="source-line-no">896</span><span id="line-896"></span>
-<span class="source-line-no">897</span><span id="line-897"> @Override</span>
-<span class="source-line-no">898</span><span id="line-898"> public RpcScheduler getScheduler() {</span>
-<span class="source-line-no">899</span><span id="line-899"> return scheduler;</span>
-<span class="source-line-no">900</span><span id="line-900"> }</span>
-<span class="source-line-no">901</span><span id="line-901"></span>
-<span class="source-line-no">902</span><span id="line-902"> @Override</span>
-<span class="source-line-no">903</span><span id="line-903"> public ByteBuffAllocator getByteBuffAllocator() {</span>
-<span class="source-line-no">904</span><span id="line-904"> return this.bbAllocator;</span>
-<span class="source-line-no">905</span><span id="line-905"> }</span>
-<span class="source-line-no">906</span><span id="line-906"></span>
-<span class="source-line-no">907</span><span id="line-907"> @Override</span>
-<span class="source-line-no">908</span><span id="line-908"> public void setRsRpcServices(RSRpcServices rsRpcServices) {</span>
-<span class="source-line-no">909</span><span id="line-909"> this.rsRpcServices = rsRpcServices;</span>
-<span class="source-line-no">910</span><span id="line-910"> }</span>
-<span class="source-line-no">911</span><span id="line-911"></span>
-<span class="source-line-no">912</span><span id="line-912"> @Override</span>
-<span class="source-line-no">913</span><span id="line-913"> public void setNamedQueueRecorder(NamedQueueRecorder namedQueueRecorder) {</span>
-<span class="source-line-no">914</span><span id="line-914"> this.namedQueueRecorder = namedQueueRecorder;</span>
-<span class="source-line-no">915</span><span id="line-915"> }</span>
-<span class="source-line-no">916</span><span id="line-916"></span>
-<span class="source-line-no">917</span><span id="line-917"> protected boolean needAuthorization() {</span>
-<span class="source-line-no">918</span><span id="line-918"> return authorize;</span>
-<span class="source-line-no">919</span><span id="line-919"> }</span>
-<span class="source-line-no">920</span><span id="line-920"></span>
-<span class="source-line-no">921</span><span id="line-921"> @RestrictedApi(explanation = "Should only be called in tests", link = "",</span>
-<span class="source-line-no">922</span><span id="line-922"> allowedOnPath = ".*/src/test/.*")</span>
-<span class="source-line-no">923</span><span id="line-923"> public List<BlockingServiceAndInterface> getServices() {</span>
-<span class="source-line-no">924</span><span id="line-924"> return services;</span>
-<span class="source-line-no">925</span><span id="line-925"> }</span>
-<span class="source-line-no">926</span><span id="line-926"></span>
-<span class="source-line-no">927</span><span id="line-927"> private void initializeCoprocessorHost(Configuration conf) {</span>
-<span class="source-line-no">928</span><span id="line-928"> this.cpHost = new RpcCoprocessorHost(conf);</span>
-<span class="source-line-no">929</span><span id="line-929"> }</span>
-<span class="source-line-no">930</span><span id="line-930"></span>
-<span class="source-line-no">931</span><span id="line-931"> @Override</span>
-<span class="source-line-no">932</span><span id="line-932"> public RpcCoprocessorHost getRpcCoprocessorHost() {</span>
-<span class="source-line-no">933</span><span id="line-933"> return cpHost;</span>
-<span class="source-line-no">934</span><span id="line-934"> }</span>
-<span class="source-line-no">935</span><span id="line-935">}</span>
+<span class="source-line-no">838</span><span id="line-838"> * Returns the ServerRpcConnection for the current RPC request or not present if no connection is</span>
+<span class="source-line-no">839</span><span id="line-839"> * available. This allows access to connection-level information such as the client's IP address,</span>
+<span class="source-line-no">840</span><span id="line-840"> * authentication details, codec configuration, etc.</span>
+<span class="source-line-no">841</span><span id="line-841"> * <p></span>
+<span class="source-line-no">842</span><span id="line-842"> * This method should only be called from within an RPC handler thread context.</span>
+<span class="source-line-no">843</span><span id="line-843"> * @return the current ServerRpcConnection, or Optional.empty() if called outside of an RPC</span>
+<span class="source-line-no">844</span><span id="line-844"> * context</span>
+<span class="source-line-no">845</span><span id="line-845"> */</span>
+<span class="source-line-no">846</span><span id="line-846"> public static Optional<ServerRpcConnection> getCurrentServerRpcConnection() {</span>
+<span class="source-line-no">847</span><span id="line-847"> Optional<RpcCall> call = getCurrentCall();</span>
+<span class="source-line-no">848</span><span id="line-848"> if (call.isPresent() && call.get() instanceof ServerCall) {</span>
+<span class="source-line-no">849</span><span id="line-849"> ServerCall<?> serverCall = (ServerCall<?>) call.get();</span>
+<span class="source-line-no">850</span><span id="line-850"> return Optional.ofNullable(serverCall.getConnection());</span>
+<span class="source-line-no">851</span><span id="line-851"> }</span>
+<span class="source-line-no">852</span><span id="line-852"> return Optional.empty();</span>
+<span class="source-line-no">853</span><span id="line-853"> }</span>
+<span class="source-line-no">854</span><span id="line-854"></span>
+<span class="source-line-no">855</span><span id="line-855"> /**</span>
+<span class="source-line-no">856</span><span id="line-856"> * @param serviceName Some arbitrary string that represents a 'service'.</span>
+<span class="source-line-no">857</span><span id="line-857"> * @param services Available service instances</span>
+<span class="source-line-no">858</span><span id="line-858"> * @return Matching BlockingServiceAndInterface pair</span>
+<span class="source-line-no">859</span><span id="line-859"> */</span>
+<span class="source-line-no">860</span><span id="line-860"> protected static BlockingServiceAndInterface getServiceAndInterface(</span>
+<span class="source-line-no">861</span><span id="line-861"> final List<BlockingServiceAndInterface> services, final String serviceName) {</span>
+<span class="source-line-no">862</span><span id="line-862"> for (BlockingServiceAndInterface bs : services) {</span>
+<span class="source-line-no">863</span><span id="line-863"> if (bs.getBlockingService().getDescriptorForType().getName().equals(serviceName)) {</span>
+<span class="source-line-no">864</span><span id="line-864"> return bs;</span>
+<span class="source-line-no">865</span><span id="line-865"> }</span>
+<span class="source-line-no">866</span><span id="line-866"> }</span>
+<span class="source-line-no">867</span><span id="line-867"> return null;</span>
+<span class="source-line-no">868</span><span id="line-868"> }</span>
+<span class="source-line-no">869</span><span id="line-869"></span>
+<span class="source-line-no">870</span><span id="line-870"> /**</span>
+<span class="source-line-no">871</span><span id="line-871"> * @param serviceName Some arbitrary string that represents a 'service'.</span>
+<span class="source-line-no">872</span><span id="line-872"> * @param services Available services and their service interfaces.</span>
+<span class="source-line-no">873</span><span id="line-873"> * @return Service interface class for <code>serviceName</code></span>
+<span class="source-line-no">874</span><span id="line-874"> */</span>
+<span class="source-line-no">875</span><span id="line-875"> protected static Class<?> getServiceInterface(final List<BlockingServiceAndInterface> services,</span>
+<span class="source-line-no">876</span><span id="line-876"> final String serviceName) {</span>
+<span class="source-line-no">877</span><span id="line-877"> BlockingServiceAndInterface bsasi = getServiceAndInterface(services, serviceName);</span>
+<span class="source-line-no">878</span><span id="line-878"> return bsasi == null ? null : bsasi.getServiceInterface();</span>
+<span class="source-line-no">879</span><span id="line-879"> }</span>
+<span class="source-line-no">880</span><span id="line-880"></span>
+<span class="source-line-no">881</span><span id="line-881"> /**</span>
+<span class="source-line-no">882</span><span id="line-882"> * @param serviceName Some arbitrary string that represents a 'service'.</span>
+<span class="source-line-no">883</span><span id="line-883"> * @param services Available services and their service interfaces.</span>
+<span class="source-line-no">884</span><span id="line-884"> * @return BlockingService that goes with the passed <code>serviceName</code></span>
+<span class="source-line-no">885</span><span id="line-885"> */</span>
+<span class="source-line-no">886</span><span id="line-886"> protected static BlockingService getService(final List<BlockingServiceAndInterface> services,</span>
+<span class="source-line-no">887</span><span id="line-887"> final String serviceName) {</span>
+<span class="source-line-no">888</span><span id="line-888"> BlockingServiceAndInterface bsasi = getServiceAndInterface(services, serviceName);</span>
+<span class="source-line-no">889</span><span id="line-889"> return bsasi == null ? null : bsasi.getBlockingService();</span>
+<span class="source-line-no">890</span><span id="line-890"> }</span>
+<span class="source-line-no">891</span><span id="line-891"></span>
+<span class="source-line-no">892</span><span id="line-892"> protected static MonitoredRPCHandler getStatus() {</span>
+<span class="source-line-no">893</span><span id="line-893"> // It is ugly the way we park status up in RpcServer. Let it be for now. TODO.</span>
+<span class="source-line-no">894</span><span id="line-894"> MonitoredRPCHandler status = RpcServer.MONITORED_RPC.get();</span>
+<span class="source-line-no">895</span><span id="line-895"> if (status != null) {</span>
+<span class="source-line-no">896</span><span id="line-896"> return status;</span>
+<span class="source-line-no">897</span><span id="line-897"> }</span>
+<span class="source-line-no">898</span><span id="line-898"> status = TaskMonitor.get().createRPCStatus(Thread.currentThread().getName());</span>
+<span class="source-line-no">899</span><span id="line-899"> status.pause("Waiting for a call");</span>
+<span class="source-line-no">900</span><span id="line-900"> RpcServer.MONITORED_RPC.set(status);</span>
+<span class="source-line-no">901</span><span id="line-901"> return status;</span>
+<span class="source-line-no">902</span><span id="line-902"> }</span>
+<span class="source-line-no">903</span><span id="line-903"></span>
+<span class="source-line-no">904</span><span id="line-904"> /**</span>
+<span class="source-line-no">905</span><span id="line-905"> * Returns the remote side ip address when invoked inside an RPC Returns null incase of an error.</span>
+<span class="source-line-no">906</span><span id="line-906"> */</span>
+<span class="source-line-no">907</span><span id="line-907"> public static InetAddress getRemoteIp() {</span>
+<span class="source-line-no">908</span><span id="line-908"> RpcCall call = CurCall.get();</span>
+<span class="source-line-no">909</span><span id="line-909"> if (call != null) {</span>
+<span class="source-line-no">910</span><span id="line-910"> return call.getRemoteAddress();</span>
+<span class="source-line-no">911</span><span id="line-911"> }</span>
+<span class="source-line-no">912</span><span id="line-912"> return null;</span>
+<span class="source-line-no">913</span><span id="line-913"> }</span>
+<span class="source-line-no">914</span><span id="line-914"></span>
+<span class="source-line-no">915</span><span id="line-915"> @Override</span>
+<span class="source-line-no">916</span><span id="line-916"> public RpcScheduler getScheduler() {</span>
+<span class="source-line-no">917</span><span id="line-917"> return scheduler;</span>
+<span class="source-line-no">918</span><span id="line-918"> }</span>
+<span class="source-line-no">919</span><span id="line-919"></span>
+<span class="source-line-no">920</span><span id="line-920"> @Override</span>
+<span class="source-line-no">921</span><span id="line-921"> public ByteBuffAllocator getByteBuffAllocator() {</span>
+<span class="source-line-no">922</span><span id="line-922"> return this.bbAllocator;</span>
+<span class="source-line-no">923</span><span id="line-923"> }</span>
+<span class="source-line-no">924</span><span id="line-924"></span>
+<span class="source-line-no">925</span><span id="line-925"> @Override</span>
+<span class="source-line-no">926</span><span id="line-926"> public void setRsRpcServices(RSRpcServices rsRpcServices) {</span>
+<span class="source-line-no">927</span><span id="line-927"> this.rsRpcServices = rsRpcServices;</span>
+<span class="source-line-no">928</span><span id="line-928"> }</span>
+<span class="source-line-no">929</span><span id="line-929"></span>
+<span class="source-line-no">930</span><span id="line-930"> @Override</span>
+<span class="source-line-no">931</span><span id="line-931"> public void setNamedQueueRecorder(NamedQueueRecorder namedQueueRecorder) {</span>
+<span class="source-line-no">932</span><span id="line-932"> this.namedQueueRecorder = namedQueueRecorder;</span>
+<span class="source-line-no">933</span><span id="line-933"> }</span>
+<span class="source-line-no">934</span><span id="line-934"></span>
+<span class="source-line-no">935</span><span id="line-935"> protected boolean needAuthorization() {</span>
+<span class="source-line-no">936</span><span id="line-936"> return authorize;</span>
+<span class="source-line-no">937</span><span id="line-937"> }</span>
+<span class="source-line-no">938</span><span id="line-938"></span>
+<span class="source-line-no">939</span><span id="line-939"> @RestrictedApi(explanation = "Should only be called in tests", link = "",</span>
+<span class="source-line-no">940</span><span id="line-940"> allowedOnPath = ".*/src/test/.*")</span>
+<span class="source-line-no">941</span><span id="line-941"> public List<BlockingServiceAndInterface> getServices() {</span>
+<span class="source-line-no">942</span><span id="line-942"> return services;</span>
+<span class="source-line-no">943</span><span id="line-943"> }</span>
+<span class="source-line-no">944</span><span id="line-944"></span>
+<span class="source-line-no">945</span><span id="line-945"> private void initializeCoprocessorHost(Configuration conf) {</span>
+<span class="source-line-no">946</span><span id="line-946"> this.cpHost = new RpcCoprocessorHost(conf);</span>
+<span class="source-line-no">947</span><span id="line-947"> }</span>
+<span class="source-line-no">948</span><span id="line-948"></span>
+<span class="source-line-no">949</span><span id="line-949"> @Override</span>
+<span class="source-line-no">950</span><span id="line-950"> public RpcCoprocessorHost getRpcCoprocessorHost() {</span>
+<span class="source-line-no">951</span><span id="line-951"> return cpHost;</span>
+<span class="source-line-no">952</span><span id="line-952"> }</span>
+<span class="source-line-no">953</span><span id="line-953">}</span>
diff --git a/apidocs/src-html/org/apache/hadoop/hbase/ipc/RpcServer.html b/apidocs/src-html/org/apache/hadoop/hbase/ipc/RpcServer.html
index b84b9718c5e..5f499ad8434 100644
--- a/apidocs/src-html/org/apache/hadoop/hbase/ipc/RpcServer.html
+++ b/apidocs/src-html/org/apache/hadoop/hbase/ipc/RpcServer.html
@@ -848,104 +848,122 @@
<span class="source-line-no">835</span><span id="line-835"> }</span>
<span class="source-line-no">836</span><span id="line-836"></span>
<span class="source-line-no">837</span><span id="line-837"> /**</span>
-<span class="source-line-no">838</span><span id="line-838"> * @param serviceName Some arbitrary string that represents a 'service'.</span>
-<span class="source-line-no">839</span><span id="line-839"> * @param services Available service instances</span>
-<span class="source-line-no">840</span><span id="line-840"> * @return Matching BlockingServiceAndInterface pair</span>
-<span class="source-line-no">841</span><span id="line-841"> */</span>
-<span class="source-line-no">842</span><span id="line-842"> protected static BlockingServiceAndInterface getServiceAndInterface(</span>
-<span class="source-line-no">843</span><span id="line-843"> final List<BlockingServiceAndInterface> services, final String serviceName) {</span>
-<span class="source-line-no">844</span><span id="line-844"> for (BlockingServiceAndInterface bs : services) {</span>
-<span class="source-line-no">845</span><span id="line-845"> if (bs.getBlockingService().getDescriptorForType().getName().equals(serviceName)) {</span>
-<span class="source-line-no">846</span><span id="line-846"> return bs;</span>
-<span class="source-line-no">847</span><span id="line-847"> }</span>
-<span class="source-line-no">848</span><span id="line-848"> }</span>
-<span class="source-line-no">849</span><span id="line-849"> return null;</span>
-<span class="source-line-no">850</span><span id="line-850"> }</span>
-<span class="source-line-no">851</span><span id="line-851"></span>
-<span class="source-line-no">852</span><span id="line-852"> /**</span>
-<span class="source-line-no">853</span><span id="line-853"> * @param serviceName Some arbitrary string that represents a 'service'.</span>
-<span class="source-line-no">854</span><span id="line-854"> * @param services Available services and their service interfaces.</span>
-<span class="source-line-no">855</span><span id="line-855"> * @return Service interface class for <code>serviceName</code></span>
-<span class="source-line-no">856</span><span id="line-856"> */</span>
-<span class="source-line-no">857</span><span id="line-857"> protected static Class<?> getServiceInterface(final List<BlockingServiceAndInterface> services,</span>
-<span class="source-line-no">858</span><span id="line-858"> final String serviceName) {</span>
-<span class="source-line-no">859</span><span id="line-859"> BlockingServiceAndInterface bsasi = getServiceAndInterface(services, serviceName);</span>
-<span class="source-line-no">860</span><span id="line-860"> return bsasi == null ? null : bsasi.getServiceInterface();</span>
-<span class="source-line-no">861</span><span id="line-861"> }</span>
-<span class="source-line-no">862</span><span id="line-862"></span>
-<span class="source-line-no">863</span><span id="line-863"> /**</span>
-<span class="source-line-no">864</span><span id="line-864"> * @param serviceName Some arbitrary string that represents a 'service'.</span>
-<span class="source-line-no">865</span><span id="line-865"> * @param services Available services and their service interfaces.</span>
-<span class="source-line-no">866</span><span id="line-866"> * @return BlockingService that goes with the passed <code>serviceName</code></span>
-<span class="source-line-no">867</span><span id="line-867"> */</span>
-<span class="source-line-no">868</span><span id="line-868"> protected static BlockingService getService(final List<BlockingServiceAndInterface> services,</span>
-<span class="source-line-no">869</span><span id="line-869"> final String serviceName) {</span>
-<span class="source-line-no">870</span><span id="line-870"> BlockingServiceAndInterface bsasi = getServiceAndInterface(services, serviceName);</span>
-<span class="source-line-no">871</span><span id="line-871"> return bsasi == null ? null : bsasi.getBlockingService();</span>
-<span class="source-line-no">872</span><span id="line-872"> }</span>
-<span class="source-line-no">873</span><span id="line-873"></span>
-<span class="source-line-no">874</span><span id="line-874"> protected static MonitoredRPCHandler getStatus() {</span>
-<span class="source-line-no">875</span><span id="line-875"> // It is ugly the way we park status up in RpcServer. Let it be for now. TODO.</span>
-<span class="source-line-no">876</span><span id="line-876"> MonitoredRPCHandler status = RpcServer.MONITORED_RPC.get();</span>
-<span class="source-line-no">877</span><span id="line-877"> if (status != null) {</span>
-<span class="source-line-no">878</span><span id="line-878"> return status;</span>
-<span class="source-line-no">879</span><span id="line-879"> }</span>
-<span class="source-line-no">880</span><span id="line-880"> status = TaskMonitor.get().createRPCStatus(Thread.currentThread().getName());</span>
-<span class="source-line-no">881</span><span id="line-881"> status.pause("Waiting for a call");</span>
-<span class="source-line-no">882</span><span id="line-882"> RpcServer.MONITORED_RPC.set(status);</span>
-<span class="source-line-no">883</span><span id="line-883"> return status;</span>
-<span class="source-line-no">884</span><span id="line-884"> }</span>
-<span class="source-line-no">885</span><span id="line-885"></span>
-<span class="source-line-no">886</span><span id="line-886"> /**</span>
-<span class="source-line-no">887</span><span id="line-887"> * Returns the remote side ip address when invoked inside an RPC Returns null incase of an error.</span>
-<span class="source-line-no">888</span><span id="line-888"> */</span>
-<span class="source-line-no">889</span><span id="line-889"> public static InetAddress getRemoteIp() {</span>
-<span class="source-line-no">890</span><span id="line-890"> RpcCall call = CurCall.get();</span>
-<span class="source-line-no">891</span><span id="line-891"> if (call != null) {</span>
-<span class="source-line-no">892</span><span id="line-892"> return call.getRemoteAddress();</span>
-<span class="source-line-no">893</span><span id="line-893"> }</span>
-<span class="source-line-no">894</span><span id="line-894"> return null;</span>
-<span class="source-line-no">895</span><span id="line-895"> }</span>
-<span class="source-line-no">896</span><span id="line-896"></span>
-<span class="source-line-no">897</span><span id="line-897"> @Override</span>
-<span class="source-line-no">898</span><span id="line-898"> public RpcScheduler getScheduler() {</span>
-<span class="source-line-no">899</span><span id="line-899"> return scheduler;</span>
-<span class="source-line-no">900</span><span id="line-900"> }</span>
-<span class="source-line-no">901</span><span id="line-901"></span>
-<span class="source-line-no">902</span><span id="line-902"> @Override</span>
-<span class="source-line-no">903</span><span id="line-903"> public ByteBuffAllocator getByteBuffAllocator() {</span>
-<span class="source-line-no">904</span><span id="line-904"> return this.bbAllocator;</span>
-<span class="source-line-no">905</span><span id="line-905"> }</span>
-<span class="source-line-no">906</span><span id="line-906"></span>
-<span class="source-line-no">907</span><span id="line-907"> @Override</span>
-<span class="source-line-no">908</span><span id="line-908"> public void setRsRpcServices(RSRpcServices rsRpcServices) {</span>
-<span class="source-line-no">909</span><span id="line-909"> this.rsRpcServices = rsRpcServices;</span>
-<span class="source-line-no">910</span><span id="line-910"> }</span>
-<span class="source-line-no">911</span><span id="line-911"></span>
-<span class="source-line-no">912</span><span id="line-912"> @Override</span>
-<span class="source-line-no">913</span><span id="line-913"> public void setNamedQueueRecorder(NamedQueueRecorder namedQueueRecorder) {</span>
-<span class="source-line-no">914</span><span id="line-914"> this.namedQueueRecorder = namedQueueRecorder;</span>
-<span class="source-line-no">915</span><span id="line-915"> }</span>
-<span class="source-line-no">916</span><span id="line-916"></span>
-<span class="source-line-no">917</span><span id="line-917"> protected boolean needAuthorization() {</span>
-<span class="source-line-no">918</span><span id="line-918"> return authorize;</span>
-<span class="source-line-no">919</span><span id="line-919"> }</span>
-<span class="source-line-no">920</span><span id="line-920"></span>
-<span class="source-line-no">921</span><span id="line-921"> @RestrictedApi(explanation = "Should only be called in tests", link = "",</span>
-<span class="source-line-no">922</span><span id="line-922"> allowedOnPath = ".*/src/test/.*")</span>
-<span class="source-line-no">923</span><span id="line-923"> public List<BlockingServiceAndInterface> getServices() {</span>
-<span class="source-line-no">924</span><span id="line-924"> return services;</span>
-<span class="source-line-no">925</span><span id="line-925"> }</span>
-<span class="source-line-no">926</span><span id="line-926"></span>
-<span class="source-line-no">927</span><span id="line-927"> private void initializeCoprocessorHost(Configuration conf) {</span>
-<span class="source-line-no">928</span><span id="line-928"> this.cpHost = new RpcCoprocessorHost(conf);</span>
-<span class="source-line-no">929</span><span id="line-929"> }</span>
-<span class="source-line-no">930</span><span id="line-930"></span>
-<span class="source-line-no">931</span><span id="line-931"> @Override</span>
-<span class="source-line-no">932</span><span id="line-932"> public RpcCoprocessorHost getRpcCoprocessorHost() {</span>
-<span class="source-line-no">933</span><span id="line-933"> return cpHost;</span>
-<span class="source-line-no">934</span><span id="line-934"> }</span>
-<span class="source-line-no">935</span><span id="line-935">}</span>
+<span class="source-line-no">838</span><span id="line-838"> * Returns the ServerRpcConnection for the current RPC request or not present if no connection is</span>
+<span class="source-line-no">839</span><span id="line-839"> * available. This allows access to connection-level information such as the client's IP address,</span>
+<span class="source-line-no">840</span><span id="line-840"> * authentication details, codec configuration, etc.</span>
+<span class="source-line-no">841</span><span id="line-841"> * <p></span>
+<span class="source-line-no">842</span><span id="line-842"> * This method should only be called from within an RPC handler thread context.</span>
+<span class="source-line-no">843</span><span id="line-843"> * @return the current ServerRpcConnection, or Optional.empty() if called outside of an RPC</span>
+<span class="source-line-no">844</span><span id="line-844"> * context</span>
+<span class="source-line-no">845</span><span id="line-845"> */</span>
+<span class="source-line-no">846</span><span id="line-846"> public static Optional<ServerRpcConnection> getCurrentServerRpcConnection() {</span>
+<span class="source-line-no">847</span><span id="line-847"> Optional<RpcCall> call = getCurrentCall();</span>
+<span class="source-line-no">848</span><span id="line-848"> if (call.isPresent() && call.get() instanceof ServerCall) {</span>
+<span class="source-line-no">849</span><span id="line-849"> ServerCall<?> serverCall = (ServerCall<?>) call.get();</span>
+<span class="source-line-no">850</span><span id="line-850"> return Optional.ofNullable(serverCall.getConnection());</span>
+<span class="source-line-no">851</span><span id="line-851"> }</span>
+<span class="source-line-no">852</span><span id="line-852"> return Optional.empty();</span>
+<span class="source-line-no">853</span><span id="line-853"> }</span>
+<span class="source-line-no">854</span><span id="line-854"></span>
+<span class="source-line-no">855</span><span id="line-855"> /**</span>
+<span class="source-line-no">856</span><span id="line-856"> * @param serviceName Some arbitrary string that represents a 'service'.</span>
+<span class="source-line-no">857</span><span id="line-857"> * @param services Available service instances</span>
+<span class="source-line-no">858</span><span id="line-858"> * @return Matching BlockingServiceAndInterface pair</span>
+<span class="source-line-no">859</span><span id="line-859"> */</span>
+<span class="source-line-no">860</span><span id="line-860"> protected static BlockingServiceAndInterface getServiceAndInterface(</span>
+<span class="source-line-no">861</span><span id="line-861"> final List<BlockingServiceAndInterface> services, final String serviceName) {</span>
+<span class="source-line-no">862</span><span id="line-862"> for (BlockingServiceAndInterface bs : services) {</span>
+<span class="source-line-no">863</span><span id="line-863"> if (bs.getBlockingService().getDescriptorForType().getName().equals(serviceName)) {</span>
+<span class="source-line-no">864</span><span id="line-864"> return bs;</span>
+<span class="source-line-no">865</span><span id="line-865"> }</span>
+<span class="source-line-no">866</span><span id="line-866"> }</span>
+<span class="source-line-no">867</span><span id="line-867"> return null;</span>
+<span class="source-line-no">868</span><span id="line-868"> }</span>
+<span class="source-line-no">869</span><span id="line-869"></span>
+<span class="source-line-no">870</span><span id="line-870"> /**</span>
+<span class="source-line-no">871</span><span id="line-871"> * @param serviceName Some arbitrary string that represents a 'service'.</span>
+<span class="source-line-no">872</span><span id="line-872"> * @param services Available services and their service interfaces.</span>
+<span class="source-line-no">873</span><span id="line-873"> * @return Service interface class for <code>serviceName</code></span>
+<span class="source-line-no">874</span><span id="line-874"> */</span>
+<span class="source-line-no">875</span><span id="line-875"> protected static Class<?> getServiceInterface(final List<BlockingServiceAndInterface> services,</span>
+<span class="source-line-no">876</span><span id="line-876"> final String serviceName) {</span>
+<span class="source-line-no">877</span><span id="line-877"> BlockingServiceAndInterface bsasi = getServiceAndInterface(services, serviceName);</span>
+<span class="source-line-no">878</span><span id="line-878"> return bsasi == null ? null : bsasi.getServiceInterface();</span>
+<span class="source-line-no">879</span><span id="line-879"> }</span>
+<span class="source-line-no">880</span><span id="line-880"></span>
+<span class="source-line-no">881</span><span id="line-881"> /**</span>
+<span class="source-line-no">882</span><span id="line-882"> * @param serviceName Some arbitrary string that represents a 'service'.</span>
+<span class="source-line-no">883</span><span id="line-883"> * @param services Available services and their service interfaces.</span>
+<span class="source-line-no">884</span><span id="line-884"> * @return BlockingService that goes with the passed <code>serviceName</code></span>
+<span class="source-line-no">885</span><span id="line-885"> */</span>
+<span class="source-line-no">886</span><span id="line-886"> protected static BlockingService getService(final List<BlockingServiceAndInterface> services,</span>
+<span class="source-line-no">887</span><span id="line-887"> final String serviceName) {</span>
+<span class="source-line-no">888</span><span id="line-888"> BlockingServiceAndInterface bsasi = getServiceAndInterface(services, serviceName);</span>
+<span class="source-line-no">889</span><span id="line-889"> return bsasi == null ? null : bsasi.getBlockingService();</span>
+<span class="source-line-no">890</span><span id="line-890"> }</span>
+<span class="source-line-no">891</span><span id="line-891"></span>
+<span class="source-line-no">892</span><span id="line-892"> protected static MonitoredRPCHandler getStatus() {</span>
+<span class="source-line-no">893</span><span id="line-893"> // It is ugly the way we park status up in RpcServer. Let it be for now. TODO.</span>
+<span class="source-line-no">894</span><span id="line-894"> MonitoredRPCHandler status = RpcServer.MONITORED_RPC.get();</span>
+<span class="source-line-no">895</span><span id="line-895"> if (status != null) {</span>
+<span class="source-line-no">896</span><span id="line-896"> return status;</span>
+<span class="source-line-no">897</span><span id="line-897"> }</span>
+<span class="source-line-no">898</span><span id="line-898"> status = TaskMonitor.get().createRPCStatus(Thread.currentThread().getName());</span>
+<span class="source-line-no">899</span><span id="line-899"> status.pause("Waiting for a call");</span>
+<span class="source-line-no">900</span><span id="line-900"> RpcServer.MONITORED_RPC.set(status);</span>
+<span class="source-line-no">901</span><span id="line-901"> return status;</span>
+<span class="source-line-no">902</span><span id="line-902"> }</span>
+<span class="source-line-no">903</span><span id="line-903"></span>
+<span class="source-line-no">904</span><span id="line-904"> /**</span>
+<span class="source-line-no">905</span><span id="line-905"> * Returns the remote side ip address when invoked inside an RPC Returns null incase of an error.</span>
+<span class="source-line-no">906</span><span id="line-906"> */</span>
+<span class="source-line-no">907</span><span id="line-907"> public static InetAddress getRemoteIp() {</span>
+<span class="source-line-no">908</span><span id="line-908"> RpcCall call = CurCall.get();</span>
+<span class="source-line-no">909</span><span id="line-909"> if (call != null) {</span>
+<span class="source-line-no">910</span><span id="line-910"> return call.getRemoteAddress();</span>
+<span class="source-line-no">911</span><span id="line-911"> }</span>
+<span class="source-line-no">912</span><span id="line-912"> return null;</span>
+<span class="source-line-no">913</span><span id="line-913"> }</span>
+<span class="source-line-no">914</span><span id="line-914"></span>
+<span class="source-line-no">915</span><span id="line-915"> @Override</span>
+<span class="source-line-no">916</span><span id="line-916"> public RpcScheduler getScheduler() {</span>
+<span class="source-line-no">917</span><span id="line-917"> return scheduler;</span>
+<span class="source-line-no">918</span><span id="line-918"> }</span>
+<span class="source-line-no">919</span><span id="line-919"></span>
+<span class="source-line-no">920</span><span id="line-920"> @Override</span>
+<span class="source-line-no">921</span><span id="line-921"> public ByteBuffAllocator getByteBuffAllocator() {</span>
+<span class="source-line-no">922</span><span id="line-922"> return this.bbAllocator;</span>
+<span class="source-line-no">923</span><span id="line-923"> }</span>
+<span class="source-line-no">924</span><span id="line-924"></span>
+<span class="source-line-no">925</span><span id="line-925"> @Override</span>
+<span class="source-line-no">926</span><span id="line-926"> public void setRsRpcServices(RSRpcServices rsRpcServices) {</span>
+<span class="source-line-no">927</span><span id="line-927"> this.rsRpcServices = rsRpcServices;</span>
+<span class="source-line-no">928</span><span id="line-928"> }</span>
+<span class="source-line-no">929</span><span id="line-929"></span>
+<span class="source-line-no">930</span><span id="line-930"> @Override</span>
+<span class="source-line-no">931</span><span id="line-931"> public void setNamedQueueRecorder(NamedQueueRecorder namedQueueRecorder) {</span>
+<span class="source-line-no">932</span><span id="line-932"> this.namedQueueRecorder = namedQueueRecorder;</span>
+<span class="source-line-no">933</span><span id="line-933"> }</span>
+<span class="source-line-no">934</span><span id="line-934"></span>
+<span class="source-line-no">935</span><span id="line-935"> protected boolean needAuthorization() {</span>
+<span class="source-line-no">936</span><span id="line-936"> return authorize;</span>
+<span class="source-line-no">937</span><span id="line-937"> }</span>
+<span class="source-line-no">938</span><span id="line-938"></span>
+<span class="source-line-no">939</span><span id="line-939"> @RestrictedApi(explanation = "Should only be called in tests", link = "",</span>
+<span class="source-line-no">940</span><span id="line-940"> allowedOnPath = ".*/src/test/.*")</span>
+<span class="source-line-no">941</span><span id="line-941"> public List<BlockingServiceAndInterface> getServices() {</span>
+<span class="source-line-no">942</span><span id="line-942"> return services;</span>
+<span class="source-line-no">943</span><span id="line-943"> }</span>
+<span class="source-line-no">944</span><span id="line-944"></span>
+<span class="source-line-no">945</span><span id="line-945"> private void initializeCoprocessorHost(Configuration conf) {</span>
+<span class="source-line-no">946</span><span id="line-946"> this.cpHost = new RpcCoprocessorHost(conf);</span>
+<span class="source-line-no">947</span><span id="line-947"> }</span>
+<span class="source-line-no">948</span><span id="line-948"></span>
+<span class="source-line-no">949</span><span id="line-949"> @Override</span>
+<span class="source-line-no">950</span><span id="line-950"> public RpcCoprocessorHost getRpcCoprocessorHost() {</span>
+<span class="source-line-no">951</span><span id="line-951"> return cpHost;</span>
+<span class="source-line-no">952</span><span id="line-952"> }</span>
+<span class="source-line-no">953</span><span id="line-953">}</span>
diff --git a/apidocs/src-html/org/apache/hadoop/hbase/ipc/ServerCall.html b/apidocs/src-html/org/apache/hadoop/hbase/ipc/ServerCall.html
index d86f4281cfb..1d10d72262c 100644
--- a/apidocs/src-html/org/apache/hadoop/hbase/ipc/ServerCall.html
+++ b/apidocs/src-html/org/apache/hadoop/hbase/ipc/ServerCall.html
@@ -269,354 +269,362 @@
<span class="source-line-no">256</span><span id="line-256"> return this.header.getPriority();</span>
<span class="source-line-no">257</span><span id="line-257"> }</span>
<span class="source-line-no">258</span><span id="line-258"></span>
-<span class="source-line-no">259</span><span id="line-259"> /*</span>
-<span class="source-line-no">260</span><span id="line-260"> * Short string representation without param info because param itself could be huge depends on</span>
-<span class="source-line-no">261</span><span id="line-261"> * the payload of a command</span>
+<span class="source-line-no">259</span><span id="line-259"> /**</span>
+<span class="source-line-no">260</span><span id="line-260"> * Get the ServerRpcConnection associated with this call.</span>
+<span class="source-line-no">261</span><span id="line-261"> * @return the connection object</span>
<span class="source-line-no">262</span><span id="line-262"> */</span>
-<span class="source-line-no">263</span><span id="line-263"> @Override</span>
-<span class="source-line-no">264</span><span id="line-264"> public String toShortString() {</span>
-<span class="source-line-no">265</span><span id="line-265"> String serviceName = this.connection.service != null</span>
-<span class="source-line-no">266</span><span id="line-266"> ? this.connection.service.getDescriptorForType().getName()</span>
-<span class="source-line-no">267</span><span id="line-267"> : "null";</span>
-<span class="source-line-no">268</span><span id="line-268"> return "callId: " + this.id + " service: " + serviceName + " methodName: "</span>
-<span class="source-line-no">269</span><span id="line-269"> + ((this.md != null) ? this.md.getName() : "n/a") + " size: "</span>
-<span class="source-line-no">270</span><span id="line-270"> + StringUtils.TraditionalBinaryPrefix.long2String(this.size, "", 1) + " connection: "</span>
-<span class="source-line-no">271</span><span id="line-271"> + connection + " deadline: " + deadline;</span>
-<span class="source-line-no">272</span><span id="line-272"> }</span>
-<span class="source-line-no">273</span><span id="line-273"></span>
-<span class="source-line-no">274</span><span id="line-274"> @Override</span>
-<span class="source-line-no">275</span><span id="line-275"> public synchronized void setResponse(Message m, final ExtendedCellScanner cells, Throwable t,</span>
-<span class="source-line-no">276</span><span id="line-276"> String errorMsg) {</span>
-<span class="source-line-no">277</span><span id="line-277"> if (this.isError) {</span>
-<span class="source-line-no">278</span><span id="line-278"> return;</span>
-<span class="source-line-no">279</span><span id="line-279"> }</span>
-<span class="source-line-no">280</span><span id="line-280"> if (t != null) {</span>
-<span class="source-line-no">281</span><span id="line-281"> this.isError = true;</span>
-<span class="source-line-no">282</span><span id="line-282"> TraceUtil.setError(span, t);</span>
-<span class="source-line-no">283</span><span id="line-283"> } else {</span>
-<span class="source-line-no">284</span><span id="line-284"> span.setStatus(StatusCode.OK);</span>
-<span class="source-line-no">285</span><span id="line-285"> }</span>
-<span class="source-line-no">286</span><span id="line-286"> BufferChain bc = null;</span>
-<span class="source-line-no">287</span><span id="line-287"> try {</span>
-<span class="source-line-no">288</span><span id="line-288"> ResponseHeader.Builder headerBuilder = ResponseHeader.newBuilder();</span>
-<span class="source-line-no">289</span><span id="line-289"> // Call id.</span>
-<span class="source-line-no">290</span><span id="line-290"> headerBuilder.setCallId(this.id);</span>
-<span class="source-line-no">291</span><span id="line-291"> if (t != null) {</span>
-<span class="source-line-no">292</span><span id="line-292"> setExceptionResponse(t, errorMsg, headerBuilder);</span>
-<span class="source-line-no">293</span><span id="line-293"> }</span>
-<span class="source-line-no">294</span><span id="line-294"> // Pass reservoir to buildCellBlock. Keep reference to returne so can add it back to the</span>
-<span class="source-line-no">295</span><span id="line-295"> // reservoir when finished. This is hacky and the hack is not contained but benefits are</span>
-<span class="source-line-no">296</span><span id="line-296"> // high when we can avoid a big buffer allocation on each rpc.</span>
-<span class="source-line-no">297</span><span id="line-297"> List<ByteBuffer> cellBlock = null;</span>
-<span class="source-line-no">298</span><span id="line-298"> int cellBlockSize = 0;</span>
-<span class="source-line-no">299</span><span id="line-299"> if (bbAllocator.isReservoirEnabled()) {</span>
-<span class="source-line-no">300</span><span id="line-300"> this.cellBlockStream = this.cellBlockBuilder.buildCellBlockStream(this.connection.codec,</span>
-<span class="source-line-no">301</span><span id="line-301"> this.connection.compressionCodec, cells, bbAllocator);</span>
-<span class="source-line-no">302</span><span id="line-302"> if (this.cellBlockStream != null) {</span>
-<span class="source-line-no">303</span><span id="line-303"> cellBlock = this.cellBlockStream.getByteBuffers();</span>
-<span class="source-line-no">304</span><span id="line-304"> cellBlockSize = this.cellBlockStream.size();</span>
-<span class="source-line-no">305</span><span id="line-305"> }</span>
-<span class="source-line-no">306</span><span id="line-306"> } else {</span>
-<span class="source-line-no">307</span><span id="line-307"> ByteBuffer b = this.cellBlockBuilder.buildCellBlock(this.connection.codec,</span>
-<span class="source-line-no">308</span><span id="line-308"> this.connection.compressionCodec, cells);</span>
-<span class="source-line-no">309</span><span id="line-309"> if (b != null) {</span>
-<span class="source-line-no">310</span><span id="line-310"> cellBlockSize = b.remaining();</span>
-<span class="source-line-no">311</span><span id="line-311"> cellBlock = new ArrayList<>(1);</span>
-<span class="source-line-no">312</span><span id="line-312"> cellBlock.add(b);</span>
+<span class="source-line-no">263</span><span id="line-263"> public T getConnection() {</span>
+<span class="source-line-no">264</span><span id="line-264"> return this.connection;</span>
+<span class="source-line-no">265</span><span id="line-265"> }</span>
+<span class="source-line-no">266</span><span id="line-266"></span>
+<span class="source-line-no">267</span><span id="line-267"> /*</span>
+<span class="source-line-no">268</span><span id="line-268"> * Short string representation without param info because param itself could be huge depends on</span>
+<span class="source-line-no">269</span><span id="line-269"> * the payload of a command</span>
+<span class="source-line-no">270</span><span id="line-270"> */</span>
+<span class="source-line-no">271</span><span id="line-271"> @Override</span>
+<span class="source-line-no">272</span><span id="line-272"> public String toShortString() {</span>
+<span class="source-line-no">273</span><span id="line-273"> String serviceName = this.connection.service != null</span>
+<span class="source-line-no">274</span><span id="line-274"> ? this.connection.service.getDescriptorForType().getName()</span>
+<span class="source-line-no">275</span><span id="line-275"> : "null";</span>
+<span class="source-line-no">276</span><span id="line-276"> return "callId: " + this.id + " service: " + serviceName + " methodName: "</span>
+<span class="source-line-no">277</span><span id="line-277"> + ((this.md != null) ? this.md.getName() : "n/a") + " size: "</span>
+<span class="source-line-no">278</span><span id="line-278"> + StringUtils.TraditionalBinaryPrefix.long2String(this.size, "", 1) + " connection: "</span>
+<span class="source-line-no">279</span><span id="line-279"> + connection + " deadline: " + deadline;</span>
+<span class="source-line-no">280</span><span id="line-280"> }</span>
+<span class="source-line-no">281</span><span id="line-281"></span>
+<span class="source-line-no">282</span><span id="line-282"> @Override</span>
+<span class="source-line-no">283</span><span id="line-283"> public synchronized void setResponse(Message m, final ExtendedCellScanner cells, Throwable t,</span>
+<span class="source-line-no">284</span><span id="line-284"> String errorMsg) {</span>
+<span class="source-line-no">285</span><span id="line-285"> if (this.isError) {</span>
+<span class="source-line-no">286</span><span id="line-286"> return;</span>
+<span class="source-line-no">287</span><span id="line-287"> }</span>
+<span class="source-line-no">288</span><span id="line-288"> if (t != null) {</span>
+<span class="source-line-no">289</span><span id="line-289"> this.isError = true;</span>
+<span class="source-line-no">290</span><span id="line-290"> TraceUtil.setError(span, t);</span>
+<span class="source-line-no">291</span><span id="line-291"> } else {</span>
+<span class="source-line-no">292</span><span id="line-292"> span.setStatus(StatusCode.OK);</span>
+<span class="source-line-no">293</span><span id="line-293"> }</span>
+<span class="source-line-no">294</span><span id="line-294"> BufferChain bc = null;</span>
+<span class="source-line-no">295</span><span id="line-295"> try {</span>
+<span class="source-line-no">296</span><span id="line-296"> ResponseHeader.Builder headerBuilder = ResponseHeader.newBuilder();</span>
+<span class="source-line-no">297</span><span id="line-297"> // Call id.</span>
+<span class="source-line-no">298</span><span id="line-298"> headerBuilder.setCallId(this.id);</span>
+<span class="source-line-no">299</span><span id="line-299"> if (t != null) {</span>
+<span class="source-line-no">300</span><span id="line-300"> setExceptionResponse(t, errorMsg, headerBuilder);</span>
+<span class="source-line-no">301</span><span id="line-301"> }</span>
+<span class="source-line-no">302</span><span id="line-302"> // Pass reservoir to buildCellBlock. Keep reference to returne so can add it back to the</span>
+<span class="source-line-no">303</span><span id="line-303"> // reservoir when finished. This is hacky and the hack is not contained but benefits are</span>
+<span class="source-line-no">304</span><span id="line-304"> // high when we can avoid a big buffer allocation on each rpc.</span>
+<span class="source-line-no">305</span><span id="line-305"> List<ByteBuffer> cellBlock = null;</span>
+<span class="source-line-no">306</span><span id="line-306"> int cellBlockSize = 0;</span>
+<span class="source-line-no">307</span><span id="line-307"> if (bbAllocator.isReservoirEnabled()) {</span>
+<span class="source-line-no">308</span><span id="line-308"> this.cellBlockStream = this.cellBlockBuilder.buildCellBlockStream(this.connection.codec,</span>
+<span class="source-line-no">309</span><span id="line-309"> this.connection.compressionCodec, cells, bbAllocator);</span>
+<span class="source-line-no">310</span><span id="line-310"> if (this.cellBlockStream != null) {</span>
+<span class="source-line-no">311</span><span id="line-311"> cellBlock = this.cellBlockStream.getByteBuffers();</span>
+<span class="source-line-no">312</span><span id="line-312"> cellBlockSize = this.cellBlockStream.size();</span>
<span class="source-line-no">313</span><span id="line-313"> }</span>
-<span class="source-line-no">314</span><span id="line-314"> }</span>
-<span class="source-line-no">315</span><span id="line-315"></span>
-<span class="source-line-no">316</span><span id="line-316"> if (cellBlockSize > 0) {</span>
-<span class="source-line-no">317</span><span id="line-317"> CellBlockMeta.Builder cellBlockBuilder = CellBlockMeta.newBuilder();</span>
-<span class="source-line-no">318</span><span id="line-318"> // Presumes the cellBlock bytebuffer has been flipped so limit has total size in it.</span>
-<span class="source-line-no">319</span><span id="line-319"> cellBlockBuilder.setLength(cellBlockSize);</span>
-<span class="source-line-no">320</span><span id="line-320"> headerBuilder.setCellBlockMeta(cellBlockBuilder.build());</span>
-<span class="source-line-no">321</span><span id="line-321"> }</span>
-<span class="source-line-no">322</span><span id="line-322"> Message header = headerBuilder.build();</span>
-<span class="source-line-no">323</span><span id="line-323"> ByteBuffer headerBuf = createHeaderAndMessageBytes(m, header, cellBlockSize, cellBlock);</span>
-<span class="source-line-no">324</span><span id="line-324"> ByteBuffer[] responseBufs = null;</span>
-<span class="source-line-no">325</span><span id="line-325"> int cellBlockBufferSize = 0;</span>
-<span class="source-line-no">326</span><span id="line-326"> if (cellBlock != null) {</span>
-<span class="source-line-no">327</span><span id="line-327"> cellBlockBufferSize = cellBlock.size();</span>
-<span class="source-line-no">328</span><span id="line-328"> responseBufs = new ByteBuffer[1 + cellBlockBufferSize];</span>
-<span class="source-line-no">329</span><span id="line-329"> } else {</span>
-<span class="source-line-no">330</span><span id="line-330"> responseBufs = new ByteBuffer[1];</span>
-<span class="source-line-no">331</span><span id="line-331"> }</span>
-<span class="source-line-no">332</span><span id="line-332"> responseBufs[0] = headerBuf;</span>
-<span class="source-line-no">333</span><span id="line-333"> if (cellBlock != null) {</span>
-<span class="source-line-no">334</span><span id="line-334"> for (int i = 0; i < cellBlockBufferSize; i++) {</span>
-<span class="source-line-no">335</span><span id="line-335"> responseBufs[i + 1] = cellBlock.get(i);</span>
-<span class="source-line-no">336</span><span id="line-336"> }</span>
-<span class="source-line-no">337</span><span id="line-337"> }</span>
-<span class="source-line-no">338</span><span id="line-338"> bc = new BufferChain(responseBufs);</span>
-<span class="source-line-no">339</span><span id="line-339"> } catch (IOException e) {</span>
-<span class="source-line-no">340</span><span id="line-340"> RpcServer.LOG.warn("Exception while creating response " + e);</span>
-<span class="source-line-no">341</span><span id="line-341"> bc = createFallbackErrorResponse(e);</span>
-<span class="source-line-no">342</span><span id="line-342"> }</span>
-<span class="source-line-no">343</span><span id="line-343"> this.response = bc;</span>
-<span class="source-line-no">344</span><span id="line-344"> // Once a response message is created and set to this.response, this Call can be treated as</span>
-<span class="source-line-no">345</span><span id="line-345"> // done. The Responder thread will do the n/w write of this message back to client.</span>
-<span class="source-line-no">346</span><span id="line-346"> if (this.rpcCallback != null) {</span>
-<span class="source-line-no">347</span><span id="line-347"> try (Scope ignored = span.makeCurrent()) {</span>
-<span class="source-line-no">348</span><span id="line-348"> this.rpcCallback.run();</span>
-<span class="source-line-no">349</span><span id="line-349"> } catch (Exception e) {</span>
-<span class="source-line-no">350</span><span id="line-350"> // Don't allow any exception here to kill this handler thread.</span>
-<span class="source-line-no">351</span><span id="line-351"> RpcServer.LOG.warn("Exception while running the Rpc Callback.", e);</span>
-<span class="source-line-no">352</span><span id="line-352"> TraceUtil.setError(span, e);</span>
-<span class="source-line-no">353</span><span id="line-353"> }</span>
-<span class="source-line-no">354</span><span id="line-354"> }</span>
-<span class="source-line-no">355</span><span id="line-355"> }</span>
-<span class="source-line-no">356</span><span id="line-356"></span>
-<span class="source-line-no">357</span><span id="line-357"> static void setExceptionResponse(Throwable t, String errorMsg,</span>
-<span class="source-line-no">358</span><span id="line-358"> ResponseHeader.Builder headerBuilder) {</span>
-<span class="source-line-no">359</span><span id="line-359"> ExceptionResponse.Builder exceptionBuilder = ExceptionResponse.newBuilder();</span>
-<span class="source-line-no">360</span><span id="line-360"> exceptionBuilder.setExceptionClassName(t.getClass().getName());</span>
-<span class="source-line-no">361</span><span id="line-361"> exceptionBuilder.setStackTrace(errorMsg);</span>
-<span class="source-line-no">362</span><span id="line-362"> exceptionBuilder.setDoNotRetry(t instanceof DoNotRetryIOException);</span>
-<span class="source-line-no">363</span><span id="line-363"> if (t instanceof RegionMovedException) {</span>
-<span class="source-line-no">364</span><span id="line-364"> // Special casing for this exception. This is only one carrying a payload.</span>
-<span class="source-line-no">365</span><span id="line-365"> // Do this instead of build a generic system for allowing exceptions carry</span>
-<span class="source-line-no">366</span><span id="line-366"> // any kind of payload.</span>
-<span class="source-line-no">367</span><span id="line-367"> RegionMovedException rme = (RegionMovedException) t;</span>
-<span class="source-line-no">368</span><span id="line-368"> exceptionBuilder.setHostname(rme.getHostname());</span>
-<span class="source-line-no">369</span><span id="line-369"> exceptionBuilder.setPort(rme.getPort());</span>
-<span class="source-line-no">370</span><span id="line-370"> } else if (t instanceof HBaseServerException) {</span>
-<span class="source-line-no">371</span><span id="line-371"> HBaseServerException hse = (HBaseServerException) t;</span>
-<span class="source-line-no">372</span><span id="line-372"> exceptionBuilder.setServerOverloaded(hse.isServerOverloaded());</span>
-<span class="source-line-no">373</span><span id="line-373"> }</span>
-<span class="source-line-no">374</span><span id="line-374"> // Set the exception as the result of the method invocation.</span>
-<span class="source-line-no">375</span><span id="line-375"> headerBuilder.setException(exceptionBuilder.build());</span>
-<span class="source-line-no">376</span><span id="line-376"> }</span>
-<span class="source-line-no">377</span><span id="line-377"></span>
-<span class="source-line-no">378</span><span id="line-378"> /*</span>
-<span class="source-line-no">379</span><span id="line-379"> * Creates a fallback error response when the primary response creation fails. This method is</span>
-<span class="source-line-no">380</span><span id="line-380"> * invoked as a last resort when an IOException occurs during the normal response creation</span>
-<span class="source-line-no">381</span><span id="line-381"> * process. It attempts to create a minimal error response containing only the error information,</span>
-<span class="source-line-no">382</span><span id="line-382"> * without any cell blocks or additional data. The purpose is to ensure that the client receives</span>
-<span class="source-line-no">383</span><span id="line-383"> * some indication of the failure rather than experiencing a silent connection drop. This provides</span>
-<span class="source-line-no">384</span><span id="line-384"> * better error handling on the client side.</span>
-<span class="source-line-no">385</span><span id="line-385"> */</span>
-<span class="source-line-no">386</span><span id="line-386"> private BufferChain createFallbackErrorResponse(IOException originalException) {</span>
-<span class="source-line-no">387</span><span id="line-387"> try {</span>
-<span class="source-line-no">388</span><span id="line-388"> ResponseHeader.Builder headerBuilder = ResponseHeader.newBuilder();</span>
-<span class="source-line-no">389</span><span id="line-389"> headerBuilder.setCallId(this.id);</span>
-<span class="source-line-no">390</span><span id="line-390"> String responseErrorMsg =</span>
-<span class="source-line-no">391</span><span id="line-391"> "Failed to create response due to: " + originalException.getMessage();</span>
-<span class="source-line-no">392</span><span id="line-392"> setExceptionResponse(originalException, responseErrorMsg, headerBuilder);</span>
-<span class="source-line-no">393</span><span id="line-393"> Message header = headerBuilder.build();</span>
-<span class="source-line-no">394</span><span id="line-394"> ByteBuffer headerBuf = createHeaderAndMessageBytes(null, header, 0, null);</span>
-<span class="source-line-no">395</span><span id="line-395"> this.isError = true;</span>
-<span class="source-line-no">396</span><span id="line-396"> return new BufferChain(new ByteBuffer[] { headerBuf });</span>
-<span class="source-line-no">397</span><span id="line-397"> } catch (IOException e) {</span>
-<span class="source-line-no">398</span><span id="line-398"> RpcServer.LOG.error("Failed to create error response for client, connection may be dropped",</span>
-<span class="source-line-no">399</span><span id="line-399"> e);</span>
-<span class="source-line-no">400</span><span id="line-400"> return null;</span>
-<span class="source-line-no">401</span><span id="line-401"> }</span>
-<span class="source-line-no">402</span><span id="line-402"> }</span>
-<span class="source-line-no">403</span><span id="line-403"></span>
-<span class="source-line-no">404</span><span id="line-404"> static ByteBuffer createHeaderAndMessageBytes(Message result, Message header, int cellBlockSize,</span>
-<span class="source-line-no">405</span><span id="line-405"> List<ByteBuffer> cellBlock) throws IOException {</span>
-<span class="source-line-no">406</span><span id="line-406"> // Organize the response as a set of bytebuffers rather than collect it all together inside</span>
-<span class="source-line-no">407</span><span id="line-407"> // one big byte array; save on allocations.</span>
-<span class="source-line-no">408</span><span id="line-408"> // for writing the header, we check if there is available space in the buffers</span>
-<span class="source-line-no">409</span><span id="line-409"> // created for the cellblock itself. If there is space for the header, we reuse</span>
-<span class="source-line-no">410</span><span id="line-410"> // the last buffer in the cellblock. This applies to the cellblock created from the</span>
-<span class="source-line-no">411</span><span id="line-411"> // pool or even the onheap cellblock buffer in case there is no pool enabled.</span>
-<span class="source-line-no">412</span><span id="line-412"> // Possible reuse would avoid creating a temporary array for storing the header every time.</span>
-<span class="source-line-no">413</span><span id="line-413"> ByteBuffer possiblePBBuf = (cellBlockSize > 0) ? cellBlock.get(cellBlock.size() - 1) : null;</span>
-<span class="source-line-no">414</span><span id="line-414"> int headerSerializedSize = 0, resultSerializedSize = 0, headerVintSize = 0, resultVintSize = 0;</span>
-<span class="source-line-no">415</span><span id="line-415"> if (header != null) {</span>
-<span class="source-line-no">416</span><span id="line-416"> headerSerializedSize = header.getSerializedSize();</span>
-<span class="source-line-no">417</span><span id="line-417"> headerVintSize = CodedOutputStream.computeUInt32SizeNoTag(headerSerializedSize);</span>
-<span class="source-line-no">418</span><span id="line-418"> }</span>
-<span class="source-line-no">419</span><span id="line-419"> if (result != null) {</span>
-<span class="source-line-no">420</span><span id="line-420"> resultSerializedSize = result.getSerializedSize();</span>
-<span class="source-line-no">421</span><span id="line-421"> resultVintSize = CodedOutputStream.computeUInt32SizeNoTag(resultSerializedSize);</span>
-<span class="source-line-no">422</span><span id="line-422"> }</span>
-<span class="source-line-no">423</span><span id="line-423"> // calculate the total size</span>
-<span class="source-line-no">424</span><span id="line-424"> int totalSize = headerSerializedSize + headerVintSize + (resultSerializedSize + resultVintSize)</span>
-<span class="source-line-no">425</span><span id="line-425"> + cellBlockSize;</span>
-<span class="source-line-no">426</span><span id="line-426"> int totalPBSize = headerSerializedSize + headerVintSize + resultSerializedSize + resultVintSize</span>
-<span class="source-line-no">427</span><span id="line-427"> + Bytes.SIZEOF_INT;</span>
-<span class="source-line-no">428</span><span id="line-428"> // Only if the last buffer has enough space for header use it. Else allocate</span>
-<span class="source-line-no">429</span><span id="line-429"> // a new buffer. Assume they are all flipped</span>
-<span class="source-line-no">430</span><span id="line-430"> if (possiblePBBuf != null && possiblePBBuf.limit() + totalPBSize <= possiblePBBuf.capacity()) {</span>
-<span class="source-line-no">431</span><span id="line-431"> // duplicate the buffer. This is where the header is going to be written</span>
-<span class="source-line-no">432</span><span id="line-432"> ByteBuffer pbBuf = possiblePBBuf.duplicate();</span>
-<span class="source-line-no">433</span><span id="line-433"> // get the current limit</span>
-<span class="source-line-no">434</span><span id="line-434"> int limit = pbBuf.limit();</span>
-<span class="source-line-no">435</span><span id="line-435"> // Position such that we write the header to the end of the buffer</span>
-<span class="source-line-no">436</span><span id="line-436"> pbBuf.position(limit);</span>
-<span class="source-line-no">437</span><span id="line-437"> // limit to the header size</span>
-<span class="source-line-no">438</span><span id="line-438"> pbBuf.limit(totalPBSize + limit);</span>
-<span class="source-line-no">439</span><span id="line-439"> // mark the current position</span>
-<span class="source-line-no">440</span><span id="line-440"> pbBuf.mark();</span>
-<span class="source-line-no">441</span><span id="line-441"> writeToCOS(result, header, totalSize, pbBuf);</span>
-<span class="source-line-no">442</span><span id="line-442"> // reset the buffer back to old position</span>
-<span class="source-line-no">443</span><span id="line-443"> pbBuf.reset();</span>
-<span class="source-line-no">444</span><span id="line-444"> return pbBuf;</span>
-<span class="source-line-no">445</span><span id="line-445"> } else {</span>
-<span class="source-line-no">446</span><span id="line-446"> return createHeaderAndMessageBytes(result, header, totalSize, totalPBSize);</span>
-<span class="source-line-no">447</span><span id="line-447"> }</span>
-<span class="source-line-no">448</span><span id="line-448"> }</span>
-<span class="source-line-no">449</span><span id="line-449"></span>
-<span class="source-line-no">450</span><span id="line-450"> private static void writeToCOS(Message result, Message header, int totalSize, ByteBuffer pbBuf)</span>
-<span class="source-line-no">451</span><span id="line-451"> throws IOException {</span>
-<span class="source-line-no">452</span><span id="line-452"> ByteBufferUtils.putInt(pbBuf, totalSize);</span>
-<span class="source-line-no">453</span><span id="line-453"> // create COS that works on BB</span>
-<span class="source-line-no">454</span><span id="line-454"> CodedOutputStream cos = CodedOutputStream.newInstance(pbBuf);</span>
-<span class="source-line-no">455</span><span id="line-455"> if (header != null) {</span>
-<span class="source-line-no">456</span><span id="line-456"> cos.writeMessageNoTag(header);</span>
-<span class="source-line-no">457</span><span id="line-457"> }</span>
-<span class="source-line-no">458</span><span id="line-458"> if (result != null) {</span>
-<span class="source-line-no">459</span><span id="line-459"> cos.writeMessageNoTag(result);</span>
-<span class="source-line-no">460</span><span id="line-460"> }</span>
-<span class="source-line-no">461</span><span id="line-461"> cos.flush();</span>
-<span class="source-line-no">462</span><span id="line-462"> cos.checkNoSpaceLeft();</span>
-<span class="source-line-no">463</span><span id="line-463"> }</span>
-<span class="source-line-no">464</span><span id="line-464"></span>
-<span class="source-line-no">465</span><span id="line-465"> private static ByteBuffer createHeaderAndMessageBytes(Message result, Message header,</span>
-<span class="source-line-no">466</span><span id="line-466"> int totalSize, int totalPBSize) throws IOException {</span>
-<span class="source-line-no">467</span><span id="line-467"> ByteBuffer pbBuf = ByteBuffer.allocate(totalPBSize);</span>
-<span class="source-line-no">468</span><span id="line-468"> writeToCOS(result, header, totalSize, pbBuf);</span>
-<span class="source-line-no">469</span><span id="line-469"> pbBuf.flip();</span>
-<span class="source-line-no">470</span><span id="line-470"> return pbBuf;</span>
+<span class="source-line-no">314</span><span id="line-314"> } else {</span>
+<span class="source-line-no">315</span><span id="line-315"> ByteBuffer b = this.cellBlockBuilder.buildCellBlock(this.connection.codec,</span>
+<span class="source-line-no">316</span><span id="line-316"> this.connection.compressionCodec, cells);</span>
+<span class="source-line-no">317</span><span id="line-317"> if (b != null) {</span>
+<span class="source-line-no">318</span><span id="line-318"> cellBlockSize = b.remaining();</span>
+<span class="source-line-no">319</span><span id="line-319"> cellBlock = new ArrayList<>(1);</span>
+<span class="source-line-no">320</span><span id="line-320"> cellBlock.add(b);</span>
+<span class="source-line-no">321</span><span id="line-321"> }</span>
+<span class="source-line-no">322</span><span id="line-322"> }</span>
+<span class="source-line-no">323</span><span id="line-323"></span>
+<span class="source-line-no">324</span><span id="line-324"> if (cellBlockSize > 0) {</span>
+<span class="source-line-no">325</span><span id="line-325"> CellBlockMeta.Builder cellBlockBuilder = CellBlockMeta.newBuilder();</span>
+<span class="source-line-no">326</span><span id="line-326"> // Presumes the cellBlock bytebuffer has been flipped so limit has total size in it.</span>
+<span class="source-line-no">327</span><span id="line-327"> cellBlockBuilder.setLength(cellBlockSize);</span>
+<span class="source-line-no">328</span><span id="line-328"> headerBuilder.setCellBlockMeta(cellBlockBuilder.build());</span>
+<span class="source-line-no">329</span><span id="line-329"> }</span>
+<span class="source-line-no">330</span><span id="line-330"> Message header = headerBuilder.build();</span>
+<span class="source-line-no">331</span><span id="line-331"> ByteBuffer headerBuf = createHeaderAndMessageBytes(m, header, cellBlockSize, cellBlock);</span>
+<span class="source-line-no">332</span><span id="line-332"> ByteBuffer[] responseBufs = null;</span>
+<span class="source-line-no">333</span><span id="line-333"> int cellBlockBufferSize = 0;</span>
+<span class="source-line-no">334</span><span id="line-334"> if (cellBlock != null) {</span>
+<span class="source-line-no">335</span><span id="line-335"> cellBlockBufferSize = cellBlock.size();</span>
+<span class="source-line-no">336</span><span id="line-336"> responseBufs = new ByteBuffer[1 + cellBlockBufferSize];</span>
+<span class="source-line-no">337</span><span id="line-337"> } else {</span>
+<span class="source-line-no">338</span><span id="line-338"> responseBufs = new ByteBuffer[1];</span>
+<span class="source-line-no">339</span><span id="line-339"> }</span>
+<span class="source-line-no">340</span><span id="line-340"> responseBufs[0] = headerBuf;</span>
+<span class="source-line-no">341</span><span id="line-341"> if (cellBlock != null) {</span>
+<span class="source-line-no">342</span><span id="line-342"> for (int i = 0; i < cellBlockBufferSize; i++) {</span>
+<span class="source-line-no">343</span><span id="line-343"> responseBufs[i + 1] = cellBlock.get(i);</span>
+<span class="source-line-no">344</span><span id="line-344"> }</span>
+<span class="source-line-no">345</span><span id="line-345"> }</span>
+<span class="source-line-no">346</span><span id="line-346"> bc = new BufferChain(responseBufs);</span>
+<span class="source-line-no">347</span><span id="line-347"> } catch (IOException e) {</span>
+<span class="source-line-no">348</span><span id="line-348"> RpcServer.LOG.warn("Exception while creating response " + e);</span>
+<span class="source-line-no">349</span><span id="line-349"> bc = createFallbackErrorResponse(e);</span>
+<span class="source-line-no">350</span><span id="line-350"> }</span>
+<span class="source-line-no">351</span><span id="line-351"> this.response = bc;</span>
+<span class="source-line-no">352</span><span id="line-352"> // Once a response message is created and set to this.response, this Call can be treated as</span>
+<span class="source-line-no">353</span><span id="line-353"> // done. The Responder thread will do the n/w write of this message back to client.</span>
+<span class="source-line-no">354</span><span id="line-354"> if (this.rpcCallback != null) {</span>
+<span class="source-line-no">355</span><span id="line-355"> try (Scope ignored = span.makeCurrent()) {</span>
+<span class="source-line-no">356</span><span id="line-356"> this.rpcCallback.run();</span>
+<span class="source-line-no">357</span><span id="line-357"> } catch (Exception e) {</span>
+<span class="source-line-no">358</span><span id="line-358"> // Don't allow any exception here to kill this handler thread.</span>
+<span class="source-line-no">359</span><span id="line-359"> RpcServer.LOG.warn("Exception while running the Rpc Callback.", e);</span>
+<span class="source-line-no">360</span><span id="line-360"> TraceUtil.setError(span, e);</span>
+<span class="source-line-no">361</span><span id="line-361"> }</span>
+<span class="source-line-no">362</span><span id="line-362"> }</span>
+<span class="source-line-no">363</span><span id="line-363"> }</span>
+<span class="source-line-no">364</span><span id="line-364"></span>
+<span class="source-line-no">365</span><span id="line-365"> static void setExceptionResponse(Throwable t, String errorMsg,</span>
+<span class="source-line-no">366</span><span id="line-366"> ResponseHeader.Builder headerBuilder) {</span>
+<span class="source-line-no">367</span><span id="line-367"> ExceptionResponse.Builder exceptionBuilder = ExceptionResponse.newBuilder();</span>
+<span class="source-line-no">368</span><span id="line-368"> exceptionBuilder.setExceptionClassName(t.getClass().getName());</span>
+<span class="source-line-no">369</span><span id="line-369"> exceptionBuilder.setStackTrace(errorMsg);</span>
+<span class="source-line-no">370</span><span id="line-370"> exceptionBuilder.setDoNotRetry(t instanceof DoNotRetryIOException);</span>
+<span class="source-line-no">371</span><span id="line-371"> if (t instanceof RegionMovedException) {</span>
+<span class="source-line-no">372</span><span id="line-372"> // Special casing for this exception. This is only one carrying a payload.</span>
+<span class="source-line-no">373</span><span id="line-373"> // Do this instead of build a generic system for allowing exceptions carry</span>
+<span class="source-line-no">374</span><span id="line-374"> // any kind of payload.</span>
+<span class="source-line-no">375</span><span id="line-375"> RegionMovedException rme = (RegionMovedException) t;</span>
+<span class="source-line-no">376</span><span id="line-376"> exceptionBuilder.setHostname(rme.getHostname());</span>
+<span class="source-line-no">377</span><span id="line-377"> exceptionBuilder.setPort(rme.getPort());</span>
+<span class="source-line-no">378</span><span id="line-378"> } else if (t instanceof HBaseServerException) {</span>
+<span class="source-line-no">379</span><span id="line-379"> HBaseServerException hse = (HBaseServerException) t;</span>
+<span class="source-line-no">380</span><span id="line-380"> exceptionBuilder.setServerOverloaded(hse.isServerOverloaded());</span>
+<span class="source-line-no">381</span><span id="line-381"> }</span>
+<span class="source-line-no">382</span><span id="line-382"> // Set the exception as the result of the method invocation.</span>
+<span class="source-line-no">383</span><span id="line-383"> headerBuilder.setException(exceptionBuilder.build());</span>
+<span class="source-line-no">384</span><span id="line-384"> }</span>
+<span class="source-line-no">385</span><span id="line-385"></span>
+<span class="source-line-no">386</span><span id="line-386"> /*</span>
+<span class="source-line-no">387</span><span id="line-387"> * Creates a fallback error response when the primary response creation fails. This method is</span>
+<span class="source-line-no">388</span><span id="line-388"> * invoked as a last resort when an IOException occurs during the normal response creation</span>
+<span class="source-line-no">389</span><span id="line-389"> * process. It attempts to create a minimal error response containing only the error information,</span>
+<span class="source-line-no">390</span><span id="line-390"> * without any cell blocks or additional data. The purpose is to ensure that the client receives</span>
+<span class="source-line-no">391</span><span id="line-391"> * some indication of the failure rather than experiencing a silent connection drop. This provides</span>
+<span class="source-line-no">392</span><span id="line-392"> * better error handling on the client side.</span>
+<span class="source-line-no">393</span><span id="line-393"> */</span>
+<span class="source-line-no">394</span><span id="line-394"> private BufferChain createFallbackErrorResponse(IOException originalException) {</span>
+<span class="source-line-no">395</span><span id="line-395"> try {</span>
+<span class="source-line-no">396</span><span id="line-396"> ResponseHeader.Builder headerBuilder = ResponseHeader.newBuilder();</span>
+<span class="source-line-no">397</span><span id="line-397"> headerBuilder.setCallId(this.id);</span>
+<span class="source-line-no">398</span><span id="line-398"> String responseErrorMsg =</span>
+<span class="source-line-no">399</span><span id="line-399"> "Failed to create response due to: " + originalException.getMessage();</span>
+<span class="source-line-no">400</span><span id="line-400"> setExceptionResponse(originalException, responseErrorMsg, headerBuilder);</span>
+<span class="source-line-no">401</span><span id="line-401"> Message header = headerBuilder.build();</span>
+<span class="source-line-no">402</span><span id="line-402"> ByteBuffer headerBuf = createHeaderAndMessageBytes(null, header, 0, null);</span>
+<span class="source-line-no">403</span><span id="line-403"> this.isError = true;</span>
+<span class="source-line-no">404</span><span id="line-404"> return new BufferChain(new ByteBuffer[] { headerBuf });</span>
+<span class="source-line-no">405</span><span id="line-405"> } catch (IOException e) {</span>
+<span class="source-line-no">406</span><span id="line-406"> RpcServer.LOG.error("Failed to create error response for client, connection may be dropped",</span>
+<span class="source-line-no">407</span><span id="line-407"> e);</span>
+<span class="source-line-no">408</span><span id="line-408"> return null;</span>
+<span class="source-line-no">409</span><span id="line-409"> }</span>
+<span class="source-line-no">410</span><span id="line-410"> }</span>
+<span class="source-line-no">411</span><span id="line-411"></span>
+<span class="source-line-no">412</span><span id="line-412"> static ByteBuffer createHeaderAndMessageBytes(Message result, Message header, int cellBlockSize,</span>
+<span class="source-line-no">413</span><span id="line-413"> List<ByteBuffer> cellBlock) throws IOException {</span>
+<span class="source-line-no">414</span><span id="line-414"> // Organize the response as a set of bytebuffers rather than collect it all together inside</span>
+<span class="source-line-no">415</span><span id="line-415"> // one big byte array; save on allocations.</span>
+<span class="source-line-no">416</span><span id="line-416"> // for writing the header, we check if there is available space in the buffers</span>
+<span class="source-line-no">417</span><span id="line-417"> // created for the cellblock itself. If there is space for the header, we reuse</span>
+<span class="source-line-no">418</span><span id="line-418"> // the last buffer in the cellblock. This applies to the cellblock created from the</span>
+<span class="source-line-no">419</span><span id="line-419"> // pool or even the onheap cellblock buffer in case there is no pool enabled.</span>
+<span class="source-line-no">420</span><span id="line-420"> // Possible reuse would avoid creating a temporary array for storing the header every time.</span>
+<span class="source-line-no">421</span><span id="line-421"> ByteBuffer possiblePBBuf = (cellBlockSize > 0) ? cellBlock.get(cellBlock.size() - 1) : null;</span>
+<span class="source-line-no">422</span><span id="line-422"> int headerSerializedSize = 0, resultSerializedSize = 0, headerVintSize = 0, resultVintSize = 0;</span>
+<span class="source-line-no">423</span><span id="line-423"> if (header != null) {</span>
+<span class="source-line-no">424</span><span id="line-424"> headerSerializedSize = header.getSerializedSize();</span>
+<span class="source-line-no">425</span><span id="line-425"> headerVintSize = CodedOutputStream.computeUInt32SizeNoTag(headerSerializedSize);</span>
+<span class="source-line-no">426</span><span id="line-426"> }</span>
+<span class="source-line-no">427</span><span id="line-427"> if (result != null) {</span>
+<span class="source-line-no">428</span><span id="line-428"> resultSerializedSize = result.getSerializedSize();</span>
+<span class="source-line-no">429</span><span id="line-429"> resultVintSize = CodedOutputStream.computeUInt32SizeNoTag(resultSerializedSize);</span>
+<span class="source-line-no">430</span><span id="line-430"> }</span>
+<span class="source-line-no">431</span><span id="line-431"> // calculate the total size</span>
+<span class="source-line-no">432</span><span id="line-432"> int totalSize = headerSerializedSize + headerVintSize + (resultSerializedSize + resultVintSize)</span>
+<span class="source-line-no">433</span><span id="line-433"> + cellBlockSize;</span>
+<span class="source-line-no">434</span><span id="line-434"> int totalPBSize = headerSerializedSize + headerVintSize + resultSerializedSize + resultVintSize</span>
+<span class="source-line-no">435</span><span id="line-435"> + Bytes.SIZEOF_INT;</span>
+<span class="source-line-no">436</span><span id="line-436"> // Only if the last buffer has enough space for header use it. Else allocate</span>
+<span class="source-line-no">437</span><span id="line-437"> // a new buffer. Assume they are all flipped</span>
+<span class="source-line-no">438</span><span id="line-438"> if (possiblePBBuf != null && possiblePBBuf.limit() + totalPBSize <= possiblePBBuf.capacity()) {</span>
+<span class="source-line-no">439</span><span id="line-439"> // duplicate the buffer. This is where the header is going to be written</span>
+<span class="source-line-no">440</span><span id="line-440"> ByteBuffer pbBuf = possiblePBBuf.duplicate();</span>
+<span class="source-line-no">441</span><span id="line-441"> // get the current limit</span>
+<span class="source-line-no">442</span><span id="line-442"> int limit = pbBuf.limit();</span>
+<span class="source-line-no">443</span><span id="line-443"> // Position such that we write the header to the end of the buffer</span>
+<span class="source-line-no">444</span><span id="line-444"> pbBuf.position(limit);</span>
+<span class="source-line-no">445</span><span id="line-445"> // limit to the header size</span>
+<span class="source-line-no">446</span><span id="line-446"> pbBuf.limit(totalPBSize + limit);</span>
+<span class="source-line-no">447</span><span id="line-447"> // mark the current position</span>
+<span class="source-line-no">448</span><span id="line-448"> pbBuf.mark();</span>
+<span class="source-line-no">449</span><span id="line-449"> writeToCOS(result, header, totalSize, pbBuf);</span>
+<span class="source-line-no">450</span><span id="line-450"> // reset the buffer back to old position</span>
+<span class="source-line-no">451</span><span id="line-451"> pbBuf.reset();</span>
+<span class="source-line-no">452</span><span id="line-452"> return pbBuf;</span>
+<span class="source-line-no">453</span><span id="line-453"> } else {</span>
+<span class="source-line-no">454</span><span id="line-454"> return createHeaderAndMessageBytes(result, header, totalSize, totalPBSize);</span>
+<span class="source-line-no">455</span><span id="line-455"> }</span>
+<span class="source-line-no">456</span><span id="line-456"> }</span>
+<span class="source-line-no">457</span><span id="line-457"></span>
+<span class="source-line-no">458</span><span id="line-458"> private static void writeToCOS(Message result, Message header, int totalSize, ByteBuffer pbBuf)</span>
+<span class="source-line-no">459</span><span id="line-459"> throws IOException {</span>
+<span class="source-line-no">460</span><span id="line-460"> ByteBufferUtils.putInt(pbBuf, totalSize);</span>
+<span class="source-line-no">461</span><span id="line-461"> // create COS that works on BB</span>
+<span class="source-line-no">462</span><span id="line-462"> CodedOutputStream cos = CodedOutputStream.newInstance(pbBuf);</span>
+<span class="source-line-no">463</span><span id="line-463"> if (header != null) {</span>
+<span class="source-line-no">464</span><span id="line-464"> cos.writeMessageNoTag(header);</span>
+<span class="source-line-no">465</span><span id="line-465"> }</span>
+<span class="source-line-no">466</span><span id="line-466"> if (result != null) {</span>
+<span class="source-line-no">467</span><span id="line-467"> cos.writeMessageNoTag(result);</span>
+<span class="source-line-no">468</span><span id="line-468"> }</span>
+<span class="source-line-no">469</span><span id="line-469"> cos.flush();</span>
+<span class="source-line-no">470</span><span id="line-470"> cos.checkNoSpaceLeft();</span>
<span class="source-line-no">471</span><span id="line-471"> }</span>
<span class="source-line-no">472</span><span id="line-472"></span>
-<span class="source-line-no">473</span><span id="line-473"> @Override</span>
-<span class="source-line-no">474</span><span id="line-474"> public long disconnectSince() {</span>
-<span class="source-line-no">475</span><span id="line-475"> if (!this.connection.isConnectionOpen()) {</span>
-<span class="source-line-no">476</span><span id="line-476"> return EnvironmentEdgeManager.currentTime() - receiveTime;</span>
-<span class="source-line-no">477</span><span id="line-477"> } else {</span>
-<span class="source-line-no">478</span><span id="line-478"> return -1L;</span>
-<span class="source-line-no">479</span><span id="line-479"> }</span>
-<span class="source-line-no">480</span><span id="line-480"> }</span>
-<span class="source-line-no">481</span><span id="line-481"></span>
-<span class="source-line-no">482</span><span id="line-482"> @Override</span>
-<span class="source-line-no">483</span><span id="line-483"> public boolean isClientCellBlockSupported() {</span>
-<span class="source-line-no">484</span><span id="line-484"> return this.connection != null && this.connection.codec != null;</span>
-<span class="source-line-no">485</span><span id="line-485"> }</span>
-<span class="source-line-no">486</span><span id="line-486"></span>
-<span class="source-line-no">487</span><span id="line-487"> @Override</span>
-<span class="source-line-no">488</span><span id="line-488"> public long getResponseCellSize() {</span>
-<span class="source-line-no">489</span><span id="line-489"> return responseCellSize;</span>
-<span class="source-line-no">490</span><span id="line-490"> }</span>
-<span class="source-line-no">491</span><span id="line-491"></span>
-<span class="source-line-no">492</span><span id="line-492"> @Override</span>
-<span class="source-line-no">493</span><span id="line-493"> public void incrementResponseCellSize(long cellSize) {</span>
-<span class="source-line-no">494</span><span id="line-494"> responseCellSize += cellSize;</span>
-<span class="source-line-no">495</span><span id="line-495"> }</span>
-<span class="source-line-no">496</span><span id="line-496"></span>
-<span class="source-line-no">497</span><span id="line-497"> @Override</span>
-<span class="source-line-no">498</span><span id="line-498"> public long getBlockBytesScanned() {</span>
-<span class="source-line-no">499</span><span id="line-499"> return responseBlockSize;</span>
-<span class="source-line-no">500</span><span id="line-500"> }</span>
-<span class="source-line-no">501</span><span id="line-501"></span>
-<span class="source-line-no">502</span><span id="line-502"> @Override</span>
-<span class="source-line-no">503</span><span id="line-503"> public void incrementBlockBytesScanned(long blockSize) {</span>
-<span class="source-line-no">504</span><span id="line-504"> responseBlockSize += blockSize;</span>
-<span class="source-line-no">505</span><span id="line-505"> }</span>
-<span class="source-line-no">506</span><span id="line-506"></span>
-<span class="source-line-no">507</span><span id="line-507"> @Override</span>
-<span class="source-line-no">508</span><span id="line-508"> public long getResponseExceptionSize() {</span>
-<span class="source-line-no">509</span><span id="line-509"> return exceptionSize;</span>
-<span class="source-line-no">510</span><span id="line-510"> }</span>
-<span class="source-line-no">511</span><span id="line-511"></span>
-<span class="source-line-no">512</span><span id="line-512"> @Override</span>
-<span class="source-line-no">513</span><span id="line-513"> public void incrementResponseExceptionSize(long exSize) {</span>
-<span class="source-line-no">514</span><span id="line-514"> exceptionSize += exSize;</span>
-<span class="source-line-no">515</span><span id="line-515"> }</span>
-<span class="source-line-no">516</span><span id="line-516"></span>
-<span class="source-line-no">517</span><span id="line-517"> @Override</span>
-<span class="source-line-no">518</span><span id="line-518"> public long getSize() {</span>
-<span class="source-line-no">519</span><span id="line-519"> return this.size;</span>
-<span class="source-line-no">520</span><span id="line-520"> }</span>
-<span class="source-line-no">521</span><span id="line-521"></span>
-<span class="source-line-no">522</span><span id="line-522"> @Override</span>
-<span class="source-line-no">523</span><span id="line-523"> public long getDeadline() {</span>
-<span class="source-line-no">524</span><span id="line-524"> return deadline;</span>
-<span class="source-line-no">525</span><span id="line-525"> }</span>
-<span class="source-line-no">526</span><span id="line-526"></span>
-<span class="source-line-no">527</span><span id="line-527"> @Override</span>
-<span class="source-line-no">528</span><span id="line-528"> public Optional<User> getRequestUser() {</span>
-<span class="source-line-no">529</span><span id="line-529"> return Optional.ofNullable(user);</span>
-<span class="source-line-no">530</span><span id="line-530"> }</span>
-<span class="source-line-no">531</span><span id="line-531"></span>
-<span class="source-line-no">532</span><span id="line-532"> @Override</span>
-<span class="source-line-no">533</span><span id="line-533"> public Optional<X509Certificate[]> getClientCertificateChain() {</span>
-<span class="source-line-no">534</span><span id="line-534"> return Optional.ofNullable(clientCertificateChain);</span>
-<span class="source-line-no">535</span><span id="line-535"> }</span>
-<span class="source-line-no">536</span><span id="line-536"></span>
-<span class="source-line-no">537</span><span id="line-537"> @Override</span>
-<span class="source-line-no">538</span><span id="line-538"> public InetAddress getRemoteAddress() {</span>
-<span class="source-line-no">539</span><span id="line-539"> return remoteAddress;</span>
-<span class="source-line-no">540</span><span id="line-540"> }</span>
-<span class="source-line-no">541</span><span id="line-541"></span>
-<span class="source-line-no">542</span><span id="line-542"> @Override</span>
-<span class="source-line-no">543</span><span id="line-543"> public VersionInfo getClientVersionInfo() {</span>
-<span class="source-line-no">544</span><span id="line-544"> return connection.getVersionInfo();</span>
-<span class="source-line-no">545</span><span id="line-545"> }</span>
-<span class="source-line-no">546</span><span id="line-546"></span>
-<span class="source-line-no">547</span><span id="line-547"> @Override</span>
-<span class="source-line-no">548</span><span id="line-548"> public synchronized void setCallBack(RpcCallback callback) {</span>
-<span class="source-line-no">549</span><span id="line-549"> this.rpcCallback = callback;</span>
-<span class="source-line-no">550</span><span id="line-550"> }</span>
-<span class="source-line-no">551</span><span id="line-551"></span>
-<span class="source-line-no">552</span><span id="line-552"> @Override</span>
-<span class="source-line-no">553</span><span id="line-553"> public boolean isRetryImmediatelySupported() {</span>
-<span class="source-line-no">554</span><span id="line-554"> return retryImmediatelySupported;</span>
-<span class="source-line-no">555</span><span id="line-555"> }</span>
-<span class="source-line-no">556</span><span id="line-556"></span>
-<span class="source-line-no">557</span><span id="line-557"> @Override</span>
-<span class="source-line-no">558</span><span id="line-558"> public BlockingService getService() {</span>
-<span class="source-line-no">559</span><span id="line-559"> return service;</span>
-<span class="source-line-no">560</span><span id="line-560"> }</span>
-<span class="source-line-no">561</span><span id="line-561"></span>
-<span class="source-line-no">562</span><span id="line-562"> @Override</span>
-<span class="source-line-no">563</span><span id="line-563"> public MethodDescriptor getMethod() {</span>
-<span class="source-line-no">564</span><span id="line-564"> return md;</span>
-<span class="source-line-no">565</span><span id="line-565"> }</span>
-<span class="source-line-no">566</span><span id="line-566"></span>
-<span class="source-line-no">567</span><span id="line-567"> @Override</span>
-<span class="source-line-no">568</span><span id="line-568"> public Message getParam() {</span>
-<span class="source-line-no">569</span><span id="line-569"> return param;</span>
-<span class="source-line-no">570</span><span id="line-570"> }</span>
-<span class="source-line-no">571</span><span id="line-571"></span>
-<span class="source-line-no">572</span><span id="line-572"> @Override</span>
-<span class="source-line-no">573</span><span id="line-573"> public ExtendedCellScanner getCellScanner() {</span>
-<span class="source-line-no">574</span><span id="line-574"> return cellScanner;</span>
-<span class="source-line-no">575</span><span id="line-575"> }</span>
-<span class="source-line-no">576</span><span id="line-576"></span>
-<span class="source-line-no">577</span><span id="line-577"> @Override</span>
-<span class="source-line-no">578</span><span id="line-578"> public long getReceiveTime() {</span>
-<span class="source-line-no">579</span><span id="line-579"> return receiveTime;</span>
-<span class="source-line-no">580</span><span id="line-580"> }</span>
-<span class="source-line-no">581</span><span id="line-581"></span>
-<span class="source-line-no">582</span><span id="line-582"> @Override</span>
-<span class="source-line-no">583</span><span id="line-583"> public long getStartTime() {</span>
-<span class="source-line-no">584</span><span id="line-584"> return startTime;</span>
-<span class="source-line-no">585</span><span id="line-585"> }</span>
-<span class="source-line-no">586</span><span id="line-586"></span>
-<span class="source-line-no">587</span><span id="line-587"> @Override</span>
-<span class="source-line-no">588</span><span id="line-588"> public void setStartTime(long t) {</span>
-<span class="source-line-no">589</span><span id="line-589"> this.startTime = t;</span>
-<span class="source-line-no">590</span><span id="line-590"> }</span>
-<span class="source-line-no">591</span><span id="line-591"></span>
-<span class="source-line-no">592</span><span id="line-592"> @Override</span>
-<span class="source-line-no">593</span><span id="line-593"> public int getTimeout() {</span>
-<span class="source-line-no">594</span><span id="line-594"> return timeout;</span>
-<span class="source-line-no">595</span><span id="line-595"> }</span>
-<span class="source-line-no">596</span><span id="line-596"></span>
-<span class="source-line-no">597</span><span id="line-597"> @Override</span>
-<span class="source-line-no">598</span><span id="line-598"> public int getRemotePort() {</span>
-<span class="source-line-no">599</span><span id="line-599"> return connection.getRemotePort();</span>
-<span class="source-line-no">600</span><span id="line-600"> }</span>
-<span class="source-line-no">601</span><span id="line-601"></span>
-<span class="source-line-no">602</span><span id="line-602"> @Override</span>
-<span class="source-line-no">603</span><span id="line-603"> public synchronized BufferChain getResponse() {</span>
-<span class="source-line-no">604</span><span id="line-604"> return response;</span>
-<span class="source-line-no">605</span><span id="line-605"> }</span>
-<span class="source-line-no">606</span><span id="line-606">}</span>
+<span class="source-line-no">473</span><span id="line-473"> private static ByteBuffer createHeaderAndMessageBytes(Message result, Message header,</span>
+<span class="source-line-no">474</span><span id="line-474"> int totalSize, int totalPBSize) throws IOException {</span>
+<span class="source-line-no">475</span><span id="line-475"> ByteBuffer pbBuf = ByteBuffer.allocate(totalPBSize);</span>
+<span class="source-line-no">476</span><span id="line-476"> writeToCOS(result, header, totalSize, pbBuf);</span>
+<span class="source-line-no">477</span><span id="line-477"> pbBuf.flip();</span>
+<span class="source-line-no">478</span><span id="line-478"> return pbBuf;</span>
+<span class="source-line-no">479</span><span id="line-479"> }</span>
+<span class="source-line-no">480</span><span id="line-480"></span>
+<span class="source-line-no">481</span><span id="line-481"> @Override</span>
+<span class="source-line-no">482</span><span id="line-482"> public long disconnectSince() {</span>
+<span class="source-line-no">483</span><span id="line-483"> if (!this.connection.isConnectionOpen()) {</span>
+<span class="source-line-no">484</span><span id="line-484"> return EnvironmentEdgeManager.currentTime() - receiveTime;</span>
+<span class="source-line-no">485</span><span id="line-485"> } else {</span>
+<span class="source-line-no">486</span><span id="line-486"> return -1L;</span>
+<span class="source-line-no">487</span><span id="line-487"> }</span>
+<span class="source-line-no">488</span><span id="line-488"> }</span>
+<span class="source-line-no">489</span><span id="line-489"></span>
+<span class="source-line-no">490</span><span id="line-490"> @Override</span>
+<span class="source-line-no">491</span><span id="line-491"> public boolean isClientCellBlockSupported() {</span>
+<span class="source-line-no">492</span><span id="line-492"> return this.connection != null && this.connection.codec != null;</span>
+<span class="source-line-no">493</span><span id="line-493"> }</span>
+<span class="source-line-no">494</span><span id="line-494"></span>
+<span class="source-line-no">495</span><span id="line-495"> @Override</span>
+<span class="source-line-no">496</span><span id="line-496"> public long getResponseCellSize() {</span>
+<span class="source-line-no">497</span><span id="line-497"> return responseCellSize;</span>
+<span class="source-line-no">498</span><span id="line-498"> }</span>
+<span class="source-line-no">499</span><span id="line-499"></span>
+<span class="source-line-no">500</span><span id="line-500"> @Override</span>
+<span class="source-line-no">501</span><span id="line-501"> public void incrementResponseCellSize(long cellSize) {</span>
+<span class="source-line-no">502</span><span id="line-502"> responseCellSize += cellSize;</span>
+<span class="source-line-no">503</span><span id="line-503"> }</span>
+<span class="source-line-no">504</span><span id="line-504"></span>
+<span class="source-line-no">505</span><span id="line-505"> @Override</span>
+<span class="source-line-no">506</span><span id="line-506"> public long getBlockBytesScanned() {</span>
+<span class="source-line-no">507</span><span id="line-507"> return responseBlockSize;</span>
+<span class="source-line-no">508</span><span id="line-508"> }</span>
+<span class="source-line-no">509</span><span id="line-509"></span>
+<span class="source-line-no">510</span><span id="line-510"> @Override</span>
+<span class="source-line-no">511</span><span id="line-511"> public void incrementBlockBytesScanned(long blockSize) {</span>
+<span class="source-line-no">512</span><span id="line-512"> responseBlockSize += blockSize;</span>
+<span class="source-line-no">513</span><span id="line-513"> }</span>
+<span class="source-line-no">514</span><span id="line-514"></span>
+<span class="source-line-no">515</span><span id="line-515"> @Override</span>
+<span class="source-line-no">516</span><span id="line-516"> public long getResponseExceptionSize() {</span>
+<span class="source-line-no">517</span><span id="line-517"> return exceptionSize;</span>
+<span class="source-line-no">518</span><span id="line-518"> }</span>
+<span class="source-line-no">519</span><span id="line-519"></span>
+<span class="source-line-no">520</span><span id="line-520"> @Override</span>
+<span class="source-line-no">521</span><span id="line-521"> public void incrementResponseExceptionSize(long exSize) {</span>
+<span class="source-line-no">522</span><span id="line-522"> exceptionSize += exSize;</span>
+<span class="source-line-no">523</span><span id="line-523"> }</span>
+<span class="source-line-no">524</span><span id="line-524"></span>
+<span class="source-line-no">525</span><span id="line-525"> @Override</span>
+<span class="source-line-no">526</span><span id="line-526"> public long getSize() {</span>
+<span class="source-line-no">527</span><span id="line-527"> return this.size;</span>
+<span class="source-line-no">528</span><span id="line-528"> }</span>
+<span class="source-line-no">529</span><span id="line-529"></span>
+<span class="source-line-no">530</span><span id="line-530"> @Override</span>
+<span class="source-line-no">531</span><span id="line-531"> public long getDeadline() {</span>
+<span class="source-line-no">532</span><span id="line-532"> return deadline;</span>
+<span class="source-line-no">533</span><span id="line-533"> }</span>
+<span class="source-line-no">534</span><span id="line-534"></span>
+<span class="source-line-no">535</span><span id="line-535"> @Override</span>
+<span class="source-line-no">536</span><span id="line-536"> public Optional<User> getRequestUser() {</span>
+<span class="source-line-no">537</span><span id="line-537"> return Optional.ofNullable(user);</span>
+<span class="source-line-no">538</span><span id="line-538"> }</span>
+<span class="source-line-no">539</span><span id="line-539"></span>
+<span class="source-line-no">540</span><span id="line-540"> @Override</span>
+<span class="source-line-no">541</span><span id="line-541"> public Optional<X509Certificate[]> getClientCertificateChain() {</span>
+<span class="source-line-no">542</span><span id="line-542"> return Optional.ofNullable(clientCertificateChain);</span>
+<span class="source-line-no">543</span><span id="line-543"> }</span>
+<span class="source-line-no">544</span><span id="line-544"></span>
+<span class="source-line-no">545</span><span id="line-545"> @Override</span>
+<span class="source-line-no">546</span><span id="line-546"> public InetAddress getRemoteAddress() {</span>
+<span class="source-line-no">547</span><span id="line-547"> return remoteAddress;</span>
+<span class="source-line-no">548</span><span id="line-548"> }</span>
+<span class="source-line-no">549</span><span id="line-549"></span>
+<span class="source-line-no">550</span><span id="line-550"> @Override</span>
+<span class="source-line-no">551</span><span id="line-551"> public VersionInfo getClientVersionInfo() {</span>
+<span class="source-line-no">552</span><span id="line-552"> return connection.getVersionInfo();</span>
+<span class="source-line-no">553</span><span id="line-553"> }</span>
+<span class="source-line-no">554</span><span id="line-554"></span>
+<span class="source-line-no">555</span><span id="line-555"> @Override</span>
+<span class="source-line-no">556</span><span id="line-556"> public synchronized void setCallBack(RpcCallback callback) {</span>
+<span class="source-line-no">557</span><span id="line-557"> this.rpcCallback = callback;</span>
+<span class="source-line-no">558</span><span id="line-558"> }</span>
+<span class="source-line-no">559</span><span id="line-559"></span>
+<span class="source-line-no">560</span><span id="line-560"> @Override</span>
+<span class="source-line-no">561</span><span id="line-561"> public boolean isRetryImmediatelySupported() {</span>
+<span class="source-line-no">562</span><span id="line-562"> return retryImmediatelySupported;</span>
+<span class="source-line-no">563</span><span id="line-563"> }</span>
+<span class="source-line-no">564</span><span id="line-564"></span>
+<span class="source-line-no">565</span><span id="line-565"> @Override</span>
+<span class="source-line-no">566</span><span id="line-566"> public BlockingService getService() {</span>
+<span class="source-line-no">567</span><span id="line-567"> return service;</span>
+<span class="source-line-no">568</span><span id="line-568"> }</span>
+<span class="source-line-no">569</span><span id="line-569"></span>
+<span class="source-line-no">570</span><span id="line-570"> @Override</span>
+<span class="source-line-no">571</span><span id="line-571"> public MethodDescriptor getMethod() {</span>
+<span class="source-line-no">572</span><span id="line-572"> return md;</span>
+<span class="source-line-no">573</span><span id="line-573"> }</span>
+<span class="source-line-no">574</span><span id="line-574"></span>
+<span class="source-line-no">575</span><span id="line-575"> @Override</span>
+<span class="source-line-no">576</span><span id="line-576"> public Message getParam() {</span>
+<span class="source-line-no">577</span><span id="line-577"> return param;</span>
+<span class="source-line-no">578</span><span id="line-578"> }</span>
+<span class="source-line-no">579</span><span id="line-579"></span>
+<span class="source-line-no">580</span><span id="line-580"> @Override</span>
+<span class="source-line-no">581</span><span id="line-581"> public ExtendedCellScanner getCellScanner() {</span>
+<span class="source-line-no">582</span><span id="line-582"> return cellScanner;</span>
+<span class="source-line-no">583</span><span id="line-583"> }</span>
+<span class="source-line-no">584</span><span id="line-584"></span>
+<span class="source-line-no">585</span><span id="line-585"> @Override</span>
+<span class="source-line-no">586</span><span id="line-586"> public long getReceiveTime() {</span>
+<span class="source-line-no">587</span><span id="line-587"> return receiveTime;</span>
+<span class="source-line-no">588</span><span id="line-588"> }</span>
+<span class="source-line-no">589</span><span id="line-589"></span>
+<span class="source-line-no">590</span><span id="line-590"> @Override</span>
+<span class="source-line-no">591</span><span id="line-591"> public long getStartTime() {</span>
+<span class="source-line-no">592</span><span id="line-592"> return startTime;</span>
+<span class="source-line-no">593</span><span id="line-593"> }</span>
+<span class="source-line-no">594</span><span id="line-594"></span>
+<span class="source-line-no">595</span><span id="line-595"> @Override</span>
+<span class="source-line-no">596</span><span id="line-596"> public void setStartTime(long t) {</span>
+<span class="source-line-no">597</span><span id="line-597"> this.startTime = t;</span>
+<span class="source-line-no">598</span><span id="line-598"> }</span>
+<span class="source-line-no">599</span><span id="line-599"></span>
+<span class="source-line-no">600</span><span id="line-600"> @Override</span>
+<span class="source-line-no">601</span><span id="line-601"> public int getTimeout() {</span>
+<span class="source-line-no">602</span><span id="line-602"> return timeout;</span>
+<span class="source-line-no">603</span><span id="line-603"> }</span>
+<span class="source-line-no">604</span><span id="line-604"></span>
+<span class="source-line-no">605</span><span id="line-605"> @Override</span>
+<span class="source-line-no">606</span><span id="line-606"> public int getRemotePort() {</span>
+<span class="source-line-no">607</span><span id="line-607"> return connection.getRemotePort();</span>
+<span class="source-line-no">608</span><span id="line-608"> }</span>
+<span class="source-line-no">609</span><span id="line-609"></span>
+<span class="source-line-no">610</span><span id="line-610"> @Override</span>
+<span class="source-line-no">611</span><span id="line-611"> public synchronized BufferChain getResponse() {</span>
+<span class="source-line-no">612</span><span id="line-612"> return response;</span>
+<span class="source-line-no">613</span><span id="line-613"> }</span>
+<span class="source-line-no">614</span><span id="line-614">}</span>
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/ipc/ServerRpcConnection.PreambleResponse.html b/apidocs/src-html/org/apache/hadoop/hbase/ipc/ServerRpcConnection.PreambleResponse.html
similarity index 83%
copy from devapidocs/src-html/org/apache/hadoop/hbase/ipc/ServerRpcConnection.PreambleResponse.html
copy to apidocs/src-html/org/apache/hadoop/hbase/ipc/ServerRpcConnection.PreambleResponse.html
index 985d2429114..b38df1889ef 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/ipc/ServerRpcConnection.PreambleResponse.html
+++ b/apidocs/src-html/org/apache/hadoop/hbase/ipc/ServerRpcConnection.PreambleResponse.html
@@ -109,7 +109,7 @@
<span class="source-line-no">096</span><span id="line-96">@edu.umd.cs.findbugs.annotations.SuppressWarnings(value = "VO_VOLATILE_INCREMENT",</span>
<span class="source-line-no">097</span><span id="line-97"> justification = "False positive according to http://sourceforge.net/p/findbugs/bugs/1032/")</span>
<span class="source-line-no">098</span><span id="line-98">@InterfaceAudience.Private</span>
-<span class="source-line-no">099</span><span id="line-99">abstract class ServerRpcConnection implements Closeable {</span>
+<span class="source-line-no">099</span><span id="line-99">public abstract class ServerRpcConnection implements Closeable {</span>
<span class="source-line-no">100</span><span id="line-100"></span>
<span class="source-line-no">101</span><span id="line-101"> private static final TextMapGetter<RPCTInfo> getter = new RPCTInfoGetter();</span>
<span class="source-line-no">102</span><span id="line-102"></span>
@@ -500,380 +500,384 @@
<span class="source-line-no">487</span><span id="line-487"> this.hostAddress, this.remotePort, version, this.useSasl, this.ugi, serviceName);</span>
<span class="source-line-no">488</span><span id="line-488"> }</span>
<span class="source-line-no">489</span><span id="line-489"></span>
-<span class="source-line-no">490</span><span id="line-490"> /**</span>
-<span class="source-line-no">491</span><span id="line-491"> * Send the response for connection header</span>
-<span class="source-line-no">492</span><span id="line-492"> */</span>
-<span class="source-line-no">493</span><span id="line-493"> private void sendConnectionHeaderResponseIfNeeded() throws FatalConnectionException {</span>
-<span class="source-line-no">494</span><span id="line-494"> Pair<RPCProtos.ConnectionHeaderResponse, CryptoAES> pair = setupCryptoCipher();</span>
-<span class="source-line-no">495</span><span id="line-495"> // Response the connection header if Crypto AES is enabled</span>
-<span class="source-line-no">496</span><span id="line-496"> if (pair == null) {</span>
-<span class="source-line-no">497</span><span id="line-497"> return;</span>
-<span class="source-line-no">498</span><span id="line-498"> }</span>
-<span class="source-line-no">499</span><span id="line-499"> try {</span>
-<span class="source-line-no">500</span><span id="line-500"> int size = pair.getFirst().getSerializedSize();</span>
-<span class="source-line-no">501</span><span id="line-501"> BufferChain bc;</span>
-<span class="source-line-no">502</span><span id="line-502"> try (ByteBufferOutputStream bbOut = new ByteBufferOutputStream(4 + size);</span>
-<span class="source-line-no">503</span><span id="line-503"> DataOutputStream out = new DataOutputStream(bbOut)) {</span>
-<span class="source-line-no">504</span><span id="line-504"> out.writeInt(size);</span>
-<span class="source-line-no">505</span><span id="line-505"> pair.getFirst().writeTo(out);</span>
-<span class="source-line-no">506</span><span id="line-506"> bc = new BufferChain(bbOut.getByteBuffer());</span>
-<span class="source-line-no">507</span><span id="line-507"> }</span>
-<span class="source-line-no">508</span><span id="line-508"> doRespond(new RpcResponse() {</span>
-<span class="source-line-no">509</span><span id="line-509"></span>
-<span class="source-line-no">510</span><span id="line-510"> @Override</span>
-<span class="source-line-no">511</span><span id="line-511"> public BufferChain getResponse() {</span>
-<span class="source-line-no">512</span><span id="line-512"> return bc;</span>
-<span class="source-line-no">513</span><span id="line-513"> }</span>
-<span class="source-line-no">514</span><span id="line-514"></span>
-<span class="source-line-no">515</span><span id="line-515"> @Override</span>
-<span class="source-line-no">516</span><span id="line-516"> public void done() {</span>
-<span class="source-line-no">517</span><span id="line-517"> // must switch after sending the connection header response, as the client still uses the</span>
-<span class="source-line-no">518</span><span id="line-518"> // original SaslClient to unwrap the data we send back</span>
-<span class="source-line-no">519</span><span id="line-519"> saslServer.switchToCryptoAES(pair.getSecond());</span>
-<span class="source-line-no">520</span><span id="line-520"> }</span>
-<span class="source-line-no">521</span><span id="line-521"> });</span>
-<span class="source-line-no">522</span><span id="line-522"> } catch (IOException ex) {</span>
-<span class="source-line-no">523</span><span id="line-523"> throw new UnsupportedCryptoException(ex.getMessage(), ex);</span>
-<span class="source-line-no">524</span><span id="line-524"> }</span>
-<span class="source-line-no">525</span><span id="line-525"> }</span>
-<span class="source-line-no">526</span><span id="line-526"></span>
-<span class="source-line-no">527</span><span id="line-527"> protected abstract void doRespond(RpcResponse resp) throws IOException;</span>
-<span class="source-line-no">528</span><span id="line-528"></span>
-<span class="source-line-no">529</span><span id="line-529"> /**</span>
-<span class="source-line-no">530</span><span id="line-530"> * Has the request header and the request param and optionally encoded data buffer all in this one</span>
-<span class="source-line-no">531</span><span id="line-531"> * array.</span>
-<span class="source-line-no">532</span><span id="line-532"> * <p/></span>
-<span class="source-line-no">533</span><span id="line-533"> * Will be overridden in tests.</span>
-<span class="source-line-no">534</span><span id="line-534"> */</span>
-<span class="source-line-no">535</span><span id="line-535"> protected void processRequest(ByteBuff buf) throws IOException, InterruptedException {</span>
-<span class="source-line-no">536</span><span id="line-536"> long totalRequestSize = buf.limit();</span>
-<span class="source-line-no">537</span><span id="line-537"> int offset = 0;</span>
-<span class="source-line-no">538</span><span id="line-538"> // Here we read in the header. We avoid having pb</span>
-<span class="source-line-no">539</span><span id="line-539"> // do its default 4k allocation for CodedInputStream. We force it to use</span>
-<span class="source-line-no">540</span><span id="line-540"> // backing array.</span>
-<span class="source-line-no">541</span><span id="line-541"> CodedInputStream cis = createCis(buf);</span>
-<span class="source-line-no">542</span><span id="line-542"> int headerSize = cis.readRawVarint32();</span>
-<span class="source-line-no">543</span><span id="line-543"> offset = cis.getTotalBytesRead();</span>
-<span class="source-line-no">544</span><span id="line-544"> Message.Builder builder = RequestHeader.newBuilder();</span>
-<span class="source-line-no">545</span><span id="line-545"> ProtobufUtil.mergeFrom(builder, cis, headerSize);</span>
-<span class="source-line-no">546</span><span id="line-546"> RequestHeader header = (RequestHeader) builder.build();</span>
-<span class="source-line-no">547</span><span id="line-547"> offset += headerSize;</span>
-<span class="source-line-no">548</span><span id="line-548"> Context traceCtx = GlobalOpenTelemetry.getPropagators().getTextMapPropagator()</span>
-<span class="source-line-no">549</span><span id="line-549"> .extract(Context.current(), header.getTraceInfo(), getter);</span>
-<span class="source-line-no">550</span><span id="line-550"></span>
-<span class="source-line-no">551</span><span id="line-551"> // n.b. Management of this Span instance is a little odd. Most exit paths from this try scope</span>
-<span class="source-line-no">552</span><span id="line-552"> // are early-exits due to error cases. There's only one success path, the asynchronous call to</span>
-<span class="source-line-no">553</span><span id="line-553"> // RpcScheduler#dispatch. The success path assumes ownership of the span, which is represented</span>
-<span class="source-line-no">554</span><span id="line-554"> // by null-ing out the reference in this scope. All other paths end the span. Thus, and in</span>
-<span class="source-line-no">555</span><span id="line-555"> // order to avoid accidentally orphaning the span, the call to Span#end happens in a finally</span>
-<span class="source-line-no">556</span><span id="line-556"> // block iff the span is non-null.</span>
-<span class="source-line-no">557</span><span id="line-557"> Span span = TraceUtil.createRemoteSpan("RpcServer.process", traceCtx);</span>
-<span class="source-line-no">558</span><span id="line-558"> try (Scope ignored = span.makeCurrent()) {</span>
-<span class="source-line-no">559</span><span id="line-559"> int id = header.getCallId();</span>
-<span class="source-line-no">560</span><span id="line-560"> // HBASE-28128 - if server is aborting, don't bother trying to process. It will</span>
-<span class="source-line-no">561</span><span id="line-561"> // fail at the handler layer, but worse might result in CallQueueTooBigException if the</span>
-<span class="source-line-no">562</span><span id="line-562"> // queue is full but server is not properly processing requests. Better to throw an aborted</span>
-<span class="source-line-no">563</span><span id="line-563"> // exception here so that the client can properly react.</span>
-<span class="source-line-no">564</span><span id="line-564"> if (rpcServer.server != null && rpcServer.server.isAborted()) {</span>
-<span class="source-line-no">565</span><span id="line-565"> RegionServerAbortedException serverIsAborted = new RegionServerAbortedException(</span>
-<span class="source-line-no">566</span><span id="line-566"> "Server " + rpcServer.server.getServerName() + " aborting");</span>
-<span class="source-line-no">567</span><span id="line-567"> this.rpcServer.metrics.exception(serverIsAborted);</span>
-<span class="source-line-no">568</span><span id="line-568"> sendErrorResponseForCall(id, totalRequestSize, span, serverIsAborted.getMessage(),</span>
-<span class="source-line-no">569</span><span id="line-569"> serverIsAborted);</span>
-<span class="source-line-no">570</span><span id="line-570"> return;</span>
-<span class="source-line-no">571</span><span id="line-571"> }</span>
-<span class="source-line-no">572</span><span id="line-572"></span>
-<span class="source-line-no">573</span><span id="line-573"> if (RpcServer.LOG.isTraceEnabled()) {</span>
-<span class="source-line-no">574</span><span id="line-574"> RpcServer.LOG.trace("RequestHeader " + TextFormat.shortDebugString(header)</span>
-<span class="source-line-no">575</span><span id="line-575"> + " totalRequestSize: " + totalRequestSize + " bytes");</span>
-<span class="source-line-no">576</span><span id="line-576"> }</span>
-<span class="source-line-no">577</span><span id="line-577"> // Enforcing the call queue size, this triggers a retry in the client</span>
-<span class="source-line-no">578</span><span id="line-578"> // This is a bit late to be doing this check - we have already read in the</span>
-<span class="source-line-no">579</span><span id="line-579"> // total request.</span>
-<span class="source-line-no">580</span><span id="line-580"> if (</span>
-<span class="source-line-no">581</span><span id="line-581"> (totalRequestSize + this.rpcServer.callQueueSizeInBytes.sum())</span>
-<span class="source-line-no">582</span><span id="line-582"> > this.rpcServer.maxQueueSizeInBytes</span>
-<span class="source-line-no">583</span><span id="line-583"> ) {</span>
-<span class="source-line-no">584</span><span id="line-584"> this.rpcServer.metrics.exception(RpcServer.CALL_QUEUE_TOO_BIG_EXCEPTION);</span>
-<span class="source-line-no">585</span><span id="line-585"> sendErrorResponseForCall(id, totalRequestSize, span,</span>
-<span class="source-line-no">586</span><span id="line-586"> "Call queue is full on " + this.rpcServer.server.getServerName()</span>
-<span class="source-line-no">587</span><span id="line-587"> + ", is hbase.ipc.server.max.callqueue.size too small?",</span>
-<span class="source-line-no">588</span><span id="line-588"> RpcServer.CALL_QUEUE_TOO_BIG_EXCEPTION);</span>
-<span class="source-line-no">589</span><span id="line-589"> return;</span>
-<span class="source-line-no">590</span><span id="line-590"> }</span>
-<span class="source-line-no">591</span><span id="line-591"> MethodDescriptor md = null;</span>
-<span class="source-line-no">592</span><span id="line-592"> Message param = null;</span>
-<span class="source-line-no">593</span><span id="line-593"> ExtendedCellScanner cellScanner = null;</span>
-<span class="source-line-no">594</span><span id="line-594"> try {</span>
-<span class="source-line-no">595</span><span id="line-595"> if (header.hasRequestParam() && header.getRequestParam()) {</span>
-<span class="source-line-no">596</span><span id="line-596"> md = this.service.getDescriptorForType().findMethodByName(header.getMethodName());</span>
-<span class="source-line-no">597</span><span id="line-597"> if (md == null) {</span>
-<span class="source-line-no">598</span><span id="line-598"> throw new UnsupportedOperationException(header.getMethodName());</span>
-<span class="source-line-no">599</span><span id="line-599"> }</span>
-<span class="source-line-no">600</span><span id="line-600"> builder = this.service.getRequestPrototype(md).newBuilderForType();</span>
-<span class="source-line-no">601</span><span id="line-601"> cis.resetSizeCounter();</span>
-<span class="source-line-no">602</span><span id="line-602"> int paramSize = cis.readRawVarint32();</span>
-<span class="source-line-no">603</span><span id="line-603"> offset += cis.getTotalBytesRead();</span>
-<span class="source-line-no">604</span><span id="line-604"> if (builder != null) {</span>
-<span class="source-line-no">605</span><span id="line-605"> ProtobufUtil.mergeFrom(builder, cis, paramSize);</span>
-<span class="source-line-no">606</span><span id="line-606"> param = builder.build();</span>
-<span class="source-line-no">607</span><span id="line-607"> }</span>
-<span class="source-line-no">608</span><span id="line-608"> offset += paramSize;</span>
-<span class="source-line-no">609</span><span id="line-609"> } else {</span>
-<span class="source-line-no">610</span><span id="line-610"> // currently header must have request param, so we directly throw</span>
-<span class="source-line-no">611</span><span id="line-611"> // exception here</span>
-<span class="source-line-no">612</span><span id="line-612"> String msg = "Invalid request header: " + TextFormat.shortDebugString(header)</span>
-<span class="source-line-no">613</span><span id="line-613"> + ", should have param set in it";</span>
-<span class="source-line-no">614</span><span id="line-614"> RpcServer.LOG.warn(msg);</span>
-<span class="source-line-no">615</span><span id="line-615"> throw new DoNotRetryIOException(msg);</span>
-<span class="source-line-no">616</span><span id="line-616"> }</span>
-<span class="source-line-no">617</span><span id="line-617"> if (header.hasCellBlockMeta()) {</span>
-<span class="source-line-no">618</span><span id="line-618"> buf.position(offset);</span>
-<span class="source-line-no">619</span><span id="line-619"> ByteBuff dup = buf.duplicate();</span>
-<span class="source-line-no">620</span><span id="line-620"> dup.limit(offset + header.getCellBlockMeta().getLength());</span>
-<span class="source-line-no">621</span><span id="line-621"> cellScanner = this.rpcServer.cellBlockBuilder.createCellScannerReusingBuffers(this.codec,</span>
-<span class="source-line-no">622</span><span id="line-622"> this.compressionCodec, dup);</span>
-<span class="source-line-no">623</span><span id="line-623"> }</span>
-<span class="source-line-no">624</span><span id="line-624"> } catch (Throwable thrown) {</span>
-<span class="source-line-no">625</span><span id="line-625"> InetSocketAddress address = this.rpcServer.getListenerAddress();</span>
-<span class="source-line-no">626</span><span id="line-626"> String msg = (address != null ? address : "(channel closed)")</span>
-<span class="source-line-no">627</span><span id="line-627"> + " is unable to read call parameter from client " + getHostAddress();</span>
-<span class="source-line-no">628</span><span id="line-628"> RpcServer.LOG.warn(msg, thrown);</span>
-<span class="source-line-no">629</span><span id="line-629"></span>
-<span class="source-line-no">630</span><span id="line-630"> this.rpcServer.metrics.exception(thrown);</span>
-<span class="source-line-no">631</span><span id="line-631"></span>
-<span class="source-line-no">632</span><span id="line-632"> final Throwable responseThrowable;</span>
-<span class="source-line-no">633</span><span id="line-633"> if (thrown instanceof LinkageError) {</span>
-<span class="source-line-no">634</span><span id="line-634"> // probably the hbase hadoop version does not match the running hadoop version</span>
-<span class="source-line-no">635</span><span id="line-635"> responseThrowable = new DoNotRetryIOException(thrown);</span>
-<span class="source-line-no">636</span><span id="line-636"> } else if (thrown instanceof UnsupportedOperationException) {</span>
-<span class="source-line-no">637</span><span id="line-637"> // If the method is not present on the server, do not retry.</span>
-<span class="source-line-no">638</span><span id="line-638"> responseThrowable = new DoNotRetryIOException(thrown);</span>
-<span class="source-line-no">639</span><span id="line-639"> } else {</span>
-<span class="source-line-no">640</span><span id="line-640"> responseThrowable = thrown;</span>
-<span class="source-line-no">641</span><span id="line-641"> }</span>
-<span class="source-line-no">642</span><span id="line-642"></span>
-<span class="source-line-no">643</span><span id="line-643"> sendErrorResponseForCall(id, totalRequestSize, span,</span>
-<span class="source-line-no">644</span><span id="line-644"> msg + "; " + responseThrowable.getMessage(), responseThrowable);</span>
-<span class="source-line-no">645</span><span id="line-645"> return;</span>
-<span class="source-line-no">646</span><span id="line-646"> }</span>
-<span class="source-line-no">647</span><span id="line-647"></span>
-<span class="source-line-no">648</span><span id="line-648"> int timeout = 0;</span>
-<span class="source-line-no">649</span><span id="line-649"> if (header.hasTimeout() && header.getTimeout() > 0) {</span>
-<span class="source-line-no">650</span><span id="line-650"> timeout = Math.max(this.rpcServer.minClientRequestTimeout, header.getTimeout());</span>
-<span class="source-line-no">651</span><span id="line-651"> }</span>
-<span class="source-line-no">652</span><span id="line-652"> ServerCall<?> call = createCall(id, this.service, md, header, param, cellScanner,</span>
-<span class="source-line-no">653</span><span id="line-653"> totalRequestSize, this.addr, timeout, this.callCleanup);</span>
-<span class="source-line-no">654</span><span id="line-654"></span>
-<span class="source-line-no">655</span><span id="line-655"> if (this.rpcServer.scheduler.dispatch(new CallRunner(this.rpcServer, call))) {</span>
-<span class="source-line-no">656</span><span id="line-656"> // unset span do that it's not closed in the finally block</span>
-<span class="source-line-no">657</span><span id="line-657"> span = null;</span>
-<span class="source-line-no">658</span><span id="line-658"> } else {</span>
-<span class="source-line-no">659</span><span id="line-659"> this.rpcServer.callQueueSizeInBytes.add(-1 * call.getSize());</span>
-<span class="source-line-no">660</span><span id="line-660"> this.rpcServer.metrics.exception(RpcServer.CALL_QUEUE_TOO_BIG_EXCEPTION);</span>
-<span class="source-line-no">661</span><span id="line-661"> call.setResponse(null, null, RpcServer.CALL_QUEUE_TOO_BIG_EXCEPTION,</span>
-<span class="source-line-no">662</span><span id="line-662"> "Call queue is full on " + this.rpcServer.server.getServerName()</span>
-<span class="source-line-no">663</span><span id="line-663"> + ", too many items queued ?");</span>
-<span class="source-line-no">664</span><span id="line-664"> TraceUtil.setError(span, RpcServer.CALL_QUEUE_TOO_BIG_EXCEPTION);</span>
-<span class="source-line-no">665</span><span id="line-665"> call.sendResponseIfReady();</span>
-<span class="source-line-no">666</span><span id="line-666"> }</span>
-<span class="source-line-no">667</span><span id="line-667"> } finally {</span>
-<span class="source-line-no">668</span><span id="line-668"> if (span != null) {</span>
-<span class="source-line-no">669</span><span id="line-669"> span.end();</span>
+<span class="source-line-no">490</span><span id="line-490"> public ConnectionHeader getConnectionHeader() {</span>
+<span class="source-line-no">491</span><span id="line-491"> return connectionHeader;</span>
+<span class="source-line-no">492</span><span id="line-492"> }</span>
+<span class="source-line-no">493</span><span id="line-493"></span>
+<span class="source-line-no">494</span><span id="line-494"> /**</span>
+<span class="source-line-no">495</span><span id="line-495"> * Send the response for connection header</span>
+<span class="source-line-no">496</span><span id="line-496"> */</span>
+<span class="source-line-no">497</span><span id="line-497"> private void sendConnectionHeaderResponseIfNeeded() throws FatalConnectionException {</span>
+<span class="source-line-no">498</span><span id="line-498"> Pair<RPCProtos.ConnectionHeaderResponse, CryptoAES> pair = setupCryptoCipher();</span>
+<span class="source-line-no">499</span><span id="line-499"> // Response the connection header if Crypto AES is enabled</span>
+<span class="source-line-no">500</span><span id="line-500"> if (pair == null) {</span>
+<span class="source-line-no">501</span><span id="line-501"> return;</span>
+<span class="source-line-no">502</span><span id="line-502"> }</span>
+<span class="source-line-no">503</span><span id="line-503"> try {</span>
+<span class="source-line-no">504</span><span id="line-504"> int size = pair.getFirst().getSerializedSize();</span>
+<span class="source-line-no">505</span><span id="line-505"> BufferChain bc;</span>
+<span class="source-line-no">506</span><span id="line-506"> try (ByteBufferOutputStream bbOut = new ByteBufferOutputStream(4 + size);</span>
+<span class="source-line-no">507</span><span id="line-507"> DataOutputStream out = new DataOutputStream(bbOut)) {</span>
+<span class="source-line-no">508</span><span id="line-508"> out.writeInt(size);</span>
+<span class="source-line-no">509</span><span id="line-509"> pair.getFirst().writeTo(out);</span>
+<span class="source-line-no">510</span><span id="line-510"> bc = new BufferChain(bbOut.getByteBuffer());</span>
+<span class="source-line-no">511</span><span id="line-511"> }</span>
+<span class="source-line-no">512</span><span id="line-512"> doRespond(new RpcResponse() {</span>
+<span class="source-line-no">513</span><span id="line-513"></span>
+<span class="source-line-no">514</span><span id="line-514"> @Override</span>
+<span class="source-line-no">515</span><span id="line-515"> public BufferChain getResponse() {</span>
+<span class="source-line-no">516</span><span id="line-516"> return bc;</span>
+<span class="source-line-no">517</span><span id="line-517"> }</span>
+<span class="source-line-no">518</span><span id="line-518"></span>
+<span class="source-line-no">519</span><span id="line-519"> @Override</span>
+<span class="source-line-no">520</span><span id="line-520"> public void done() {</span>
+<span class="source-line-no">521</span><span id="line-521"> // must switch after sending the connection header response, as the client still uses the</span>
+<span class="source-line-no">522</span><span id="line-522"> // original SaslClient to unwrap the data we send back</span>
+<span class="source-line-no">523</span><span id="line-523"> saslServer.switchToCryptoAES(pair.getSecond());</span>
+<span class="source-line-no">524</span><span id="line-524"> }</span>
+<span class="source-line-no">525</span><span id="line-525"> });</span>
+<span class="source-line-no">526</span><span id="line-526"> } catch (IOException ex) {</span>
+<span class="source-line-no">527</span><span id="line-527"> throw new UnsupportedCryptoException(ex.getMessage(), ex);</span>
+<span class="source-line-no">528</span><span id="line-528"> }</span>
+<span class="source-line-no">529</span><span id="line-529"> }</span>
+<span class="source-line-no">530</span><span id="line-530"></span>
+<span class="source-line-no">531</span><span id="line-531"> protected abstract void doRespond(RpcResponse resp) throws IOException;</span>
+<span class="source-line-no">532</span><span id="line-532"></span>
+<span class="source-line-no">533</span><span id="line-533"> /**</span>
+<span class="source-line-no">534</span><span id="line-534"> * Has the request header and the request param and optionally encoded data buffer all in this one</span>
+<span class="source-line-no">535</span><span id="line-535"> * array.</span>
+<span class="source-line-no">536</span><span id="line-536"> * <p/></span>
+<span class="source-line-no">537</span><span id="line-537"> * Will be overridden in tests.</span>
+<span class="source-line-no">538</span><span id="line-538"> */</span>
+<span class="source-line-no">539</span><span id="line-539"> protected void processRequest(ByteBuff buf) throws IOException, InterruptedException {</span>
+<span class="source-line-no">540</span><span id="line-540"> long totalRequestSize = buf.limit();</span>
+<span class="source-line-no">541</span><span id="line-541"> int offset = 0;</span>
+<span class="source-line-no">542</span><span id="line-542"> // Here we read in the header. We avoid having pb</span>
+<span class="source-line-no">543</span><span id="line-543"> // do its default 4k allocation for CodedInputStream. We force it to use</span>
+<span class="source-line-no">544</span><span id="line-544"> // backing array.</span>
+<span class="source-line-no">545</span><span id="line-545"> CodedInputStream cis = createCis(buf);</span>
+<span class="source-line-no">546</span><span id="line-546"> int headerSize = cis.readRawVarint32();</span>
+<span class="source-line-no">547</span><span id="line-547"> offset = cis.getTotalBytesRead();</span>
+<span class="source-line-no">548</span><span id="line-548"> Message.Builder builder = RequestHeader.newBuilder();</span>
+<span class="source-line-no">549</span><span id="line-549"> ProtobufUtil.mergeFrom(builder, cis, headerSize);</span>
+<span class="source-line-no">550</span><span id="line-550"> RequestHeader header = (RequestHeader) builder.build();</span>
+<span class="source-line-no">551</span><span id="line-551"> offset += headerSize;</span>
+<span class="source-line-no">552</span><span id="line-552"> Context traceCtx = GlobalOpenTelemetry.getPropagators().getTextMapPropagator()</span>
+<span class="source-line-no">553</span><span id="line-553"> .extract(Context.current(), header.getTraceInfo(), getter);</span>
+<span class="source-line-no">554</span><span id="line-554"></span>
+<span class="source-line-no">555</span><span id="line-555"> // n.b. Management of this Span instance is a little odd. Most exit paths from this try scope</span>
+<span class="source-line-no">556</span><span id="line-556"> // are early-exits due to error cases. There's only one success path, the asynchronous call to</span>
+<span class="source-line-no">557</span><span id="line-557"> // RpcScheduler#dispatch. The success path assumes ownership of the span, which is represented</span>
+<span class="source-line-no">558</span><span id="line-558"> // by null-ing out the reference in this scope. All other paths end the span. Thus, and in</span>
+<span class="source-line-no">559</span><span id="line-559"> // order to avoid accidentally orphaning the span, the call to Span#end happens in a finally</span>
+<span class="source-line-no">560</span><span id="line-560"> // block iff the span is non-null.</span>
+<span class="source-line-no">561</span><span id="line-561"> Span span = TraceUtil.createRemoteSpan("RpcServer.process", traceCtx);</span>
+<span class="source-line-no">562</span><span id="line-562"> try (Scope ignored = span.makeCurrent()) {</span>
+<span class="source-line-no">563</span><span id="line-563"> int id = header.getCallId();</span>
+<span class="source-line-no">564</span><span id="line-564"> // HBASE-28128 - if server is aborting, don't bother trying to process. It will</span>
+<span class="source-line-no">565</span><span id="line-565"> // fail at the handler layer, but worse might result in CallQueueTooBigException if the</span>
+<span class="source-line-no">566</span><span id="line-566"> // queue is full but server is not properly processing requests. Better to throw an aborted</span>
+<span class="source-line-no">567</span><span id="line-567"> // exception here so that the client can properly react.</span>
+<span class="source-line-no">568</span><span id="line-568"> if (rpcServer.server != null && rpcServer.server.isAborted()) {</span>
+<span class="source-line-no">569</span><span id="line-569"> RegionServerAbortedException serverIsAborted = new RegionServerAbortedException(</span>
+<span class="source-line-no">570</span><span id="line-570"> "Server " + rpcServer.server.getServerName() + " aborting");</span>
+<span class="source-line-no">571</span><span id="line-571"> this.rpcServer.metrics.exception(serverIsAborted);</span>
+<span class="source-line-no">572</span><span id="line-572"> sendErrorResponseForCall(id, totalRequestSize, span, serverIsAborted.getMessage(),</span>
+<span class="source-line-no">573</span><span id="line-573"> serverIsAborted);</span>
+<span class="source-line-no">574</span><span id="line-574"> return;</span>
+<span class="source-line-no">575</span><span id="line-575"> }</span>
+<span class="source-line-no">576</span><span id="line-576"></span>
+<span class="source-line-no">577</span><span id="line-577"> if (RpcServer.LOG.isTraceEnabled()) {</span>
+<span class="source-line-no">578</span><span id="line-578"> RpcServer.LOG.trace("RequestHeader " + TextFormat.shortDebugString(header)</span>
+<span class="source-line-no">579</span><span id="line-579"> + " totalRequestSize: " + totalRequestSize + " bytes");</span>
+<span class="source-line-no">580</span><span id="line-580"> }</span>
+<span class="source-line-no">581</span><span id="line-581"> // Enforcing the call queue size, this triggers a retry in the client</span>
+<span class="source-line-no">582</span><span id="line-582"> // This is a bit late to be doing this check - we have already read in the</span>
+<span class="source-line-no">583</span><span id="line-583"> // total request.</span>
+<span class="source-line-no">584</span><span id="line-584"> if (</span>
+<span class="source-line-no">585</span><span id="line-585"> (totalRequestSize + this.rpcServer.callQueueSizeInBytes.sum())</span>
+<span class="source-line-no">586</span><span id="line-586"> > this.rpcServer.maxQueueSizeInBytes</span>
+<span class="source-line-no">587</span><span id="line-587"> ) {</span>
+<span class="source-line-no">588</span><span id="line-588"> this.rpcServer.metrics.exception(RpcServer.CALL_QUEUE_TOO_BIG_EXCEPTION);</span>
+<span class="source-line-no">589</span><span id="line-589"> sendErrorResponseForCall(id, totalRequestSize, span,</span>
+<span class="source-line-no">590</span><span id="line-590"> "Call queue is full on " + this.rpcServer.server.getServerName()</span>
+<span class="source-line-no">591</span><span id="line-591"> + ", is hbase.ipc.server.max.callqueue.size too small?",</span>
+<span class="source-line-no">592</span><span id="line-592"> RpcServer.CALL_QUEUE_TOO_BIG_EXCEPTION);</span>
+<span class="source-line-no">593</span><span id="line-593"> return;</span>
+<span class="source-line-no">594</span><span id="line-594"> }</span>
+<span class="source-line-no">595</span><span id="line-595"> MethodDescriptor md = null;</span>
+<span class="source-line-no">596</span><span id="line-596"> Message param = null;</span>
+<span class="source-line-no">597</span><span id="line-597"> ExtendedCellScanner cellScanner = null;</span>
+<span class="source-line-no">598</span><span id="line-598"> try {</span>
+<span class="source-line-no">599</span><span id="line-599"> if (header.hasRequestParam() && header.getRequestParam()) {</span>
+<span class="source-line-no">600</span><span id="line-600"> md = this.service.getDescriptorForType().findMethodByName(header.getMethodName());</span>
+<span class="source-line-no">601</span><span id="line-601"> if (md == null) {</span>
+<span class="source-line-no">602</span><span id="line-602"> throw new UnsupportedOperationException(header.getMethodName());</span>
+<span class="source-line-no">603</span><span id="line-603"> }</span>
+<span class="source-line-no">604</span><span id="line-604"> builder = this.service.getRequestPrototype(md).newBuilderForType();</span>
+<span class="source-line-no">605</span><span id="line-605"> cis.resetSizeCounter();</span>
+<span class="source-line-no">606</span><span id="line-606"> int paramSize = cis.readRawVarint32();</span>
+<span class="source-line-no">607</span><span id="line-607"> offset += cis.getTotalBytesRead();</span>
+<span class="source-line-no">608</span><span id="line-608"> if (builder != null) {</span>
+<span class="source-line-no">609</span><span id="line-609"> ProtobufUtil.mergeFrom(builder, cis, paramSize);</span>
+<span class="source-line-no">610</span><span id="line-610"> param = builder.build();</span>
+<span class="source-line-no">611</span><span id="line-611"> }</span>
+<span class="source-line-no">612</span><span id="line-612"> offset += paramSize;</span>
+<span class="source-line-no">613</span><span id="line-613"> } else {</span>
+<span class="source-line-no">614</span><span id="line-614"> // currently header must have request param, so we directly throw</span>
+<span class="source-line-no">615</span><span id="line-615"> // exception here</span>
+<span class="source-line-no">616</span><span id="line-616"> String msg = "Invalid request header: " + TextFormat.shortDebugString(header)</span>
+<span class="source-line-no">617</span><span id="line-617"> + ", should have param set in it";</span>
+<span class="source-line-no">618</span><span id="line-618"> RpcServer.LOG.warn(msg);</span>
+<span class="source-line-no">619</span><span id="line-619"> throw new DoNotRetryIOException(msg);</span>
+<span class="source-line-no">620</span><span id="line-620"> }</span>
+<span class="source-line-no">621</span><span id="line-621"> if (header.hasCellBlockMeta()) {</span>
+<span class="source-line-no">622</span><span id="line-622"> buf.position(offset);</span>
+<span class="source-line-no">623</span><span id="line-623"> ByteBuff dup = buf.duplicate();</span>
+<span class="source-line-no">624</span><span id="line-624"> dup.limit(offset + header.getCellBlockMeta().getLength());</span>
+<span class="source-line-no">625</span><span id="line-625"> cellScanner = this.rpcServer.cellBlockBuilder.createCellScannerReusingBuffers(this.codec,</span>
+<span class="source-line-no">626</span><span id="line-626"> this.compressionCodec, dup);</span>
+<span class="source-line-no">627</span><span id="line-627"> }</span>
+<span class="source-line-no">628</span><span id="line-628"> } catch (Throwable thrown) {</span>
+<span class="source-line-no">629</span><span id="line-629"> InetSocketAddress address = this.rpcServer.getListenerAddress();</span>
+<span class="source-line-no">630</span><span id="line-630"> String msg = (address != null ? address : "(channel closed)")</span>
+<span class="source-line-no">631</span><span id="line-631"> + " is unable to read call parameter from client " + getHostAddress();</span>
+<span class="source-line-no">632</span><span id="line-632"> RpcServer.LOG.warn(msg, thrown);</span>
+<span class="source-line-no">633</span><span id="line-633"></span>
+<span class="source-line-no">634</span><span id="line-634"> this.rpcServer.metrics.exception(thrown);</span>
+<span class="source-line-no">635</span><span id="line-635"></span>
+<span class="source-line-no">636</span><span id="line-636"> final Throwable responseThrowable;</span>
+<span class="source-line-no">637</span><span id="line-637"> if (thrown instanceof LinkageError) {</span>
+<span class="source-line-no">638</span><span id="line-638"> // probably the hbase hadoop version does not match the running hadoop version</span>
+<span class="source-line-no">639</span><span id="line-639"> responseThrowable = new DoNotRetryIOException(thrown);</span>
+<span class="source-line-no">640</span><span id="line-640"> } else if (thrown instanceof UnsupportedOperationException) {</span>
+<span class="source-line-no">641</span><span id="line-641"> // If the method is not present on the server, do not retry.</span>
+<span class="source-line-no">642</span><span id="line-642"> responseThrowable = new DoNotRetryIOException(thrown);</span>
+<span class="source-line-no">643</span><span id="line-643"> } else {</span>
+<span class="source-line-no">644</span><span id="line-644"> responseThrowable = thrown;</span>
+<span class="source-line-no">645</span><span id="line-645"> }</span>
+<span class="source-line-no">646</span><span id="line-646"></span>
+<span class="source-line-no">647</span><span id="line-647"> sendErrorResponseForCall(id, totalRequestSize, span,</span>
+<span class="source-line-no">648</span><span id="line-648"> msg + "; " + responseThrowable.getMessage(), responseThrowable);</span>
+<span class="source-line-no">649</span><span id="line-649"> return;</span>
+<span class="source-line-no">650</span><span id="line-650"> }</span>
+<span class="source-line-no">651</span><span id="line-651"></span>
+<span class="source-line-no">652</span><span id="line-652"> int timeout = 0;</span>
+<span class="source-line-no">653</span><span id="line-653"> if (header.hasTimeout() && header.getTimeout() > 0) {</span>
+<span class="source-line-no">654</span><span id="line-654"> timeout = Math.max(this.rpcServer.minClientRequestTimeout, header.getTimeout());</span>
+<span class="source-line-no">655</span><span id="line-655"> }</span>
+<span class="source-line-no">656</span><span id="line-656"> ServerCall<?> call = createCall(id, this.service, md, header, param, cellScanner,</span>
+<span class="source-line-no">657</span><span id="line-657"> totalRequestSize, this.addr, timeout, this.callCleanup);</span>
+<span class="source-line-no">658</span><span id="line-658"></span>
+<span class="source-line-no">659</span><span id="line-659"> if (this.rpcServer.scheduler.dispatch(new CallRunner(this.rpcServer, call))) {</span>
+<span class="source-line-no">660</span><span id="line-660"> // unset span do that it's not closed in the finally block</span>
+<span class="source-line-no">661</span><span id="line-661"> span = null;</span>
+<span class="source-line-no">662</span><span id="line-662"> } else {</span>
+<span class="source-line-no">663</span><span id="line-663"> this.rpcServer.callQueueSizeInBytes.add(-1 * call.getSize());</span>
+<span class="source-line-no">664</span><span id="line-664"> this.rpcServer.metrics.exception(RpcServer.CALL_QUEUE_TOO_BIG_EXCEPTION);</span>
+<span class="source-line-no">665</span><span id="line-665"> call.setResponse(null, null, RpcServer.CALL_QUEUE_TOO_BIG_EXCEPTION,</span>
+<span class="source-line-no">666</span><span id="line-666"> "Call queue is full on " + this.rpcServer.server.getServerName()</span>
+<span class="source-line-no">667</span><span id="line-667"> + ", too many items queued ?");</span>
+<span class="source-line-no">668</span><span id="line-668"> TraceUtil.setError(span, RpcServer.CALL_QUEUE_TOO_BIG_EXCEPTION);</span>
+<span class="source-line-no">669</span><span id="line-669"> call.sendResponseIfReady();</span>
<span class="source-line-no">670</span><span id="line-670"> }</span>
-<span class="source-line-no">671</span><span id="line-671"> }</span>
-<span class="source-line-no">672</span><span id="line-672"> }</span>
-<span class="source-line-no">673</span><span id="line-673"></span>
-<span class="source-line-no">674</span><span id="line-674"> private void sendErrorResponseForCall(int id, long totalRequestSize, Span span, String msg,</span>
-<span class="source-line-no">675</span><span id="line-675"> Throwable responseThrowable) throws IOException {</span>
-<span class="source-line-no">676</span><span id="line-676"> ServerCall<?> failedcall = createCall(id, this.service, null, null, null, null,</span>
-<span class="source-line-no">677</span><span id="line-677"> totalRequestSize, null, 0, this.callCleanup);</span>
-<span class="source-line-no">678</span><span id="line-678"> failedcall.setResponse(null, null, responseThrowable, msg);</span>
-<span class="source-line-no">679</span><span id="line-679"> TraceUtil.setError(span, responseThrowable);</span>
-<span class="source-line-no">680</span><span id="line-680"> failedcall.sendResponseIfReady();</span>
-<span class="source-line-no">681</span><span id="line-681"> }</span>
-<span class="source-line-no">682</span><span id="line-682"></span>
-<span class="source-line-no">683</span><span id="line-683"> protected final RpcResponse getErrorResponse(String msg, Exception e) throws IOException {</span>
-<span class="source-line-no">684</span><span id="line-684"> ResponseHeader.Builder headerBuilder = ResponseHeader.newBuilder().setCallId(-1);</span>
-<span class="source-line-no">685</span><span id="line-685"> ServerCall.setExceptionResponse(e, msg, headerBuilder);</span>
-<span class="source-line-no">686</span><span id="line-686"> ByteBuffer headerBuf =</span>
-<span class="source-line-no">687</span><span id="line-687"> ServerCall.createHeaderAndMessageBytes(null, headerBuilder.build(), 0, null);</span>
-<span class="source-line-no">688</span><span id="line-688"> BufferChain buf = new BufferChain(headerBuf);</span>
-<span class="source-line-no">689</span><span id="line-689"> return () -> buf;</span>
-<span class="source-line-no">690</span><span id="line-690"> }</span>
-<span class="source-line-no">691</span><span id="line-691"></span>
-<span class="source-line-no">692</span><span id="line-692"> private void doBadPreambleHandling(String msg) throws IOException {</span>
-<span class="source-line-no">693</span><span id="line-693"> doBadPreambleHandling(msg, new FatalConnectionException(msg));</span>
+<span class="source-line-no">671</span><span id="line-671"> } finally {</span>
+<span class="source-line-no">672</span><span id="line-672"> if (span != null) {</span>
+<span class="source-line-no">673</span><span id="line-673"> span.end();</span>
+<span class="source-line-no">674</span><span id="line-674"> }</span>
+<span class="source-line-no">675</span><span id="line-675"> }</span>
+<span class="source-line-no">676</span><span id="line-676"> }</span>
+<span class="source-line-no">677</span><span id="line-677"></span>
+<span class="source-line-no">678</span><span id="line-678"> private void sendErrorResponseForCall(int id, long totalRequestSize, Span span, String msg,</span>
+<span class="source-line-no">679</span><span id="line-679"> Throwable responseThrowable) throws IOException {</span>
+<span class="source-line-no">680</span><span id="line-680"> ServerCall<?> failedcall = createCall(id, this.service, null, null, null, null,</span>
+<span class="source-line-no">681</span><span id="line-681"> totalRequestSize, null, 0, this.callCleanup);</span>
+<span class="source-line-no">682</span><span id="line-682"> failedcall.setResponse(null, null, responseThrowable, msg);</span>
+<span class="source-line-no">683</span><span id="line-683"> TraceUtil.setError(span, responseThrowable);</span>
+<span class="source-line-no">684</span><span id="line-684"> failedcall.sendResponseIfReady();</span>
+<span class="source-line-no">685</span><span id="line-685"> }</span>
+<span class="source-line-no">686</span><span id="line-686"></span>
+<span class="source-line-no">687</span><span id="line-687"> protected final RpcResponse getErrorResponse(String msg, Exception e) throws IOException {</span>
+<span class="source-line-no">688</span><span id="line-688"> ResponseHeader.Builder headerBuilder = ResponseHeader.newBuilder().setCallId(-1);</span>
+<span class="source-line-no">689</span><span id="line-689"> ServerCall.setExceptionResponse(e, msg, headerBuilder);</span>
+<span class="source-line-no">690</span><span id="line-690"> ByteBuffer headerBuf =</span>
+<span class="source-line-no">691</span><span id="line-691"> ServerCall.createHeaderAndMessageBytes(null, headerBuilder.build(), 0, null);</span>
+<span class="source-line-no">692</span><span id="line-692"> BufferChain buf = new BufferChain(headerBuf);</span>
+<span class="source-line-no">693</span><span id="line-693"> return () -> buf;</span>
<span class="source-line-no">694</span><span id="line-694"> }</span>
<span class="source-line-no">695</span><span id="line-695"></span>
-<span class="source-line-no">696</span><span id="line-696"> private void doBadPreambleHandling(String msg, Exception e) throws IOException {</span>
-<span class="source-line-no">697</span><span id="line-697"> RpcServer.LOG.warn(msg, e);</span>
-<span class="source-line-no">698</span><span id="line-698"> doRespond(getErrorResponse(msg, e));</span>
-<span class="source-line-no">699</span><span id="line-699"> }</span>
-<span class="source-line-no">700</span><span id="line-700"></span>
-<span class="source-line-no">701</span><span id="line-701"> private void doPreambleResponse(Message resp) throws IOException {</span>
-<span class="source-line-no">702</span><span id="line-702"> ResponseHeader header = ResponseHeader.newBuilder().setCallId(-1).build();</span>
-<span class="source-line-no">703</span><span id="line-703"> ByteBuffer buf = ServerCall.createHeaderAndMessageBytes(resp, header, 0, null);</span>
-<span class="source-line-no">704</span><span id="line-704"> BufferChain bufChain = new BufferChain(buf);</span>
-<span class="source-line-no">705</span><span id="line-705"> doRespond(() -> bufChain);</span>
-<span class="source-line-no">706</span><span id="line-706"> }</span>
-<span class="source-line-no">707</span><span id="line-707"></span>
-<span class="source-line-no">708</span><span id="line-708"> private boolean doConnectionRegistryResponse() throws IOException {</span>
-<span class="source-line-no">709</span><span id="line-709"> if (!(rpcServer.server instanceof ConnectionRegistryEndpoint)) {</span>
-<span class="source-line-no">710</span><span id="line-710"> // should be in tests or some scenarios where we should not reach here</span>
-<span class="source-line-no">711</span><span id="line-711"> return false;</span>
-<span class="source-line-no">712</span><span id="line-712"> }</span>
-<span class="source-line-no">713</span><span id="line-713"> // on backup masters, this request may be blocked since we need to fetch it from filesystem,</span>
-<span class="source-line-no">714</span><span id="line-714"> // but since it is just backup master, it is not a critical problem</span>
-<span class="source-line-no">715</span><span id="line-715"> String clusterId = ((ConnectionRegistryEndpoint) rpcServer.server).getClusterId();</span>
-<span class="source-line-no">716</span><span id="line-716"> RpcServer.LOG.debug("Response connection registry, clusterId = '{}'", clusterId);</span>
-<span class="source-line-no">717</span><span id="line-717"> if (clusterId == null) {</span>
-<span class="source-line-no">718</span><span id="line-718"> // should be in tests or some scenarios where we should not reach here</span>
-<span class="source-line-no">719</span><span id="line-719"> return false;</span>
-<span class="source-line-no">720</span><span id="line-720"> }</span>
-<span class="source-line-no">721</span><span id="line-721"> GetConnectionRegistryResponse resp =</span>
-<span class="source-line-no">722</span><span id="line-722"> GetConnectionRegistryResponse.newBuilder().setClusterId(clusterId).build();</span>
-<span class="source-line-no">723</span><span id="line-723"> doPreambleResponse(resp);</span>
-<span class="source-line-no">724</span><span id="line-724"> return true;</span>
-<span class="source-line-no">725</span><span id="line-725"> }</span>
-<span class="source-line-no">726</span><span id="line-726"></span>
-<span class="source-line-no">727</span><span id="line-727"> private void doSecurityPreambleResponse() throws IOException {</span>
-<span class="source-line-no">728</span><span id="line-728"> if (rpcServer.isSecurityEnabled) {</span>
-<span class="source-line-no">729</span><span id="line-729"> SecurityPreamableResponse resp = SecurityPreamableResponse.newBuilder()</span>
-<span class="source-line-no">730</span><span id="line-730"> .setServerPrincipal(rpcServer.serverPrincipal).build();</span>
-<span class="source-line-no">731</span><span id="line-731"> doPreambleResponse(resp);</span>
-<span class="source-line-no">732</span><span id="line-732"> } else {</span>
-<span class="source-line-no">733</span><span id="line-733"> // security is not enabled, do not need a principal when connecting, throw a special exception</span>
-<span class="source-line-no">734</span><span id="line-734"> // to let client know it should just use simple authentication</span>
-<span class="source-line-no">735</span><span id="line-735"> doRespond(getErrorResponse("security is not enabled", new SecurityNotEnabledException()));</span>
-<span class="source-line-no">736</span><span id="line-736"> }</span>
-<span class="source-line-no">737</span><span id="line-737"> }</span>
-<span class="source-line-no">738</span><span id="line-738"></span>
-<span class="source-line-no">739</span><span id="line-739"> protected final void callCleanupIfNeeded() {</span>
-<span class="source-line-no">740</span><span id="line-740"> if (callCleanup != null) {</span>
-<span class="source-line-no">741</span><span id="line-741"> callCleanup.run();</span>
-<span class="source-line-no">742</span><span id="line-742"> callCleanup = null;</span>
-<span class="source-line-no">743</span><span id="line-743"> }</span>
-<span class="source-line-no">744</span><span id="line-744"> }</span>
-<span class="source-line-no">745</span><span id="line-745"></span>
-<span class="source-line-no">746</span><span id="line-746"> protected enum PreambleResponse {</span>
-<span class="source-line-no">747</span><span id="line-747"> SUCCEED, // successfully processed the rpc preamble header</span>
-<span class="source-line-no">748</span><span id="line-748"> CONTINUE, // the preamble header is for other purpose, wait for the rpc preamble header</span>
-<span class="source-line-no">749</span><span id="line-749"> CLOSE // close the rpc connection</span>
-<span class="source-line-no">750</span><span id="line-750"> }</span>
-<span class="source-line-no">751</span><span id="line-751"></span>
-<span class="source-line-no">752</span><span id="line-752"> protected final PreambleResponse processPreamble(ByteBuffer preambleBuffer) throws IOException {</span>
-<span class="source-line-no">753</span><span id="line-753"> assert preambleBuffer.remaining() == 6;</span>
-<span class="source-line-no">754</span><span id="line-754"> if (</span>
-<span class="source-line-no">755</span><span id="line-755"> ByteBufferUtils.equals(preambleBuffer, preambleBuffer.position(), 6,</span>
-<span class="source-line-no">756</span><span id="line-756"> RpcClient.REGISTRY_PREAMBLE_HEADER, 0, 6) && doConnectionRegistryResponse()</span>
-<span class="source-line-no">757</span><span id="line-757"> ) {</span>
-<span class="source-line-no">758</span><span id="line-758"> return PreambleResponse.CLOSE;</span>
-<span class="source-line-no">759</span><span id="line-759"> }</span>
-<span class="source-line-no">760</span><span id="line-760"> if (</span>
-<span class="source-line-no">761</span><span id="line-761"> ByteBufferUtils.equals(preambleBuffer, preambleBuffer.position(), 6,</span>
-<span class="source-line-no">762</span><span id="line-762"> RpcClient.SECURITY_PREAMBLE_HEADER, 0, 6)</span>
-<span class="source-line-no">763</span><span id="line-763"> ) {</span>
-<span class="source-line-no">764</span><span id="line-764"> doSecurityPreambleResponse();</span>
-<span class="source-line-no">765</span><span id="line-765"> return PreambleResponse.CONTINUE;</span>
-<span class="source-line-no">766</span><span id="line-766"> }</span>
-<span class="source-line-no">767</span><span id="line-767"> if (!ByteBufferUtils.equals(preambleBuffer, preambleBuffer.position(), 4, RPC_HEADER, 0, 4)) {</span>
-<span class="source-line-no">768</span><span id="line-768"> doBadPreambleHandling(</span>
-<span class="source-line-no">769</span><span id="line-769"> "Expected HEADER=" + Bytes.toStringBinary(RPC_HEADER) + " but received HEADER="</span>
-<span class="source-line-no">770</span><span id="line-770"> + Bytes.toStringBinary(</span>
-<span class="source-line-no">771</span><span id="line-771"> ByteBufferUtils.toBytes(preambleBuffer, preambleBuffer.position(), RPC_HEADER.length),</span>
-<span class="source-line-no">772</span><span id="line-772"> 0, RPC_HEADER.length)</span>
-<span class="source-line-no">773</span><span id="line-773"> + " from " + toString());</span>
-<span class="source-line-no">774</span><span id="line-774"> return PreambleResponse.CLOSE;</span>
-<span class="source-line-no">775</span><span id="line-775"> }</span>
-<span class="source-line-no">776</span><span id="line-776"> int version = preambleBuffer.get(preambleBuffer.position() + 4) & 0xFF;</span>
-<span class="source-line-no">777</span><span id="line-777"> byte authByte = preambleBuffer.get(preambleBuffer.position() + 5);</span>
-<span class="source-line-no">778</span><span id="line-778"> if (version != RpcServer.CURRENT_VERSION) {</span>
-<span class="source-line-no">779</span><span id="line-779"> String msg = getFatalConnectionString(version, authByte);</span>
-<span class="source-line-no">780</span><span id="line-780"> doBadPreambleHandling(msg, new WrongVersionException(msg));</span>
-<span class="source-line-no">781</span><span id="line-781"> return PreambleResponse.CLOSE;</span>
-<span class="source-line-no">782</span><span id="line-782"> }</span>
-<span class="source-line-no">783</span><span id="line-783"></span>
-<span class="source-line-no">784</span><span id="line-784"> this.provider = rpcServer.saslProviders.selectProvider(authByte);</span>
-<span class="source-line-no">785</span><span id="line-785"> if (this.provider == null) {</span>
-<span class="source-line-no">786</span><span id="line-786"> String msg = getFatalConnectionString(version, authByte);</span>
-<span class="source-line-no">787</span><span id="line-787"> doBadPreambleHandling(msg, new BadAuthException(msg));</span>
-<span class="source-line-no">788</span><span id="line-788"> return PreambleResponse.CLOSE;</span>
-<span class="source-line-no">789</span><span id="line-789"> }</span>
-<span class="source-line-no">790</span><span id="line-790"> // TODO this is a wart while simple auth'n doesn't go through sasl.</span>
-<span class="source-line-no">791</span><span id="line-791"> if (this.rpcServer.isSecurityEnabled && isSimpleAuthentication()) {</span>
-<span class="source-line-no">792</span><span id="line-792"> if (this.rpcServer.allowFallbackToSimpleAuth) {</span>
-<span class="source-line-no">793</span><span id="line-793"> this.rpcServer.metrics.authenticationFallback();</span>
-<span class="source-line-no">794</span><span id="line-794"> authenticatedWithFallback = true;</span>
-<span class="source-line-no">795</span><span id="line-795"> } else {</span>
-<span class="source-line-no">796</span><span id="line-796"> AccessDeniedException ae = new AccessDeniedException("Authentication is required");</span>
-<span class="source-line-no">797</span><span id="line-797"> doRespond(getErrorResponse(ae.getMessage(), ae));</span>
-<span class="source-line-no">798</span><span id="line-798"> return PreambleResponse.CLOSE;</span>
-<span class="source-line-no">799</span><span id="line-799"> }</span>
-<span class="source-line-no">800</span><span id="line-800"> }</span>
-<span class="source-line-no">801</span><span id="line-801"> if (!this.rpcServer.isSecurityEnabled && !isSimpleAuthentication()) {</span>
-<span class="source-line-no">802</span><span id="line-802"> doRawSaslReply(SaslStatus.SUCCESS, new IntWritable(SaslUtil.SWITCH_TO_SIMPLE_AUTH), null,</span>
-<span class="source-line-no">803</span><span id="line-803"> null);</span>
-<span class="source-line-no">804</span><span id="line-804"> provider = rpcServer.saslProviders.getSimpleProvider();</span>
-<span class="source-line-no">805</span><span id="line-805"> // client has already sent the initial Sasl message and we</span>
-<span class="source-line-no">806</span><span id="line-806"> // should ignore it. Both client and server should fall back</span>
-<span class="source-line-no">807</span><span id="line-807"> // to simple auth from now on.</span>
-<span class="source-line-no">808</span><span id="line-808"> skipInitialSaslHandshake = true;</span>
-<span class="source-line-no">809</span><span id="line-809"> }</span>
-<span class="source-line-no">810</span><span id="line-810"> useSasl = !(provider instanceof SimpleSaslServerAuthenticationProvider);</span>
-<span class="source-line-no">811</span><span id="line-811"> return PreambleResponse.SUCCEED;</span>
-<span class="source-line-no">812</span><span id="line-812"> }</span>
-<span class="source-line-no">813</span><span id="line-813"></span>
-<span class="source-line-no">814</span><span id="line-814"> boolean isSimpleAuthentication() {</span>
-<span class="source-line-no">815</span><span id="line-815"> return Objects.requireNonNull(provider) instanceof SimpleSaslServerAuthenticationProvider;</span>
+<span class="source-line-no">696</span><span id="line-696"> private void doBadPreambleHandling(String msg) throws IOException {</span>
+<span class="source-line-no">697</span><span id="line-697"> doBadPreambleHandling(msg, new FatalConnectionException(msg));</span>
+<span class="source-line-no">698</span><span id="line-698"> }</span>
+<span class="source-line-no">699</span><span id="line-699"></span>
+<span class="source-line-no">700</span><span id="line-700"> private void doBadPreambleHandling(String msg, Exception e) throws IOException {</span>
+<span class="source-line-no">701</span><span id="line-701"> RpcServer.LOG.warn(msg, e);</span>
+<span class="source-line-no">702</span><span id="line-702"> doRespond(getErrorResponse(msg, e));</span>
+<span class="source-line-no">703</span><span id="line-703"> }</span>
+<span class="source-line-no">704</span><span id="line-704"></span>
+<span class="source-line-no">705</span><span id="line-705"> private void doPreambleResponse(Message resp) throws IOException {</span>
+<span class="source-line-no">706</span><span id="line-706"> ResponseHeader header = ResponseHeader.newBuilder().setCallId(-1).build();</span>
+<span class="source-line-no">707</span><span id="line-707"> ByteBuffer buf = ServerCall.createHeaderAndMessageBytes(resp, header, 0, null);</span>
+<span class="source-line-no">708</span><span id="line-708"> BufferChain bufChain = new BufferChain(buf);</span>
+<span class="source-line-no">709</span><span id="line-709"> doRespond(() -> bufChain);</span>
+<span class="source-line-no">710</span><span id="line-710"> }</span>
+<span class="source-line-no">711</span><span id="line-711"></span>
+<span class="source-line-no">712</span><span id="line-712"> private boolean doConnectionRegistryResponse() throws IOException {</span>
+<span class="source-line-no">713</span><span id="line-713"> if (!(rpcServer.server instanceof ConnectionRegistryEndpoint)) {</span>
+<span class="source-line-no">714</span><span id="line-714"> // should be in tests or some scenarios where we should not reach here</span>
+<span class="source-line-no">715</span><span id="line-715"> return false;</span>
+<span class="source-line-no">716</span><span id="line-716"> }</span>
+<span class="source-line-no">717</span><span id="line-717"> // on backup masters, this request may be blocked since we need to fetch it from filesystem,</span>
+<span class="source-line-no">718</span><span id="line-718"> // but since it is just backup master, it is not a critical problem</span>
+<span class="source-line-no">719</span><span id="line-719"> String clusterId = ((ConnectionRegistryEndpoint) rpcServer.server).getClusterId();</span>
+<span class="source-line-no">720</span><span id="line-720"> RpcServer.LOG.debug("Response connection registry, clusterId = '{}'", clusterId);</span>
+<span class="source-line-no">721</span><span id="line-721"> if (clusterId == null) {</span>
+<span class="source-line-no">722</span><span id="line-722"> // should be in tests or some scenarios where we should not reach here</span>
+<span class="source-line-no">723</span><span id="line-723"> return false;</span>
+<span class="source-line-no">724</span><span id="line-724"> }</span>
+<span class="source-line-no">725</span><span id="line-725"> GetConnectionRegistryResponse resp =</span>
+<span class="source-line-no">726</span><span id="line-726"> GetConnectionRegistryResponse.newBuilder().setClusterId(clusterId).build();</span>
+<span class="source-line-no">727</span><span id="line-727"> doPreambleResponse(resp);</span>
+<span class="source-line-no">728</span><span id="line-728"> return true;</span>
+<span class="source-line-no">729</span><span id="line-729"> }</span>
+<span class="source-line-no">730</span><span id="line-730"></span>
+<span class="source-line-no">731</span><span id="line-731"> private void doSecurityPreambleResponse() throws IOException {</span>
+<span class="source-line-no">732</span><span id="line-732"> if (rpcServer.isSecurityEnabled) {</span>
+<span class="source-line-no">733</span><span id="line-733"> SecurityPreamableResponse resp = SecurityPreamableResponse.newBuilder()</span>
+<span class="source-line-no">734</span><span id="line-734"> .setServerPrincipal(rpcServer.serverPrincipal).build();</span>
+<span class="source-line-no">735</span><span id="line-735"> doPreambleResponse(resp);</span>
+<span class="source-line-no">736</span><span id="line-736"> } else {</span>
+<span class="source-line-no">737</span><span id="line-737"> // security is not enabled, do not need a principal when connecting, throw a special exception</span>
+<span class="source-line-no">738</span><span id="line-738"> // to let client know it should just use simple authentication</span>
+<span class="source-line-no">739</span><span id="line-739"> doRespond(getErrorResponse("security is not enabled", new SecurityNotEnabledException()));</span>
+<span class="source-line-no">740</span><span id="line-740"> }</span>
+<span class="source-line-no">741</span><span id="line-741"> }</span>
+<span class="source-line-no">742</span><span id="line-742"></span>
+<span class="source-line-no">743</span><span id="line-743"> protected final void callCleanupIfNeeded() {</span>
+<span class="source-line-no">744</span><span id="line-744"> if (callCleanup != null) {</span>
+<span class="source-line-no">745</span><span id="line-745"> callCleanup.run();</span>
+<span class="source-line-no">746</span><span id="line-746"> callCleanup = null;</span>
+<span class="source-line-no">747</span><span id="line-747"> }</span>
+<span class="source-line-no">748</span><span id="line-748"> }</span>
+<span class="source-line-no">749</span><span id="line-749"></span>
+<span class="source-line-no">750</span><span id="line-750"> protected enum PreambleResponse {</span>
+<span class="source-line-no">751</span><span id="line-751"> SUCCEED, // successfully processed the rpc preamble header</span>
+<span class="source-line-no">752</span><span id="line-752"> CONTINUE, // the preamble header is for other purpose, wait for the rpc preamble header</span>
+<span class="source-line-no">753</span><span id="line-753"> CLOSE // close the rpc connection</span>
+<span class="source-line-no">754</span><span id="line-754"> }</span>
+<span class="source-line-no">755</span><span id="line-755"></span>
+<span class="source-line-no">756</span><span id="line-756"> protected final PreambleResponse processPreamble(ByteBuffer preambleBuffer) throws IOException {</span>
+<span class="source-line-no">757</span><span id="line-757"> assert preambleBuffer.remaining() == 6;</span>
+<span class="source-line-no">758</span><span id="line-758"> if (</span>
+<span class="source-line-no">759</span><span id="line-759"> ByteBufferUtils.equals(preambleBuffer, preambleBuffer.position(), 6,</span>
+<span class="source-line-no">760</span><span id="line-760"> RpcClient.REGISTRY_PREAMBLE_HEADER, 0, 6) && doConnectionRegistryResponse()</span>
+<span class="source-line-no">761</span><span id="line-761"> ) {</span>
+<span class="source-line-no">762</span><span id="line-762"> return PreambleResponse.CLOSE;</span>
+<span class="source-line-no">763</span><span id="line-763"> }</span>
+<span class="source-line-no">764</span><span id="line-764"> if (</span>
+<span class="source-line-no">765</span><span id="line-765"> ByteBufferUtils.equals(preambleBuffer, preambleBuffer.position(), 6,</span>
+<span class="source-line-no">766</span><span id="line-766"> RpcClient.SECURITY_PREAMBLE_HEADER, 0, 6)</span>
+<span class="source-line-no">767</span><span id="line-767"> ) {</span>
+<span class="source-line-no">768</span><span id="line-768"> doSecurityPreambleResponse();</span>
+<span class="source-line-no">769</span><span id="line-769"> return PreambleResponse.CONTINUE;</span>
+<span class="source-line-no">770</span><span id="line-770"> }</span>
+<span class="source-line-no">771</span><span id="line-771"> if (!ByteBufferUtils.equals(preambleBuffer, preambleBuffer.position(), 4, RPC_HEADER, 0, 4)) {</span>
+<span class="source-line-no">772</span><span id="line-772"> doBadPreambleHandling(</span>
+<span class="source-line-no">773</span><span id="line-773"> "Expected HEADER=" + Bytes.toStringBinary(RPC_HEADER) + " but received HEADER="</span>
+<span class="source-line-no">774</span><span id="line-774"> + Bytes.toStringBinary(</span>
+<span class="source-line-no">775</span><span id="line-775"> ByteBufferUtils.toBytes(preambleBuffer, preambleBuffer.position(), RPC_HEADER.length),</span>
+<span class="source-line-no">776</span><span id="line-776"> 0, RPC_HEADER.length)</span>
+<span class="source-line-no">777</span><span id="line-777"> + " from " + toString());</span>
+<span class="source-line-no">778</span><span id="line-778"> return PreambleResponse.CLOSE;</span>
+<span class="source-line-no">779</span><span id="line-779"> }</span>
+<span class="source-line-no">780</span><span id="line-780"> int version = preambleBuffer.get(preambleBuffer.position() + 4) & 0xFF;</span>
+<span class="source-line-no">781</span><span id="line-781"> byte authByte = preambleBuffer.get(preambleBuffer.position() + 5);</span>
+<span class="source-line-no">782</span><span id="line-782"> if (version != RpcServer.CURRENT_VERSION) {</span>
+<span class="source-line-no">783</span><span id="line-783"> String msg = getFatalConnectionString(version, authByte);</span>
+<span class="source-line-no">784</span><span id="line-784"> doBadPreambleHandling(msg, new WrongVersionException(msg));</span>
+<span class="source-line-no">785</span><span id="line-785"> return PreambleResponse.CLOSE;</span>
+<span class="source-line-no">786</span><span id="line-786"> }</span>
+<span class="source-line-no">787</span><span id="line-787"></span>
+<span class="source-line-no">788</span><span id="line-788"> this.provider = rpcServer.saslProviders.selectProvider(authByte);</span>
+<span class="source-line-no">789</span><span id="line-789"> if (this.provider == null) {</span>
+<span class="source-line-no">790</span><span id="line-790"> String msg = getFatalConnectionString(version, authByte);</span>
+<span class="source-line-no">791</span><span id="line-791"> doBadPreambleHandling(msg, new BadAuthException(msg));</span>
+<span class="source-line-no">792</span><span id="line-792"> return PreambleResponse.CLOSE;</span>
+<span class="source-line-no">793</span><span id="line-793"> }</span>
+<span class="source-line-no">794</span><span id="line-794"> // TODO this is a wart while simple auth'n doesn't go through sasl.</span>
+<span class="source-line-no">795</span><span id="line-795"> if (this.rpcServer.isSecurityEnabled && isSimpleAuthentication()) {</span>
+<span class="source-line-no">796</span><span id="line-796"> if (this.rpcServer.allowFallbackToSimpleAuth) {</span>
+<span class="source-line-no">797</span><span id="line-797"> this.rpcServer.metrics.authenticationFallback();</span>
+<span class="source-line-no">798</span><span id="line-798"> authenticatedWithFallback = true;</span>
+<span class="source-line-no">799</span><span id="line-799"> } else {</span>
+<span class="source-line-no">800</span><span id="line-800"> AccessDeniedException ae = new AccessDeniedException("Authentication is required");</span>
+<span class="source-line-no">801</span><span id="line-801"> doRespond(getErrorResponse(ae.getMessage(), ae));</span>
+<span class="source-line-no">802</span><span id="line-802"> return PreambleResponse.CLOSE;</span>
+<span class="source-line-no">803</span><span id="line-803"> }</span>
+<span class="source-line-no">804</span><span id="line-804"> }</span>
+<span class="source-line-no">805</span><span id="line-805"> if (!this.rpcServer.isSecurityEnabled && !isSimpleAuthentication()) {</span>
+<span class="source-line-no">806</span><span id="line-806"> doRawSaslReply(SaslStatus.SUCCESS, new IntWritable(SaslUtil.SWITCH_TO_SIMPLE_AUTH), null,</span>
+<span class="source-line-no">807</span><span id="line-807"> null);</span>
+<span class="source-line-no">808</span><span id="line-808"> provider = rpcServer.saslProviders.getSimpleProvider();</span>
+<span class="source-line-no">809</span><span id="line-809"> // client has already sent the initial Sasl message and we</span>
+<span class="source-line-no">810</span><span id="line-810"> // should ignore it. Both client and server should fall back</span>
+<span class="source-line-no">811</span><span id="line-811"> // to simple auth from now on.</span>
+<span class="source-line-no">812</span><span id="line-812"> skipInitialSaslHandshake = true;</span>
+<span class="source-line-no">813</span><span id="line-813"> }</span>
+<span class="source-line-no">814</span><span id="line-814"> useSasl = !(provider instanceof SimpleSaslServerAuthenticationProvider);</span>
+<span class="source-line-no">815</span><span id="line-815"> return PreambleResponse.SUCCEED;</span>
<span class="source-line-no">816</span><span id="line-816"> }</span>
<span class="source-line-no">817</span><span id="line-817"></span>
-<span class="source-line-no">818</span><span id="line-818"> public abstract boolean isConnectionOpen();</span>
-<span class="source-line-no">819</span><span id="line-819"></span>
-<span class="source-line-no">820</span><span id="line-820"> public abstract ServerCall<?> createCall(int id, BlockingService service, MethodDescriptor md,</span>
-<span class="source-line-no">821</span><span id="line-821"> RequestHeader header, Message param, ExtendedCellScanner cellScanner, long size,</span>
-<span class="source-line-no">822</span><span id="line-822"> InetAddress remoteAddress, int timeout, CallCleanup reqCleanup);</span>
+<span class="source-line-no">818</span><span id="line-818"> boolean isSimpleAuthentication() {</span>
+<span class="source-line-no">819</span><span id="line-819"> return Objects.requireNonNull(provider) instanceof SimpleSaslServerAuthenticationProvider;</span>
+<span class="source-line-no">820</span><span id="line-820"> }</span>
+<span class="source-line-no">821</span><span id="line-821"></span>
+<span class="source-line-no">822</span><span id="line-822"> public abstract boolean isConnectionOpen();</span>
<span class="source-line-no">823</span><span id="line-823"></span>
-<span class="source-line-no">824</span><span id="line-824"> private static class ByteBuffByteInput extends ByteInput {</span>
-<span class="source-line-no">825</span><span id="line-825"></span>
-<span class="source-line-no">826</span><span id="line-826"> private ByteBuff buf;</span>
-<span class="source-line-no">827</span><span id="line-827"> private int length;</span>
-<span class="source-line-no">828</span><span id="line-828"></span>
-<span class="source-line-no">829</span><span id="line-829"> ByteBuffByteInput(ByteBuff buf, int length) {</span>
-<span class="source-line-no">830</span><span id="line-830"> this.buf = buf;</span>
-<span class="source-line-no">831</span><span id="line-831"> this.length = length;</span>
-<span class="source-line-no">832</span><span id="line-832"> }</span>
-<span class="source-line-no">833</span><span id="line-833"></span>
-<span class="source-line-no">834</span><span id="line-834"> @Override</span>
-<span class="source-line-no">835</span><span id="line-835"> public byte read(int offset) {</span>
-<span class="source-line-no">836</span><span id="line-836"> return this.buf.get(offset);</span>
-<span class="source-line-no">837</span><span id="line-837"> }</span>
-<span class="source-line-no">838</span><span id="line-838"></span>
-<span class="source-line-no">839</span><span id="line-839"> @Override</span>
-<span class="source-line-no">840</span><span id="line-840"> public int read(int offset, byte[] out, int outOffset, int len) {</span>
-<span class="source-line-no">841</span><span id="line-841"> this.buf.get(offset, out, outOffset, len);</span>
-<span class="source-line-no">842</span><span id="line-842"> return len;</span>
-<span class="source-line-no">843</span><span id="line-843"> }</span>
-<span class="source-line-no">844</span><span id="line-844"></span>
-<span class="source-line-no">845</span><span id="line-845"> @Override</span>
-<span class="source-line-no">846</span><span id="line-846"> public int read(int offset, ByteBuffer out) {</span>
-<span class="source-line-no">847</span><span id="line-847"> int len = out.remaining();</span>
-<span class="source-line-no">848</span><span id="line-848"> this.buf.get(out, offset, len);</span>
-<span class="source-line-no">849</span><span id="line-849"> return len;</span>
-<span class="source-line-no">850</span><span id="line-850"> }</span>
-<span class="source-line-no">851</span><span id="line-851"></span>
-<span class="source-line-no">852</span><span id="line-852"> @Override</span>
-<span class="source-line-no">853</span><span id="line-853"> public long readLong(int offset) {</span>
-<span class="source-line-no">854</span><span id="line-854"> return this.buf.getLong(offset);</span>
-<span class="source-line-no">855</span><span id="line-855"> }</span>
-<span class="source-line-no">856</span><span id="line-856"></span>
-<span class="source-line-no">857</span><span id="line-857"> @Override</span>
-<span class="source-line-no">858</span><span id="line-858"> public int size() {</span>
-<span class="source-line-no">859</span><span id="line-859"> return this.length;</span>
-<span class="source-line-no">860</span><span id="line-860"> }</span>
-<span class="source-line-no">861</span><span id="line-861"></span>
-<span class="source-line-no">862</span><span id="line-862"> }</span>
-<span class="source-line-no">863</span><span id="line-863">}</span>
+<span class="source-line-no">824</span><span id="line-824"> public abstract ServerCall<?> createCall(int id, BlockingService service, MethodDescriptor md,</span>
+<span class="source-line-no">825</span><span id="line-825"> RequestHeader header, Message param, ExtendedCellScanner cellScanner, long size,</span>
+<span class="source-line-no">826</span><span id="line-826"> InetAddress remoteAddress, int timeout, CallCleanup reqCleanup);</span>
+<span class="source-line-no">827</span><span id="line-827"></span>
+<span class="source-line-no">828</span><span id="line-828"> private static class ByteBuffByteInput extends ByteInput {</span>
+<span class="source-line-no">829</span><span id="line-829"></span>
+<span class="source-line-no">830</span><span id="line-830"> private ByteBuff buf;</span>
+<span class="source-line-no">831</span><span id="line-831"> private int length;</span>
+<span class="source-line-no">832</span><span id="line-832"></span>
+<span class="source-line-no">833</span><span id="line-833"> ByteBuffByteInput(ByteBuff buf, int length) {</span>
+<span class="source-line-no">834</span><span id="line-834"> this.buf = buf;</span>
+<span class="source-line-no">835</span><span id="line-835"> this.length = length;</span>
+<span class="source-line-no">836</span><span id="line-836"> }</span>
+<span class="source-line-no">837</span><span id="line-837"></span>
+<span class="source-line-no">838</span><span id="line-838"> @Override</span>
+<span class="source-line-no">839</span><span id="line-839"> public byte read(int offset) {</span>
+<span class="source-line-no">840</span><span id="line-840"> return this.buf.get(offset);</span>
+<span class="source-line-no">841</span><span id="line-841"> }</span>
+<span class="source-line-no">842</span><span id="line-842"></span>
+<span class="source-line-no">843</span><span id="line-843"> @Override</span>
+<span class="source-line-no">844</span><span id="line-844"> public int read(int offset, byte[] out, int outOffset, int len) {</span>
+<span class="source-line-no">845</span><span id="line-845"> this.buf.get(offset, out, outOffset, len);</span>
+<span class="source-line-no">846</span><span id="line-846"> return len;</span>
+<span class="source-line-no">847</span><span id="line-847"> }</span>
+<span class="source-line-no">848</span><span id="line-848"></span>
+<span class="source-line-no">849</span><span id="line-849"> @Override</span>
+<span class="source-line-no">850</span><span id="line-850"> public int read(int offset, ByteBuffer out) {</span>
+<span class="source-line-no">851</span><span id="line-851"> int len = out.remaining();</span>
+<span class="source-line-no">852</span><span id="line-852"> this.buf.get(out, offset, len);</span>
+<span class="source-line-no">853</span><span id="line-853"> return len;</span>
+<span class="source-line-no">854</span><span id="line-854"> }</span>
+<span class="source-line-no">855</span><span id="line-855"></span>
+<span class="source-line-no">856</span><span id="line-856"> @Override</span>
+<span class="source-line-no">857</span><span id="line-857"> public long readLong(int offset) {</span>
+<span class="source-line-no">858</span><span id="line-858"> return this.buf.getLong(offset);</span>
+<span class="source-line-no">859</span><span id="line-859"> }</span>
+<span class="source-line-no">860</span><span id="line-860"></span>
+<span class="source-line-no">861</span><span id="line-861"> @Override</span>
+<span class="source-line-no">862</span><span id="line-862"> public int size() {</span>
+<span class="source-line-no">863</span><span id="line-863"> return this.length;</span>
+<span class="source-line-no">864</span><span id="line-864"> }</span>
+<span class="source-line-no">865</span><span id="line-865"></span>
+<span class="source-line-no">866</span><span id="line-866"> }</span>
+<span class="source-line-no">867</span><span id="line-867">}</span>
diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/ipc/ServerRpcConnection.html b/apidocs/src-html/org/apache/hadoop/hbase/ipc/ServerRpcConnection.html
similarity index 83%
copy from devapidocs/src-html/org/apache/hadoop/hbase/ipc/ServerRpcConnection.html
copy to apidocs/src-html/org/apache/hadoop/hbase/ipc/ServerRpcConnection.html
index f48206b6470..b95e539c00b 100644
--- a/devapidocs/src-html/org/apache/hadoop/hbase/ipc/ServerRpcConnection.html
+++ b/apidocs/src-html/org/apache/hadoop/hbase/ipc/ServerRpcConnection.html
@@ -109,7 +109,7 @@
<span class="source-line-no">096</span><span id="line-96">@edu.umd.cs.findbugs.annotations.SuppressWarnings(value = "VO_VOLATILE_INCREMENT",</span>
<span class="source-line-no">097</span><span id="line-97"> justification = "False positive according to http://sourceforge.net/p/findbugs/bugs/1032/")</span>
<span class="source-line-no">098</span><span id="line-98">@InterfaceAudience.Private</span>
-<span class="source-line-no">099</span><span id="line-99">abstract class ServerRpcConnection implements Closeable {</span>
+<span class="source-line-no">099</span><span id="line-99">public abstract class ServerRpcConnection implements Closeable {</span>
<span class="source-line-no">100</span><span id="line-100"></span>
<span class="source-line-no">101</span><span id="line-101"> private static final TextMapGetter<RPCTInfo> getter = new RPCTInfoGetter();</span>
<span class="source-line-no">102</span><span id="line-102"></span>
@@ -500,380 +500,384 @@
<span class="source-line-no">487</span><span id="line-487"> this.hostAddress, this.remotePort, version, this.useSasl, this.ugi, serviceName);</span>
<span class="source-line-no">488</span><span id="line-488"> }</span>
<span class="source-line-no">489</span><span id="line-489"></span>
-<span class="source-line-no">490</span><span id="line-490"> /**</span>
-<span class="source-line-no">491</span><span id="line-491"> * Send the response for connection header</span>
-<span class="source-line-no">492</span><span id="line-492"> */</span>
-<span class="source-line-no">493</span><span id="line-493"> private void sendConnectionHeaderResponseIfNeeded() throws FatalConnectionException {</span>
-<span class="source-line-no">494</span><span id="line-494"> Pair<RPCProtos.ConnectionHeaderResponse, CryptoAES> pair = setupCryptoCipher();</span>
-<span class="source-line-no">495</span><span id="line-495"> // Response the connection header if Crypto AES is enabled</span>
-<span class="source-line-no">496</span><span id="line-496"> if (pair == null) {</span>
-<span class="source-line-no">497</span><span id="line-497"> return;</span>
-<span class="source-line-no">498</span><span id="line-498"> }</span>
-<span class="source-line-no">499</span><span id="line-499"> try {</span>
-<span class="source-line-no">500</span><span id="line-500"> int size = pair.getFirst().getSerializedSize();</span>
-<span class="source-line-no">501</span><span id="line-501"> BufferChain bc;</span>
-<span class="source-line-no">502</span><span id="line-502"> try (ByteBufferOutputStream bbOut = new ByteBufferOutputStream(4 + size);</span>
-<span class="source-line-no">503</span><span id="line-503"> DataOutputStream out = new DataOutputStream(bbOut)) {</span>
-<span class="source-line-no">504</span><span id="line-504"> out.writeInt(size);</span>
-<span class="source-line-no">505</span><span id="line-505"> pair.getFirst().writeTo(out);</span>
-<span class="source-line-no">506</span><span id="line-506"> bc = new BufferChain(bbOut.getByteBuffer());</span>
-<span class="source-line-no">507</span><span id="line-507"> }</span>
-<span class="source-line-no">508</span><span id="line-508"> doRespond(new RpcResponse() {</span>
-<span class="source-line-no">509</span><span id="line-509"></span>
-<span class="source-line-no">510</span><span id="line-510"> @Override</span>
-<span class="source-line-no">511</span><span id="line-511"> public BufferChain getResponse() {</span>
-<span class="source-line-no">512</span><span id="line-512"> return bc;</span>
-<span class="source-line-no">513</span><span id="line-513"> }</span>
-<span class="source-line-no">514</span><span id="line-514"></span>
-<span class="source-line-no">515</span><span id="line-515"> @Override</span>
-<span class="source-line-no">516</span><span id="line-516"> public void done() {</span>
-<span class="source-line-no">517</span><span id="line-517"> // must switch after sending the connection header response, as the client still uses the</span>
-<span class="source-line-no">518</span><span id="line-518"> // original SaslClient to unwrap the data we send back</span>
-<span class="source-line-no">519</span><span id="line-519"> saslServer.switchToCryptoAES(pair.getSecond());</span>
-<span class="source-line-no">520</span><span id="line-520"> }</span>
-<span class="source-line-no">521</span><span id="line-521"> });</span>
-<span class="source-line-no">522</span><span id="line-522"> } catch (IOException ex) {</span>
-<span class="source-line-no">523</span><span id="line-523"> throw new UnsupportedCryptoException(ex.getMessage(), ex);</span>
-<span class="source-line-no">524</span><span id="line-524"> }</span>
-<span class="source-line-no">525</span><span id="line-525"> }</span>
-<span class="source-line-no">526</span><span id="line-526"></span>
-<span class="source-line-no">527</span><span id="line-527"> protected abstract void doRespond(RpcResponse resp) throws IOException;</span>
-<span class="source-line-no">528</span><span id="line-528"></span>
-<span class="source-line-no">529</span><span id="line-529"> /**</span>
-<span class="source-line-no">530</span><span id="line-530"> * Has the request header and the request param and optionally encoded data buffer all in this one</span>
-<span class="source-line-no">531</span><span id="line-531"> * array.</span>
-<span class="source-line-no">532</span><span id="line-532"> * <p/></span>
-<span class="source-line-no">533</span><span id="line-533"> * Will be overridden in tests.</span>
-<span class="source-line-no">534</span><span id="line-534"> */</span>
-<span class="source-line-no">535</span><span id="line-535"> protected void processRequest(ByteBuff buf) throws IOException, InterruptedException {</span>
-<span class="source-line-no">536</span><span id="line-536"> long totalRequestSize = buf.limit();</span>
-<span class="source-line-no">537</span><span id="line-537"> int offset = 0;</span>
-<span class="source-line-no">538</span><span id="line-538"> // Here we read in the header. We avoid having pb</span>
-<span class="source-line-no">539</span><span id="line-539"> // do its default 4k allocation for CodedInputStream. We force it to use</span>
-<span class="source-line-no">540</span><span id="line-540"> // backing array.</span>
-<span class="source-line-no">541</span><span id="line-541"> CodedInputStream cis = createCis(buf);</span>
-<span class="source-line-no">542</span><span id="line-542"> int headerSize = cis.readRawVarint32();</span>
-<span class="source-line-no">543</span><span id="line-543"> offset = cis.getTotalBytesRead();</span>
-<span class="source-line-no">544</span><span id="line-544"> Message.Builder builder = RequestHeader.newBuilder();</span>
-<span class="source-line-no">545</span><span id="line-545"> ProtobufUtil.mergeFrom(builder, cis, headerSize);</span>
-<span class="source-line-no">546</span><span id="line-546"> RequestHeader header = (RequestHeader) builder.build();</span>
-<span class="source-line-no">547</span><span id="line-547"> offset += headerSize;</span>
-<span class="source-line-no">548</span><span id="line-548"> Context traceCtx = GlobalOpenTelemetry.getPropagators().getTextMapPropagator()</span>
-<span class="source-line-no">549</span><span id="line-549"> .extract(Context.current(), header.getTraceInfo(), getter);</span>
-<span class="source-line-no">550</span><span id="line-550"></span>
-<span class="source-line-no">551</span><span id="line-551"> // n.b. Management of this Span instance is a little odd. Most exit paths from this try scope</span>
-<span class="source-line-no">552</span><span id="line-552"> // are early-exits due to error cases. There's only one success path, the asynchronous call to</span>
-<span class="source-line-no">553</span><span id="line-553"> // RpcScheduler#dispatch. The success path assumes ownership of the span, which is represented</span>
-<span class="source-line-no">554</span><span id="line-554"> // by null-ing out the reference in this scope. All other paths end the span. Thus, and in</span>
-<span class="source-line-no">555</span><span id="line-555"> // order to avoid accidentally orphaning the span, the call to Span#end happens in a finally</span>
-<span class="source-line-no">556</span><span id="line-556"> // block iff the span is non-null.</span>
-<span class="source-line-no">557</span><span id="line-557"> Span span = TraceUtil.createRemoteSpan("RpcServer.process", traceCtx);</span>
-<span class="source-line-no">558</span><span id="line-558"> try (Scope ignored = span.makeCurrent()) {</span>
-<span class="source-line-no">559</span><span id="line-559"> int id = header.getCallId();</span>
-<span class="source-line-no">560</span><span id="line-560"> // HBASE-28128 - if server is aborting, don't bother trying to process. It will</span>
-<span class="source-line-no">561</span><span id="line-561"> // fail at the handler layer, but worse might result in CallQueueTooBigException if the</span>
-<span class="source-line-no">562</span><span id="line-562"> // queue is full but server is not properly processing requests. Better to throw an aborted</span>
-<span class="source-line-no">563</span><span id="line-563"> // exception here so that the client can properly react.</span>
-<span class="source-line-no">564</span><span id="line-564"> if (rpcServer.server != null && rpcServer.server.isAborted()) {</span>
-<span class="source-line-no">565</span><span id="line-565"> RegionServerAbortedException serverIsAborted = new RegionServerAbortedException(</span>
-<span class="source-line-no">566</span><span id="line-566"> "Server " + rpcServer.server.getServerName() + " aborting");</span>
-<span class="source-line-no">567</span><span id="line-567"> this.rpcServer.metrics.exception(serverIsAborted);</span>
-<span class="source-line-no">568</span><span id="line-568"> sendErrorResponseForCall(id, totalRequestSize, span, serverIsAborted.getMessage(),</span>
-<span class="source-line-no">569</span><span id="line-569"> serverIsAborted);</span>
-<span class="source-line-no">570</span><span id="line-570"> return;</span>
-<span class="source-line-no">571</span><span id="line-571"> }</span>
-<span class="source-line-no">572</span><span id="line-572"></span>
-<span class="source-line-no">573</span><span id="line-573"> if (RpcServer.LOG.isTraceEnabled()) {</span>
-<span class="source-line-no">574</span><span id="line-574"> RpcServer.LOG.trace("RequestHeader " + TextFormat.shortDebugString(header)</span>
-<span class="source-line-no">575</span><span id="line-575"> + " totalRequestSize: " + totalRequestSize + " bytes");</span>
-<span class="source-line-no">576</span><span id="line-576"> }</span>
-<span class="source-line-no">577</span><span id="line-577"> // Enforcing the call queue size, this triggers a retry in the client</span>
-<span class="source-line-no">578</span><span id="line-578"> // This is a bit late to be doing this check - we have already read in the</span>
-<span class="source-line-no">579</span><span id="line-579"> // total request.</span>
-<span class="source-line-no">580</span><span id="line-580"> if (</span>
-<span class="source-line-no">581</span><span id="line-581"> (totalRequestSize + this.rpcServer.callQueueSizeInBytes.sum())</span>
-<span class="source-line-no">582</span><span id="line-582"> > this.rpcServer.maxQueueSizeInBytes</span>
-<span class="source-line-no">583</span><span id="line-583"> ) {</span>
-<span class="source-line-no">584</span><span id="line-584"> this.rpcServer.metrics.exception(RpcServer.CALL_QUEUE_TOO_BIG_EXCEPTION);</span>
-<span class="source-line-no">585</span><span id="line-585"> sendErrorResponseForCall(id, totalRequestSize, span,</span>
-<span class="source-line-no">586</span><span id="line-586"> "Call queue is full on " + this.rpcServer.server.getServerName()</span>
-<span class="source-line-no">587</span><span id="line-587"> + ", is hbase.ipc.server.max.callqueue.size too small?",</span>
-<span class="source-line-no">588</span><span id="line-588"> RpcServer.CALL_QUEUE_TOO_BIG_EXCEPTION);</span>
-<span class="source-line-no">589</span><span id="line-589"> return;</span>
-<span class="source-line-no">590</span><span id="line-590"> }</span>
-<span class="source-line-no">591</span><span id="line-591"> MethodDescriptor md = null;</span>
-<span class="source-line-no">592</span><span id="line-592"> Message param = null;</span>
-<span class="source-line-no">593</span><span id="line-593"> ExtendedCellScanner cellScanner = null;</span>
-<span class="source-line-no">594</span><span id="line-594"> try {</span>
-<span class="source-line-no">595</span><span id="line-595"> if (header.hasRequestParam() && header.getRequestParam()) {</span>
-<span class="source-line-no">596</span><span id="line-596"> md = this.service.getDescriptorForType().findMethodByName(header.getMethodName());</span>
-<span class="source-line-no">597</span><span id="line-597"> if (md == null) {</span>
-<span class="source-line-no">598</span><span id="line-598"> throw new UnsupportedOperationException(header.getMethodName());</span>
-<span class="source-line-no">599</span><span id="line-599"> }</span>
-<span class="source-line-no">600</span><span id="line-600"> builder = this.service.getRequestPrototype(md).newBuilderForType();</span>
-<span class="source-line-no">601</span><span id="line-601"> cis.resetSizeCounter();</span>
-<span class="source-line-no">602</span><span id="line-602"> int paramSize = cis.readRawVarint32();</span>
-<span class="source-line-no">603</span><span id="line-603"> offset += cis.getTotalBytesRead();</span>
-<span class="source-line-no">604</span><span id="line-604"> if (builder != null) {</span>
-<span class="source-line-no">605</span><span id="line-605"> ProtobufUtil.mergeFrom(builder, cis, paramSize);</span>
-<span class="source-line-no">606</span><span id="line-606"> param = builder.build();</span>
-<span class="source-line-no">607</span><span id="line-607"> }</span>
-<span class="source-line-no">608</span><span id="line-608"> offset += paramSize;</span>
-<span class="source-line-no">609</span><span id="line-609"> } else {</span>
-<span class="source-line-no">610</span><span id="line-610"> // currently header must have request param, so we directly throw</span>
-<span class="source-line-no">611</span><span id="line-611"> // exception here</span>
-<span class="source-line-no">612</span><span id="line-612"> String msg = "Invalid request header: " + TextFormat.shortDebugString(header)</span>
-<span class="source-line-no">613</span><span id="line-613"> + ", should have param set in it";</span>
-<span class="source-line-no">614</span><span id="line-614"> RpcServer.LOG.warn(msg);</span>
-<span class="source-line-no">615</span><span id="line-615"> throw new DoNotRetryIOException(msg);</span>
-<span class="source-line-no">616</span><span id="line-616"> }</span>
-<span class="source-line-no">617</span><span id="line-617"> if (header.hasCellBlockMeta()) {</span>
-<span class="source-line-no">618</span><span id="line-618"> buf.position(offset);</span>
-<span class="source-line-no">619</span><span id="line-619"> ByteBuff dup = buf.duplicate();</span>
-<span class="source-line-no">620</span><span id="line-620"> dup.limit(offset + header.getCellBlockMeta().getLength());</span>
-<span class="source-line-no">621</span><span id="line-621"> cellScanner = this.rpcServer.cellBlockBuilder.createCellScannerReusingBuffers(this.codec,</span>
-<span class="source-line-no">622</span><span id="line-622"> this.compressionCodec, dup);</span>
-<span class="source-line-no">623</span><span id="line-623"> }</span>
-<span class="source-line-no">624</span><span id="line-624"> } catch (Throwable thrown) {</span>
-<span class="source-line-no">625</span><span id="line-625"> InetSocketAddress address = this.rpcServer.getListenerAddress();</span>
-<span class="source-line-no">626</span><span id="line-626"> String msg = (address != null ? address : "(channel closed)")</span>
-<span class="source-line-no">627</span><span id="line-627"> + " is unable to read call parameter from client " + getHostAddress();</span>
-<span class="source-line-no">628</span><span id="line-628"> RpcServer.LOG.warn(msg, thrown);</span>
-<span class="source-line-no">629</span><span id="line-629"></span>
-<span class="source-line-no">630</span><span id="line-630"> this.rpcServer.metrics.exception(thrown);</span>
-<span class="source-line-no">631</span><span id="line-631"></span>
-<span class="source-line-no">632</span><span id="line-632"> final Throwable responseThrowable;</span>
-<span class="source-line-no">633</span><span id="line-633"> if (thrown instanceof LinkageError) {</span>
-<span class="source-line-no">634</span><span id="line-634"> // probably the hbase hadoop version does not match the running hadoop version</span>
-<span class="source-line-no">635</span><span id="line-635"> responseThrowable = new DoNotRetryIOException(thrown);</span>
-<span class="source-line-no">636</span><span id="line-636"> } else if (thrown instanceof UnsupportedOperationException) {</span>
-<span class="source-line-no">637</span><span id="line-637"> // If the method is not present on the server, do not retry.</span>
-<span class="source-line-no">638</span><span id="line-638"> responseThrowable = new DoNotRetryIOException(thrown);</span>
-<span class="source-line-no">639</span><span id="line-639"> } else {</span>
-<span class="source-line-no">640</span><span id="line-640"> responseThrowable = thrown;</span>
-<span class="source-line-no">641</span><span id="line-641"> }</span>
-<span class="source-line-no">642</span><span id="line-642"></span>
-<span class="source-line-no">643</span><span id="line-643"> sendErrorResponseForCall(id, totalRequestSize, span,</span>
-<span class="source-line-no">644</span><span id="line-644"> msg + "; " + responseThrowable.getMessage(), responseThrowable);</span>
-<span class="source-line-no">645</span><span id="line-645"> return;</span>
-<span class="source-line-no">646</span><span id="line-646"> }</span>
-<span class="source-line-no">647</span><span id="line-647"></span>
-<span class="source-line-no">648</span><span id="line-648"> int timeout = 0;</span>
-<span class="source-line-no">649</span><span id="line-649"> if (header.hasTimeout() && header.getTimeout() > 0) {</span>
-<span class="source-line-no">650</span><span id="line-650"> timeout = Math.max(this.rpcServer.minClientRequestTimeout, header.getTimeout());</span>
-<span class="source-line-no">651</span><span id="line-651"> }</span>
-<span class="source-line-no">652</span><span id="line-652"> ServerCall<?> call = createCall(id, this.service, md, header, param, cellScanner,</span>
-<span class="source-line-no">653</span><span id="line-653"> totalRequestSize, this.addr, timeout, this.callCleanup);</span>
-<span class="source-line-no">654</span><span id="line-654"></span>
-<span class="source-line-no">655</span><span id="line-655"> if (this.rpcServer.scheduler.dispatch(new CallRunner(this.rpcServer, call))) {</span>
-<span class="source-line-no">656</span><span id="line-656"> // unset span do that it's not closed in the finally block</span>
-<span class="source-line-no">657</span><span id="line-657"> span = null;</span>
-<span class="source-line-no">658</span><span id="line-658"> } else {</span>
-<span class="source-line-no">659</span><span id="line-659"> this.rpcServer.callQueueSizeInBytes.add(-1 * call.getSize());</span>
-<span class="source-line-no">660</span><span id="line-660"> this.rpcServer.metrics.exception(RpcServer.CALL_QUEUE_TOO_BIG_EXCEPTION);</span>
-<span class="source-line-no">661</span><span id="line-661"> call.setResponse(null, null, RpcServer.CALL_QUEUE_TOO_BIG_EXCEPTION,</span>
-<span class="source-line-no">662</span><span id="line-662"> "Call queue is full on " + this.rpcServer.server.getServerName()</span>
-<span class="source-line-no">663</span><span id="line-663"> + ", too many items queued ?");</span>
-<span class="source-line-no">664</span><span id="line-664"> TraceUtil.setError(span, RpcServer.CALL_QUEUE_TOO_BIG_EXCEPTION);</span>
-<span class="source-line-no">665</span><span id="line-665"> call.sendResponseIfReady();</span>
-<span class="source-line-no">666</span><span id="line-666"> }</span>
-<span class="source-line-no">667</span><span id="line-667"> } finally {</span>
-<span class="source-line-no">668</span><span id="line-668"> if (span != null) {</span>
-<span class="source-line-no">669</span><span id="line-669"> span.end();</span>
+<span class="source-line-no">490</span><span id="line-490"> public ConnectionHeader getConnectionHeader() {</span>
+<span class="source-line-no">491</span><span id="line-491"> return connectionHeader;</span>
+<span class="source-line-no">492</span><span id="line-492"> }</span>
+<span class="source-line-no">493</span><span id="line-493"></span>
+<span class="source-line-no">494</span><span id="line-494"> /**</span>
+<span class="source-line-no">495</span><span id="line-495"> * Send the response for connection header</span>
+<span class="source-line-no">496</span><span id="line-496"> */</span>
+<span class="source-line-no">497</span><span id="line-497"> private void sendConnectionHeaderResponseIfNeeded() throws FatalConnectionException {</span>
+<span class="source-line-no">498</span><span id="line-498"> Pair<RPCProtos.ConnectionHeaderResponse, CryptoAES> pair = setupCryptoCipher();</span>
+<span class="source-line-no">499</span><span id="line-499"> // Response the connection header if Crypto AES is enabled</span>
+<span class="source-line-no">500</span><span id="line-500"> if (pair == null) {</span>
+<span class="source-line-no">501</span><span id="line-501"> return;</span>
+<span class="source-line-no">502</span><span id="line-502"> }</span>
+<span class="source-line-no">503</span><span id="line-503"> try {</span>
+<span class="source-line-no">504</span><span id="line-504"> int size = pair.getFirst().getSerializedSize();</span>
+<span class="source-line-no">505</span><span id="line-505"> BufferChain bc;</span>
+<span class="source-line-no">506</span><span id="line-506"> try (ByteBufferOutputStream bbOut = new ByteBufferOutputStream(4 + size);</span>
+<span class="source-line-no">507</span><span id="line-507"> DataOutputStream out = new DataOutputStream(bbOut)) {</span>
+<span class="source-line-no">508</span><span id="line-508"> out.writeInt(size);</span>
+<span class="source-line-no">509</span><span id="line-509"> pair.getFirst().writeTo(out);</span>
+<span class="source-line-no">510</span><span id="line-510"> bc = new BufferChain(bbOut.getByteBuffer());</span>
+<span class="source-line-no">511</span><span id="line-511"> }</span>
+<span class="source-line-no">512</span><span id="line-512"> doRespond(new RpcResponse() {</span>
+<span class="source-line-no">513</span><span id="line-513"></span>
+<span class="source-line-no">514</span><span id="line-514"> @Override</span>
+<span class="source-line-no">515</span><span id="line-515"> public BufferChain getResponse() {</span>
+<span class="source-line-no">516</span><span id="line-516"> return bc;</span>
+<span class="source-line-no">517</span><span id="line-517"> }</span>
+<span class="source-line-no">518</span><span id="line-518"></span>
+<span class="source-line-no">519</span><span id="line-519"> @Override</span>
+<span class="source-line-no">520</span><span id="line-520"> public void done() {</span>
+<span class="source-line-no">521</span><span id="line-521"> // must switch after sending the connection header response, as the client still uses the</span>
+<span class="source-line-no">522</span><span id="line-522"> // original SaslClient to unwrap the data we send back</span>
+<span class="source-line-no">523</span><span id="line-523"> saslServer.switchToCryptoAES(pair.getSecond());</span>
+<span class="source-line-no">524</span><span id="line-524"> }</span>
+<span class="source-line-no">525</span><span id="line-525"> });</span>
+<span class="source-line-no">526</span><span id="line-526"> } catch (IOException ex) {</span>
+<span class="source-line-no">527</span><span id="line-527"> throw new UnsupportedCryptoException(ex.getMessage(), ex);</span>
+<span class="source-line-no">528</span><span id="line-528"> }</span>
+<span class="source-line-no">529</span><span id="line-529"> }</span>
+<span class="source-line-no">530</span><span id="line-530"></span>
+<span class="source-line-no">531</span><span id="line-531"> protected abstract void doRespond(RpcResponse resp) throws IOException;</span>
+<span class="source-line-no">532</span><span id="line-532"></span>
+<span class="source-line-no">533</span><span id="line-533"> /**</span>
+<span class="source-line-no">534</span><span id="line-534"> * Has the request header and the request param and optionally encoded data buffer all in this one</span>
+<span class="source-line-no">535</span><span id="line-535"> * array.</span>
+<span class="source-line-no">536</span><span id="line-536"> * <p/></span>
+<span class="source-line-no">537</span><span id="line-537"> * Will be overridden in tests.</span>
+<span class="source-line-no">538</span><span id="line-538"> */</span>
+<span class="source-line-no">539</span><span id="line-539"> protected void processRequest(ByteBuff buf) throws IOException, InterruptedException {</span>
+<span class="source-line-no">540</span><span id="line-540"> long totalRequestSize = buf.limit();</span>
+<span class="source-line-no">541</span><span id="line-541"> int offset = 0;</span>
+<span class="source-line-no">542</span><span id="line-542"> // Here we read in the header. We avoid having pb</span>
+<span class="source-line-no">543</span><span id="line-543"> // do its default 4k allocation for CodedInputStream. We force it to use</span>
+<span class="source-line-no">544</span><span id="line-544"> // backing array.</span>
+<span class="source-line-no">545</span><span id="line-545"> CodedInputStream cis = createCis(buf);</span>
+<span class="source-line-no">546</span><span id="line-546"> int headerSize = cis.readRawVarint32();</span>
+<span class="source-line-no">547</span><span id="line-547"> offset = cis.getTotalBytesRead();</span>
+<span class="source-line-no">548</span><span id="line-548"> Message.Builder builder = RequestHeader.newBuilder();</span>
+<span class="source-line-no">549</span><span id="line-549"> ProtobufUtil.mergeFrom(builder, cis, headerSize);</span>
+<span class="source-line-no">550</span><span id="line-550"> RequestHeader header = (RequestHeader) builder.build();</span>
+<span class="source-line-no">551</span><span id="line-551"> offset += headerSize;</span>
+<span class="source-line-no">552</span><span id="line-552"> Context traceCtx = GlobalOpenTelemetry.getPropagators().getTextMapPropagator()</span>
+<span class="source-line-no">553</span><span id="line-553"> .extract(Context.current(), header.getTraceInfo(), getter);</span>
+<span class="source-line-no">554</span><span id="line-554"></span>
+<span class="source-line-no">555</span><span id="line-555"> // n.b. Management of this Span instance is a little odd. Most exit paths from this try scope</span>
+<span class="source-line-no">556</span><span id="line-556"> // are early-exits due to error cases. There's only one success path, the asynchronous call to</span>
+<span class="source-line-no">557</span><span id="line-557"> // RpcScheduler#dispatch. The success path assumes ownership of the span, which is represented</span>
+<span class="source-line-no">558</span><span id="line-558"> // by null-ing out the reference in this scope. All other paths end the span. Thus, and in</span>
+<span class="source-line-no">559</span><span id="line-559"> // order to avoid accidentally orphaning the span, the call to Span#end happens in a finally</span>
+<span class="source-line-no">560</span><span id="line-560"> // block iff the span is non-null.</span>
+<span class="source-line-no">561</span><span id="line-561"> Span span = TraceUtil.createRemoteSpan("RpcServer.process", traceCtx);</span>
+<span class="source-line-no">562</span><span id="line-562"> try (Scope ignored = span.makeCurrent()) {</span>
+<span class="source-line-no">563</span><span id="line-563"> int id = header.getCallId();</span>
+<span class="source-line-no">564</span><span id="line-564"> // HBASE-28128 - if server is aborting, don't bother trying to process. It will</span>
+<span class="source-line-no">565</span><span id="line-565"> // fail at the handler layer, but worse might result in CallQueueTooBigException if the</span>
+<span class="source-line-no">566</span><span id="line-566"> // queue is full but server is not properly processing requests. Better to throw an aborted</span>
+<span class="source-line-no">567</span><span id="line-567"> // exception here so that the client can properly react.</span>
+<span class="source-line-no">568</span><span id="line-568"> if (rpcServer.server != null && rpcServer.server.isAborted()) {</span>
+<span class="source-line-no">569</span><span id="line-569"> RegionServerAbortedException serverIsAborted = new RegionServerAbortedException(</span>
+<span class="source-line-no">570</span><span id="line-570"> "Server " + rpcServer.server.getServerName() + " aborting");</span>
+<span class="source-line-no">571</span><span id="line-571"> this.rpcServer.metrics.exception(serverIsAborted);</span>
+<span class="source-line-no">572</span><span id="line-572"> sendErrorResponseForCall(id, totalRequestSize, span, serverIsAborted.getMessage(),</span>
+<span class="source-line-no">573</span><span id="line-573"> serverIsAborted);</span>
+<span class="source-line-no">574</span><span id="line-574"> return;</span>
+<span class="source-line-no">575</span><span id="line-575"> }</span>
+<span class="source-line-no">576</span><span id="line-576"></span>
+<span class="source-line-no">577</span><span id="line-577"> if (RpcServer.LOG.isTraceEnabled()) {</span>
+<span class="source-line-no">578</span><span id="line-578"> RpcServer.LOG.trace("RequestHeader " + TextFormat.shortDebugString(header)</span>
+<span class="source-line-no">579</span><span id="line-579"> + " totalRequestSize: " + totalRequestSize + " bytes");</span>
+<span class="source-line-no">580</span><span id="line-580"> }</span>
+<span class="source-line-no">581</span><span id="line-581"> // Enforcing the call queue size, this triggers a retry in the client</span>
+<span class="source-line-no">582</span><span id="line-582"> // This is a bit late to be doing this check - we have already read in the</span>
+<span class="source-line-no">583</span><span id="line-583"> // total request.</span>
+<span class="source-line-no">584</span><span id="line-584"> if (</span>
+<span class="source-line-no">585</span><span id="line-585"> (totalRequestSize + this.rpcServer.callQueueSizeInBytes.sum())</span>
+<span class="source-line-no">586</span><span id="line-586"> > this.rpcServer.maxQueueSizeInBytes</span>
+<span class="source-line-no">587</span><span id="line-587"> ) {</span>
+<span class="source-line-no">588</span><span id="line-588"> this.rpcServer.metrics.exception(RpcServer.CALL_QUEUE_TOO_BIG_EXCEPTION);</span>
+<span class="source-line-no">589</span><span id="line-589"> sendErrorResponseForCall(id, totalRequestSize, span,</span>
+<span class="source-line-no">590</span><span id="line-590"> "Call queue is full on " + this.rpcServer.server.getServerName()</span>
+<span class="source-line-no">591</span><span id="line-591"> + ", is hbase.ipc.server.max.callqueue.size too small?",</span>
+<span class="source-line-no">592</span><span id="line-592"> RpcServer.CALL_QUEUE_TOO_BIG_EXCEPTION);</span>
+<span class="source-line-no">593</span><span id="line-593"> return;</span>
+<span class="source-line-no">594</span><span id="line-594"> }</span>
+<span class="source-line-no">595</span><span id="line-595"> MethodDescriptor md = null;</span>
+<span class="source-line-no">596</span><span id="line-596"> Message param = null;</span>
+<span class="source-line-no">597</span><span id="line-597"> ExtendedCellScanner cellScanner = null;</span>
+<span class="source-line-no">598</span><span id="line-598"> try {</span>
+<span class="source-line-no">599</span><span id="line-599"> if (header.hasRequestParam() && header.getRequestParam()) {</span>
+<span class="source-line-no">600</span><span id="line-600"> md = this.service.getDescriptorForType().findMethodByName(header.getMethodName());</span>
+<span class="source-line-no">601</span><span id="line-601"> if (md == null) {</span>
+<span class="source-line-no">602</span><span id="line-602"> throw new UnsupportedOperationException(header.getMethodName());</span>
+<span class="source-line-no">603</span><span id="line-603"> }</span>
+<span class="source-line-no">604</span><span id="line-604"> builder = this.service.getRequestPrototype(md).newBuilderForType();</span>
+<span class="source-line-no">605</span><span id="line-605"> cis.resetSizeCounter();</span>
+<span class="source-line-no">606</span><span id="line-606"> int paramSize = cis.readRawVarint32();</span>
+<span class="source-line-no">607</span><span id="line-607"> offset += cis.getTotalBytesRead();</span>
+<span class="source-line-no">608</span><span id="line-608"> if (builder != null) {</span>
+<span class="source-line-no">609</span><span id="line-609"> ProtobufUtil.mergeFrom(builder, cis, paramSize);</span>
+<span class="source-line-no">610</span><span id="line-610"> param = builder.build();</span>
+<span class="source-line-no">611</span><span id="line-611"> }</span>
+<span class="source-line-no">612</span><span id="line-612"> offset += paramSize;</span>
+<span class="source-line-no">613</span><span id="line-613"> } else {</span>
+<span class="source-line-no">614</span><span id="line-614"> // currently header must have request param, so we directly throw</span>
+<span class="source-line-no">615</span><span id="line-615"> // exception here</span>
+<span class="source-line-no">616</span><span id="line-616"> String msg = "Invalid request header: " + TextFormat.shortDebugString(header)</span>
+<span class="source-line-no">617</span><span id="line-617"> + ", should have param set in it";</span>
+<span class="source-line-no">618</span><span id="line-618"> RpcServer.LOG.warn(msg);</span>
+<span class="source-line-no">619</span><span id="line-619"> throw new DoNotRetryIOException(msg);</span>
+<span class="source-line-no">620</span><span id="line-620"> }</span>
+<span class="source-line-no">621</span><span id="line-621"> if (header.hasCellBlockMeta()) {</span>
+<span class="source-line-no">622</span><span id="line-622"> buf.position(offset);</span>
+<span class="source-line-no">623</span><span id="line-623"> ByteBuff dup = buf.duplicate();</span>
+<span class="source-line-no">624</span><span id="line-624"> dup.limit(offset + header.getCellBlockMeta().getLength());</span>
+<span class="source-line-no">625</span><span id="line-625"> cellScanner = this.rpcServer.cellBlockBuilder.createCellScannerReusingBuffers(this.codec,</span>
+<span class="source-line-no">626</span><span id="line-626"> this.compressionCodec, dup);</span>
+<span class="source-line-no">627</span><span id="line-627"> }</span>
+<span class="source-line-no">628</span><span id="line-628"> } catch (Throwable thrown) {</span>
+<span class="source-line-no">629</span><span id="line-629"> InetSocketAddress address = this.rpcServer.getListenerAddress();</span>
+<span class="source-line-no">630</span><span id="line-630"> String msg = (address != null ? address : "(channel closed)")</span>
+<span class="source-line-no">631</span><span id="line-631"> + " is unable to read call parameter from client " + getHostAddress();</span>
+<span class="source-line-no">632</span><span id="line-632"> RpcServer.LOG.warn(msg, thrown);</span>
+<span class="source-line-no">633</span><span id="line-633"></span>
+<span class="source-line-no">634</span><span id="line-634"> this.rpcServer.metrics.exception(thrown);</span>
+<span class="source-line-no">635</span><span id="line-635"></span>
+<span class="source-line-no">636</span><span id="line-636"> final Throwable responseThrowable;</span>
+<span class="source-line-no">637</span><span id="line-637"> if (thrown instanceof LinkageError) {</span>
+<span class="source-line-no">638</span><span id="line-638"> // probably the hbase hadoop version does not match the running hadoop version</span>
+<span class="source-line-no">639</span><span id="line-639"> responseThrowable = new DoNotRetryIOException(thrown);</span>
+<span class="source-line-no">640</span><span id="line-640"> } else if (thrown instanceof UnsupportedOperationException) {</span>
+<span class="source-line-no">641</span><span id="line-641"> // If the method is not present on the server, do not retry.</span>
+<span class="source-line-no">642</span><span id="line-642"> responseThrowable = new DoNotRetryIOException(thrown);</span>
+<span class="source-line-no">643</span><span id="line-643"> } else {</span>
+<span class="source-line-no">644</span><span id="line-644"> responseThrowable = thrown;</span>
+<span class="source-line-no">645</span><span id="line-645"> }</span>
+<span class="source-line-no">646</span><span id="line-646"></span>
+<span class="source-line-no">647</span><span id="line-647"> sendErrorResponseForCall(id, totalRequestSize, span,</span>
+<span class="source-line-no">648</span><span id="line-648"> msg + "; " + responseThrowable.getMessage(), responseThrowable);</span>
+<span class="source-line-no">649</span><span id="line-649"> return;</span>
+<span class="source-line-no">650</span><span id="line-650"> }</span>
+<span class="source-line-no">651</span><span id="line-651"></span>
+<span class="source-line-no">652</span><span id="line-652"> int timeout = 0;</span>
+<span class="source-line-no">653</span><span id="line-653"> if (header.hasTimeout() && header.getTimeout() > 0) {</span>
+<span class="source-line-no">654</span><span id="line-654"> timeout = Math.max(this.rpcServer.minClientRequestTimeout, header.getTimeout());</span>
+<span class="source-line-no">655</span><span id="line-655"> }</span>
+<span class="source-line-no">656</span><span id="line-656"> ServerCall<?> call = createCall(id, this.service, md, header, param, cellScanner,</span>
+<span class="source-line-no">657</span><span id="line-657"> totalRequestSize, this.addr, timeout, this.callCleanup);</span>
+<span class="source-line-no">658</span><span id="line-658"></span>
+<span class="source-line-no">659</span><span id="line-659"> if (this.rpcServer.scheduler.dispatch(new CallRunner(this.rpcServer, call))) {</span>
+<span class="source-line-no">660</span><span id="line-660"> // unset span do that it's not closed in the finally block</span>
+<span class="source-line-no">661</span><span id="line-661"> span = null;</span>
+<span class="source-line-no">662</span><span id="line-662"> } else {</span>
+<span class="source-line-no">663</span><span id="line-663"> this.rpcServer.callQueueSizeInBytes.add(-1 * call.getSize());</span>
+<span class="source-line-no">664</span><span id="line-664"> this.rpcServer.metrics.exception(RpcServer.CALL_QUEUE_TOO_BIG_EXCEPTION);</span>
+<span class="source-line-no">665</span><span id="line-665"> call.setResponse(null, null, RpcServer.CALL_QUEUE_TOO_BIG_EXCEPTION,</span>
+<span class="source-line-no">666</span><span id="line-666"> "Call queue is full on " + this.rpcServer.server.getServerName()</span>
+<span class="source-line-no">667</span><span id="line-667"> + ", too many items queued ?");</span>
+<span class="source-line-no">668</span><span id="line-668"> TraceUtil.setError(span, RpcServer.CALL_QUEUE_TOO_BIG_EXCEPTION);</span>
+<span class="source-line-no">669</span><span id="line-669"> call.sendResponseIfReady();</span>
<span class="source-line-no">670</span><span id="line-670"> }</span>
-<span class="source-line-no">671</span><span id="line-671"> }</span>
-<span class="source-line-no">672</span><span id="line-672"> }</span>
-<span class="source-line-no">673</span><span id="line-673"></span>
-<span class="source-line-no">674</span><span id="line-674"> private void sendErrorResponseForCall(int id, long totalRequestSize, Span span, String msg,</span>
-<span class="source-line-no">675</span><span id="line-675"> Throwable responseThrowable) throws IOException {</span>
-<span class="source-line-no">676</span><span id="line-676"> ServerCall<?> failedcall = createCall(id, this.service, null, null, null, null,</span>
-<span class="source-line-no">677</span><span id="line-677"> totalRequestSize, null, 0, this.callCleanup);</span>
-<span class="source-line-no">678</span><span id="line-678"> failedcall.setResponse(null, null, responseThrowable, msg);</span>
-<span class="source-line-no">679</span><span id="line-679"> TraceUtil.setError(span, responseThrowable);</span>
-<span class="source-line-no">680</span><span id="line-680"> failedcall.sendResponseIfReady();</span>
-<span class="source-line-no">681</span><span id="line-681"> }</span>
-<span class="source-line-no">682</span><span id="line-682"></span>
-<span class="source-line-no">683</span><span id="line-683"> protected final RpcResponse getErrorResponse(String msg, Exception e) throws IOException {</span>
-<span class="source-line-no">684</span><span id="line-684"> ResponseHeader.Builder headerBuilder = ResponseHeader.newBuilder().setCallId(-1);</span>
-<span class="source-line-no">685</span><span id="line-685"> ServerCall.setExceptionResponse(e, msg, headerBuilder);</span>
-<span class="source-line-no">686</span><span id="line-686"> ByteBuffer headerBuf =</span>
-<span class="source-line-no">687</span><span id="line-687"> ServerCall.createHeaderAndMessageBytes(null, headerBuilder.build(), 0, null);</span>
-<span class="source-line-no">688</span><span id="line-688"> BufferChain buf = new BufferChain(headerBuf);</span>
-<span class="source-line-no">689</span><span id="line-689"> return () -> buf;</span>
-<span class="source-line-no">690</span><span id="line-690"> }</span>
-<span class="source-line-no">691</span><span id="line-691"></span>
-<span class="source-line-no">692</span><span id="line-692"> private void doBadPreambleHandling(String msg) throws IOException {</span>
-<span class="source-line-no">693</span><span id="line-693"> doBadPreambleHandling(msg, new FatalConnectionException(msg));</span>
+<span class="source-line-no">671</span><span id="line-671"> } finally {</span>
+<span class="source-line-no">672</span><span id="line-672"> if (span != null) {</span>
+<span class="source-line-no">673</span><span id="line-673"> span.end();</span>
+<span class="source-line-no">674</span><span id="line-674"> }</span>
+<span class="source-line-no">675</span><span id="line-675"> }</span>
+<span class="source-line-no">676</span><span id="line-676"> }</span>
+<span class="source-line-no">677</span><span id="line-677"></span>
+<span class="source-line-no">678</span><span id="line-678"> private void sendErrorResponseForCall(int id, long totalRequestSize, Span span, String msg,</span>
+<span class="source-line-no">679</span><span id="line-679"> Throwable responseThrowable) throws IOException {</span>
+<span class="source-line-no">680</span><span id="line-680"> ServerCall<?> failedcall = createCall(id, this.service, null, null, null, null,</span>
+<span class="source-line-no">681</span><span id="line-681"> totalRequestSize, null, 0, this.callCleanup);</span>
+<span class="source-line-no">682</span><span id="line-682"> failedcall.setResponse(null, null, responseThrowable, msg);</span>
+<span class="source-line-no">683</span><span id="line-683"> TraceUtil.setError(span, responseThrowable);</span>
+<span class="source-line-no">684</span><span id="line-684"> failedcall.sendResponseIfReady();</span>
+<span class="source-line-no">685</span><span id="line-685"> }</span>
+<span class="source-line-no">686</span><span id="line-686"></span>
+<span class="source-line-no">687</span><span id="line-687"> protected final RpcResponse getErrorResponse(String msg, Exception e) throws IOException {</span>
+<span class="source-line-no">688</span><span id="line-688"> ResponseHeader.Builder headerBuilder = ResponseHeader.newBuilder().setCallId(-1);</span>
+<span class="source-line-no">689</span><span id="line-689"> ServerCall.setExceptionResponse(e, msg, headerBuilder);</span>
+<span class="source-line-no">690</span><span id="line-690"> ByteBuffer headerBuf =</span>
+<span class="source-line-no">691</span><span id="line-691"> ServerCall.createHeaderAndMessageBytes(null, headerBuilder.build(), 0, null);</span>
+<span class="source-line-no">692</span><span id="line-692"> BufferChain buf = new BufferChain(headerBuf);</span>
+<span class="source-line-no">693</span><span id="line-693"> return () -> buf;</span>
<span class="source-line-no">694</span><span id="line-694"> }</span>
<span class="source-line-no">695</span><span id="line-695"></span>
-<span class="source-line-no">696</span><span id="line-696"> private void doBadPreambleHandling(String msg, Exception e) throws IOException {</span>
-<span class="source-line-no">697</span><span id="line-697"> RpcServer.LOG.warn(msg, e);</span>
-<span class="source-line-no">698</span><span id="line-698"> doRespond(getErrorResponse(msg, e));</span>
-<span class="source-line-no">699</span><span id="line-699"> }</span>
-<span class="source-line-no">700</span><span id="line-700"></span>
-<span class="source-line-no">701</span><span id="line-701"> private void doPreambleResponse(Message resp) throws IOException {</span>
-<span class="source-line-no">702</span><span id="line-702"> ResponseHeader header = ResponseHeader.newBuilder().setCallId(-1).build();</span>
-<span class="source-line-no">703</span><span id="line-703"> ByteBuffer buf = ServerCall.createHeaderAndMessageBytes(resp, header, 0, null);</span>
-<span class="source-line-no">704</span><span id="line-704"> BufferChain bufChain = new BufferChain(buf);</span>
-<span class="source-line-no">705</span><span id="line-705"> doRespond(() -> bufChain);</span>
-<span class="source-line-no">706</span><span id="line-706"> }</span>
-<span class="source-line-no">707</span><span id="line-707"></span>
-<span class="source-line-no">708</span><span id="line-708"> private boolean doConnectionRegistryResponse() throws IOException {</span>
-<span class="source-line-no">709</span><span id="line-709"> if (!(rpcServer.server instanceof ConnectionRegistryEndpoint)) {</span>
-<span class="source-line-no">710</span><span id="line-710"> // should be in tests or some scenarios where we should not reach here</span>
-<span class="source-line-no">711</span><span id="line-711"> return false;</span>
-<span class="source-line-no">712</span><span id="line-712"> }</span>
-<span class="source-line-no">713</span><span id="line-713"> // on backup masters, this request may be blocked since we need to fetch it from filesystem,</span>
-<span class="source-line-no">714</span><span id="line-714"> // but since it is just backup master, it is not a critical problem</span>
-<span class="source-line-no">715</span><span id="line-715"> String clusterId = ((ConnectionRegistryEndpoint) rpcServer.server).getClusterId();</span>
-<span class="source-line-no">716</span><span id="line-716"> RpcServer.LOG.debug("Response connection registry, clusterId = '{}'", clusterId);</span>
-<span class="source-line-no">717</span><span id="line-717"> if (clusterId == null) {</span>
-<span class="source-line-no">718</span><span id="line-718"> // should be in tests or some scenarios where we should not reach here</span>
-<span class="source-line-no">719</span><span id="line-719"> return false;</span>
-<span class="source-line-no">720</span><span id="line-720"> }</span>
-<span class="source-line-no">721</span><span id="line-721"> GetConnectionRegistryResponse resp =</span>
-<span class="source-line-no">722</span><span id="line-722"> GetConnectionRegistryResponse.newBuilder().setClusterId(clusterId).build();</span>
-<span class="source-line-no">723</span><span id="line-723"> doPreambleResponse(resp);</span>
-<span class="source-line-no">724</span><span id="line-724"> return true;</span>
-<span class="source-line-no">725</span><span id="line-725"> }</span>
-<span class="source-line-no">726</span><span id="line-726"></span>
-<span class="source-line-no">727</span><span id="line-727"> private void doSecurityPreambleResponse() throws IOException {</span>
-<span class="source-line-no">728</span><span id="line-728"> if (rpcServer.isSecurityEnabled) {</span>
-<span class="source-line-no">729</span><span id="line-729"> SecurityPreamableResponse resp = SecurityPreamableResponse.newBuilder()</span>
-<span class="source-line-no">730</span><span id="line-730"> .setServerPrincipal(rpcServer.serverPrincipal).build();</span>
-<span class="source-line-no">731</span><span id="line-731"> doPreambleResponse(resp);</span>
-<span class="source-line-no">732</span><span id="line-732"> } else {</span>
-<span class="source-line-no">733</span><span id="line-733"> // security is not enabled, do not need a principal when connecting, throw a special exception</span>
-<span class="source-line-no">734</span><span id="line-734"> // to let client know it should just use simple authentication</span>
-<span class="source-line-no">735</span><span id="line-735"> doRespond(getErrorResponse("security is not enabled", new SecurityNotEnabledException()));</span>
-<span class="source-line-no">736</span><span id="line-736"> }</span>
-<span class="source-line-no">737</span><span id="line-737"> }</span>
-<span class="source-line-no">738</span><span id="line-738"></span>
-<span class="source-line-no">739</span><span id="line-739"> protected final void callCleanupIfNeeded() {</span>
-<span class="source-line-no">740</span><span id="line-740"> if (callCleanup != null) {</span>
-<span class="source-line-no">741</span><span id="line-741"> callCleanup.run();</span>
-<span class="source-line-no">742</span><span id="line-742"> callCleanup = null;</span>
-<span class="source-line-no">743</span><span id="line-743"> }</span>
-<span class="source-line-no">744</span><span id="line-744"> }</span>
-<span class="source-line-no">745</span><span id="line-745"></span>
-<span class="source-line-no">746</span><span id="line-746"> protected enum PreambleResponse {</span>
-<span class="source-line-no">747</span><span id="line-747"> SUCCEED, // successfully processed the rpc preamble header</span>
-<span class="source-line-no">748</span><span id="line-748"> CONTINUE, // the preamble header is for other purpose, wait for the rpc preamble header</span>
-<span class="source-line-no">749</span><span id="line-749"> CLOSE // close the rpc connection</span>
-<span class="source-line-no">750</span><span id="line-750"> }</span>
-<span class="source-line-no">751</span><span id="line-751"></span>
-<span class="source-line-no">752</span><span id="line-752"> protected final PreambleResponse processPreamble(ByteBuffer preambleBuffer) throws IOException {</span>
-<span class="source-line-no">753</span><span id="line-753"> assert preambleBuffer.remaining() == 6;</span>
-<span class="source-line-no">754</span><span id="line-754"> if (</span>
-<span class="source-line-no">755</span><span id="line-755"> ByteBufferUtils.equals(preambleBuffer, preambleBuffer.position(), 6,</span>
-<span class="source-line-no">756</span><span id="line-756"> RpcClient.REGISTRY_PREAMBLE_HEADER, 0, 6) && doConnectionRegistryResponse()</span>
-<span class="source-line-no">757</span><span id="line-757"> ) {</span>
-<span class="source-line-no">758</span><span id="line-758"> return PreambleResponse.CLOSE;</span>
-<span class="source-line-no">759</span><span id="line-759"> }</span>
-<span class="source-line-no">760</span><span id="line-760"> if (</span>
-<span class="source-line-no">761</span><span id="line-761"> ByteBufferUtils.equals(preambleBuffer, preambleBuffer.position(), 6,</span>
-<span class="source-line-no">762</span><span id="line-762"> RpcClient.SECURITY_PREAMBLE_HEADER, 0, 6)</span>
-<span class="source-line-no">763</span><span id="line-763"> ) {</span>
-<span class="source-line-no">764</span><span id="line-764"> doSecurityPreambleResponse();</span>
-<span class="source-line-no">765</span><span id="line-765"> return PreambleResponse.CONTINUE;</span>
-<span class="source-line-no">766</span><span id="line-766"> }</span>
-<span class="source-line-no">767</span><span id="line-767"> if (!ByteBufferUtils.equals(preambleBuffer, preambleBuffer.position(), 4, RPC_HEADER, 0, 4)) {</span>
-<span class="source-line-no">768</span><span id="line-768"> doBadPreambleHandling(</span>
-<span class="source-line-no">769</span><span id="line-769"> "Expected HEADER=" + Bytes.toStringBinary(RPC_HEADER) + " but received HEADER="</span>
-<span class="source-line-no">770</span><span id="line-770"> + Bytes.toStringBinary(</span>
-<span class="source-line-no">771</span><span id="line-771"> ByteBufferUtils.toBytes(preambleBuffer, preambleBuffer.position(), RPC_HEADER.length),</span>
-<span class="source-line-no">772</span><span id="line-772"> 0, RPC_HEADER.length)</span>
-<span class="source-line-no">773</span><span id="line-773"> + " from " + toString());</span>
-<span class="source-line-no">774</span><span id="line-774"> return PreambleResponse.CLOSE;</span>
-<span class="source-line-no">775</span><span id="line-775"> }</span>
-<span class="source-line-no">776</span><span id="line-776"> int version = preambleBuffer.get(preambleBuffer.position() + 4) & 0xFF;</span>
-<span class="source-line-no">777</span><span id="line-777"> byte authByte = preambleBuffer.get(preambleBuffer.position() + 5);</span>
-<span class="source-line-no">778</span><span id="line-778"> if (version != RpcServer.CURRENT_VERSION) {</span>
-<span class="source-line-no">779</span><span id="line-779"> String msg = getFatalConnectionString(version, authByte);</span>
-<span class="source-line-no">780</span><span id="line-780"> doBadPreambleHandling(msg, new WrongVersionException(msg));</span>
-<span class="source-line-no">781</span><span id="line-781"> return PreambleResponse.CLOSE;</span>
-<span class="source-line-no">782</span><span id="line-782"> }</span>
-<span class="source-line-no">783</span><span id="line-783"></span>
-<span class="source-line-no">784</span><span id="line-784"> this.provider = rpcServer.saslProviders.selectProvider(authByte);</span>
-<span class="source-line-no">785</span><span id="line-785"> if (this.provider == null) {</span>
-<span class="source-line-no">786</span><span id="line-786"> String msg = getFatalConnectionString(version, authByte);</span>
-<span class="source-line-no">787</span><span id="line-787"> doBadPreambleHandling(msg, new BadAuthException(msg));</span>
-<span class="source-line-no">788</span><span id="line-788"> return PreambleResponse.CLOSE;</span>
-<span class="source-line-no">789</span><span id="line-789"> }</span>
-<span class="source-line-no">790</span><span id="line-790"> // TODO this is a wart while simple auth'n doesn't go through sasl.</span>
-<span class="source-line-no">791</span><span id="line-791"> if (this.rpcServer.isSecurityEnabled && isSimpleAuthentication()) {</span>
-<span class="source-line-no">792</span><span id="line-792"> if (this.rpcServer.allowFallbackToSimpleAuth) {</span>
-<span class="source-line-no">793</span><span id="line-793"> this.rpcServer.metrics.authenticationFallback();</span>
-<span class="source-line-no">794</span><span id="line-794"> authenticatedWithFallback = true;</span>
-<span class="source-line-no">795</span><span id="line-795"> } else {</span>
-<span class="source-line-no">796</span><span id="line-796"> AccessDeniedException ae = new AccessDeniedException("Authentication is required");</span>
-<span class="source-line-no">797</span><span id="line-797"> doRespond(getErrorResponse(ae.getMessage(), ae));</span>
-<span class="source-line-no">798</span><span id="line-798"> return PreambleResponse.CLOSE;</span>
-<span class="source-line-no">799</span><span id="line-799"> }</span>
-<span class="source-line-no">800</span><span id="line-800"> }</span>
-<span class="source-line-no">801</span><span id="line-801"> if (!this.rpcServer.isSecurityEnabled && !isSimpleAuthentication()) {</span>
-<span class="source-line-no">802</span><span id="line-802"> doRawSaslReply(SaslStatus.SUCCESS, new IntWritable(SaslUtil.SWITCH_TO_SIMPLE_AUTH), null,</span>
-<span class="source-line-no">803</span><span id="line-803"> null);</span>
-<span class="source-line-no">804</span><span id="line-804"> provider = rpcServer.saslProviders.getSimpleProvider();</span>
-<span class="source-line-no">805</span><span id="line-805"> // client has already sent the initial Sasl message and we</span>
-<span class="source-line-no">806</span><span id="line-806"> // should ignore it. Both client and server should fall back</span>
-<span class="source-line-no">807</span><span id="line-807"> // to simple auth from now on.</span>
-<span class="source-line-no">808</span><span id="line-808"> skipInitialSaslHandshake = true;</span>
-<span class="source-line-no">809</span><span id="line-809"> }</span>
-<span class="source-line-no">810</span><span id="line-810"> useSasl = !(provider instanceof SimpleSaslServerAuthenticationProvider);</span>
-<span class="source-line-no">811</span><span id="line-811"> return PreambleResponse.SUCCEED;</span>
-<span class="source-line-no">812</span><span id="line-812"> }</span>
-<span class="source-line-no">813</span><span id="line-813"></span>
-<span class="source-line-no">814</span><span id="line-814"> boolean isSimpleAuthentication() {</span>
-<span class="source-line-no">815</span><span id="line-815"> return Objects.requireNonNull(provider) instanceof SimpleSaslServerAuthenticationProvider;</span>
+<span class="source-line-no">696</span><span id="line-696"> private void doBadPreambleHandling(String msg) throws IOException {</span>
+<span class="source-line-no">697</span><span id="line-697"> doBadPreambleHandling(msg, new FatalConnectionException(msg));</span>
+<span class="source-line-no">698</span><span id="line-698"> }</span>
+<span class="source-line-no">699</span><span id="line-699"></span>
+<span class="source-line-no">700</span><span id="line-700"> private void doBadPreambleHandling(String msg, Exception e) throws IOException {</span>
+<span class="source-line-no">701</span><span id="line-701"> RpcServer.LOG.warn(msg, e);</span>
+<span class="source-line-no">702</span><span id="line-702"> doRespond(getErrorResponse(msg, e));</span>
+<span class="source-line-no">703</span><span id="line-703"> }</span>
+<span class="source-line-no">704</span><span id="line-704"></span>
+<span class="source-line-no">705</span><span id="line-705"> private void doPreambleResponse(Message resp) throws IOException {</span>
+<span class="source-line-no">706</span><span id="line-706"> ResponseHeader header = ResponseHeader.newBuilder().setCallId(-1).build();</span>
+<span class="source-line-no">707</span><span id="line-707"> ByteBuffer buf = ServerCall.createHeaderAndMessageBytes(resp, header, 0, null);</span>
+<span class="source-line-no">708</span><span id="line-708"> BufferChain bufChain = new BufferChain(buf);</span>
+<span class="source-line-no">709</span><span id="line-709"> doRespond(() -> bufChain);</span>
+<span class="source-line-no">710</span><span id="line-710"> }</span>
+<span class="source-line-no">711</span><span id="line-711"></span>
+<span class="source-line-no">712</span><span id="line-712"> private boolean doConnectionRegistryResponse() throws IOException {</span>
+<span class="source-line-no">713</span><span id="line-713"> if (!(rpcServer.server instanceof ConnectionRegistryEndpoint)) {</span>
+<span class="source-line-no">714</span><span id="line-714"> // should be in tests or some scenarios where we should not reach here</span>
+<span class="source-line-no">715</span><span id="line-715"> return false;</span>
+<span class="source-line-no">716</span><span id="line-716"> }</span>
+<span class="source-line-no">717</span><span id="line-717"> // on backup masters, this request may be blocked since we need to fetch it from filesystem,</span>
+<span class="source-line-no">718</span><span id="line-718"> // but since it is just backup master, it is not a critical problem</span>
+<span class="source-line-no">719</span><span id="line-719"> String clusterId = ((ConnectionRegistryEndpoint) rpcServer.server).getClusterId();</span>
+<span class="source-line-no">720</span><span id="line-720"> RpcServer.LOG.debug("Response connection registry, clusterId = '{}'", clusterId);</span>
+<span class="source-line-no">721</span><span id="line-721"> if (clusterId == null) {</span>
+<span class="source-line-no">722</span><span id="line-722"> // should be in tests or some scenarios where we should not reach here</span>
+<span class="source-line-no">723</span><span id="line-723"> return false;</span>
+<span class="source-line-no">724</span><span id="line-724"> }</span>
+<span class="source-line-no">725</span><span id="line-725"> GetConnectionRegistryResponse resp =</span>
+<span class="source-line-no">726</span><span id="line-726"> GetConnectionRegistryResponse.newBuilder().setClusterId(clusterId).build();</span>
+<span class="source-line-no">727</span><span id="line-727"> doPreambleResponse(resp);</span>
+<span class="source-line-no">728</span><span id="line-728"> return true;</span>
+<span class="source-line-no">729</span><span id="line-729"> }</span>
+<span class="source-line-no">730</span><span id="line-730"></span>
+<span class="source-line-no">731</span><span id="line-731"> private void doSecurityPreambleResponse() throws IOException {</span>
+<span class="source-line-no">732</span><span id="line-732"> if (rpcServer.isSecurityEnabled) {</span>
+<span class="source-line-no">733</span><span id="line-733"> SecurityPreamableResponse resp = SecurityPreamableResponse.newBuilder()</span>
+<span class="source-line-no">734</span><span id="line-734"> .setServerPrincipal(rpcServer.serverPrincipal).build();</span>
+<span class="source-line-no">735</span><span id="line-735"> doPreambleResponse(resp);</span>
+<span class="source-line-no">736</span><span id="line-736"> } else {</span>
+<span class="source-line-no">737</span><span id="line-737"> // security is not enabled, do not need a principal when connecting, throw a special exception</span>
+<span class="source-line-no">738</span><span id="line-738"> // to let client know it should just use simple authentication</span>
+<span class="source-line-no">739</span><span id="line-739"> doRespond(getErrorResponse("security is not enabled", new SecurityNotEnabledException()));</span>
+<span class="source-line-no">740</span><span id="line-740"> }</span>
+<span class="source-line-no">741</span><span id="line-741"> }</span>
+<span class="source-line-no">742</span><span id="line-742"></span>
+<span class="source-line-no">743</span><span id="line-743"> protected final void callCleanupIfNeeded() {</span>
+<span class="source-line-no">744</span><span id="line-744"> if (callCleanup != null) {</span>
+<span class="source-line-no">745</span><span id="line-745"> callCleanup.run();</span>
+<span class="source-line-no">746</span><span id="line-746"> callCleanup = null;</span>
+<span class="source-line-no">747</span><span id="line-747"> }</span>
+<span class="source-line-no">748</span><span id="line-748"> }</span>
+<span class="source-line-no">749</span><span id="line-749"></span>
+<span class="source-line-no">750</span><span id="line-750"> protected enum PreambleResponse {</span>
+<span class="source-line-no">751</span><span id="line-751"> SUCCEED, // successfully processed the rpc preamble header</span>
+<span class="source-line-no">752</span><span id="line-752"> CONTINUE, // the preamble header is for other purpose, wait for the rpc preamble header</span>
+<span class="source-line-no">753</span><span id="line-753"> CLOSE // close the rpc connection</span>
+<span class="source-line-no">754</span><span id="line-754"> }</span>
+<span class="source-line-no">755</span><span id="line-755"></span>
+<span class="source-line-no">756</span><span id="line-756"> protected final PreambleResponse processPreamble(ByteBuffer preambleBuffer) throws IOException {</span>
+<span class="source-line-no">757</span><span id="line-757"> assert preambleBuffer.remaining() == 6;</span>
+<span class="source-line-no">758</span><span id="line-758"> if (</span>
+<span class="source-line-no">759</span><span id="line-759"> ByteBufferUtils.equals(preambleBuffer, preambleBuffer.position(), 6,</span>
+<span class="source-line-no">760</span><span id="line-760"> RpcClient.REGISTRY_PREAMBLE_HEADER, 0, 6) && doConnectionRegistryResponse()</span>
+<span class="source-line-no">761</span><span id="line-761"> ) {</span>
+<span class="source-line-no">762</span><span id="line-762"> return PreambleResponse.CLOSE;</span>
+<span class="source-line-no">763</span><span id="line-763"> }</span>
+<span class="source-line-no">764</span><span id="line-764"> if (</span>
+<span class="source-line-no">765</span><span id="line-765"> ByteBufferUtils.equals(preambleBuffer, preambleBuffer.position(), 6,</span>
+<span class="source-line-no">766</span><span id="line-766"> RpcClient.SECURITY_PREAMBLE_HEADER, 0, 6)</span>
+<span class="source-line-no">767</span><span id="line-767"> ) {</span>
+<span class="source-line-no">768</span><span id="line-768"> doSecurityPreambleResponse();</span>
+<span class="source-line-no">769</span><span id="line-769"> return PreambleResponse.CONTINUE;</span>
+<span class="source-line-no">770</span><span id="line-770"> }</span>
+<span class="source-line-no">771</span><span id="line-771"> if (!ByteBufferUtils.equals(preambleBuffer, preambleBuffer.position(), 4, RPC_HEADER, 0, 4)) {</span>
+<span class="source-line-no">772</span><span id="line-772"> doBadPreambleHandling(</span>
+<span class="source-line-no">773</span><span id="line-773"> "Expected HEADER=" + Bytes.toStringBinary(RPC_HEADER) + " but received HEADER="</span>
+<span class="source-line-no">774</span><span id="line-774"> + Bytes.toStringBinary(</span>
+<span class="source-line-no">775</span><span id="line-775"> ByteBufferUtils.toBytes(preambleBuffer, preambleBuffer.position(), RPC_HEADER.length),</span>
+<span class="source-line-no">776</span><span id="line-776"> 0, RPC_HEADER.length)</span>
+<span class="source-line-no">777</span><span id="line-777"> + " from " + toString());</span>
+<span class="source-line-no">778</span><span id="line-778"> return PreambleResponse.CLOSE;</span>
+<span class="source-line-no">779</span><span id="line-779"> }</span>
+<span class="source-line-no">780</span><span id="line-780"> int version = preambleBuffer.get(preambleBuffer.position() + 4) & 0xFF;</span>
+<span class="source-line-no">781</span><span id="line-781"> byte authByte = preambleBuffer.get(preambleBuffer.position() + 5);</span>
+<span class="source-line-no">782</span><span id="line-782"> if (version != RpcServer.CURRENT_VERSION) {</span>
+<span class="source-line-no">783</span><span id="line-783"> String msg = getFatalConnectionString(version, authByte);</span>
+<span class="source-line-no">784</span><span id="line-784"> doBadPreambleHandling(msg, new WrongVersionException(msg));</span>
+<span class="source-line-no">785</span><span id="line-785"> return PreambleResponse.CLOSE;</span>
+<span class="source-line-no">786</span><span id="line-786"> }</span>
+<span class="source-line-no">787</span><span id="line-787"></span>
+<span class="source-line-no">788</span><span id="line-788"> this.provider = rpcServer.saslProviders.selectProvider(authByte);</span>
+<span class="source-line-no">789</span><span id="line-789"> if (this.provider == null) {</span>
+<span class="source-line-no">790</span><span id="line-790"> String msg = getFatalConnectionString(version, authByte);</span>
+<span class="source-line-no">791</span><span id="line-791"> doBadPreambleHandling(msg, new BadAuthException(msg));</span>
+<span class="source-line-no">792</span><span id="line-792"> return PreambleResponse.CLOSE;</span>
+<span class="source-line-no">793</span><span id="line-793"> }</span>
+<span class="source-line-no">794</span><span id="line-794"> // TODO this is a wart while simple auth'n doesn't go through sasl.</span>
+<span class="source-line-no">795</span><span id="line-795"> if (this.rpcServer.isSecurityEnabled && isSimpleAuthentication()) {</span>
+<span class="source-line-no">796</span><span id="line-796"> if (this.rpcServer.allowFallbackToSimpleAuth) {</span>
+<span class="source-line-no">797</span><span id="line-797"> this.rpcServer.metrics.authenticationFallback();</span>
+<span class="source-line-no">798</span><span id="line-798"> authenticatedWithFallback = true;</span>
+<span class="source-line-no">799</span><span id="line-799"> } else {</span>
+<span class="source-line-no">800</span><span id="line-800"> AccessDeniedException ae = new AccessDeniedException("Authentication is required");</span>
+<span class="source-line-no">801</span><span id="line-801"> doRespond(getErrorResponse(ae.getMessage(), ae));</span>
+<span class="source-line-no">802</span><span id="line-802"> return PreambleResponse.CLOSE;</span>
+<span class="source-line-no">803</span><span id="line-803"> }</span>
+<span class="source-line-no">804</span><span id="line-804"> }</span>
+<span class="source-line-no">805</span><span id="line-805"> if (!this.rpcServer.isSecurityEnabled && !isSimpleAuthentication()) {</span>
+<span class="source-line-no">806</span><span id="line-806"> doRawSaslReply(SaslStatus.SUCCESS, new IntWritable(SaslUtil.SWITCH_TO_SIMPLE_AUTH), null,</span>
+<span class="source-line-no">807</span><span id="line-807"> null);</span>
+<span class="source-line-no">808</span><span id="line-808"> provider = rpcServer.saslProviders.getSimpleProvider();</span>
+<span class="source-line-no">809</span><span id="line-809"> // client has already sent the initial Sasl message and we</span>
+<span class="source-line-no">810</span><span id="line-810"> // should ignore it. Both client and server should fall back</span>
+<span class="source-line-no">811</span><span id="line-811"> // to simple auth from now on.</span>
+<span class="source-line-no">812</span><span id="line-812"> skipInitialSaslHandshake = true;</span>
+<span class="source-line-no">813</span><span id="line-813"> }</span>
+<span class="source-line-no">814</span><span id="line-814"> useSasl = !(provider instanceof SimpleSaslServerAuthenticationProvider);</span>
+<span class="source-line-no">815</span><span id="line-815"> return PreambleResponse.SUCCEED;</span>
<span class="source-line-no">816</span><span id="line-816"> }</span>
<span class="source-line-no">817</span><span id="line-817"></span>
-<span class="source-line-no">818</span><span id="line-818"> public abstract boolean isConnectionOpen();</span>
-<span class="source-line-no">819</span><span id="line-819"></span>
-<span class="source-line-no">820</span><span id="line-820"> public abstract ServerCall<?> createCall(int id, BlockingService service, MethodDescriptor md,</span>
-<span class="source-line-no">821</span><span id="line-821"> RequestHeader header, Message param, ExtendedCellScanner cellScanner, long size,</span>
-<span class="source-line-no">822</span><span id="line-822"> InetAddress remoteAddress, int timeout, CallCleanup reqCleanup);</span>
+<span class="source-line-no">818</span><span id="line-818"> boolean isSimpleAuthentication() {</span>
+<span class="source-line-no">819</span><span id="line-819"> return Objects.requireNonNull(provider) instanceof SimpleSaslServerAuthenticationProvider;</span>
+<span class="source-line-no">820</span><span id="line-820"> }</span>
+<span class="source-line-no">821</span><span id="line-821"></span>
+<span class="source-line-no">822</span><span id="line-822"> public abstract boolean isConnectionOpen();</span>
<span class="source-line-no">823</span><span id="line-823"></span>
-<span class="source-line-no">824</span><span id="line-824"> private static class ByteBuffByteInput extends ByteInput {</span>
-<span class="source-line-no">825</span><span id="line-825"></span>
-<span class="source-line-no">826</span><span id="line-826"> private ByteBuff buf;</span>
-<span class="source-line-no">827</span><span id="line-827"> private int length;</span>
-<span class="source-line-no">828</span><span id="line-828"></span>
-<span class="source-line-no">829</span><span id="line-829"> ByteBuffByteInput(ByteBuff buf, int length) {</span>
-<span class="source-line-no">830</span><span id="line-830"> this.buf = buf;</span>
-<span class="source-line-no">831</span><span id="line-831"> this.length = length;</span>
-<span class="source-line-no">832</span><span id="line-832"> }</span>
-<span class="source-line-no">833</span><span id="line-833"></span>
-<span class="source-line-no">834</span><span id="line-834"> @Override</span>
-<span class="source-line-no">835</span><span id="line-835"> public byte read(int offset) {</span>
-<span class="source-line-no">836</span><span id="line-836"> return this.buf.get(offset);</span>
-<span class="source-line-no">837</span><span id="line-837"> }</span>
-<span class="source-line-no">838</span><span id="line-838"></span>
-<span class="source-line-no">839</span><span id="line-839"> @Override</span>
-<span class="source-line-no">840</span><span id="line-840"> public int read(int offset, byte[] out, int outOffset, int len) {</span>
-<span class="source-line-no">841</span><span id="line-841"> this.buf.get(offset, out, outOffset, len);</span>
-<span class="source-line-no">842</span><span id="line-842"> return len;</span>
-<span class="source-line-no">843</span><span id="line-843"> }</span>
-<span class="source-line-no">844</span><span id="line-844"></span>
-<span class="source-line-no">845</span><span id="line-845"> @Override</span>
-<span class="source-line-no">846</span><span id="line-846"> public int read(int offset, ByteBuffer out) {</span>
-<span class="source-line-no">847</span><span id="line-847"> int len = out.remaining();</span>
-<span class="source-line-no">848</span><span id="line-848"> this.buf.get(out, offset, len);</span>
-<span class="source-line-no">849</span><span id="line-849"> return len;</span>
-<span class="source-line-no">850</span><span id="line-850"> }</span>
-<span class="source-line-no">851</span><span id="line-851"></span>
-<span class="source-line-no">852</span><span id="line-852"> @Override</span>
-<span class="source-line-no">853</span><span id="line-853"> public long readLong(int offset) {</span>
-<span class="source-line-no">854</span><span id="line-854"> return this.buf.getLong(offset);</span>
-<span class="source-line-no">855</span><span id="line-855"> }</span>
-<span class="source-line-no">856</span><span id="line-856"></span>
-<span class="source-line-no">857</span><span id="line-857"> @Override</span>
-<span class="source-line-no">858</span><span id="line-858"> public int size() {</span>
-<span class="source-line-no">859</span><span id="line-859"> return this.length;</span>
-<span class="source-line-no">860</span><span id="line-860"> }</span>
-<span class="source-line-no">861</span><span id="line-861"></span>
-<span class="source-line-no">862</span><span id="line-862"> }</span>
-<span class="source-line-no">863</span><span id="line-863">}</span>
+<span class="source-line-no">824</span><span id="line-824"> public abstract ServerCall<?> createCall(int id, BlockingService service, MethodDescriptor md,</span>
+<span class="source-line-no">825</span><span id="line-825"> RequestHeader header, Message param, ExtendedCellScanner cellScanner, long size,</span>
+<span class="source-line-no">826</span><span id="line-826"> InetAddress remoteAddress, int timeout, CallCleanup reqCleanup);</span>
+<span class="source-line-no">827</span><span id="line-827"></span>
+<span class="source-line-no">828</span><span id="line-828"> private static class ByteBuffByteInput extends ByteInput {</span>
+<span class="source-line-no">829</span><span id="line-829"></span>
+<span class="source-line-no">830</span><span id="line-830"> private ByteBuff buf;</span>
+<span class="source-line-no">831</span><span id="line-831"> private int length;</span>
+<span class="source-line-no">832</span><span id="line-832"></span>
+<span class="source-line-no">833</span><span id="line-833"> ByteBuffByteInput(ByteBuff buf, int length) {</span>
+<span class="source-line-no">834</span><span id="line-834"> this.buf = buf;</span>
+<span class="source-line-no">835</span><span id="line-835"> this.length = length;</span>
+<span class="source-line-no">836</span><span id="line-836"> }</span>
+<span class="source-line-no">837</span><span id="line-837"></span>
+<span class="source-line-no">838</span><span id="line-838"> @Override</span>
+<span class="source-line-no">839</span><span id="line-839"> public byte read(int offset) {</span>
+<span class="source-line-no">840</span><span id="line-840"> return this.buf.get(offset);</span>
+<span class="source-line-no">841</span><span id="line-841"> }</span>
+<span class="source-line-no">842</span><span id="line-842"></span>
+<span class="source-line-no">843</span><span id="line-843"> @Override</span>
+<span class="source-line-no">844</span><span id="line-844"> public int read(int offset, byte[] out, int outOffset, int len) {</span>
+<span class="source-line-no">845</span><span id="line-845"> this.buf.get(offset, out, outOffset, len);</span>
+<span class="source-line-no">846</span><span id="line-846"> return len;</span>
+<span class="source-line-no">847</span><span id="line-847"> }</span>
+<span class="source-line-no">848</span><span id="line-848"></span>
+<span class="source-line-no">849</span><span id="line-849"> @Override</span>
+<span class="source-line-no">850</span><span id="line-850"> public int read(int offset, ByteBuffer out) {</span>
+<span class="source-line-no">851</span><span id="line-851"> int len = out.remaining();</span>
+<span class="source-line-no">852</span><span id="line-852"> this.buf.get(out, offset, len);</span>
+<span class="source-line-no">853</span><span id="line-853"> return len;</span>
+<span class="source-line-no">854</span><span id="line-854"> }</span>
+<span class="source-line-no">855</span><span id="line-855"></span>
+<span class="source-line-no">856</span><span id="line-856"> @Override</span>
+<span class="source-line-no">857</span><span id="line-857"> public long readLong(int offset) {</span>
+<span class="source-line-no">858</span><span id="line-858"> return this.buf.getLong(offset);</span>
+<span class="source-line-no">859</span><span id="line-859"> }</span>
+<span class="source-line-no">860</span><span id="line-860"></span>
+<span class="source-line-no">861</span><span id="line-861"> @Override</span>
+<span class="source-line-no">862</span><span id="line-862"> public int size() {</span>
+<span class="source-line-no">863</span><span id="line-863"> return this.length;</span>
+<span class="source-line-no">864</span><span id="line-864"> }</span>
+<span class="source-line-no">865</span><span id="line-865"></span>
+<span class="source-line-no">866</span><span id="line-866"> }</span>
+<span class="source-line-no">867</span><span id="line-867">}</span>
diff --git a/apidocs/src-html/org/apache/hadoop/hbase/regionserver/HRegionServer.html b/apidocs/src-html/org/apache/hadoop/hbase/regionserver/HRegionServer.html
index d1f86cfea30..23bf408aba5 100644
--- a/apidocs/src-html/org/apache/hadoop/hbase/regionserver/HRegionServer.html
+++ b/apidocs/src-html/org/apache/hadoop/hbase/regionserver/HRegionServer.html
@@ -1685,2084 +1685,2088 @@
<span class="source-line-no">1672</span><span id="line-1672"> .setHostName(clientMetrics.getHostName())</span>
<span class="source-line-no">1673</span><span id="line-1673"> .setWriteRequestsCount(clientMetrics.getWriteRequestsCount())</span>
<span class="source-line-no">1674</span><span id="line-1674"> .setFilteredRequestsCount(clientMetrics.getFilteredReadRequests())</span>
-<span class="source-line-no">1675</span><span id="line-1675"> .setReadRequestsCount(clientMetrics.getReadRequestsCount()).build())</span>
-<span class="source-line-no">1676</span><span id="line-1676"> .forEach(userLoadBldr::addClientMetrics);</span>
-<span class="source-line-no">1677</span><span id="line-1677"> return userLoadBldr.build();</span>
-<span class="source-line-no">1678</span><span id="line-1678"> }</span>
-<span class="source-line-no">1679</span><span id="line-1679"></span>
-<span class="source-line-no">1680</span><span id="line-1680"> public RegionLoad createRegionLoad(final String encodedRegionName) throws IOException {</span>
-<span class="source-line-no">1681</span><span id="line-1681"> HRegion r = onlineRegions.get(encodedRegionName);</span>
-<span class="source-line-no">1682</span><span id="line-1682"> return r != null ? createRegionLoad(r, null, null) : null;</span>
-<span class="source-line-no">1683</span><span id="line-1683"> }</span>
-<span class="source-line-no">1684</span><span id="line-1684"></span>
-<span class="source-line-no">1685</span><span id="line-1685"> /**</span>
-<span class="source-line-no">1686</span><span id="line-1686"> * Inner class that runs on a long period checking if regions need compaction.</span>
-<span class="source-line-no">1687</span><span id="line-1687"> */</span>
-<span class="source-line-no">1688</span><span id="line-1688"> private static class CompactionChecker extends ScheduledChore {</span>
-<span class="source-line-no">1689</span><span id="line-1689"> private final HRegionServer instance;</span>
-<span class="source-line-no">1690</span><span id="line-1690"> private final int majorCompactPriority;</span>
-<span class="source-line-no">1691</span><span id="line-1691"> private final static int DEFAULT_PRIORITY = Integer.MAX_VALUE;</span>
-<span class="source-line-no">1692</span><span id="line-1692"> // Iteration is 1-based rather than 0-based so we don't check for compaction</span>
-<span class="source-line-no">1693</span><span id="line-1693"> // immediately upon region server startup</span>
-<span class="source-line-no">1694</span><span id="line-1694"> private long iteration = 1;</span>
-<span class="source-line-no">1695</span><span id="line-1695"></span>
-<span class="source-line-no">1696</span><span id="line-1696"> CompactionChecker(final HRegionServer h, final int sleepTime, final Stoppable stopper) {</span>
-<span class="source-line-no">1697</span><span id="line-1697"> super("CompactionChecker", stopper, sleepTime);</span>
-<span class="source-line-no">1698</span><span id="line-1698"> this.instance = h;</span>
-<span class="source-line-no">1699</span><span id="line-1699"> LOG.info(this.getName() + " runs every " + Duration.ofMillis(sleepTime));</span>
-<span class="source-line-no">1700</span><span id="line-1700"></span>
-<span class="source-line-no">1701</span><span id="line-1701"> /*</span>
-<span class="source-line-no">1702</span><span id="line-1702"> * MajorCompactPriority is configurable. If not set, the compaction will use default priority.</span>
-<span class="source-line-no">1703</span><span id="line-1703"> */</span>
-<span class="source-line-no">1704</span><span id="line-1704"> this.majorCompactPriority = this.instance.conf</span>
-<span class="source-line-no">1705</span><span id="line-1705"> .getInt("hbase.regionserver.compactionChecker.majorCompactPriority", DEFAULT_PRIORITY);</span>
-<span class="source-line-no">1706</span><span id="line-1706"> }</span>
-<span class="source-line-no">1707</span><span id="line-1707"></span>
-<span class="source-line-no">1708</span><span id="line-1708"> @Override</span>
-<span class="source-line-no">1709</span><span id="line-1709"> protected void chore() {</span>
-<span class="source-line-no">1710</span><span id="line-1710"> for (HRegion hr : this.instance.onlineRegions.values()) {</span>
-<span class="source-line-no">1711</span><span id="line-1711"> // If region is read only or compaction is disabled at table level, there's no need to</span>
-<span class="source-line-no">1712</span><span id="line-1712"> // iterate through region's stores</span>
-<span class="source-line-no">1713</span><span id="line-1713"> if (hr == null || hr.isReadOnly() || !hr.getTableDescriptor().isCompactionEnabled()) {</span>
-<span class="source-line-no">1714</span><span id="line-1714"> continue;</span>
-<span class="source-line-no">1715</span><span id="line-1715"> }</span>
-<span class="source-line-no">1716</span><span id="line-1716"></span>
-<span class="source-line-no">1717</span><span id="line-1717"> for (HStore s : hr.stores.values()) {</span>
-<span class="source-line-no">1718</span><span id="line-1718"> try {</span>
-<span class="source-line-no">1719</span><span id="line-1719"> long multiplier = s.getCompactionCheckMultiplier();</span>
-<span class="source-line-no">1720</span><span id="line-1720"> assert multiplier > 0;</span>
-<span class="source-line-no">1721</span><span id="line-1721"> if (iteration % multiplier != 0) {</span>
-<span class="source-line-no">1722</span><span id="line-1722"> continue;</span>
-<span class="source-line-no">1723</span><span id="line-1723"> }</span>
-<span class="source-line-no">1724</span><span id="line-1724"> if (s.needsCompaction()) {</span>
-<span class="source-line-no">1725</span><span id="line-1725"> // Queue a compaction. Will recognize if major is needed.</span>
-<span class="source-line-no">1726</span><span id="line-1726"> this.instance.compactSplitThread.requestSystemCompaction(hr, s,</span>
-<span class="source-line-no">1727</span><span id="line-1727"> getName() + " requests compaction");</span>
-<span class="source-line-no">1728</span><span id="line-1728"> } else if (s.shouldPerformMajorCompaction()) {</span>
-<span class="source-line-no">1729</span><span id="line-1729"> s.triggerMajorCompaction();</span>
-<span class="source-line-no">1730</span><span id="line-1730"> if (</span>
-<span class="source-line-no">1731</span><span id="line-1731"> majorCompactPriority == DEFAULT_PRIORITY</span>
-<span class="source-line-no">1732</span><span id="line-1732"> || majorCompactPriority > hr.getCompactPriority()</span>
-<span class="source-line-no">1733</span><span id="line-1733"> ) {</span>
-<span class="source-line-no">1734</span><span id="line-1734"> this.instance.compactSplitThread.requestCompaction(hr, s,</span>
-<span class="source-line-no">1735</span><span id="line-1735"> getName() + " requests major compaction; use default priority", Store.NO_PRIORITY,</span>
-<span class="source-line-no">1736</span><span id="line-1736"> CompactionLifeCycleTracker.DUMMY, null);</span>
-<span class="source-line-no">1737</span><span id="line-1737"> } else {</span>
+<span class="source-line-no">1675</span><span id="line-1675"> .setReadRequestsCount(clientMetrics.getReadRequestsCount())</span>
+<span class="source-line-no">1676</span><span id="line-1676"> .setHostAddress(clientMetrics.getHostAddress()).setUserName(clientMetrics.getUserName())</span>
+<span class="source-line-no">1677</span><span id="line-1677"> .setClientVersion(clientMetrics.getClientVersion())</span>
+<span class="source-line-no">1678</span><span id="line-1678"> .setServiceName(clientMetrics.getServiceName())</span>
+<span class="source-line-no">1679</span><span id="line-1679"> .setClientVersion(clientMetrics.getClientVersion()).build())</span>
+<span class="source-line-no">1680</span><span id="line-1680"> .forEach(userLoadBldr::addClientMetrics);</span>
+<span class="source-line-no">1681</span><span id="line-1681"> return userLoadBldr.build();</span>
+<span class="source-line-no">1682</span><span id="line-1682"> }</span>
+<span class="source-line-no">1683</span><span id="line-1683"></span>
+<span class="source-line-no">1684</span><span id="line-1684"> public RegionLoad createRegionLoad(final String encodedRegionName) throws IOException {</span>
+<span class="source-line-no">1685</span><span id="line-1685"> HRegion r = onlineRegions.get(encodedRegionName);</span>
+<span class="source-line-no">1686</span><span id="line-1686"> return r != null ? createRegionLoad(r, null, null) : null;</span>
+<span class="source-line-no">1687</span><span id="line-1687"> }</span>
+<span class="source-line-no">1688</span><span id="line-1688"></span>
+<span class="source-line-no">1689</span><span id="line-1689"> /**</span>
+<span class="source-line-no">1690</span><span id="line-1690"> * Inner class that runs on a long period checking if regions need compaction.</span>
+<span class="source-line-no">1691</span><span id="line-1691"> */</span>
+<span class="source-line-no">1692</span><span id="line-1692"> private static class CompactionChecker extends ScheduledChore {</span>
+<span class="source-line-no">1693</span><span id="line-1693"> private final HRegionServer instance;</span>
+<span class="source-line-no">1694</span><span id="line-1694"> private final int majorCompactPriority;</span>
+<span class="source-line-no">1695</span><span id="line-1695"> private final static int DEFAULT_PRIORITY = Integer.MAX_VALUE;</span>
+<span class="source-line-no">1696</span><span id="line-1696"> // Iteration is 1-based rather than 0-based so we don't check for compaction</span>
+<span class="source-line-no">1697</span><span id="line-1697"> // immediately upon region server startup</span>
+<span class="source-line-no">1698</span><span id="line-1698"> private long iteration = 1;</span>
+<span class="source-line-no">1699</span><span id="line-1699"></span>
+<span class="source-line-no">1700</span><span id="line-1700"> CompactionChecker(final HRegionServer h, final int sleepTime, final Stoppable stopper) {</span>
+<span class="source-line-no">1701</span><span id="line-1701"> super("CompactionChecker", stopper, sleepTime);</span>
+<span class="source-line-no">1702</span><span id="line-1702"> this.instance = h;</span>
+<span class="source-line-no">1703</span><span id="line-1703"> LOG.info(this.getName() + " runs every " + Duration.ofMillis(sleepTime));</span>
+<span class="source-line-no">1704</span><span id="line-1704"></span>
+<span class="source-line-no">1705</span><span id="line-1705"> /*</span>
+<span class="source-line-no">1706</span><span id="line-1706"> * MajorCompactPriority is configurable. If not set, the compaction will use default priority.</span>
+<span class="source-line-no">1707</span><span id="line-1707"> */</span>
+<span class="source-line-no">1708</span><span id="line-1708"> this.majorCompactPriority = this.instance.conf</span>
+<span class="source-line-no">1709</span><span id="line-1709"> .getInt("hbase.regionserver.compactionChecker.majorCompactPriority", DEFAULT_PRIORITY);</span>
+<span class="source-line-no">1710</span><span id="line-1710"> }</span>
+<span class="source-line-no">1711</span><span id="line-1711"></span>
+<span class="source-line-no">1712</span><span id="line-1712"> @Override</span>
+<span class="source-line-no">1713</span><span id="line-1713"> protected void chore() {</span>
+<span class="source-line-no">1714</span><span id="line-1714"> for (HRegion hr : this.instance.onlineRegions.values()) {</span>
+<span class="source-line-no">1715</span><span id="line-1715"> // If region is read only or compaction is disabled at table level, there's no need to</span>
+<span class="source-line-no">1716</span><span id="line-1716"> // iterate through region's stores</span>
+<span class="source-line-no">1717</span><span id="line-1717"> if (hr == null || hr.isReadOnly() || !hr.getTableDescriptor().isCompactionEnabled()) {</span>
+<span class="source-line-no">1718</span><span id="line-1718"> continue;</span>
+<span class="source-line-no">1719</span><span id="line-1719"> }</span>
+<span class="source-line-no">1720</span><span id="line-1720"></span>
+<span class="source-line-no">1721</span><span id="line-1721"> for (HStore s : hr.stores.values()) {</span>
+<span class="source-line-no">1722</span><span id="line-1722"> try {</span>
+<span class="source-line-no">1723</span><span id="line-1723"> long multiplier = s.getCompactionCheckMultiplier();</span>
+<span class="source-line-no">1724</span><span id="line-1724"> assert multiplier > 0;</span>
+<span class="source-line-no">1725</span><span id="line-1725"> if (iteration % multiplier != 0) {</span>
+<span class="source-line-no">1726</span><span id="line-1726"> continue;</span>
+<span class="source-line-no">1727</span><span id="line-1727"> }</span>
+<span class="source-line-no">1728</span><span id="line-1728"> if (s.needsCompaction()) {</span>
+<span class="source-line-no">1729</span><span id="line-1729"> // Queue a compaction. Will recognize if major is needed.</span>
+<span class="source-line-no">1730</span><span id="line-1730"> this.instance.compactSplitThread.requestSystemCompaction(hr, s,</span>
+<span class="source-line-no">1731</span><span id="line-1731"> getName() + " requests compaction");</span>
+<span class="source-line-no">1732</span><span id="line-1732"> } else if (s.shouldPerformMajorCompaction()) {</span>
+<span class="source-line-no">1733</span><span id="line-1733"> s.triggerMajorCompaction();</span>
+<span class="source-line-no">1734</span><span id="line-1734"> if (</span>
+<span class="source-line-no">1735</span><span id="line-1735"> majorCompactPriority == DEFAULT_PRIORITY</span>
+<span class="source-line-no">1736</span><span id="line-1736"> || majorCompactPriority > hr.getCompactPriority()</span>
+<span class="source-line-no">1737</span><span id="line-1737"> ) {</span>
<span class="source-line-no">1738</span><span id="line-1738"> this.instance.compactSplitThread.requestCompaction(hr, s,</span>
-<span class="source-line-no">1739</span><span id="line-1739"> getName() + " requests major compaction; use configured priority",</span>
-<span class="source-line-no">1740</span><span id="line-1740"> this.majorCompactPriority, CompactionLifeCycleTracker.DUMMY, null);</span>
-<span class="source-line-no">1741</span><span id="line-1741"> }</span>
-<span class="source-line-no">1742</span><span id="line-1742"> }</span>
-<span class="source-line-no">1743</span><span id="line-1743"> } catch (IOException e) {</span>
-<span class="source-line-no">1744</span><span id="line-1744"> LOG.warn("Failed major compaction check on " + hr, e);</span>
-<span class="source-line-no">1745</span><span id="line-1745"> }</span>
-<span class="source-line-no">1746</span><span id="line-1746"> }</span>
-<span class="source-line-no">1747</span><span id="line-1747"> }</span>
-<span class="source-line-no">1748</span><span id="line-1748"> iteration = (iteration == Long.MAX_VALUE) ? 0 : (iteration + 1);</span>
-<span class="source-line-no">1749</span><span id="line-1749"> }</span>
-<span class="source-line-no">1750</span><span id="line-1750"> }</span>
-<span class="source-line-no">1751</span><span id="line-1751"></span>
-<span class="source-line-no">1752</span><span id="line-1752"> private static class PeriodicMemStoreFlusher extends ScheduledChore {</span>
-<span class="source-line-no">1753</span><span id="line-1753"> private final HRegionServer server;</span>
-<span class="source-line-no">1754</span><span id="line-1754"> private final static int RANGE_OF_DELAY = 5 * 60; // 5 min in seconds</span>
-<span class="source-line-no">1755</span><span id="line-1755"> private final static int MIN_DELAY_TIME = 0; // millisec</span>
-<span class="source-line-no">1756</span><span id="line-1756"> private final long rangeOfDelayMs;</span>
-<span class="source-line-no">1757</span><span id="line-1757"></span>
-<span class="source-line-no">1758</span><span id="line-1758"> PeriodicMemStoreFlusher(int cacheFlushInterval, final HRegionServer server) {</span>
-<span class="source-line-no">1759</span><span id="line-1759"> super("MemstoreFlusherChore", server, cacheFlushInterval);</span>
-<span class="source-line-no">1760</span><span id="line-1760"> this.server = server;</span>
+<span class="source-line-no">1739</span><span id="line-1739"> getName() + " requests major compaction; use default priority", Store.NO_PRIORITY,</span>
+<span class="source-line-no">1740</span><span id="line-1740"> CompactionLifeCycleTracker.DUMMY, null);</span>
+<span class="source-line-no">1741</span><span id="line-1741"> } else {</span>
+<span class="source-line-no">1742</span><span id="line-1742"> this.instance.compactSplitThread.requestCompaction(hr, s,</span>
+<span class="source-line-no">1743</span><span id="line-1743"> getName() + " requests major compaction; use configured priority",</span>
+<span class="source-line-no">1744</span><span id="line-1744"> this.majorCompactPriority, CompactionLifeCycleTracker.DUMMY, null);</span>
+<span class="source-line-no">1745</span><span id="line-1745"> }</span>
+<span class="source-line-no">1746</span><span id="line-1746"> }</span>
+<span class="source-line-no">1747</span><span id="line-1747"> } catch (IOException e) {</span>
+<span class="source-line-no">1748</span><span id="line-1748"> LOG.warn("Failed major compaction check on " + hr, e);</span>
+<span class="source-line-no">1749</span><span id="line-1749"> }</span>
+<span class="source-line-no">1750</span><span id="line-1750"> }</span>
+<span class="source-line-no">1751</span><span id="line-1751"> }</span>
+<span class="source-line-no">1752</span><span id="line-1752"> iteration = (iteration == Long.MAX_VALUE) ? 0 : (iteration + 1);</span>
+<span class="source-line-no">1753</span><span id="line-1753"> }</span>
+<span class="source-line-no">1754</span><span id="line-1754"> }</span>
+<span class="source-line-no">1755</span><span id="line-1755"></span>
+<span class="source-line-no">1756</span><span id="line-1756"> private static class PeriodicMemStoreFlusher extends ScheduledChore {</span>
+<span class="source-line-no">1757</span><span id="line-1757"> private final HRegionServer server;</span>
+<span class="source-line-no">1758</span><span id="line-1758"> private final static int RANGE_OF_DELAY = 5 * 60; // 5 min in seconds</span>
+<span class="source-line-no">1759</span><span id="line-1759"> private final static int MIN_DELAY_TIME = 0; // millisec</span>
+<span class="source-line-no">1760</span><span id="line-1760"> private final long rangeOfDelayMs;</span>
<span class="source-line-no">1761</span><span id="line-1761"></span>
-<span class="source-line-no">1762</span><span id="line-1762"> final long configuredRangeOfDelay = server.getConfiguration()</span>
-<span class="source-line-no">1763</span><span id="line-1763"> .getInt("hbase.regionserver.periodicmemstoreflusher.rangeofdelayseconds", RANGE_OF_DELAY);</span>
-<span class="source-line-no">1764</span><span id="line-1764"> this.rangeOfDelayMs = TimeUnit.SECONDS.toMillis(configuredRangeOfDelay);</span>
-<span class="source-line-no">1765</span><span id="line-1765"> }</span>
-<span class="source-line-no">1766</span><span id="line-1766"></span>
-<span class="source-line-no">1767</span><span id="line-1767"> @Override</span>
-<span class="source-line-no">1768</span><span id="line-1768"> protected void chore() {</span>
-<span class="source-line-no">1769</span><span id="line-1769"> final StringBuilder whyFlush = new StringBuilder();</span>
-<span class="source-line-no">1770</span><span id="line-1770"> for (HRegion r : this.server.onlineRegions.values()) {</span>
-<span class="source-line-no">1771</span><span id="line-1771"> if (r == null) {</span>
-<span class="source-line-no">1772</span><span id="line-1772"> continue;</span>
-<span class="source-line-no">1773</span><span id="line-1773"> }</span>
-<span class="source-line-no">1774</span><span id="line-1774"> if (r.shouldFlush(whyFlush)) {</span>
-<span class="source-line-no">1775</span><span id="line-1775"> FlushRequester requester = server.getFlushRequester();</span>
-<span class="source-line-no">1776</span><span id="line-1776"> if (requester != null) {</span>
-<span class="source-line-no">1777</span><span id="line-1777"> long delay = ThreadLocalRandom.current().nextLong(rangeOfDelayMs) + MIN_DELAY_TIME;</span>
-<span class="source-line-no">1778</span><span id="line-1778"> // Throttle the flushes by putting a delay. If we don't throttle, and there</span>
-<span class="source-line-no">1779</span><span id="line-1779"> // is a balanced write-load on the regions in a table, we might end up</span>
-<span class="source-line-no">1780</span><span id="line-1780"> // overwhelming the filesystem with too many flushes at once.</span>
-<span class="source-line-no">1781</span><span id="line-1781"> if (requester.requestDelayedFlush(r, delay)) {</span>
-<span class="source-line-no">1782</span><span id="line-1782"> LOG.info("{} requesting flush of {} because {} after random delay {} ms", getName(),</span>
-<span class="source-line-no">1783</span><span id="line-1783"> r.getRegionInfo().getRegionNameAsString(), whyFlush.toString(), delay);</span>
-<span class="source-line-no">1784</span><span id="line-1784"> }</span>
-<span class="source-line-no">1785</span><span id="line-1785"> }</span>
-<span class="source-line-no">1786</span><span id="line-1786"> }</span>
-<span class="source-line-no">1787</span><span id="line-1787"> }</span>
-<span class="source-line-no">1788</span><span id="line-1788"> }</span>
-<span class="source-line-no">1789</span><span id="line-1789"> }</span>
-<span class="source-line-no">1790</span><span id="line-1790"></span>
-<span class="source-line-no">1791</span><span id="line-1791"> /**</span>
-<span class="source-line-no">1792</span><span id="line-1792"> * Report the status of the server. A server is online once all the startup is completed (setting</span>
-<span class="source-line-no">1793</span><span id="line-1793"> * up filesystem, starting executorService threads, etc.). This method is designed mostly to be</span>
-<span class="source-line-no">1794</span><span id="line-1794"> * useful in tests.</span>
-<span class="source-line-no">1795</span><span id="line-1795"> * @return true if online, false if not.</span>
-<span class="source-line-no">1796</span><span id="line-1796"> */</span>
-<span class="source-line-no">1797</span><span id="line-1797"> public boolean isOnline() {</span>
-<span class="source-line-no">1798</span><span id="line-1798"> return online.get();</span>
-<span class="source-line-no">1799</span><span id="line-1799"> }</span>
-<span class="source-line-no">1800</span><span id="line-1800"></span>
-<span class="source-line-no">1801</span><span id="line-1801"> /**</span>
-<span class="source-line-no">1802</span><span id="line-1802"> * Setup WAL log and replication if enabled. Replication setup is done in here because it wants to</span>
-<span class="source-line-no">1803</span><span id="line-1803"> * be hooked up to WAL.</span>
-<span class="source-line-no">1804</span><span id="line-1804"> */</span>
-<span class="source-line-no">1805</span><span id="line-1805"> private void setupWALAndReplication() throws IOException {</span>
-<span class="source-line-no">1806</span><span id="line-1806"> WALFactory factory = new WALFactory(conf, serverName, this);</span>
-<span class="source-line-no">1807</span><span id="line-1807"> // TODO Replication make assumptions here based on the default filesystem impl</span>
-<span class="source-line-no">1808</span><span id="line-1808"> Path oldLogDir = new Path(walRootDir, HConstants.HREGION_OLDLOGDIR_NAME);</span>
-<span class="source-line-no">1809</span><span id="line-1809"> String logName = AbstractFSWALProvider.getWALDirectoryName(this.serverName.toString());</span>
-<span class="source-line-no">1810</span><span id="line-1810"></span>
-<span class="source-line-no">1811</span><span id="line-1811"> Path logDir = new Path(walRootDir, logName);</span>
-<span class="source-line-no">1812</span><span id="line-1812"> LOG.debug("logDir={}", logDir);</span>
-<span class="source-line-no">1813</span><span id="line-1813"> if (this.walFs.exists(logDir)) {</span>
-<span class="source-line-no">1814</span><span id="line-1814"> throw new RegionServerRunningException(</span>
-<span class="source-line-no">1815</span><span id="line-1815"> "Region server has already created directory at " + this.serverName.toString());</span>
-<span class="source-line-no">1816</span><span id="line-1816"> }</span>
-<span class="source-line-no">1817</span><span id="line-1817"> // Create wal directory here and we will never create it again in other places. This is</span>
-<span class="source-line-no">1818</span><span id="line-1818"> // important to make sure that our fencing way takes effect. See HBASE-29797 for more details.</span>
-<span class="source-line-no">1819</span><span id="line-1819"> if (!this.walFs.mkdirs(logDir)) {</span>
-<span class="source-line-no">1820</span><span id="line-1820"> throw new IOException("Can not create wal directory " + logDir);</span>
-<span class="source-line-no">1821</span><span id="line-1821"> }</span>
-<span class="source-line-no">1822</span><span id="line-1822"> // Instantiate replication if replication enabled. Pass it the log directories.</span>
-<span class="source-line-no">1823</span><span id="line-1823"> createNewReplicationInstance(conf, this, this.walFs, logDir, oldLogDir, factory);</span>
-<span class="source-line-no">1824</span><span id="line-1824"></span>
-<span class="source-line-no">1825</span><span id="line-1825"> WALActionsListener walEventListener = getWALEventTrackerListener(conf);</span>
-<span class="source-line-no">1826</span><span id="line-1826"> if (walEventListener != null && factory.getWALProvider() != null) {</span>
-<span class="source-line-no">1827</span><span id="line-1827"> factory.getWALProvider().addWALActionsListener(walEventListener);</span>
-<span class="source-line-no">1828</span><span id="line-1828"> }</span>
-<span class="source-line-no">1829</span><span id="line-1829"> this.walFactory = factory;</span>
-<span class="source-line-no">1830</span><span id="line-1830"> }</span>
-<span class="source-line-no">1831</span><span id="line-1831"></span>
-<span class="source-line-no">1832</span><span id="line-1832"> private WALActionsListener getWALEventTrackerListener(Configuration conf) {</span>
-<span class="source-line-no">1833</span><span id="line-1833"> if (conf.getBoolean(WAL_EVENT_TRACKER_ENABLED_KEY, WAL_EVENT_TRACKER_ENABLED_DEFAULT)) {</span>
-<span class="source-line-no">1834</span><span id="line-1834"> WALEventTrackerListener listener =</span>
-<span class="source-line-no">1835</span><span id="line-1835"> new WALEventTrackerListener(conf, getNamedQueueRecorder(), getServerName());</span>
-<span class="source-line-no">1836</span><span id="line-1836"> return listener;</span>
-<span class="source-line-no">1837</span><span id="line-1837"> }</span>
-<span class="source-line-no">1838</span><span id="line-1838"> return null;</span>
-<span class="source-line-no">1839</span><span id="line-1839"> }</span>
-<span class="source-line-no">1840</span><span id="line-1840"></span>
-<span class="source-line-no">1841</span><span id="line-1841"> /**</span>
-<span class="source-line-no">1842</span><span id="line-1842"> * Start up replication source and sink handlers.</span>
-<span class="source-line-no">1843</span><span id="line-1843"> */</span>
-<span class="source-line-no">1844</span><span id="line-1844"> private void startReplicationService() throws IOException {</span>
-<span class="source-line-no">1845</span><span id="line-1845"> if (sameReplicationSourceAndSink && this.replicationSourceHandler != null) {</span>
-<span class="source-line-no">1846</span><span id="line-1846"> this.replicationSourceHandler.startReplicationService();</span>
-<span class="source-line-no">1847</span><span id="line-1847"> } else {</span>
-<span class="source-line-no">1848</span><span id="line-1848"> if (this.replicationSourceHandler != null) {</span>
-<span class="source-line-no">1849</span><span id="line-1849"> this.replicationSourceHandler.startReplicationService();</span>
-<span class="source-line-no">1850</span><span id="line-1850"> }</span>
-<span class="source-line-no">1851</span><span id="line-1851"> if (this.replicationSinkHandler != null) {</span>
-<span class="source-line-no">1852</span><span id="line-1852"> this.replicationSinkHandler.startReplicationService();</span>
-<span class="source-line-no">1853</span><span id="line-1853"> }</span>
-<span class="source-line-no">1854</span><span id="line-1854"> }</span>
-<span class="source-line-no">1855</span><span id="line-1855"> }</span>
-<span class="source-line-no">1856</span><span id="line-1856"></span>
-<span class="source-line-no">1857</span><span id="line-1857"> /** Returns Master address tracker instance. */</span>
-<span class="source-line-no">1858</span><span id="line-1858"> public MasterAddressTracker getMasterAddressTracker() {</span>
-<span class="source-line-no">1859</span><span id="line-1859"> return this.masterAddressTracker;</span>
-<span class="source-line-no">1860</span><span id="line-1860"> }</span>
-<span class="source-line-no">1861</span><span id="line-1861"></span>
-<span class="source-line-no">1862</span><span id="line-1862"> /**</span>
-<span class="source-line-no">1863</span><span id="line-1863"> * Start maintenance Threads, Server, Worker and lease checker threads. Start all threads we need</span>
-<span class="source-line-no">1864</span><span id="line-1864"> * to run. This is called after we've successfully registered with the Master. Install an</span>
-<span class="source-line-no">1865</span><span id="line-1865"> * UncaughtExceptionHandler that calls abort of RegionServer if we get an unhandled exception. We</span>
-<span class="source-line-no">1866</span><span id="line-1866"> * cannot set the handler on all threads. Server's internal Listener thread is off limits. For</span>
-<span class="source-line-no">1867</span><span id="line-1867"> * Server, if an OOME, it waits a while then retries. Meantime, a flush or a compaction that tries</span>
-<span class="source-line-no">1868</span><span id="line-1868"> * to run should trigger same critical condition and the shutdown will run. On its way out, this</span>
-<span class="source-line-no">1869</span><span id="line-1869"> * server will shut down Server. Leases are sort of inbetween. It has an internal thread that</span>
-<span class="source-line-no">1870</span><span id="line-1870"> * while it inherits from Chore, it keeps its own internal stop mechanism so needs to be stopped</span>
-<span class="source-line-no">1871</span><span id="line-1871"> * by this hosting server. Worker logs the exception and exits.</span>
-<span class="source-line-no">1872</span><span id="line-1872"> */</span>
-<span class="source-line-no">1873</span><span id="line-1873"> private void startServices() throws IOException {</span>
-<span class="source-line-no">1874</span><span id="line-1874"> if (!isStopped() && !isAborted()) {</span>
-<span class="source-line-no">1875</span><span id="line-1875"> initializeThreads();</span>
-<span class="source-line-no">1876</span><span id="line-1876"> }</span>
-<span class="source-line-no">1877</span><span id="line-1877"> this.secureBulkLoadManager = new SecureBulkLoadManager(this.conf, asyncClusterConnection);</span>
-<span class="source-line-no">1878</span><span id="line-1878"> this.secureBulkLoadManager.start();</span>
-<span class="source-line-no">1879</span><span id="line-1879"></span>
-<span class="source-line-no">1880</span><span id="line-1880"> // Health checker thread.</span>
-<span class="source-line-no">1881</span><span id="line-1881"> if (isHealthCheckerConfigured()) {</span>
-<span class="source-line-no">1882</span><span id="line-1882"> int sleepTime = this.conf.getInt(HConstants.HEALTH_CHORE_WAKE_FREQ,</span>
-<span class="source-line-no">1883</span><span id="line-1883"> HConstants.DEFAULT_THREAD_WAKE_FREQUENCY);</span>
-<span class="source-line-no">1884</span><span id="line-1884"> healthCheckChore = new HealthCheckChore(sleepTime, this, getConfiguration());</span>
-<span class="source-line-no">1885</span><span id="line-1885"> }</span>
-<span class="source-line-no">1886</span><span id="line-1886"> // Executor status collect thread.</span>
-<span class="source-line-no">1887</span><span id="line-1887"> if (</span>
-<span class="source-line-no">1888</span><span id="line-1888"> this.conf.getBoolean(HConstants.EXECUTOR_STATUS_COLLECT_ENABLED,</span>
-<span class="source-line-no">1889</span><span id="line-1889"> HConstants.DEFAULT_EXECUTOR_STATUS_COLLECT_ENABLED)</span>
-<span class="source-line-no">1890</span><span id="line-1890"> ) {</span>
-<span class="source-line-no">1891</span><span id="line-1891"> int sleepTime =</span>
-<span class="source-line-no">1892</span><span id="line-1892"> this.conf.getInt(ExecutorStatusChore.WAKE_FREQ, ExecutorStatusChore.DEFAULT_WAKE_FREQ);</span>
-<span class="source-line-no">1893</span><span id="line-1893"> executorStatusChore = new ExecutorStatusChore(sleepTime, this, this.getExecutorService(),</span>
-<span class="source-line-no">1894</span><span id="line-1894"> this.metricsRegionServer.getMetricsSource());</span>
-<span class="source-line-no">1895</span><span id="line-1895"> }</span>
-<span class="source-line-no">1896</span><span id="line-1896"></span>
-<span class="source-line-no">1897</span><span id="line-1897"> this.walRoller = new LogRoller(this);</span>
-<span class="source-line-no">1898</span><span id="line-1898"> this.flushThroughputController = FlushThroughputControllerFactory.create(this, conf);</span>
-<span class="source-line-no">1899</span><span id="line-1899"> this.procedureResultReporter = new RemoteProcedureResultReporter(this);</span>
+<span class="source-line-no">1762</span><span id="line-1762"> PeriodicMemStoreFlusher(int cacheFlushInterval, final HRegionServer server) {</span>
+<span class="source-line-no">1763</span><span id="line-1763"> super("MemstoreFlusherChore", server, cacheFlushInterval);</span>
+<span class="source-line-no">1764</span><span id="line-1764"> this.server = server;</span>
+<span class="source-line-no">1765</span><span id="line-1765"></span>
+<span class="source-line-no">1766</span><span id="line-1766"> final long configuredRangeOfDelay = server.getConfiguration()</span>
+<span class="source-line-no">1767</span><span id="line-1767"> .getInt("hbase.regionserver.periodicmemstoreflusher.rangeofdelayseconds", RANGE_OF_DELAY);</span>
+<span class="source-line-no">1768</span><span id="line-1768"> this.rangeOfDelayMs = TimeUnit.SECONDS.toMillis(configuredRangeOfDelay);</span>
+<span class="source-line-no">1769</span><span id="line-1769"> }</span>
+<span class="source-line-no">1770</span><span id="line-1770"></span>
+<span class="source-line-no">1771</span><span id="line-1771"> @Override</span>
+<span class="source-line-no">1772</span><span id="line-1772"> protected void chore() {</span>
+<span class="source-line-no">1773</span><span id="line-1773"> final StringBuilder whyFlush = new StringBuilder();</span>
+<span class="source-line-no">1774</span><span id="line-1774"> for (HRegion r : this.server.onlineRegions.values()) {</span>
+<span class="source-line-no">1775</span><span id="line-1775"> if (r == null) {</span>
+<span class="source-line-no">1776</span><span id="line-1776"> continue;</span>
+<span class="source-line-no">1777</span><span id="line-1777"> }</span>
+<span class="source-line-no">1778</span><span id="line-1778"> if (r.shouldFlush(whyFlush)) {</span>
+<span class="source-line-no">1779</span><span id="line-1779"> FlushRequester requester = server.getFlushRequester();</span>
+<span class="source-line-no">1780</span><span id="line-1780"> if (requester != null) {</span>
+<span class="source-line-no">1781</span><span id="line-1781"> long delay = ThreadLocalRandom.current().nextLong(rangeOfDelayMs) + MIN_DELAY_TIME;</span>
+<span class="source-line-no">1782</span><span id="line-1782"> // Throttle the flushes by putting a delay. If we don't throttle, and there</span>
+<span class="source-line-no">1783</span><span id="line-1783"> // is a balanced write-load on the regions in a table, we might end up</span>
+<span class="source-line-no">1784</span><span id="line-1784"> // overwhelming the filesystem with too many flushes at once.</span>
+<span class="source-line-no">1785</span><span id="line-1785"> if (requester.requestDelayedFlush(r, delay)) {</span>
+<span class="source-line-no">1786</span><span id="line-1786"> LOG.info("{} requesting flush of {} because {} after random delay {} ms", getName(),</span>
+<span class="source-line-no">1787</span><span id="line-1787"> r.getRegionInfo().getRegionNameAsString(), whyFlush.toString(), delay);</span>
+<span class="source-line-no">1788</span><span id="line-1788"> }</span>
+<span class="source-line-no">1789</span><span id="line-1789"> }</span>
+<span class="source-line-no">1790</span><span id="line-1790"> }</span>
+<span class="source-line-no">1791</span><span id="line-1791"> }</span>
+<span class="source-line-no">1792</span><span id="line-1792"> }</span>
+<span class="source-line-no">1793</span><span id="line-1793"> }</span>
+<span class="source-line-no">1794</span><span id="line-1794"></span>
+<span class="source-line-no">1795</span><span id="line-1795"> /**</span>
+<span class="source-line-no">1796</span><span id="line-1796"> * Report the status of the server. A server is online once all the startup is completed (setting</span>
+<span class="source-line-no">1797</span><span id="line-1797"> * up filesystem, starting executorService threads, etc.). This method is designed mostly to be</span>
+<span class="source-line-no">1798</span><span id="line-1798"> * useful in tests.</span>
+<span class="source-line-no">1799</span><span id="line-1799"> * @return true if online, false if not.</span>
+<span class="source-line-no">1800</span><span id="line-1800"> */</span>
+<span class="source-line-no">1801</span><span id="line-1801"> public boolean isOnline() {</span>
+<span class="source-line-no">1802</span><span id="line-1802"> return online.get();</span>
+<span class="source-line-no">1803</span><span id="line-1803"> }</span>
+<span class="source-line-no">1804</span><span id="line-1804"></span>
+<span class="source-line-no">1805</span><span id="line-1805"> /**</span>
+<span class="source-line-no">1806</span><span id="line-1806"> * Setup WAL log and replication if enabled. Replication setup is done in here because it wants to</span>
+<span class="source-line-no">1807</span><span id="line-1807"> * be hooked up to WAL.</span>
+<span class="source-line-no">1808</span><span id="line-1808"> */</span>
+<span class="source-line-no">1809</span><span id="line-1809"> private void setupWALAndReplication() throws IOException {</span>
+<span class="source-line-no">1810</span><span id="line-1810"> WALFactory factory = new WALFactory(conf, serverName, this);</span>
+<span class="source-line-no">1811</span><span id="line-1811"> // TODO Replication make assumptions here based on the default filesystem impl</span>
+<span class="source-line-no">1812</span><span id="line-1812"> Path oldLogDir = new Path(walRootDir, HConstants.HREGION_OLDLOGDIR_NAME);</span>
+<span class="source-line-no">1813</span><span id="line-1813"> String logName = AbstractFSWALProvider.getWALDirectoryName(this.serverName.toString());</span>
+<span class="source-line-no">1814</span><span id="line-1814"></span>
+<span class="source-line-no">1815</span><span id="line-1815"> Path logDir = new Path(walRootDir, logName);</span>
+<span class="source-line-no">1816</span><span id="line-1816"> LOG.debug("logDir={}", logDir);</span>
+<span class="source-line-no">1817</span><span id="line-1817"> if (this.walFs.exists(logDir)) {</span>
+<span class="source-line-no">1818</span><span id="line-1818"> throw new RegionServerRunningException(</span>
+<span class="source-line-no">1819</span><span id="line-1819"> "Region server has already created directory at " + this.serverName.toString());</span>
+<span class="source-line-no">1820</span><span id="line-1820"> }</span>
+<span class="source-line-no">1821</span><span id="line-1821"> // Create wal directory here and we will never create it again in other places. This is</span>
+<span class="source-line-no">1822</span><span id="line-1822"> // important to make sure that our fencing way takes effect. See HBASE-29797 for more details.</span>
+<span class="source-line-no">1823</span><span id="line-1823"> if (!this.walFs.mkdirs(logDir)) {</span>
+<span class="source-line-no">1824</span><span id="line-1824"> throw new IOException("Can not create wal directory " + logDir);</span>
+<span class="source-line-no">1825</span><span id="line-1825"> }</span>
+<span class="source-line-no">1826</span><span id="line-1826"> // Instantiate replication if replication enabled. Pass it the log directories.</span>
+<span class="source-line-no">1827</span><span id="line-1827"> createNewReplicationInstance(conf, this, this.walFs, logDir, oldLogDir, factory);</span>
+<span class="source-line-no">1828</span><span id="line-1828"></span>
+<span class="source-line-no">1829</span><span id="line-1829"> WALActionsListener walEventListener = getWALEventTrackerListener(conf);</span>
+<span class="source-line-no">1830</span><span id="line-1830"> if (walEventListener != null && factory.getWALProvider() != null) {</span>
+<span class="source-line-no">1831</span><span id="line-1831"> factory.getWALProvider().addWALActionsListener(walEventListener);</span>
+<span class="source-line-no">1832</span><span id="line-1832"> }</span>
+<span class="source-line-no">1833</span><span id="line-1833"> this.walFactory = factory;</span>
+<span class="source-line-no">1834</span><span id="line-1834"> }</span>
+<span class="source-line-no">1835</span><span id="line-1835"></span>
+<span class="source-line-no">1836</span><span id="line-1836"> private WALActionsListener getWALEventTrackerListener(Configuration conf) {</span>
+<span class="source-line-no">1837</span><span id="line-1837"> if (conf.getBoolean(WAL_EVENT_TRACKER_ENABLED_KEY, WAL_EVENT_TRACKER_ENABLED_DEFAULT)) {</span>
+<span class="source-line-no">1838</span><span id="line-1838"> WALEventTrackerListener listener =</span>
+<span class="source-line-no">1839</span><span id="line-1839"> new WALEventTrackerListener(conf, getNamedQueueRecorder(), getServerName());</span>
+<span class="source-line-no">1840</span><span id="line-1840"> return listener;</span>
+<span class="source-line-no">1841</span><span id="line-1841"> }</span>
+<span class="source-line-no">1842</span><span id="line-1842"> return null;</span>
+<span class="source-line-no">1843</span><span id="line-1843"> }</span>
+<span class="source-line-no">1844</span><span id="line-1844"></span>
+<span class="source-line-no">1845</span><span id="line-1845"> /**</span>
+<span class="source-line-no">1846</span><span id="line-1846"> * Start up replication source and sink handlers.</span>
+<span class="source-line-no">1847</span><span id="line-1847"> */</span>
+<span class="source-line-no">1848</span><span id="line-1848"> private void startReplicationService() throws IOException {</span>
+<span class="source-line-no">1849</span><span id="line-1849"> if (sameReplicationSourceAndSink && this.replicationSourceHandler != null) {</span>
+<span class="source-line-no">1850</span><span id="line-1850"> this.replicationSourceHandler.startReplicationService();</span>
+<span class="source-line-no">1851</span><span id="line-1851"> } else {</span>
+<span class="source-line-no">1852</span><span id="line-1852"> if (this.replicationSourceHandler != null) {</span>
+<span class="source-line-no">1853</span><span id="line-1853"> this.replicationSourceHandler.startReplicationService();</span>
+<span class="source-line-no">1854</span><span id="line-1854"> }</span>
+<span class="source-line-no">1855</span><span id="line-1855"> if (this.replicationSinkHandler != null) {</span>
+<span class="source-line-no">1856</span><span id="line-1856"> this.replicationSinkHandler.startReplicationService();</span>
+<span class="source-line-no">1857</span><span id="line-1857"> }</span>
+<span class="source-line-no">1858</span><span id="line-1858"> }</span>
+<span class="source-line-no">1859</span><span id="line-1859"> }</span>
+<span class="source-line-no">1860</span><span id="line-1860"></span>
+<span class="source-line-no">1861</span><span id="line-1861"> /** Returns Master address tracker instance. */</span>
+<span class="source-line-no">1862</span><span id="line-1862"> public MasterAddressTracker getMasterAddressTracker() {</span>
+<span class="source-line-no">1863</span><span id="line-1863"> return this.masterAddressTracker;</span>
+<span class="source-line-no">1864</span><span id="line-1864"> }</span>
+<span class="source-line-no">1865</span><span id="line-1865"></span>
+<span class="source-line-no">1866</span><span id="line-1866"> /**</span>
+<span class="source-line-no">1867</span><span id="line-1867"> * Start maintenance Threads, Server, Worker and lease checker threads. Start all threads we need</span>
+<span class="source-line-no">1868</span><span id="line-1868"> * to run. This is called after we've successfully registered with the Master. Install an</span>
+<span class="source-line-no">1869</span><span id="line-1869"> * UncaughtExceptionHandler that calls abort of RegionServer if we get an unhandled exception. We</span>
+<span class="source-line-no">1870</span><span id="line-1870"> * cannot set the handler on all threads. Server's internal Listener thread is off limits. For</span>
+<span class="source-line-no">1871</span><span id="line-1871"> * Server, if an OOME, it waits a while then retries. Meantime, a flush or a compaction that tries</span>
+<span class="source-line-no">1872</span><span id="line-1872"> * to run should trigger same critical condition and the shutdown will run. On its way out, this</span>
+<span class="source-line-no">1873</span><span id="line-1873"> * server will shut down Server. Leases are sort of inbetween. It has an internal thread that</span>
+<span class="source-line-no">1874</span><span id="line-1874"> * while it inherits from Chore, it keeps its own internal stop mechanism so needs to be stopped</span>
+<span class="source-line-no">1875</span><span id="line-1875"> * by this hosting server. Worker logs the exception and exits.</span>
+<span class="source-line-no">1876</span><span id="line-1876"> */</span>
+<span class="source-line-no">1877</span><span id="line-1877"> private void startServices() throws IOException {</span>
+<span class="source-line-no">1878</span><span id="line-1878"> if (!isStopped() && !isAborted()) {</span>
+<span class="source-line-no">1879</span><span id="line-1879"> initializeThreads();</span>
+<span class="source-line-no">1880</span><span id="line-1880"> }</span>
+<span class="source-line-no">1881</span><span id="line-1881"> this.secureBulkLoadManager = new SecureBulkLoadManager(this.conf, asyncClusterConnection);</span>
+<span class="source-line-no">1882</span><span id="line-1882"> this.secureBulkLoadManager.start();</span>
+<span class="source-line-no">1883</span><span id="line-1883"></span>
+<span class="source-line-no">1884</span><span id="line-1884"> // Health checker thread.</span>
+<span class="source-line-no">1885</span><span id="line-1885"> if (isHealthCheckerConfigured()) {</span>
+<span class="source-line-no">1886</span><span id="line-1886"> int sleepTime = this.conf.getInt(HConstants.HEALTH_CHORE_WAKE_FREQ,</span>
+<span class="source-line-no">1887</span><span id="line-1887"> HConstants.DEFAULT_THREAD_WAKE_FREQUENCY);</span>
+<span class="source-line-no">1888</span><span id="line-1888"> healthCheckChore = new HealthCheckChore(sleepTime, this, getConfiguration());</span>
+<span class="source-line-no">1889</span><span id="line-1889"> }</span>
+<span class="source-line-no">1890</span><span id="line-1890"> // Executor status collect thread.</span>
+<span class="source-line-no">1891</span><span id="line-1891"> if (</span>
+<span class="source-line-no">1892</span><span id="line-1892"> this.conf.getBoolean(HConstants.EXECUTOR_STATUS_COLLECT_ENABLED,</span>
+<span class="source-line-no">1893</span><span id="line-1893"> HConstants.DEFAULT_EXECUTOR_STATUS_COLLECT_ENABLED)</span>
+<span class="source-line-no">1894</span><span id="line-1894"> ) {</span>
+<span class="source-line-no">1895</span><span id="line-1895"> int sleepTime =</span>
+<span class="source-line-no">1896</span><span id="line-1896"> this.conf.getInt(ExecutorStatusChore.WAKE_FREQ, ExecutorStatusChore.DEFAULT_WAKE_FREQ);</span>
+<span class="source-line-no">1897</span><span id="line-1897"> executorStatusChore = new ExecutorStatusChore(sleepTime, this, this.getExecutorService(),</span>
+<span class="source-line-no">1898</span><span id="line-1898"> this.metricsRegionServer.getMetricsSource());</span>
+<span class="source-line-no">1899</span><span id="line-1899"> }</span>
<span class="source-line-no">1900</span><span id="line-1900"></span>
-<span class="source-line-no">1901</span><span id="line-1901"> // Create the CompactedFileDischarger chore executorService. This chore helps to</span>
-<span class="source-line-no">1902</span><span id="line-1902"> // remove the compacted files that will no longer be used in reads.</span>
-<span class="source-line-no">1903</span><span id="line-1903"> // Default is 2 mins. The default value for TTLCleaner is 5 mins so we set this to</span>
-<span class="source-line-no">1904</span><span id="line-1904"> // 2 mins so that compacted files can be archived before the TTLCleaner runs</span>
-<span class="source-line-no">1905</span><span id="line-1905"> int cleanerInterval = conf.getInt("hbase.hfile.compaction.discharger.interval", 2 * 60 * 1000);</span>
-<span class="source-line-no">1906</span><span id="line-1906"> this.compactedFileDischarger = new CompactedHFilesDischarger(cleanerInterval, this, this);</span>
-<span class="source-line-no">1907</span><span id="line-1907"> choreService.scheduleChore(compactedFileDischarger);</span>
-<span class="source-line-no">1908</span><span id="line-1908"></span>
-<span class="source-line-no">1909</span><span id="line-1909"> // Start executor services</span>
-<span class="source-line-no">1910</span><span id="line-1910"> final int openRegionThreads = conf.getInt("hbase.regionserver.executor.openregion.threads", 3);</span>
-<span class="source-line-no">1911</span><span id="line-1911"> executorService.startExecutorService(executorService.new ExecutorConfig()</span>
-<span class="source-line-no">1912</span><span id="line-1912"> .setExecutorType(ExecutorType.RS_OPEN_REGION).setCorePoolSize(openRegionThreads));</span>
-<span class="source-line-no">1913</span><span id="line-1913"> final int openMetaThreads = conf.getInt("hbase.regionserver.executor.openmeta.threads", 1);</span>
-<span class="source-line-no">1914</span><span id="line-1914"> executorService.startExecutorService(executorService.new ExecutorConfig()</span>
-<span class="source-line-no">1915</span><span id="line-1915"> .setExecutorType(ExecutorType.RS_OPEN_META).setCorePoolSize(openMetaThreads));</span>
-<span class="source-line-no">1916</span><span id="line-1916"> final int openPriorityRegionThreads =</span>
-<span class="source-line-no">1917</span><span id="line-1917"> conf.getInt("hbase.regionserver.executor.openpriorityregion.threads", 3);</span>
-<span class="source-line-no">1918</span><span id="line-1918"> executorService.startExecutorService(</span>
-<span class="source-line-no">1919</span><span id="line-1919"> executorService.new ExecutorConfig().setExecutorType(ExecutorType.RS_OPEN_PRIORITY_REGION)</span>
-<span class="source-line-no">1920</span><span id="line-1920"> .setCorePoolSize(openPriorityRegionThreads));</span>
-<span class="source-line-no">1921</span><span id="line-1921"> final int closeRegionThreads =</span>
-<span class="source-line-no">1922</span><span id="line-1922"> conf.getInt("hbase.regionserver.executor.closeregion.threads", 3);</span>
-<span class="source-line-no">1923</span><span id="line-1923"> executorService.startExecutorService(executorService.new ExecutorConfig()</span>
-<span class="source-line-no">1924</span><span id="line-1924"> .setExecutorType(ExecutorType.RS_CLOSE_REGION).setCorePoolSize(closeRegionThreads));</span>
-<span class="source-line-no">1925</span><span id="line-1925"> final int closeMetaThreads = conf.getInt("hbase.regionserver.executor.closemeta.threads", 1);</span>
-<span class="source-line-no">1926</span><span id="line-1926"> executorService.startExecutorService(executorService.new ExecutorConfig()</span>
-<span class="source-line-no">1927</span><span id="line-1927"> .setExecutorType(ExecutorType.RS_CLOSE_META).setCorePoolSize(closeMetaThreads));</span>
-<span class="source-line-no">1928</span><span id="line-1928"> if (conf.getBoolean(StoreScanner.STORESCANNER_PARALLEL_SEEK_ENABLE, false)) {</span>
-<span class="source-line-no">1929</span><span id="line-1929"> final int storeScannerParallelSeekThreads =</span>
-<span class="source-line-no">1930</span><span id="line-1930"> conf.getInt("hbase.storescanner.parallel.seek.threads", 10);</span>
-<span class="source-line-no">1931</span><span id="line-1931"> executorService.startExecutorService(</span>
-<span class="source-line-no">1932</span><span id="line-1932"> executorService.new ExecutorConfig().setExecutorType(ExecutorType.RS_PARALLEL_SEEK)</span>
-<span class="source-line-no">1933</span><span id="line-1933"> .setCorePoolSize(storeScannerParallelSeekThreads).setAllowCoreThreadTimeout(true));</span>
-<span class="source-line-no">1934</span><span id="line-1934"> }</span>
-<span class="source-line-no">1935</span><span id="line-1935"> final int logReplayOpsThreads =</span>
-<span class="source-line-no">1936</span><span id="line-1936"> conf.getInt(HBASE_SPLIT_WAL_MAX_SPLITTER, DEFAULT_HBASE_SPLIT_WAL_MAX_SPLITTER);</span>
-<span class="source-line-no">1937</span><span id="line-1937"> executorService.startExecutorService(</span>
-<span class="source-line-no">1938</span><span id="line-1938"> executorService.new ExecutorConfig().setExecutorType(ExecutorType.RS_LOG_REPLAY_OPS)</span>
-<span class="source-line-no">1939</span><span id="line-1939"> .setCorePoolSize(logReplayOpsThreads).setAllowCoreThreadTimeout(true));</span>
-<span class="source-line-no">1940</span><span id="line-1940"> // Start the threads for compacted files discharger</span>
-<span class="source-line-no">1941</span><span id="line-1941"> final int compactionDischargerThreads =</span>
-<span class="source-line-no">1942</span><span id="line-1942"> conf.getInt(CompactionConfiguration.HBASE_HFILE_COMPACTION_DISCHARGER_THREAD_COUNT, 10);</span>
-<span class="source-line-no">1943</span><span id="line-1943"> executorService.startExecutorService(executorService.new ExecutorConfig()</span>
-<span class="source-line-no">1944</span><span id="line-1944"> .setExecutorType(ExecutorType.RS_COMPACTED_FILES_DISCHARGER)</span>
-<span class="source-line-no">1945</span><span id="line-1945"> .setCorePoolSize(compactionDischargerThreads));</span>
-<span class="source-line-no">1946</span><span id="line-1946"> if (ServerRegionReplicaUtil.isRegionReplicaWaitForPrimaryFlushEnabled(conf)) {</span>
-<span class="source-line-no">1947</span><span id="line-1947"> final int regionReplicaFlushThreads =</span>
-<span class="source-line-no">1948</span><span id="line-1948"> conf.getInt("hbase.regionserver.region.replica.flusher.threads",</span>
-<span class="source-line-no">1949</span><span id="line-1949"> conf.getInt("hbase.regionserver.executor.openregion.threads", 3));</span>
-<span class="source-line-no">1950</span><span id="line-1950"> executorService.startExecutorService(executorService.new ExecutorConfig()</span>
-<span class="source-line-no">1951</span><span id="line-1951"> .setExecutorType(ExecutorType.RS_REGION_REPLICA_FLUSH_OPS)</span>
-<span class="source-line-no">1952</span><span id="line-1952"> .setCorePoolSize(regionReplicaFlushThreads));</span>
-<span class="source-line-no">1953</span><span id="line-1953"> }</span>
-<span class="source-line-no">1954</span><span id="line-1954"> final int refreshPeerThreads =</span>
-<span class="source-line-no">1955</span><span id="line-1955"> conf.getInt("hbase.regionserver.executor.refresh.peer.threads", 2);</span>
-<span class="source-line-no">1956</span><span id="line-1956"> executorService.startExecutorService(executorService.new ExecutorConfig()</span>
-<span class="source-line-no">1957</span><span id="line-1957"> .setExecutorType(ExecutorType.RS_REFRESH_PEER).setCorePoolSize(refreshPeerThreads));</span>
-<span class="source-line-no">1958</span><span id="line-1958"> final int replaySyncReplicationWALThreads =</span>
-<span class="source-line-no">1959</span><span id="line-1959"> conf.getInt("hbase.regionserver.executor.replay.sync.replication.wal.threads", 1);</span>
+<span class="source-line-no">1901</span><span id="line-1901"> this.walRoller = new LogRoller(this);</span>
+<span class="source-line-no">1902</span><span id="line-1902"> this.flushThroughputController = FlushThroughputControllerFactory.create(this, conf);</span>
+<span class="source-line-no">1903</span><span id="line-1903"> this.procedureResultReporter = new RemoteProcedureResultReporter(this);</span>
+<span class="source-line-no">1904</span><span id="line-1904"></span>
+<span class="source-line-no">1905</span><span id="line-1905"> // Create the CompactedFileDischarger chore executorService. This chore helps to</span>
+<span class="source-line-no">1906</span><span id="line-1906"> // remove the compacted files that will no longer be used in reads.</span>
+<span class="source-line-no">1907</span><span id="line-1907"> // Default is 2 mins. The default value for TTLCleaner is 5 mins so we set this to</span>
+<span class="source-line-no">1908</span><span id="line-1908"> // 2 mins so that compacted files can be archived before the TTLCleaner runs</span>
+<span class="source-line-no">1909</span><span id="line-1909"> int cleanerInterval = conf.getInt("hbase.hfile.compaction.discharger.interval", 2 * 60 * 1000);</span>
+<span class="source-line-no">1910</span><span id="line-1910"> this.compactedFileDischarger = new CompactedHFilesDischarger(cleanerInterval, this, this);</span>
+<span class="source-line-no">1911</span><span id="line-1911"> choreService.scheduleChore(compactedFileDischarger);</span>
+<span class="source-line-no">1912</span><span id="line-1912"></span>
+<span class="source-line-no">1913</span><span id="line-1913"> // Start executor services</span>
+<span class="source-line-no">1914</span><span id="line-1914"> final int openRegionThreads = conf.getInt("hbase.regionserver.executor.openregion.threads", 3);</span>
+<span class="source-line-no">1915</span><span id="line-1915"> executorService.startExecutorService(executorService.new ExecutorConfig()</span>
+<span class="source-line-no">1916</span><span id="line-1916"> .setExecutorType(ExecutorType.RS_OPEN_REGION).setCorePoolSize(openRegionThreads));</span>
+<span class="source-line-no">1917</span><span id="line-1917"> final int openMetaThreads = conf.getInt("hbase.regionserver.executor.openmeta.threads", 1);</span>
+<span class="source-line-no">1918</span><span id="line-1918"> executorService.startExecutorService(executorService.new ExecutorConfig()</span>
+<span class="source-line-no">1919</span><span id="line-1919"> .setExecutorType(ExecutorType.RS_OPEN_META).setCorePoolSize(openMetaThreads));</span>
+<span class="source-line-no">1920</span><span id="line-1920"> final int openPriorityRegionThreads =</span>
+<span class="source-line-no">1921</span><span id="line-1921"> conf.getInt("hbase.regionserver.executor.openpriorityregion.threads", 3);</span>
+<span class="source-line-no">1922</span><span id="line-1922"> executorService.startExecutorService(</span>
+<span class="source-line-no">1923</span><span id="line-1923"> executorService.new ExecutorConfig().setExecutorType(ExecutorType.RS_OPEN_PRIORITY_REGION)</span>
+<span class="source-line-no">1924</span><span id="line-1924"> .setCorePoolSize(openPriorityRegionThreads));</span>
+<span class="source-line-no">1925</span><span id="line-1925"> final int closeRegionThreads =</span>
+<span class="source-line-no">1926</span><span id="line-1926"> conf.getInt("hbase.regionserver.executor.closeregion.threads", 3);</span>
+<span class="source-line-no">1927</span><span id="line-1927"> executorService.startExecutorService(executorService.new ExecutorConfig()</span>
+<span class="source-line-no">1928</span><span id="line-1928"> .setExecutorType(ExecutorType.RS_CLOSE_REGION).setCorePoolSize(closeRegionThreads));</span>
+<span class="source-line-no">1929</span><span id="line-1929"> final int closeMetaThreads = conf.getInt("hbase.regionserver.executor.closemeta.threads", 1);</span>
+<span class="source-line-no">1930</span><span id="line-1930"> executorService.startExecutorService(executorService.new ExecutorConfig()</span>
+<span class="source-line-no">1931</span><span id="line-1931"> .setExecutorType(ExecutorType.RS_CLOSE_META).setCorePoolSize(closeMetaThreads));</span>
+<span class="source-line-no">1932</span><span id="line-1932"> if (conf.getBoolean(StoreScanner.STORESCANNER_PARALLEL_SEEK_ENABLE, false)) {</span>
+<span class="source-line-no">1933</span><span id="line-1933"> final int storeScannerParallelSeekThreads =</span>
+<span class="source-line-no">1934</span><span id="line-1934"> conf.getInt("hbase.storescanner.parallel.seek.threads", 10);</span>
+<span class="source-line-no">1935</span><span id="line-1935"> executorService.startExecutorService(</span>
+<span class="source-line-no">1936</span><span id="line-1936"> executorService.new ExecutorConfig().setExecutorType(ExecutorType.RS_PARALLEL_SEEK)</span>
+<span class="source-line-no">1937</span><span id="line-1937"> .setCorePoolSize(storeScannerParallelSeekThreads).setAllowCoreThreadTimeout(true));</span>
+<span class="source-line-no">1938</span><span id="line-1938"> }</span>
+<span class="source-line-no">1939</span><span id="line-1939"> final int logReplayOpsThreads =</span>
+<span class="source-line-no">1940</span><span id="line-1940"> conf.getInt(HBASE_SPLIT_WAL_MAX_SPLITTER, DEFAULT_HBASE_SPLIT_WAL_MAX_SPLITTER);</span>
+<span class="source-line-no">1941</span><span id="line-1941"> executorService.startExecutorService(</span>
+<span class="source-line-no">1942</span><span id="line-1942"> executorService.new ExecutorConfig().setExecutorType(ExecutorType.RS_LOG_REPLAY_OPS)</span>
+<span class="source-line-no">1943</span><span id="line-1943"> .setCorePoolSize(logReplayOpsThreads).setAllowCoreThreadTimeout(true));</span>
+<span class="source-line-no">1944</span><span id="line-1944"> // Start the threads for compacted files discharger</span>
+<span class="source-line-no">1945</span><span id="line-1945"> final int compactionDischargerThreads =</span>
+<span class="source-line-no">1946</span><span id="line-1946"> conf.getInt(CompactionConfiguration.HBASE_HFILE_COMPACTION_DISCHARGER_THREAD_COUNT, 10);</span>
+<span class="source-line-no">1947</span><span id="line-1947"> executorService.startExecutorService(executorService.new ExecutorConfig()</span>
+<span class="source-line-no">1948</span><span id="line-1948"> .setExecutorType(ExecutorType.RS_COMPACTED_FILES_DISCHARGER)</span>
+<span class="source-line-no">1949</span><span id="line-1949"> .setCorePoolSize(compactionDischargerThreads));</span>
+<span class="source-line-no">1950</span><span id="line-1950"> if (ServerRegionReplicaUtil.isRegionReplicaWaitForPrimaryFlushEnabled(conf)) {</span>
+<span class="source-line-no">1951</span><span id="line-1951"> final int regionReplicaFlushThreads =</span>
+<span class="source-line-no">1952</span><span id="line-1952"> conf.getInt("hbase.regionserver.region.replica.flusher.threads",</span>
+<span class="source-line-no">1953</span><span id="line-1953"> conf.getInt("hbase.regionserver.executor.openregion.threads", 3));</span>
+<span class="source-line-no">1954</span><span id="line-1954"> executorService.startExecutorService(executorService.new ExecutorConfig()</span>
+<span class="source-line-no">1955</span><span id="line-1955"> .setExecutorType(ExecutorType.RS_REGION_REPLICA_FLUSH_OPS)</span>
+<span class="source-line-no">1956</span><span id="line-1956"> .setCorePoolSize(regionReplicaFlushThreads));</span>
+<span class="source-line-no">1957</span><span id="line-1957"> }</span>
+<span class="source-line-no">1958</span><span id="line-1958"> final int refreshPeerThreads =</span>
+<span class="source-line-no">1959</span><span id="line-1959"> conf.getInt("hbase.regionserver.executor.refresh.peer.threads", 2);</span>
<span class="source-line-no">1960</span><span id="line-1960"> executorService.startExecutorService(executorService.new ExecutorConfig()</span>
-<span class="source-line-no">1961</span><span id="line-1961"> .setExecutorType(ExecutorType.RS_REPLAY_SYNC_REPLICATION_WAL)</span>
-<span class="source-line-no">1962</span><span id="line-1962"> .setCorePoolSize(replaySyncReplicationWALThreads));</span>
-<span class="source-line-no">1963</span><span id="line-1963"> final int switchRpcThrottleThreads =</span>
-<span class="source-line-no">1964</span><span id="line-1964"> conf.getInt("hbase.regionserver.executor.switch.rpc.throttle.threads", 1);</span>
-<span class="source-line-no">1965</span><span id="line-1965"> executorService.startExecutorService(</span>
-<span class="source-line-no">1966</span><span id="line-1966"> executorService.new ExecutorConfig().setExecutorType(ExecutorType.RS_SWITCH_RPC_THROTTLE)</span>
-<span class="source-line-no">1967</span><span id="line-1967"> .setCorePoolSize(switchRpcThrottleThreads));</span>
-<span class="source-line-no">1968</span><span id="line-1968"> final int claimReplicationQueueThreads =</span>
-<span class="source-line-no">1969</span><span id="line-1969"> conf.getInt("hbase.regionserver.executor.claim.replication.queue.threads", 1);</span>
-<span class="source-line-no">1970</span><span id="line-1970"> executorService.startExecutorService(</span>
-<span class="source-line-no">1971</span><span id="line-1971"> executorService.new ExecutorConfig().setExecutorType(ExecutorType.RS_CLAIM_REPLICATION_QUEUE)</span>
-<span class="source-line-no">1972</span><span id="line-1972"> .setCorePoolSize(claimReplicationQueueThreads));</span>
-<span class="source-line-no">1973</span><span id="line-1973"> final int rsSnapshotOperationThreads =</span>
-<span class="source-line-no">1974</span><span id="line-1974"> conf.getInt("hbase.regionserver.executor.snapshot.operations.threads", 3);</span>
-<span class="source-line-no">1975</span><span id="line-1975"> executorService.startExecutorService(</span>
-<span class="source-line-no">1976</span><span id="line-1976"> executorService.new ExecutorConfig().setExecutorType(ExecutorType.RS_SNAPSHOT_OPERATIONS)</span>
-<span class="source-line-no">1977</span><span id="line-1977"> .setCorePoolSize(rsSnapshotOperationThreads));</span>
-<span class="source-line-no">1978</span><span id="line-1978"> final int rsFlushOperationThreads =</span>
-<span class="source-line-no">1979</span><span id="line-1979"> conf.getInt("hbase.regionserver.executor.flush.operations.threads", 3);</span>
-<span class="source-line-no">1980</span><span id="line-1980"> executorService.startExecutorService(executorService.new ExecutorConfig()</span>
-<span class="source-line-no">1981</span><span id="line-1981"> .setExecutorType(ExecutorType.RS_FLUSH_OPERATIONS).setCorePoolSize(rsFlushOperationThreads));</span>
-<span class="source-line-no">1982</span><span id="line-1982"> final int rsRefreshQuotasThreads =</span>
-<span class="source-line-no">1983</span><span id="line-1983"> conf.getInt("hbase.regionserver.executor.refresh.quotas.threads", 1);</span>
-<span class="source-line-no">1984</span><span id="line-1984"> executorService.startExecutorService(</span>
-<span class="source-line-no">1985</span><span id="line-1985"> executorService.new ExecutorConfig().setExecutorType(ExecutorType.RS_RELOAD_QUOTAS_OPERATIONS)</span>
-<span class="source-line-no">1986</span><span id="line-1986"> .setCorePoolSize(rsRefreshQuotasThreads));</span>
-<span class="source-line-no">1987</span><span id="line-1987"> final int logRollThreads = conf.getInt("hbase.regionserver.executor.log.roll.threads", 1);</span>
-<span class="source-line-no">1988</span><span id="line-1988"> executorService.startExecutorService(executorService.new ExecutorConfig()</span>
-<span class="source-line-no">1989</span><span id="line-1989"> .setExecutorType(ExecutorType.RS_LOG_ROLL).setCorePoolSize(logRollThreads));</span>
-<span class="source-line-no">1990</span><span id="line-1990"> final int rsRefreshHFilesThreads =</span>
-<span class="source-line-no">1991</span><span id="line-1991"> conf.getInt("hbase.regionserver.executor.refresh.hfiles.threads", 3);</span>
+<span class="source-line-no">1961</span><span id="line-1961"> .setExecutorType(ExecutorType.RS_REFRESH_PEER).setCorePoolSize(refreshPeerThreads));</span>
+<span class="source-line-no">1962</span><span id="line-1962"> final int replaySyncReplicationWALThreads =</span>
+<span class="source-line-no">1963</span><span id="line-1963"> conf.getInt("hbase.regionserver.executor.replay.sync.replication.wal.threads", 1);</span>
+<span class="source-line-no">1964</span><span id="line-1964"> executorService.startExecutorService(executorService.new ExecutorConfig()</span>
+<span class="source-line-no">1965</span><span id="line-1965"> .setExecutorType(ExecutorType.RS_REPLAY_SYNC_REPLICATION_WAL)</span>
+<span class="source-line-no">1966</span><span id="line-1966"> .setCorePoolSize(replaySyncReplicationWALThreads));</span>
+<span class="source-line-no">1967</span><span id="line-1967"> final int switchRpcThrottleThreads =</span>
+<span class="source-line-no">1968</span><span id="line-1968"> conf.getInt("hbase.regionserver.executor.switch.rpc.throttle.threads", 1);</span>
+<span class="source-line-no">1969</span><span id="line-1969"> executorService.startExecutorService(</span>
+<span class="source-line-no">1970</span><span id="line-1970"> executorService.new ExecutorConfig().setExecutorType(ExecutorType.RS_SWITCH_RPC_THROTTLE)</span>
+<span class="source-line-no">1971</span><span id="line-1971"> .setCorePoolSize(switchRpcThrottleThreads));</span>
+<span class="source-line-no">1972</span><span id="line-1972"> final int claimReplicationQueueThreads =</span>
+<span class="source-line-no">1973</span><span id="line-1973"> conf.getInt("hbase.regionserver.executor.claim.replication.queue.threads", 1);</span>
+<span class="source-line-no">1974</span><span id="line-1974"> executorService.startExecutorService(</span>
+<span class="source-line-no">1975</span><span id="line-1975"> executorService.new ExecutorConfig().setExecutorType(ExecutorType.RS_CLAIM_REPLICATION_QUEUE)</span>
+<span class="source-line-no">1976</span><span id="line-1976"> .setCorePoolSize(claimReplicationQueueThreads));</span>
+<span class="source-line-no">1977</span><span id="line-1977"> final int rsSnapshotOperationThreads =</span>
+<span class="source-line-no">1978</span><span id="line-1978"> conf.getInt("hbase.regionserver.executor.snapshot.operations.threads", 3);</span>
+<span class="source-line-no">1979</span><span id="line-1979"> executorService.startExecutorService(</span>
+<span class="source-line-no">1980</span><span id="line-1980"> executorService.new ExecutorConfig().setExecutorType(ExecutorType.RS_SNAPSHOT_OPERATIONS)</span>
+<span class="source-line-no">1981</span><span id="line-1981"> .setCorePoolSize(rsSnapshotOperationThreads));</span>
+<span class="source-line-no">1982</span><span id="line-1982"> final int rsFlushOperationThreads =</span>
+<span class="source-line-no">1983</span><span id="line-1983"> conf.getInt("hbase.regionserver.executor.flush.operations.threads", 3);</span>
+<span class="source-line-no">1984</span><span id="line-1984"> executorService.startExecutorService(executorService.new ExecutorConfig()</span>
+<span class="source-line-no">1985</span><span id="line-1985"> .setExecutorType(ExecutorType.RS_FLUSH_OPERATIONS).setCorePoolSize(rsFlushOperationThreads));</span>
+<span class="source-line-no">1986</span><span id="line-1986"> final int rsRefreshQuotasThreads =</span>
+<span class="source-line-no">1987</span><span id="line-1987"> conf.getInt("hbase.regionserver.executor.refresh.quotas.threads", 1);</span>
+<span class="source-line-no">1988</span><span id="line-1988"> executorService.startExecutorService(</span>
+<span class="source-line-no">1989</span><span id="line-1989"> executorService.new ExecutorConfig().setExecutorType(ExecutorType.RS_RELOAD_QUOTAS_OPERATIONS)</span>
+<span class="source-line-no">1990</span><span id="line-1990"> .setCorePoolSize(rsRefreshQuotasThreads));</span>
+<span class="source-line-no">1991</span><span id="line-1991"> final int logRollThreads = conf.getInt("hbase.regionserver.executor.log.roll.threads", 1);</span>
<span class="source-line-no">1992</span><span id="line-1992"> executorService.startExecutorService(executorService.new ExecutorConfig()</span>
-<span class="source-line-no">1993</span><span id="line-1993"> .setExecutorType(ExecutorType.RS_REFRESH_HFILES).setCorePoolSize(rsRefreshHFilesThreads));</span>
-<span class="source-line-no">1994</span><span id="line-1994"></span>
-<span class="source-line-no">1995</span><span id="line-1995"> Threads.setDaemonThreadRunning(this.walRoller, getName() + ".logRoller",</span>
-<span class="source-line-no">1996</span><span id="line-1996"> uncaughtExceptionHandler);</span>
-<span class="source-line-no">1997</span><span id="line-1997"> if (this.cacheFlusher != null) {</span>
-<span class="source-line-no">1998</span><span id="line-1998"> this.cacheFlusher.start(uncaughtExceptionHandler);</span>
-<span class="source-line-no">1999</span><span id="line-1999"> }</span>
-<span class="source-line-no">2000</span><span id="line-2000"> Threads.setDaemonThreadRunning(this.procedureResultReporter,</span>
-<span class="source-line-no">2001</span><span id="line-2001"> getName() + ".procedureResultReporter", uncaughtExceptionHandler);</span>
-<span class="source-line-no">2002</span><span id="line-2002"></span>
-<span class="source-line-no">2003</span><span id="line-2003"> if (this.compactionChecker != null) {</span>
-<span class="source-line-no">2004</span><span id="line-2004"> choreService.scheduleChore(compactionChecker);</span>
-<span class="source-line-no">2005</span><span id="line-2005"> }</span>
-<span class="source-line-no">2006</span><span id="line-2006"> if (this.periodicFlusher != null) {</span>
-<span class="source-line-no">2007</span><span id="line-2007"> choreService.scheduleChore(periodicFlusher);</span>
-<span class="source-line-no">2008</span><span id="line-2008"> }</span>
-<span class="source-line-no">2009</span><span id="line-2009"> if (this.healthCheckChore != null) {</span>
-<span class="source-line-no">2010</span><span id="line-2010"> choreService.scheduleChore(healthCheckChore);</span>
-<span class="source-line-no">2011</span><span id="line-2011"> }</span>
-<span class="source-line-no">2012</span><span id="line-2012"> if (this.executorStatusChore != null) {</span>
-<span class="source-line-no">2013</span><span id="line-2013"> choreService.scheduleChore(executorStatusChore);</span>
-<span class="source-line-no">2014</span><span id="line-2014"> }</span>
-<span class="source-line-no">2015</span><span id="line-2015"> if (this.nonceManagerChore != null) {</span>
-<span class="source-line-no">2016</span><span id="line-2016"> choreService.scheduleChore(nonceManagerChore);</span>
-<span class="source-line-no">2017</span><span id="line-2017"> }</span>
-<span class="source-line-no">2018</span><span id="line-2018"> if (this.storefileRefresher != null) {</span>
-<span class="source-line-no">2019</span><span id="line-2019"> choreService.scheduleChore(storefileRefresher);</span>
-<span class="source-line-no">2020</span><span id="line-2020"> }</span>
-<span class="source-line-no">2021</span><span id="line-2021"> if (this.fsUtilizationChore != null) {</span>
-<span class="source-line-no">2022</span><span id="line-2022"> choreService.scheduleChore(fsUtilizationChore);</span>
-<span class="source-line-no">2023</span><span id="line-2023"> }</span>
-<span class="source-line-no">2024</span><span id="line-2024"> if (this.namedQueueServiceChore != null) {</span>
-<span class="source-line-no">2025</span><span id="line-2025"> choreService.scheduleChore(namedQueueServiceChore);</span>
-<span class="source-line-no">2026</span><span id="line-2026"> }</span>
-<span class="source-line-no">2027</span><span id="line-2027"> if (this.brokenStoreFileCleaner != null) {</span>
-<span class="source-line-no">2028</span><span id="line-2028"> choreService.scheduleChore(brokenStoreFileCleaner);</span>
-<span class="source-line-no">2029</span><span id="line-2029"> }</span>
-<span class="source-line-no">2030</span><span id="line-2030"> if (this.rsMobFileCleanerChore != null) {</span>
-<span class="source-line-no">2031</span><span id="line-2031"> choreService.scheduleChore(rsMobFileCleanerChore);</span>
-<span class="source-line-no">2032</span><span id="line-2032"> }</span>
-<span class="source-line-no">2033</span><span id="line-2033"> if (replicationMarkerChore != null) {</span>
-<span class="source-line-no">2034</span><span id="line-2034"> LOG.info("Starting replication marker chore");</span>
-<span class="source-line-no">2035</span><span id="line-2035"> choreService.scheduleChore(replicationMarkerChore);</span>
+<span class="source-line-no">1993</span><span id="line-1993"> .setExecutorType(ExecutorType.RS_LOG_ROLL).setCorePoolSize(logRollThreads));</span>
+<span class="source-line-no">1994</span><span id="line-1994"> final int rsRefreshHFilesThreads =</span>
+<span class="source-line-no">1995</span><span id="line-1995"> conf.getInt("hbase.regionserver.executor.refresh.hfiles.threads", 3);</span>
+<span class="source-line-no">1996</span><span id="line-1996"> executorService.startExecutorService(executorService.new ExecutorConfig()</span>
+<span class="source-line-no">1997</span><span id="line-1997"> .setExecutorType(ExecutorType.RS_REFRESH_HFILES).setCorePoolSize(rsRefreshHFilesThreads));</span>
+<span class="source-line-no">1998</span><span id="line-1998"></span>
+<span class="source-line-no">1999</span><span id="line-1999"> Threads.setDaemonThreadRunning(this.walRoller, getName() + ".logRoller",</span>
+<span class="source-line-no">2000</span><span id="line-2000"> uncaughtExceptionHandler);</span>
+<span class="source-line-no">2001</span><span id="line-2001"> if (this.cacheFlusher != null) {</span>
+<span class="source-line-no">2002</span><span id="line-2002"> this.cacheFlusher.start(uncaughtExceptionHandler);</span>
+<span class="source-line-no">2003</span><span id="line-2003"> }</span>
+<span class="source-line-no">2004</span><span id="line-2004"> Threads.setDaemonThreadRunning(this.procedureResultReporter,</span>
+<span class="source-line-no">2005</span><span id="line-2005"> getName() + ".procedureResultReporter", uncaughtExceptionHandler);</span>
+<span class="source-line-no">2006</span><span id="line-2006"></span>
+<span class="source-line-no">2007</span><span id="line-2007"> if (this.compactionChecker != null) {</span>
+<span class="source-line-no">2008</span><span id="line-2008"> choreService.scheduleChore(compactionChecker);</span>
+<span class="source-line-no">2009</span><span id="line-2009"> }</span>
+<span class="source-line-no">2010</span><span id="line-2010"> if (this.periodicFlusher != null) {</span>
+<span class="source-line-no">2011</span><span id="line-2011"> choreService.scheduleChore(periodicFlusher);</span>
+<span class="source-line-no">2012</span><span id="line-2012"> }</span>
+<span class="source-line-no">2013</span><span id="line-2013"> if (this.healthCheckChore != null) {</span>
+<span class="source-line-no">2014</span><span id="line-2014"> choreService.scheduleChore(healthCheckChore);</span>
+<span class="source-line-no">2015</span><span id="line-2015"> }</span>
+<span class="source-line-no">2016</span><span id="line-2016"> if (this.executorStatusChore != null) {</span>
+<span class="source-line-no">2017</span><span id="line-2017"> choreService.scheduleChore(executorStatusChore);</span>
+<span class="source-line-no">2018</span><span id="line-2018"> }</span>
+<span class="source-line-no">2019</span><span id="line-2019"> if (this.nonceManagerChore != null) {</span>
+<span class="source-line-no">2020</span><span id="line-2020"> choreService.scheduleChore(nonceManagerChore);</span>
+<span class="source-line-no">2021</span><span id="line-2021"> }</span>
+<span class="source-line-no">2022</span><span id="line-2022"> if (this.storefileRefresher != null) {</span>
+<span class="source-line-no">2023</span><span id="line-2023"> choreService.scheduleChore(storefileRefresher);</span>
+<span class="source-line-no">2024</span><span id="line-2024"> }</span>
+<span class="source-line-no">2025</span><span id="line-2025"> if (this.fsUtilizationChore != null) {</span>
+<span class="source-line-no">2026</span><span id="line-2026"> choreService.scheduleChore(fsUtilizationChore);</span>
+<span class="source-line-no">2027</span><span id="line-2027"> }</span>
+<span class="source-line-no">2028</span><span id="line-2028"> if (this.namedQueueServiceChore != null) {</span>
+<span class="source-line-no">2029</span><span id="line-2029"> choreService.scheduleChore(namedQueueServiceChore);</span>
+<span class="source-line-no">2030</span><span id="line-2030"> }</span>
+<span class="source-line-no">2031</span><span id="line-2031"> if (this.brokenStoreFileCleaner != null) {</span>
+<span class="source-line-no">2032</span><span id="line-2032"> choreService.scheduleChore(brokenStoreFileCleaner);</span>
+<span class="source-line-no">2033</span><span id="line-2033"> }</span>
+<span class="source-line-no">2034</span><span id="line-2034"> if (this.rsMobFileCleanerChore != null) {</span>
+<span class="source-line-no">2035</span><span id="line-2035"> choreService.scheduleChore(rsMobFileCleanerChore);</span>
<span class="source-line-no">2036</span><span id="line-2036"> }</span>
-<span class="source-line-no">2037</span><span id="line-2037"></span>
-<span class="source-line-no">2038</span><span id="line-2038"> // Leases is not a Thread. Internally it runs a daemon thread. If it gets</span>
-<span class="source-line-no">2039</span><span id="line-2039"> // an unhandled exception, it will just exit.</span>
-<span class="source-line-no">2040</span><span id="line-2040"> Threads.setDaemonThreadRunning(this.leaseManager, getName() + ".leaseChecker",</span>
-<span class="source-line-no">2041</span><span id="line-2041"> uncaughtExceptionHandler);</span>
-<span class="source-line-no">2042</span><span id="line-2042"></span>
-<span class="source-line-no">2043</span><span id="line-2043"> // Create the log splitting worker and start it</span>
-<span class="source-line-no">2044</span><span id="line-2044"> // set a smaller retries to fast fail otherwise splitlogworker could be blocked for</span>
-<span class="source-line-no">2045</span><span id="line-2045"> // quite a while inside Connection layer. The worker won't be available for other</span>
-<span class="source-line-no">2046</span><span id="line-2046"> // tasks even after current task is preempted after a split task times out.</span>
-<span class="source-line-no">2047</span><span id="line-2047"> Configuration sinkConf = HBaseConfiguration.create(conf);</span>
-<span class="source-line-no">2048</span><span id="line-2048"> sinkConf.setInt(HConstants.HBASE_CLIENT_RETRIES_NUMBER,</span>
-<span class="source-line-no">2049</span><span id="line-2049"> conf.getInt("hbase.log.replay.retries.number", 8)); // 8 retries take about 23 seconds</span>
-<span class="source-line-no">2050</span><span id="line-2050"> sinkConf.setInt(HConstants.HBASE_RPC_TIMEOUT_KEY,</span>
-<span class="source-line-no">2051</span><span id="line-2051"> conf.getInt("hbase.log.replay.rpc.timeout", 30000)); // default 30 seconds</span>
-<span class="source-line-no">2052</span><span id="line-2052"> sinkConf.setInt(HConstants.HBASE_CLIENT_SERVERSIDE_RETRIES_MULTIPLIER, 1);</span>
-<span class="source-line-no">2053</span><span id="line-2053"> if (</span>
-<span class="source-line-no">2054</span><span id="line-2054"> this.csm != null</span>
-<span class="source-line-no">2055</span><span id="line-2055"> && conf.getBoolean(HBASE_SPLIT_WAL_COORDINATED_BY_ZK, DEFAULT_HBASE_SPLIT_COORDINATED_BY_ZK)</span>
-<span class="source-line-no">2056</span><span id="line-2056"> ) {</span>
-<span class="source-line-no">2057</span><span id="line-2057"> // SplitLogWorker needs csm. If none, don't start this.</span>
-<span class="source-line-no">2058</span><span id="line-2058"> this.splitLogWorker = new SplitLogWorker(sinkConf, this, this, walFactory);</span>
-<span class="source-line-no">2059</span><span id="line-2059"> splitLogWorker.start();</span>
-<span class="source-line-no">2060</span><span id="line-2060"> LOG.debug("SplitLogWorker started");</span>
-<span class="source-line-no">2061</span><span id="line-2061"> }</span>
-<span class="source-line-no">2062</span><span id="line-2062"></span>
-<span class="source-line-no">2063</span><span id="line-2063"> // Memstore services.</span>
-<span class="source-line-no">2064</span><span id="line-2064"> startHeapMemoryManager();</span>
-<span class="source-line-no">2065</span><span id="line-2065"> // Call it after starting HeapMemoryManager.</span>
-<span class="source-line-no">2066</span><span id="line-2066"> initializeMemStoreChunkCreator(hMemManager);</span>
-<span class="source-line-no">2067</span><span id="line-2067"> }</span>
-<span class="source-line-no">2068</span><span id="line-2068"></span>
-<span class="source-line-no">2069</span><span id="line-2069"> private void initializeThreads() {</span>
-<span class="source-line-no">2070</span><span id="line-2070"> // Cache flushing thread.</span>
-<span class="source-line-no">2071</span><span id="line-2071"> this.cacheFlusher = new MemStoreFlusher(conf, this);</span>
+<span class="source-line-no">2037</span><span id="line-2037"> if (replicationMarkerChore != null) {</span>
+<span class="source-line-no">2038</span><span id="line-2038"> LOG.info("Starting replication marker chore");</span>
+<span class="source-line-no">2039</span><span id="line-2039"> choreService.scheduleChore(replicationMarkerChore);</span>
+<span class="source-line-no">2040</span><span id="line-2040"> }</span>
+<span class="source-line-no">2041</span><span id="line-2041"></span>
+<span class="source-line-no">2042</span><span id="line-2042"> // Leases is not a Thread. Internally it runs a daemon thread. If it gets</span>
+<span class="source-line-no">2043</span><span id="line-2043"> // an unhandled exception, it will just exit.</span>
+<span class="source-line-no">2044</span><span id="line-2044"> Threads.setDaemonThreadRunning(this.leaseManager, getName() + ".leaseChecker",</span>
+<span class="source-line-no">2045</span><span id="line-2045"> uncaughtExceptionHandler);</span>
+<span class="source-line-no">2046</span><span id="line-2046"></span>
+<span class="source-line-no">2047</span><span id="line-2047"> // Create the log splitting worker and start it</span>
+<span class="source-line-no">2048</span><span id="line-2048"> // set a smaller retries to fast fail otherwise splitlogworker could be blocked for</span>
+<span class="source-line-no">2049</span><span id="line-2049"> // quite a while inside Connection layer. The worker won't be available for other</span>
+<span class="source-line-no">2050</span><span id="line-2050"> // tasks even after current task is preempted after a split task times out.</span>
+<span class="source-line-no">2051</span><span id="line-2051"> Configuration sinkConf = HBaseConfiguration.create(conf);</span>
+<span class="source-line-no">2052</span><span id="line-2052"> sinkConf.setInt(HConstants.HBASE_CLIENT_RETRIES_NUMBER,</span>
+<span class="source-line-no">2053</span><span id="line-2053"> conf.getInt("hbase.log.replay.retries.number", 8)); // 8 retries take about 23 seconds</span>
+<span class="source-line-no">2054</span><span id="line-2054"> sinkConf.setInt(HConstants.HBASE_RPC_TIMEOUT_KEY,</span>
+<span class="source-line-no">2055</span><span id="line-2055"> conf.getInt("hbase.log.replay.rpc.timeout", 30000)); // default 30 seconds</span>
+<span class="source-line-no">2056</span><span id="line-2056"> sinkConf.setInt(HConstants.HBASE_CLIENT_SERVERSIDE_RETRIES_MULTIPLIER, 1);</span>
+<span class="source-line-no">2057</span><span id="line-2057"> if (</span>
+<span class="source-line-no">2058</span><span id="line-2058"> this.csm != null</span>
+<span class="source-line-no">2059</span><span id="line-2059"> && conf.getBoolean(HBASE_SPLIT_WAL_COORDINATED_BY_ZK, DEFAULT_HBASE_SPLIT_COORDINATED_BY_ZK)</span>
+<span class="source-line-no">2060</span><span id="line-2060"> ) {</span>
+<span class="source-line-no">2061</span><span id="line-2061"> // SplitLogWorker needs csm. If none, don't start this.</span>
+<span class="source-line-no">2062</span><span id="line-2062"> this.splitLogWorker = new SplitLogWorker(sinkConf, this, this, walFactory);</span>
+<span class="source-line-no">2063</span><span id="line-2063"> splitLogWorker.start();</span>
+<span class="source-line-no">2064</span><span id="line-2064"> LOG.debug("SplitLogWorker started");</span>
+<span class="source-line-no">2065</span><span id="line-2065"> }</span>
+<span class="source-line-no">2066</span><span id="line-2066"></span>
+<span class="source-line-no">2067</span><span id="line-2067"> // Memstore services.</span>
+<span class="source-line-no">2068</span><span id="line-2068"> startHeapMemoryManager();</span>
+<span class="source-line-no">2069</span><span id="line-2069"> // Call it after starting HeapMemoryManager.</span>
+<span class="source-line-no">2070</span><span id="line-2070"> initializeMemStoreChunkCreator(hMemManager);</span>
+<span class="source-line-no">2071</span><span id="line-2071"> }</span>
<span class="source-line-no">2072</span><span id="line-2072"></span>
-<span class="source-line-no">2073</span><span id="line-2073"> // Compaction thread</span>
-<span class="source-line-no">2074</span><span id="line-2074"> this.compactSplitThread = new CompactSplit(this);</span>
-<span class="source-line-no">2075</span><span id="line-2075"></span>
-<span class="source-line-no">2076</span><span id="line-2076"> // Prefetch Notifier</span>
-<span class="source-line-no">2077</span><span id="line-2077"> this.prefetchExecutorNotifier = new PrefetchExecutorNotifier(conf);</span>
-<span class="source-line-no">2078</span><span id="line-2078"></span>
-<span class="source-line-no">2079</span><span id="line-2079"> // Background thread to check for compactions; needed if region has not gotten updates</span>
-<span class="source-line-no">2080</span><span id="line-2080"> // in a while. It will take care of not checking too frequently on store-by-store basis.</span>
-<span class="source-line-no">2081</span><span id="line-2081"> this.compactionChecker = new CompactionChecker(this, this.compactionCheckFrequency, this);</span>
-<span class="source-line-no">2082</span><span id="line-2082"> this.periodicFlusher = new PeriodicMemStoreFlusher(this.flushCheckFrequency, this);</span>
-<span class="source-line-no">2083</span><span id="line-2083"> this.leaseManager = new LeaseManager(this.threadWakeFrequency);</span>
-<span class="source-line-no">2084</span><span id="line-2084"></span>
-<span class="source-line-no">2085</span><span id="line-2085"> final boolean isSlowLogTableEnabled = conf.getBoolean(HConstants.SLOW_LOG_SYS_TABLE_ENABLED_KEY,</span>
-<span class="source-line-no">2086</span><span id="line-2086"> HConstants.DEFAULT_SLOW_LOG_SYS_TABLE_ENABLED_KEY);</span>
-<span class="source-line-no">2087</span><span id="line-2087"> final boolean walEventTrackerEnabled =</span>
-<span class="source-line-no">2088</span><span id="line-2088"> conf.getBoolean(WAL_EVENT_TRACKER_ENABLED_KEY, WAL_EVENT_TRACKER_ENABLED_DEFAULT);</span>
-<span class="source-line-no">2089</span><span id="line-2089"></span>
-<span class="source-line-no">2090</span><span id="line-2090"> if (isSlowLogTableEnabled || walEventTrackerEnabled) {</span>
-<span class="source-line-no">2091</span><span id="line-2091"> // default chore duration: 10 min</span>
-<span class="source-line-no">2092</span><span id="line-2092"> // After <version number>, we will remove hbase.slowlog.systable.chore.duration conf property</span>
-<span class="source-line-no">2093</span><span id="line-2093"> final int slowLogChoreDuration = conf.getInt(HConstants.SLOW_LOG_SYS_TABLE_CHORE_DURATION_KEY,</span>
-<span class="source-line-no">2094</span><span id="line-2094"> DEFAULT_SLOW_LOG_SYS_TABLE_CHORE_DURATION);</span>
-<span class="source-line-no">2095</span><span id="line-2095"></span>
-<span class="source-line-no">2096</span><span id="line-2096"> final int namedQueueChoreDuration =</span>
-<span class="source-line-no">2097</span><span id="line-2097"> conf.getInt(NAMED_QUEUE_CHORE_DURATION_KEY, NAMED_QUEUE_CHORE_DURATION_DEFAULT);</span>
-<span class="source-line-no">2098</span><span id="line-2098"> // Considering min of slowLogChoreDuration and namedQueueChoreDuration</span>
-<span class="source-line-no">2099</span><span id="line-2099"> int choreDuration = Math.min(slowLogChoreDuration, namedQueueChoreDuration);</span>
-<span class="source-line-no">2100</span><span id="line-2100"></span>
-<span class="source-line-no">2101</span><span id="line-2101"> namedQueueServiceChore = new NamedQueueServiceChore(this, choreDuration,</span>
-<span class="source-line-no">2102</span><span id="line-2102"> this.namedQueueRecorder, this.getConnection());</span>
-<span class="source-line-no">2103</span><span id="line-2103"> }</span>
+<span class="source-line-no">2073</span><span id="line-2073"> private void initializeThreads() {</span>
+<span class="source-line-no">2074</span><span id="line-2074"> // Cache flushing thread.</span>
+<span class="source-line-no">2075</span><span id="line-2075"> this.cacheFlusher = new MemStoreFlusher(conf, this);</span>
+<span class="source-line-no">2076</span><span id="line-2076"></span>
+<span class="source-line-no">2077</span><span id="line-2077"> // Compaction thread</span>
+<span class="source-line-no">2078</span><span id="line-2078"> this.compactSplitThread = new CompactSplit(this);</span>
+<span class="source-line-no">2079</span><span id="line-2079"></span>
+<span class="source-line-no">2080</span><span id="line-2080"> // Prefetch Notifier</span>
+<span class="source-line-no">2081</span><span id="line-2081"> this.prefetchExecutorNotifier = new PrefetchExecutorNotifier(conf);</span>
+<span class="source-line-no">2082</span><span id="line-2082"></span>
+<span class="source-line-no">2083</span><span id="line-2083"> // Background thread to check for compactions; needed if region has not gotten updates</span>
+<span class="source-line-no">2084</span><span id="line-2084"> // in a while. It will take care of not checking too frequently on store-by-store basis.</span>
+<span class="source-line-no">2085</span><span id="line-2085"> this.compactionChecker = new CompactionChecker(this, this.compactionCheckFrequency, this);</span>
+<span class="source-line-no">2086</span><span id="line-2086"> this.periodicFlusher = new PeriodicMemStoreFlusher(this.flushCheckFrequency, this);</span>
+<span class="source-line-no">2087</span><span id="line-2087"> this.leaseManager = new LeaseManager(this.threadWakeFrequency);</span>
+<span class="source-line-no">2088</span><span id="line-2088"></span>
+<span class="source-line-no">2089</span><span id="line-2089"> final boolean isSlowLogTableEnabled = conf.getBoolean(HConstants.SLOW_LOG_SYS_TABLE_ENABLED_KEY,</span>
+<span class="source-line-no">2090</span><span id="line-2090"> HConstants.DEFAULT_SLOW_LOG_SYS_TABLE_ENABLED_KEY);</span>
+<span class="source-line-no">2091</span><span id="line-2091"> final boolean walEventTrackerEnabled =</span>
+<span class="source-line-no">2092</span><span id="line-2092"> conf.getBoolean(WAL_EVENT_TRACKER_ENABLED_KEY, WAL_EVENT_TRACKER_ENABLED_DEFAULT);</span>
+<span class="source-line-no">2093</span><span id="line-2093"></span>
+<span class="source-line-no">2094</span><span id="line-2094"> if (isSlowLogTableEnabled || walEventTrackerEnabled) {</span>
+<span class="source-line-no">2095</span><span id="line-2095"> // default chore duration: 10 min</span>
+<span class="source-line-no">2096</span><span id="line-2096"> // After <version number>, we will remove hbase.slowlog.systable.chore.duration conf property</span>
+<span class="source-line-no">2097</span><span id="line-2097"> final int slowLogChoreDuration = conf.getInt(HConstants.SLOW_LOG_SYS_TABLE_CHORE_DURATION_KEY,</span>
+<span class="source-line-no">2098</span><span id="line-2098"> DEFAULT_SLOW_LOG_SYS_TABLE_CHORE_DURATION);</span>
+<span class="source-line-no">2099</span><span id="line-2099"></span>
+<span class="source-line-no">2100</span><span id="line-2100"> final int namedQueueChoreDuration =</span>
+<span class="source-line-no">2101</span><span id="line-2101"> conf.getInt(NAMED_QUEUE_CHORE_DURATION_KEY, NAMED_QUEUE_CHORE_DURATION_DEFAULT);</span>
+<span class="source-line-no">2102</span><span id="line-2102"> // Considering min of slowLogChoreDuration and namedQueueChoreDuration</span>
+<span class="source-line-no">2103</span><span id="line-2103"> int choreDuration = Math.min(slowLogChoreDuration, namedQueueChoreDuration);</span>
<span class="source-line-no">2104</span><span id="line-2104"></span>
-<span class="source-line-no">2105</span><span id="line-2105"> if (this.nonceManager != null) {</span>
-<span class="source-line-no">2106</span><span id="line-2106"> // Create the scheduled chore that cleans up nonces.</span>
-<span class="source-line-no">2107</span><span id="line-2107"> nonceManagerChore = this.nonceManager.createCleanupScheduledChore(this);</span>
-<span class="source-line-no">2108</span><span id="line-2108"> }</span>
-<span class="source-line-no">2109</span><span id="line-2109"></span>
-<span class="source-line-no">2110</span><span id="line-2110"> // Setup the Quota Manager</span>
-<span class="source-line-no">2111</span><span id="line-2111"> rsQuotaManager = new RegionServerRpcQuotaManager(this);</span>
-<span class="source-line-no">2112</span><span id="line-2112"> configurationManager.registerObserver(rsQuotaManager);</span>
-<span class="source-line-no">2113</span><span id="line-2113"> rsSpaceQuotaManager = new RegionServerSpaceQuotaManager(this);</span>
-<span class="source-line-no">2114</span><span id="line-2114"></span>
-<span class="source-line-no">2115</span><span id="line-2115"> if (QuotaUtil.isQuotaEnabled(conf)) {</span>
-<span class="source-line-no">2116</span><span id="line-2116"> this.fsUtilizationChore = new FileSystemUtilizationChore(this);</span>
-<span class="source-line-no">2117</span><span id="line-2117"> }</span>
+<span class="source-line-no">2105</span><span id="line-2105"> namedQueueServiceChore = new NamedQueueServiceChore(this, choreDuration,</span>
+<span class="source-line-no">2106</span><span id="line-2106"> this.namedQueueRecorder, this.getConnection());</span>
+<span class="source-line-no">2107</span><span id="line-2107"> }</span>
+<span class="source-line-no">2108</span><span id="line-2108"></span>
+<span class="source-line-no">2109</span><span id="line-2109"> if (this.nonceManager != null) {</span>
+<span class="source-line-no">2110</span><span id="line-2110"> // Create the scheduled chore that cleans up nonces.</span>
+<span class="source-line-no">2111</span><span id="line-2111"> nonceManagerChore = this.nonceManager.createCleanupScheduledChore(this);</span>
+<span class="source-line-no">2112</span><span id="line-2112"> }</span>
+<span class="source-line-no">2113</span><span id="line-2113"></span>
+<span class="source-line-no">2114</span><span id="line-2114"> // Setup the Quota Manager</span>
+<span class="source-line-no">2115</span><span id="line-2115"> rsQuotaManager = new RegionServerRpcQuotaManager(this);</span>
+<span class="source-line-no">2116</span><span id="line-2116"> configurationManager.registerObserver(rsQuotaManager);</span>
+<span class="source-line-no">2117</span><span id="line-2117"> rsSpaceQuotaManager = new RegionServerSpaceQuotaManager(this);</span>
<span class="source-line-no">2118</span><span id="line-2118"></span>
-<span class="source-line-no">2119</span><span id="line-2119"> boolean onlyMetaRefresh = false;</span>
-<span class="source-line-no">2120</span><span id="line-2120"> int storefileRefreshPeriod =</span>
-<span class="source-line-no">2121</span><span id="line-2121"> conf.getInt(StorefileRefresherChore.REGIONSERVER_STOREFILE_REFRESH_PERIOD,</span>
-<span class="source-line-no">2122</span><span id="line-2122"> StorefileRefresherChore.DEFAULT_REGIONSERVER_STOREFILE_REFRESH_PERIOD);</span>
-<span class="source-line-no">2123</span><span id="line-2123"> if (storefileRefreshPeriod == 0) {</span>
-<span class="source-line-no">2124</span><span id="line-2124"> storefileRefreshPeriod =</span>
-<span class="source-line-no">2125</span><span id="line-2125"> conf.getInt(StorefileRefresherChore.REGIONSERVER_META_STOREFILE_REFRESH_PERIOD,</span>
-<span class="source-line-no">2126</span><span id="line-2126"> StorefileRefresherChore.DEFAULT_REGIONSERVER_STOREFILE_REFRESH_PERIOD);</span>
-<span class="source-line-no">2127</span><span id="line-2127"> onlyMetaRefresh = true;</span>
-<span class="source-line-no">2128</span><span id="line-2128"> }</span>
-<span class="source-line-no">2129</span><span id="line-2129"> if (storefileRefreshPeriod > 0) {</span>
-<span class="source-line-no">2130</span><span id="line-2130"> this.storefileRefresher =</span>
-<span class="source-line-no">2131</span><span id="line-2131"> new StorefileRefresherChore(storefileRefreshPeriod, onlyMetaRefresh, this, this);</span>
+<span class="source-line-no">2119</span><span id="line-2119"> if (QuotaUtil.isQuotaEnabled(conf)) {</span>
+<span class="source-line-no">2120</span><span id="line-2120"> this.fsUtilizationChore = new FileSystemUtilizationChore(this);</span>
+<span class="source-line-no">2121</span><span id="line-2121"> }</span>
+<span class="source-line-no">2122</span><span id="line-2122"></span>
+<span class="source-line-no">2123</span><span id="line-2123"> boolean onlyMetaRefresh = false;</span>
+<span class="source-line-no">2124</span><span id="line-2124"> int storefileRefreshPeriod =</span>
+<span class="source-line-no">2125</span><span id="line-2125"> conf.getInt(StorefileRefresherChore.REGIONSERVER_STOREFILE_REFRESH_PERIOD,</span>
+<span class="source-line-no">2126</span><span id="line-2126"> StorefileRefresherChore.DEFAULT_REGIONSERVER_STOREFILE_REFRESH_PERIOD);</span>
+<span class="source-line-no">2127</span><span id="line-2127"> if (storefileRefreshPeriod == 0) {</span>
+<span class="source-line-no">2128</span><span id="line-2128"> storefileRefreshPeriod =</span>
+<span class="source-line-no">2129</span><span id="line-2129"> conf.getInt(StorefileRefresherChore.REGIONSERVER_META_STOREFILE_REFRESH_PERIOD,</span>
+<span class="source-line-no">2130</span><span id="line-2130"> StorefileRefresherChore.DEFAULT_REGIONSERVER_STOREFILE_REFRESH_PERIOD);</span>
+<span class="source-line-no">2131</span><span id="line-2131"> onlyMetaRefresh = true;</span>
<span class="source-line-no">2132</span><span id="line-2132"> }</span>
-<span class="source-line-no">2133</span><span id="line-2133"></span>
-<span class="source-line-no">2134</span><span id="line-2134"> int brokenStoreFileCleanerPeriod =</span>
-<span class="source-line-no">2135</span><span id="line-2135"> conf.getInt(BrokenStoreFileCleaner.BROKEN_STOREFILE_CLEANER_PERIOD,</span>
-<span class="source-line-no">2136</span><span id="line-2136"> BrokenStoreFileCleaner.DEFAULT_BROKEN_STOREFILE_CLEANER_PERIOD);</span>
-<span class="source-line-no">2137</span><span id="line-2137"> int brokenStoreFileCleanerDelay =</span>
-<span class="source-line-no">2138</span><span id="line-2138"> conf.getInt(BrokenStoreFileCleaner.BROKEN_STOREFILE_CLEANER_DELAY,</span>
-<span class="source-line-no">2139</span><span id="line-2139"> BrokenStoreFileCleaner.DEFAULT_BROKEN_STOREFILE_CLEANER_DELAY);</span>
-<span class="source-line-no">2140</span><span id="line-2140"> double brokenStoreFileCleanerDelayJitter =</span>
-<span class="source-line-no">2141</span><span id="line-2141"> conf.getDouble(BrokenStoreFileCleaner.BROKEN_STOREFILE_CLEANER_DELAY_JITTER,</span>
-<span class="source-line-no">2142</span><span id="line-2142"> BrokenStoreFileCleaner.DEFAULT_BROKEN_STOREFILE_CLEANER_DELAY_JITTER);</span>
-<span class="source-line-no">2143</span><span id="line-2143"> double jitterRate =</span>
-<span class="source-line-no">2144</span><span id="line-2144"> (ThreadLocalRandom.current().nextDouble() - 0.5D) * brokenStoreFileCleanerDelayJitter;</span>
-<span class="source-line-no">2145</span><span id="line-2145"> long jitterValue = Math.round(brokenStoreFileCleanerDelay * jitterRate);</span>
-<span class="source-line-no">2146</span><span id="line-2146"> this.brokenStoreFileCleaner =</span>
-<span class="source-line-no">2147</span><span id="line-2147"> new BrokenStoreFileCleaner((int) (brokenStoreFileCleanerDelay + jitterValue),</span>
-<span class="source-line-no">2148</span><span id="line-2148"> brokenStoreFileCleanerPeriod, this, conf, this);</span>
-<span class="source-line-no">2149</span><span id="line-2149"></span>
-<span class="source-line-no">2150</span><span id="line-2150"> this.rsMobFileCleanerChore = new RSMobFileCleanerChore(this);</span>
-<span class="source-line-no">2151</span><span id="line-2151"></span>
-<span class="source-line-no">2152</span><span id="line-2152"> registerConfigurationObservers();</span>
-<span class="source-line-no">2153</span><span id="line-2153"> initializeReplicationMarkerChore();</span>
-<span class="source-line-no">2154</span><span id="line-2154"> }</span>
+<span class="source-line-no">2133</span><span id="line-2133"> if (storefileRefreshPeriod > 0) {</span>
+<span class="source-line-no">2134</span><span id="line-2134"> this.storefileRefresher =</span>
+<span class="source-line-no">2135</span><span id="line-2135"> new StorefileRefresherChore(storefileRefreshPeriod, onlyMetaRefresh, this, this);</span>
+<span class="source-line-no">2136</span><span id="line-2136"> }</span>
+<span class="source-line-no">2137</span><span id="line-2137"></span>
+<span class="source-line-no">2138</span><span id="line-2138"> int brokenStoreFileCleanerPeriod =</span>
+<span class="source-line-no">2139</span><span id="line-2139"> conf.getInt(BrokenStoreFileCleaner.BROKEN_STOREFILE_CLEANER_PERIOD,</span>
+<span class="source-line-no">2140</span><span id="line-2140"> BrokenStoreFileCleaner.DEFAULT_BROKEN_STOREFILE_CLEANER_PERIOD);</span>
+<span class="source-line-no">2141</span><span id="line-2141"> int brokenStoreFileCleanerDelay =</span>
+<span class="source-line-no">2142</span><span id="line-2142"> conf.getInt(BrokenStoreFileCleaner.BROKEN_STOREFILE_CLEANER_DELAY,</span>
+<span class="source-line-no">2143</span><span id="line-2143"> BrokenStoreFileCleaner.DEFAULT_BROKEN_STOREFILE_CLEANER_DELAY);</span>
+<span class="source-line-no">2144</span><span id="line-2144"> double brokenStoreFileCleanerDelayJitter =</span>
+<span class="source-line-no">2145</span><span id="line-2145"> conf.getDouble(BrokenStoreFileCleaner.BROKEN_STOREFILE_CLEANER_DELAY_JITTER,</span>
+<span class="source-line-no">2146</span><span id="line-2146"> BrokenStoreFileCleaner.DEFAULT_BROKEN_STOREFILE_CLEANER_DELAY_JITTER);</span>
+<span class="source-line-no">2147</span><span id="line-2147"> double jitterRate =</span>
+<span class="source-line-no">2148</span><span id="line-2148"> (ThreadLocalRandom.current().nextDouble() - 0.5D) * brokenStoreFileCleanerDelayJitter;</span>
+<span class="source-line-no">2149</span><span id="line-2149"> long jitterValue = Math.round(brokenStoreFileCleanerDelay * jitterRate);</span>
+<span class="source-line-no">2150</span><span id="line-2150"> this.brokenStoreFileCleaner =</span>
+<span class="source-line-no">2151</span><span id="line-2151"> new BrokenStoreFileCleaner((int) (brokenStoreFileCleanerDelay + jitterValue),</span>
+<span class="source-line-no">2152</span><span id="line-2152"> brokenStoreFileCleanerPeriod, this, conf, this);</span>
+<span class="source-line-no">2153</span><span id="line-2153"></span>
+<span class="source-line-no">2154</span><span id="line-2154"> this.rsMobFileCleanerChore = new RSMobFileCleanerChore(this);</span>
<span class="source-line-no">2155</span><span id="line-2155"></span>
-<span class="source-line-no">2156</span><span id="line-2156"> private void registerConfigurationObservers() {</span>
-<span class="source-line-no">2157</span><span id="line-2157"> // Register Replication if possible, as now we support recreating replication peer storage, for</span>
-<span class="source-line-no">2158</span><span id="line-2158"> // migrating across different replication peer storages online</span>
-<span class="source-line-no">2159</span><span id="line-2159"> if (replicationSourceHandler instanceof ConfigurationObserver) {</span>
-<span class="source-line-no">2160</span><span id="line-2160"> configurationManager.registerObserver((ConfigurationObserver) replicationSourceHandler);</span>
-<span class="source-line-no">2161</span><span id="line-2161"> }</span>
-<span class="source-line-no">2162</span><span id="line-2162"> if (!sameReplicationSourceAndSink && replicationSinkHandler instanceof ConfigurationObserver) {</span>
-<span class="source-line-no">2163</span><span id="line-2163"> configurationManager.registerObserver((ConfigurationObserver) replicationSinkHandler);</span>
-<span class="source-line-no">2164</span><span id="line-2164"> }</span>
-<span class="source-line-no">2165</span><span id="line-2165"> // Registering the compactSplitThread object with the ConfigurationManager.</span>
-<span class="source-line-no">2166</span><span id="line-2166"> configurationManager.registerObserver(this.compactSplitThread);</span>
-<span class="source-line-no">2167</span><span id="line-2167"> configurationManager.registerObserver(this.cacheFlusher);</span>
-<span class="source-line-no">2168</span><span id="line-2168"> configurationManager.registerObserver(this.rpcServices);</span>
-<span class="source-line-no">2169</span><span id="line-2169"> configurationManager.registerObserver(this.prefetchExecutorNotifier);</span>
-<span class="source-line-no">2170</span><span id="line-2170"> configurationManager.registerObserver(this);</span>
-<span class="source-line-no">2171</span><span id="line-2171"> }</span>
-<span class="source-line-no">2172</span><span id="line-2172"></span>
-<span class="source-line-no">2173</span><span id="line-2173"> /*</span>
-<span class="source-line-no">2174</span><span id="line-2174"> * Verify that server is healthy</span>
-<span class="source-line-no">2175</span><span id="line-2175"> */</span>
-<span class="source-line-no">2176</span><span id="line-2176"> private boolean isHealthy() {</span>
-<span class="source-line-no">2177</span><span id="line-2177"> if (!dataFsOk) {</span>
-<span class="source-line-no">2178</span><span id="line-2178"> // File system problem</span>
-<span class="source-line-no">2179</span><span id="line-2179"> return false;</span>
-<span class="source-line-no">2180</span><span id="line-2180"> }</span>
-<span class="source-line-no">2181</span><span id="line-2181"> // Verify that all threads are alive</span>
-<span class="source-line-no">2182</span><span id="line-2182"> boolean healthy = (this.leaseManager == null || this.leaseManager.isAlive())</span>
-<span class="source-line-no">2183</span><span id="line-2183"> && (this.cacheFlusher == null || this.cacheFlusher.isAlive())</span>
-<span class="source-line-no">2184</span><span id="line-2184"> && (this.walRoller == null || this.walRoller.isAlive())</span>
-<span class="source-line-no">2185</span><span id="line-2185"> && (this.compactionChecker == null || this.compactionChecker.isScheduled())</span>
-<span class="source-line-no">2186</span><span id="line-2186"> && (this.periodicFlusher == null || this.periodicFlusher.isScheduled());</span>
-<span class="source-line-no">2187</span><span id="line-2187"> if (!healthy) {</span>
-<span class="source-line-no">2188</span><span id="line-2188"> stop("One or more threads are no longer alive -- stop");</span>
-<span class="source-line-no">2189</span><span id="line-2189"> }</span>
-<span class="source-line-no">2190</span><span id="line-2190"> return healthy;</span>
-<span class="source-line-no">2191</span><span id="line-2191"> }</span>
-<span class="source-line-no">2192</span><span id="line-2192"></span>
-<span class="source-line-no">2193</span><span id="line-2193"> @Override</span>
-<span class="source-line-no">2194</span><span id="line-2194"> public List<WAL> getWALs() {</span>
-<span class="source-line-no">2195</span><span id="line-2195"> return walFactory.getWALs();</span>
-<span class="source-line-no">2196</span><span id="line-2196"> }</span>
-<span class="source-line-no">2197</span><span id="line-2197"></span>
-<span class="source-line-no">2198</span><span id="line-2198"> @Override</span>
-<span class="source-line-no">2199</span><span id="line-2199"> public WAL getWAL(RegionInfo regionInfo) throws IOException {</span>
-<span class="source-line-no">2200</span><span id="line-2200"> WAL wal = walFactory.getWAL(regionInfo);</span>
-<span class="source-line-no">2201</span><span id="line-2201"> if (this.walRoller != null) {</span>
-<span class="source-line-no">2202</span><span id="line-2202"> this.walRoller.addWAL(wal);</span>
-<span class="source-line-no">2203</span><span id="line-2203"> }</span>
-<span class="source-line-no">2204</span><span id="line-2204"> return wal;</span>
-<span class="source-line-no">2205</span><span id="line-2205"> }</span>
-<span class="source-line-no">2206</span><span id="line-2206"></span>
-<span class="source-line-no">2207</span><span id="line-2207"> public LogRoller getWalRoller() {</span>
-<span class="source-line-no">2208</span><span id="line-2208"> return walRoller;</span>
+<span class="source-line-no">2156</span><span id="line-2156"> registerConfigurationObservers();</span>
+<span class="source-line-no">2157</span><span id="line-2157"> initializeReplicationMarkerChore();</span>
+<span class="source-line-no">2158</span><span id="line-2158"> }</span>
+<span class="source-line-no">2159</span><span id="line-2159"></span>
+<span class="source-line-no">2160</span><span id="line-2160"> private void registerConfigurationObservers() {</span>
+<span class="source-line-no">2161</span><span id="line-2161"> // Register Replication if possible, as now we support recreating replication peer storage, for</span>
+<span class="source-line-no">2162</span><span id="line-2162"> // migrating across different replication peer storages online</span>
+<span class="source-line-no">2163</span><span id="line-2163"> if (replicationSourceHandler instanceof ConfigurationObserver) {</span>
+<span class="source-line-no">2164</span><span id="line-2164"> configurationManager.registerObserver((ConfigurationObserver) replicationSourceHandler);</span>
+<span class="source-line-no">2165</span><span id="line-2165"> }</span>
+<span class="source-line-no">2166</span><span id="line-2166"> if (!sameReplicationSourceAndSink && replicationSinkHandler instanceof ConfigurationObserver) {</span>
+<span class="source-line-no">2167</span><span id="line-2167"> configurationManager.registerObserver((ConfigurationObserver) replicationSinkHandler);</span>
+<span class="source-line-no">2168</span><span id="line-2168"> }</span>
+<span class="source-line-no">2169</span><span id="line-2169"> // Registering the compactSplitThread object with the ConfigurationManager.</span>
+<span class="source-line-no">2170</span><span id="line-2170"> configurationManager.registerObserver(this.compactSplitThread);</span>
+<span class="source-line-no">2171</span><span id="line-2171"> configurationManager.registerObserver(this.cacheFlusher);</span>
+<span class="source-line-no">2172</span><span id="line-2172"> configurationManager.registerObserver(this.rpcServices);</span>
+<span class="source-line-no">2173</span><span id="line-2173"> configurationManager.registerObserver(this.prefetchExecutorNotifier);</span>
+<span class="source-line-no">2174</span><span id="line-2174"> configurationManager.registerObserver(this);</span>
+<span class="source-line-no">2175</span><span id="line-2175"> }</span>
+<span class="source-line-no">2176</span><span id="line-2176"></span>
+<span class="source-line-no">2177</span><span id="line-2177"> /*</span>
+<span class="source-line-no">2178</span><span id="line-2178"> * Verify that server is healthy</span>
+<span class="source-line-no">2179</span><span id="line-2179"> */</span>
+<span class="source-line-no">2180</span><span id="line-2180"> private boolean isHealthy() {</span>
+<span class="source-line-no">2181</span><span id="line-2181"> if (!dataFsOk) {</span>
+<span class="source-line-no">2182</span><span id="line-2182"> // File system problem</span>
+<span class="source-line-no">2183</span><span id="line-2183"> return false;</span>
+<span class="source-line-no">2184</span><span id="line-2184"> }</span>
+<span class="source-line-no">2185</span><span id="line-2185"> // Verify that all threads are alive</span>
+<span class="source-line-no">2186</span><span id="line-2186"> boolean healthy = (this.leaseManager == null || this.leaseManager.isAlive())</span>
+<span class="source-line-no">2187</span><span id="line-2187"> && (this.cacheFlusher == null || this.cacheFlusher.isAlive())</span>
+<span class="source-line-no">2188</span><span id="line-2188"> && (this.walRoller == null || this.walRoller.isAlive())</span>
+<span class="source-line-no">2189</span><span id="line-2189"> && (this.compactionChecker == null || this.compactionChecker.isScheduled())</span>
+<span class="source-line-no">2190</span><span id="line-2190"> && (this.periodicFlusher == null || this.periodicFlusher.isScheduled());</span>
+<span class="source-line-no">2191</span><span id="line-2191"> if (!healthy) {</span>
+<span class="source-line-no">2192</span><span id="line-2192"> stop("One or more threads are no longer alive -- stop");</span>
+<span class="source-line-no">2193</span><span id="line-2193"> }</span>
+<span class="source-line-no">2194</span><span id="line-2194"> return healthy;</span>
+<span class="source-line-no">2195</span><span id="line-2195"> }</span>
+<span class="source-line-no">2196</span><span id="line-2196"></span>
+<span class="source-line-no">2197</span><span id="line-2197"> @Override</span>
+<span class="source-line-no">2198</span><span id="line-2198"> public List<WAL> getWALs() {</span>
+<span class="source-line-no">2199</span><span id="line-2199"> return walFactory.getWALs();</span>
+<span class="source-line-no">2200</span><span id="line-2200"> }</span>
+<span class="source-line-no">2201</span><span id="line-2201"></span>
+<span class="source-line-no">2202</span><span id="line-2202"> @Override</span>
+<span class="source-line-no">2203</span><span id="line-2203"> public WAL getWAL(RegionInfo regionInfo) throws IOException {</span>
+<span class="source-line-no">2204</span><span id="line-2204"> WAL wal = walFactory.getWAL(regionInfo);</span>
+<span class="source-line-no">2205</span><span id="line-2205"> if (this.walRoller != null) {</span>
+<span class="source-line-no">2206</span><span id="line-2206"> this.walRoller.addWAL(wal);</span>
+<span class="source-line-no">2207</span><span id="line-2207"> }</span>
+<span class="source-line-no">2208</span><span id="line-2208"> return wal;</span>
<span class="source-line-no">2209</span><span id="line-2209"> }</span>
<span class="source-line-no">2210</span><span id="line-2210"></span>
-<span class="source-line-no">2211</span><span id="line-2211"> public WALFactory getWalFactory() {</span>
-<span class="source-line-no">2212</span><span id="line-2212"> return walFactory;</span>
+<span class="source-line-no">2211</span><span id="line-2211"> public LogRoller getWalRoller() {</span>
+<span class="source-line-no">2212</span><span id="line-2212"> return walRoller;</span>
<span class="source-line-no">2213</span><span id="line-2213"> }</span>
<span class="source-line-no">2214</span><span id="line-2214"></span>
-<span class="source-line-no">2215</span><span id="line-2215"> @Override</span>
-<span class="source-line-no">2216</span><span id="line-2216"> public void stop(final String msg) {</span>
-<span class="source-line-no">2217</span><span id="line-2217"> stop(msg, false, RpcServer.getRequestUser().orElse(null));</span>
-<span class="source-line-no">2218</span><span id="line-2218"> }</span>
-<span class="source-line-no">2219</span><span id="line-2219"></span>
-<span class="source-line-no">2220</span><span id="line-2220"> /**</span>
-<span class="source-line-no">2221</span><span id="line-2221"> * Stops the regionserver.</span>
-<span class="source-line-no">2222</span><span id="line-2222"> * @param msg Status message</span>
-<span class="source-line-no">2223</span><span id="line-2223"> * @param force True if this is a regionserver abort</span>
-<span class="source-line-no">2224</span><span id="line-2224"> * @param user The user executing the stop request, or null if no user is associated</span>
-<span class="source-line-no">2225</span><span id="line-2225"> */</span>
-<span class="source-line-no">2226</span><span id="line-2226"> public void stop(final String msg, final boolean force, final User user) {</span>
-<span class="source-line-no">2227</span><span id="line-2227"> if (!this.stopped) {</span>
-<span class="source-line-no">2228</span><span id="line-2228"> LOG.info("***** STOPPING region server '{}' *****", this);</span>
-<span class="source-line-no">2229</span><span id="line-2229"> if (this.rsHost != null) {</span>
-<span class="source-line-no">2230</span><span id="line-2230"> // when forced via abort don't allow CPs to override</span>
-<span class="source-line-no">2231</span><span id="line-2231"> try {</span>
-<span class="source-line-no">2232</span><span id="line-2232"> this.rsHost.preStop(msg, user);</span>
-<span class="source-line-no">2233</span><span id="line-2233"> } catch (IOException ioe) {</span>
-<span class="source-line-no">2234</span><span id="line-2234"> if (!force) {</span>
-<span class="source-line-no">2235</span><span id="line-2235"> LOG.warn("The region server did not stop", ioe);</span>
-<span class="source-line-no">2236</span><span id="line-2236"> return;</span>
-<span class="source-line-no">2237</span><span id="line-2237"> }</span>
-<span class="source-line-no">2238</span><span id="line-2238"> LOG.warn("Skipping coprocessor exception on preStop() due to forced shutdown", ioe);</span>
-<span class="source-line-no">2239</span><span id="line-2239"> }</span>
-<span class="source-line-no">2240</span><span id="line-2240"> }</span>
-<span class="source-line-no">2241</span><span id="line-2241"> this.stopped = true;</span>
-<span class="source-line-no">2242</span><span id="line-2242"> LOG.info("STOPPED: " + msg);</span>
-<span class="source-line-no">2243</span><span id="line-2243"> // Wakes run() if it is sleeping</span>
-<span class="source-line-no">2244</span><span id="line-2244"> sleeper.skipSleepCycle();</span>
-<span class="source-line-no">2245</span><span id="line-2245"> }</span>
-<span class="source-line-no">2246</span><span id="line-2246"> }</span>
-<span class="source-line-no">2247</span><span id="line-2247"></span>
-<span class="source-line-no">2248</span><span id="line-2248"> public void waitForServerOnline() {</span>
-<span class="source-line-no">2249</span><span id="line-2249"> while (!isStopped() && !isOnline()) {</span>
-<span class="source-line-no">2250</span><span id="line-2250"> synchronized (online) {</span>
-<span class="source-line-no">2251</span><span id="line-2251"> try {</span>
-<span class="source-line-no">2252</span><span id="line-2252"> online.wait(msgInterval);</span>
-<span class="source-line-no">2253</span><span id="line-2253"> } catch (InterruptedException ie) {</span>
-<span class="source-line-no">2254</span><span id="line-2254"> Thread.currentThread().interrupt();</span>
-<span class="source-line-no">2255</span><span id="line-2255"> break;</span>
-<span class="source-line-no">2256</span><span id="line-2256"> }</span>
-<span class="source-line-no">2257</span><span id="line-2257"> }</span>
-<span class="source-line-no">2258</span><span id="line-2258"> }</span>
-<span class="source-line-no">2259</span><span id="line-2259"> }</span>
-<span class="source-line-no">2260</span><span id="line-2260"></span>
-<span class="source-line-no">2261</span><span id="line-2261"> @Override</span>
-<span class="source-line-no">2262</span><span id="line-2262"> public void postOpenDeployTasks(final PostOpenDeployContext context) throws IOException {</span>
-<span class="source-line-no">2263</span><span id="line-2263"> HRegion r = context.getRegion();</span>
-<span class="source-line-no">2264</span><span id="line-2264"> long openProcId = context.getOpenProcId();</span>
-<span class="source-line-no">2265</span><span id="line-2265"> long masterSystemTime = context.getMasterSystemTime();</span>
-<span class="source-line-no">2266</span><span id="line-2266"> long initiatingMasterActiveTime = context.getInitiatingMasterActiveTime();</span>
-<span class="source-line-no">2267</span><span id="line-2267"> rpcServices.checkOpen();</span>
-<span class="source-line-no">2268</span><span id="line-2268"> LOG.info("Post open deploy tasks for {}, pid={}, masterSystemTime={}",</span>
-<span class="source-line-no">2269</span><span id="line-2269"> r.getRegionInfo().getRegionNameAsString(), openProcId, masterSystemTime);</span>
-<span class="source-line-no">2270</span><span id="line-2270"> // Do checks to see if we need to compact (references or too many files)</span>
-<span class="source-line-no">2271</span><span id="line-2271"> // Skip compaction check if region is read only</span>
-<span class="source-line-no">2272</span><span id="line-2272"> if (!r.isReadOnly()) {</span>
-<span class="source-line-no">2273</span><span id="line-2273"> for (HStore s : r.stores.values()) {</span>
-<span class="source-line-no">2274</span><span id="line-2274"> if (s.hasReferences() || s.needsCompaction()) {</span>
-<span class="source-line-no">2275</span><span id="line-2275"> this.compactSplitThread.requestSystemCompaction(r, s, "Opening Region");</span>
-<span class="source-line-no">2276</span><span id="line-2276"> }</span>
-<span class="source-line-no">2277</span><span id="line-2277"> }</span>
-<span class="source-line-no">2278</span><span id="line-2278"> }</span>
-<span class="source-line-no">2279</span><span id="line-2279"> long openSeqNum = r.getOpenSeqNum();</span>
-<span class="source-line-no">2280</span><span id="line-2280"> if (openSeqNum == HConstants.NO_SEQNUM) {</span>
-<span class="source-line-no">2281</span><span id="line-2281"> // If we opened a region, we should have read some sequence number from it.</span>
-<span class="source-line-no">2282</span><span id="line-2282"> LOG.error(</span>
-<span class="source-line-no">2283</span><span id="line-2283"> "No sequence number found when opening " + r.getRegionInfo().getRegionNameAsString());</span>
-<span class="source-line-no">2284</span><span id="line-2284"> openSeqNum = 0;</span>
-<span class="source-line-no">2285</span><span id="line-2285"> }</span>
-<span class="source-line-no">2286</span><span id="line-2286"></span>
-<span class="source-line-no">2287</span><span id="line-2287"> // Notify master</span>
-<span class="source-line-no">2288</span><span id="line-2288"> if (</span>
-<span class="source-line-no">2289</span><span id="line-2289"> !reportRegionStateTransition(new RegionStateTransitionContext(TransitionCode.OPENED,</span>
-<span class="source-line-no">2290</span><span id="line-2290"> openSeqNum, openProcId, masterSystemTime, r.getRegionInfo(), initiatingMasterActiveTime))</span>
-<span class="source-line-no">2291</span><span id="line-2291"> ) {</span>
-<span class="source-line-no">2292</span><span id="line-2292"> throw new IOException(</span>
-<span class="source-line-no">2293</span><span id="line-2293"> "Failed to report opened region to master: " + r.getRegionInfo().getRegionNameAsString());</span>
-<span class="source-line-no">2294</span><span id="line-2294"> }</span>
-<span class="source-line-no">2295</span><span id="line-2295"></span>
-<span class="source-line-no">2296</span><span id="line-2296"> triggerFlushInPrimaryRegion(r);</span>
-<span class="source-line-no">2297</span><span id="line-2297"></span>
-<span class="source-line-no">2298</span><span id="line-2298"> LOG.debug("Finished post open deploy task for " + r.getRegionInfo().getRegionNameAsString());</span>
-<span class="source-line-no">2299</span><span id="line-2299"> }</span>
-<span class="source-line-no">2300</span><span id="line-2300"></span>
-<span class="source-line-no">2301</span><span id="line-2301"> /**</span>
-<span class="source-line-no">2302</span><span id="line-2302"> * Helper method for use in tests. Skip the region transition report when there's no master around</span>
-<span class="source-line-no">2303</span><span id="line-2303"> * to receive it.</span>
-<span class="source-line-no">2304</span><span id="line-2304"> */</span>
-<span class="source-line-no">2305</span><span id="line-2305"> private boolean skipReportingTransition(final RegionStateTransitionContext context) {</span>
-<span class="source-line-no">2306</span><span id="line-2306"> final TransitionCode code = context.getCode();</span>
-<span class="source-line-no">2307</span><span id="line-2307"> final long openSeqNum = context.getOpenSeqNum();</span>
-<span class="source-line-no">2308</span><span id="line-2308"> long masterSystemTime = context.getMasterSystemTime();</span>
-<span class="source-line-no">2309</span><span id="line-2309"> final RegionInfo[] hris = context.getHris();</span>
-<span class="source-line-no">2310</span><span id="line-2310"></span>
-<span class="source-line-no">2311</span><span id="line-2311"> if (code == TransitionCode.OPENED) {</span>
-<span class="source-line-no">2312</span><span id="line-2312"> Preconditions.checkArgument(hris != null && hris.length == 1);</span>
-<span class="source-line-no">2313</span><span id="line-2313"> if (hris[0].isMetaRegion()) {</span>
-<span class="source-line-no">2314</span><span id="line-2314"> LOG.warn(</span>
-<span class="source-line-no">2315</span><span id="line-2315"> "meta table location is stored in master local store, so we can not skip reporting");</span>
-<span class="source-line-no">2316</span><span id="line-2316"> return false;</span>
-<span class="source-line-no">2317</span><span id="line-2317"> } else {</span>
-<span class="source-line-no">2318</span><span id="line-2318"> try {</span>
-<span class="source-line-no">2319</span><span id="line-2319"> MetaTableAccessor.updateRegionLocation(asyncClusterConnection.toConnection(), hris[0],</span>
-<span class="source-line-no">2320</span><span id="line-2320"> serverName, openSeqNum, masterSystemTime);</span>
-<span class="source-line-no">2321</span><span id="line-2321"> } catch (IOException e) {</span>
-<span class="source-line-no">2322</span><span id="line-2322"> LOG.info("Failed to update meta", e);</span>
-<span class="source-line-no">2323</span><span id="line-2323"> return false;</span>
-<span class="source-line-no">2324</span><span id="line-2324"> }</span>
-<span class="source-line-no">2325</span><span id="line-2325"> }</span>
-<span class="source-line-no">2326</span><span id="line-2326"> }</span>
-<span class="source-line-no">2327</span><span id="line-2327"> return true;</span>
-<span class="source-line-no">2328</span><span id="line-2328"> }</span>
-<span class="source-line-no">2329</span><span id="line-2329"></span>
-<span class="source-line-no">2330</span><span id="line-2330"> private ReportRegionStateTransitionRequest</span>
-<span class="source-line-no">2331</span><span id="line-2331"> createReportRegionStateTransitionRequest(final RegionStateTransitionContext context) {</span>
-<span class="source-line-no">2332</span><span id="line-2332"> final TransitionCode code = context.getCode();</span>
-<span class="source-line-no">2333</span><span id="line-2333"> final long openSeqNum = context.getOpenSeqNum();</span>
-<span class="source-line-no">2334</span><span id="line-2334"> final RegionInfo[] hris = context.getHris();</span>
-<span class="source-line-no">2335</span><span id="line-2335"> final long[] procIds = context.getProcIds();</span>
-<span class="source-line-no">2336</span><span id="line-2336"></span>
-<span class="source-line-no">2337</span><span id="line-2337"> ReportRegionStateTransitionRequest.Builder builder =</span>
-<span class="source-line-no">2338</span><span id="line-2338"> ReportRegionStateTransitionRequest.newBuilder();</span>
-<span class="source-line-no">2339</span><span id="line-2339"> builder.setServer(ProtobufUtil.toServerName(serverName));</span>
-<span class="source-line-no">2340</span><span id="line-2340"> RegionStateTransition.Builder transition = builder.addTransitionBuilder();</span>
-<span class="source-line-no">2341</span><span id="line-2341"> transition.setTransitionCode(code);</span>
-<span class="source-line-no">2342</span><span id="line-2342"> if (code == TransitionCode.OPENED && openSeqNum >= 0) {</span>
-<span class="source-line-no">2343</span><span id="line-2343"> transition.setOpenSeqNum(openSeqNum);</span>
-<span class="source-line-no">2344</span><span id="line-2344"> }</span>
-<span class="source-line-no">2345</span><span id="line-2345"> for (RegionInfo hri : hris) {</span>
-<span class="source-line-no">2346</span><span id="line-2346"> transition.addRegionInfo(ProtobufUtil.toRegionInfo(hri));</span>
-<span class="source-line-no">2347</span><span id="line-2347"> }</span>
-<span class="source-line-no">2348</span><span id="line-2348"> for (long procId : procIds) {</span>
-<span class="source-line-no">2349</span><span id="line-2349"> transition.addProcId(procId);</span>
-<span class="source-line-no">2350</span><span id="line-2350"> }</span>
-<span class="source-line-no">2351</span><span id="line-2351"> transition.setInitiatingMasterActiveTime(context.getInitiatingMasterActiveTime());</span>
-<span class="source-line-no">2352</span><span id="line-2352"></span>
-<span class="source-line-no">2353</span><span id="line-2353"> return builder.build();</span>
-<span class="source-line-no">2354</span><span id="line-2354"> }</span>
-<span class="source-line-no">2355</span><span id="line-2355"></span>
-<span class="source-line-no">2356</span><span id="line-2356"> @Override</span>
-<span class="source-line-no">2357</span><span id="line-2357"> public boolean reportRegionStateTransition(final RegionStateTransitionContext context) {</span>
-<span class="source-line-no">2358</span><span id="line-2358"> if (TEST_SKIP_REPORTING_TRANSITION) {</span>
-<span class="source-line-no">2359</span><span id="line-2359"> return skipReportingTransition(context);</span>
-<span class="source-line-no">2360</span><span id="line-2360"> }</span>
-<span class="source-line-no">2361</span><span id="line-2361"> final ReportRegionStateTransitionRequest request =</span>
-<span class="source-line-no">2362</span><span id="line-2362"> createReportRegionStateTransitionRequest(context);</span>
-<span class="source-line-no">2363</span><span id="line-2363"></span>
-<span class="source-line-no">2364</span><span id="line-2364"> int tries = 0;</span>
-<span class="source-line-no">2365</span><span id="line-2365"> long pauseTime = this.retryPauseTime;</span>
-<span class="source-line-no">2366</span><span id="line-2366"> // Keep looping till we get an error. We want to send reports even though server is going down.</span>
-<span class="source-line-no">2367</span><span id="line-2367"> // Only go down if clusterConnection is null. It is set to null almost as last thing as the</span>
-<span class="source-line-no">2368</span><span id="line-2368"> // HRegionServer does down.</span>
-<span class="source-line-no">2369</span><span id="line-2369"> while (this.asyncClusterConnection != null && !this.asyncClusterConnection.isClosed()) {</span>
-<span class="source-line-no">2370</span><span id="line-2370"> RegionServerStatusService.BlockingInterface rss = rssStub;</span>
-<span class="source-line-no">2371</span><span id="line-2371"> try {</span>
-<span class="source-line-no">2372</span><span id="line-2372"> if (rss == null) {</span>
-<span class="source-line-no">2373</span><span id="line-2373"> createRegionServerStatusStub();</span>
-<span class="source-line-no">2374</span><span id="line-2374"> continue;</span>
-<span class="source-line-no">2375</span><span id="line-2375"> }</span>
-<span class="source-line-no">2376</span><span id="line-2376"> ReportRegionStateTransitionResponse response =</span>
-<span class="source-line-no">2377</span><span id="line-2377"> rss.reportRegionStateTransition(null, request);</span>
-<span class="source-line-no">2378</span><span id="line-2378"> if (response.hasErrorMessage()) {</span>
-<span class="source-line-no">2379</span><span id="line-2379"> LOG.info("TRANSITION FAILED " + request + ": " + response.getErrorMessage());</span>
-<span class="source-line-no">2380</span><span id="line-2380"> break;</span>
-<span class="source-line-no">2381</span><span id="line-2381"> }</span>
-<span class="source-line-no">2382</span><span id="line-2382"> // Log if we had to retry else don't log unless TRACE. We want to</span>
-<span class="source-line-no">2383</span><span id="line-2383"> // know if were successful after an attempt showed in logs as failed.</span>
-<span class="source-line-no">2384</span><span id="line-2384"> if (tries > 0 || LOG.isTraceEnabled()) {</span>
-<span class="source-line-no">2385</span><span id="line-2385"> LOG.info("TRANSITION REPORTED " + request);</span>
-<span class="source-line-no">2386</span><span id="line-2386"> }</span>
-<span class="source-line-no">2387</span><span id="line-2387"> // NOTE: Return mid-method!!!</span>
-<span class="source-line-no">2388</span><span id="line-2388"> return true;</span>
-<span class="source-line-no">2389</span><span id="line-2389"> } catch (ServiceException se) {</span>
-<span class="source-line-no">2390</span><span id="line-2390"> IOException ioe = ProtobufUtil.getRemoteException(se);</span>
-<span class="source-line-no">2391</span><span id="line-2391"> boolean pause = ioe instanceof ServerNotRunningYetException</span>
-<span class="source-line-no">2392</span><span id="line-2392"> || ioe instanceof PleaseHoldException || ioe instanceof CallQueueTooBigException;</span>
-<span class="source-line-no">2393</span><span id="line-2393"> if (pause) {</span>
-<span class="source-line-no">2394</span><span id="line-2394"> // Do backoff else we flood the Master with requests.</span>
-<span class="source-line-no">2395</span><span id="line-2395"> pauseTime = ConnectionUtils.getPauseTime(this.retryPauseTime, tries);</span>
-<span class="source-line-no">2396</span><span id="line-2396"> } else {</span>
-<span class="source-line-no">2397</span><span id="line-2397"> pauseTime = this.retryPauseTime; // Reset.</span>
-<span class="source-line-no">2398</span><span id="line-2398"> }</span>
-<span class="source-line-no">2399</span><span id="line-2399"> LOG.info("Failed report transition " + TextFormat.shortDebugString(request) + "; retry (#"</span>
-<span class="source-line-no">2400</span><span id="line-2400"> + tries + ")"</span>
-<span class="source-line-no">2401</span><span id="line-2401"> + (pause</span>
-<span class="source-line-no">2402</span><span id="line-2402"> ? " after " + pauseTime + "ms delay (Master is coming online...)."</span>
-<span class="source-line-no">2403</span><span id="line-2403"> : " immediately."),</span>
-<span class="source-line-no">2404</span><span id="line-2404"> ioe);</span>
-<span class="source-line-no">2405</span><span id="line-2405"> if (pause) {</span>
-<span class="source-line-no">2406</span><span id="line-2406"> Threads.sleep(pauseTime);</span>
-<span class="source-line-no">2407</span><span id="line-2407"> }</span>
-<span class="source-line-no">2408</span><span id="line-2408"> tries++;</span>
-<span class="source-line-no">2409</span><span id="line-2409"> if (rssStub == rss) {</span>
-<span class="source-line-no">2410</span><span id="line-2410"> rssStub = null;</span>
+<span class="source-line-no">2215</span><span id="line-2215"> public WALFactory getWalFactory() {</span>
+<span class="source-line-no">2216</span><span id="line-2216"> return walFactory;</span>
+<span class="source-line-no">2217</span><span id="line-2217"> }</span>
+<span class="source-line-no">2218</span><span id="line-2218"></span>
+<span class="source-line-no">2219</span><span id="line-2219"> @Override</span>
+<span class="source-line-no">2220</span><span id="line-2220"> public void stop(final String msg) {</span>
+<span class="source-line-no">2221</span><span id="line-2221"> stop(msg, false, RpcServer.getRequestUser().orElse(null));</span>
+<span class="source-line-no">2222</span><span id="line-2222"> }</span>
+<span class="source-line-no">2223</span><span id="line-2223"></span>
+<span class="source-line-no">2224</span><span id="line-2224"> /**</span>
+<span class="source-line-no">2225</span><span id="line-2225"> * Stops the regionserver.</span>
+<span class="source-line-no">2226</span><span id="line-2226"> * @param msg Status message</span>
+<span class="source-line-no">2227</span><span id="line-2227"> * @param force True if this is a regionserver abort</span>
+<span class="source-line-no">2228</span><span id="line-2228"> * @param user The user executing the stop request, or null if no user is associated</span>
+<span class="source-line-no">2229</span><span id="line-2229"> */</span>
+<span class="source-line-no">2230</span><span id="line-2230"> public void stop(final String msg, final boolean force, final User user) {</span>
+<span class="source-line-no">2231</span><span id="line-2231"> if (!this.stopped) {</span>
+<span class="source-line-no">2232</span><span id="line-2232"> LOG.info("***** STOPPING region server '{}' *****", this);</span>
+<span class="source-line-no">2233</span><span id="line-2233"> if (this.rsHost != null) {</span>
+<span class="source-line-no">2234</span><span id="line-2234"> // when forced via abort don't allow CPs to override</span>
+<span class="source-line-no">2235</span><span id="line-2235"> try {</span>
+<span class="source-line-no">2236</span><span id="line-2236"> this.rsHost.preStop(msg, user);</span>
+<span class="source-line-no">2237</span><span id="line-2237"> } catch (IOException ioe) {</span>
+<span class="source-line-no">2238</span><span id="line-2238"> if (!force) {</span>
+<span class="source-line-no">2239</span><span id="line-2239"> LOG.warn("The region server did not stop", ioe);</span>
+<span class="source-line-no">2240</span><span id="line-2240"> return;</span>
+<span class="source-line-no">2241</span><span id="line-2241"> }</span>
+<span class="source-line-no">2242</span><span id="line-2242"> LOG.warn("Skipping coprocessor exception on preStop() due to forced shutdown", ioe);</span>
+<span class="source-line-no">2243</span><span id="line-2243"> }</span>
+<span class="source-line-no">2244</span><span id="line-2244"> }</span>
+<span class="source-line-no">2245</span><span id="line-2245"> this.stopped = true;</span>
+<span class="source-line-no">2246</span><span id="line-2246"> LOG.info("STOPPED: " + msg);</span>
+<span class="source-line-no">2247</span><span id="line-2247"> // Wakes run() if it is sleeping</span>
+<span class="source-line-no">2248</span><span id="line-2248"> sleeper.skipSleepCycle();</span>
+<span class="source-line-no">2249</span><span id="line-2249"> }</span>
+<span class="source-line-no">2250</span><span id="line-2250"> }</span>
+<span class="source-line-no">2251</span><span id="line-2251"></span>
+<span class="source-line-no">2252</span><span id="line-2252"> public void waitForServerOnline() {</span>
+<span class="source-line-no">2253</span><span id="line-2253"> while (!isStopped() && !isOnline()) {</span>
+<span class="source-line-no">2254</span><span id="line-2254"> synchronized (online) {</span>
+<span class="source-line-no">2255</span><span id="line-2255"> try {</span>
+<span class="source-line-no">2256</span><span id="line-2256"> online.wait(msgInterval);</span>
+<span class="source-line-no">2257</span><span id="line-2257"> } catch (InterruptedException ie) {</span>
+<span class="source-line-no">2258</span><span id="line-2258"> Thread.currentThread().interrupt();</span>
+<span class="source-line-no">2259</span><span id="line-2259"> break;</span>
+<span class="source-line-no">2260</span><span id="line-2260"> }</span>
+<span class="source-line-no">2261</span><span id="line-2261"> }</span>
+<span class="source-line-no">2262</span><span id="line-2262"> }</span>
+<span class="source-line-no">2263</span><span id="line-2263"> }</span>
+<span class="source-line-no">2264</span><span id="line-2264"></span>
+<span class="source-line-no">2265</span><span id="line-2265"> @Override</span>
+<span class="source-line-no">2266</span><span id="line-2266"> public void postOpenDeployTasks(final PostOpenDeployContext context) throws IOException {</span>
+<span class="source-line-no">2267</span><span id="line-2267"> HRegion r = context.getRegion();</span>
+<span class="source-line-no">2268</span><span id="line-2268"> long openProcId = context.getOpenProcId();</span>
+<span class="source-line-no">2269</span><span id="line-2269"> long masterSystemTime = context.getMasterSystemTime();</span>
+<span class="source-line-no">2270</span><span id="line-2270"> long initiatingMasterActiveTime = context.getInitiatingMasterActiveTime();</span>
+<span class="source-line-no">2271</span><span id="line-2271"> rpcServices.checkOpen();</span>
+<span class="source-line-no">2272</span><span id="line-2272"> LOG.info("Post open deploy tasks for {}, pid={}, masterSystemTime={}",</span>
+<span class="source-line-no">2273</span><span id="line-2273"> r.getRegionInfo().getRegionNameAsString(), openProcId, masterSystemTime);</span>
+<span class="source-line-no">2274</span><span id="line-2274"> // Do checks to see if we need to compact (references or too many files)</span>
+<span class="source-line-no">2275</span><span id="line-2275"> // Skip compaction check if region is read only</span>
+<span class="source-line-no">2276</span><span id="line-2276"> if (!r.isReadOnly()) {</span>
+<span class="source-line-no">2277</span><span id="line-2277"> for (HStore s : r.stores.values()) {</span>
+<span class="source-line-no">2278</span><span id="line-2278"> if (s.hasReferences() || s.needsCompaction()) {</span>
+<span class="source-line-no">2279</span><span id="line-2279"> this.compactSplitThread.requestSystemCompaction(r, s, "Opening Region");</span>
+<span class="source-line-no">2280</span><span id="line-2280"> }</span>
+<span class="source-line-no">2281</span><span id="line-2281"> }</span>
+<span class="source-line-no">2282</span><span id="line-2282"> }</span>
+<span class="source-line-no">2283</span><span id="line-2283"> long openSeqNum = r.getOpenSeqNum();</span>
+<span class="source-line-no">2284</span><span id="line-2284"> if (openSeqNum == HConstants.NO_SEQNUM) {</span>
+<span class="source-line-no">2285</span><span id="line-2285"> // If we opened a region, we should have read some sequence number from it.</span>
+<span class="source-line-no">2286</span><span id="line-2286"> LOG.error(</span>
+<span class="source-line-no">2287</span><span id="line-2287"> "No sequence number found when opening " + r.getRegionInfo().getRegionNameAsString());</span>
+<span class="source-line-no">2288</span><span id="line-2288"> openSeqNum = 0;</span>
+<span class="source-line-no">2289</span><span id="line-2289"> }</span>
+<span class="source-line-no">2290</span><span id="line-2290"></span>
+<span class="source-line-no">2291</span><span id="line-2291"> // Notify master</span>
+<span class="source-line-no">2292</span><span id="line-2292"> if (</span>
+<span class="source-line-no">2293</span><span id="line-2293"> !reportRegionStateTransition(new RegionStateTransitionContext(TransitionCode.OPENED,</span>
+<span class="source-line-no">2294</span><span id="line-2294"> openSeqNum, openProcId, masterSystemTime, r.getRegionInfo(), initiatingMasterActiveTime))</span>
+<span class="source-line-no">2295</span><span id="line-2295"> ) {</span>
+<span class="source-line-no">2296</span><span id="line-2296"> throw new IOException(</span>
+<span class="source-line-no">2297</span><span id="line-2297"> "Failed to report opened region to master: " + r.getRegionInfo().getRegionNameAsString());</span>
+<span class="source-line-no">2298</span><span id="line-2298"> }</span>
+<span class="source-line-no">2299</span><span id="line-2299"></span>
+<span class="source-line-no">2300</span><span id="line-2300"> triggerFlushInPrimaryRegion(r);</span>
+<span class="source-line-no">2301</span><span id="line-2301"></span>
+<span class="source-line-no">2302</span><span id="line-2302"> LOG.debug("Finished post open deploy task for " + r.getRegionInfo().getRegionNameAsString());</span>
+<span class="source-line-no">2303</span><span id="line-2303"> }</span>
+<span class="source-line-no">2304</span><span id="line-2304"></span>
+<span class="source-line-no">2305</span><span id="line-2305"> /**</span>
+<span class="source-line-no">2306</span><span id="line-2306"> * Helper method for use in tests. Skip the region transition report when there's no master around</span>
+<span class="source-line-no">2307</span><span id="line-2307"> * to receive it.</span>
+<span class="source-line-no">2308</span><span id="line-2308"> */</span>
+<span class="source-line-no">2309</span><span id="line-2309"> private boolean skipReportingTransition(final RegionStateTransitionContext context) {</span>
+<span class="source-line-no">2310</span><span id="line-2310"> final TransitionCode code = context.getCode();</span>
+<span class="source-line-no">2311</span><span id="line-2311"> final long openSeqNum = context.getOpenSeqNum();</span>
+<span class="source-line-no">2312</span><span id="line-2312"> long masterSystemTime = context.getMasterSystemTime();</span>
+<span class="source-line-no">2313</span><span id="line-2313"> final RegionInfo[] hris = context.getHris();</span>
+<span class="source-line-no">2314</span><span id="line-2314"></span>
+<span class="source-line-no">2315</span><span id="line-2315"> if (code == TransitionCode.OPENED) {</span>
+<span class="source-line-no">2316</span><span id="line-2316"> Preconditions.checkArgument(hris != null && hris.length == 1);</span>
+<span class="source-line-no">2317</span><span id="line-2317"> if (hris[0].isMetaRegion()) {</span>
+<span class="source-line-no">2318</span><span id="line-2318"> LOG.warn(</span>
+<span class="source-line-no">2319</span><span id="line-2319"> "meta table location is stored in master local store, so we can not skip reporting");</span>
+<span class="source-line-no">2320</span><span id="line-2320"> return false;</span>
+<span class="source-line-no">2321</span><span id="line-2321"> } else {</span>
+<span class="source-line-no">2322</span><span id="line-2322"> try {</span>
+<span class="source-line-no">2323</span><span id="line-2323"> MetaTableAccessor.updateRegionLocation(asyncClusterConnection.toConnection(), hris[0],</span>
+<span class="source-line-no">2324</span><span id="line-2324"> serverName, openSeqNum, masterSystemTime);</span>
+<span class="source-line-no">2325</span><span id="line-2325"> } catch (IOException e) {</span>
+<span class="source-line-no">2326</span><span id="line-2326"> LOG.info("Failed to update meta", e);</span>
+<span class="source-line-no">2327</span><span id="line-2327"> return false;</span>
+<span class="source-line-no">2328</span><span id="line-2328"> }</span>
+<span class="source-line-no">2329</span><span id="line-2329"> }</span>
+<span class="source-line-no">2330</span><span id="line-2330"> }</span>
+<span class="source-line-no">2331</span><span id="line-2331"> return true;</span>
+<span class="source-line-no">2332</span><span id="line-2332"> }</span>
+<span class="source-line-no">2333</span><span id="line-2333"></span>
+<span class="source-line-no">2334</span><span id="line-2334"> private ReportRegionStateTransitionRequest</span>
+<span class="source-line-no">2335</span><span id="line-2335"> createReportRegionStateTransitionRequest(final RegionStateTransitionContext context) {</span>
+<span class="source-line-no">2336</span><span id="line-2336"> final TransitionCode code = context.getCode();</span>
+<span class="source-line-no">2337</span><span id="line-2337"> final long openSeqNum = context.getOpenSeqNum();</span>
+<span class="source-line-no">2338</span><span id="line-2338"> final RegionInfo[] hris = context.getHris();</span>
+<span class="source-line-no">2339</span><span id="line-2339"> final long[] procIds = context.getProcIds();</span>
+<span class="source-line-no">2340</span><span id="line-2340"></span>
+<span class="source-line-no">2341</span><span id="line-2341"> ReportRegionStateTransitionRequest.Builder builder =</span>
+<span class="source-line-no">2342</span><span id="line-2342"> ReportRegionStateTransitionRequest.newBuilder();</span>
+<span class="source-line-no">2343</span><span id="line-2343"> builder.setServer(ProtobufUtil.toServerName(serverName));</span>
+<span class="source-line-no">2344</span><span id="line-2344"> RegionStateTransition.Builder transition = builder.addTransitionBuilder();</span>
+<span class="source-line-no">2345</span><span id="line-2345"> transition.setTransitionCode(code);</span>
+<span class="source-line-no">2346</span><span id="line-2346"> if (code == TransitionCode.OPENED && openSeqNum >= 0) {</span>
+<span class="source-line-no">2347</span><span id="line-2347"> transition.setOpenSeqNum(openSeqNum);</span>
+<span class="source-line-no">2348</span><span id="line-2348"> }</span>
+<span class="source-line-no">2349</span><span id="line-2349"> for (RegionInfo hri : hris) {</span>
+<span class="source-line-no">2350</span><span id="line-2350"> transition.addRegionInfo(ProtobufUtil.toRegionInfo(hri));</span>
+<span class="source-line-no">2351</span><span id="line-2351"> }</span>
+<span class="source-line-no">2352</span><span id="line-2352"> for (long procId : procIds) {</span>
+<span class="source-line-no">2353</span><span id="line-2353"> transition.addProcId(procId);</span>
+<span class="source-line-no">2354</span><span id="line-2354"> }</span>
+<span class="source-line-no">2355</span><span id="line-2355"> transition.setInitiatingMasterActiveTime(context.getInitiatingMasterActiveTime());</span>
+<span class="source-line-no">2356</span><span id="line-2356"></span>
+<span class="source-line-no">2357</span><span id="line-2357"> return builder.build();</span>
+<span class="source-line-no">2358</span><span id="line-2358"> }</span>
+<span class="source-line-no">2359</span><span id="line-2359"></span>
+<span class="source-line-no">2360</span><span id="line-2360"> @Override</span>
+<span class="source-line-no">2361</span><span id="line-2361"> public boolean reportRegionStateTransition(final RegionStateTransitionContext context) {</span>
+<span class="source-line-no">2362</span><span id="line-2362"> if (TEST_SKIP_REPORTING_TRANSITION) {</span>
+<span class="source-line-no">2363</span><span id="line-2363"> return skipReportingTransition(context);</span>
+<span class="source-line-no">2364</span><span id="line-2364"> }</span>
+<span class="source-line-no">2365</span><span id="line-2365"> final ReportRegionStateTransitionRequest request =</span>
+<span class="source-line-no">2366</span><span id="line-2366"> createReportRegionStateTransitionRequest(context);</span>
+<span class="source-line-no">2367</span><span id="line-2367"></span>
+<span class="source-line-no">2368</span><span id="line-2368"> int tries = 0;</span>
+<span class="source-line-no">2369</span><span id="line-2369"> long pauseTime = this.retryPauseTime;</span>
+<span class="source-line-no">2370</span><span id="line-2370"> // Keep looping till we get an error. We want to send reports even though server is going down.</span>
+<span class="source-line-no">2371</span><span id="line-2371"> // Only go down if clusterConnection is null. It is set to null almost as last thing as the</span>
+<span class="source-line-no">2372</span><span id="line-2372"> // HRegionServer does down.</span>
+<span class="source-line-no">2373</span><span id="line-2373"> while (this.asyncClusterConnection != null && !this.asyncClusterConnection.isClosed()) {</span>
+<span class="source-line-no">2374</span><span id="line-2374"> RegionServerStatusService.BlockingInterface rss = rssStub;</span>
+<span class="source-line-no">2375</span><span id="line-2375"> try {</span>
+<span class="source-line-no">2376</span><span id="line-2376"> if (rss == null) {</span>
+<span class="source-line-no">2377</span><span id="line-2377"> createRegionServerStatusStub();</span>
+<span class="source-line-no">2378</span><span id="line-2378"> continue;</span>
+<span class="source-line-no">2379</span><span id="line-2379"> }</span>
+<span class="source-line-no">2380</span><span id="line-2380"> ReportRegionStateTransitionResponse response =</span>
+<span class="source-line-no">2381</span><span id="line-2381"> rss.reportRegionStateTransition(null, request);</span>
+<span class="source-line-no">2382</span><span id="line-2382"> if (response.hasErrorMessage()) {</span>
+<span class="source-line-no">2383</span><span id="line-2383"> LOG.info("TRANSITION FAILED " + request + ": " + response.getErrorMessage());</span>
+<span class="source-line-no">2384</span><span id="line-2384"> break;</span>
+<span class="source-line-no">2385</span><span id="line-2385"> }</span>
+<span class="source-line-no">2386</span><span id="line-2386"> // Log if we had to retry else don't log unless TRACE. We want to</span>
+<span class="source-line-no">2387</span><span id="line-2387"> // know if were successful after an attempt showed in logs as failed.</span>
+<span class="source-line-no">2388</span><span id="line-2388"> if (tries > 0 || LOG.isTraceEnabled()) {</span>
+<span class="source-line-no">2389</span><span id="line-2389"> LOG.info("TRANSITION REPORTED " + request);</span>
+<span class="source-line-no">2390</span><span id="line-2390"> }</span>
+<span class="source-line-no">2391</span><span id="line-2391"> // NOTE: Return mid-method!!!</span>
+<span class="source-line-no">2392</span><span id="line-2392"> return true;</span>
+<span class="source-line-no">2393</span><span id="line-2393"> } catch (ServiceException se) {</span>
+<span class="source-line-no">2394</span><span id="line-2394"> IOException ioe = ProtobufUtil.getRemoteException(se);</span>
+<span class="source-line-no">2395</span><span id="line-2395"> boolean pause = ioe instanceof ServerNotRunningYetException</span>
+<span class="source-line-no">2396</span><span id="line-2396"> || ioe instanceof PleaseHoldException || ioe instanceof CallQueueTooBigException;</span>
+<span class="source-line-no">2397</span><span id="line-2397"> if (pause) {</span>
+<span class="source-line-no">2398</span><span id="line-2398"> // Do backoff else we flood the Master with requests.</span>
+<span class="source-line-no">2399</span><span id="line-2399"> pauseTime = ConnectionUtils.getPauseTime(this.retryPauseTime, tries);</span>
+<span class="source-line-no">2400</span><span id="line-2400"> } else {</span>
+<span class="source-line-no">2401</span><span id="line-2401"> pauseTime = this.retryPauseTime; // Reset.</span>
+<span class="source-line-no">2402</span><span id="line-2402"> }</span>
+<span class="source-line-no">2403</span><span id="line-2403"> LOG.info("Failed report transition " + TextFormat.shortDebugString(request) + "; retry (#"</span>
+<span class="source-line-no">2404</span><span id="line-2404"> + tries + ")"</span>
+<span class="source-line-no">2405</span><span id="line-2405"> + (pause</span>
+<span class="source-line-no">2406</span><span id="line-2406"> ? " after " + pauseTime + "ms delay (Master is coming online...)."</span>
+<span class="source-line-no">2407</span><span id="line-2407"> : " immediately."),</span>
+<span class="source-line-no">2408</span><span id="line-2408"> ioe);</span>
+<span class="source-line-no">2409</span><span id="line-2409"> if (pause) {</span>
+<span class="source-line-no">2410</span><span id="line-2410"> Threads.sleep(pauseTime);</span>
<span class="source-line-no">2411</span><span id="line-2411"> }</span>
-<span class="source-line-no">2412</span><span id="line-2412"> }</span>
-<span class="source-line-no">2413</span><span id="line-2413"> }</span>
-<span class="source-line-no">2414</span><span id="line-2414"> return false;</span>
-<span class="source-line-no">2415</span><span id="line-2415"> }</span>
-<span class="source-line-no">2416</span><span id="line-2416"></span>
-<span class="source-line-no">2417</span><span id="line-2417"> /**</span>
-<span class="source-line-no">2418</span><span id="line-2418"> * Trigger a flush in the primary region replica if this region is a secondary replica. Does not</span>
-<span class="source-line-no">2419</span><span id="line-2419"> * block this thread. See RegionReplicaFlushHandler for details.</span>
-<span class="source-line-no">2420</span><span id="line-2420"> */</span>
-<span class="source-line-no">2421</span><span id="line-2421"> private void triggerFlushInPrimaryRegion(final HRegion region) {</span>
-<span class="source-line-no">2422</span><span id="line-2422"> if (ServerRegionReplicaUtil.isDefaultReplica(region.getRegionInfo())) {</span>
-<span class="source-line-no">2423</span><span id="line-2423"> return;</span>
-<span class="source-line-no">2424</span><span id="line-2424"> }</span>
-<span class="source-line-no">2425</span><span id="line-2425"> TableName tn = region.getTableDescriptor().getTableName();</span>
-<span class="source-line-no">2426</span><span id="line-2426"> if (</span>
-<span class="source-line-no">2427</span><span id="line-2427"> !ServerRegionReplicaUtil.isRegionReplicaReplicationEnabled(region.conf, tn)</span>
-<span class="source-line-no">2428</span><span id="line-2428"> || !ServerRegionReplicaUtil.isRegionReplicaWaitForPrimaryFlushEnabled(region.conf) ||</span>
-<span class="source-line-no">2429</span><span id="line-2429"> // If the memstore replication not setup, we do not have to wait for observing a flush event</span>
-<span class="source-line-no">2430</span><span id="line-2430"> // from primary before starting to serve reads, because gaps from replication is not</span>
-<span class="source-line-no">2431</span><span id="line-2431"> // applicable,this logic is from</span>
-<span class="source-line-no">2432</span><span id="line-2432"> // TableDescriptorBuilder.ModifyableTableDescriptor.setRegionMemStoreReplication by</span>
-<span class="source-line-no">2433</span><span id="line-2433"> // HBASE-13063</span>
-<span class="source-line-no">2434</span><span id="line-2434"> !region.getTableDescriptor().hasRegionMemStoreReplication()</span>
-<span class="source-line-no">2435</span><span id="line-2435"> ) {</span>
-<span class="source-line-no">2436</span><span id="line-2436"> region.setReadsEnabled(true);</span>
-<span class="source-line-no">2437</span><span id="line-2437"> return;</span>
-<span class="source-line-no">2438</span><span id="line-2438"> }</span>
-<span class="source-line-no">2439</span><span id="line-2439"></span>
-<span class="source-line-no">2440</span><span id="line-2440"> region.setReadsEnabled(false); // disable reads before marking the region as opened.</span>
-<span class="source-line-no">2441</span><span id="line-2441"> // RegionReplicaFlushHandler might reset this.</span>
-<span class="source-line-no">2442</span><span id="line-2442"></span>
-<span class="source-line-no">2443</span><span id="line-2443"> // Submit it to be handled by one of the handlers so that we do not block OpenRegionHandler</span>
-<span class="source-line-no">2444</span><span id="line-2444"> if (this.executorService != null) {</span>
-<span class="source-line-no">2445</span><span id="line-2445"> this.executorService.submit(new RegionReplicaFlushHandler(this, region));</span>
-<span class="source-line-no">2446</span><span id="line-2446"> } else {</span>
-<span class="source-line-no">2447</span><span id="line-2447"> LOG.info("Executor is null; not running flush of primary region replica for {}",</span>
-<span class="source-line-no">2448</span><span id="line-2448"> region.getRegionInfo());</span>
-<span class="source-line-no">2449</span><span id="line-2449"> }</span>
-<span class="source-line-no">2450</span><span id="line-2450"> }</span>
-<span class="source-line-no">2451</span><span id="line-2451"></span>
-<span class="source-line-no">2452</span><span id="line-2452"> @InterfaceAudience.Private</span>
-<span class="source-line-no">2453</span><span id="line-2453"> public RSRpcServices getRSRpcServices() {</span>
-<span class="source-line-no">2454</span><span id="line-2454"> return rpcServices;</span>
-<span class="source-line-no">2455</span><span id="line-2455"> }</span>
-<span class="source-line-no">2456</span><span id="line-2456"></span>
-<span class="source-line-no">2457</span><span id="line-2457"> /**</span>
-<span class="source-line-no">2458</span><span id="line-2458"> * Cause the server to exit without closing the regions it is serving, the log it is using and</span>
-<span class="source-line-no">2459</span><span id="line-2459"> * without notifying the master. Used unit testing and on catastrophic events such as HDFS is</span>
-<span class="source-line-no">2460</span><span id="line-2460"> * yanked out from under hbase or we OOME. the reason we are aborting the exception that caused</span>
-<span class="source-line-no">2461</span><span id="line-2461"> * the abort, or null</span>
-<span class="source-line-no">2462</span><span id="line-2462"> */</span>
-<span class="source-line-no">2463</span><span id="line-2463"> @Override</span>
-<span class="source-line-no">2464</span><span id="line-2464"> public void abort(String reason, Throwable cause) {</span>
-<span class="source-line-no">2465</span><span id="line-2465"> if (!setAbortRequested()) {</span>
-<span class="source-line-no">2466</span><span id="line-2466"> // Abort already in progress, ignore the new request.</span>
-<span class="source-line-no">2467</span><span id="line-2467"> LOG.debug("Abort already in progress. Ignoring the current request with reason: {}", reason);</span>
-<span class="source-line-no">2468</span><span id="line-2468"> return;</span>
-<span class="source-line-no">2469</span><span id="line-2469"> }</span>
-<span class="source-line-no">2470</span><span id="line-2470"> String msg = "***** ABORTING region server " + this + ": " + reason + " *****";</span>
-<span class="source-line-no">2471</span><span id="line-2471"> if (cause != null) {</span>
-<span class="source-line-no">2472</span><span id="line-2472"> LOG.error(HBaseMarkers.FATAL, msg, cause);</span>
-<span class="source-line-no">2473</span><span id="line-2473"> } else {</span>
-<span class="source-line-no">2474</span><span id="line-2474"> LOG.error(HBaseMarkers.FATAL, msg);</span>
-<span class="source-line-no">2475</span><span id="line-2475"> }</span>
-<span class="source-line-no">2476</span><span id="line-2476"> // HBASE-4014: show list of coprocessors that were loaded to help debug</span>
-<span class="source-line-no">2477</span><span id="line-2477"> // regionserver crashes.Note that we're implicitly using</span>
-<span class="source-line-no">2478</span><span id="line-2478"> // java.util.HashSet's toString() method to print the coprocessor names.</span>
-<span class="source-line-no">2479</span><span id="line-2479"> LOG.error(HBaseMarkers.FATAL,</span>
-<span class="source-line-no">2480</span><span id="line-2480"> "RegionServer abort: loaded coprocessors are: " + CoprocessorHost.getLoadedCoprocessors());</span>
-<span class="source-line-no">2481</span><span id="line-2481"> // Try and dump metrics if abort -- might give clue as to how fatal came about....</span>
-<span class="source-line-no">2482</span><span id="line-2482"> try {</span>
-<span class="source-line-no">2483</span><span id="line-2483"> LOG.info("Dump of metrics as JSON on abort: " + DumpRegionServerMetrics.dumpMetrics());</span>
-<span class="source-line-no">2484</span><span id="line-2484"> } catch (MalformedObjectNameException | IOException e) {</span>
-<span class="source-line-no">2485</span><span id="line-2485"> LOG.warn("Failed dumping metrics", e);</span>
-<span class="source-line-no">2486</span><span id="line-2486"> }</span>
-<span class="source-line-no">2487</span><span id="line-2487"></span>
-<span class="source-line-no">2488</span><span id="line-2488"> // Do our best to report our abort to the master, but this may not work</span>
-<span class="source-line-no">2489</span><span id="line-2489"> try {</span>
-<span class="source-line-no">2490</span><span id="line-2490"> if (cause != null) {</span>
-<span class="source-line-no">2491</span><span id="line-2491"> msg += "\nCause:\n" + Throwables.getStackTraceAsString(cause);</span>
-<span class="source-line-no">2492</span><span id="line-2492"> }</span>
-<span class="source-line-no">2493</span><span id="line-2493"> // Report to the master but only if we have already registered with the master.</span>
-<span class="source-line-no">2494</span><span id="line-2494"> RegionServerStatusService.BlockingInterface rss = rssStub;</span>
-<span class="source-line-no">2495</span><span id="line-2495"> if (rss != null && this.serverName != null) {</span>
-<span class="source-line-no">2496</span><span id="line-2496"> ReportRSFatalErrorRequest.Builder builder = ReportRSFatalErrorRequest.newBuilder();</span>
-<span class="source-line-no">2497</span><span id="line-2497"> builder.setServer(ProtobufUtil.toServerName(this.serverName));</span>
-<span class="source-line-no">2498</span><span id="line-2498"> builder.setErrorMessage(msg);</span>
-<span class="source-line-no">2499</span><span id="line-2499"> rss.reportRSFatalError(null, builder.build());</span>
-<span class="source-line-no">2500</span><span id="line-2500"> }</span>
-<span class="source-line-no">2501</span><span id="line-2501"> } catch (Throwable t) {</span>
-<span class="source-line-no">2502</span><span id="line-2502"> LOG.warn("Unable to report fatal error to master", t);</span>
-<span class="source-line-no">2503</span><span id="line-2503"> }</span>
-<span class="source-line-no">2504</span><span id="line-2504"></span>
-<span class="source-line-no">2505</span><span id="line-2505"> scheduleAbortTimer();</span>
-<span class="source-line-no">2506</span><span id="line-2506"> // shutdown should be run as the internal user</span>
-<span class="source-line-no">2507</span><span id="line-2507"> stop(reason, true, null);</span>
-<span class="source-line-no">2508</span><span id="line-2508"> }</span>
-<span class="source-line-no">2509</span><span id="line-2509"></span>
-<span class="source-line-no">2510</span><span id="line-2510"> /*</span>
-<span class="source-line-no">2511</span><span id="line-2511"> * Simulate a kill -9 of this server. Exits w/o closing regions or cleaninup logs but it does</span>
-<span class="source-line-no">2512</span><span id="line-2512"> * close socket in case want to bring up server on old hostname+port immediately.</span>
-<span class="source-line-no">2513</span><span id="line-2513"> */</span>
-<span class="source-line-no">2514</span><span id="line-2514"> @InterfaceAudience.Private</span>
-<span class="source-line-no">2515</span><span id="line-2515"> protected void kill() {</span>
-<span class="source-line-no">2516</span><span id="line-2516"> this.killed = true;</span>
-<span class="source-line-no">2517</span><span id="line-2517"> abort("Simulated kill");</span>
-<span class="source-line-no">2518</span><span id="line-2518"> }</span>
-<span class="source-line-no">2519</span><span id="line-2519"></span>
-<span class="source-line-no">2520</span><span id="line-2520"> // Limits the time spent in the shutdown process.</span>
-<span class="source-line-no">2521</span><span id="line-2521"> private void scheduleAbortTimer() {</span>
-<span class="source-line-no">2522</span><span id="line-2522"> if (this.abortMonitor == null) {</span>
-<span class="source-line-no">2523</span><span id="line-2523"> this.abortMonitor = new Timer("Abort regionserver monitor", true);</span>
-<span class="source-line-no">2524</span><span id="line-2524"> TimerTask abortTimeoutTask = null;</span>
-<span class="source-line-no">2525</span><span id="line-2525"> try {</span>
-<span class="source-line-no">2526</span><span id="line-2526"> Constructor<? extends TimerTask> timerTaskCtor =</span>
-<span class="source-line-no">2527</span><span id="line-2527"> Class.forName(conf.get(ABORT_TIMEOUT_TASK, SystemExitWhenAbortTimeout.class.getName()))</span>
-<span class="source-line-no">2528</span><span id="line-2528"> .asSubclass(TimerTask.class).getDeclaredConstructor();</span>
-<span class="source-line-no">2529</span><span id="line-2529"> timerTaskCtor.setAccessible(true);</span>
-<span class="source-line-no">2530</span><span id="line-2530"> abortTimeoutTask = timerTaskCtor.newInstance();</span>
-<span class="source-line-no">2531</span><span id="line-2531"> } catch (Exception e) {</span>
-<span class="source-line-no">2532</span><span id="line-2532"> LOG.warn("Initialize abort timeout task failed", e);</span>
-<span class="source-line-no">2533</span><span id="line-2533"> }</span>
-<span class="source-line-no">2534</span><span id="line-2534"> if (abortTimeoutTask != null) {</span>
-<span class="source-line-no">2535</span><span id="line-2535"> abortMonitor.schedule(abortTimeoutTask, conf.getLong(ABORT_TIMEOUT, DEFAULT_ABORT_TIMEOUT));</span>
-<span class="source-line-no">2536</span><span id="line-2536"> }</span>
-<span class="source-line-no">2537</span><span id="line-2537"> }</span>
-<span class="source-line-no">2538</span><span id="line-2538"> }</span>
-<span class="source-line-no">2539</span><span id="line-2539"></span>
-<span class="source-line-no">2540</span><span id="line-2540"> /**</span>
-<span class="source-line-no">2541</span><span id="line-2541"> * Wait on all threads to finish. Presumption is that all closes and stops have already been</span>
-<span class="source-line-no">2542</span><span id="line-2542"> * called.</span>
-<span class="source-line-no">2543</span><span id="line-2543"> */</span>
-<span class="source-line-no">2544</span><span id="line-2544"> protected void stopServiceThreads() {</span>
-<span class="source-line-no">2545</span><span id="line-2545"> // clean up the scheduled chores</span>
-<span class="source-line-no">2546</span><span id="line-2546"> stopChoreService();</span>
-<span class="source-line-no">2547</span><span id="line-2547"> if (bootstrapNodeManager != null) {</span>
-<span class="source-line-no">2548</span><span id="line-2548"> bootstrapNodeManager.stop();</span>
-<span class="source-line-no">2549</span><span id="line-2549"> }</span>
-<span class="source-line-no">2550</span><span id="line-2550"> if (this.cacheFlusher != null) {</span>
-<span class="source-line-no">2551</span><span id="line-2551"> this.cacheFlusher.shutdown();</span>
-<span class="source-line-no">2552</span><span id="line-2552"> }</span>
-<span class="source-line-no">2553</span><span id="line-2553"> if (this.walRoller != null) {</span>
-<span class="source-line-no">2554</span><span id="line-2554"> this.walRoller.close();</span>
-<span class="source-line-no">2555</span><span id="line-2555"> }</span>
-<span class="source-line-no">2556</span><span id="line-2556"> if (this.compactSplitThread != null) {</span>
-<span class="source-line-no">2557</span><span id="line-2557"> this.compactSplitThread.join();</span>
-<span class="source-line-no">2558</span><span id="line-2558"> }</span>
-<span class="source-line-no">2559</span><span id="line-2559"> stopExecutorService();</span>
-<span class="source-line-no">2560</span><span id="line-2560"> if (sameReplicationSourceAndSink && this.replicationSourceHandler != null) {</span>
-<span class="source-line-no">2561</span><span id="line-2561"> this.replicationSourceHandler.stopReplicationService();</span>
-<span class="source-line-no">2562</span><span id="line-2562"> } else {</span>
-<span class="source-line-no">2563</span><span id="line-2563"> if (this.replicationSourceHandler != null) {</span>
-<span class="source-line-no">2564</span><span id="line-2564"> this.replicationSourceHandler.stopReplicationService();</span>
-<span class="source-line-no">2565</span><span id="line-2565"> }</span>
-<span class="source-line-no">2566</span><span id="line-2566"> if (this.replicationSinkHandler != null) {</span>
-<span class="source-line-no">2567</span><span id="line-2567"> this.replicationSinkHandler.stopReplicationService();</span>
-<span class="source-line-no">2568</span><span id="line-2568"> }</span>
-<span class="source-line-no">2569</span><span id="line-2569"> }</span>
-<span class="source-line-no">2570</span><span id="line-2570"> }</span>
-<span class="source-line-no">2571</span><span id="line-2571"></span>
-<span class="source-line-no">2572</span><span id="line-2572"> /** Returns Return the object that implements the replication source executorService. */</span>
-<span class="source-line-no">2573</span><span id="line-2573"> @Override</span>
-<span class="source-line-no">2574</span><span id="line-2574"> public ReplicationSourceService getReplicationSourceService() {</span>
-<span class="source-line-no">2575</span><span id="line-2575"> return replicationSourceHandler;</span>
-<span class="source-line-no">2576</span><span id="line-2576"> }</span>
-<span class="source-line-no">2577</span><span id="line-2577"></span>
-<span class="source-line-no">2578</span><span id="line-2578"> /** Returns Return the object that implements the replication sink executorService. */</span>
-<span class="source-line-no">2579</span><span id="line-2579"> public ReplicationSinkService getReplicationSinkService() {</span>
-<span class="source-line-no">2580</span><span id="line-2580"> return replicationSinkHandler;</span>
-<span class="source-line-no">2581</span><span id="line-2581"> }</span>
-<span class="source-line-no">2582</span><span id="line-2582"></span>
-<span class="source-line-no">2583</span><span id="line-2583"> /**</span>
-<span class="source-line-no">2584</span><span id="line-2584"> * Get the current master from ZooKeeper and open the RPC connection to it. To get a fresh</span>
-<span class="source-line-no">2585</span><span id="line-2585"> * connection, the current rssStub must be null. Method will block until a master is available.</span>
-<span class="source-line-no">2586</span><span id="line-2586"> * You can break from this block by requesting the server stop.</span>
-<span class="source-line-no">2587</span><span id="line-2587"> * @return master + port, or null if server has been stopped</span>
-<span class="source-line-no">2588</span><span id="line-2588"> */</span>
-<span class="source-line-no">2589</span><span id="line-2589"> private synchronized ServerName createRegionServerStatusStub() {</span>
-<span class="source-line-no">2590</span><span id="line-2590"> // Create RS stub without refreshing the master node from ZK, use cached data</span>
-<span class="source-line-no">2591</span><span id="line-2591"> return createRegionServerStatusStub(false);</span>
-<span class="source-line-no">2592</span><span id="line-2592"> }</span>
-<span class="source-line-no">2593</span><span id="line-2593"></span>
-<span class="source-line-no">2594</span><span id="line-2594"> /**</span>
-<span class="source-line-no">2595</span><span id="line-2595"> * Get the current master from ZooKeeper and open the RPC connection to it. To get a fresh</span>
-<span class="source-line-no">2596</span><span id="line-2596"> * connection, the current rssStub must be null. Method will block until a master is available.</span>
-<span class="source-line-no">2597</span><span id="line-2597"> * You can break from this block by requesting the server stop.</span>
-<span class="source-line-no">2598</span><span id="line-2598"> * @param refresh If true then master address will be read from ZK, otherwise use cached data</span>
-<span class="source-line-no">2599</span><span id="line-2599"> * @return master + port, or null if server has been stopped</span>
-<span class="source-line-no">2600</span><span id="line-2600"> */</span>
-<span class="source-line-no">2601</span><span id="line-2601"> @InterfaceAudience.Private</span>
-<span class="source-line-no">2602</span><span id="line-2602"> protected synchronized ServerName createRegionServerStatusStub(boolean refresh) {</span>
-<span class="source-line-no">2603</span><span id="line-2603"> if (rssStub != null) {</span>
-<span class="source-line-no">2604</span><span id="line-2604"> return masterAddressTracker.getMasterAddress();</span>
-<span class="source-line-no">2605</span><span id="line-2605"> }</span>
-<span class="source-line-no">2606</span><span id="line-2606"> ServerName sn = null;</span>
-<span class="source-line-no">2607</span><span id="line-2607"> long previousLogTime = 0;</span>
-<span class="source-line-no">2608</span><span id="line-2608"> RegionServerStatusService.BlockingInterface intRssStub = null;</span>
-<span class="source-line-no">2609</span><span id="line-2609"> LockService.BlockingInterface intLockStub = null;</span>
-<span class="source-line-no">2610</span><span id="line-2610"> boolean interrupted = false;</span>
-<span class="source-line-no">2611</span><span id="line-2611"> try {</span>
-<span class="source-line-no">2612</span><span id="line-2612"> while (keepLooping()) {</span>
-<span class="source-line-no">2613</span><span id="line-2613"> sn = this.masterAddressTracker.getMasterAddress(refresh);</span>
-<span class="source-line-no">2614</span><span id="line-2614"> if (sn == null) {</span>
-<span class="source-line-no">2615</span><span id="line-2615"> if (!keepLooping()) {</span>
-<span class="source-line-no">2616</span><span id="line-2616"> // give up with no connection.</span>
-<span class="source-line-no">2617</span><span id="line-2617"> LOG.debug("No master found and cluster is stopped; bailing out");</span>
-<span class="source-line-no">2618</span><span id="line-2618"> return null;</span>
-<span class="source-line-no">2619</span><span id="line-2619"> }</span>
-<span class="source-line-no">2620</span><span id="line-2620"> if (EnvironmentEdgeManager.currentTime() > (previousLogTime + 1000)) {</span>
-<span class="source-line-no">2621</span><span id="line-2621"> LOG.debug("No master found; retry");</span>
-<span class="source-line-no">2622</span><span id="line-2622"> previousLogTime = EnvironmentEdgeManager.currentTime();</span>
+<span class="source-line-no">2412</span><span id="line-2412"> tries++;</span>
+<span class="source-line-no">2413</span><span id="line-2413"> if (rssStub == rss) {</span>
+<span class="source-line-no">2414</span><span id="line-2414"> rssStub = null;</span>
+<span class="source-line-no">2415</span><span id="line-2415"> }</span>
+<span class="source-line-no">2416</span><span id="line-2416"> }</span>
+<span class="source-line-no">2417</span><span id="line-2417"> }</span>
+<span class="source-line-no">2418</span><span id="line-2418"> return false;</span>
+<span class="source-line-no">2419</span><span id="line-2419"> }</span>
+<span class="source-line-no">2420</span><span id="line-2420"></span>
+<span class="source-line-no">2421</span><span id="line-2421"> /**</span>
+<span class="source-line-no">2422</span><span id="line-2422"> * Trigger a flush in the primary region replica if this region is a secondary replica. Does not</span>
+<span class="source-line-no">2423</span><span id="line-2423"> * block this thread. See RegionReplicaFlushHandler for details.</span>
+<span class="source-line-no">2424</span><span id="line-2424"> */</span>
+<span class="source-line-no">2425</span><span id="line-2425"> private void triggerFlushInPrimaryRegion(final HRegion region) {</span>
+<span class="source-line-no">2426</span><span id="line-2426"> if (ServerRegionReplicaUtil.isDefaultReplica(region.getRegionInfo())) {</span>
+<span class="source-line-no">2427</span><span id="line-2427"> return;</span>
+<span class="source-line-no">2428</span><span id="line-2428"> }</span>
+<span class="source-line-no">2429</span><span id="line-2429"> TableName tn = region.getTableDescriptor().getTableName();</span>
+<span class="source-line-no">2430</span><span id="line-2430"> if (</span>
+<span class="source-line-no">2431</span><span id="line-2431"> !ServerRegionReplicaUtil.isRegionReplicaReplicationEnabled(region.conf, tn)</span>
+<span class="source-line-no">2432</span><span id="line-2432"> || !ServerRegionReplicaUtil.isRegionReplicaWaitForPrimaryFlushEnabled(region.conf) ||</span>
+<span class="source-line-no">2433</span><span id="line-2433"> // If the memstore replication not setup, we do not have to wait for observing a flush event</span>
+<span class="source-line-no">2434</span><span id="line-2434"> // from primary before starting to serve reads, because gaps from replication is not</span>
+<span class="source-line-no">2435</span><span id="line-2435"> // applicable,this logic is from</span>
+<span class="source-line-no">2436</span><span id="line-2436"> // TableDescriptorBuilder.ModifyableTableDescriptor.setRegionMemStoreReplication by</span>
+<span class="source-line-no">2437</span><span id="line-2437"> // HBASE-13063</span>
+<span class="source-line-no">2438</span><span id="line-2438"> !region.getTableDescriptor().hasRegionMemStoreReplication()</span>
+<span class="source-line-no">2439</span><span id="line-2439"> ) {</span>
+<span class="source-line-no">2440</span><span id="line-2440"> region.setReadsEnabled(true);</span>
+<span class="source-line-no">2441</span><span id="line-2441"> return;</span>
+<span class="source-line-no">2442</span><span id="line-2442"> }</span>
+<span class="source-line-no">2443</span><span id="line-2443"></span>
+<span class="source-line-no">2444</span><span id="line-2444"> region.setReadsEnabled(false); // disable reads before marking the region as opened.</span>
+<span class="source-line-no">2445</span><span id="line-2445"> // RegionReplicaFlushHandler might reset this.</span>
+<span class="source-line-no">2446</span><span id="line-2446"></span>
+<span class="source-line-no">2447</span><span id="line-2447"> // Submit it to be handled by one of the handlers so that we do not block OpenRegionHandler</span>
+<span class="source-line-no">2448</span><span id="line-2448"> if (this.executorService != null) {</span>
+<span class="source-line-no">2449</span><span id="line-2449"> this.executorService.submit(new RegionReplicaFlushHandler(this, region));</span>
+<span class="source-line-no">2450</span><span id="line-2450"> } else {</span>
+<span class="source-line-no">2451</span><span id="line-2451"> LOG.info("Executor is null; not running flush of primary region replica for {}",</span>
+<span class="source-line-no">2452</span><span id="line-2452"> region.getRegionInfo());</span>
+<span class="source-line-no">2453</span><span id="line-2453"> }</span>
+<span class="source-line-no">2454</span><span id="line-2454"> }</span>
+<span class="source-line-no">2455</span><span id="line-2455"></span>
+<span class="source-line-no">2456</span><span id="line-2456"> @InterfaceAudience.Private</span>
+<span class="source-line-no">2457</span><span id="line-2457"> public RSRpcServices getRSRpcServices() {</span>
+<span class="source-line-no">2458</span><span id="line-2458"> return rpcServices;</span>
+<span class="source-line-no">2459</span><span id="line-2459"> }</span>
+<span class="source-line-no">2460</span><span id="line-2460"></span>
+<span class="source-line-no">2461</span><span id="line-2461"> /**</span>
+<span class="source-line-no">2462</span><span id="line-2462"> * Cause the server to exit without closing the regions it is serving, the log it is using and</span>
+<span class="source-line-no">2463</span><span id="line-2463"> * without notifying the master. Used unit testing and on catastrophic events such as HDFS is</span>
+<span class="source-line-no">2464</span><span id="line-2464"> * yanked out from under hbase or we OOME. the reason we are aborting the exception that caused</span>
+<span class="source-line-no">2465</span><span id="line-2465"> * the abort, or null</span>
+<span class="source-line-no">2466</span><span id="line-2466"> */</span>
+<span class="source-line-no">2467</span><span id="line-2467"> @Override</span>
+<span class="source-line-no">2468</span><span id="line-2468"> public void abort(String reason, Throwable cause) {</span>
+<span class="source-line-no">2469</span><span id="line-2469"> if (!setAbortRequested()) {</span>
+<span class="source-line-no">2470</span><span id="line-2470"> // Abort already in progress, ignore the new request.</span>
+<span class="source-line-no">2471</span><span id="line-2471"> LOG.debug("Abort already in progress. Ignoring the current request with reason: {}", reason);</span>
+<span class="source-line-no">2472</span><span id="line-2472"> return;</span>
+<span class="source-line-no">2473</span><span id="line-2473"> }</span>
+<span class="source-line-no">2474</span><span id="line-2474"> String msg = "***** ABORTING region server " + this + ": " + reason + " *****";</span>
+<span class="source-line-no">2475</span><span id="line-2475"> if (cause != null) {</span>
+<span class="source-line-no">2476</span><span id="line-2476"> LOG.error(HBaseMarkers.FATAL, msg, cause);</span>
+<span class="source-line-no">2477</span><span id="line-2477"> } else {</span>
+<span class="source-line-no">2478</span><span id="line-2478"> LOG.error(HBaseMarkers.FATAL, msg);</span>
+<span class="source-line-no">2479</span><span id="line-2479"> }</span>
+<span class="source-line-no">2480</span><span id="line-2480"> // HBASE-4014: show list of coprocessors that were loaded to help debug</span>
+<span class="source-line-no">2481</span><span id="line-2481"> // regionserver crashes.Note that we're implicitly using</span>
+<span class="source-line-no">2482</span><span id="line-2482"> // java.util.HashSet's toString() method to print the coprocessor names.</span>
+<span class="source-line-no">2483</span><span id="line-2483"> LOG.error(HBaseMarkers.FATAL,</span>
+<span class="source-line-no">2484</span><span id="line-2484"> "RegionServer abort: loaded coprocessors are: " + CoprocessorHost.getLoadedCoprocessors());</span>
+<span class="source-line-no">2485</span><span id="line-2485"> // Try and dump metrics if abort -- might give clue as to how fatal came about....</span>
+<span class="source-line-no">2486</span><span id="line-2486"> try {</span>
+<span class="source-line-no">2487</span><span id="line-2487"> LOG.info("Dump of metrics as JSON on abort: " + DumpRegionServerMetrics.dumpMetrics());</span>
+<span class="source-line-no">2488</span><span id="line-2488"> } catch (MalformedObjectNameException | IOException e) {</span>
+<span class="source-line-no">2489</span><span id="line-2489"> LOG.warn("Failed dumping metrics", e);</span>
+<span class="source-line-no">2490</span><span id="line-2490"> }</span>
+<span class="source-line-no">2491</span><span id="line-2491"></span>
+<span class="source-line-no">2492</span><span id="line-2492"> // Do our best to report our abort to the master, but this may not work</span>
+<span class="source-line-no">2493</span><span id="line-2493"> try {</span>
+<span class="source-line-no">2494</span><span id="line-2494"> if (cause != null) {</span>
+<span class="source-line-no">2495</span><span id="line-2495"> msg += "\nCause:\n" + Throwables.getStackTraceAsString(cause);</span>
+<span class="source-line-no">2496</span><span id="line-2496"> }</span>
+<span class="source-line-no">2497</span><span id="line-2497"> // Report to the master but only if we have already registered with the master.</span>
+<span class="source-line-no">2498</span><span id="line-2498"> RegionServerStatusService.BlockingInterface rss = rssStub;</span>
+<span class="source-line-no">2499</span><span id="line-2499"> if (rss != null && this.serverName != null) {</span>
+<span class="source-line-no">2500</span><span id="line-2500"> ReportRSFatalErrorRequest.Builder builder = ReportRSFatalErrorRequest.newBuilder();</span>
+<span class="source-line-no">2501</span><span id="line-2501"> builder.setServer(ProtobufUtil.toServerName(this.serverName));</span>
+<span class="source-line-no">2502</span><span id="line-2502"> builder.setErrorMessage(msg);</span>
+<span class="source-line-no">2503</span><span id="line-2503"> rss.reportRSFatalError(null, builder.build());</span>
+<span class="source-line-no">2504</span><span id="line-2504"> }</span>
+<span class="source-line-no">2505</span><span id="line-2505"> } catch (Throwable t) {</span>
+<span class="source-line-no">2506</span><span id="line-2506"> LOG.warn("Unable to report fatal error to master", t);</span>
+<span class="source-line-no">2507</span><span id="line-2507"> }</span>
+<span class="source-line-no">2508</span><span id="line-2508"></span>
+<span class="source-line-no">2509</span><span id="line-2509"> scheduleAbortTimer();</span>
+<span class="source-line-no">2510</span><span id="line-2510"> // shutdown should be run as the internal user</span>
+<span class="source-line-no">2511</span><span id="line-2511"> stop(reason, true, null);</span>
+<span class="source-line-no">2512</span><span id="line-2512"> }</span>
+<span class="source-line-no">2513</span><span id="line-2513"></span>
+<span class="source-line-no">2514</span><span id="line-2514"> /*</span>
+<span class="source-line-no">2515</span><span id="line-2515"> * Simulate a kill -9 of this server. Exits w/o closing regions or cleaninup logs but it does</span>
+<span class="source-line-no">2516</span><span id="line-2516"> * close socket in case want to bring up server on old hostname+port immediately.</span>
+<span class="source-line-no">2517</span><span id="line-2517"> */</span>
+<span class="source-line-no">2518</span><span id="line-2518"> @InterfaceAudience.Private</span>
+<span class="source-line-no">2519</span><span id="line-2519"> protected void kill() {</span>
+<span class="source-line-no">2520</span><span id="line-2520"> this.killed = true;</span>
+<span class="source-line-no">2521</span><span id="line-2521"> abort("Simulated kill");</span>
+<span class="source-line-no">2522</span><span id="line-2522"> }</span>
+<span class="source-line-no">2523</span><span id="line-2523"></span>
+<span class="source-line-no">2524</span><span id="line-2524"> // Limits the time spent in the shutdown process.</span>
+<span class="source-line-no">2525</span><span id="line-2525"> private void scheduleAbortTimer() {</span>
+<span class="source-line-no">2526</span><span id="line-2526"> if (this.abortMonitor == null) {</span>
+<span class="source-line-no">2527</span><span id="line-2527"> this.abortMonitor = new Timer("Abort regionserver monitor", true);</span>
+<span class="source-line-no">2528</span><span id="line-2528"> TimerTask abortTimeoutTask = null;</span>
+<span class="source-line-no">2529</span><span id="line-2529"> try {</span>
+<span class="source-line-no">2530</span><span id="line-2530"> Constructor<? extends TimerTask> timerTaskCtor =</span>
+<span class="source-line-no">2531</span><span id="line-2531"> Class.forName(conf.get(ABORT_TIMEOUT_TASK, SystemExitWhenAbortTimeout.class.getName()))</span>
+<span class="source-line-no">2532</span><span id="line-2532"> .asSubclass(TimerTask.class).getDeclaredConstructor();</span>
+<span class="source-line-no">2533</span><span id="line-2533"> timerTaskCtor.setAccessible(true);</span>
+<span class="source-line-no">2534</span><span id="line-2534"> abortTimeoutTask = timerTaskCtor.newInstance();</span>
+<span class="source-line-no">2535</span><span id="line-2535"> } catch (Exception e) {</span>
+<span class="source-line-no">2536</span><span id="line-2536"> LOG.warn("Initialize abort timeout task failed", e);</span>
+<span class="source-line-no">2537</span><span id="line-2537"> }</span>
+<span class="source-line-no">2538</span><span id="line-2538"> if (abortTimeoutTask != null) {</span>
+<span class="source-line-no">2539</span><span id="line-2539"> abortMonitor.schedule(abortTimeoutTask, conf.getLong(ABORT_TIMEOUT, DEFAULT_ABORT_TIMEOUT));</span>
+<span class="source-line-no">2540</span><span id="line-2540"> }</span>
+<span class="source-line-no">2541</span><span id="line-2541"> }</span>
+<span class="source-line-no">2542</span><span id="line-2542"> }</span>
+<span class="source-line-no">2543</span><span id="line-2543"></span>
+<span class="source-line-no">2544</span><span id="line-2544"> /**</span>
+<span class="source-line-no">2545</span><span id="line-2545"> * Wait on all threads to finish. Presumption is that all closes and stops have already been</span>
+<span class="source-line-no">2546</span><span id="line-2546"> * called.</span>
+<span class="source-line-no">2547</span><span id="line-2547"> */</span>
+<span class="source-line-no">2548</span><span id="line-2548"> protected void stopServiceThreads() {</span>
+<span class="source-line-no">2549</span><span id="line-2549"> // clean up the scheduled chores</span>
+<span class="source-line-no">2550</span><span id="line-2550"> stopChoreService();</span>
+<span class="source-line-no">2551</span><span id="line-2551"> if (bootstrapNodeManager != null) {</span>
+<span class="source-line-no">2552</span><span id="line-2552"> bootstrapNodeManager.stop();</span>
+<span class="source-line-no">2553</span><span id="line-2553"> }</span>
+<span class="source-line-no">2554</span><span id="line-2554"> if (this.cacheFlusher != null) {</span>
+<span class="source-line-no">2555</span><span id="line-2555"> this.cacheFlusher.shutdown();</span>
+<span class="source-line-no">2556</span><span id="line-2556"> }</span>
+<span class="source-line-no">2557</span><span id="line-2557"> if (this.walRoller != null) {</span>
+<span class="source-line-no">2558</span><span id="line-2558"> this.walRoller.close();</span>
+<span class="source-line-no">2559</span><span id="line-2559"> }</span>
+<span class="source-line-no">2560</span><span id="line-2560"> if (this.compactSplitThread != null) {</span>
+<span class="source-line-no">2561</span><span id="line-2561"> this.compactSplitThread.join();</span>
+<span class="source-line-no">2562</span><span id="line-2562"> }</span>
+<span class="source-line-no">2563</span><span id="line-2563"> stopExecutorService();</span>
+<span class="source-line-no">2564</span><span id="line-2564"> if (sameReplicationSourceAndSink && this.replicationSourceHandler != null) {</span>
+<span class="source-line-no">2565</span><span id="line-2565"> this.replicationSourceHandler.stopReplicationService();</span>
+<span class="source-line-no">2566</span><span id="line-2566"> } else {</span>
+<span class="source-line-no">2567</span><span id="line-2567"> if (this.replicationSourceHandler != null) {</span>
+<span class="source-line-no">2568</span><span id="line-2568"> this.replicationSourceHandler.stopReplicationService();</span>
+<span class="source-line-no">2569</span><span id="line-2569"> }</span>
+<span class="source-line-no">2570</span><span id="line-2570"> if (this.replicationSinkHandler != null) {</span>
+<span class="source-line-no">2571</span><span id="line-2571"> this.replicationSinkHandler.stopReplicationService();</span>
+<span class="source-line-no">2572</span><span id="line-2572"> }</span>
+<span class="source-line-no">2573</span><span id="line-2573"> }</span>
+<span class="source-line-no">2574</span><span id="line-2574"> }</span>
+<span class="source-line-no">2575</span><span id="line-2575"></span>
+<span class="source-line-no">2576</span><span id="line-2576"> /** Returns Return the object that implements the replication source executorService. */</span>
+<span class="source-line-no">2577</span><span id="line-2577"> @Override</span>
+<span class="source-line-no">2578</span><span id="line-2578"> public ReplicationSourceService getReplicationSourceService() {</span>
+<span class="source-line-no">2579</span><span id="line-2579"> return replicationSourceHandler;</span>
+<span class="source-line-no">2580</span><span id="line-2580"> }</span>
+<span class="source-line-no">2581</span><span id="line-2581"></span>
+<span class="source-line-no">2582</span><span id="line-2582"> /** Returns Return the object that implements the replication sink executorService. */</span>
+<span class="source-line-no">2583</span><span id="line-2583"> public ReplicationSinkService getReplicationSinkService() {</span>
+<span class="source-line-no">2584</span><span id="line-2584"> return replicationSinkHandler;</span>
+<span class="source-line-no">2585</span><span id="line-2585"> }</span>
+<span class="source-line-no">2586</span><span id="line-2586"></span>
+<span class="source-line-no">2587</span><span id="line-2587"> /**</span>
+<span class="source-line-no">2588</span><span id="line-2588"> * Get the current master from ZooKeeper and open the RPC connection to it. To get a fresh</span>
+<span class="source-line-no">2589</span><span id="line-2589"> * connection, the current rssStub must be null. Method will block until a master is available.</span>
+<span class="source-line-no">2590</span><span id="line-2590"> * You can break from this block by requesting the server stop.</span>
+<span class="source-line-no">2591</span><span id="line-2591"> * @return master + port, or null if server has been stopped</span>
+<span class="source-line-no">2592</span><span id="line-2592"> */</span>
+<span class="source-line-no">2593</span><span id="line-2593"> private synchronized ServerName createRegionServerStatusStub() {</span>
+<span class="source-line-no">2594</span><span id="line-2594"> // Create RS stub without refreshing the master node from ZK, use cached data</span>
+<span class="source-line-no">2595</span><span id="line-2595"> return createRegionServerStatusStub(false);</span>
+<span class="source-line-no">2596</span><span id="line-2596"> }</span>
+<span class="source-line-no">2597</span><span id="line-2597"></span>
+<span class="source-line-no">2598</span><span id="line-2598"> /**</span>
+<span class="source-line-no">2599</span><span id="line-2599"> * Get the current master from ZooKeeper and open the RPC connection to it. To get a fresh</span>
+<span class="source-line-no">2600</span><span id="line-2600"> * connection, the current rssStub must be null. Method will block until a master is available.</span>
+<span class="source-line-no">2601</span><span id="line-2601"> * You can break from this block by requesting the server stop.</span>
+<span class="source-line-no">2602</span><span id="line-2602"> * @param refresh If true then master address will be read from ZK, otherwise use cached data</span>
+<span class="source-line-no">2603</span><span id="line-2603"> * @return master + port, or null if server has been stopped</span>
+<span class="source-line-no">2604</span><span id="line-2604"> */</span>
+<span class="source-line-no">2605</span><span id="line-2605"> @InterfaceAudience.Private</span>
+<span class="source-line-no">2606</span><span id="line-2606"> protected synchronized ServerName createRegionServerStatusStub(boolean refresh) {</span>
+<span class="source-line-no">2607</span><span id="line-2607"> if (rssStub != null) {</span>
+<span class="source-line-no">2608</span><span id="line-2608"> return masterAddressTracker.getMasterAddress();</span>
+<span class="source-line-no">2609</span><span id="line-2609"> }</span>
+<span class="source-line-no">2610</span><span id="line-2610"> ServerName sn = null;</span>
+<span class="source-line-no">2611</span><span id="line-2611"> long previousLogTime = 0;</span>
+<span class="source-line-no">2612</span><span id="line-2612"> RegionServerStatusService.BlockingInterface intRssStub = null;</span>
+<span class="source-line-no">2613</span><span id="line-2613"> LockService.BlockingInterface intLockStub = null;</span>
+<span class="source-line-no">2614</span><span id="line-2614"> boolean interrupted = false;</span>
+<span class="source-line-no">2615</span><span id="line-2615"> try {</span>
+<span class="source-line-no">2616</span><span id="line-2616"> while (keepLooping()) {</span>
+<span class="source-line-no">2617</span><span id="line-2617"> sn = this.masterAddressTracker.getMasterAddress(refresh);</span>
+<span class="source-line-no">2618</span><span id="line-2618"> if (sn == null) {</span>
+<span class="source-line-no">2619</span><span id="line-2619"> if (!keepLooping()) {</span>
+<span class="source-line-no">2620</span><span id="line-2620"> // give up with no connection.</span>
+<span class="source-line-no">2621</span><span id="line-2621"> LOG.debug("No master found and cluster is stopped; bailing out");</span>
+<span class="source-line-no">2622</span><span id="line-2622"> return null;</span>
<span class="source-line-no">2623</span><span id="line-2623"> }</span>
-<span class="source-line-no">2624</span><span id="line-2624"> refresh = true; // let's try pull it from ZK directly</span>
-<span class="source-line-no">2625</span><span id="line-2625"> if (sleepInterrupted(200)) {</span>
-<span class="source-line-no">2626</span><span id="line-2626"> interrupted = true;</span>
+<span class="source-line-no">2624</span><span id="line-2624"> if (EnvironmentEdgeManager.currentTime() > (previousLogTime + 1000)) {</span>
+<span class="source-line-no">2625</span><span id="line-2625"> LOG.debug("No master found; retry");</span>
+<span class="source-line-no">2626</span><span id="line-2626"> previousLogTime = EnvironmentEdgeManager.currentTime();</span>
<span class="source-line-no">2627</span><span id="line-2627"> }</span>
-<span class="source-line-no">2628</span><span id="line-2628"> continue;</span>
-<span class="source-line-no">2629</span><span id="line-2629"> }</span>
-<span class="source-line-no">2630</span><span id="line-2630"> try {</span>
-<span class="source-line-no">2631</span><span id="line-2631"> BlockingRpcChannel channel = this.rpcClient.createBlockingRpcChannel(sn,</span>
-<span class="source-line-no">2632</span><span id="line-2632"> userProvider.getCurrent(), shortOperationTimeout);</span>
-<span class="source-line-no">2633</span><span id="line-2633"> intRssStub = RegionServerStatusService.newBlockingStub(channel);</span>
-<span class="source-line-no">2634</span><span id="line-2634"> intLockStub = LockService.newBlockingStub(channel);</span>
-<span class="source-line-no">2635</span><span id="line-2635"> break;</span>
-<span class="source-line-no">2636</span><span id="line-2636"> } catch (IOException e) {</span>
-<span class="source-line-no">2637</span><span id="line-2637"> if (EnvironmentEdgeManager.currentTime() > (previousLogTime + 1000)) {</span>
-<span class="source-line-no">2638</span><span id="line-2638"> e = e instanceof RemoteException ? ((RemoteException) e).unwrapRemoteException() : e;</span>
-<span class="source-line-no">2639</span><span id="line-2639"> if (e instanceof ServerNotRunningYetException) {</span>
-<span class="source-line-no">2640</span><span id="line-2640"> LOG.info("Master isn't available yet, retrying");</span>
-<span class="source-line-no">2641</span><span id="line-2641"> } else {</span>
-<span class="source-line-no">2642</span><span id="line-2642"> LOG.warn("Unable to connect to master. Retrying. Error was:", e);</span>
-<span class="source-line-no">2643</span><span id="line-2643"> }</span>
-<span class="source-line-no">2644</span><span id="line-2644"> previousLogTime = EnvironmentEdgeManager.currentTime();</span>
-<span class="source-line-no">2645</span><span id="line-2645"> }</span>
-<span class="source-line-no">2646</span><span id="line-2646"> if (sleepInterrupted(200)) {</span>
-<span class="source-line-no">2647</span><span id="line-2647"> interrupted = true;</span>
-<span class="source-line-no">2648</span><span id="line-2648"> }</span>
-<span class="source-line-no">2649</span><span id="line-2649"> }</span>
-<span class="source-line-no">2650</span><span id="line-2650"> }</span>
-<span class="source-line-no">2651</span><span id="line-2651"> } finally {</span>
-<span class="source-line-no">2652</span><span id="line-2652"> if (interrupted) {</span>
-<span class="source-line-no">2653</span><span id="line-2653"> Thread.currentThread().interrupt();</span>
+<span class="source-line-no">2628</span><span id="line-2628"> refresh = true; // let's try pull it from ZK directly</span>
+<span class="source-line-no">2629</span><span id="line-2629"> if (sleepInterrupted(200)) {</span>
+<span class="source-line-no">2630</span><span id="line-2630"> interrupted = true;</span>
+<span class="source-line-no">2631</span><span id="line-2631"> }</span>
+<span class="source-line-no">2632</span><span id="line-2632"> continue;</span>
+<span class="source-line-no">2633</span><span id="line-2633"> }</span>
+<span class="source-line-no">2634</span><span id="line-2634"> try {</span>
+<span class="source-line-no">2635</span><span id="line-2635"> BlockingRpcChannel channel = this.rpcClient.createBlockingRpcChannel(sn,</span>
+<span class="source-line-no">2636</span><span id="line-2636"> userProvider.getCurrent(), shortOperationTimeout);</span>
+<span class="source-line-no">2637</span><span id="line-2637"> intRssStub = RegionServerStatusService.newBlockingStub(channel);</span>
+<span class="source-line-no">2638</span><span id="line-2638"> intLockStub = LockService.newBlockingStub(channel);</span>
+<span class="source-line-no">2639</span><span id="line-2639"> break;</span>
+<span class="source-line-no">2640</span><span id="line-2640"> } catch (IOException e) {</span>
+<span class="source-line-no">2641</span><span id="line-2641"> if (EnvironmentEdgeManager.currentTime() > (previousLogTime + 1000)) {</span>
+<span class="source-line-no">2642</span><span id="line-2642"> e = e instanceof RemoteException ? ((RemoteException) e).unwrapRemoteException() : e;</span>
+<span class="source-line-no">2643</span><span id="line-2643"> if (e instanceof ServerNotRunningYetException) {</span>
+<span class="source-line-no">2644</span><span id="line-2644"> LOG.info("Master isn't available yet, retrying");</span>
+<span class="source-line-no">2645</span><span id="line-2645"> } else {</span>
+<span class="source-line-no">2646</span><span id="line-2646"> LOG.warn("Unable to connect to master. Retrying. Error was:", e);</span>
+<span class="source-line-no">2647</span><span id="line-2647"> }</span>
+<span class="source-line-no">2648</span><span id="line-2648"> previousLogTime = EnvironmentEdgeManager.currentTime();</span>
+<span class="source-line-no">2649</span><span id="line-2649"> }</span>
+<span class="source-line-no">2650</span><span id="line-2650"> if (sleepInterrupted(200)) {</span>
+<span class="source-line-no">2651</span><span id="line-2651"> interrupted = true;</span>
+<span class="source-line-no">2652</span><span id="line-2652"> }</span>
+<span class="source-line-no">2653</span><span id="line-2653"> }</span>
<span class="source-line-no">2654</span><span id="line-2654"> }</span>
-<span class="source-line-no">2655</span><span id="line-2655"> }</span>
-<span class="source-line-no">2656</span><span id="line-2656"> this.rssStub = intRssStub;</span>
-<span class="source-line-no">2657</span><span id="line-2657"> this.lockStub = intLockStub;</span>
-<span class="source-line-no">2658</span><span id="line-2658"> return sn;</span>
-<span class="source-line-no">2659</span><span id="line-2659"> }</span>
-<span class="source-line-no">2660</span><span id="line-2660"></span>
-<span class="source-line-no">2661</span><span id="line-2661"> /**</span>
-<span class="source-line-no">2662</span><span id="line-2662"> * @return True if we should break loop because cluster is going down or this server has been</span>
-<span class="source-line-no">2663</span><span id="line-2663"> * stopped or hdfs has gone bad.</span>
-<span class="source-line-no">2664</span><span id="line-2664"> */</span>
-<span class="source-line-no">2665</span><span id="line-2665"> private boolean keepLooping() {</span>
-<span class="source-line-no">2666</span><span id="line-2666"> return !this.stopped && isClusterUp();</span>
-<span class="source-line-no">2667</span><span id="line-2667"> }</span>
-<span class="source-line-no">2668</span><span id="line-2668"></span>
-<span class="source-line-no">2669</span><span id="line-2669"> /*</span>
-<span class="source-line-no">2670</span><span id="line-2670"> * Let the master know we're here Run initialization using parameters passed us by the master.</span>
-<span class="source-line-no">2671</span><span id="line-2671"> * @return A Map of key/value configurations we got from the Master else null if we failed to</span>
-<span class="source-line-no">2672</span><span id="line-2672"> * register.</span>
-<span class="source-line-no">2673</span><span id="line-2673"> */</span>
-<span class="source-line-no">2674</span><span id="line-2674"> private RegionServerStartupResponse reportForDuty() throws IOException {</span>
-<span class="source-line-no">2675</span><span id="line-2675"> if (this.masterless) {</span>
-<span class="source-line-no">2676</span><span id="line-2676"> return RegionServerStartupResponse.getDefaultInstance();</span>
-<span class="source-line-no">2677</span><span id="line-2677"> }</span>
-<span class="source-line-no">2678</span><span id="line-2678"> ServerName masterServerName = createRegionServerStatusStub(true);</span>
-<span class="source-line-no">2679</span><span id="line-2679"> RegionServerStatusService.BlockingInterface rss = rssStub;</span>
-<span class="source-line-no">2680</span><span id="line-2680"> if (masterServerName == null || rss == null) {</span>
-<span class="source-line-no">2681</span><span id="line-2681"> return null;</span>
-<span class="source-line-no">2682</span><span id="line-2682"> }</span>
-<span class="source-line-no">2683</span><span id="line-2683"> RegionServerStartupResponse result = null;</span>
-<span class="source-line-no">2684</span><span id="line-2684"> try {</span>
-<span class="source-line-no">2685</span><span id="line-2685"> rpcServices.requestCount.reset();</span>
-<span class="source-line-no">2686</span><span id="line-2686"> rpcServices.rpcGetRequestCount.reset();</span>
-<span class="source-line-no">2687</span><span id="line-2687"> rpcServices.rpcScanRequestCount.reset();</span>
-<span class="source-line-no">2688</span><span id="line-2688"> rpcServices.rpcFullScanRequestCount.reset();</span>
-<span class="source-line-no">2689</span><span id="line-2689"> rpcServices.rpcMultiRequestCount.reset();</span>
-<span class="source-line-no">2690</span><span id="line-2690"> rpcServices.rpcMutateRequestCount.reset();</span>
-<span class="source-line-no">2691</span><span id="line-2691"> LOG.info("reportForDuty to master=" + masterServerName + " with port="</span>
-<span class="source-line-no">2692</span><span id="line-2692"> + rpcServices.getSocketAddress().getPort() + ", startcode=" + this.startcode);</span>
-<span class="source-line-no">2693</span><span id="line-2693"> long now = EnvironmentEdgeManager.currentTime();</span>
-<span class="source-line-no">2694</span><span id="line-2694"> int port = rpcServices.getSocketAddress().getPort();</span>
-<span class="source-line-no">2695</span><span id="line-2695"> RegionServerStartupRequest.Builder request = RegionServerStartupRequest.newBuilder();</span>
-<span class="source-line-no">2696</span><span id="line-2696"> if (!StringUtils.isBlank(useThisHostnameInstead)) {</span>
-<span class="source-line-no">2697</span><span id="line-2697"> request.setUseThisHostnameInstead(useThisHostnameInstead);</span>
-<span class="source-line-no">2698</span><span id="line-2698"> }</span>
-<span class="source-line-no">2699</span><span id="line-2699"> request.setPort(port);</span>
-<span class="source-line-no">2700</span><span id="line-2700"> request.setServerStartCode(this.startcode);</span>
-<span class="source-line-no">2701</span><span id="line-2701"> request.setServerCurrentTime(now);</span>
-<span class="source-line-no">2702</span><span id="line-2702"> result = rss.regionServerStartup(null, request.build());</span>
-<span class="source-line-no">2703</span><span id="line-2703"> } catch (ServiceException se) {</span>
-<span class="source-line-no">2704</span><span id="line-2704"> IOException ioe = ProtobufUtil.getRemoteException(se);</span>
-<span class="source-line-no">2705</span><span id="line-2705"> if (ioe instanceof ClockOutOfSyncException) {</span>
-<span class="source-line-no">2706</span><span id="line-2706"> LOG.error(HBaseMarkers.FATAL, "Master rejected startup because clock is out of sync", ioe);</span>
-<span class="source-line-no">2707</span><span id="line-2707"> // Re-throw IOE will cause RS to abort</span>
-<span class="source-line-no">2708</span><span id="line-2708"> throw ioe;</span>
-<span class="source-line-no">2709</span><span id="line-2709"> } else if (ioe instanceof DecommissionedHostRejectedException) {</span>
-<span class="source-line-no">2710</span><span id="line-2710"> LOG.error(HBaseMarkers.FATAL,</span>
-<span class="source-line-no">2711</span><span id="line-2711"> "Master rejected startup because the host is considered decommissioned", ioe);</span>
-<span class="source-line-no">2712</span><span id="line-2712"> // Re-throw IOE will cause RS to abort</span>
-<span class="source-line-no">2713</span><span id="line-2713"> throw ioe;</span>
-<span class="source-line-no">2714</span><span id="line-2714"> } else if (ioe instanceof ServerNotRunningYetException) {</span>
-<span class="source-line-no">2715</span><span id="line-2715"> LOG.debug("Master is not running yet");</span>
-<span class="source-line-no">2716</span><span id="line-2716"> } else {</span>
-<span class="source-line-no">2717</span><span id="line-2717"> LOG.warn("error telling master we are up", se);</span>
-<span class="source-line-no">2718</span><span id="line-2718"> }</span>
-<span class="source-line-no">2719</span><span id="line-2719"> rssStub = null;</span>
-<span class="source-line-no">2720</span><span id="line-2720"> }</span>
-<span class="source-line-no">2721</span><span id="line-2721"> return result;</span>
-<span class="source-line-no">2722</span><span id="line-2722"> }</span>
-<span class="source-line-no">2723</span><span id="line-2723"></span>
-<span class="source-line-no">2724</span><span id="line-2724"> @Override</span>
-<span class="source-line-no">2725</span><span id="line-2725"> public RegionStoreSequenceIds getLastSequenceId(byte[] encodedRegionName) {</span>
-<span class="source-line-no">2726</span><span id="line-2726"> try {</span>
-<span class="source-line-no">2727</span><span id="line-2727"> GetLastFlushedSequenceIdRequest req =</span>
-<span class="source-line-no">2728</span><span id="line-2728"> RequestConverter.buildGetLastFlushedSequenceIdRequest(encodedRegionName);</span>
-<span class="source-line-no">2729</span><span id="line-2729"> RegionServerStatusService.BlockingInterface rss = rssStub;</span>
-<span class="source-line-no">2730</span><span id="line-2730"> if (rss == null) { // Try to connect one more time</span>
-<span class="source-line-no">2731</span><span id="line-2731"> createRegionServerStatusStub();</span>
-<span class="source-line-no">2732</span><span id="line-2732"> rss = rssStub;</span>
-<span class="source-line-no">2733</span><span id="line-2733"> if (rss == null) {</span>
-<span class="source-line-no">2734</span><span id="line-2734"> // Still no luck, we tried</span>
-<span class="source-line-no">2735</span><span id="line-2735"> LOG.warn("Unable to connect to the master to check " + "the last flushed sequence id");</span>
-<span class="source-line-no">2736</span><span id="line-2736"> return RegionStoreSequenceIds.newBuilder().setLastFlushedSequenceId(HConstants.NO_SEQNUM)</span>
-<span class="source-line-no">2737</span><span id="line-2737"> .build();</span>
-<span class="source-line-no">2738</span><span id="line-2738"> }</span>
-<span class="source-line-no">2739</span><span id="line-2739"> }</span>
-<span class="source-line-no">2740</span><span id="line-2740"> GetLastFlushedSequenceIdResponse resp = rss.getLastFlushedSequenceId(null, req);</span>
-<span class="source-line-no">2741</span><span id="line-2741"> return RegionStoreSequenceIds.newBuilder()</span>
-<span class="source-line-no">2742</span><span id="line-2742"> .setLastFlushedSequenceId(resp.getLastFlushedSequenceId())</span>
-<span class="source-line-no">2743</span><span id="line-2743"> .addAllStoreSequenceId(resp.getStoreLastFlushedSequenceIdList()).build();</span>
-<span class="source-line-no">2744</span><span id="line-2744"> } catch (ServiceException e) {</span>
-<span class="source-line-no">2745</span><span id="line-2745"> LOG.warn("Unable to connect to the master to check the last flushed sequence id", e);</span>
-<span class="source-line-no">2746</span><span id="line-2746"> return RegionStoreSequenceIds.newBuilder().setLastFlushedSequenceId(HConstants.NO_SEQNUM)</span>
-<span class="source-line-no">2747</span><span id="line-2747"> .build();</span>
-<span class="source-line-no">2748</span><span id="line-2748"> }</span>
-<span class="source-line-no">2749</span><span id="line-2749"> }</span>
-<span class="source-line-no">2750</span><span id="line-2750"></span>
-<span class="source-line-no">2751</span><span id="line-2751"> /**</span>
-<span class="source-line-no">2752</span><span id="line-2752"> * Close meta region if we carry it</span>
-<span class="source-line-no">2753</span><span id="line-2753"> * @param abort Whether we're running an abort.</span>
-<span class="source-line-no">2754</span><span id="line-2754"> */</span>
-<span class="source-line-no">2755</span><span id="line-2755"> private void closeMetaTableRegions(final boolean abort) {</span>
-<span class="source-line-no">2756</span><span id="line-2756"> HRegion meta = null;</span>
-<span class="source-line-no">2757</span><span id="line-2757"> this.onlineRegionsLock.writeLock().lock();</span>
-<span class="source-line-no">2758</span><span id="line-2758"> try {</span>
-<span class="source-line-no">2759</span><span id="line-2759"> for (Map.Entry<String, HRegion> e : onlineRegions.entrySet()) {</span>
-<span class="source-line-no">2760</span><span id="line-2760"> RegionInfo hri = e.getValue().getRegionInfo();</span>
-<span class="source-line-no">2761</span><span id="line-2761"> if (hri.isMetaRegion()) {</span>
-<span class="source-line-no">2762</span><span id="line-2762"> meta = e.getValue();</span>
-<span class="source-line-no">2763</span><span id="line-2763"> }</span>
-<span class="source-line-no">2764</span><span id="line-2764"> if (meta != null) {</span>
-<span class="source-line-no">2765</span><span id="line-2765"> break;</span>
-<span class="source-line-no">2766</span><span id="line-2766"> }</span>
-<span class="source-line-no">2767</span><span id="line-2767"> }</span>
-<span class="source-line-no">2768</span><span id="line-2768"> } finally {</span>
-<span class="source-line-no">2769</span><span id="line-2769"> this.onlineRegionsLock.writeLock().unlock();</span>
-<span class="source-line-no">2770</span><span id="line-2770"> }</span>
-<span class="source-line-no">2771</span><span id="line-2771"> if (meta != null) {</span>
-<span class="source-line-no">2772</span><span id="line-2772"> closeRegionIgnoreErrors(meta.getRegionInfo(), abort);</span>
-<span class="source-line-no">2773</span><span id="line-2773"> }</span>
-<span class="source-line-no">2774</span><span id="line-2774"> }</span>
-<span class="source-line-no">2775</span><span id="line-2775"></span>
-<span class="source-line-no">2776</span><span id="line-2776"> /**</span>
-<span class="source-line-no">2777</span><span id="line-2777"> * Schedule closes on all user regions. Should be safe calling multiple times because it wont'</span>
-<span class="source-line-no">2778</span><span id="line-2778"> * close regions that are already closed or that are closing.</span>
-<span class="source-line-no">2779</span><span id="line-2779"> * @param abort Whether we're running an abort.</span>
-<span class="source-line-no">2780</span><span id="line-2780"> */</span>
-<span class="source-line-no">2781</span><span id="line-2781"> private void closeUserRegions(final boolean abort) {</span>
-<span class="source-line-no">2782</span><span id="line-2782"> this.onlineRegionsLock.writeLock().lock();</span>
-<span class="source-line-no">2783</span><span id="line-2783"> try {</span>
-<span class="source-line-no">2784</span><span id="line-2784"> for (Map.Entry<String, HRegion> e : this.onlineRegions.entrySet()) {</span>
-<span class="source-line-no">2785</span><span id="line-2785"> HRegion r = e.getValue();</span>
-<span class="source-line-no">2786</span><span id="line-2786"> if (!r.getRegionInfo().isMetaRegion() && r.isAvailable()) {</span>
-<span class="source-line-no">2787</span><span id="line-2787"> // Don't update zk with this close transition; pass false.</span>
-<span class="source-line-no">2788</span><span id="line-2788"> closeRegionIgnoreErrors(r.getRegionInfo(), abort);</span>
-<span class="source-line-no">2789</span><span id="line-2789"> }</span>
-<span class="source-line-no">2790</span><span id="line-2790"> }</span>
-<span class="source-line-no">2791</span><span id="line-2791"> } finally {</span>
-<span class="source-line-no">2792</span><span id="line-2792"> this.onlineRegionsLock.writeLock().unlock();</span>
-<span class="source-line-no">2793</span><span id="line-2793"> }</span>
-<span class="source-line-no">2794</span><span id="line-2794"> }</span>
-<span class="source-line-no">2795</span><span id="line-2795"></span>
-<span class="source-line-no">2796</span><span id="line-2796"> protected Map<String, HRegion> getOnlineRegions() {</span>
-<span class="source-line-no">2797</span><span id="line-2797"> return this.onlineRegions;</span>
+<span class="source-line-no">2655</span><span id="line-2655"> } finally {</span>
+<span class="source-line-no">2656</span><span id="line-2656"> if (interrupted) {</span>
+<span class="source-line-no">2657</span><span id="line-2657"> Thread.currentThread().interrupt();</span>
+<span class="source-line-no">2658</span><span id="line-2658"> }</span>
+<span class="source-line-no">2659</span><span id="line-2659"> }</span>
+<span class="source-line-no">2660</span><span id="line-2660"> this.rssStub = intRssStub;</span>
+<span class="source-line-no">2661</span><span id="line-2661"> this.lockStub = intLockStub;</span>
+<span class="source-line-no">2662</span><span id="line-2662"> return sn;</span>
+<span class="source-line-no">2663</span><span id="line-2663"> }</span>
+<span class="source-line-no">2664</span><span id="line-2664"></span>
+<span class="source-line-no">2665</span><span id="line-2665"> /**</span>
+<span class="source-line-no">2666</span><span id="line-2666"> * @return True if we should break loop because cluster is going down or this server has been</span>
+<span class="source-line-no">2667</span><span id="line-2667"> * stopped or hdfs has gone bad.</span>
+<span class="source-line-no">2668</span><span id="line-2668"> */</span>
+<span class="source-line-no">2669</span><span id="line-2669"> private boolean keepLooping() {</span>
+<span class="source-line-no">2670</span><span id="line-2670"> return !this.stopped && isClusterUp();</span>
+<span class="source-line-no">2671</span><span id="line-2671"> }</span>
+<span class="source-line-no">2672</span><span id="line-2672"></span>
+<span class="source-line-no">2673</span><span id="line-2673"> /*</span>
+<span class="source-line-no">2674</span><span id="line-2674"> * Let the master know we're here Run initialization using parameters passed us by the master.</span>
+<span class="source-line-no">2675</span><span id="line-2675"> * @return A Map of key/value configurations we got from the Master else null if we failed to</span>
+<span class="source-line-no">2676</span><span id="line-2676"> * register.</span>
+<span class="source-line-no">2677</span><span id="line-2677"> */</span>
+<span class="source-line-no">2678</span><span id="line-2678"> private RegionServerStartupResponse reportForDuty() throws IOException {</span>
+<span class="source-line-no">2679</span><span id="line-2679"> if (this.masterless) {</span>
+<span class="source-line-no">2680</span><span id="line-2680"> return RegionServerStartupResponse.getDefaultInstance();</span>
+<span class="source-line-no">2681</span><span id="line-2681"> }</span>
+<span class="source-line-no">2682</span><span id="line-2682"> ServerName masterServerName = createRegionServerStatusStub(true);</span>
+<span class="source-line-no">2683</span><span id="line-2683"> RegionServerStatusService.BlockingInterface rss = rssStub;</span>
+<span class="source-line-no">2684</span><span id="line-2684"> if (masterServerName == null || rss == null) {</span>
+<span class="source-line-no">2685</span><span id="line-2685"> return null;</span>
+<span class="source-line-no">2686</span><span id="line-2686"> }</span>
+<span class="source-line-no">2687</span><span id="line-2687"> RegionServerStartupResponse result = null;</span>
+<span class="source-line-no">2688</span><span id="line-2688"> try {</span>
+<span class="source-line-no">2689</span><span id="line-2689"> rpcServices.requestCount.reset();</span>
+<span class="source-line-no">2690</span><span id="line-2690"> rpcServices.rpcGetRequestCount.reset();</span>
+<span class="source-line-no">2691</span><span id="line-2691"> rpcServices.rpcScanRequestCount.reset();</span>
+<span class="source-line-no">2692</span><span id="line-2692"> rpcServices.rpcFullScanRequestCount.reset();</span>
+<span class="source-line-no">2693</span><span id="line-2693"> rpcServices.rpcMultiRequestCount.reset();</span>
+<span class="source-line-no">2694</span><span id="line-2694"> rpcServices.rpcMutateRequestCount.reset();</span>
+<span class="source-line-no">2695</span><span id="line-2695"> LOG.info("reportForDuty to master=" + masterServerName + " with port="</span>
+<span class="source-line-no">2696</span><span id="line-2696"> + rpcServices.getSocketAddress().getPort() + ", startcode=" + this.startcode);</span>
+<span class="source-line-no">2697</span><span id="line-2697"> long now = EnvironmentEdgeManager.currentTime();</span>
+<span class="source-line-no">2698</span><span id="line-2698"> int port = rpcServices.getSocketAddress().getPort();</span>
+<span class="source-line-no">2699</span><span id="line-2699"> RegionServerStartupRequest.Builder request = RegionServerStartupRequest.newBuilder();</span>
+<span class="source-line-no">2700</span><span id="line-2700"> if (!StringUtils.isBlank(useThisHostnameInstead)) {</span>
+<span class="source-line-no">2701</span><span id="line-2701"> request.setUseThisHostnameInstead(useThisHostnameInstead);</span>
+<span class="source-line-no">2702</span><span id="line-2702"> }</span>
+<span class="source-line-no">2703</span><span id="line-2703"> request.setPort(port);</span>
+<span class="source-line-no">2704</span><span id="line-2704"> request.setServerStartCode(this.startcode);</span>
+<span class="source-line-no">2705</span><span id="line-2705"> request.setServerCurrentTime(now);</span>
+<span class="source-line-no">2706</span><span id="line-2706"> result = rss.regionServerStartup(null, request.build());</span>
+<span class="source-line-no">2707</span><span id="line-2707"> } catch (ServiceException se) {</span>
+<span class="source-line-no">2708</span><span id="line-2708"> IOException ioe = ProtobufUtil.getRemoteException(se);</span>
+<span class="source-line-no">2709</span><span id="line-2709"> if (ioe instanceof ClockOutOfSyncException) {</span>
+<span class="source-line-no">2710</span><span id="line-2710"> LOG.error(HBaseMarkers.FATAL, "Master rejected startup because clock is out of sync", ioe);</span>
+<span class="source-line-no">2711</span><span id="line-2711"> // Re-throw IOE will cause RS to abort</span>
+<span class="source-line-no">2712</span><span id="line-2712"> throw ioe;</span>
+<span class="source-line-no">2713</span><span id="line-2713"> } else if (ioe instanceof DecommissionedHostRejectedException) {</span>
+<span class="source-line-no">2714</span><span id="line-2714"> LOG.error(HBaseMarkers.FATAL,</span>
+<span class="source-line-no">2715</span><span id="line-2715"> "Master rejected startup because the host is considered decommissioned", ioe);</span>
+<span class="source-line-no">2716</span><span id="line-2716"> // Re-throw IOE will cause RS to abort</span>
+<span class="source-line-no">2717</span><span id="line-2717"> throw ioe;</span>
+<span class="source-line-no">2718</span><span id="line-2718"> } else if (ioe instanceof ServerNotRunningYetException) {</span>
+<span class="source-line-no">2719</span><span id="line-2719"> LOG.debug("Master is not running yet");</span>
+<span class="source-line-no">2720</span><span id="line-2720"> } else {</span>
+<span class="source-line-no">2721</span><span id="line-2721"> LOG.warn("error telling master we are up", se);</span>
+<span class="source-line-no">2722</span><span id="line-2722"> }</span>
+<span class="source-line-no">2723</span><span id="line-2723"> rssStub = null;</span>
+<span class="source-line-no">2724</span><span id="line-2724"> }</span>
+<span class="source-line-no">2725</span><span id="line-2725"> return result;</span>
+<span class="source-line-no">2726</span><span id="line-2726"> }</span>
+<span class="source-line-no">2727</span><span id="line-2727"></span>
+<span class="source-line-no">2728</span><span id="line-2728"> @Override</span>
+<span class="source-line-no">2729</span><span id="line-2729"> public RegionStoreSequenceIds getLastSequenceId(byte[] encodedRegionName) {</span>
+<span class="source-line-no">2730</span><span id="line-2730"> try {</span>
+<span class="source-line-no">2731</span><span id="line-2731"> GetLastFlushedSequenceIdRequest req =</span>
+<span class="source-line-no">2732</span><span id="line-2732"> RequestConverter.buildGetLastFlushedSequenceIdRequest(encodedRegionName);</span>
+<span class="source-line-no">2733</span><span id="line-2733"> RegionServerStatusService.BlockingInterface rss = rssStub;</span>
+<span class="source-line-no">2734</span><span id="line-2734"> if (rss == null) { // Try to connect one more time</span>
+<span class="source-line-no">2735</span><span id="line-2735"> createRegionServerStatusStub();</span>
+<span class="source-line-no">2736</span><span id="line-2736"> rss = rssStub;</span>
+<span class="source-line-no">2737</span><span id="line-2737"> if (rss == null) {</span>
+<span class="source-line-no">2738</span><span id="line-2738"> // Still no luck, we tried</span>
+<span class="source-line-no">2739</span><span id="line-2739"> LOG.warn("Unable to connect to the master to check " + "the last flushed sequence id");</span>
+<span class="source-line-no">2740</span><span id="line-2740"> return RegionStoreSequenceIds.newBuilder().setLastFlushedSequenceId(HConstants.NO_SEQNUM)</span>
+<span class="source-line-no">2741</span><span id="line-2741"> .build();</span>
+<span class="source-line-no">2742</span><span id="line-2742"> }</span>
+<span class="source-line-no">2743</span><span id="line-2743"> }</span>
+<span class="source-line-no">2744</span><span id="line-2744"> GetLastFlushedSequenceIdResponse resp = rss.getLastFlushedSequenceId(null, req);</span>
+<span class="source-line-no">2745</span><span id="line-2745"> return RegionStoreSequenceIds.newBuilder()</span>
+<span class="source-line-no">2746</span><span id="line-2746"> .setLastFlushedSequenceId(resp.getLastFlushedSequenceId())</span>
+<span class="source-line-no">2747</span><span id="line-2747"> .addAllStoreSequenceId(resp.getStoreLastFlushedSequenceIdList()).build();</span>
+<span class="source-line-no">2748</span><span id="line-2748"> } catch (ServiceException e) {</span>
+<span class="source-line-no">2749</span><span id="line-2749"> LOG.warn("Unable to connect to the master to check the last flushed sequence id", e);</span>
+<span class="source-line-no">2750</span><span id="line-2750"> return RegionStoreSequenceIds.newBuilder().setLastFlushedSequenceId(HConstants.NO_SEQNUM)</span>
+<span class="source-line-no">2751</span><span id="line-2751"> .build();</span>
+<span class="source-line-no">2752</span><span id="line-2752"> }</span>
+<span class="source-line-no">2753</span><span id="line-2753"> }</span>
+<span class="source-line-no">2754</span><span id="line-2754"></span>
+<span class="source-line-no">2755</span><span id="line-2755"> /**</span>
+<span class="source-line-no">2756</span><span id="line-2756"> * Close meta region if we carry it</span>
+<span class="source-line-no">2757</span><span id="line-2757"> * @param abort Whether we're running an abort.</span>
+<span class="source-line-no">2758</span><span id="line-2758"> */</span>
+<span class="source-line-no">2759</span><span id="line-2759"> private void closeMetaTableRegions(final boolean abort) {</span>
+<span class="source-line-no">2760</span><span id="line-2760"> HRegion meta = null;</span>
+<span class="source-line-no">2761</span><span id="line-2761"> this.onlineRegionsLock.writeLock().lock();</span>
+<span class="source-line-no">2762</span><span id="line-2762"> try {</span>
+<span class="source-line-no">2763</span><span id="line-2763"> for (Map.Entry<String, HRegion> e : onlineRegions.entrySet()) {</span>
+<span class="source-line-no">2764</span><span id="line-2764"> RegionInfo hri = e.getValue().getRegionInfo();</span>
+<span class="source-line-no">2765</span><span id="line-2765"> if (hri.isMetaRegion()) {</span>
+<span class="source-line-no">2766</span><span id="line-2766"> meta = e.getValue();</span>
+<span class="source-line-no">2767</span><span id="line-2767"> }</span>
+<span class="source-line-no">2768</span><span id="line-2768"> if (meta != null) {</span>
+<span class="source-line-no">2769</span><span id="line-2769"> break;</span>
+<span class="source-line-no">2770</span><span id="line-2770"> }</span>
+<span class="source-line-no">2771</span><span id="line-2771"> }</span>
+<span class="source-line-no">2772</span><span id="line-2772"> } finally {</span>
+<span class="source-line-no">2773</span><span id="line-2773"> this.onlineRegionsLock.writeLock().unlock();</span>
+<span class="source-line-no">2774</span><span id="line-2774"> }</span>
+<span class="source-line-no">2775</span><span id="line-2775"> if (meta != null) {</span>
+<span class="source-line-no">2776</span><span id="line-2776"> closeRegionIgnoreErrors(meta.getRegionInfo(), abort);</span>
+<span class="source-line-no">2777</span><span id="line-2777"> }</span>
+<span class="source-line-no">2778</span><span id="line-2778"> }</span>
+<span class="source-line-no">2779</span><span id="line-2779"></span>
+<span class="source-line-no">2780</span><span id="line-2780"> /**</span>
+<span class="source-line-no">2781</span><span id="line-2781"> * Schedule closes on all user regions. Should be safe calling multiple times because it wont'</span>
+<span class="source-line-no">2782</span><span id="line-2782"> * close regions that are already closed or that are closing.</span>
+<span class="source-line-no">2783</span><span id="line-2783"> * @param abort Whether we're running an abort.</span>
+<span class="source-line-no">2784</span><span id="line-2784"> */</span>
+<span class="source-line-no">2785</span><span id="line-2785"> private void closeUserRegions(final boolean abort) {</span>
+<span class="source-line-no">2786</span><span id="line-2786"> this.onlineRegionsLock.writeLock().lock();</span>
+<span class="source-line-no">2787</span><span id="line-2787"> try {</span>
+<span class="source-line-no">2788</span><span id="line-2788"> for (Map.Entry<String, HRegion> e : this.onlineRegions.entrySet()) {</span>
+<span class="source-line-no">2789</span><span id="line-2789"> HRegion r = e.getValue();</span>
+<span class="source-line-no">2790</span><span id="line-2790"> if (!r.getRegionInfo().isMetaRegion() && r.isAvailable()) {</span>
+<span class="source-line-no">2791</span><span id="line-2791"> // Don't update zk with this close transition; pass false.</span>
+<span class="source-line-no">2792</span><span id="line-2792"> closeRegionIgnoreErrors(r.getRegionInfo(), abort);</span>
+<span class="source-line-no">2793</span><span id="line-2793"> }</span>
+<span class="source-line-no">2794</span><span id="line-2794"> }</span>
+<span class="source-line-no">2795</span><span id="line-2795"> } finally {</span>
+<span class="source-line-no">2796</span><span id="line-2796"> this.onlineRegionsLock.writeLock().unlock();</span>
+<span class="source-line-no">2797</span><span id="line-2797"> }</span>
<span class="source-line-no">2798</span><span id="line-2798"> }</span>
<span class="source-line-no">2799</span><span id="line-2799"></span>
-<span class="source-line-no">2800</span><span id="line-2800"> public int getNumberOfOnlineRegions() {</span>
-<span class="source-line-no">2801</span><span id="line-2801"> return this.onlineRegions.size();</span>
+<span class="source-line-no">2800</span><span id="line-2800"> protected Map<String, HRegion> getOnlineRegions() {</span>
+<span class="source-line-no">2801</span><span id="line-2801"> return this.onlineRegions;</span>
<span class="source-line-no">2802</span><span id="line-2802"> }</span>
<span class="source-line-no">2803</span><span id="line-2803"></span>
-<span class="source-line-no">2804</span><span id="line-2804"> /**</span>
-<span class="source-line-no">2805</span><span id="line-2805"> * For tests, web ui and metrics. This method will only work if HRegionServer is in the same JVM</span>
-<span class="source-line-no">2806</span><span id="line-2806"> * as client; HRegion cannot be serialized to cross an rpc.</span>
-<span class="source-line-no">2807</span><span id="line-2807"> */</span>
-<span class="source-line-no">2808</span><span id="line-2808"> public Collection<HRegion> getOnlineRegionsLocalContext() {</span>
-<span class="source-line-no">2809</span><span id="line-2809"> Collection<HRegion> regions = this.onlineRegions.values();</span>
-<span class="source-line-no">2810</span><span id="line-2810"> return Collections.unmodifiableCollection(regions);</span>
-<span class="source-line-no">2811</span><span id="line-2811"> }</span>
-<span class="source-line-no">2812</span><span id="line-2812"></span>
-<span class="source-line-no">2813</span><span id="line-2813"> @Override</span>
-<span class="source-line-no">2814</span><span id="line-2814"> public void addRegion(HRegion region) {</span>
-<span class="source-line-no">2815</span><span id="line-2815"> this.onlineRegions.put(region.getRegionInfo().getEncodedName(), region);</span>
-<span class="source-line-no">2816</span><span id="line-2816"> configurationManager.registerObserver(region);</span>
-<span class="source-line-no">2817</span><span id="line-2817"> }</span>
-<span class="source-line-no">2818</span><span id="line-2818"></span>
-<span class="source-line-no">2819</span><span id="line-2819"> private void addRegion(SortedMap<Long, Collection<HRegion>> sortedRegions, HRegion region,</span>
-<span class="source-line-no">2820</span><span id="line-2820"> long size) {</span>
-<span class="source-line-no">2821</span><span id="line-2821"> if (!sortedRegions.containsKey(size)) {</span>
-<span class="source-line-no">2822</span><span id="line-2822"> sortedRegions.put(size, new ArrayList<>());</span>
-<span class="source-line-no">2823</span><span id="line-2823"> }</span>
-<span class="source-line-no">2824</span><span id="line-2824"> sortedRegions.get(size).add(region);</span>
-<span class="source-line-no">2825</span><span id="line-2825"> }</span>
-<span class="source-line-no">2826</span><span id="line-2826"></span>
-<span class="source-line-no">2827</span><span id="line-2827"> /**</span>
-<span class="source-line-no">2828</span><span id="line-2828"> * @return A new Map of online regions sorted by region off-heap size with the first entry being</span>
-<span class="source-line-no">2829</span><span id="line-2829"> * the biggest.</span>
-<span class="source-line-no">2830</span><span id="line-2830"> */</span>
-<span class="source-line-no">2831</span><span id="line-2831"> SortedMap<Long, Collection<HRegion>> getCopyOfOnlineRegionsSortedByOffHeapSize() {</span>
-<span class="source-line-no">2832</span><span id="line-2832"> // we'll sort the regions in reverse</span>
-<span class="source-line-no">2833</span><span id="line-2833"> SortedMap<Long, Collection<HRegion>> sortedRegions = new TreeMap<>(Comparator.reverseOrder());</span>
-<span class="source-line-no">2834</span><span id="line-2834"> // Copy over all regions. Regions are sorted by size with biggest first.</span>
-<span class="source-line-no">2835</span><span id="line-2835"> for (HRegion region : this.onlineRegions.values()) {</span>
-<span class="source-line-no">2836</span><span id="line-2836"> addRegion(sortedRegions, region, region.getMemStoreOffHeapSize());</span>
-<span class="source-line-no">2837</span><span id="line-2837"> }</span>
-<span class="source-line-no">2838</span><span id="line-2838"> return sortedRegions;</span>
-<span class="source-line-no">2839</span><span id="line-2839"> }</span>
-<span class="source-line-no">2840</span><span id="line-2840"></span>
-<span class="source-line-no">2841</span><span id="line-2841"> /**</span>
-<span class="source-line-no">2842</span><span id="line-2842"> * @return A new Map of online regions sorted by region heap size with the first entry being the</span>
-<span class="source-line-no">2843</span><span id="line-2843"> * biggest.</span>
-<span class="source-line-no">2844</span><span id="line-2844"> */</span>
-<span class="source-line-no">2845</span><span id="line-2845"> SortedMap<Long, Collection<HRegion>> getCopyOfOnlineRegionsSortedByOnHeapSize() {</span>
-<span class="source-line-no">2846</span><span id="line-2846"> // we'll sort the regions in reverse</span>
-<span class="source-line-no">2847</span><span id="line-2847"> SortedMap<Long, Collection<HRegion>> sortedRegions = new TreeMap<>(Comparator.reverseOrder());</span>
-<span class="source-line-no">2848</span><span id="line-2848"> // Copy over all regions. Regions are sorted by size with biggest first.</span>
-<span class="source-line-no">2849</span><span id="line-2849"> for (HRegion region : this.onlineRegions.values()) {</span>
-<span class="source-line-no">2850</span><span id="line-2850"> addRegion(sortedRegions, region, region.getMemStoreHeapSize());</span>
-<span class="source-line-no">2851</span><span id="line-2851"> }</span>
-<span class="source-line-no">2852</span><span id="line-2852"> return sortedRegions;</span>
-<span class="source-line-no">2853</span><span id="line-2853"> }</span>
-<span class="source-line-no">2854</span><span id="line-2854"></span>
-<span class="source-line-no">2855</span><span id="line-2855"> /** Returns reference to FlushRequester */</span>
-<span class="source-line-no">2856</span><span id="line-2856"> @Override</span>
-<span class="source-line-no">2857</span><span id="line-2857"> public FlushRequester getFlushRequester() {</span>
-<span class="source-line-no">2858</span><span id="line-2858"> return this.cacheFlusher;</span>
-<span class="source-line-no">2859</span><span id="line-2859"> }</span>
-<span class="source-line-no">2860</span><span id="line-2860"></span>
-<span class="source-line-no">2861</span><span id="line-2861"> @Override</span>
-<span class="source-line-no">2862</span><span id="line-2862"> public CompactionRequester getCompactionRequestor() {</span>
-<span class="source-line-no">2863</span><span id="line-2863"> return this.compactSplitThread;</span>
-<span class="source-line-no">2864</span><span id="line-2864"> }</span>
-<span class="source-line-no">2865</span><span id="line-2865"></span>
-<span class="source-line-no">2866</span><span id="line-2866"> @Override</span>
-<span class="source-line-no">2867</span><span id="line-2867"> public LeaseManager getLeaseManager() {</span>
-<span class="source-line-no">2868</span><span id="line-2868"> return leaseManager;</span>
-<span class="source-line-no">2869</span><span id="line-2869"> }</span>
-<span class="source-line-no">2870</span><span id="line-2870"></span>
-<span class="source-line-no">2871</span><span id="line-2871"> /** Returns {@code true} when the data file system is available, {@code false} otherwise. */</span>
-<span class="source-line-no">2872</span><span id="line-2872"> boolean isDataFileSystemOk() {</span>
-<span class="source-line-no">2873</span><span id="line-2873"> return this.dataFsOk;</span>
-<span class="source-line-no">2874</span><span id="line-2874"> }</span>
-<span class="source-line-no">2875</span><span id="line-2875"></span>
-<span class="source-line-no">2876</span><span id="line-2876"> public RegionServerCoprocessorHost getRegionServerCoprocessorHost() {</span>
-<span class="source-line-no">2877</span><span id="line-2877"> return this.rsHost;</span>
+<span class="source-line-no">2804</span><span id="line-2804"> public int getNumberOfOnlineRegions() {</span>
+<span class="source-line-no">2805</span><span id="line-2805"> return this.onlineRegions.size();</span>
+<span class="source-line-no">2806</span><span id="line-2806"> }</span>
+<span class="source-line-no">2807</span><span id="line-2807"></span>
+<span class="source-line-no">2808</span><span id="line-2808"> /**</span>
+<span class="source-line-no">2809</span><span id="line-2809"> * For tests, web ui and metrics. This method will only work if HRegionServer is in the same JVM</span>
+<span class="source-line-no">2810</span><span id="line-2810"> * as client; HRegion cannot be serialized to cross an rpc.</span>
+<span class="source-line-no">2811</span><span id="line-2811"> */</span>
+<span class="source-line-no">2812</span><span id="line-2812"> public Collection<HRegion> getOnlineRegionsLocalContext() {</span>
+<span class="source-line-no">2813</span><span id="line-2813"> Collection<HRegion> regions = this.onlineRegions.values();</span>
+<span class="source-line-no">2814</span><span id="line-2814"> return Collections.unmodifiableCollection(regions);</span>
+<span class="source-line-no">2815</span><span id="line-2815"> }</span>
+<span class="source-line-no">2816</span><span id="line-2816"></span>
+<span class="source-line-no">2817</span><span id="line-2817"> @Override</span>
+<span class="source-line-no">2818</span><span id="line-2818"> public void addRegion(HRegion region) {</span>
+<span class="source-line-no">2819</span><span id="line-2819"> this.onlineRegions.put(region.getRegionInfo().getEncodedName(), region);</span>
+<span class="source-line-no">2820</span><span id="line-2820"> configurationManager.registerObserver(region);</span>
+<span class="source-line-no">2821</span><span id="line-2821"> }</span>
+<span class="source-line-no">2822</span><span id="line-2822"></span>
+<span class="source-line-no">2823</span><span id="line-2823"> private void addRegion(SortedMap<Long, Collection<HRegion>> sortedRegions, HRegion region,</span>
+<span class="source-line-no">2824</span><span id="line-2824"> long size) {</span>
+<span class="source-line-no">2825</span><span id="line-2825"> if (!sortedRegions.containsKey(size)) {</span>
+<span class="source-line-no">2826</span><span id="line-2826"> sortedRegions.put(size, new ArrayList<>());</span>
+<span class="source-line-no">2827</span><span id="line-2827"> }</span>
+<span class="source-line-no">2828</span><span id="line-2828"> sortedRegions.get(size).add(region);</span>
+<span class="source-line-no">2829</span><span id="line-2829"> }</span>
+<span class="source-line-no">2830</span><span id="line-2830"></span>
+<span class="source-line-no">2831</span><span id="line-2831"> /**</span>
+<span class="source-line-no">2832</span><span id="line-2832"> * @return A new Map of online regions sorted by region off-heap size with the first entry being</span>
+<span class="source-line-no">2833</span><span id="line-2833"> * the biggest.</span>
+<span class="source-line-no">2834</span><span id="line-2834"> */</span>
+<span class="source-line-no">2835</span><span id="line-2835"> SortedMap<Long, Collection<HRegion>> getCopyOfOnlineRegionsSortedByOffHeapSize() {</span>
+<span class="source-line-no">2836</span><span id="line-2836"> // we'll sort the regions in reverse</span>
+<span class="source-line-no">2837</span><span id="line-2837"> SortedMap<Long, Collection<HRegion>> sortedRegions = new TreeMap<>(Comparator.reverseOrder());</span>
+<span class="source-line-no">2838</span><span id="line-2838"> // Copy over all regions. Regions are sorted by size with biggest first.</span>
+<span class="source-line-no">2839</span><span id="line-2839"> for (HRegion region : this.onlineRegions.values()) {</span>
+<span class="source-line-no">2840</span><span id="line-2840"> addRegion(sortedRegions, region, region.getMemStoreOffHeapSize());</span>
+<span class="source-line-no">2841</span><span id="line-2841"> }</span>
+<span class="source-line-no">2842</span><span id="line-2842"> return sortedRegions;</span>
+<span class="source-line-no">2843</span><span id="line-2843"> }</span>
+<span class="source-line-no">2844</span><span id="line-2844"></span>
+<span class="source-line-no">2845</span><span id="line-2845"> /**</span>
+<span class="source-line-no">2846</span><span id="line-2846"> * @return A new Map of online regions sorted by region heap size with the first entry being the</span>
+<span class="source-line-no">2847</span><span id="line-2847"> * biggest.</span>
+<span class="source-line-no">2848</span><span id="line-2848"> */</span>
+<span class="source-line-no">2849</span><span id="line-2849"> SortedMap<Long, Collection<HRegion>> getCopyOfOnlineRegionsSortedByOnHeapSize() {</span>
+<span class="source-line-no">2850</span><span id="line-2850"> // we'll sort the regions in reverse</span>
+<span class="source-line-no">2851</span><span id="line-2851"> SortedMap<Long, Collection<HRegion>> sortedRegions = new TreeMap<>(Comparator.reverseOrder());</span>
+<span class="source-line-no">2852</span><span id="line-2852"> // Copy over all regions. Regions are sorted by size with biggest first.</span>
+<span class="source-line-no">2853</span><span id="line-2853"> for (HRegion region : this.onlineRegions.values()) {</span>
+<span class="source-line-no">2854</span><span id="line-2854"> addRegion(sortedRegions, region, region.getMemStoreHeapSize());</span>
+<span class="source-line-no">2855</span><span id="line-2855"> }</span>
+<span class="source-line-no">2856</span><span id="line-2856"> return sortedRegions;</span>
+<span class="source-line-no">2857</span><span id="line-2857"> }</span>
+<span class="source-line-no">2858</span><span id="line-2858"></span>
+<span class="source-line-no">2859</span><span id="line-2859"> /** Returns reference to FlushRequester */</span>
+<span class="source-line-no">2860</span><span id="line-2860"> @Override</span>
+<span class="source-line-no">2861</span><span id="line-2861"> public FlushRequester getFlushRequester() {</span>
+<span class="source-line-no">2862</span><span id="line-2862"> return this.cacheFlusher;</span>
+<span class="source-line-no">2863</span><span id="line-2863"> }</span>
+<span class="source-line-no">2864</span><span id="line-2864"></span>
+<span class="source-line-no">2865</span><span id="line-2865"> @Override</span>
+<span class="source-line-no">2866</span><span id="line-2866"> public CompactionRequester getCompactionRequestor() {</span>
+<span class="source-line-no">2867</span><span id="line-2867"> return this.compactSplitThread;</span>
+<span class="source-line-no">2868</span><span id="line-2868"> }</span>
+<span class="source-line-no">2869</span><span id="line-2869"></span>
+<span class="source-line-no">2870</span><span id="line-2870"> @Override</span>
+<span class="source-line-no">2871</span><span id="line-2871"> public LeaseManager getLeaseManager() {</span>
+<span class="source-line-no">2872</span><span id="line-2872"> return leaseManager;</span>
+<span class="source-line-no">2873</span><span id="line-2873"> }</span>
+<span class="source-line-no">2874</span><span id="line-2874"></span>
+<span class="source-line-no">2875</span><span id="line-2875"> /** Returns {@code true} when the data file system is available, {@code false} otherwise. */</span>
+<span class="source-line-no">2876</span><span id="line-2876"> boolean isDataFileSystemOk() {</span>
+<span class="source-line-no">2877</span><span id="line-2877"> return this.dataFsOk;</span>
<span class="source-line-no">2878</span><span id="line-2878"> }</span>
<span class="source-line-no">2879</span><span id="line-2879"></span>
-<span class="source-line-no">2880</span><span id="line-2880"> @Override</span>
-<span class="source-line-no">2881</span><span id="line-2881"> public ConcurrentMap<byte[], Boolean> getRegionsInTransitionInRS() {</span>
-<span class="source-line-no">2882</span><span id="line-2882"> return this.regionsInTransitionInRS;</span>
-<span class="source-line-no">2883</span><span id="line-2883"> }</span>
-<span class="source-line-no">2884</span><span id="line-2884"></span>
-<span class="source-line-no">2885</span><span id="line-2885"> @Override</span>
-<span class="source-line-no">2886</span><span id="line-2886"> public RegionServerRpcQuotaManager getRegionServerRpcQuotaManager() {</span>
-<span class="source-line-no">2887</span><span id="line-2887"> return rsQuotaManager;</span>
-<span class="source-line-no">2888</span><span id="line-2888"> }</span>
-<span class="source-line-no">2889</span><span id="line-2889"></span>
-<span class="source-line-no">2890</span><span id="line-2890"> //</span>
-<span class="source-line-no">2891</span><span id="line-2891"> // Main program and support routines</span>
-<span class="source-line-no">2892</span><span id="line-2892"> //</span>
-<span class="source-line-no">2893</span><span id="line-2893"> /**</span>
-<span class="source-line-no">2894</span><span id="line-2894"> * Load the replication executorService objects, if any</span>
-<span class="source-line-no">2895</span><span id="line-2895"> */</span>
-<span class="source-line-no">2896</span><span id="line-2896"> private static void createNewReplicationInstance(Configuration conf, HRegionServer server,</span>
-<span class="source-line-no">2897</span><span id="line-2897"> FileSystem walFs, Path walDir, Path oldWALDir, WALFactory walFactory) throws IOException {</span>
-<span class="source-line-no">2898</span><span id="line-2898"> // read in the name of the source replication class from the config file.</span>
-<span class="source-line-no">2899</span><span id="line-2899"> String sourceClassname = conf.get(HConstants.REPLICATION_SOURCE_SERVICE_CLASSNAME,</span>
-<span class="source-line-no">2900</span><span id="line-2900"> HConstants.REPLICATION_SERVICE_CLASSNAME_DEFAULT);</span>
-<span class="source-line-no">2901</span><span id="line-2901"></span>
-<span class="source-line-no">2902</span><span id="line-2902"> // read in the name of the sink replication class from the config file.</span>
-<span class="source-line-no">2903</span><span id="line-2903"> String sinkClassname = conf.get(HConstants.REPLICATION_SINK_SERVICE_CLASSNAME,</span>
-<span class="source-line-no">2904</span><span id="line-2904"> HConstants.REPLICATION_SINK_SERVICE_CLASSNAME_DEFAULT);</span>
+<span class="source-line-no">2880</span><span id="line-2880"> public RegionServerCoprocessorHost getRegionServerCoprocessorHost() {</span>
+<span class="source-line-no">2881</span><span id="line-2881"> return this.rsHost;</span>
+<span class="source-line-no">2882</span><span id="line-2882"> }</span>
+<span class="source-line-no">2883</span><span id="line-2883"></span>
+<span class="source-line-no">2884</span><span id="line-2884"> @Override</span>
+<span class="source-line-no">2885</span><span id="line-2885"> public ConcurrentMap<byte[], Boolean> getRegionsInTransitionInRS() {</span>
+<span class="source-line-no">2886</span><span id="line-2886"> return this.regionsInTransitionInRS;</span>
+<span class="source-line-no">2887</span><span id="line-2887"> }</span>
+<span class="source-line-no">2888</span><span id="line-2888"></span>
+<span class="source-line-no">2889</span><span id="line-2889"> @Override</span>
+<span class="source-line-no">2890</span><span id="line-2890"> public RegionServerRpcQuotaManager getRegionServerRpcQuotaManager() {</span>
+<span class="source-line-no">2891</span><span id="line-2891"> return rsQuotaManager;</span>
+<span class="source-line-no">2892</span><span id="line-2892"> }</span>
+<span class="source-line-no">2893</span><span id="line-2893"></span>
+<span class="source-line-no">2894</span><span id="line-2894"> //</span>
+<span class="source-line-no">2895</span><span id="line-2895"> // Main program and support routines</span>
+<span class="source-line-no">2896</span><span id="line-2896"> //</span>
+<span class="source-line-no">2897</span><span id="line-2897"> /**</span>
+<span class="source-line-no">2898</span><span id="line-2898"> * Load the replication executorService objects, if any</span>
+<span class="source-line-no">2899</span><span id="line-2899"> */</span>
+<span class="source-line-no">2900</span><span id="line-2900"> private static void createNewReplicationInstance(Configuration conf, HRegionServer server,</span>
+<span class="source-line-no">2901</span><span id="line-2901"> FileSystem walFs, Path walDir, Path oldWALDir, WALFactory walFactory) throws IOException {</span>
+<span class="source-line-no">2902</span><span id="line-2902"> // read in the name of the source replication class from the config file.</span>
+<span class="source-line-no">2903</span><span id="line-2903"> String sourceClassname = conf.get(HConstants.REPLICATION_SOURCE_SERVICE_CLASSNAME,</span>
+<span class="source-line-no">2904</span><span id="line-2904"> HConstants.REPLICATION_SERVICE_CLASSNAME_DEFAULT);</span>
<span class="source-line-no">2905</span><span id="line-2905"></span>
-<span class="source-line-no">2906</span><span id="line-2906"> // If both the sink and the source class names are the same, then instantiate</span>
-<span class="source-line-no">2907</span><span id="line-2907"> // only one object.</span>
-<span class="source-line-no">2908</span><span id="line-2908"> if (sourceClassname.equals(sinkClassname)) {</span>
-<span class="source-line-no">2909</span><span id="line-2909"> server.replicationSourceHandler = newReplicationInstance(sourceClassname,</span>
-<span class="source-line-no">2910</span><span id="line-2910"> ReplicationSourceService.class, conf, server, walFs, walDir, oldWALDir, walFactory);</span>
-<span class="source-line-no">2911</span><span id="line-2911"> server.replicationSinkHandler = (ReplicationSinkService) server.replicationSourceHandler;</span>
-<span class="source-line-no">2912</span><span id="line-2912"> server.sameReplicationSourceAndSink = true;</span>
-<span class="source-line-no">2913</span><span id="line-2913"> } else {</span>
-<span class="source-line-no">2914</span><span id="line-2914"> server.replicationSourceHandler = newReplicationInstance(sourceClassname,</span>
-<span class="source-line-no">2915</span><span id="line-2915"> ReplicationSourceService.class, conf, server, walFs, walDir, oldWALDir, walFactory);</span>
-<span class="source-line-no">2916</span><span id="line-2916"> server.replicationSinkHandler = newReplicationInstance(sinkClassname,</span>
-<span class="source-line-no">2917</span><span id="line-2917"> ReplicationSinkService.class, conf, server, walFs, walDir, oldWALDir, walFactory);</span>
-<span class="source-line-no">2918</span><span id="line-2918"> server.sameReplicationSourceAndSink = false;</span>
-<span class="source-line-no">2919</span><span id="line-2919"> }</span>
-<span class="source-line-no">2920</span><span id="line-2920"> }</span>
-<span class="source-line-no">2921</span><span id="line-2921"></span>
-<span class="source-line-no">2922</span><span id="line-2922"> private static <T extends ReplicationService> T newReplicationInstance(String classname,</span>
-<span class="source-line-no">2923</span><span id="line-2923"> Class<T> xface, Configuration conf, HRegionServer server, FileSystem walFs, Path logDir,</span>
-<span class="source-line-no">2924</span><span id="line-2924"> Path oldLogDir, WALFactory walFactory) throws IOException {</span>
-<span class="source-line-no">2925</span><span id="line-2925"> final Class<? extends T> clazz;</span>
-<span class="source-line-no">2926</span><span id="line-2926"> try {</span>
-<span class="source-line-no">2927</span><span id="line-2927"> ClassLoader classLoader = Thread.currentThread().getContextClassLoader();</span>
-<span class="source-line-no">2928</span><span id="line-2928"> clazz = Class.forName(classname, true, classLoader).asSubclass(xface);</span>
-<span class="source-line-no">2929</span><span id="line-2929"> } catch (java.lang.ClassNotFoundException nfe) {</span>
-<span class="source-line-no">2930</span><span id="line-2930"> throw new IOException("Could not find class for " + classname);</span>
-<span class="source-line-no">2931</span><span id="line-2931"> }</span>
-<span class="source-line-no">2932</span><span id="line-2932"> T service = ReflectionUtils.newInstance(clazz, conf);</span>
-<span class="source-line-no">2933</span><span id="line-2933"> service.initialize(server, walFs, logDir, oldLogDir, walFactory);</span>
-<span class="source-line-no">2934</span><span id="line-2934"> return service;</span>
-<span class="source-line-no">2935</span><span id="line-2935"> }</span>
-<span class="source-line-no">2936</span><span id="line-2936"></span>
-<span class="source-line-no">2937</span><span id="line-2937"> public Map<String, ReplicationStatus> getWalGroupsReplicationStatus() {</span>
-<span class="source-line-no">2938</span><span id="line-2938"> Map<String, ReplicationStatus> walGroupsReplicationStatus = new TreeMap<>();</span>
-<span class="source-line-no">2939</span><span id="line-2939"> if (!this.isOnline()) {</span>
-<span class="source-line-no">2940</span><span id="line-2940"> return walGroupsReplicationStatus;</span>
-<span class="source-line-no">2941</span><span id="line-2941"> }</span>
-<span class="source-line-no">2942</span><span id="line-2942"> List<ReplicationSourceInterface> allSources = new ArrayList<>();</span>
-<span class="source-line-no">2943</span><span id="line-2943"> allSources.addAll(replicationSourceHandler.getReplicationManager().getSources());</span>
-<span class="source-line-no">2944</span><span id="line-2944"> allSources.addAll(replicationSourceHandler.getReplicationManager().getOldSources());</span>
-<span class="source-line-no">2945</span><span id="line-2945"> for (ReplicationSourceInterface source : allSources) {</span>
-<span class="source-line-no">2946</span><span id="line-2946"> walGroupsReplicationStatus.putAll(source.getWalGroupStatus());</span>
-<span class="source-line-no">2947</span><span id="line-2947"> }</span>
-<span class="source-line-no">2948</span><span id="line-2948"> return walGroupsReplicationStatus;</span>
-<span class="source-line-no">2949</span><span id="line-2949"> }</span>
-<span class="source-line-no">2950</span><span id="line-2950"></span>
-<span class="source-line-no">2951</span><span id="line-2951"> /**</span>
-<span class="source-line-no">2952</span><span id="line-2952"> * Utility for constructing an instance of the passed HRegionServer class.</span>
-<span class="source-line-no">2953</span><span id="line-2953"> */</span>
-<span class="source-line-no">2954</span><span id="line-2954"> static HRegionServer constructRegionServer(final Class<? extends HRegionServer> regionServerClass,</span>
-<span class="source-line-no">2955</span><span id="line-2955"> final Configuration conf) {</span>
-<span class="source-line-no">2956</span><span id="line-2956"> try {</span>
-<span class="source-line-no">2957</span><span id="line-2957"> Constructor<? extends HRegionServer> c =</span>
-<span class="source-line-no">2958</span><span id="line-2958"> regionServerClass.getConstructor(Configuration.class);</span>
-<span class="source-line-no">2959</span><span id="line-2959"> return c.newInstance(conf);</span>
-<span class="source-line-no">2960</span><span id="line-2960"> } catch (Exception e) {</span>
-<span class="source-line-no">2961</span><span id="line-2961"> throw new RuntimeException(</span>
-<span class="source-line-no">2962</span><span id="line-2962"> "Failed construction of " + "Regionserver: " + regionServerClass.toString(), e);</span>
-<span class="source-line-no">2963</span><span id="line-2963"> }</span>
-<span class="source-line-no">2964</span><span id="line-2964"> }</span>
-<span class="source-line-no">2965</span><span id="line-2965"></span>
-<span class="source-line-no">2966</span><span id="line-2966"> /**</span>
-<span class="source-line-no">2967</span><span id="line-2967"> * @see org.apache.hadoop.hbase.regionserver.HRegionServerCommandLine</span>
-<span class="source-line-no">2968</span><span id="line-2968"> */</span>
-<span class="source-line-no">2969</span><span id="line-2969"> public static void main(String[] args) {</span>
-<span class="source-line-no">2970</span><span id="line-2970"> LOG.info("STARTING executorService " + HRegionServer.class.getSimpleName());</span>
-<span class="source-line-no">2971</span><span id="line-2971"> VersionInfo.logVersion();</span>
-<span class="source-line-no">2972</span><span id="line-2972"> Configuration conf = HBaseConfiguration.create();</span>
-<span class="source-line-no">2973</span><span id="line-2973"> @SuppressWarnings("unchecked")</span>
-<span class="source-line-no">2974</span><span id="line-2974"> Class<? extends HRegionServer> regionServerClass = (Class<? extends HRegionServer>) conf</span>
-<span class="source-line-no">2975</span><span id="line-2975"> .getClass(HConstants.REGION_SERVER_IMPL, HRegionServer.class);</span>
-<span class="source-line-no">2976</span><span id="line-2976"></span>
-<span class="source-line-no">2977</span><span id="line-2977"> new HRegionServerCommandLine(regionServerClass).doMain(args);</span>
-<span class="source-line-no">2978</span><span id="line-2978"> }</span>
-<span class="source-line-no">2979</span><span id="line-2979"></span>
-<span class="source-line-no">2980</span><span id="line-2980"> /**</span>
-<span class="source-line-no">2981</span><span id="line-2981"> * Gets the online regions of the specified table. This method looks at the in-memory</span>
-<span class="source-line-no">2982</span><span id="line-2982"> * onlineRegions. It does not go to <code>hbase:meta</code>. Only returns <em>online</em> regions.</span>
-<span class="source-line-no">2983</span><span id="line-2983"> * If a region on this table has been closed during a disable, etc., it will not be included in</span>
-<span class="source-line-no">2984</span><span id="line-2984"> * the returned list. So, the returned list may not necessarily be ALL regions in this table, its</span>
-<span class="source-line-no">2985</span><span id="line-2985"> * all the ONLINE regions in the table.</span>
-<span class="source-line-no">2986</span><span id="line-2986"> * @param tableName table to limit the scope of the query</span>
-<span class="source-line-no">2987</span><span id="line-2987"> * @return Online regions from <code>tableName</code></span>
-<span class="source-line-no">2988</span><span id="line-2988"> */</span>
-<span class="source-line-no">2989</span><span id="line-2989"> @Override</span>
-<span class="source-line-no">2990</span><span id="line-2990"> public List<HRegion> getRegions(TableName tableName) {</span>
-<span class="source-line-no">2991</span><span id="line-2991"> List<HRegion> tableRegions = new ArrayList<>();</span>
-<span class="source-line-no">2992</span><span id="line-2992"> synchronized (this.onlineRegions) {</span>
-<span class="source-line-no">2993</span><span id="line-2993"> for (HRegion region : this.onlineRegions.values()) {</span>
-<span class="source-line-no">2994</span><span id="line-2994"> RegionInfo regionInfo = region.getRegionInfo();</span>
-<span class="source-line-no">2995</span><span id="line-2995"> if (regionInfo.getTable().equals(tableName)) {</span>
-<span class="source-line-no">2996</span><span id="line-2996"> tableRegions.add(region);</span>
-<span class="source-line-no">2997</span><span id="line-2997"> }</span>
-<span class="source-line-no">2998</span><span id="line-2998"> }</span>
-<span class="source-line-no">2999</span><span id="line-2999"> }</span>
-<span class="source-line-no">3000</span><span id="line-3000"> return tableRegions;</span>
-<span class="source-line-no">3001</span><span id="line-3001"> }</span>
-<span class="source-line-no">3002</span><span id="line-3002"></span>
-<span class="source-line-no">3003</span><span id="line-3003"> @Override</span>
-<span class="source-line-no">3004</span><span id="line-3004"> public List<HRegion> getRegions() {</span>
-<span class="source-line-no">3005</span><span id="line-3005"> List<HRegion> allRegions;</span>
-<span class="source-line-no">3006</span><span id="line-3006"> synchronized (this.onlineRegions) {</span>
-<span class="source-line-no">3007</span><span id="line-3007"> // Return a clone copy of the onlineRegions</span>
-<span class="source-line-no">3008</span><span id="line-3008"> allRegions = new ArrayList<>(onlineRegions.values());</span>
-<span class="source-line-no">3009</span><span id="line-3009"> }</span>
-<span class="source-line-no">3010</span><span id="line-3010"> return allRegions;</span>
-<span class="source-line-no">3011</span><span id="line-3011"> }</span>
-<span class="source-line-no">3012</span><span id="line-3012"></span>
-<span class="source-line-no">3013</span><span id="line-3013"> /**</span>
-<span class="source-line-no">3014</span><span id="line-3014"> * Gets the online tables in this RS. This method looks at the in-memory onlineRegions.</span>
-<span class="source-line-no">3015</span><span id="line-3015"> * @return all the online tables in this RS</span>
-<span class="source-line-no">3016</span><span id="line-3016"> */</span>
-<span class="source-line-no">3017</span><span id="line-3017"> public Set<TableName> getOnlineTables() {</span>
-<span class="source-line-no">3018</span><span id="line-3018"> Set<TableName> tables = new HashSet<>();</span>
-<span class="source-line-no">3019</span><span id="line-3019"> synchronized (this.onlineRegions) {</span>
-<span class="source-line-no">3020</span><span id="line-3020"> for (Region region : this.onlineRegions.values()) {</span>
-<span class="source-line-no">3021</span><span id="line-3021"> tables.add(region.getTableDescriptor().getTableName());</span>
-<span class="source-line-no">3022</span><span id="line-3022"> }</span>
-<span class="source-line-no">3023</span><span id="line-3023"> }</span>
-<span class="source-line-no">3024</span><span id="line-3024"> return tables;</span>
-<span class="source-line-no">3025</span><span id="line-3025"> }</span>
-<span class="source-line-no">3026</span><span id="line-3026"></span>
-<span class="source-line-no">3027</span><span id="line-3027"> public String[] getRegionServerCoprocessors() {</span>
-<span class="source-line-no">3028</span><span id="line-3028"> TreeSet<String> coprocessors = new TreeSet<>();</span>
-<span class="source-line-no">3029</span><span id="line-3029"> try {</span>
-<span class="source-line-no">3030</span><span id="line-3030"> coprocessors.addAll(getWAL(null).getCoprocessorHost().getCoprocessors());</span>
-<span class="source-line-no">3031</span><span id="line-3031"> } catch (IOException exception) {</span>
-<span class="source-line-no">3032</span><span id="line-3032"> LOG.warn("Exception attempting to fetch wal coprocessor information for the common wal; "</span>
-<span class="source-line-no">3033</span><span id="line-3033"> + "skipping.");</span>
-<span class="source-line-no">3034</span><span id="line-3034"> LOG.debug("Exception details for failure to fetch wal coprocessor information.", exception);</span>
-<span class="source-line-no">3035</span><span id="line-3035"> }</span>
-<span class="source-line-no">3036</span><span id="line-3036"> Collection<HRegion> regions = getOnlineRegionsLocalContext();</span>
-<span class="source-line-no">3037</span><span id="line-3037"> for (HRegion region : regions) {</span>
-<span class="source-line-no">3038</span><span id="line-3038"> coprocessors.addAll(region.getCoprocessorHost().getCoprocessors());</span>
-<span class="source-line-no">3039</span><span id="line-3039"> try {</span>
-<span class="source-line-no">3040</span><span id="line-3040"> coprocessors.addAll(getWAL(region.getRegionInfo()).getCoprocessorHost().getCoprocessors());</span>
-<span class="source-line-no">3041</span><span id="line-3041"> } catch (IOException exception) {</span>
-<span class="source-line-no">3042</span><span id="line-3042"> LOG.warn("Exception attempting to fetch wal coprocessor information for region " + region</span>
-<span class="source-line-no">3043</span><span id="line-3043"> + "; skipping.");</span>
-<span class="source-line-no">3044</span><span id="line-3044"> LOG.debug("Exception details for failure to fetch wal coprocessor information.", exception);</span>
-<span class="source-line-no">3045</span><span id="line-3045"> }</span>
-<span class="source-line-no">3046</span><span id="line-3046"> }</span>
-<span class="source-line-no">3047</span><span id="line-3047"> coprocessors.addAll(rsHost.getCoprocessors());</span>
-<span class="source-line-no">3048</span><span id="line-3048"> return coprocessors.toArray(new String[0]);</span>
-<span class="source-line-no">3049</span><span id="line-3049"> }</span>
-<span class="source-line-no">3050</span><span id="line-3050"></span>
-<span class="source-line-no">3051</span><span id="line-3051"> /**</span>
-<span class="source-line-no">3052</span><span id="line-3052"> * Try to close the region, logs a warning on failure but continues.</span>
-<span class="source-line-no">3053</span><span id="line-3053"> * @param region Region to close</span>
-<span class="source-line-no">3054</span><span id="line-3054"> */</span>
-<span class="source-line-no">3055</span><span id="line-3055"> private void closeRegionIgnoreErrors(RegionInfo region, final boolean abort) {</span>
-<span class="source-line-no">3056</span><span id="line-3056"> try {</span>
-<span class="source-line-no">3057</span><span id="line-3057"> if (!closeRegion(region.getEncodedName(), abort, null)) {</span>
-<span class="source-line-no">3058</span><span id="line-3058"> LOG</span>
-<span class="source-line-no">3059</span><span id="line-3059"> .warn("Failed to close " + region.getRegionNameAsString() + " - ignoring and continuing");</span>
-<span class="source-line-no">3060</span><span id="line-3060"> }</span>
-<span class="source-line-no">3061</span><span id="line-3061"> } catch (IOException e) {</span>
-<span class="source-line-no">3062</span><span id="line-3062"> LOG.warn("Failed to close " + region.getRegionNameAsString() + " - ignoring and continuing",</span>
-<span class="source-line-no">3063</span><span id="line-3063"> e);</span>
-<span class="source-line-no">3064</span><span id="line-3064"> }</span>
-<span class="source-line-no">3065</span><span id="line-3065"> }</span>
-<span class="source-line-no">3066</span><span id="line-3066"></span>
-<span class="source-line-no">3067</span><span id="line-3067"> /**</span>
-<span class="source-line-no">3068</span><span id="line-3068"> * Close asynchronously a region, can be called from the master or internally by the regionserver</span>
-<span class="source-line-no">3069</span><span id="line-3069"> * when stopping. If called from the master, the region will update the status.</span>
-<span class="source-line-no">3070</span><span id="line-3070"> * <p></span>
-<span class="source-line-no">3071</span><span id="line-3071"> * If an opening was in progress, this method will cancel it, but will not start a new close. The</span>
-<span class="source-line-no">3072</span><span id="line-3072"> * coprocessors are not called in this case. A NotServingRegionException exception is thrown.</span>
-<span class="source-line-no">3073</span><span id="line-3073"> * </p></span>
+<span class="source-line-no">2906</span><span id="line-2906"> // read in the name of the sink replication class from the config file.</span>
+<span class="source-line-no">2907</span><span id="line-2907"> String sinkClassname = conf.get(HConstants.REPLICATION_SINK_SERVICE_CLASSNAME,</span>
+<span class="source-line-no">2908</span><span id="line-2908"> HConstants.REPLICATION_SINK_SERVICE_CLASSNAME_DEFAULT);</span>
+<span class="source-line-no">2909</span><span id="line-2909"></span>
+<span class="source-line-no">2910</span><span id="line-2910"> // If both the sink and the source class names are the same, then instantiate</span>
+<span class="source-line-no">2911</span><span id="line-2911"> // only one object.</span>
+<span class="source-line-no">2912</span><span id="line-2912"> if (sourceClassname.equals(sinkClassname)) {</span>
+<span class="source-line-no">2913</span><span id="line-2913"> server.replicationSourceHandler = newReplicationInstance(sourceClassname,</span>
+<span class="source-line-no">2914</span><span id="line-2914"> ReplicationSourceService.class, conf, server, walFs, walDir, oldWALDir, walFactory);</span>
+<span class="source-line-no">2915</span><span id="line-2915"> server.replicationSinkHandler = (ReplicationSinkService) server.replicationSourceHandler;</span>
+<span class="source-line-no">2916</span><span id="line-2916"> server.sameReplicationSourceAndSink = true;</span>
+<span class="source-line-no">2917</span><span id="line-2917"> } else {</span>
+<span class="source-line-no">2918</span><span id="line-2918"> server.replicationSourceHandler = newReplicationInstance(sourceClassname,</span>
+<span class="source-line-no">2919</span><span id="line-2919"> ReplicationSourceService.class, conf, server, walFs, walDir, oldWALDir, walFactory);</span>
+<span class="source-line-no">2920</span><span id="line-2920"> server.replicationSinkHandler = newReplicationInstance(sinkClassname,</span>
+<span class="source-line-no">2921</span><span id="line-2921"> ReplicationSinkService.class, conf, server, walFs, walDir, oldWALDir, walFactory);</span>
+<span class="source-line-no">2922</span><span id="line-2922"> server.sameReplicationSourceAndSink = false;</span>
+<span class="source-line-no">2923</span><span id="line-2923"> }</span>
+<span class="source-line-no">2924</span><span id="line-2924"> }</span>
+<span class="source-line-no">2925</span><span id="line-2925"></span>
+<span class="source-line-no">2926</span><span id="line-2926"> private static <T extends ReplicationService> T newReplicationInstance(String classname,</span>
+<span class="source-line-no">2927</span><span id="line-2927"> Class<T> xface, Configuration conf, HRegionServer server, FileSystem walFs, Path logDir,</span>
+<span class="source-line-no">2928</span><span id="line-2928"> Path oldLogDir, WALFactory walFactory) throws IOException {</span>
+<span class="source-line-no">2929</span><span id="line-2929"> final Class<? extends T> clazz;</span>
+<span class="source-line-no">2930</span><span id="line-2930"> try {</span>
+<span class="source-line-no">2931</span><span id="line-2931"> ClassLoader classLoader = Thread.currentThread().getContextClassLoader();</span>
+<span class="source-line-no">2932</span><span id="line-2932"> clazz = Class.forName(classname, true, classLoader).asSubclass(xface);</span>
+<span class="source-line-no">2933</span><span id="line-2933"> } catch (java.lang.ClassNotFoundException nfe) {</span>
+<span class="source-line-no">2934</span><span id="line-2934"> throw new IOException("Could not find class for " + classname);</span>
+<span class="source-line-no">2935</span><span id="line-2935"> }</span>
+<span class="source-line-no">2936</span><span id="line-2936"> T service = ReflectionUtils.newInstance(clazz, conf);</span>
+<span class="source-line-no">2937</span><span id="line-2937"> service.initialize(server, walFs, logDir, oldLogDir, walFactory);</span>
+<span class="source-line-no">2938</span><span id="line-2938"> return service;</span>
+<span class="source-line-no">2939</span><span id="line-2939"> }</span>
+<span class="source-line-no">2940</span><span id="line-2940"></span>
+<span class="source-line-no">2941</span><span id="line-2941"> public Map<String, ReplicationStatus> getWalGroupsReplicationStatus() {</span>
+<span class="source-line-no">2942</span><span id="line-2942"> Map<String, ReplicationStatus> walGroupsReplicationStatus = new TreeMap<>();</span>
+<span class="source-line-no">2943</span><span id="line-2943"> if (!this.isOnline()) {</span>
+<span class="source-line-no">2944</span><span id="line-2944"> return walGroupsReplicationStatus;</span>
+<span class="source-line-no">2945</span><span id="line-2945"> }</span>
+<span class="source-line-no">2946</span><span id="line-2946"> List<ReplicationSourceInterface> allSources = new ArrayList<>();</span>
+<span class="source-line-no">2947</span><span id="line-2947"> allSources.addAll(replicationSourceHandler.getReplicationManager().getSources());</span>
+<span class="source-line-no">2948</span><span id="line-2948"> allSources.addAll(replicationSourceHandler.getReplicationManager().getOldSources());</span>
+<span class="source-line-no">2949</span><span id="line-2949"> for (ReplicationSourceInterface source : allSources) {</span>
+<span class="source-line-no">2950</span><span id="line-2950"> walGroupsReplicationStatus.putAll(source.getWalGroupStatus());</span>
+<span class="source-line-no">2951</span><span id="line-2951"> }</span>
+<span class="source-line-no">2952</span><span id="line-2952"> return walGroupsReplicationStatus;</span>
+<span class="source-line-no">2953</span><span id="line-2953"> }</span>
+<span class="source-line-no">2954</span><span id="line-2954"></span>
+<span class="source-line-no">2955</span><span id="line-2955"> /**</span>
+<span class="source-line-no">2956</span><span id="line-2956"> * Utility for constructing an instance of the passed HRegionServer class.</span>
+<span class="source-line-no">2957</span><span id="line-2957"> */</span>
+<span class="source-line-no">2958</span><span id="line-2958"> static HRegionServer constructRegionServer(final Class<? extends HRegionServer> regionServerClass,</span>
+<span class="source-line-no">2959</span><span id="line-2959"> final Configuration conf) {</span>
+<span class="source-line-no">2960</span><span id="line-2960"> try {</span>
+<span class="source-line-no">2961</span><span id="line-2961"> Constructor<? extends HRegionServer> c =</span>
+<span class="source-line-no">2962</span><span id="line-2962"> regionServerClass.getConstructor(Configuration.class);</span>
+<span class="source-line-no">2963</span><span id="line-2963"> return c.newInstance(conf);</span>
+<span class="source-line-no">2964</span><span id="line-2964"> } catch (Exception e) {</span>
+<span class="source-line-no">2965</span><span id="line-2965"> throw new RuntimeException(</span>
+<span class="source-line-no">2966</span><span id="line-2966"> "Failed construction of " + "Regionserver: " + regionServerClass.toString(), e);</span>
+<span class="source-line-no">2967</span><span id="line-2967"> }</span>
+<span class="source-line-no">2968</span><span id="line-2968"> }</span>
+<span class="source-line-no">2969</span><span id="line-2969"></span>
+<span class="source-line-no">2970</span><span id="line-2970"> /**</span>
+<span class="source-line-no">2971</span><span id="line-2971"> * @see org.apache.hadoop.hbase.regionserver.HRegionServerCommandLine</span>
+<span class="source-line-no">2972</span><span id="line-2972"> */</span>
+<span class="source-line-no">2973</span><span id="line-2973"> public static void main(String[] args) {</span>
+<span class="source-line-no">2974</span><span id="line-2974"> LOG.info("STARTING executorService " + HRegionServer.class.getSimpleName());</span>
+<span class="source-line-no">2975</span><span id="line-2975"> VersionInfo.logVersion();</span>
+<span class="source-line-no">2976</span><span id="line-2976"> Configuration conf = HBaseConfiguration.create();</span>
+<span class="source-line-no">2977</span><span id="line-2977"> @SuppressWarnings("unchecked")</span>
+<span class="source-line-no">2978</span><span id="line-2978"> Class<? extends HRegionServer> regionServerClass = (Class<? extends HRegionServer>) conf</span>
+<span class="source-line-no">2979</span><span id="line-2979"> .getClass(HConstants.REGION_SERVER_IMPL, HRegionServer.class);</span>
+<span class="source-line-no">2980</span><span id="line-2980"></span>
+<span class="source-line-no">2981</span><span id="line-2981"> new HRegionServerCommandLine(regionServerClass).doMain(args);</span>
+<span class="source-line-no">2982</span><span id="line-2982"> }</span>
+<span class="source-line-no">2983</span><span id="line-2983"></span>
+<span class="source-line-no">2984</span><span id="line-2984"> /**</span>
+<span class="source-line-no">2985</span><span id="line-2985"> * Gets the online regions of the specified table. This method looks at the in-memory</span>
+<span class="source-line-no">2986</span><span id="line-2986"> * onlineRegions. It does not go to <code>hbase:meta</code>. Only returns <em>online</em> regions.</span>
+<span class="source-line-no">2987</span><span id="line-2987"> * If a region on this table has been closed during a disable, etc., it will not be included in</span>
+<span class="source-line-no">2988</span><span id="line-2988"> * the returned list. So, the returned list may not necessarily be ALL regions in this table, its</span>
+<span class="source-line-no">2989</span><span id="line-2989"> * all the ONLINE regions in the table.</span>
+<span class="source-line-no">2990</span><span id="line-2990"> * @param tableName table to limit the scope of the query</span>
+<span class="source-line-no">2991</span><span id="line-2991"> * @return Online regions from <code>tableName</code></span>
+<span class="source-line-no">2992</span><span id="line-2992"> */</span>
+<span class="source-line-no">2993</span><span id="line-2993"> @Override</span>
+<span class="source-line-no">2994</span><span id="line-2994"> public List<HRegion> getRegions(TableName tableName) {</span>
+<span class="source-line-no">2995</span><span id="line-2995"> List<HRegion> tableRegions = new ArrayList<>();</span>
+<span class="source-line-no">2996</span><span id="line-2996"> synchronized (this.onlineRegions) {</span>
+<span class="source-line-no">2997</span><span id="line-2997"> for (HRegion region : this.onlineRegions.values()) {</span>
+<span class="source-line-no">2998</span><span id="line-2998"> RegionInfo regionInfo = region.getRegionInfo();</span>
+<span class="source-line-no">2999</span><span id="line-2999"> if (regionInfo.getTable().equals(tableName)) {</span>
+<span class="source-line-no">3000</span><span id="line-3000"> tableRegions.add(region);</span>
+<span class="source-line-no">3001</span><span id="line-3001"> }</span>
+<span class="source-line-no">3002</span><span id="line-3002"> }</span>
+<span class="source-line-no">3003</span><span id="line-3003"> }</span>
+<span class="source-line-no">3004</span><span id="line-3004"> return tableRegions;</span>
+<span class="source-line-no">3005</span><span id="line-3005"> }</span>
+<span class="source-line-no">3006</span><span id="line-3006"></span>
+<span class="source-line-no">3007</span><span id="line-3007"> @Override</span>
+<span class="source-line-no">3008</span><span id="line-3008"> public List<HRegion> getRegions() {</span>
+<span class="source-line-no">3009</span><span id="line-3009"> List<HRegion> allRegions;</span>
+<span class="source-line-no">3010</span><span id="line-3010"> synchronized (this.onlineRegions) {</span>
+<span class="source-line-no">3011</span><span id="line-3011"> // Return a clone copy of the onlineRegions</span>
+<span class="source-line-no">3012</span><span id="line-3012"> allRegions = new ArrayList<>(onlineRegions.values());</span>
+<span class="source-line-no">3013</span><span id="line-3013"> }</span>
+<span class="source-line-no">3014</span><span id="line-3014"> return allRegions;</span>
+<span class="source-line-no">3015</span><span id="line-3015"> }</span>
+<span class="source-line-no">3016</span><span id="line-3016"></span>
+<span class="source-line-no">3017</span><span id="line-3017"> /**</span>
+<span class="source-line-no">3018</span><span id="line-3018"> * Gets the online tables in this RS. This method looks at the in-memory onlineRegions.</span>
+<span class="source-line-no">3019</span><span id="line-3019"> * @return all the online tables in this RS</span>
+<span class="source-line-no">3020</span><span id="line-3020"> */</span>
+<span class="source-line-no">3021</span><span id="line-3021"> public Set<TableName> getOnlineTables() {</span>
+<span class="source-line-no">3022</span><span id="line-3022"> Set<TableName> tables = new HashSet<>();</span>
+<span class="source-line-no">3023</span><span id="line-3023"> synchronized (this.onlineRegions) {</span>
+<span class="source-line-no">3024</span><span id="line-3024"> for (Region region : this.onlineRegions.values()) {</span>
+<span class="source-line-no">3025</span><span id="line-3025"> tables.add(region.getTableDescriptor().getTableName());</span>
+<span class="source-line-no">3026</span><span id="line-3026"> }</span>
+<span class="source-line-no">3027</span><span id="line-3027"> }</span>
+<span class="source-line-no">3028</span><span id="line-3028"> return tables;</span>
+<span class="source-line-no">3029</span><span id="line-3029"> }</span>
+<span class="source-line-no">3030</span><span id="line-3030"></span>
+<span class="source-line-no">3031</span><span id="line-3031"> public String[] getRegionServerCoprocessors() {</span>
+<span class="source-line-no">3032</span><span id="line-3032"> TreeSet<String> coprocessors = new TreeSet<>();</span>
+<span class="source-line-no">3033</span><span id="line-3033"> try {</span>
+<span class="source-line-no">3034</span><span id="line-3034"> coprocessors.addAll(getWAL(null).getCoprocessorHost().getCoprocessors());</span>
+<span class="source-line-no">3035</span><span id="line-3035"> } catch (IOException exception) {</span>
+<span class="source-line-no">3036</span><span id="line-3036"> LOG.warn("Exception attempting to fetch wal coprocessor information for the common wal; "</span>
+<span class="source-line-no">3037</span><span id="line-3037"> + "skipping.");</span>
+<span class="source-line-no">3038</span><span id="line-3038"> LOG.debug("Exception details for failure to fetch wal coprocessor information.", exception);</span>
+<span class="source-line-no">3039</span><span id="line-3039"> }</span>
+<span class="source-line-no">3040</span><span id="line-3040"> Collection<HRegion> regions = getOnlineRegionsLocalContext();</span>
+<span class="source-line-no">3041</span><span id="line-3041"> for (HRegion region : regions) {</span>
+<span class="source-line-no">3042</span><span id="line-3042"> coprocessors.addAll(region.getCoprocessorHost().getCoprocessors());</span>
+<span class="source-line-no">3043</span><span id="line-3043"> try {</span>
+<span class="source-line-no">3044</span><span id="line-3044"> coprocessors.addAll(getWAL(region.getRegionInfo()).getCoprocessorHost().getCoprocessors());</span>
+<span class="source-line-no">3045</span><span id="line-3045"> } catch (IOException exception) {</span>
+<span class="source-line-no">3046</span><span id="line-3046"> LOG.warn("Exception attempting to fetch wal coprocessor information for region " + region</span>
+<span class="source-line-no">3047</span><span id="line-3047"> + "; skipping.");</span>
+<span class="source-line-no">3048</span><span id="line-3048"> LOG.debug("Exception details for failure to fetch wal coprocessor information.", exception);</span>
+<span class="source-line-no">3049</span><span id="line-3049"> }</span>
+<span class="source-line-no">3050</span><span id="line-3050"> }</span>
+<span class="source-line-no">3051</span><span id="line-3051"> coprocessors.addAll(rsHost.getCoprocessors());</span>
+<span class="source-line-no">3052</span><span id="line-3052"> return coprocessors.toArray(new String[0]);</span>
+<span class="source-line-no">3053</span><span id="line-3053"> }</span>
+<span class="source-line-no">3054</span><span id="line-3054"></span>
+<span class="source-line-no">3055</span><span id="line-3055"> /**</span>
+<span class="source-line-no">3056</span><span id="line-3056"> * Try to close the region, logs a warning on failure but continues.</span>
+<span class="source-line-no">3057</span><span id="line-3057"> * @param region Region to close</span>
+<span class="source-line-no">3058</span><span id="line-3058"> */</span>
+<span class="source-line-no">3059</span><span id="line-3059"> private void closeRegionIgnoreErrors(RegionInfo region, final boolean abort) {</span>
+<span class="source-line-no">3060</span><span id="line-3060"> try {</span>
+<span class="source-line-no">3061</span><span id="line-3061"> if (!closeRegion(region.getEncodedName(), abort, null)) {</span>
+<span class="source-line-no">3062</span><span id="line-3062"> LOG</span>
+<span class="source-line-no">3063</span><span id="line-3063"> .warn("Failed to close " + region.getRegionNameAsString() + " - ignoring and continuing");</span>
+<span class="source-line-no">3064</span><span id="line-3064"> }</span>
+<span class="source-line-no">3065</span><span id="line-3065"> } catch (IOException e) {</span>
+<span class="source-line-no">3066</span><span id="line-3066"> LOG.warn("Failed to close " + region.getRegionNameAsString() + " - ignoring and continuing",</span>
+<span class="source-line-no">3067</span><span id="line-3067"> e);</span>
+<span class="source-line-no">3068</span><span id="line-3068"> }</span>
+<span class="source-line-no">3069</span><span id="line-3069"> }</span>
+<span class="source-line-no">3070</span><span id="line-3070"></span>
+<span class="source-line-no">3071</span><span id="line-3071"> /**</span>
+<span class="source-line-no">3072</span><span id="line-3072"> * Close asynchronously a region, can be called from the master or internally by the regionserver</span>
+<span class="source-line-no">3073</span><span id="line-3073"> * when stopping. If called from the master, the region will update the status.</span>
<span class="source-line-no">3074</span><span id="line-3074"> * <p></span>
-<span class="source-line-no">3075</span><span id="line-3075"> * If a close was in progress, this new request will be ignored, and an exception thrown.</span>
-<span class="source-line-no">3076</span><span id="line-3076"> * </p></span>
-<span class="source-line-no">3077</span><span id="line-3077"> * <p></span>
-<span class="source-line-no">3078</span><span id="line-3078"> * Provides additional flag to indicate if this region blocks should be evicted from the cache.</span>
-<span class="source-line-no">3079</span><span id="line-3079"> * </p></span>
-<span class="source-line-no">3080</span><span id="line-3080"> * @param encodedName Region to close</span>
-<span class="source-line-no">3081</span><span id="line-3081"> * @param abort True if we are aborting</span>
-<span class="source-line-no">3082</span><span id="line-3082"> * @param destination Where the Region is being moved too... maybe null if unknown.</span>
-<span class="source-line-no">3083</span><span id="line-3083"> * @return True if closed a region.</span>
-<span class="source-line-no">3084</span><span id="line-3084"> * @throws NotServingRegionException if the region is not online</span>
-<span class="source-line-no">3085</span><span id="line-3085"> */</span>
-<span class="source-line-no">3086</span><span id="line-3086"> protected boolean closeRegion(String encodedName, final boolean abort,</span>
-<span class="source-line-no">3087</span><span id="line-3087"> final ServerName destination) throws NotServingRegionException {</span>
-<span class="source-line-no">3088</span><span id="line-3088"> // Check for permissions to close.</span>
-<span class="source-line-no">3089</span><span id="line-3089"> HRegion actualRegion = this.getRegion(encodedName);</span>
-<span class="source-line-no">3090</span><span id="line-3090"> // Can be null if we're calling close on a region that's not online</span>
-<span class="source-line-no">3091</span><span id="line-3091"> if ((actualRegion != null) && (actualRegion.getCoprocessorHost() != null)) {</span>
-<span class="source-line-no">3092</span><span id="line-3092"> try {</span>
-<span class="source-line-no">3093</span><span id="line-3093"> actualRegion.getCoprocessorHost().preClose(false);</span>
-<span class="source-line-no">3094</span><span id="line-3094"> } catch (IOException exp) {</span>
-<span class="source-line-no">3095</span><span id="line-3095"> LOG.warn("Unable to close region: the coprocessor launched an error ", exp);</span>
-<span class="source-line-no">3096</span><span id="line-3096"> return false;</span>
-<span class="source-line-no">3097</span><span id="line-3097"> }</span>
-<span class="source-line-no">3098</span><span id="line-3098"> }</span>
-<span class="source-line-no">3099</span><span id="line-3099"></span>
-<span class="source-line-no">3100</span><span id="line-3100"> // previous can come back 'null' if not in map.</span>
-<span class="source-line-no">3101</span><span id="line-3101"> final Boolean previous =</span>
-<span class="source-line-no">3102</span><span id="line-3102"> this.regionsInTransitionInRS.putIfAbsent(Bytes.toBytes(encodedName), Boolean.FALSE);</span>
+<span class="source-line-no">3075</span><span id="line-3075"> * If an opening was in progress, this method will cancel it, but will not start a new close. The</span>
+<span class="source-line-no">3076</span><span id="line-3076"> * coprocessors are not called in this case. A NotServingRegionException exception is thrown.</span>
+<span class="source-line-no">3077</span><span id="line-3077"> * </p></span>
+<span class="source-line-no">3078</span><span id="line-3078"> * <p></span>
+<span class="source-line-no">3079</span><span id="line-3079"> * If a close was in progress, this new request will be ignored, and an exception thrown.</span>
+<span class="source-line-no">3080</span><span id="line-3080"> * </p></span>
+<span class="source-line-no">3081</span><span id="line-3081"> * <p></span>
+<span class="source-line-no">3082</span><span id="line-3082"> * Provides additional flag to indicate if this region blocks should be evicted from the cache.</span>
+<span class="source-line-no">3083</span><span id="line-3083"> * </p></span>
+<span class="source-line-no">3084</span><span id="line-3084"> * @param encodedName Region to close</span>
+<span class="source-line-no">3085</span><span id="line-3085"> * @param abort True if we are aborting</span>
+<span class="source-line-no">3086</span><span id="line-3086"> * @param destination Where the Region is being moved too... maybe null if unknown.</span>
+<span class="source-line-no">3087</span><span id="line-3087"> * @return True if closed a region.</span>
+<span class="source-line-no">3088</span><span id="line-3088"> * @throws NotServingRegionException if the region is not online</span>
+<span class="source-line-no">3089</span><span id="line-3089"> */</span>
+<span class="source-line-no">3090</span><span id="line-3090"> protected boolean closeRegion(String encodedName, final boolean abort,</span>
+<span class="source-line-no">3091</span><span id="line-3091"> final ServerName destination) throws NotServingRegionException {</span>
+<span class="source-line-no">3092</span><span id="line-3092"> // Check for permissions to close.</span>
+<span class="source-line-no">3093</span><span id="line-3093"> HRegion actualRegion = this.getRegion(encodedName);</span>
+<span class="source-line-no">3094</span><span id="line-3094"> // Can be null if we're calling close on a region that's not online</span>
+<span class="source-line-no">3095</span><span id="line-3095"> if ((actualRegion != null) && (actualRegion.getCoprocessorHost() != null)) {</span>
+<span class="source-line-no">3096</span><span id="line-3096"> try {</span>
+<span class="source-line-no">3097</span><span id="line-3097"> actualRegion.getCoprocessorHost().preClose(false);</span>
+<span class="source-line-no">3098</span><span id="line-3098"> } catch (IOException exp) {</span>
+<span class="source-line-no">3099</span><span id="line-3099"> LOG.warn("Unable to close region: the coprocessor launched an error ", exp);</span>
+<span class="source-line-no">3100</span><span id="line-3100"> return false;</span>
+<span class="source-line-no">3101</span><span id="line-3101"> }</span>
+<span class="source-line-no">3102</span><span id="line-3102"> }</span>
<span class="source-line-no">3103</span><span id="line-3103"></span>
-<span class="source-line-no">3104</span><span id="line-3104"> if (Boolean.TRUE.equals(previous)) {</span>
-<span class="source-line-no">3105</span><span id="line-3105"> LOG.info("Received CLOSE for the region:" + encodedName + " , which we are already "</span>
-<span class="source-line-no">3106</span><span id="line-3106"> + "trying to OPEN. Cancelling OPENING.");</span>
-<span class="source-line-no">3107</span><span id="line-3107"> if (!regionsInTransitionInRS.replace(Bytes.toBytes(encodedName), previous, Boolean.FALSE)) {</span>
-<span class="source-line-no">3108</span><span id="line-3108"> // The replace failed. That should be an exceptional case, but theoretically it can happen.</span>
-<span class="source-line-no">3109</span><span id="line-3109"> // We're going to try to do a standard close then.</span>
-<span class="source-line-no">3110</span><span id="line-3110"> LOG.warn("The opening for region " + encodedName + " was done before we could cancel it."</span>
-<span class="source-line-no">3111</span><span id="line-3111"> + " Doing a standard close now");</span>
-<span class="source-line-no">3112</span><span id="line-3112"> return closeRegion(encodedName, abort, destination);</span>
-<span class="source-line-no">3113</span><span id="line-3113"> }</span>
-<span class="source-line-no">3114</span><span id="line-3114"> // Let's get the region from the online region list again</span>
-<span class="source-line-no">3115</span><span id="line-3115"> actualRegion = this.getRegion(encodedName);</span>
-<span class="source-line-no">3116</span><span id="line-3116"> if (actualRegion == null) { // If already online, we still need to close it.</span>
-<span class="source-line-no">3117</span><span id="line-3117"> LOG.info("The opening previously in progress has been cancelled by a CLOSE request.");</span>
-<span class="source-line-no">3118</span><span id="line-3118"> // The master deletes the znode when it receives this exception.</span>
-<span class="source-line-no">3119</span><span id="line-3119"> throw new NotServingRegionException(</span>
-<span class="source-line-no">3120</span><span id="line-3120"> "The region " + encodedName + " was opening but not yet served. Opening is cancelled.");</span>
-<span class="source-line-no">3121</span><span id="line-3121"> }</span>
-<span class="source-line-no">3122</span><span id="line-3122"> } else if (previous == null) {</span>
-<span class="source-line-no">3123</span><span id="line-3123"> LOG.info("Received CLOSE for {}", encodedName);</span>
-<span class="source-line-no">3124</span><span id="line-3124"> } else if (Boolean.FALSE.equals(previous)) {</span>
-<span class="source-line-no">3125</span><span id="line-3125"> LOG.info("Received CLOSE for the region: " + encodedName</span>
-<span class="source-line-no">3126</span><span id="line-3126"> + ", which we are already trying to CLOSE, but not completed yet");</span>
-<span class="source-line-no">3127</span><span id="line-3127"> return true;</span>
-<span class="source-line-no">3128</span><span id="line-3128"> }</span>
-<span class="source-line-no">3129</span><span id="line-3129"></span>
-<span class="source-line-no">3130</span><span id="line-3130"> if (actualRegion == null) {</span>
-<span class="source-line-no">3131</span><span id="line-3131"> LOG.debug("Received CLOSE for a region which is not online, and we're not opening.");</span>
-<span class="source-line-no">3132</span><span id="line-3132"> this.regionsInTransitionInRS.remove(Bytes.toBytes(encodedName));</span>
-<span class="source-line-no">3133</span><span id="line-3133"> // The master deletes the znode when it receives this exception.</span>
-<span class="source-line-no">3134</span><span id="line-3134"> throw new NotServingRegionException(</span>
-<span class="source-line-no">3135</span><span id="line-3135"> "The region " + encodedName + " is not online, and is not opening.");</span>
-<span class="source-line-no">3136</span><span id="line-3136"> }</span>
-<span class="source-line-no">3137</span><span id="line-3137"></span>
-<span class="source-line-no">3138</span><span id="line-3138"> CloseRegionHandler crh;</span>
-<span class="source-line-no">3139</span><span id="line-3139"> final RegionInfo hri = actualRegion.getRegionInfo();</span>
-<span class="source-line-no">3140</span><span id="line-3140"> if (hri.isMetaRegion()) {</span>
-<span class="source-line-no">3141</span><span id="line-3141"> crh = new CloseMetaHandler(this, this, hri, abort);</span>
-<span class="source-line-no">3142</span><span id="line-3142"> } else {</span>
-<span class="source-line-no">3143</span><span id="line-3143"> crh = new CloseRegionHandler(this, this, hri, abort, destination);</span>
-<span class="source-line-no">3144</span><span id="line-3144"> }</span>
-<span class="source-line-no">3145</span><span id="line-3145"> this.executorService.submit(crh);</span>
-<span class="source-line-no">3146</span><span id="line-3146"> return true;</span>
-<span class="source-line-no">3147</span><span id="line-3147"> }</span>
-<span class="source-line-no">3148</span><span id="line-3148"></span>
-<span class="source-line-no">3149</span><span id="line-3149"> /**</span>
-<span class="source-line-no">3150</span><span id="line-3150"> * @return HRegion for the passed binary <code>regionName</code> or null if named region is not</span>
-<span class="source-line-no">3151</span><span id="line-3151"> * member of the online regions.</span>
-<span class="source-line-no">3152</span><span id="line-3152"> */</span>
-<span class="source-line-no">3153</span><span id="line-3153"> public HRegion getOnlineRegion(final byte[] regionName) {</span>
-<span class="source-line-no">3154</span><span id="line-3154"> String encodedRegionName = RegionInfo.encodeRegionName(regionName);</span>
-<span class="source-line-no">3155</span><span id="line-3155"> return this.onlineRegions.get(encodedRegionName);</span>
-<span class="source-line-no">3156</span><span id="line-3156"> }</span>
-<span class="source-line-no">3157</span><span id="line-3157"></span>
-<span class="source-line-no">3158</span><span id="line-3158"> @Override</span>
-<span class="source-line-no">3159</span><span id="line-3159"> public HRegion getRegion(final String encodedRegionName) {</span>
-<span class="source-line-no">3160</span><span id="line-3160"> return this.onlineRegions.get(encodedRegionName);</span>
-<span class="source-line-no">3161</span><span id="line-3161"> }</span>
-<span class="source-line-no">3162</span><span id="line-3162"></span>
-<span class="source-line-no">3163</span><span id="line-3163"> @Override</span>
-<span class="source-line-no">3164</span><span id="line-3164"> public boolean removeRegion(final HRegion r, ServerName destination) {</span>
-<span class="source-line-no">3165</span><span id="line-3165"> HRegion toReturn = this.onlineRegions.remove(r.getRegionInfo().getEncodedName());</span>
-<span class="source-line-no">3166</span><span id="line-3166"> if (DataTieringManager.getInstance() != null) {</span>
-<span class="source-line-no">3167</span><span id="line-3167"> DataTieringManager.getInstance().getRegionColdDataSize()</span>
-<span class="source-line-no">3168</span><span id="line-3168"> .remove(r.getRegionInfo().getEncodedName());</span>
-<span class="source-line-no">3169</span><span id="line-3169"> }</span>
-<span class="source-line-no">3170</span><span id="line-3170"> metricsRegionServerImpl.requestsCountCache.remove(r.getRegionInfo().getEncodedName());</span>
-<span class="source-line-no">3171</span><span id="line-3171"> if (destination != null) {</span>
-<span class="source-line-no">3172</span><span id="line-3172"> long closeSeqNum = r.getMaxFlushedSeqId();</span>
-<span class="source-line-no">3173</span><span id="line-3173"> if (closeSeqNum == HConstants.NO_SEQNUM) {</span>
-<span class="source-line-no">3174</span><span id="line-3174"> // No edits in WAL for this region; get the sequence number when the region was opened.</span>
-<span class="source-line-no">3175</span><span id="line-3175"> closeSeqNum = r.getOpenSeqNum();</span>
-<span class="source-line-no">3176</span><span id="line-3176"> if (closeSeqNum == HConstants.NO_SEQNUM) {</span>
-<span class="source-line-no">3177</span><span id="line-3177"> closeSeqNum = 0;</span>
-<span class="source-line-no">3178</span><span id="line-3178"> }</span>
-<span class="source-line-no">3179</span><span id="line-3179"> }</span>
-<span class="source-line-no">3180</span><span id="line-3180"> boolean selfMove = ServerName.isSameAddress(destination, this.getServerName());</span>
-<span class="source-line-no">3181</span><span id="line-3181"> addToMovedRegions(r.getRegionInfo().getEncodedName(), destination, closeSeqNum, selfMove);</span>
-<span class="source-line-no">3182</span><span id="line-3182"> if (selfMove) {</span>
-<span class="source-line-no">3183</span><span id="line-3183"> this.regionServerAccounting.getRetainedRegionRWRequestsCnt().put(</span>
-<span class="source-line-no">3184</span><span id="line-3184"> r.getRegionInfo().getEncodedName(),</span>
-<span class="source-line-no">3185</span><span id="line-3185"> new Pair<>(r.getReadRequestsCount(), r.getWriteRequestsCount()));</span>
-<span class="source-line-no">3186</span><span id="line-3186"> }</span>
-<span class="source-line-no">3187</span><span id="line-3187"> }</span>
-<span class="source-line-no">3188</span><span id="line-3188"> this.regionFavoredNodesMap.remove(r.getRegionInfo().getEncodedName());</span>
-<span class="source-line-no">3189</span><span id="line-3189"> configurationManager.deregisterObserver(r);</span>
-<span class="source-line-no">3190</span><span id="line-3190"> return toReturn != null;</span>
-<span class="source-line-no">3191</span><span id="line-3191"> }</span>
-<span class="source-line-no">3192</span><span id="line-3192"></span>
-<span class="source-line-no">3193</span><span id="line-3193"> /**</span>
-<span class="source-line-no">3194</span><span id="line-3194"> * Protected Utility method for safely obtaining an HRegion handle.</span>
-<span class="source-line-no">3195</span><span id="line-3195"> * @param regionName Name of online {@link HRegion} to return</span>
-<span class="source-line-no">3196</span><span id="line-3196"> * @return {@link HRegion} for <code>regionName</code></span>
-<span class="source-line-no">3197</span><span id="line-3197"> */</span>
-<span class="source-line-no">3198</span><span id="line-3198"> protected HRegion getRegion(final byte[] regionName) throws NotServingRegionException {</span>
-<span class="source-line-no">3199</span><span id="line-3199"> String encodedRegionName = RegionInfo.encodeRegionName(regionName);</span>
-<span class="source-line-no">3200</span><span id="line-3200"> return getRegionByEncodedName(regionName, encodedRegionName);</span>
-<span class="source-line-no">3201</span><span id="line-3201"> }</span>
-<span class="source-line-no">3202</span><span id="line-3202"></span>
-<span class="source-line-no">3203</span><span id="line-3203"> public HRegion getRegionByEncodedName(String encodedRegionName) throws NotServingRegionException {</span>
-<span class="source-line-no">3204</span><span id="line-3204"> return getRegionByEncodedName(null, encodedRegionName);</span>
+<span class="source-line-no">3104</span><span id="line-3104"> // previous can come back 'null' if not in map.</span>
+<span class="source-line-no">3105</span><span id="line-3105"> final Boolean previous =</span>
+<span class="source-line-no">3106</span><span id="line-3106"> this.regionsInTransitionInRS.putIfAbsent(Bytes.toBytes(encodedName), Boolean.FALSE);</span>
+<span class="source-line-no">3107</span><span id="line-3107"></span>
+<span class="source-line-no">3108</span><span id="line-3108"> if (Boolean.TRUE.equals(previous)) {</span>
+<span class="source-line-no">3109</span><span id="line-3109"> LOG.info("Received CLOSE for the region:" + encodedName + " , which we are already "</span>
+<span class="source-line-no">3110</span><span id="line-3110"> + "trying to OPEN. Cancelling OPENING.");</span>
+<span class="source-line-no">3111</span><span id="line-3111"> if (!regionsInTransitionInRS.replace(Bytes.toBytes(encodedName), previous, Boolean.FALSE)) {</span>
+<span class="source-line-no">3112</span><span id="line-3112"> // The replace failed. That should be an exceptional case, but theoretically it can happen.</span>
+<span class="source-line-no">3113</span><span id="line-3113"> // We're going to try to do a standard close then.</span>
+<span class="source-line-no">3114</span><span id="line-3114"> LOG.warn("The opening for region " + encodedName + " was done before we could cancel it."</span>
+<span class="source-line-no">3115</span><span id="line-3115"> + " Doing a standard close now");</span>
+<span class="source-line-no">3116</span><span id="line-3116"> return closeRegion(encodedName, abort, destination);</span>
+<span class="source-line-no">3117</span><span id="line-3117"> }</span>
+<span class="source-line-no">3118</span><span id="line-3118"> // Let's get the region from the online region list again</span>
+<span class="source-line-no">3119</span><span id="line-3119"> actualRegion = this.getRegion(encodedName);</span>
+<span class="source-line-no">3120</span><span id="line-3120"> if (actualRegion == null) { // If already online, we still need to close it.</span>
+<span class="source-line-no">3121</span><span id="line-3121"> LOG.info("The opening previously in progress has been cancelled by a CLOSE request.");</span>
+<span class="source-line-no">3122</span><span id="line-3122"> // The master deletes the znode when it receives this exception.</span>
+<span class="source-line-no">3123</span><span id="line-3123"> throw new NotServingRegionException(</span>
+<span class="source-line-no">3124</span><span id="line-3124"> "The region " + encodedName + " was opening but not yet served. Opening is cancelled.");</span>
+<span class="source-line-no">3125</span><span id="line-3125"> }</span>
+<span class="source-line-no">3126</span><span id="line-3126"> } else if (previous == null) {</span>
+<span class="source-line-no">3127</span><span id="line-3127"> LOG.info("Received CLOSE for {}", encodedName);</span>
+<span class="source-line-no">3128</span><span id="line-3128"> } else if (Boolean.FALSE.equals(previous)) {</span>
+<span class="source-line-no">3129</span><span id="line-3129"> LOG.info("Received CLOSE for the region: " + encodedName</span>
+<span class="source-line-no">3130</span><span id="line-3130"> + ", which we are already trying to CLOSE, but not completed yet");</span>
+<span class="source-line-no">3131</span><span id="line-3131"> return true;</span>
+<span class="source-line-no">3132</span><span id="line-3132"> }</span>
+<span class="source-line-no">3133</span><span id="line-3133"></span>
+<span class="source-line-no">3134</span><span id="line-3134"> if (actualRegion == null) {</span>
+<span class="source-line-no">3135</span><span id="line-3135"> LOG.debug("Received CLOSE for a region which is not online, and we're not opening.");</span>
+<span class="source-line-no">3136</span><span id="line-3136"> this.regionsInTransitionInRS.remove(Bytes.toBytes(encodedName));</span>
+<span class="source-line-no">3137</span><span id="line-3137"> // The master deletes the znode when it receives this exception.</span>
+<span class="source-line-no">3138</span><span id="line-3138"> throw new NotServingRegionException(</span>
+<span class="source-line-no">3139</span><span id="line-3139"> "The region " + encodedName + " is not online, and is not opening.");</span>
+<span class="source-line-no">3140</span><span id="line-3140"> }</span>
+<span class="source-line-no">3141</span><span id="line-3141"></span>
+<span class="source-line-no">3142</span><span id="line-3142"> CloseRegionHandler crh;</span>
+<span class="source-line-no">3143</span><span id="line-3143"> final RegionInfo hri = actualRegion.getRegionInfo();</span>
+<span class="source-line-no">3144</span><span id="line-3144"> if (hri.isMetaRegion()) {</span>
+<span class="source-line-no">3145</span><span id="line-3145"> crh = new CloseMetaHandler(this, this, hri, abort);</span>
+<span class="source-line-no">3146</span><span id="line-3146"> } else {</span>
+<span class="source-line-no">3147</span><span id="line-3147"> crh = new CloseRegionHandler(this, this, hri, abort, destination);</span>
+<span class="source-line-no">3148</span><span id="line-3148"> }</span>
+<span class="source-line-no">3149</span><span id="line-3149"> this.executorService.submit(crh);</span>
+<span class="source-line-no">3150</span><span id="line-3150"> return true;</span>
+<span class="source-line-no">3151</span><span id="line-3151"> }</span>
+<span class="source-line-no">3152</span><span id="line-3152"></span>
+<span class="source-line-no">3153</span><span id="line-3153"> /**</span>
+<span class="source-line-no">3154</span><span id="line-3154"> * @return HRegion for the passed binary <code>regionName</code> or null if named region is not</span>
+<span class="source-line-no">3155</span><span id="line-3155"> * member of the online regions.</span>
+<span class="source-line-no">3156</span><span id="line-3156"> */</span>
+<span class="source-line-no">3157</span><span id="line-3157"> public HRegion getOnlineRegion(final byte[] regionName) {</span>
+<span class="source-line-no">3158</span><span id="line-3158"> String encodedRegionName = RegionInfo.encodeRegionName(regionName);</span>
+<span class="source-line-no">3159</span><span id="line-3159"> return this.onlineRegions.get(encodedRegionName);</span>
+<span class="source-line-no">3160</span><span id="line-3160"> }</span>
+<span class="source-line-no">3161</span><span id="line-3161"></span>
+<span class="source-line-no">3162</span><span id="line-3162"> @Override</span>
+<span class="source-line-no">3163</span><span id="line-3163"> public HRegion getRegion(final String encodedRegionName) {</span>
+<span class="source-line-no">3164</span><span id="line-3164"> return this.onlineRegions.get(encodedRegionName);</span>
+<span class="source-line-no">3165</span><span id="line-3165"> }</span>
+<span class="source-line-no">3166</span><span id="line-3166"></span>
+<span class="source-line-no">3167</span><span id="line-3167"> @Override</span>
+<span class="source-line-no">3168</span><span id="line-3168"> public boolean removeRegion(final HRegion r, ServerName destination) {</span>
+<span class="source-line-no">3169</span><span id="line-3169"> HRegion toReturn = this.onlineRegions.remove(r.getRegionInfo().getEncodedName());</span>
+<span class="source-line-no">3170</span><span id="line-3170"> if (DataTieringManager.getInstance() != null) {</span>
+<span class="source-line-no">3171</span><span id="line-3171"> DataTieringManager.getInstance().getRegionColdDataSize()</span>
+<span class="source-line-no">3172</span><span id="line-3172"> .remove(r.getRegionInfo().getEncodedName());</span>
+<span class="source-line-no">3173</span><span id="line-3173"> }</span>
+<span class="source-line-no">3174</span><span id="line-3174"> metricsRegionServerImpl.requestsCountCache.remove(r.getRegionInfo().getEncodedName());</span>
+<span class="source-line-no">3175</span><span id="line-3175"> if (destination != null) {</span>
+<span class="source-line-no">3176</span><span id="line-3176"> long closeSeqNum = r.getMaxFlushedSeqId();</span>
+<span class="source-line-no">3177</span><span id="line-3177"> if (closeSeqNum == HConstants.NO_SEQNUM) {</span>
+<span class="source-line-no">3178</span><span id="line-3178"> // No edits in WAL for this region; get the sequence number when the region was opened.</span>
+<span class="source-line-no">3179</span><span id="line-3179"> closeSeqNum = r.getOpenSeqNum();</span>
+<span class="source-line-no">3180</span><span id="line-3180"> if (closeSeqNum == HConstants.NO_SEQNUM) {</span>
+<span class="source-line-no">3181</span><span id="line-3181"> closeSeqNum = 0;</span>
+<span class="source-line-no">3182</span><span id="line-3182"> }</span>
+<span class="source-line-no">3183</span><span id="line-3183"> }</span>
+<span class="source-line-no">3184</span><span id="line-3184"> boolean selfMove = ServerName.isSameAddress(destination, this.getServerName());</span>
+<span class="source-line-no">3185</span><span id="line-3185"> addToMovedRegions(r.getRegionInfo().getEncodedName(), destination, closeSeqNum, selfMove);</span>
+<span class="source-line-no">3186</span><span id="line-3186"> if (selfMove) {</span>
+<span class="source-line-no">3187</span><span id="line-3187"> this.regionServerAccounting.getRetainedRegionRWRequestsCnt().put(</span>
+<span class="source-line-no">3188</span><span id="line-3188"> r.getRegionInfo().getEncodedName(),</span>
+<span class="source-line-no">3189</span><span id="line-3189"> new Pair<>(r.getReadRequestsCount(), r.getWriteRequestsCount()));</span>
+<span class="source-line-no">3190</span><span id="line-3190"> }</span>
+<span class="source-line-no">3191</span><span id="line-3191"> }</span>
+<span class="source-line-no">3192</span><span id="line-3192"> this.regionFavoredNodesMap.remove(r.getRegionInfo().getEncodedName());</span>
+<span class="source-line-no">3193</span><span id="line-3193"> configurationManager.deregisterObserver(r);</span>
+<span class="source-line-no">3194</span><span id="line-3194"> return toReturn != null;</span>
+<span class="source-line-no">3195</span><span id="line-3195"> }</span>
+<span class="source-line-no">3196</span><span id="line-3196"></span>
+<span class="source-line-no">3197</span><span id="line-3197"> /**</span>
+<span class="source-line-no">3198</span><span id="line-3198"> * Protected Utility method for safely obtaining an HRegion handle.</span>
+<span class="source-line-no">3199</span><span id="line-3199"> * @param regionName Name of online {@link HRegion} to return</span>
+<span class="source-line-no">3200</span><span id="line-3200"> * @return {@link HRegion} for <code>regionName</code></span>
+<span class="source-line-no">3201</span><span id="line-3201"> */</span>
+<span class="source-line-no">3202</span><span id="line-3202"> protected HRegion getRegion(final byte[] regionName) throws NotServingRegionException {</span>
+<span class="source-line-no">3203</span><span id="line-3203"> String encodedRegionName = RegionInfo.encodeRegionName(regionName);</span>
+<span class="source-line-no">3204</span><span id="line-3204"> return getRegionByEncodedName(regionName, encodedRegionName);</span>
<span class="source-line-no">3205</span><span id="line-3205"> }</span>
<span class="source-line-no">3206</span><span id="line-3206"></span>
-<span class="source-line-no">3207</span><span id="line-3207"> private HRegion getRegionByEncodedName(byte[] regionName, String encodedRegionName)</span>
-<span class="source-line-no">3208</span><span id="line-3208"> throws NotServingRegionException {</span>
-<span class="source-line-no">3209</span><span id="line-3209"> HRegion region = this.onlineRegions.get(encodedRegionName);</span>
-<span class="source-line-no">3210</span><span id="line-3210"> if (region == null) {</span>
-<span class="source-line-no">3211</span><span id="line-3211"> MovedRegionInfo moveInfo = getMovedRegion(encodedRegionName);</span>
-<span class="source-line-no">3212</span><span id="line-3212"> if (moveInfo != null) {</span>
-<span class="source-line-no">3213</span><span id="line-3213"> throw new RegionMovedException(moveInfo.getServerName(), moveInfo.getSeqNum());</span>
-<span class="source-line-no">3214</span><span id="line-3214"> }</span>
-<span class="source-line-no">3215</span><span id="line-3215"> Boolean isOpening = this.regionsInTransitionInRS.get(Bytes.toBytes(encodedRegionName));</span>
-<span class="source-line-no">3216</span><span id="line-3216"> String regionNameStr =</span>
-<span class="source-line-no">3217</span><span id="line-3217"> regionName == null ? encodedRegionName : Bytes.toStringBinary(regionName);</span>
-<span class="source-line-no">3218</span><span id="line-3218"> if (isOpening != null && isOpening) {</span>
-<span class="source-line-no">3219</span><span id="line-3219"> throw new RegionOpeningException(</span>
-<span class="source-line-no">3220</span><span id="line-3220"> "Region " + regionNameStr + " is opening on " + this.serverName);</span>
-<span class="source-line-no">3221</span><span id="line-3221"> }</span>
-<span class="source-line-no">3222</span><span id="line-3222"> throw new NotServingRegionException(</span>
-<span class="source-line-no">3223</span><span id="line-3223"> "" + regionNameStr + " is not online on " + this.serverName);</span>
-<span class="source-line-no">3224</span><span id="line-3224"> }</span>
-<span class="source-line-no">3225</span><span id="line-3225"> return region;</span>
-<span class="source-line-no">3226</span><span id="line-3226"> }</span>
-<span class="source-line-no">3227</span><span id="line-3227"></span>
-<span class="source-line-no">3228</span><span id="line-3228"> /**</span>
-<span class="source-line-no">3229</span><span id="line-3229"> * Cleanup after Throwable caught invoking method. Converts <code>t</code> to IOE if it isn't</span>
-<span class="source-line-no">3230</span><span id="line-3230"> * already.</span>
-<span class="source-line-no">3231</span><span id="line-3231"> * @param t Throwable</span>
-<span class="source-line-no">3232</span><span id="line-3232"> * @param msg Message to log in error. Can be null.</span>
-<span class="source-line-no">3233</span><span id="line-3233"> * @return Throwable converted to an IOE; methods can only let out IOEs.</span>
-<span class="source-line-no">3234</span><span id="line-3234"> */</span>
-<span class="source-line-no">3235</span><span id="line-3235"> private Throwable cleanup(final Throwable t, final String msg) {</span>
-<span class="source-line-no">3236</span><span id="line-3236"> // Don't log as error if NSRE; NSRE is 'normal' operation.</span>
-<span class="source-line-no">3237</span><span id="line-3237"> if (t instanceof NotServingRegionException) {</span>
-<span class="source-line-no">3238</span><span id="line-3238"> LOG.debug("NotServingRegionException; " + t.getMessage());</span>
-<span class="source-line-no">3239</span><span id="line-3239"> return t;</span>
-<span class="source-line-no">3240</span><span id="line-3240"> }</span>
-<span class="source-line-no">3241</span><span id="line-3241"> Throwable e = t instanceof RemoteException ? ((RemoteException) t).unwrapRemoteException() : t;</span>
-<span class="source-line-no">3242</span><span id="line-3242"> if (msg == null) {</span>
-<span class="source-line-no">3243</span><span id="line-3243"> LOG.error("", e);</span>
-<span class="source-line-no">3244</span><span id="line-3244"> } else {</span>
-<span class="source-line-no">3245</span><span id="line-3245"> LOG.error(msg, e);</span>
-<span class="source-line-no">3246</span><span id="line-3246"> }</span>
-<span class="source-line-no">3247</span><span id="line-3247"> if (!rpcServices.checkOOME(t)) {</span>
-<span class="source-line-no">3248</span><span id="line-3248"> checkFileSystem();</span>
-<span class="source-line-no">3249</span><span id="line-3249"> }</span>
-<span class="source-line-no">3250</span><span id="line-3250"> return t;</span>
-<span class="source-line-no">3251</span><span id="line-3251"> }</span>
-<span class="source-line-no">3252</span><span id="line-3252"></span>
-<span class="source-line-no">3253</span><span id="line-3253"> /**</span>
-<span class="source-line-no">3254</span><span id="line-3254"> * @param msg Message to put in new IOE if passed <code>t</code> is not an IOE</span>
-<span class="source-line-no">3255</span><span id="line-3255"> * @return Make <code>t</code> an IOE if it isn't already.</span>
-<span class="source-line-no">3256</span><span id="line-3256"> */</span>
-<span class="source-line-no">3257</span><span id="line-3257"> private IOException convertThrowableToIOE(final Throwable t, final String msg) {</span>
-<span class="source-line-no">3258</span><span id="line-3258"> return (t instanceof IOException ? (IOException) t</span>
-<span class="source-line-no">3259</span><span id="line-3259"> : msg == null || msg.length() == 0 ? new IOException(t)</span>
-<span class="source-line-no">3260</span><span id="line-3260"> : new IOException(msg, t));</span>
-<span class="source-line-no">3261</span><span id="line-3261"> }</span>
-<span class="source-line-no">3262</span><span id="line-3262"></span>
-<span class="source-line-no">3263</span><span id="line-3263"> /**</span>
-<span class="source-line-no">3264</span><span id="line-3264"> * Checks to see if the file system is still accessible. If not, sets abortRequested and</span>
-<span class="source-line-no">3265</span><span id="line-3265"> * stopRequested</span>
-<span class="source-line-no">3266</span><span id="line-3266"> * @return false if file system is not available</span>
-<span class="source-line-no">3267</span><span id="line-3267"> */</span>
-<span class="source-line-no">3268</span><span id="line-3268"> boolean checkFileSystem() {</span>
-<span class="source-line-no">3269</span><span id="line-3269"> if (this.dataFsOk && this.dataFs != null) {</span>
-<span class="source-line-no">3270</span><span id="line-3270"> try {</span>
-<span class="source-line-no">3271</span><span id="line-3271"> FSUtils.checkFileSystemAvailable(this.dataFs);</span>
-<span class="source-line-no">3272</span><span id="line-3272"> } catch (IOException e) {</span>
-<span class="source-line-no">3273</span><span id="line-3273"> abort("File System not available", e);</span>
-<span class="source-line-no">3274</span><span id="line-3274"> this.dataFsOk = false;</span>
-<span class="source-line-no">3275</span><span id="line-3275"> }</span>
-<span class="source-line-no">3276</span><span id="line-3276"> }</span>
-<span class="source-line-no">3277</span><span id="line-3277"> return this.dataFsOk;</span>
-<span class="source-line-no">3278</span><span id="line-3278"> }</span>
-<span class="source-line-no">3279</span><span id="line-3279"></span>
-<span class="source-line-no">3280</span><span id="line-3280"> @Override</span>
-<span class="source-line-no">3281</span><span id="line-3281"> public void updateRegionFavoredNodesMapping(String encodedRegionName,</span>
-<span class="source-line-no">3282</span><span id="line-3282"> List<org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos.ServerName> favoredNodes) {</span>
-<span class="source-line-no">3283</span><span id="line-3283"> Address[] addr = new Address[favoredNodes.size()];</span>
-<span class="source-line-no">3284</span><span id="line-3284"> // Refer to the comment on the declaration of regionFavoredNodesMap on why</span>
-<span class="source-line-no">3285</span><span id="line-3285"> // it is a map of region name to Address[]</span>
-<span class="source-line-no">3286</span><span id="line-3286"> for (int i = 0; i < favoredNodes.size(); i++) {</span>
-<span class="source-line-no">3287</span><span id="line-3287"> addr[i] = Address.fromParts(favoredNodes.get(i).getHostName(), favoredNodes.get(i).getPort());</span>
-<span class="source-line-no">3288</span><span id="line-3288"> }</span>
-<span class="source-line-no">3289</span><span id="line-3289"> regionFavoredNodesMap.put(encodedRegionName, addr);</span>
-<span class="source-line-no">3290</span><span id="line-3290"> }</span>
-<span class="source-line-no">3291</span><span id="line-3291"></span>
-<span class="source-line-no">3292</span><span id="line-3292"> /**</span>
-<span class="source-line-no">3293</span><span id="line-3293"> * Return the favored nodes for a region given its encoded name. Look at the comment around</span>
-<span class="source-line-no">3294</span><span id="line-3294"> * {@link #regionFavoredNodesMap} on why we convert to InetSocketAddress[] here.</span>
-<span class="source-line-no">3295</span><span id="line-3295"> * @param encodedRegionName the encoded region name.</span>
-<span class="source-line-no">3296</span><span id="line-3296"> * @return array of favored locations</span>
-<span class="source-line-no">3297</span><span id="line-3297"> */</span>
-<span class="source-line-no">3298</span><span id="line-3298"> @Override</span>
-<span class="source-line-no">3299</span><span id="line-3299"> public InetSocketAddress[] getFavoredNodesForRegion(String encodedRegionName) {</span>
-<span class="source-line-no">3300</span><span id="line-3300"> return Address.toSocketAddress(regionFavoredNodesMap.get(encodedRegionName));</span>
-<span class="source-line-no">3301</span><span id="line-3301"> }</span>
-<span class="source-line-no">3302</span><span id="line-3302"></span>
-<span class="source-line-no">3303</span><span id="line-3303"> @Override</span>
-<span class="source-line-no">3304</span><span id="line-3304"> public ServerNonceManager getNonceManager() {</span>
-<span class="source-line-no">3305</span><span id="line-3305"> return this.nonceManager;</span>
-<span class="source-line-no">3306</span><span id="line-3306"> }</span>
-<span class="source-line-no">3307</span><span id="line-3307"></span>
-<span class="source-line-no">3308</span><span id="line-3308"> private static class MovedRegionInfo {</span>
-<span class="source-line-no">3309</span><span id="line-3309"> private final ServerName serverName;</span>
-<span class="source-line-no">3310</span><span id="line-3310"> private final long seqNum;</span>
+<span class="source-line-no">3207</span><span id="line-3207"> public HRegion getRegionByEncodedName(String encodedRegionName) throws NotServingRegionException {</span>
+<span class="source-line-no">3208</span><span id="line-3208"> return getRegionByEncodedName(null, encodedRegionName);</span>
+<span class="source-line-no">3209</span><span id="line-3209"> }</span>
+<span class="source-line-no">3210</span><span id="line-3210"></span>
+<span class="source-line-no">3211</span><span id="line-3211"> private HRegion getRegionByEncodedName(byte[] regionName, String encodedRegionName)</span>
+<span class="source-line-no">3212</span><span id="line-3212"> throws NotServingRegionException {</span>
+<span class="source-line-no">3213</span><span id="line-3213"> HRegion region = this.onlineRegions.get(encodedRegionName);</span>
+<span class="source-line-no">3214</span><span id="line-3214"> if (region == null) {</span>
+<span class="source-line-no">3215</span><span id="line-3215"> MovedRegionInfo moveInfo = getMovedRegion(encodedRegionName);</span>
+<span class="source-line-no">3216</span><span id="line-3216"> if (moveInfo != null) {</span>
+<span class="source-line-no">3217</span><span id="line-3217"> throw new RegionMovedException(moveInfo.getServerName(), moveInfo.getSeqNum());</span>
+<span class="source-line-no">3218</span><span id="line-3218"> }</span>
+<span class="source-line-no">3219</span><span id="line-3219"> Boolean isOpening = this.regionsInTransitionInRS.get(Bytes.toBytes(encodedRegionName));</span>
+<span class="source-line-no">3220</span><span id="line-3220"> String regionNameStr =</span>
+<span class="source-line-no">3221</span><span id="line-3221"> regionName == null ? encodedRegionName : Bytes.toStringBinary(regionName);</span>
+<span class="source-line-no">3222</span><span id="line-3222"> if (isOpening != null && isOpening) {</span>
+<span class="source-line-no">3223</span><span id="line-3223"> throw new RegionOpeningException(</span>
+<span class="source-line-no">3224</span><span id="line-3224"> "Region " + regionNameStr + " is opening on " + this.serverName);</span>
+<span class="source-line-no">3225</span><span id="line-3225"> }</span>
+<span class="source-line-no">3226</span><span id="line-3226"> throw new NotServingRegionException(</span>
+<span class="source-line-no">3227</span><span id="line-3227"> "" + regionNameStr + " is not online on " + this.serverName);</span>
+<span class="source-line-no">3228</span><span id="line-3228"> }</span>
+<span class="source-line-no">3229</span><span id="line-3229"> return region;</span>
+<span class="source-line-no">3230</span><span id="line-3230"> }</span>
+<span class="source-line-no">3231</span><span id="line-3231"></span>
+<span class="source-line-no">3232</span><span id="line-3232"> /**</span>
+<span class="source-line-no">3233</span><span id="line-3233"> * Cleanup after Throwable caught invoking method. Converts <code>t</code> to IOE if it isn't</span>
+<span class="source-line-no">3234</span><span id="line-3234"> * already.</span>
+<span class="source-line-no">3235</span><span id="line-3235"> * @param t Throwable</span>
+<span class="source-line-no">3236</span><span id="line-3236"> * @param msg Message to log in error. Can be null.</span>
+<span class="source-line-no">3237</span><span id="line-3237"> * @return Throwable converted to an IOE; methods can only let out IOEs.</span>
+<span class="source-line-no">3238</span><span id="line-3238"> */</span>
+<span class="source-line-no">3239</span><span id="line-3239"> private Throwable cleanup(final Throwable t, final String msg) {</span>
+<span class="source-line-no">3240</span><span id="line-3240"> // Don't log as error if NSRE; NSRE is 'normal' operation.</span>
+<span class="source-line-no">3241</span><span id="line-3241"> if (t instanceof NotServingRegionException) {</span>
+<span class="source-line-no">3242</span><span id="line-3242"> LOG.debug("NotServingRegionException; " + t.getMessage());</span>
+<span class="source-line-no">3243</span><span id="line-3243"> return t;</span>
+<span class="source-line-no">3244</span><span id="line-3244"> }</span>
+<span class="source-line-no">3245</span><span id="line-3245"> Throwable e = t instanceof RemoteException ? ((RemoteException) t).unwrapRemoteException() : t;</span>
+<span class="source-line-no">3246</span><span id="line-3246"> if (msg == null) {</span>
+<span class="source-line-no">3247</span><span id="line-3247"> LOG.error("", e);</span>
+<span class="source-line-no">3248</span><span id="line-3248"> } else {</span>
+<span class="source-line-no">3249</span><span id="line-3249"> LOG.error(msg, e);</span>
+<span class="source-line-no">3250</span><span id="line-3250"> }</span>
+<span class="source-line-no">3251</span><span id="line-3251"> if (!rpcServices.checkOOME(t)) {</span>
+<span class="source-line-no">3252</span><span id="line-3252"> checkFileSystem();</span>
+<span class="source-line-no">3253</span><span id="line-3253"> }</span>
+<span class="source-line-no">3254</span><span id="line-3254"> return t;</span>
+<span class="source-line-no">3255</span><span id="line-3255"> }</span>
+<span class="source-line-no">3256</span><span id="line-3256"></span>
+<span class="source-line-no">3257</span><span id="line-3257"> /**</span>
+<span class="source-line-no">3258</span><span id="line-3258"> * @param msg Message to put in new IOE if passed <code>t</code> is not an IOE</span>
+<span class="source-line-no">3259</span><span id="line-3259"> * @return Make <code>t</code> an IOE if it isn't already.</span>
+<span class="source-line-no">3260</span><span id="line-3260"> */</span>
+<span class="source-line-no">3261</span><span id="line-3261"> private IOException convertThrowableToIOE(final Throwable t, final String msg) {</span>
+<span class="source-line-no">3262</span><span id="line-3262"> return (t instanceof IOException ? (IOException) t</span>
+<span class="source-line-no">3263</span><span id="line-3263"> : msg == null || msg.length() == 0 ? new IOException(t)</span>
+<span class="source-line-no">3264</span><span id="line-3264"> : new IOException(msg, t));</span>
+<span class="source-line-no">3265</span><span id="line-3265"> }</span>
+<span class="source-line-no">3266</span><span id="line-3266"></span>
+<span class="source-line-no">3267</span><span id="line-3267"> /**</span>
+<span class="source-line-no">3268</span><span id="line-3268"> * Checks to see if the file system is still accessible. If not, sets abortRequested and</span>
+<span class="source-line-no">3269</span><span id="line-3269"> * stopRequested</span>
+<span class="source-line-no">3270</span><span id="line-3270"> * @return false if file system is not available</span>
+<span class="source-line-no">3271</span><span id="line-3271"> */</span>
+<span class="source-line-no">3272</span><span id="line-3272"> boolean checkFileSystem() {</span>
+<span class="source-line-no">3273</span><span id="line-3273"> if (this.dataFsOk && this.dataFs != null) {</span>
+<span class="source-line-no">3274</span><span id="line-3274"> try {</span>
+<span class="source-line-no">3275</span><span id="line-3275"> FSUtils.checkFileSystemAvailable(this.dataFs);</span>
+<span class="source-line-no">3276</span><span id="line-3276"> } catch (IOException e) {</span>
+<span class="source-line-no">3277</span><span id="line-3277"> abort("File System not available", e);</span>
+<span class="source-line-no">3278</span><span id="line-3278"> this.dataFsOk = false;</span>
+<span class="source-line-no">3279</span><span id="line-3279"> }</span>
+<span class="source-line-no">3280</span><span id="line-3280"> }</span>
+<span class="source-line-no">3281</span><span id="line-3281"> return this.dataFsOk;</span>
+<span class="source-line-no">3282</span><span id="line-3282"> }</span>
+<span class="source-line-no">3283</span><span id="line-3283"></span>
+<span class="source-line-no">3284</span><span id="line-3284"> @Override</span>
+<span class="source-line-no">3285</span><span id="line-3285"> public void updateRegionFavoredNodesMapping(String encodedRegionName,</span>
+<span class="source-line-no">3286</span><span id="line-3286"> List<org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos.ServerName> favoredNodes) {</span>
+<span class="source-line-no">3287</span><span id="line-3287"> Address[] addr = new Address[favoredNodes.size()];</span>
+<span class="source-line-no">3288</span><span id="line-3288"> // Refer to the comment on the declaration of regionFavoredNodesMap on why</span>
+<span class="source-line-no">3289</span><span id="line-3289"> // it is a map of region name to Address[]</span>
+<span class="source-line-no">3290</span><span id="line-3290"> for (int i = 0; i < favoredNodes.size(); i++) {</span>
+<span class="source-line-no">3291</span><span id="line-3291"> addr[i] = Address.fromParts(favoredNodes.get(i).getHostName(), favoredNodes.get(i).getPort());</span>
+<span class="source-line-no">3292</span><span id="line-3292"> }</span>
+<span class="source-line-no">3293</span><span id="line-3293"> regionFavoredNodesMap.put(encodedRegionName, addr);</span>
+<span class="source-line-no">3294</span><span id="line-3294"> }</span>
+<span class="source-line-no">3295</span><span id="line-3295"></span>
+<span class="source-line-no">3296</span><span id="line-3296"> /**</span>
+<span class="source-line-no">3297</span><span id="line-3297"> * Return the favored nodes for a region given its encoded name. Look at the comment around</span>
+<span class="source-line-no">3298</span><span id="line-3298"> * {@link #regionFavoredNodesMap} on why we convert to InetSocketAddress[] here.</span>
+<span class="source-line-no">3299</span><span id="line-3299"> * @param encodedRegionName the encoded region name.</span>
+<span class="source-line-no">3300</span><span id="line-3300"> * @return array of favored locations</span>
+<span class="source-line-no">3301</span><span id="line-3301"> */</span>
+<span class="source-line-no">3302</span><span id="line-3302"> @Override</span>
+<span class="source-line-no">3303</span><span id="line-3303"> public InetSocketAddress[] getFavoredNodesForRegion(String encodedRegionName) {</span>
+<span class="source-line-no">3304</span><span id="line-3304"> return Address.toSocketAddress(regionFavoredNodesMap.get(encodedRegionName));</span>
+<span class="source-line-no">3305</span><span id="line-3305"> }</span>
+<span class="source-line-no">3306</span><span id="line-3306"></span>
+<span class="source-line-no">3307</span><span id="line-3307"> @Override</span>
+<span class="source-line-no">3308</span><span id="line-3308"> public ServerNonceManager getNonceManager() {</span>
+<span class="source-line-no">3309</span><span id="line-3309"> return this.nonceManager;</span>
+<span class="source-line-no">3310</span><span id="line-3310"> }</span>
<span class="source-line-no">3311</span><span id="line-3311"></span>
-<span class="source-line-no">3312</span><span id="line-3312"> MovedRegionInfo(ServerName serverName, long closeSeqNum) {</span>
-<span class="source-line-no">3313</span><span id="line-3313"> this.serverName = serverName;</span>
-<span class="source-line-no">3314</span><span id="line-3314"> this.seqNum = closeSeqNum;</span>
-<span class="source-line-no">3315</span><span id="line-3315"> }</span>
-<span class="source-line-no">3316</span><span id="line-3316"></span>
-<span class="source-line-no">3317</span><span id="line-3317"> public ServerName getServerName() {</span>
-<span class="source-line-no">3318</span><span id="line-3318"> return serverName;</span>
+<span class="source-line-no">3312</span><span id="line-3312"> private static class MovedRegionInfo {</span>
+<span class="source-line-no">3313</span><span id="line-3313"> private final ServerName serverName;</span>
+<span class="source-line-no">3314</span><span id="line-3314"> private final long seqNum;</span>
+<span class="source-line-no">3315</span><span id="line-3315"></span>
+<span class="source-line-no">3316</span><span id="line-3316"> MovedRegionInfo(ServerName serverName, long closeSeqNum) {</span>
+<span class="source-line-no">3317</span><span id="line-3317"> this.serverName = serverName;</span>
+<span class="source-line-no">3318</span><span id="line-3318"> this.seqNum = closeSeqNum;</span>
<span class="source-line-no">3319</span><span id="line-3319"> }</span>
<span class="source-line-no">3320</span><span id="line-3320"></span>
-<span class="source-line-no">3321</span><span id="line-3321"> public long getSeqNum() {</span>
-<span class="source-line-no">3322</span><span id="line-3322"> return seqNum;</span>
+<span class="source-line-no">3321</span><span id="line-3321"> public ServerName getServerName() {</span>
+<span class="source-line-no">3322</span><span id="line-3322"> return serverName;</span>
<span class="source-line-no">3323</span><span id="line-3323"> }</span>
-<span class="source-line-no">3324</span><span id="line-3324"> }</span>
-<span class="source-line-no">3325</span><span id="line-3325"></span>
-<span class="source-line-no">3326</span><span id="line-3326"> /**</span>
-<span class="source-line-no">3327</span><span id="line-3327"> * We need a timeout. If not there is a risk of giving a wrong information: this would double the</span>
-<span class="source-line-no">3328</span><span id="line-3328"> * number of network calls instead of reducing them.</span>
-<span class="source-line-no">3329</span><span id="line-3329"> */</span>
-<span class="source-line-no">3330</span><span id="line-3330"> private static final int TIMEOUT_REGION_MOVED = (2 * 60 * 1000);</span>
-<span class="source-line-no">3331</span><span id="line-3331"></span>
-<span class="source-line-no">3332</span><span id="line-3332"> private void addToMovedRegions(String encodedName, ServerName destination, long closeSeqNum,</span>
-<span class="source-line-no">3333</span><span id="line-3333"> boolean selfMove) {</span>
-<span class="source-line-no">3334</span><span id="line-3334"> if (selfMove) {</span>
-<span class="source-line-no">3335</span><span id="line-3335"> LOG.warn("Not adding moved region record: " + encodedName + " to self.");</span>
-<span class="source-line-no">3336</span><span id="line-3336"> return;</span>
-<span class="source-line-no">3337</span><span id="line-3337"> }</span>
-<span class="source-line-no">3338</span><span id="line-3338"> LOG.info("Adding " + encodedName + " move to " + destination + " record at close sequenceid="</span>
-<span class="source-line-no">3339</span><span id="line-3339"> + closeSeqNum);</span>
-<span class="source-line-no">3340</span><span id="line-3340"> movedRegionInfoCache.put(encodedName, new MovedRegionInfo(destination, closeSeqNum));</span>
-<span class="source-line-no">3341</span><span id="line-3341"> }</span>
-<span class="source-line-no">3342</span><span id="line-3342"></span>
-<span class="source-line-no">3343</span><span id="line-3343"> void removeFromMovedRegions(String encodedName) {</span>
-<span class="source-line-no">3344</span><span id="line-3344"> movedRegionInfoCache.invalidate(encodedName);</span>
+<span class="source-line-no">3324</span><span id="line-3324"></span>
+<span class="source-line-no">3325</span><span id="line-3325"> public long getSeqNum() {</span>
+<span class="source-line-no">3326</span><span id="line-3326"> return seqNum;</span>
+<span class="source-line-no">3327</span><span id="line-3327"> }</span>
+<span class="source-line-no">3328</span><span id="line-3328"> }</span>
+<span class="source-line-no">3329</span><span id="line-3329"></span>
+<span class="source-line-no">3330</span><span id="line-3330"> /**</span>
+<span class="source-line-no">3331</span><span id="line-3331"> * We need a timeout. If not there is a risk of giving a wrong information: this would double the</span>
+<span class="source-line-no">3332</span><span id="line-3332"> * number of network calls instead of reducing them.</span>
+<span class="source-line-no">3333</span><span id="line-3333"> */</span>
+<span class="source-line-no">3334</span><span id="line-3334"> private static final int TIMEOUT_REGION_MOVED = (2 * 60 * 1000);</span>
+<span class="source-line-no">3335</span><span id="line-3335"></span>
+<span class="source-line-no">3336</span><span id="line-3336"> private void addToMovedRegions(String encodedName, ServerName destination, long closeSeqNum,</span>
+<span class="source-line-no">3337</span><span id="line-3337"> boolean selfMove) {</span>
+<span class="source-line-no">3338</span><span id="line-3338"> if (selfMove) {</span>
+<span class="source-line-no">3339</span><span id="line-3339"> LOG.warn("Not adding moved region record: " + encodedName + " to self.");</span>
+<span class="source-line-no">3340</span><span id="line-3340"> return;</span>
+<span class="source-line-no">3341</span><span id="line-3341"> }</span>
+<span class="source-line-no">3342</span><span id="line-3342"> LOG.info("Adding " + encodedName + " move to " + destination + " record at close sequenceid="</span>
+<span class="source-line-no">3343</span><span id="line-3343"> + closeSeqNum);</span>
+<span class="source-line-no">3344</span><span id="line-3344"> movedRegionInfoCache.put(encodedName, new MovedRegionInfo(destination, closeSeqNum));</span>
<span class="source-line-no">3345</span><span id="line-3345"> }</span>
<span class="source-line-no">3346</span><span id="line-3346"></span>
-<span class="source-line-no">3347</span><span id="line-3347"> @InterfaceAudience.Private</span>
-<span class="source-line-no">3348</span><span id="line-3348"> public MovedRegionInfo getMovedRegion(String encodedRegionName) {</span>
-<span class="source-line-no">3349</span><span id="line-3349"> return movedRegionInfoCache.getIfPresent(encodedRegionName);</span>
-<span class="source-line-no">3350</span><span id="line-3350"> }</span>
-<span class="source-line-no">3351</span><span id="line-3351"></span>
-<span class="source-line-no">3352</span><span id="line-3352"> @InterfaceAudience.Private</span>
-<span class="source-line-no">3353</span><span id="line-3353"> public int movedRegionCacheExpiredTime() {</span>
-<span class="source-line-no">3354</span><span id="line-3354"> return TIMEOUT_REGION_MOVED;</span>
-<span class="source-line-no">3355</span><span id="line-3355"> }</span>
-<span class="source-line-no">3356</span><span id="line-3356"></span>
-<span class="source-line-no">3357</span><span id="line-3357"> private String getMyEphemeralNodePath() {</span>
-<span class="source-line-no">3358</span><span id="line-3358"> return zooKeeper.getZNodePaths().getRsPath(serverName);</span>
+<span class="source-line-no">3347</span><span id="line-3347"> void removeFromMovedRegions(String encodedName) {</span>
+<span class="source-line-no">3348</span><span id="line-3348"> movedRegionInfoCache.invalidate(encodedName);</span>
+<span class="source-line-no">3349</span><span id="line-3349"> }</span>
+<span class="source-line-no">3350</span><span id="line-3350"></span>
+<span class="source-line-no">3351</span><span id="line-3351"> @InterfaceAudience.Private</span>
+<span class="source-line-no">3352</span><span id="line-3352"> public MovedRegionInfo getMovedRegion(String encodedRegionName) {</span>
+<span class="source-line-no">3353</span><span id="line-3353"> return movedRegionInfoCache.getIfPresent(encodedRegionName);</span>
+<span class="source-line-no">3354</span><span id="line-3354"> }</span>
+<span class="source-line-no">3355</span><span id="line-3355"></span>
+<span class="source-line-no">3356</span><span id="line-3356"> @InterfaceAudience.Private</span>
+<span class="source-line-no">3357</span><span id="line-3357"> public int movedRegionCacheExpiredTime() {</span>
+<span class="source-line-no">3358</span><span id="line-3358"> return TIMEOUT_REGION_MOVED;</span>
<span class="source-line-no">3359</span><span id="line-3359"> }</span>
<span class="source-line-no">3360</span><span id="line-3360"></span>
-<span class="source-line-no">3361</span><span id="line-3361"> private boolean isHealthCheckerConfigured() {</span>
-<span class="source-line-no">3362</span><span id="line-3362"> String healthScriptLocation = this.conf.get(HConstants.HEALTH_SCRIPT_LOC);</span>
-<span class="source-line-no">3363</span><span id="line-3363"> return org.apache.commons.lang3.StringUtils.isNotBlank(healthScriptLocation);</span>
-<span class="source-line-no">3364</span><span id="line-3364"> }</span>
-<span class="source-line-no">3365</span><span id="line-3365"></span>
-<span class="source-line-no">3366</span><span id="line-3366"> /** Returns the underlying {@link CompactSplit} for the servers */</span>
-<span class="source-line-no">3367</span><span id="line-3367"> public CompactSplit getCompactSplitThread() {</span>
-<span class="source-line-no">3368</span><span id="line-3368"> return this.compactSplitThread;</span>
-<span class="source-line-no">3369</span><span id="line-3369"> }</span>
-<span class="source-line-no">3370</span><span id="line-3370"></span>
-<span class="source-line-no">3371</span><span id="line-3371"> CoprocessorServiceResponse execRegionServerService(</span>
-<span class="source-line-no">3372</span><span id="line-3372"> @SuppressWarnings("UnusedParameters") final RpcController controller,</span>
-<span class="source-line-no">3373</span><span id="line-3373"> final CoprocessorServiceRequest serviceRequest) throws ServiceException {</span>
-<span class="source-line-no">3374</span><span id="line-3374"> try {</span>
-<span class="source-line-no">3375</span><span id="line-3375"> ServerRpcController serviceController = new ServerRpcController();</span>
-<span class="source-line-no">3376</span><span id="line-3376"> CoprocessorServiceCall call = serviceRequest.getCall();</span>
-<span class="source-line-no">3377</span><span id="line-3377"> String serviceName = call.getServiceName();</span>
-<span class="source-line-no">3378</span><span id="line-3378"> Service service = coprocessorServiceHandlers.get(serviceName);</span>
-<span class="source-line-no">3379</span><span id="line-3379"> if (service == null) {</span>
-<span class="source-line-no">3380</span><span id="line-3380"> throw new UnknownProtocolException(null,</span>
-<span class="source-line-no">3381</span><span id="line-3381"> "No registered coprocessor executorService found for " + serviceName);</span>
-<span class="source-line-no">3382</span><span id="line-3382"> }</span>
-<span class="source-line-no">3383</span><span id="line-3383"> ServiceDescriptor serviceDesc = service.getDescriptorForType();</span>
-<span class="source-line-no">3384</span><span id="line-3384"></span>
-<span class="source-line-no">3385</span><span id="line-3385"> String methodName = call.getMethodName();</span>
-<span class="source-line-no">3386</span><span id="line-3386"> MethodDescriptor methodDesc = serviceDesc.findMethodByName(methodName);</span>
-<span class="source-line-no">3387</span><span id="line-3387"> if (methodDesc == null) {</span>
-<span class="source-line-no">3388</span><span id="line-3388"> throw new UnknownProtocolException(service.getClass(),</span>
-<span class="source-line-no">3389</span><span id="line-3389"> "Unknown method " + methodName + " called on executorService " + serviceName);</span>
-<span class="source-line-no">3390</span><span id="line-3390"> }</span>
-<span class="source-line-no">3391</span><span id="line-3391"></span>
-<span class="source-line-no">3392</span><span id="line-3392"> Message request = CoprocessorRpcUtils.getRequest(service, methodDesc, call.getRequest());</span>
-<span class="source-line-no">3393</span><span id="line-3393"> final Message.Builder responseBuilder =</span>
-<span class="source-line-no">3394</span><span id="line-3394"> service.getResponsePrototype(methodDesc).newBuilderForType();</span>
-<span class="source-line-no">3395</span><span id="line-3395"> service.callMethod(methodDesc, serviceController, request, message -> {</span>
-<span class="source-line-no">3396</span><span id="line-3396"> if (message != null) {</span>
-<span class="source-line-no">3397</span><span id="line-3397"> responseBuilder.mergeFrom(message);</span>
-<span class="source-line-no">3398</span><span id="line-3398"> }</span>
-<span class="source-line-no">3399</span><span id="line-3399"> });</span>
-<span class="source-line-no">3400</span><span id="line-3400"> IOException exception = CoprocessorRpcUtils.getControllerException(serviceController);</span>
-<span class="source-line-no">3401</span><span id="line-3401"> if (exception != null) {</span>
-<span class="source-line-no">3402</span><span id="line-3402"> throw exception;</span>
-<span class="source-line-no">3403</span><span id="line-3403"> }</span>
-<span class="source-line-no">3404</span><span id="line-3404"> return CoprocessorRpcUtils.getResponse(responseBuilder.build(), HConstants.EMPTY_BYTE_ARRAY);</span>
-<span class="source-line-no">3405</span><span id="line-3405"> } catch (IOException ie) {</span>
-<span class="source-line-no">3406</span><span id="line-3406"> throw new ServiceException(ie);</span>
-<span class="source-line-no">3407</span><span id="line-3407"> }</span>
-<span class="source-line-no">3408</span><span id="line-3408"> }</span>
-<span class="source-line-no">3409</span><span id="line-3409"></span>
-<span class="source-line-no">3410</span><span id="line-3410"> /**</span>
-<span class="source-line-no">3411</span><span id="line-3411"> * May be null if this is a master which not carry table.</span>
-<span class="source-line-no">3412</span><span id="line-3412"> * @return The block cache instance used by the regionserver.</span>
-<span class="source-line-no">3413</span><span id="line-3413"> */</span>
-<span class="source-line-no">3414</span><span id="line-3414"> @Override</span>
-<span class="source-line-no">3415</span><span id="line-3415"> public Optional<BlockCache> getBlockCache() {</span>
-<span class="source-line-no">3416</span><span id="line-3416"> return Optional.ofNullable(this.blockCache);</span>
-<span class="source-line-no">3417</span><span id="line-3417"> }</span>
-<span class="source-line-no">3418</span><span id="line-3418"></span>
-<span class="source-line-no">3419</span><span id="line-3419"> /**</span>
-<span class="source-line-no">3420</span><span id="line-3420"> * May be null if this is a master which not carry table.</span>
-<span class="source-line-no">3421</span><span id="line-3421"> * @return The cache for mob files used by the regionserver.</span>
-<span class="source-line-no">3422</span><span id="line-3422"> */</span>
-<span class="source-line-no">3423</span><span id="line-3423"> @Override</span>
-<span class="source-line-no">3424</span><span id="line-3424"> public Optional<MobFileCache> getMobFileCache() {</span>
-<span class="source-line-no">3425</span><span id="line-3425"> return Optional.ofNullable(this.mobFileCache);</span>
-<span class="source-line-no">3426</span><span id="line-3426"> }</span>
-<span class="source-line-no">3427</span><span id="line-3427"></span>
-<span class="source-line-no">3428</span><span id="line-3428"> CacheEvictionStats clearRegionBlockCache(Region region) {</span>
-<span class="source-line-no">3429</span><span id="line-3429"> long evictedBlocks = 0;</span>
-<span class="source-line-no">3430</span><span id="line-3430"></span>
-<span class="source-line-no">3431</span><span id="line-3431"> for (Store store : region.getStores()) {</span>
-<span class="source-line-no">3432</span><span id="line-3432"> for (StoreFile hFile : store.getStorefiles()) {</span>
-<span class="source-line-no">3433</span><span id="line-3433"> evictedBlocks += blockCache.evictBlocksByHfileName(hFile.getPath().getName());</span>
-<span class="source-line-no">3434</span><span id="line-3434"> }</span>
-<span class="source-line-no">3435</span><span id="line-3435"> }</span>
-<span class="source-line-no">3436</span><span id="line-3436"></span>
-<span class="source-line-no">3437</span><span id="line-3437"> return CacheEvictionStats.builder().withEvictedBlocks(evictedBlocks).build();</span>
-<span class="source-line-no">3438</span><span id="line-3438"> }</span>
-<span class="source-line-no">3439</span><span id="line-3439"></span>
-<span class="source-line-no">3440</span><span id="line-3440"> @Override</span>
-<span class="source-line-no">3441</span><span id="line-3441"> public double getCompactionPressure() {</span>
-<span class="source-line-no">3442</span><span id="line-3442"> double max = 0;</span>
-<span class="source-line-no">3443</span><span id="line-3443"> for (Region region : onlineRegions.values()) {</span>
-<span class="source-line-no">3444</span><span id="line-3444"> for (Store store : region.getStores()) {</span>
-<span class="source-line-no">3445</span><span id="line-3445"> double normCount = store.getCompactionPressure();</span>
-<span class="source-line-no">3446</span><span id="line-3446"> if (normCount > max) {</span>
-<span class="source-line-no">3447</span><span id="line-3447"> max = normCount;</span>
-<span class="source-line-no">3448</span><span id="line-3448"> }</span>
-<span class="source-line-no">3449</span><span id="line-3449"> }</span>
-<span class="source-line-no">3450</span><span id="line-3450"> }</span>
-<span class="source-line-no">3451</span><span id="line-3451"> return max;</span>
-<span class="source-line-no">3452</span><span id="line-3452"> }</span>
-<span class="source-line-no">3453</span><span id="line-3453"></span>
-<span class="source-line-no">3454</span><span id="line-3454"> @Override</span>
-<span class="source-line-no">3455</span><span id="line-3455"> public HeapMemoryManager getHeapMemoryManager() {</span>
-<span class="source-line-no">3456</span><span id="line-3456"> return hMemManager;</span>
-<span class="source-line-no">3457</span><span id="line-3457"> }</span>
-<span class="source-line-no">3458</span><span id="line-3458"></span>
-<span class="source-line-no">3459</span><span id="line-3459"> public MemStoreFlusher getMemStoreFlusher() {</span>
-<span class="source-line-no">3460</span><span id="line-3460"> return cacheFlusher;</span>
+<span class="source-line-no">3361</span><span id="line-3361"> private String getMyEphemeralNodePath() {</span>
+<span class="source-line-no">3362</span><span id="line-3362"> return zooKeeper.getZNodePaths().getRsPath(serverName);</span>
+<span class="source-line-no">3363</span><span id="line-3363"> }</span>
+<span class="source-line-no">3364</span><span id="line-3364"></span>
+<span class="source-line-no">3365</span><span id="line-3365"> private boolean isHealthCheckerConfigured() {</span>
+<span class="source-line-no">3366</span><span id="line-3366"> String healthScriptLocation = this.conf.get(HConstants.HEALTH_SCRIPT_LOC);</span>
+<span class="source-line-no">3367</span><span id="line-3367"> return org.apache.commons.lang3.StringUtils.isNotBlank(healthScriptLocation);</span>
+<span class="source-line-no">3368</span><span id="line-3368"> }</span>
+<span class="source-line-no">3369</span><span id="line-3369"></span>
+<span class="source-line-no">3370</span><span id="line-3370"> /** Returns the underlying {@link CompactSplit} for the servers */</span>
+<span class="source-line-no">3371</span><span id="line-3371"> public CompactSplit getCompactSplitThread() {</span>
+<span class="source-line-no">3372</span><span id="line-3372"> return this.compactSplitThread;</span>
+<span class="source-line-no">3373</span><span id="line-3373"> }</span>
+<span class="source-line-no">3374</span><span id="line-3374"></span>
+<span class="source-line-no">3375</span><span id="line-3375"> CoprocessorServiceResponse execRegionServerService(</span>
+<span class="source-line-no">3376</span><span id="line-3376"> @SuppressWarnings("UnusedParameters") final RpcController controller,</span>
+<span class="source-line-no">3377</span><span id="line-3377"> final CoprocessorServiceRequest serviceRequest) throws ServiceException {</span>
+<span class="source-line-no">3378</span><span id="line-3378"> try {</span>
+<span class="source-line-no">3379</span><span id="line-3379"> ServerRpcController serviceController = new ServerRpcController();</span>
+<span class="source-line-no">3380</span><span id="line-3380"> CoprocessorServiceCall call = serviceRequest.getCall();</span>
+<span class="source-line-no">3381</span><span id="line-3381"> String serviceName = call.getServiceName();</span>
+<span class="source-line-no">3382</span><span id="line-3382"> Service service = coprocessorServiceHandlers.get(serviceName);</span>
+<span class="source-line-no">3383</span><span id="line-3383"> if (service == null) {</span>
+<span class="source-line-no">3384</span><span id="line-3384"> throw new UnknownProtocolException(null,</span>
+<span class="source-line-no">3385</span><span id="line-3385"> "No registered coprocessor executorService found for " + serviceName);</span>
+<span class="source-line-no">3386</span><span id="line-3386"> }</span>
+<span class="source-line-no">3387</span><span id="line-3387"> ServiceDescriptor serviceDesc = service.getDescriptorForType();</span>
+<span class="source-line-no">3388</span><span id="line-3388"></span>
+<span class="source-line-no">3389</span><span id="line-3389"> String methodName = call.getMethodName();</span>
+<span class="source-line-no">3390</span><span id="line-3390"> MethodDescriptor methodDesc = serviceDesc.findMethodByName(methodName);</span>
+<span class="source-line-no">3391</span><span id="line-3391"> if (methodDesc == null) {</span>
+<span class="source-line-no">3392</span><span id="line-3392"> throw new UnknownProtocolException(service.getClass(),</span>
+<span class="source-line-no">3393</span><span id="line-3393"> "Unknown method " + methodName + " called on executorService " + serviceName);</span>
+<span class="source-line-no">3394</span><span id="line-3394"> }</span>
+<span class="source-line-no">3395</span><span id="line-3395"></span>
+<span class="source-line-no">3396</span><span id="line-3396"> Message request = CoprocessorRpcUtils.getRequest(service, methodDesc, call.getRequest());</span>
+<span class="source-line-no">3397</span><span id="line-3397"> final Message.Builder responseBuilder =</span>
+<span class="source-line-no">3398</span><span id="line-3398"> service.getResponsePrototype(methodDesc).newBuilderForType();</span>
+<span class="source-line-no">3399</span><span id="line-3399"> service.callMethod(methodDesc, serviceController, request, message -> {</span>
+<span class="source-line-no">3400</span><span id="line-3400"> if (message != null) {</span>
+<span class="source-line-no">3401</span><span id="line-3401"> responseBuilder.mergeFrom(message);</span>
+<span class="source-line-no">3402</span><span id="line-3402"> }</span>
+<span class="source-line-no">3403</span><span id="line-3403"> });</span>
+<span class="source-line-no">3404</span><span id="line-3404"> IOException exception = CoprocessorRpcUtils.getControllerException(serviceController);</span>
+<span class="source-line-no">3405</span><span id="line-3405"> if (exception != null) {</span>
+<span class="source-line-no">3406</span><span id="line-3406"> throw exception;</span>
+<span class="source-line-no">3407</span><span id="line-3407"> }</span>
+<span class="source-line-no">3408</span><span id="line-3408"> return CoprocessorRpcUtils.getResponse(responseBuilder.build(), HConstants.EMPTY_BYTE_ARRAY);</span>
+<span class="source-line-no">3409</span><span id="line-3409"> } catch (IOException ie) {</span>
+<span class="source-line-no">3410</span><span id="line-3410"> throw new ServiceException(ie);</span>
+<span class="source-line-no">3411</span><span id="line-3411"> }</span>
+<span class="source-line-no">3412</span><span id="line-3412"> }</span>
+<span class="source-line-no">3413</span><span id="line-3413"></span>
+<span class="source-line-no">3414</span><span id="line-3414"> /**</span>
+<span class="source-line-no">3415</span><span id="line-3415"> * May be null if this is a master which not carry table.</span>
+<span class="source-line-no">3416</span><span id="line-3416"> * @return The block cache instance used by the regionserver.</span>
+<span class="source-line-no">3417</span><span id="line-3417"> */</span>
+<span class="source-line-no">3418</span><span id="line-3418"> @Override</span>
+<span class="source-line-no">3419</span><span id="line-3419"> public Optional<BlockCache> getBlockCache() {</span>
+<span class="source-line-no">3420</span><span id="line-3420"> return Optional.ofNullable(this.blockCache);</span>
+<span class="source-line-no">3421</span><span id="line-3421"> }</span>
+<span class="source-line-no">3422</span><span id="line-3422"></span>
+<span class="source-line-no">3423</span><span id="line-3423"> /**</span>
+<span class="source-line-no">3424</span><span id="line-3424"> * May be null if this is a master which not carry table.</span>
+<span class="source-line-no">3425</span><span id="line-3425"> * @return The cache for mob files used by the regionserver.</span>
+<span class="source-line-no">3426</span><span id="line-3426"> */</span>
+<span class="source-line-no">3427</span><span id="line-3427"> @Override</span>
+<span class="source-line-no">3428</span><span id="line-3428"> public Optional<MobFileCache> getMobFileCache() {</span>
+<span class="source-line-no">3429</span><span id="line-3429"> return Optional.ofNullable(this.mobFileCache);</span>
+<span class="source-line-no">3430</span><span id="line-3430"> }</span>
+<span class="source-line-no">3431</span><span id="line-3431"></span>
+<span class="source-line-no">3432</span><span id="line-3432"> CacheEvictionStats clearRegionBlockCache(Region region) {</span>
+<span class="source-line-no">3433</span><span id="line-3433"> long evictedBlocks = 0;</span>
+<span class="source-line-no">3434</span><span id="line-3434"></span>
+<span class="source-line-no">3435</span><span id="line-3435"> for (Store store : region.getStores()) {</span>
+<span class="source-line-no">3436</span><span id="line-3436"> for (StoreFile hFile : store.getStorefiles()) {</span>
+<span class="source-line-no">3437</span><span id="line-3437"> evictedBlocks += blockCache.evictBlocksByHfileName(hFile.getPath().getName());</span>
+<span class="source-line-no">3438</span><span id="line-3438"> }</span>
+<span class="source-line-no">3439</span><span id="line-3439"> }</span>
+<span class="source-line-no">3440</span><span id="line-3440"></span>
+<span class="source-line-no">3441</span><span id="line-3441"> return CacheEvictionStats.builder().withEvictedBlocks(evictedBlocks).build();</span>
+<span class="source-line-no">3442</span><span id="line-3442"> }</span>
+<span class="source-line-no">3443</span><span id="line-3443"></span>
+<span class="source-line-no">3444</span><span id="line-3444"> @Override</span>
+<span class="source-line-no">3445</span><span id="line-3445"> public double getCompactionPressure() {</span>
+<span class="source-line-no">3446</span><span id="line-3446"> double max = 0;</span>
+<span class="source-line-no">3447</span><span id="line-3447"> for (Region region : onlineRegions.values()) {</span>
+<span class="source-line-no">3448</span><span id="line-3448"> for (Store store : region.getStores()) {</span>
+<span class="source-line-no">3449</span><span id="line-3449"> double normCount = store.getCompactionPressure();</span>
+<span class="source-line-no">3450</span><span id="line-3450"> if (normCount > max) {</span>
+<span class="source-line-no">3451</span><span id="line-3451"> max = normCount;</span>
+<span class="source-line-no">3452</span><span id="line-3452"> }</span>
+<span class="source-line-no">3453</span><span id="line-3453"> }</span>
+<span class="source-line-no">3454</span><span id="line-3454"> }</span>
+<span class="source-line-no">3455</span><span id="line-3455"> return max;</span>
+<span class="source-line-no">3456</span><span id="line-3456"> }</span>
+<span class="source-line-no">3457</span><span id="line-3457"></span>
+<span class="source-line-no">3458</span><span id="line-3458"> @Override</span>
+<span class="source-line-no">3459</span><span id="line-3459"> public HeapMemoryManager getHeapMemoryManager() {</span>
+<span class="source-line-no">3460</span><span id="line-3460"> return hMemManager;</span>
<span class="source-line-no">3461</span><span id="line-3461"> }</span>
<span class="source-line-no">3462</span><span id="line-3462"></span>
-<span class="source-line-no">3463</span><span id="line-3463"> /**</span>
-<span class="source-line-no">3464</span><span id="line-3464"> * For testing</span>
-<span class="source-line-no">3465</span><span id="line-3465"> * @return whether all wal roll request finished for this regionserver</span>
-<span class="source-line-no">3466</span><span id="line-3466"> */</span>
-<span class="source-line-no">3467</span><span id="line-3467"> @InterfaceAudience.Private</span>
-<span class="source-line-no">3468</span><span id="line-3468"> public boolean walRollRequestFinished() {</span>
-<span class="source-line-no">3469</span><span id="line-3469"> return this.walRoller.walRollFinished();</span>
-<span class="source-line-no">3470</span><span id="line-3470"> }</span>
-<span class="source-line-no">3471</span><span id="line-3471"></span>
-<span class="source-line-no">3472</span><span id="line-3472"> @Override</span>
-<span class="source-line-no">3473</span><span id="line-3473"> public ThroughputController getFlushThroughputController() {</span>
-<span class="source-line-no">3474</span><span id="line-3474"> return flushThroughputController;</span>
-<span class="source-line-no">3475</span><span id="line-3475"> }</span>
-<span class="source-line-no">3476</span><span id="line-3476"></span>
-<span class="source-line-no">3477</span><span id="line-3477"> @Override</span>
-<span class="source-line-no">3478</span><span id="line-3478"> public double getFlushPressure() {</span>
-<span class="source-line-no">3479</span><span id="line-3479"> if (getRegionServerAccounting() == null || cacheFlusher == null) {</span>
-<span class="source-line-no">3480</span><span id="line-3480"> // return 0 during RS initialization</span>
-<span class="source-line-no">3481</span><span id="line-3481"> return 0.0;</span>
-<span class="source-line-no">3482</span><span id="line-3482"> }</span>
-<span class="source-line-no">3483</span><span id="line-3483"> return getRegionServerAccounting().getFlushPressure();</span>
-<span class="source-line-no">3484</span><span id="line-3484"> }</span>
-<span class="source-line-no">3485</span><span id="line-3485"></span>
-<span class="source-line-no">3486</span><span id="line-3486"> /**</span>
-<span class="source-line-no">3487</span><span id="line-3487"> * Dynamically updates HRegionServer's configuration. Since HRegionServer inherits from</span>
-<span class="source-line-no">3488</span><span id="line-3488"> * {@link HBaseServerBase}, the {@code updatedConf} parameter references the same</span>
-<span class="source-line-no">3489</span><span id="line-3489"> * {@link Configuration} object as HRegionServer's {@code this.conf} instance variable in a real</span>
-<span class="source-line-no">3490</span><span id="line-3490"> * HBase deployment. This isn't necessarily the case in unit tests.</span>
-<span class="source-line-no">3491</span><span id="line-3491"> * @param updatedConf the dynamically updated configuration</span>
-<span class="source-line-no">3492</span><span id="line-3492"> */</span>
-<span class="source-line-no">3493</span><span id="line-3493"> @Override</span>
-<span class="source-line-no">3494</span><span id="line-3494"> public void onConfigurationChange(Configuration updatedConf) {</span>
-<span class="source-line-no">3495</span><span id="line-3495"> ThroughputController old = this.flushThroughputController;</span>
-<span class="source-line-no">3496</span><span id="line-3496"> if (old != null) {</span>
-<span class="source-line-no">3497</span><span id="line-3497"> old.stop("configuration change");</span>
-<span class="source-line-no">3498</span><span id="line-3498"> }</span>
-<span class="source-line-no">3499</span><span id="line-3499"> this.flushThroughputController = FlushThroughputControllerFactory.create(this, updatedConf);</span>
-<span class="source-line-no">3500</span><span id="line-3500"> try {</span>
-<span class="source-line-no">3501</span><span id="line-3501"> Superusers.initialize(updatedConf);</span>
-<span class="source-line-no">3502</span><span id="line-3502"> } catch (IOException e) {</span>
-<span class="source-line-no">3503</span><span id="line-3503"> LOG.warn("Failed to initialize SuperUsers on reloading of the configuration");</span>
-<span class="source-line-no">3504</span><span id="line-3504"> }</span>
-<span class="source-line-no">3505</span><span id="line-3505"></span>
-<span class="source-line-no">3506</span><span id="line-3506"> boolean originalIsReadOnlyEnabled = CoprocessorConfigurationUtil</span>
-<span class="source-line-no">3507</span><span id="line-3507"> .areReadOnlyCoprocessorsLoaded(this.conf, CoprocessorHost.REGIONSERVER_COPROCESSOR_CONF_KEY);</span>
-<span class="source-line-no">3508</span><span id="line-3508"></span>
-<span class="source-line-no">3509</span><span id="line-3509"> // updatedConf and this.conf reference the same Configuration object in an actual HBase</span>
-<span class="source-line-no">3510</span><span id="line-3510"> // deployment. However, in unit test cases they reference different Configuration objects, so</span>
-<span class="source-line-no">3511</span><span id="line-3511"> // this.conf needs to be updated.</span>
-<span class="source-line-no">3512</span><span id="line-3512"> CoprocessorConfigurationUtil.maybeUpdateCoprocessors(updatedConf, this.conf,</span>
-<span class="source-line-no">3513</span><span id="line-3513"> originalIsReadOnlyEnabled, this.rsHost, CoprocessorHost.REGIONSERVER_COPROCESSOR_CONF_KEY,</span>
-<span class="source-line-no">3514</span><span id="line-3514"> false, this.toString(), conf -> this.rsHost = new RegionServerCoprocessorHost(this, conf));</span>
-<span class="source-line-no">3515</span><span id="line-3515"> }</span>
-<span class="source-line-no">3516</span><span id="line-3516"></span>
-<span class="source-line-no">3517</span><span id="line-3517"> @Override</span>
-<span class="source-line-no">3518</span><span id="line-3518"> public MetricsRegionServer getMetrics() {</span>
-<span class="source-line-no">3519</span><span id="line-3519"> return metricsRegionServer;</span>
-<span class="source-line-no">3520</span><span id="line-3520"> }</span>
-<span class="source-line-no">3521</span><span id="line-3521"></span>
-<span class="source-line-no">3522</span><span id="line-3522"> @Override</span>
-<span class="source-line-no">3523</span><span id="line-3523"> public SecureBulkLoadManager getSecureBulkLoadManager() {</span>
-<span class="source-line-no">3524</span><span id="line-3524"> return this.secureBulkLoadManager;</span>
-<span class="source-line-no">3525</span><span id="line-3525"> }</span>
-<span class="source-line-no">3526</span><span id="line-3526"></span>
-<span class="source-line-no">3527</span><span id="line-3527"> @Override</span>
-<span class="source-line-no">3528</span><span id="line-3528"> public EntityLock regionLock(final List<RegionInfo> regionInfo, final String description,</span>
-<span class="source-line-no">3529</span><span id="line-3529"> final Abortable abort) {</span>
-<span class="source-line-no">3530</span><span id="line-3530"> final LockServiceClient client =</span>
-<span class="source-line-no">3531</span><span id="line-3531"> new LockServiceClient(conf, lockStub, asyncClusterConnection.getNonceGenerator());</span>
-<span class="source-line-no">3532</span><span id="line-3532"> return client.regionLock(regionInfo, description, abort);</span>
-<span class="source-line-no">3533</span><span id="line-3533"> }</span>
-<span class="source-line-no">3534</span><span id="line-3534"></span>
-<span class="source-line-no">3535</span><span id="line-3535"> @Override</span>
-<span class="source-line-no">3536</span><span id="line-3536"> public void unassign(byte[] regionName) throws IOException {</span>
-<span class="source-line-no">3537</span><span id="line-3537"> FutureUtils.get(asyncClusterConnection.getAdmin().unassign(regionName, false));</span>
-<span class="source-line-no">3538</span><span id="line-3538"> }</span>
-<span class="source-line-no">3539</span><span id="line-3539"></span>
-<span class="source-line-no">3540</span><span id="line-3540"> @Override</span>
-<span class="source-line-no">3541</span><span id="line-3541"> public RegionServerSpaceQuotaManager getRegionServerSpaceQuotaManager() {</span>
-<span class="source-line-no">3542</span><span id="line-3542"> return this.rsSpaceQuotaManager;</span>
-<span class="source-line-no">3543</span><span id="line-3543"> }</span>
-<span class="source-line-no">3544</span><span id="line-3544"></span>
-<span class="source-line-no">3545</span><span id="line-3545"> @Override</span>
-<span class="source-line-no">3546</span><span id="line-3546"> public boolean reportFileArchivalForQuotas(TableName tableName,</span>
-<span class="source-line-no">3547</span><span id="line-3547"> Collection<Entry<String, Long>> archivedFiles) {</span>
-<span class="source-line-no">3548</span><span id="line-3548"> if (TEST_SKIP_REPORTING_TRANSITION) {</span>
-<span class="source-line-no">3549</span><span id="line-3549"> return false;</span>
-<span class="source-line-no">3550</span><span id="line-3550"> }</span>
-<span class="source-line-no">3551</span><span id="line-3551"> RegionServerStatusService.BlockingInterface rss = rssStub;</span>
-<span class="source-line-no">3552</span><span id="line-3552"> if (rss == null || rsSpaceQuotaManager == null) {</span>
-<span class="source-line-no">3553</span><span id="line-3553"> // the current server could be stopping.</span>
-<span class="source-line-no">3554</span><span id="line-3554"> LOG.trace("Skipping file archival reporting to HMaster as stub is null");</span>
-<span class="source-line-no">3555</span><span id="line-3555"> return false;</span>
-<span class="source-line-no">3556</span><span id="line-3556"> }</span>
-<span class="source-line-no">3557</span><span id="line-3557"> try {</span>
-<span class="source-line-no">3558</span><span id="line-3558"> RegionServerStatusProtos.FileArchiveNotificationRequest request =</span>
-<span class="source-line-no">3559</span><span id="line-3559"> rsSpaceQuotaManager.buildFileArchiveRequest(tableName, archivedFiles);</span>
-<span class="source-line-no">3560</span><span id="line-3560"> rss.reportFileArchival(null, request);</span>
-<span class="source-line-no">3561</span><span id="line-3561"> } catch (ServiceException se) {</span>
-<span class="source-line-no">3562</span><span id="line-3562"> IOException ioe = ProtobufUtil.getRemoteException(se);</span>
-<span class="source-line-no">3563</span><span id="line-3563"> if (ioe instanceof PleaseHoldException) {</span>
-<span class="source-line-no">3564</span><span id="line-3564"> if (LOG.isTraceEnabled()) {</span>
-<span class="source-line-no">3565</span><span id="line-3565"> LOG.trace("Failed to report file archival(s) to Master because it is initializing."</span>
-<span class="source-line-no">3566</span><span id="line-3566"> + " This will be retried.", ioe);</span>
-<span class="source-line-no">3567</span><span id="line-3567"> }</span>
-<span class="source-line-no">3568</span><span id="line-3568"> // The Master is coming up. Will retry the report later. Avoid re-creating the stub.</span>
-<span class="source-line-no">3569</span><span id="line-3569"> return false;</span>
-<span class="source-line-no">3570</span><span id="line-3570"> }</span>
-<span class="source-line-no">3571</span><span id="line-3571"> if (rssStub == rss) {</span>
-<span class="source-line-no">3572</span><span id="line-3572"> rssStub = null;</span>
-<span class="source-line-no">3573</span><span id="line-3573"> }</span>
-<span class="source-line-no">3574</span><span id="line-3574"> // re-create the stub if we failed to report the archival</span>
-<span class="source-line-no">3575</span><span id="line-3575"> createRegionServerStatusStub(true);</span>
-<span class="source-line-no">3576</span><span id="line-3576"> LOG.debug("Failed to report file archival(s) to Master. This will be retried.", ioe);</span>
-<span class="source-line-no">3577</span><span id="line-3577"> return false;</span>
-<span class="source-line-no">3578</span><span id="line-3578"> }</span>
-<span class="source-line-no">3579</span><span id="line-3579"> return true;</span>
-<span class="source-line-no">3580</span><span id="line-3580"> }</span>
-<span class="source-line-no">3581</span><span id="line-3581"></span>
-<span class="source-line-no">3582</span><span id="line-3582"> void executeProcedure(long procId, long initiatingMasterActiveTime,</span>
-<span class="source-line-no">3583</span><span id="line-3583"> RSProcedureCallable callable) {</span>
-<span class="source-line-no">3584</span><span id="line-3584"> executorService</span>
-<span class="source-line-no">3585</span><span id="line-3585"> .submit(new RSProcedureHandler(this, procId, initiatingMasterActiveTime, callable));</span>
-<span class="source-line-no">3586</span><span id="line-3586"> }</span>
-<span class="source-line-no">3587</span><span id="line-3587"></span>
-<span class="source-line-no">3588</span><span id="line-3588"> public void remoteProcedureComplete(long procId, long initiatingMasterActiveTime, Throwable error,</span>
-<span class="source-line-no">3589</span><span id="line-3589"> byte[] procResultData) {</span>
-<span class="source-line-no">3590</span><span id="line-3590"> procedureResultReporter.complete(procId, initiatingMasterActiveTime, error, procResultData);</span>
-<span class="source-line-no">3591</span><span id="line-3591"> }</span>
-<span class="source-line-no">3592</span><span id="line-3592"></span>
-<span class="source-line-no">3593</span><span id="line-3593"> void reportProcedureDone(ReportProcedureDoneRequest request) throws IOException {</span>
-<span class="source-line-no">3594</span><span id="line-3594"> RegionServerStatusService.BlockingInterface rss;</span>
-<span class="source-line-no">3595</span><span id="line-3595"> // TODO: juggling class state with an instance variable, outside of a synchronized block :'(</span>
-<span class="source-line-no">3596</span><span id="line-3596"> for (;;) {</span>
-<span class="source-line-no">3597</span><span id="line-3597"> rss = rssStub;</span>
-<span class="source-line-no">3598</span><span id="line-3598"> if (rss != null) {</span>
-<span class="source-line-no">3599</span><span id="line-3599"> break;</span>
-<span class="source-line-no">3600</span><span id="line-3600"> }</span>
-<span class="source-line-no">3601</span><span id="line-3601"> createRegionServerStatusStub();</span>
-<span class="source-line-no">3602</span><span id="line-3602"> }</span>
-<span class="source-line-no">3603</span><span id="line-3603"> try {</span>
-<span class="source-line-no">3604</span><span id="line-3604"> rss.reportProcedureDone(null, request);</span>
-<span class="source-line-no">3605</span><span id="line-3605"> } catch (ServiceException se) {</span>
-<span class="source-line-no">3606</span><span id="line-3606"> if (rssStub == rss) {</span>
-<span class="source-line-no">3607</span><span id="line-3607"> rssStub = null;</span>
-<span class="source-line-no">3608</span><span id="line-3608"> }</span>
-<span class="source-line-no">3609</span><span id="line-3609"> throw ProtobufUtil.getRemoteException(se);</span>
-<span class="source-line-no">3610</span><span id="line-3610"> }</span>
-<span class="source-line-no">3611</span><span id="line-3611"> }</span>
-<span class="source-line-no">3612</span><span id="line-3612"></span>
-<span class="source-line-no">3613</span><span id="line-3613"> /**</span>
-<span class="source-line-no">3614</span><span id="line-3614"> * Will ignore the open/close region procedures which already submitted or executed. When master</span>
-<span class="source-line-no">3615</span><span id="line-3615"> * had unfinished open/close region procedure and restarted, new active master may send duplicate</span>
-<span class="source-line-no">3616</span><span id="line-3616"> * open/close region request to regionserver. The open/close request is submitted to a thread pool</span>
-<span class="source-line-no">3617</span><span id="line-3617"> * and execute. So first need a cache for submitted open/close region procedures. After the</span>
-<span class="source-line-no">3618</span><span id="line-3618"> * open/close region request executed and report region transition succeed, cache it in executed</span>
-<span class="source-line-no">3619</span><span id="line-3619"> * region procedures cache. See {@link #finishRegionProcedure(long)}. After report region</span>
-<span class="source-line-no">3620</span><span id="line-3620"> * transition succeed, master will not send the open/close region request to regionserver again.</span>
-<span class="source-line-no">3621</span><span id="line-3621"> * And we thought that the ongoing duplicate open/close region request should not be delayed more</span>
-<span class="source-line-no">3622</span><span id="line-3622"> * than 600 seconds. So the executed region procedures cache will expire after 600 seconds. See</span>
-<span class="source-line-no">3623</span><span id="line-3623"> * HBASE-22404 for more details.</span>
-<span class="source-line-no">3624</span><span id="line-3624"> * @param procId the id of the open/close region procedure</span>
-<span class="source-line-no">3625</span><span id="line-3625"> * @return true if the procedure can be submitted.</span>
-<span class="source-line-no">3626</span><span id="line-3626"> */</span>
-<span class="source-line-no">3627</span><span id="line-3627"> boolean submitRegionProcedure(long procId) {</span>
-<span class="source-line-no">3628</span><span id="line-3628"> if (procId == -1) {</span>
-<span class="source-line-no">3629</span><span id="line-3629"> return true;</span>
-<span class="source-line-no">3630</span><span id="line-3630"> }</span>
-<span class="source-line-no">3631</span><span id="line-3631"> // Ignore the region procedures which already submitted.</span>
-<span class="source-line-no">3632</span><span id="line-3632"> Long previous = submittedRegionProcedures.putIfAbsent(procId, procId);</span>
-<span class="source-line-no">3633</span><span id="line-3633"> if (previous != null) {</span>
-<span class="source-line-no">3634</span><span id="line-3634"> LOG.warn("Received procedure pid={}, which already submitted, just ignore it", procId);</span>
-<span class="source-line-no">3635</span><span id="line-3635"> return false;</span>
-<span class="source-line-no">3636</span><span id="line-3636"> }</span>
-<span class="source-line-no">3637</span><span id="line-3637"> // Ignore the region procedures which already executed.</span>
-<span class="source-line-no">3638</span><span id="line-3638"> if (executedRegionProcedures.getIfPresent(procId) != null) {</span>
-<span class="source-line-no">3639</span><span id="line-3639"> LOG.warn("Received procedure pid={}, which already executed, just ignore it", procId);</span>
-<span class="source-line-no">3640</span><span id="line-3640"> return false;</span>
-<span class="source-line-no">3641</span><span id="line-3641"> }</span>
-<span class="source-line-no">3642</span><span id="line-3642"> return true;</span>
-<span class="source-line-no">3643</span><span id="line-3643"> }</span>
-<span class="source-line-no">3644</span><span id="line-3644"></span>
-<span class="source-line-no">3645</span><span id="line-3645"> /**</span>
-<span class="source-line-no">3646</span><span id="line-3646"> * See {@link #submitRegionProcedure(long)}.</span>
-<span class="source-line-no">3647</span><span id="line-3647"> * @param procId the id of the open/close region procedure</span>
-<span class="source-line-no">3648</span><span id="line-3648"> */</span>
-<span class="source-line-no">3649</span><span id="line-3649"> public void finishRegionProcedure(long procId) {</span>
-<span class="source-line-no">3650</span><span id="line-3650"> executedRegionProcedures.put(procId, procId);</span>
-<span class="source-line-no">3651</span><span id="line-3651"> submittedRegionProcedures.remove(procId);</span>
-<span class="source-line-no">3652</span><span id="line-3652"> }</span>
-<span class="source-line-no">3653</span><span id="line-3653"></span>
-<span class="source-line-no">3654</span><span id="line-3654"> /**</span>
-<span class="source-line-no">3655</span><span id="line-3655"> * Force to terminate region server when abort timeout.</span>
-<span class="source-line-no">3656</span><span id="line-3656"> */</span>
-<span class="source-line-no">3657</span><span id="line-3657"> private static class SystemExitWhenAbortTimeout extends TimerTask {</span>
-<span class="source-line-no">3658</span><span id="line-3658"></span>
-<span class="source-line-no">3659</span><span id="line-3659"> public SystemExitWhenAbortTimeout() {</span>
-<span class="source-line-no">3660</span><span id="line-3660"> }</span>
-<span class="source-line-no">3661</span><span id="line-3661"></span>
-<span class="source-line-no">3662</span><span id="line-3662"> @Override</span>
-<span class="source-line-no">3663</span><span id="line-3663"> public void run() {</span>
-<span class="source-line-no">3664</span><span id="line-3664"> LOG.warn("Aborting region server timed out, terminating forcibly"</span>
-<span class="source-line-no">3665</span><span id="line-3665"> + " and does not wait for any running shutdown hooks or finalizers to finish their work."</span>
-<span class="source-line-no">3666</span><span id="line-3666"> + " Thread dump to stdout.");</span>
-<span class="source-line-no">3667</span><span id="line-3667"> Threads.printThreadInfo(System.out, "Zombie HRegionServer");</span>
-<span class="source-line-no">3668</span><span id="line-3668"> Runtime.getRuntime().halt(1);</span>
-<span class="source-line-no">3669</span><span id="line-3669"> }</span>
-<span class="source-line-no">3670</span><span id="line-3670"> }</span>
-<span class="source-line-no">3671</span><span id="line-3671"></span>
-<span class="source-line-no">3672</span><span id="line-3672"> @InterfaceAudience.Private</span>
-<span class="source-line-no">3673</span><span id="line-3673"> public CompactedHFilesDischarger getCompactedHFilesDischarger() {</span>
-<span class="source-line-no">3674</span><span id="line-3674"> return compactedFileDischarger;</span>
-<span class="source-line-no">3675</span><span id="line-3675"> }</span>
-<span class="source-line-no">3676</span><span id="line-3676"></span>
-<span class="source-line-no">3677</span><span id="line-3677"> /**</span>
-<span class="source-line-no">3678</span><span id="line-3678"> * Return pause time configured in {@link HConstants#HBASE_RPC_SHORTOPERATION_RETRY_PAUSE_TIME}}</span>
-<span class="source-line-no">3679</span><span id="line-3679"> * @return pause time</span>
-<span class="source-line-no">3680</span><span id="line-3680"> */</span>
-<span class="source-line-no">3681</span><span id="line-3681"> @InterfaceAudience.Private</span>
-<span class="source-line-no">3682</span><span id="line-3682"> public long getRetryPauseTime() {</span>
-<span class="source-line-no">3683</span><span id="line-3683"> return this.retryPauseTime;</span>
-<span class="source-line-no">3684</span><span id="line-3684"> }</span>
-<span class="source-line-no">3685</span><span id="line-3685"></span>
-<span class="source-line-no">3686</span><span id="line-3686"> @Override</span>
-<span class="source-line-no">3687</span><span id="line-3687"> public Optional<ServerName> getActiveMaster() {</span>
-<span class="source-line-no">3688</span><span id="line-3688"> return Optional.ofNullable(masterAddressTracker.getMasterAddress());</span>
-<span class="source-line-no">3689</span><span id="line-3689"> }</span>
-<span class="source-line-no">3690</span><span id="line-3690"></span>
-<span class="source-line-no">3691</span><span id="line-3691"> @Override</span>
-<span class="source-line-no">3692</span><span id="line-3692"> public List<ServerName> getBackupMasters() {</span>
-<span class="source-line-no">3693</span><span id="line-3693"> return masterAddressTracker.getBackupMasters();</span>
-<span class="source-line-no">3694</span><span id="line-3694"> }</span>
-<span class="source-line-no">3695</span><span id="line-3695"></span>
-<span class="source-line-no">3696</span><span id="line-3696"> @Override</span>
-<span class="source-line-no">3697</span><span id="line-3697"> public Iterator<ServerName> getBootstrapNodes() {</span>
-<span class="source-line-no">3698</span><span id="line-3698"> return bootstrapNodeManager.getBootstrapNodes().iterator();</span>
-<span class="source-line-no">3699</span><span id="line-3699"> }</span>
-<span class="source-line-no">3700</span><span id="line-3700"></span>
-<span class="source-line-no">3701</span><span id="line-3701"> @Override</span>
-<span class="source-line-no">3702</span><span id="line-3702"> public List<HRegionLocation> getMetaLocations() {</span>
-<span class="source-line-no">3703</span><span id="line-3703"> return metaRegionLocationCache.getMetaRegionLocations();</span>
-<span class="source-line-no">3704</span><span id="line-3704"> }</span>
-<span class="source-line-no">3705</span><span id="line-3705"></span>
-<span class="source-line-no">3706</span><span id="line-3706"> @Override</span>
-<span class="source-line-no">3707</span><span id="line-3707"> protected NamedQueueRecorder createNamedQueueRecord() {</span>
-<span class="source-line-no">3708</span><span id="line-3708"> return NamedQueueRecorder.getInstance(conf);</span>
-<span class="source-line-no">3709</span><span id="line-3709"> }</span>
-<span class="source-line-no">3710</span><span id="line-3710"></span>
-<span class="source-line-no">3711</span><span id="line-3711"> @Override</span>
-<span class="source-line-no">3712</span><span id="line-3712"> protected boolean clusterMode() {</span>
-<span class="source-line-no">3713</span><span id="line-3713"> // this method will be called in the constructor of super class, so we can not return masterless</span>
-<span class="source-line-no">3714</span><span id="line-3714"> // directly here, as it will always be false.</span>
-<span class="source-line-no">3715</span><span id="line-3715"> return !conf.getBoolean(MASTERLESS_CONFIG_NAME, false);</span>
-<span class="source-line-no">3716</span><span id="line-3716"> }</span>
-<span class="source-line-no">3717</span><span id="line-3717"></span>
-<span class="source-line-no">3718</span><span id="line-3718"> @InterfaceAudience.Private</span>
-<span class="source-line-no">3719</span><span id="line-3719"> public BrokenStoreFileCleaner getBrokenStoreFileCleaner() {</span>
-<span class="source-line-no">3720</span><span id="line-3720"> return brokenStoreFileCleaner;</span>
-<span class="source-line-no">3721</span><span id="line-3721"> }</span>
-<span class="source-line-no">3722</span><span id="line-3722"></span>
-<span class="source-line-no">3723</span><span id="line-3723"> @InterfaceAudience.Private</span>
-<span class="source-line-no">3724</span><span id="line-3724"> public RSMobFileCleanerChore getRSMobFileCleanerChore() {</span>
-<span class="source-line-no">3725</span><span id="line-3725"> return rsMobFileCleanerChore;</span>
-<span class="source-line-no">3726</span><span id="line-3726"> }</span>
-<span class="source-line-no">3727</span><span id="line-3727"></span>
-<span class="source-line-no">3728</span><span id="line-3728"> RSSnapshotVerifier getRsSnapshotVerifier() {</span>
-<span class="source-line-no">3729</span><span id="line-3729"> return rsSnapshotVerifier;</span>
+<span class="source-line-no">3463</span><span id="line-3463"> public MemStoreFlusher getMemStoreFlusher() {</span>
+<span class="source-line-no">3464</span><span id="line-3464"> return cacheFlusher;</span>
+<span class="source-line-no">3465</span><span id="line-3465"> }</span>
+<span class="source-line-no">3466</span><span id="line-3466"></span>
+<span class="source-line-no">3467</span><span id="line-3467"> /**</span>
+<span class="source-line-no">3468</span><span id="line-3468"> * For testing</span>
+<span class="source-line-no">3469</span><span id="line-3469"> * @return whether all wal roll request finished for this regionserver</span>
+<span class="source-line-no">3470</span><span id="line-3470"> */</span>
+<span class="source-line-no">3471</span><span id="line-3471"> @InterfaceAudience.Private</span>
+<span class="source-line-no">3472</span><span id="line-3472"> public boolean walRollRequestFinished() {</span>
+<span class="source-line-no">3473</span><span id="line-3473"> return this.walRoller.walRollFinished();</span>
+<span class="source-line-no">3474</span><span id="line-3474"> }</span>
+<span class="source-line-no">3475</span><span id="line-3475"></span>
+<span class="source-line-no">3476</span><span id="line-3476"> @Override</span>
+<span class="source-line-no">3477</span><span id="line-3477"> public ThroughputController getFlushThroughputController() {</span>
+<span class="source-line-no">3478</span><span id="line-3478"> return flushThroughputController;</span>
+<span class="source-line-no">3479</span><span id="line-3479"> }</span>
+<span class="source-line-no">3480</span><span id="line-3480"></span>
+<span class="source-line-no">3481</span><span id="line-3481"> @Override</span>
+<span class="source-line-no">3482</span><span id="line-3482"> public double getFlushPressure() {</span>
+<span class="source-line-no">3483</span><span id="line-3483"> if (getRegionServerAccounting() == null || cacheFlusher == null) {</span>
+<span class="source-line-no">3484</span><span id="line-3484"> // return 0 during RS initialization</span>
+<span class="source-line-no">3485</span><span id="line-3485"> return 0.0;</span>
+<span class="source-line-no">3486</span><span id="line-3486"> }</span>
+<span class="source-line-no">3487</span><span id="line-3487"> return getRegionServerAccounting().getFlushPressure();</span>
+<span class="source-line-no">3488</span><span id="line-3488"> }</span>
+<span class="source-line-no">3489</span><span id="line-3489"></span>
+<span class="source-line-no">3490</span><span id="line-3490"> /**</span>
+<span class="source-line-no">3491</span><span id="line-3491"> * Dynamically updates HRegionServer's configuration. Since HRegionServer inherits from</span>
+<span class="source-line-no">3492</span><span id="line-3492"> * {@link HBaseServerBase}, the {@code updatedConf} parameter references the same</span>
+<span class="source-line-no">3493</span><span id="line-3493"> * {@link Configuration} object as HRegionServer's {@code this.conf} instance variable in a real</span>
+<span class="source-line-no">3494</span><span id="line-3494"> * HBase deployment. This isn't necessarily the case in unit tests.</span>
+<span class="source-line-no">3495</span><span id="line-3495"> * @param updatedConf the dynamically updated configuration</span>
+<span class="source-line-no">3496</span><span id="line-3496"> */</span>
+<span class="source-line-no">3497</span><span id="line-3497"> @Override</span>
+<span class="source-line-no">3498</span><span id="line-3498"> public void onConfigurationChange(Configuration updatedConf) {</span>
+<span class="source-line-no">3499</span><span id="line-3499"> ThroughputController old = this.flushThroughputController;</span>
+<span class="source-line-no">3500</span><span id="line-3500"> if (old != null) {</span>
+<span class="source-line-no">3501</span><span id="line-3501"> old.stop("configuration change");</span>
+<span class="source-line-no">3502</span><span id="line-3502"> }</span>
+<span class="source-line-no">3503</span><span id="line-3503"> this.flushThroughputController = FlushThroughputControllerFactory.create(this, updatedConf);</span>
+<span class="source-line-no">3504</span><span id="line-3504"> try {</span>
+<span class="source-line-no">3505</span><span id="line-3505"> Superusers.initialize(updatedConf);</span>
+<span class="source-line-no">3506</span><span id="line-3506"> } catch (IOException e) {</span>
+<span class="source-line-no">3507</span><span id="line-3507"> LOG.warn("Failed to initialize SuperUsers on reloading of the configuration");</span>
+<span class="source-line-no">3508</span><span id="line-3508"> }</span>
+<span class="source-line-no">3509</span><span id="line-3509"></span>
+<span class="source-line-no">3510</span><span id="line-3510"> boolean originalIsReadOnlyEnabled = CoprocessorConfigurationUtil</span>
+<span class="source-line-no">3511</span><span id="line-3511"> .areReadOnlyCoprocessorsLoaded(this.conf, CoprocessorHost.REGIONSERVER_COPROCESSOR_CONF_KEY);</span>
+<span class="source-line-no">3512</span><span id="line-3512"></span>
+<span class="source-line-no">3513</span><span id="line-3513"> // updatedConf and this.conf reference the same Configuration object in an actual HBase</span>
+<span class="source-line-no">3514</span><span id="line-3514"> // deployment. However, in unit test cases they reference different Configuration objects, so</span>
+<span class="source-line-no">3515</span><span id="line-3515"> // this.conf needs to be updated.</span>
+<span class="source-line-no">3516</span><span id="line-3516"> CoprocessorConfigurationUtil.maybeUpdateCoprocessors(updatedConf, this.conf,</span>
+<span class="source-line-no">3517</span><span id="line-3517"> originalIsReadOnlyEnabled, this.rsHost, CoprocessorHost.REGIONSERVER_COPROCESSOR_CONF_KEY,</span>
+<span class="source-line-no">3518</span><span id="line-3518"> false, this.toString(), conf -> this.rsHost = new RegionServerCoprocessorHost(this, conf));</span>
+<span class="source-line-no">3519</span><span id="line-3519"> }</span>
+<span class="source-line-no">3520</span><span id="line-3520"></span>
+<span class="source-line-no">3521</span><span id="line-3521"> @Override</span>
+<span class="source-line-no">3522</span><span id="line-3522"> public MetricsRegionServer getMetrics() {</span>
+<span class="source-line-no">3523</span><span id="line-3523"> return metricsRegionServer;</span>
+<span class="source-line-no">3524</span><span id="line-3524"> }</span>
+<span class="source-line-no">3525</span><span id="line-3525"></span>
+<span class="source-line-no">3526</span><span id="line-3526"> @Override</span>
+<span class="source-line-no">3527</span><span id="line-3527"> public SecureBulkLoadManager getSecureBulkLoadManager() {</span>
+<span class="source-line-no">3528</span><span id="line-3528"> return this.secureBulkLoadManager;</span>
+<span class="source-line-no">3529</span><span id="line-3529"> }</span>
+<span class="source-line-no">3530</span><span id="line-3530"></span>
+<span class="source-line-no">3531</span><span id="line-3531"> @Override</span>
+<span class="source-line-no">3532</span><span id="line-3532"> public EntityLock regionLock(final List<RegionInfo> regionInfo, final String description,</span>
+<span class="source-line-no">3533</span><span id="line-3533"> final Abortable abort) {</span>
+<span class="source-line-no">3534</span><span id="line-3534"> final LockServiceClient client =</span>
+<span class="source-line-no">3535</span><span id="line-3535"> new LockServiceClient(conf, lockStub, asyncClusterConnection.getNonceGenerator());</span>
+<span class="source-line-no">3536</span><span id="line-3536"> return client.regionLock(regionInfo, description, abort);</span>
+<span class="source-line-no">3537</span><span id="line-3537"> }</span>
+<span class="source-line-no">3538</span><span id="line-3538"></span>
+<span class="source-line-no">3539</span><span id="line-3539"> @Override</span>
+<span class="source-line-no">3540</span><span id="line-3540"> public void unassign(byte[] regionName) throws IOException {</span>
+<span class="source-line-no">3541</span><span id="line-3541"> FutureUtils.get(asyncClusterConnection.getAdmin().unassign(regionName, false));</span>
+<span class="source-line-no">3542</span><span id="line-3542"> }</span>
+<span class="source-line-no">3543</span><span id="line-3543"></span>
+<span class="source-line-no">3544</span><span id="line-3544"> @Override</span>
+<span class="source-line-no">3545</span><span id="line-3545"> public RegionServerSpaceQuotaManager getRegionServerSpaceQuotaManager() {</span>
+<span class="source-line-no">3546</span><span id="line-3546"> return this.rsSpaceQuotaManager;</span>
+<span class="source-line-no">3547</span><span id="line-3547"> }</span>
+<span class="source-line-no">3548</span><span id="line-3548"></span>
+<span class="source-line-no">3549</span><span id="line-3549"> @Override</span>
+<span class="source-line-no">3550</span><span id="line-3550"> public boolean reportFileArchivalForQuotas(TableName tableName,</span>
+<span class="source-line-no">3551</span><span id="line-3551"> Collection<Entry<String, Long>> archivedFiles) {</span>
+<span class="source-line-no">3552</span><span id="line-3552"> if (TEST_SKIP_REPORTING_TRANSITION) {</span>
+<span class="source-line-no">3553</span><span id="line-3553"> return false;</span>
+<span class="source-line-no">3554</span><span id="line-3554"> }</span>
+<span class="source-line-no">3555</span><span id="line-3555"> RegionServerStatusService.BlockingInterface rss = rssStub;</span>
+<span class="source-line-no">3556</span><span id="line-3556"> if (rss == null || rsSpaceQuotaManager == null) {</span>
+<span class="source-line-no">3557</span><span id="line-3557"> // the current server could be stopping.</span>
+<span class="source-line-no">3558</span><span id="line-3558"> LOG.trace("Skipping file archival reporting to HMaster as stub is null");</span>
+<span class="source-line-no">3559</span><span id="line-3559"> return false;</span>
+<span class="source-line-no">3560</span><span id="line-3560"> }</span>
+<span class="source-line-no">3561</span><span id="line-3561"> try {</span>
+<span class="source-line-no">3562</span><span id="line-3562"> RegionServerStatusProtos.FileArchiveNotificationRequest request =</span>
+<span class="source-line-no">3563</span><span id="line-3563"> rsSpaceQuotaManager.buildFileArchiveRequest(tableName, archivedFiles);</span>
+<span class="source-line-no">3564</span><span id="line-3564"> rss.reportFileArchival(null, request);</span>
+<span class="source-line-no">3565</span><span id="line-3565"> } catch (ServiceException se) {</span>
+<span class="source-line-no">3566</span><span id="line-3566"> IOException ioe = ProtobufUtil.getRemoteException(se);</span>
+<span class="source-line-no">3567</span><span id="line-3567"> if (ioe instanceof PleaseHoldException) {</span>
+<span class="source-line-no">3568</span><span id="line-3568"> if (LOG.isTraceEnabled()) {</span>
+<span class="source-line-no">3569</span><span id="line-3569"> LOG.trace("Failed to report file archival(s) to Master because it is initializing."</span>
+<span class="source-line-no">3570</span><span id="line-3570"> + " This will be retried.", ioe);</span>
+<span class="source-line-no">3571</span><span id="line-3571"> }</span>
+<span class="source-line-no">3572</span><span id="line-3572"> // The Master is coming up. Will retry the report later. Avoid re-creating the stub.</span>
+<span class="source-line-no">3573</span><span id="line-3573"> return false;</span>
+<span class="source-line-no">3574</span><span id="line-3574"> }</span>
+<span class="source-line-no">3575</span><span id="line-3575"> if (rssStub == rss) {</span>
+<span class="source-line-no">3576</span><span id="line-3576"> rssStub = null;</span>
+<span class="source-line-no">3577</span><span id="line-3577"> }</span>
+<span class="source-line-no">3578</span><span id="line-3578"> // re-create the stub if we failed to report the archival</span>
+<span class="source-line-no">3579</span><span id="line-3579"> createRegionServerStatusStub(true);</span>
+<span class="source-line-no">3580</span><span id="line-3580"> LOG.debug("Failed to report file archival(s) to Master. This will be retried.", ioe);</span>
+<span class="source-line-no">3581</span><span id="line-3581"> return false;</span>
+<span class="source-line-no">3582</span><span id="line-3582"> }</span>
+<span class="source-line-no">3583</span><span id="line-3583"> return true;</span>
+<span class="source-line-no">3584</span><span id="line-3584"> }</span>
+<span class="source-line-no">3585</span><span id="line-3585"></span>
+<span class="source-line-no">3586</span><span id="line-3586"> void executeProcedure(long procId, long initiatingMasterActiveTime,</span>
+<span class="source-line-no">3587</span><span id="line-3587"> RSProcedureCallable callable) {</span>
+<span class="source-line-no">3588</span><span id="line-3588"> executorService</span>
+<span class="source-line-no">3589</span><span id="line-3589"> .submit(new RSProcedureHandler(this, procId, initiatingMasterActiveTime, callable));</span>
+<span class="source-line-no">3590</span><span id="line-3590"> }</span>
+<span class="source-line-no">3591</span><span id="line-3591"></span>
+<span class="source-line-no">3592</span><span id="line-3592"> public void remoteProcedureComplete(long procId, long initiatingMasterActiveTime, Throwable error,</span>
+<span class="source-line-no">3593</span><span id="line-3593"> byte[] procResultData) {</span>
+<span class="source-line-no">3594</span><span id="line-3594"> procedureResultReporter.complete(procId, initiatingMasterActiveTime, error, procResultData);</span>
+<span class="source-line-no">3595</span><span id="line-3595"> }</span>
+<span class="source-line-no">3596</span><span id="line-3596"></span>
+<span class="source-line-no">3597</span><span id="line-3597"> void reportProcedureDone(ReportProcedureDoneRequest request) throws IOException {</span>
+<span class="source-line-no">3598</span><span id="line-3598"> RegionServerStatusService.BlockingInterface rss;</span>
+<span class="source-line-no">3599</span><span id="line-3599"> // TODO: juggling class state with an instance variable, outside of a synchronized block :'(</span>
+<span class="source-line-no">3600</span><span id="line-3600"> for (;;) {</span>
+<span class="source-line-no">3601</span><span id="line-3601"> rss = rssStub;</span>
+<span class="source-line-no">3602</span><span id="line-3602"> if (rss != null) {</span>
+<span class="source-line-no">3603</span><span id="line-3603"> break;</span>
+<span class="source-line-no">3604</span><span id="line-3604"> }</span>
+<span class="source-line-no">3605</span><span id="line-3605"> createRegionServerStatusStub();</span>
+<span class="source-line-no">3606</span><span id="line-3606"> }</span>
+<span class="source-line-no">3607</span><span id="line-3607"> try {</span>
+<span class="source-line-no">3608</span><span id="line-3608"> rss.reportProcedureDone(null, request);</span>
+<span class="source-line-no">3609</span><span id="line-3609"> } catch (ServiceException se) {</span>
+<span class="source-line-no">3610</span><span id="line-3610"> if (rssStub == rss) {</span>
+<span class="source-line-no">3611</span><span id="line-3611"> rssStub = null;</span>
+<span class="source-line-no">3612</span><span id="line-3612"> }</span>
+<span class="source-line-no">3613</span><span id="line-3613"> throw ProtobufUtil.getRemoteException(se);</span>
+<span class="source-line-no">3614</span><span id="line-3614"> }</span>
+<span class="source-line-no">3615</span><span id="line-3615"> }</span>
+<span class="source-line-no">3616</span><span id="line-3616"></span>
+<span class="source-line-no">3617</span><span id="line-3617"> /**</span>
+<span class="source-line-no">3618</span><span id="line-3618"> * Will ignore the open/close region procedures which already submitted or executed. When master</span>
+<span class="source-line-no">3619</span><span id="line-3619"> * had unfinished open/close region procedure and restarted, new active master may send duplicate</span>
+<span class="source-line-no">3620</span><span id="line-3620"> * open/close region request to regionserver. The open/close request is submitted to a thread pool</span>
+<span class="source-line-no">3621</span><span id="line-3621"> * and execute. So first need a cache for submitted open/close region procedures. After the</span>
+<span class="source-line-no">3622</span><span id="line-3622"> * open/close region request executed and report region transition succeed, cache it in executed</span>
+<span class="source-line-no">3623</span><span id="line-3623"> * region procedures cache. See {@link #finishRegionProcedure(long)}. After report region</span>
+<span class="source-line-no">3624</span><span id="line-3624"> * transition succeed, master will not send the open/close region request to regionserver again.</span>
+<span class="source-line-no">3625</span><span id="line-3625"> * And we thought that the ongoing duplicate open/close region request should not be delayed more</span>
+<span class="source-line-no">3626</span><span id="line-3626"> * than 600 seconds. So the executed region procedures cache will expire after 600 seconds. See</span>
+<span class="source-line-no">3627</span><span id="line-3627"> * HBASE-22404 for more details.</span>
+<span class="source-line-no">3628</span><span id="line-3628"> * @param procId the id of the open/close region procedure</span>
+<span class="source-line-no">3629</span><span id="line-3629"> * @return true if the procedure can be submitted.</span>
+<span class="source-line-no">3630</span><span id="line-3630"> */</span>
+<span class="source-line-no">3631</span><span id="line-3631"> boolean submitRegionProcedure(long procId) {</span>
+<span class="source-line-no">3632</span><span id="line-3632"> if (procId == -1) {</span>
+<span class="source-line-no">3633</span><span id="line-3633"> return true;</span>
+<span class="source-line-no">3634</span><span id="line-3634"> }</span>
+<span class="source-line-no">3635</span><span id="line-3635"> // Ignore the region procedures which already submitted.</span>
+<span class="source-line-no">3636</span><span id="line-3636"> Long previous = submittedRegionProcedures.putIfAbsent(procId, procId);</span>
+<span class="source-line-no">3637</span><span id="line-3637"> if (previous != null) {</span>
+<span class="source-line-no">3638</span><span id="line-3638"> LOG.warn("Received procedure pid={}, which already submitted, just ignore it", procId);</span>
+<span class="source-line-no">3639</span><span id="line-3639"> return false;</span>
+<span class="source-line-no">3640</span><span id="line-3640"> }</span>
+<span class="source-line-no">3641</span><span id="line-3641"> // Ignore the region procedures which already executed.</span>
+<span class="source-line-no">3642</span><span id="line-3642"> if (executedRegionProcedures.getIfPresent(procId) != null) {</span>
+<span class="source-line-no">3643</span><span id="line-3643"> LOG.warn("Received procedure pid={}, which already executed, just ignore it", procId);</span>
+<span class="source-line-no">3644</span><span id="line-3644"> return false;</span>
+<span class="source-line-no">3645</span><span id="line-3645"> }</span>
+<span class="source-line-no">3646</span><span id="line-3646"> return true;</span>
+<span class="source-line-no">3647</span><span id="line-3647"> }</span>
+<span class="source-line-no">3648</span><span id="line-3648"></span>
+<span class="source-line-no">3649</span><span id="line-3649"> /**</span>
+<span class="source-line-no">3650</span><span id="line-3650"> * See {@link #submitRegionProcedure(long)}.</span>
+<span class="source-line-no">3651</span><span id="line-3651"> * @param procId the id of the open/close region procedure</span>
+<span class="source-line-no">3652</span><span id="line-3652"> */</span>
+<span class="source-line-no">3653</span><span id="line-3653"> public void finishRegionProcedure(long procId) {</span>
+<span class="source-line-no">3654</span><span id="line-3654"> executedRegionProcedures.put(procId, procId);</span>
+<span class="source-line-no">3655</span><span id="line-3655"> submittedRegionProcedures.remove(procId);</span>
+<span class="source-line-no">3656</span><span id="line-3656"> }</span>
+<span class="source-line-no">3657</span><span id="line-3657"></span>
+<span class="source-line-no">3658</span><span id="line-3658"> /**</span>
+<span class="source-line-no">3659</span><span id="line-3659"> * Force to terminate region server when abort timeout.</span>
+<span class="source-line-no">3660</span><span id="line-3660"> */</span>
+<span class="source-line-no">3661</span><span id="line-3661"> private static class SystemExitWhenAbortTimeout extends TimerTask {</span>
+<span class="source-line-no">3662</span><span id="line-3662"></span>
+<span class="source-line-no">3663</span><span id="line-3663"> public SystemExitWhenAbortTimeout() {</span>
+<span class="source-line-no">3664</span><span id="line-3664"> }</span>
+<span class="source-line-no">3665</span><span id="line-3665"></span>
+<span class="source-line-no">3666</span><span id="line-3666"> @Override</span>
+<span class="source-line-no">3667</span><span id="line-3667"> public void run() {</span>
+<span class="source-line-no">3668</span><span id="line-3668"> LOG.warn("Aborting region server timed out, terminating forcibly"</span>
+<span class="source-line-no">3669</span><span id="line-3669"> + " and does not wait for any running shutdown hooks or finalizers to finish their work."</span>
+<span class="source-line-no">3670</span><span id="line-3670"> + " Thread dump to stdout.");</span>
+<span class="source-line-no">3671</span><span id="line-3671"> Threads.printThreadInfo(System.out, "Zombie HRegionServer");</span>
+<span class="source-line-no">3672</span><span id="line-3672"> Runtime.getRuntime().halt(1);</span>
+<span class="source-line-no">3673</span><span id="line-3673"> }</span>
+<span class="source-line-no">3674</span><span id="line-3674"> }</span>
+<span class="source-line-no">3675</span><span id="line-3675"></span>
+<span class="source-line-no">3676</span><span id="line-3676"> @InterfaceAudience.Private</span>
+<span class="source-line-no">3677</span><span id="line-3677"> public CompactedHFilesDischarger getCompactedHFilesDischarger() {</span>
+<span class="source-line-no">3678</span><span id="line-3678"> return compactedFileDischarger;</span>
+<span class="source-line-no">3679</span><span id="line-3679"> }</span>
+<span class="source-line-no">3680</span><span id="line-3680"></span>
+<span class="source-line-no">3681</span><span id="line-3681"> /**</span>
+<span class="source-line-no">3682</span><span id="line-3682"> * Return pause time configured in {@link HConstants#HBASE_RPC_SHORTOPERATION_RETRY_PAUSE_TIME}}</span>
+<span class="source-line-no">3683</span><span id="line-3683"> * @return pause time</span>
+<span class="source-line-no">3684</span><span id="line-3684"> */</span>
+<span class="source-line-no">3685</span><span id="line-3685"> @InterfaceAudience.Private</span>
+<span class="source-line-no">3686</span><span id="line-3686"> public long getRetryPauseTime() {</span>
+<span class="source-line-no">3687</span><span id="line-3687"> return this.retryPauseTime;</span>
+<span class="source-line-no">3688</span><span id="line-3688"> }</span>
+<span class="source-line-no">3689</span><span id="line-3689"></span>
+<span class="source-line-no">3690</span><span id="line-3690"> @Override</span>
+<span class="source-line-no">3691</span><span id="line-3691"> public Optional<ServerName> getActiveMaster() {</span>
+<span class="source-line-no">3692</span><span id="line-3692"> return Optional.ofNullable(masterAddressTracker.getMasterAddress());</span>
+<span class="source-line-no">3693</span><span id="line-3693"> }</span>
+<span class="source-line-no">3694</span><span id="line-3694"></span>
+<span class="source-line-no">3695</span><span id="line-3695"> @Override</span>
+<span class="source-line-no">3696</span><span id="line-3696"> public List<ServerName> getBackupMasters() {</span>
+<span class="source-line-no">3697</span><span id="line-3697"> return masterAddressTracker.getBackupMasters();</span>
+<span class="source-line-no">3698</span><span id="line-3698"> }</span>
+<span class="source-line-no">3699</span><span id="line-3699"></span>
+<span class="source-line-no">3700</span><span id="line-3700"> @Override</span>
+<span class="source-line-no">3701</span><span id="line-3701"> public Iterator<ServerName> getBootstrapNodes() {</span>
+<span class="source-line-no">3702</span><span id="line-3702"> return bootstrapNodeManager.getBootstrapNodes().iterator();</span>
+<span class="source-line-no">3703</span><span id="line-3703"> }</span>
+<span class="source-line-no">3704</span><span id="line-3704"></span>
+<span class="source-line-no">3705</span><span id="line-3705"> @Override</span>
+<span class="source-line-no">3706</span><span id="line-3706"> public List<HRegionLocation> getMetaLocations() {</span>
+<span class="source-line-no">3707</span><span id="line-3707"> return metaRegionLocationCache.getMetaRegionLocations();</span>
+<span class="source-line-no">3708</span><span id="line-3708"> }</span>
+<span class="source-line-no">3709</span><span id="line-3709"></span>
+<span class="source-line-no">3710</span><span id="line-3710"> @Override</span>
+<span class="source-line-no">3711</span><span id="line-3711"> protected NamedQueueRecorder createNamedQueueRecord() {</span>
+<span class="source-line-no">3712</span><span id="line-3712"> return NamedQueueRecorder.getInstance(conf);</span>
+<span class="source-line-no">3713</span><span id="line-3713"> }</span>
+<span class="source-line-no">3714</span><span id="line-3714"></span>
+<span class="source-line-no">3715</span><span id="line-3715"> @Override</span>
+<span class="source-line-no">3716</span><span id="line-3716"> protected boolean clusterMode() {</span>
+<span class="source-line-no">3717</span><span id="line-3717"> // this method will be called in the constructor of super class, so we can not return masterless</span>
+<span class="source-line-no">3718</span><span id="line-3718"> // directly here, as it will always be false.</span>
+<span class="source-line-no">3719</span><span id="line-3719"> return !conf.getBoolean(MASTERLESS_CONFIG_NAME, false);</span>
+<span class="source-line-no">3720</span><span id="line-3720"> }</span>
+<span class="source-line-no">3721</span><span id="line-3721"></span>
+<span class="source-line-no">3722</span><span id="line-3722"> @InterfaceAudience.Private</span>
+<span class="source-line-no">3723</span><span id="line-3723"> public BrokenStoreFileCleaner getBrokenStoreFileCleaner() {</span>
+<span class="source-line-no">3724</span><span id="line-3724"> return brokenStoreFileCleaner;</span>
+<span class="source-line-no">3725</span><span id="line-3725"> }</span>
+<span class="source-line-no">3726</span><span id="line-3726"></span>
+<span class="source-line-no">3727</span><span id="line-3727"> @InterfaceAudience.Private</span>
+<span class="source-line-no">3728</span><span id="line-3728"> public RSMobFileCleanerChore getRSMobFileCleanerChore() {</span>
+<span class="source-line-no">3729</span><span id="line-3729"> return rsMobFileCleanerChore;</span>
<span class="source-line-no">3730</span><span id="line-3730"> }</span>
<span class="source-line-no">3731</span><span id="line-3731"></span>
-<span class="source-line-no">3732</span><span id="line-3732"> @Override</span>
-<span class="source-line-no">3733</span><span id="line-3733"> protected void stopChores() {</span>
-<span class="source-line-no">3734</span><span id="line-3734"> shutdownChore(nonceManagerChore);</span>
-<span class="source-line-no">3735</span><span id="line-3735"> shutdownChore(compactionChecker);</span>
-<span class="source-line-no">3736</span><span id="line-3736"> shutdownChore(compactedFileDischarger);</span>
-<span class="source-line-no">3737</span><span id="line-3737"> shutdownChore(periodicFlusher);</span>
-<span class="source-line-no">3738</span><span id="line-3738"> shutdownChore(healthCheckChore);</span>
-<span class="source-line-no">3739</span><span id="line-3739"> shutdownChore(executorStatusChore);</span>
-<span class="source-line-no">3740</span><span id="line-3740"> shutdownChore(storefileRefresher);</span>
-<span class="source-line-no">3741</span><span id="line-3741"> shutdownChore(fsUtilizationChore);</span>
-<span class="source-line-no">3742</span><span id="line-3742"> shutdownChore(namedQueueServiceChore);</span>
-<span class="source-line-no">3743</span><span id="line-3743"> shutdownChore(brokenStoreFileCleaner);</span>
-<span class="source-line-no">3744</span><span id="line-3744"> shutdownChore(rsMobFileCleanerChore);</span>
-<span class="source-line-no">3745</span><span id="line-3745"> shutdownChore(replicationMarkerChore);</span>
-<span class="source-line-no">3746</span><span id="line-3746"> }</span>
-<span class="source-line-no">3747</span><span id="line-3747"></span>
-<span class="source-line-no">3748</span><span id="line-3748"> @Override</span>
-<span class="source-line-no">3749</span><span id="line-3749"> public RegionReplicationBufferManager getRegionReplicationBufferManager() {</span>
-<span class="source-line-no">3750</span><span id="line-3750"> return regionReplicationBufferManager;</span>
-<span class="source-line-no">3751</span><span id="line-3751"> }</span>
-<span class="source-line-no">3752</span><span id="line-3752">}</span>
+<span class="source-line-no">3732</span><span id="line-3732"> RSSnapshotVerifier getRsSnapshotVerifier() {</span>
+<span class="source-line-no">3733</span><span id="line-3733"> return rsSnapshotVerifier;</span>
+<span class="source-line-no">3734</span><span id="line-3734"> }</span>
+<span class="source-line-no">3735</span><span id="line-3735"></span>
+<span class="source-line-no">3736</span><span id="line-3736"> @Override</span>
+<span class="source-line-no">3737</span><span id="line-3737"> protected void stopChores() {</span>
+<span class="source-line-no">3738</span><span id="line-3738"> shutdownChore(nonceManagerChore);</span>
+<span class="source-line-no">3739</span><span id="line-3739"> shutdownChore(compactionChecker);</span>
+<span class="source-line-no">3740</span><span id="line-3740"> shutdownChore(compactedFileDischarger);</span>
+<span class="source-line-no">3741</span><span id="line-3741"> shutdownChore(periodicFlusher);</span>
+<span class="source-line-no">3742</span><span id="line-3742"> shutdownChore(healthCheckChore);</span>
+<span class="source-line-no">3743</span><span id="line-3743"> shutdownChore(executorStatusChore);</span>
+<span class="source-line-no">3744</span><span id="line-3744"> shutdownChore(storefileRefresher);</span>
+<span class="source-line-no">3745</span><span id="line-3745"> shutdownChore(fsUtilizationChore);</span>
+<span class="source-line-no">3746</span><span id="line-3746"> shutdownChore(namedQueueServiceChore);</span>
+<span class="source-line-no">3747</span><span id="line-3747"> shutdownChore(brokenStoreFileCleaner);</span>
+<span class="source-line-no">3748</span><span id="line-3748"> shutdownChore(rsMobFileCleanerChore);</span>
+<span class="source-line-no">3749</span><span id="line-3749"> shutdownChore(replicationMarkerChore);</span>
+<span class="source-line-no">3750</span><span id="line-3750"> }</span>
+<span class="source-line-no">3751</span><span id="line-3751"></span>
+<span class="source-line-no">3752</span><span id="line-3752"> @Override</span>
+<span class="source-line-no">3753</span><span id="line-3753"> public RegionReplicationBufferManager getRegionReplicationBufferManager() {</span>
+<span class="source-line-no">3754</span><span id="line-3754"> return regionReplicationBufferManager;</span>
+<span class="source-line-no">3755</span><span id="line-3755"> }</span>
+<span class="source-line-no">3756</span><span id="line-3756">}</span>
diff --git a/apidocs/src-html/org/apache/hadoop/hbase/regionserver/MetricsUserAggregateImpl.html b/apidocs/src-html/org/apache/hadoop/hbase/regionserver/MetricsUserAggregateImpl.html
index 8537a9ff325..86e293eeda2 100644
--- a/apidocs/src-html/org/apache/hadoop/hbase/regionserver/MetricsUserAggregateImpl.html
+++ b/apidocs/src-html/org/apache/hadoop/hbase/regionserver/MetricsUserAggregateImpl.html
@@ -36,177 +36,233 @@
<span class="source-line-no">023</span><span id="line-23">import org.apache.hadoop.conf.Configuration;</span>
<span class="source-line-no">024</span><span id="line-24">import org.apache.hadoop.hbase.CompatibilitySingletonFactory;</span>
<span class="source-line-no">025</span><span id="line-25">import org.apache.hadoop.hbase.ipc.RpcServer;</span>
-<span class="source-line-no">026</span><span id="line-26">import org.apache.hadoop.hbase.security.User;</span>
-<span class="source-line-no">027</span><span id="line-27">import org.apache.hadoop.hbase.security.UserProvider;</span>
-<span class="source-line-no">028</span><span id="line-28">import org.apache.hadoop.hbase.util.LossyCounting;</span>
-<span class="source-line-no">029</span><span id="line-29">import org.apache.yetus.audience.InterfaceAudience;</span>
-<span class="source-line-no">030</span><span id="line-30"></span>
-<span class="source-line-no">031</span><span id="line-31">@InterfaceAudience.Private</span>
-<span class="source-line-no">032</span><span id="line-32">public class MetricsUserAggregateImpl implements MetricsUserAggregate {</span>
+<span class="source-line-no">026</span><span id="line-26">import org.apache.hadoop.hbase.ipc.ServerRpcConnection;</span>
+<span class="source-line-no">027</span><span id="line-27">import org.apache.hadoop.hbase.security.User;</span>
+<span class="source-line-no">028</span><span id="line-28">import org.apache.hadoop.hbase.security.UserProvider;</span>
+<span class="source-line-no">029</span><span id="line-29">import org.apache.hadoop.hbase.util.LossyCounting;</span>
+<span class="source-line-no">030</span><span id="line-30">import org.apache.yetus.audience.InterfaceAudience;</span>
+<span class="source-line-no">031</span><span id="line-31"></span>
+<span class="source-line-no">032</span><span id="line-32">import org.apache.hadoop.hbase.shaded.protobuf.generated.RPCProtos;</span>
<span class="source-line-no">033</span><span id="line-33"></span>
-<span class="source-line-no">034</span><span id="line-34"> /** Provider for mapping principal names to Users */</span>
-<span class="source-line-no">035</span><span id="line-35"> private final UserProvider userProvider;</span>
+<span class="source-line-no">034</span><span id="line-34">@InterfaceAudience.Private</span>
+<span class="source-line-no">035</span><span id="line-35">public class MetricsUserAggregateImpl implements MetricsUserAggregate {</span>
<span class="source-line-no">036</span><span id="line-36"></span>
-<span class="source-line-no">037</span><span id="line-37"> private final MetricsUserAggregateSource source;</span>
-<span class="source-line-no">038</span><span id="line-38"> private final LossyCounting<MetricsUserSource> userMetricLossyCounting;</span>
+<span class="source-line-no">037</span><span id="line-37"> /** Provider for mapping principal names to Users */</span>
+<span class="source-line-no">038</span><span id="line-38"> private final UserProvider userProvider;</span>
<span class="source-line-no">039</span><span id="line-39"></span>
-<span class="source-line-no">040</span><span id="line-40"> public MetricsUserAggregateImpl(Configuration conf) {</span>
-<span class="source-line-no">041</span><span id="line-41"> source = CompatibilitySingletonFactory.getInstance(MetricsRegionServerSourceFactory.class)</span>
-<span class="source-line-no">042</span><span id="line-42"> .getUserAggregate();</span>
-<span class="source-line-no">043</span><span id="line-43"> userMetricLossyCounting = new LossyCounting<>("userMetrics", conf, source::deregister);</span>
-<span class="source-line-no">044</span><span id="line-44"> this.userProvider = UserProvider.instantiate(conf);</span>
-<span class="source-line-no">045</span><span id="line-45"> }</span>
-<span class="source-line-no">046</span><span id="line-46"></span>
-<span class="source-line-no">047</span><span id="line-47"> /**</span>
-<span class="source-line-no">048</span><span id="line-48"> * Returns the active user to which authorization checks should be applied. If we are in the</span>
-<span class="source-line-no">049</span><span id="line-49"> * context of an RPC call, the remote user is used, otherwise the currently logged in user is</span>
-<span class="source-line-no">050</span><span id="line-50"> * used.</span>
-<span class="source-line-no">051</span><span id="line-51"> */</span>
-<span class="source-line-no">052</span><span id="line-52"> private String getActiveUser() {</span>
-<span class="source-line-no">053</span><span id="line-53"> Optional<User> user = RpcServer.getRequestUser();</span>
-<span class="source-line-no">054</span><span id="line-54"> if (!user.isPresent()) {</span>
-<span class="source-line-no">055</span><span id="line-55"> // for non-rpc handling, fallback to system user</span>
-<span class="source-line-no">056</span><span id="line-56"> try {</span>
-<span class="source-line-no">057</span><span id="line-57"> user = Optional.of(userProvider.getCurrent());</span>
-<span class="source-line-no">058</span><span id="line-58"> } catch (IOException ignore) {</span>
-<span class="source-line-no">059</span><span id="line-59"> }</span>
-<span class="source-line-no">060</span><span id="line-60"> }</span>
-<span class="source-line-no">061</span><span id="line-61"> return user.map(User::getShortName).orElse(null);</span>
-<span class="source-line-no">062</span><span id="line-62"> }</span>
-<span class="source-line-no">063</span><span id="line-63"></span>
-<span class="source-line-no">064</span><span id="line-64"> @Override</span>
-<span class="source-line-no">065</span><span id="line-65"> public MetricsUserAggregateSource getSource() {</span>
-<span class="source-line-no">066</span><span id="line-66"> return source;</span>
-<span class="source-line-no">067</span><span id="line-67"> }</span>
-<span class="source-line-no">068</span><span id="line-68"></span>
-<span class="source-line-no">069</span><span id="line-69"> @Override</span>
-<span class="source-line-no">070</span><span id="line-70"> public void updatePut(long t) {</span>
-<span class="source-line-no">071</span><span id="line-71"> String user = getActiveUser();</span>
-<span class="source-line-no">072</span><span id="line-72"> if (user != null) {</span>
-<span class="source-line-no">073</span><span id="line-73"> MetricsUserSource userSource = getOrCreateMetricsUser(user);</span>
-<span class="source-line-no">074</span><span id="line-74"> userSource.updatePut(t);</span>
-<span class="source-line-no">075</span><span id="line-75"> incrementClientWriteMetrics(userSource);</span>
-<span class="source-line-no">076</span><span id="line-76"> }</span>
-<span class="source-line-no">077</span><span id="line-77"></span>
-<span class="source-line-no">078</span><span id="line-78"> }</span>
-<span class="source-line-no">079</span><span id="line-79"></span>
-<span class="source-line-no">080</span><span id="line-80"> private String getClient() {</span>
-<span class="source-line-no">081</span><span id="line-81"> Optional<InetAddress> ipOptional = RpcServer.getRemoteAddress();</span>
-<span class="source-line-no">082</span><span id="line-82"> return ipOptional.map(InetAddress::getHostName).orElse(null);</span>
-<span class="source-line-no">083</span><span id="line-83"> }</span>
-<span class="source-line-no">084</span><span id="line-84"></span>
-<span class="source-line-no">085</span><span id="line-85"> private void incrementClientReadMetrics(MetricsUserSource userSource) {</span>
-<span class="source-line-no">086</span><span id="line-86"> String client = getClient();</span>
-<span class="source-line-no">087</span><span id="line-87"> if (client != null && userSource != null) {</span>
-<span class="source-line-no">088</span><span id="line-88"> userSource.getOrCreateMetricsClient(client).incrementReadRequest();</span>
-<span class="source-line-no">089</span><span id="line-89"> }</span>
-<span class="source-line-no">090</span><span id="line-90"> }</span>
-<span class="source-line-no">091</span><span id="line-91"></span>
-<span class="source-line-no">092</span><span id="line-92"> private void incrementFilteredReadRequests(MetricsUserSource userSource) {</span>
-<span class="source-line-no">093</span><span id="line-93"> String client = getClient();</span>
-<span class="source-line-no">094</span><span id="line-94"> if (client != null && userSource != null) {</span>
-<span class="source-line-no">095</span><span id="line-95"> userSource.getOrCreateMetricsClient(client).incrementFilteredReadRequests();</span>
-<span class="source-line-no">096</span><span id="line-96"> }</span>
-<span class="source-line-no">097</span><span id="line-97"> }</span>
-<span class="source-line-no">098</span><span id="line-98"></span>
-<span class="source-line-no">099</span><span id="line-99"> private void incrementClientWriteMetrics(MetricsUserSource userSource) {</span>
-<span class="source-line-no">100</span><span id="line-100"> String client = getClient();</span>
-<span class="source-line-no">101</span><span id="line-101"> if (client != null && userSource != null) {</span>
-<span class="source-line-no">102</span><span id="line-102"> userSource.getOrCreateMetricsClient(client).incrementWriteRequest();</span>
+<span class="source-line-no">040</span><span id="line-40"> private final MetricsUserAggregateSource source;</span>
+<span class="source-line-no">041</span><span id="line-41"> private final LossyCounting<MetricsUserSource> userMetricLossyCounting;</span>
+<span class="source-line-no">042</span><span id="line-42"></span>
+<span class="source-line-no">043</span><span id="line-43"> public MetricsUserAggregateImpl(Configuration conf) {</span>
+<span class="source-line-no">044</span><span id="line-44"> source = CompatibilitySingletonFactory.getInstance(MetricsRegionServerSourceFactory.class)</span>
+<span class="source-line-no">045</span><span id="line-45"> .getUserAggregate();</span>
+<span class="source-line-no">046</span><span id="line-46"> userMetricLossyCounting = new LossyCounting<>("userMetrics", conf, source::deregister);</span>
+<span class="source-line-no">047</span><span id="line-47"> this.userProvider = UserProvider.instantiate(conf);</span>
+<span class="source-line-no">048</span><span id="line-48"> }</span>
+<span class="source-line-no">049</span><span id="line-49"></span>
+<span class="source-line-no">050</span><span id="line-50"> /**</span>
+<span class="source-line-no">051</span><span id="line-51"> * Returns the active user to which authorization checks should be applied. If we are in the</span>
+<span class="source-line-no">052</span><span id="line-52"> * context of an RPC call, the remote user is used, otherwise the currently logged in user is</span>
+<span class="source-line-no">053</span><span id="line-53"> * used.</span>
+<span class="source-line-no">054</span><span id="line-54"> */</span>
+<span class="source-line-no">055</span><span id="line-55"> private String getActiveUser() {</span>
+<span class="source-line-no">056</span><span id="line-56"> Optional<User> user = RpcServer.getRequestUser();</span>
+<span class="source-line-no">057</span><span id="line-57"> if (!user.isPresent()) {</span>
+<span class="source-line-no">058</span><span id="line-58"> // for non-rpc handling, fallback to system user</span>
+<span class="source-line-no">059</span><span id="line-59"> try {</span>
+<span class="source-line-no">060</span><span id="line-60"> user = Optional.of(userProvider.getCurrent());</span>
+<span class="source-line-no">061</span><span id="line-61"> } catch (IOException ignore) {</span>
+<span class="source-line-no">062</span><span id="line-62"> }</span>
+<span class="source-line-no">063</span><span id="line-63"> }</span>
+<span class="source-line-no">064</span><span id="line-64"> return user.map(User::getShortName).orElse(null);</span>
+<span class="source-line-no">065</span><span id="line-65"> }</span>
+<span class="source-line-no">066</span><span id="line-66"></span>
+<span class="source-line-no">067</span><span id="line-67"> @Override</span>
+<span class="source-line-no">068</span><span id="line-68"> public MetricsUserAggregateSource getSource() {</span>
+<span class="source-line-no">069</span><span id="line-69"> return source;</span>
+<span class="source-line-no">070</span><span id="line-70"> }</span>
+<span class="source-line-no">071</span><span id="line-71"></span>
+<span class="source-line-no">072</span><span id="line-72"> @Override</span>
+<span class="source-line-no">073</span><span id="line-73"> public void updatePut(long t) {</span>
+<span class="source-line-no">074</span><span id="line-74"> String user = getActiveUser();</span>
+<span class="source-line-no">075</span><span id="line-75"> if (user != null) {</span>
+<span class="source-line-no">076</span><span id="line-76"> MetricsUserSource userSource = getOrCreateMetricsUser(user);</span>
+<span class="source-line-no">077</span><span id="line-77"> userSource.updatePut(t);</span>
+<span class="source-line-no">078</span><span id="line-78"> incrementClientWriteMetrics(userSource);</span>
+<span class="source-line-no">079</span><span id="line-79"> }</span>
+<span class="source-line-no">080</span><span id="line-80"></span>
+<span class="source-line-no">081</span><span id="line-81"> }</span>
+<span class="source-line-no">082</span><span id="line-82"></span>
+<span class="source-line-no">083</span><span id="line-83"> private String getClient() {</span>
+<span class="source-line-no">084</span><span id="line-84"> Optional<InetAddress> ipOptional = RpcServer.getRemoteAddress();</span>
+<span class="source-line-no">085</span><span id="line-85"> return ipOptional.map(InetAddress::getHostName).orElse(null);</span>
+<span class="source-line-no">086</span><span id="line-86"> }</span>
+<span class="source-line-no">087</span><span id="line-87"></span>
+<span class="source-line-no">088</span><span id="line-88"> private void incrementClientReadMetrics(MetricsUserSource userSource) {</span>
+<span class="source-line-no">089</span><span id="line-89"> ClientConnectionContext ctx = getClientConnectionContext();</span>
+<span class="source-line-no">090</span><span id="line-90"> String client = getClient();</span>
+<span class="source-line-no">091</span><span id="line-91"> if (client != null && userSource != null) {</span>
+<span class="source-line-no">092</span><span id="line-92"> userSource.getOrCreateMetricsClient(client, ctx.hostAddress, ctx.userName, ctx.clientVersion,</span>
+<span class="source-line-no">093</span><span id="line-93"> ctx.serviceName).incrementReadRequest();</span>
+<span class="source-line-no">094</span><span id="line-94"> }</span>
+<span class="source-line-no">095</span><span id="line-95"> }</span>
+<span class="source-line-no">096</span><span id="line-96"></span>
+<span class="source-line-no">097</span><span id="line-97"> private void incrementFilteredReadRequests(MetricsUserSource userSource) {</span>
+<span class="source-line-no">098</span><span id="line-98"> ClientConnectionContext ctx = getClientConnectionContext();</span>
+<span class="source-line-no">099</span><span id="line-99"> String client = getClient();</span>
+<span class="source-line-no">100</span><span id="line-100"> if (client != null && userSource != null) {</span>
+<span class="source-line-no">101</span><span id="line-101"> userSource.getOrCreateMetricsClient(client, ctx.hostAddress, ctx.userName, ctx.clientVersion,</span>
+<span class="source-line-no">102</span><span id="line-102"> ctx.serviceName).incrementFilteredReadRequests();</span>
<span class="source-line-no">103</span><span id="line-103"> }</span>
<span class="source-line-no">104</span><span id="line-104"> }</span>
<span class="source-line-no">105</span><span id="line-105"></span>
-<span class="source-line-no">106</span><span id="line-106"> @Override</span>
-<span class="source-line-no">107</span><span id="line-107"> public void updateDelete(long t) {</span>
-<span class="source-line-no">108</span><span id="line-108"> String user = getActiveUser();</span>
-<span class="source-line-no">109</span><span id="line-109"> if (user != null) {</span>
-<span class="source-line-no">110</span><span id="line-110"> MetricsUserSource userSource = getOrCreateMetricsUser(user);</span>
-<span class="source-line-no">111</span><span id="line-111"> userSource.updateDelete(t);</span>
-<span class="source-line-no">112</span><span id="line-112"> incrementClientWriteMetrics(userSource);</span>
-<span class="source-line-no">113</span><span id="line-113"> }</span>
-<span class="source-line-no">114</span><span id="line-114"> }</span>
-<span class="source-line-no">115</span><span id="line-115"></span>
-<span class="source-line-no">116</span><span id="line-116"> @Override</span>
-<span class="source-line-no">117</span><span id="line-117"> public void updateGet(long time, long blockBytesScanned) {</span>
-<span class="source-line-no">118</span><span id="line-118"> String user = getActiveUser();</span>
-<span class="source-line-no">119</span><span id="line-119"> if (user != null) {</span>
-<span class="source-line-no">120</span><span id="line-120"> MetricsUserSource userSource = getOrCreateMetricsUser(user);</span>
-<span class="source-line-no">121</span><span id="line-121"> userSource.updateGet(time, blockBytesScanned);</span>
+<span class="source-line-no">106</span><span id="line-106"> private void incrementClientWriteMetrics(MetricsUserSource userSource) {</span>
+<span class="source-line-no">107</span><span id="line-107"> ClientConnectionContext ctx = getClientConnectionContext();</span>
+<span class="source-line-no">108</span><span id="line-108"> String client = getClient();</span>
+<span class="source-line-no">109</span><span id="line-109"> if (client != null && userSource != null) {</span>
+<span class="source-line-no">110</span><span id="line-110"> userSource.getOrCreateMetricsClient(client, ctx.hostAddress, ctx.userName, ctx.clientVersion,</span>
+<span class="source-line-no">111</span><span id="line-111"> ctx.serviceName).incrementWriteRequest();</span>
+<span class="source-line-no">112</span><span id="line-112"> }</span>
+<span class="source-line-no">113</span><span id="line-113"> }</span>
+<span class="source-line-no">114</span><span id="line-114"></span>
+<span class="source-line-no">115</span><span id="line-115"> @Override</span>
+<span class="source-line-no">116</span><span id="line-116"> public void updateDelete(long t) {</span>
+<span class="source-line-no">117</span><span id="line-117"> String user = getActiveUser();</span>
+<span class="source-line-no">118</span><span id="line-118"> if (user != null) {</span>
+<span class="source-line-no">119</span><span id="line-119"> MetricsUserSource userSource = getOrCreateMetricsUser(user);</span>
+<span class="source-line-no">120</span><span id="line-120"> userSource.updateDelete(t);</span>
+<span class="source-line-no">121</span><span id="line-121"> incrementClientWriteMetrics(userSource);</span>
<span class="source-line-no">122</span><span id="line-122"> }</span>
<span class="source-line-no">123</span><span id="line-123"> }</span>
<span class="source-line-no">124</span><span id="line-124"></span>
<span class="source-line-no">125</span><span id="line-125"> @Override</span>
-<span class="source-line-no">126</span><span id="line-126"> public void updateIncrement(long time, long blockBytesScanned) {</span>
+<span class="source-line-no">126</span><span id="line-126"> public void updateGet(long time, long blockBytesScanned) {</span>
<span class="source-line-no">127</span><span id="line-127"> String user = getActiveUser();</span>
<span class="source-line-no">128</span><span id="line-128"> if (user != null) {</span>
<span class="source-line-no">129</span><span id="line-129"> MetricsUserSource userSource = getOrCreateMetricsUser(user);</span>
-<span class="source-line-no">130</span><span id="line-130"> userSource.updateIncrement(time, blockBytesScanned);</span>
-<span class="source-line-no">131</span><span id="line-131"> incrementClientWriteMetrics(userSource);</span>
-<span class="source-line-no">132</span><span id="line-132"> }</span>
-<span class="source-line-no">133</span><span id="line-133"> }</span>
-<span class="source-line-no">134</span><span id="line-134"></span>
-<span class="source-line-no">135</span><span id="line-135"> @Override</span>
-<span class="source-line-no">136</span><span id="line-136"> public void updateAppend(long time, long blockBytesScanned) {</span>
-<span class="source-line-no">137</span><span id="line-137"> String user = getActiveUser();</span>
-<span class="source-line-no">138</span><span id="line-138"> if (user != null) {</span>
-<span class="source-line-no">139</span><span id="line-139"> MetricsUserSource userSource = getOrCreateMetricsUser(user);</span>
-<span class="source-line-no">140</span><span id="line-140"> userSource.updateAppend(time, blockBytesScanned);</span>
-<span class="source-line-no">141</span><span id="line-141"> incrementClientWriteMetrics(userSource);</span>
-<span class="source-line-no">142</span><span id="line-142"> }</span>
-<span class="source-line-no">143</span><span id="line-143"> }</span>
-<span class="source-line-no">144</span><span id="line-144"></span>
-<span class="source-line-no">145</span><span id="line-145"> @Override</span>
-<span class="source-line-no">146</span><span id="line-146"> public void updateReplay(long t) {</span>
-<span class="source-line-no">147</span><span id="line-147"> String user = getActiveUser();</span>
-<span class="source-line-no">148</span><span id="line-148"> if (user != null) {</span>
-<span class="source-line-no">149</span><span id="line-149"> MetricsUserSource userSource = getOrCreateMetricsUser(user);</span>
-<span class="source-line-no">150</span><span id="line-150"> userSource.updateReplay(t);</span>
-<span class="source-line-no">151</span><span id="line-151"> incrementClientWriteMetrics(userSource);</span>
-<span class="source-line-no">152</span><span id="line-152"> }</span>
-<span class="source-line-no">153</span><span id="line-153"> }</span>
-<span class="source-line-no">154</span><span id="line-154"></span>
-<span class="source-line-no">155</span><span id="line-155"> @Override</span>
-<span class="source-line-no">156</span><span id="line-156"> public void updateScan(long time, long blockBytesScanned) {</span>
-<span class="source-line-no">157</span><span id="line-157"> String user = getActiveUser();</span>
-<span class="source-line-no">158</span><span id="line-158"> if (user != null) {</span>
-<span class="source-line-no">159</span><span id="line-159"> MetricsUserSource userSource = getOrCreateMetricsUser(user);</span>
-<span class="source-line-no">160</span><span id="line-160"> userSource.updateScan(time, blockBytesScanned);</span>
+<span class="source-line-no">130</span><span id="line-130"> userSource.updateGet(time, blockBytesScanned);</span>
+<span class="source-line-no">131</span><span id="line-131"> }</span>
+<span class="source-line-no">132</span><span id="line-132"> }</span>
+<span class="source-line-no">133</span><span id="line-133"></span>
+<span class="source-line-no">134</span><span id="line-134"> @Override</span>
+<span class="source-line-no">135</span><span id="line-135"> public void updateIncrement(long time, long blockBytesScanned) {</span>
+<span class="source-line-no">136</span><span id="line-136"> String user = getActiveUser();</span>
+<span class="source-line-no">137</span><span id="line-137"> if (user != null) {</span>
+<span class="source-line-no">138</span><span id="line-138"> MetricsUserSource userSource = getOrCreateMetricsUser(user);</span>
+<span class="source-line-no">139</span><span id="line-139"> userSource.updateIncrement(time, blockBytesScanned);</span>
+<span class="source-line-no">140</span><span id="line-140"> incrementClientWriteMetrics(userSource);</span>
+<span class="source-line-no">141</span><span id="line-141"> }</span>
+<span class="source-line-no">142</span><span id="line-142"> }</span>
+<span class="source-line-no">143</span><span id="line-143"></span>
+<span class="source-line-no">144</span><span id="line-144"> @Override</span>
+<span class="source-line-no">145</span><span id="line-145"> public void updateAppend(long time, long blockBytesScanned) {</span>
+<span class="source-line-no">146</span><span id="line-146"> String user = getActiveUser();</span>
+<span class="source-line-no">147</span><span id="line-147"> if (user != null) {</span>
+<span class="source-line-no">148</span><span id="line-148"> MetricsUserSource userSource = getOrCreateMetricsUser(user);</span>
+<span class="source-line-no">149</span><span id="line-149"> userSource.updateAppend(time, blockBytesScanned);</span>
+<span class="source-line-no">150</span><span id="line-150"> incrementClientWriteMetrics(userSource);</span>
+<span class="source-line-no">151</span><span id="line-151"> }</span>
+<span class="source-line-no">152</span><span id="line-152"> }</span>
+<span class="source-line-no">153</span><span id="line-153"></span>
+<span class="source-line-no">154</span><span id="line-154"> @Override</span>
+<span class="source-line-no">155</span><span id="line-155"> public void updateReplay(long t) {</span>
+<span class="source-line-no">156</span><span id="line-156"> String user = getActiveUser();</span>
+<span class="source-line-no">157</span><span id="line-157"> if (user != null) {</span>
+<span class="source-line-no">158</span><span id="line-158"> MetricsUserSource userSource = getOrCreateMetricsUser(user);</span>
+<span class="source-line-no">159</span><span id="line-159"> userSource.updateReplay(t);</span>
+<span class="source-line-no">160</span><span id="line-160"> incrementClientWriteMetrics(userSource);</span>
<span class="source-line-no">161</span><span id="line-161"> }</span>
<span class="source-line-no">162</span><span id="line-162"> }</span>
<span class="source-line-no">163</span><span id="line-163"></span>
<span class="source-line-no">164</span><span id="line-164"> @Override</span>
-<span class="source-line-no">165</span><span id="line-165"> public void updateCheckAndMutate(long blockBytesScanned) {</span>
+<span class="source-line-no">165</span><span id="line-165"> public void updateScan(long time, long blockBytesScanned) {</span>
<span class="source-line-no">166</span><span id="line-166"> String user = getActiveUser();</span>
<span class="source-line-no">167</span><span id="line-167"> if (user != null) {</span>
<span class="source-line-no">168</span><span id="line-168"> MetricsUserSource userSource = getOrCreateMetricsUser(user);</span>
-<span class="source-line-no">169</span><span id="line-169"> userSource.updateCheckAndMutate(blockBytesScanned);</span>
+<span class="source-line-no">169</span><span id="line-169"> userSource.updateScan(time, blockBytesScanned);</span>
<span class="source-line-no">170</span><span id="line-170"> }</span>
<span class="source-line-no">171</span><span id="line-171"> }</span>
<span class="source-line-no">172</span><span id="line-172"></span>
<span class="source-line-no">173</span><span id="line-173"> @Override</span>
-<span class="source-line-no">174</span><span id="line-174"> public void updateFilteredReadRequests() {</span>
+<span class="source-line-no">174</span><span id="line-174"> public void updateCheckAndMutate(long blockBytesScanned) {</span>
<span class="source-line-no">175</span><span id="line-175"> String user = getActiveUser();</span>
<span class="source-line-no">176</span><span id="line-176"> if (user != null) {</span>
<span class="source-line-no">177</span><span id="line-177"> MetricsUserSource userSource = getOrCreateMetricsUser(user);</span>
-<span class="source-line-no">178</span><span id="line-178"> incrementFilteredReadRequests(userSource);</span>
+<span class="source-line-no">178</span><span id="line-178"> userSource.updateCheckAndMutate(blockBytesScanned);</span>
<span class="source-line-no">179</span><span id="line-179"> }</span>
<span class="source-line-no">180</span><span id="line-180"> }</span>
<span class="source-line-no">181</span><span id="line-181"></span>
<span class="source-line-no">182</span><span id="line-182"> @Override</span>
-<span class="source-line-no">183</span><span id="line-183"> public void updateReadRequestCount() {</span>
+<span class="source-line-no">183</span><span id="line-183"> public void updateFilteredReadRequests() {</span>
<span class="source-line-no">184</span><span id="line-184"> String user = getActiveUser();</span>
<span class="source-line-no">185</span><span id="line-185"> if (user != null) {</span>
<span class="source-line-no">186</span><span id="line-186"> MetricsUserSource userSource = getOrCreateMetricsUser(user);</span>
-<span class="source-line-no">187</span><span id="line-187"> incrementClientReadMetrics(userSource);</span>
+<span class="source-line-no">187</span><span id="line-187"> incrementFilteredReadRequests(userSource);</span>
<span class="source-line-no">188</span><span id="line-188"> }</span>
<span class="source-line-no">189</span><span id="line-189"> }</span>
<span class="source-line-no">190</span><span id="line-190"></span>
-<span class="source-line-no">191</span><span id="line-191"> private MetricsUserSource getOrCreateMetricsUser(String user) {</span>
-<span class="source-line-no">192</span><span id="line-192"> MetricsUserSource userSource = source.getOrCreateMetricsUser(user);</span>
-<span class="source-line-no">193</span><span id="line-193"> userMetricLossyCounting.add(userSource);</span>
-<span class="source-line-no">194</span><span id="line-194"> return userSource;</span>
-<span class="source-line-no">195</span><span id="line-195"> }</span>
-<span class="source-line-no">196</span><span id="line-196">}</span>
+<span class="source-line-no">191</span><span id="line-191"> @Override</span>
+<span class="source-line-no">192</span><span id="line-192"> public void updateReadRequestCount() {</span>
+<span class="source-line-no">193</span><span id="line-193"> String user = getActiveUser();</span>
+<span class="source-line-no">194</span><span id="line-194"> if (user != null) {</span>
+<span class="source-line-no">195</span><span id="line-195"> MetricsUserSource userSource = getOrCreateMetricsUser(user);</span>
+<span class="source-line-no">196</span><span id="line-196"> incrementClientReadMetrics(userSource);</span>
+<span class="source-line-no">197</span><span id="line-197"> }</span>
+<span class="source-line-no">198</span><span id="line-198"> }</span>
+<span class="source-line-no">199</span><span id="line-199"></span>
+<span class="source-line-no">200</span><span id="line-200"> private MetricsUserSource getOrCreateMetricsUser(String user) {</span>
+<span class="source-line-no">201</span><span id="line-201"> MetricsUserSource userSource = source.getOrCreateMetricsUser(user);</span>
+<span class="source-line-no">202</span><span id="line-202"> userMetricLossyCounting.add(userSource);</span>
+<span class="source-line-no">203</span><span id="line-203"> return userSource;</span>
+<span class="source-line-no">204</span><span id="line-204"> }</span>
+<span class="source-line-no">205</span><span id="line-205"></span>
+<span class="source-line-no">206</span><span id="line-206"> private ClientConnectionContext getClientConnectionContext() {</span>
+<span class="source-line-no">207</span><span id="line-207"> String hostAddress = null;</span>
+<span class="source-line-no">208</span><span id="line-208"> String userName = "Unknown";</span>
+<span class="source-line-no">209</span><span id="line-209"> String clientVersion = "Unknown";</span>
+<span class="source-line-no">210</span><span id="line-210"> String serviceName = "Unknown";</span>
+<span class="source-line-no">211</span><span id="line-211"></span>
+<span class="source-line-no">212</span><span id="line-212"> Optional<ServerRpcConnection> rpcConnectionOptional = RpcServer.getCurrentServerRpcConnection();</span>
+<span class="source-line-no">213</span><span id="line-213"> if (rpcConnectionOptional.isPresent()) {</span>
+<span class="source-line-no">214</span><span id="line-214"> ServerRpcConnection rpcConnection = rpcConnectionOptional.get();</span>
+<span class="source-line-no">215</span><span id="line-215"> hostAddress = rpcConnection.getHostAddress();</span>
+<span class="source-line-no">216</span><span id="line-216"> RPCProtos.ConnectionHeader connectionHeader = rpcConnection.getConnectionHeader();</span>
+<span class="source-line-no">217</span><span id="line-217"> if (connectionHeader.hasUserInfo()) {</span>
+<span class="source-line-no">218</span><span id="line-218"> RPCProtos.UserInformation userInfoProto = connectionHeader.getUserInfo();</span>
+<span class="source-line-no">219</span><span id="line-219"> if (userInfoProto.hasEffectiveUser()) {</span>
+<span class="source-line-no">220</span><span id="line-220"> userName = userInfoProto.getEffectiveUser();</span>
+<span class="source-line-no">221</span><span id="line-221"> }</span>
+<span class="source-line-no">222</span><span id="line-222"> }</span>
+<span class="source-line-no">223</span><span id="line-223"> if (connectionHeader.hasVersionInfo()) {</span>
+<span class="source-line-no">224</span><span id="line-224"> clientVersion = connectionHeader.getVersionInfo().getVersion();</span>
+<span class="source-line-no">225</span><span id="line-225"> }</span>
+<span class="source-line-no">226</span><span id="line-226"> if (connectionHeader.hasServiceName()) {</span>
+<span class="source-line-no">227</span><span id="line-227"> serviceName = connectionHeader.getServiceName();</span>
+<span class="source-line-no">228</span><span id="line-228"> }</span>
+<span class="source-line-no">229</span><span id="line-229"> }</span>
+<span class="source-line-no">230</span><span id="line-230"> return new ClientConnectionContext(hostAddress, userName, clientVersion, serviceName);</span>
+<span class="source-line-no">231</span><span id="line-231"> }</span>
+<span class="source-line-no">232</span><span id="line-232"></span>
+<span class="source-line-no">233</span><span id="line-233"> private static class ClientConnectionContext {</span>
+<span class="source-line-no">234</span><span id="line-234"> final String hostAddress;</span>
+<span class="source-line-no">235</span><span id="line-235"> final String userName;</span>
+<span class="source-line-no">236</span><span id="line-236"> final String clientVersion;</span>
+<span class="source-line-no">237</span><span id="line-237"> final String serviceName;</span>
+<span class="source-line-no">238</span><span id="line-238"></span>
+<span class="source-line-no">239</span><span id="line-239"> ClientConnectionContext(String hostAddress, String userName, String clientVersion,</span>
+<span class="source-line-no">240</span><span id="line-240"> String serviceName) {</span>
+<span class="source-line-no">241</span><span id="line-241"> this.hostAddress = hostAddress;</span>
+<span class="source-line-no">242</span><span id="line-242"> this.userName = userName;</span>
+<span class="source-line-no">243</span><span id="line-243"> this.clientVersion = clientVersion;</span>
+<span class="source-line-no">244</span><span id="line-244"> this.serviceName = serviceName;</span>
+<span class="source-line-no">245</span><span id="line-245"> }</span>
+<span class="source-line-no">246</span><span id="line-246"></span>
+<span class="source-line-no">247</span><span id="line-247"> public String toString() {</span>
+<span class="source-line-no">248</span><span id="line-248"> return "ClientConnectionContext{hostAddress=" + hostAddress + ", userName=" + userName</span>
+<span class="source-line-no">249</span><span id="line-249"> + ", clientVersion=" + clientVersion + ", serviceName=" + serviceName + "}";</span>
+<span class="source-line-no">250</span><span id="line-250"> }</span>
+<span class="source-line-no">251</span><span id="line-251"> }</span>
+<span class="source-line-no">252</span><span id="line-252">}</span>
diff --git a/apidocs/src-html/org/apache/hadoop/hbase/regionserver/MetricsUserSource.ClientMetrics.html b/apidocs/src-html/org/apache/hadoop/hbase/regionserver/MetricsUserSource.ClientMetrics.html
index 8f6e2708192..9937914a699 100644
--- a/apidocs/src-html/org/apache/hadoop/hbase/regionserver/MetricsUserSource.ClientMetrics.html
+++ b/apidocs/src-html/org/apache/hadoop/hbase/regionserver/MetricsUserSource.ClientMetrics.html
@@ -52,46 +52,55 @@
<span class="source-line-no">039</span><span id="line-39"> void incrementFilteredReadRequests();</span>
<span class="source-line-no">040</span><span id="line-40"></span>
<span class="source-line-no">041</span><span id="line-41"> long getFilteredReadRequests();</span>
-<span class="source-line-no">042</span><span id="line-42"> }</span>
-<span class="source-line-no">043</span><span id="line-43"></span>
-<span class="source-line-no">044</span><span id="line-44"> String getUser();</span>
-<span class="source-line-no">045</span><span id="line-45"></span>
-<span class="source-line-no">046</span><span id="line-46"> void register();</span>
-<span class="source-line-no">047</span><span id="line-47"></span>
-<span class="source-line-no">048</span><span id="line-48"> void deregister();</span>
... 72718 lines suppressed ...