001/** 002 * 003 * Licensed to the Apache Software Foundation (ASF) under one 004 * or more contributor license agreements. See the NOTICE file 005 * distributed with this work for additional information 006 * regarding copyright ownership. The ASF licenses this file 007 * to you under the Apache License, Version 2.0 (the 008 * "License"); you may not use this file except in compliance 009 * with the License. You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, software 014 * distributed under the License is distributed on an "AS IS" BASIS, 015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 016 * See the License for the specific language governing permissions and 017 * limitations under the License. 018 */ 019package org.apache.hadoop.hbase.master; 020 021import static org.apache.hadoop.hbase.master.MasterWalManager.META_FILTER; 022 023import java.io.IOException; 024import java.net.BindException; 025import java.net.InetAddress; 026import java.net.InetSocketAddress; 027import java.util.ArrayList; 028import java.util.HashMap; 029import java.util.HashSet; 030import java.util.List; 031import java.util.Map; 032import java.util.Map.Entry; 033import java.util.Set; 034import java.util.function.BiFunction; 035import java.util.stream.Collectors; 036import org.apache.hadoop.conf.Configuration; 037import org.apache.hadoop.fs.Path; 038import org.apache.hadoop.hbase.ClusterMetricsBuilder; 039import org.apache.hadoop.hbase.DoNotRetryIOException; 040import org.apache.hadoop.hbase.HConstants; 041import org.apache.hadoop.hbase.MetaTableAccessor; 042import org.apache.hadoop.hbase.NamespaceDescriptor; 043import org.apache.hadoop.hbase.Server; 044import org.apache.hadoop.hbase.ServerMetrics; 045import org.apache.hadoop.hbase.ServerMetricsBuilder; 046import org.apache.hadoop.hbase.ServerName; 047import org.apache.hadoop.hbase.TableName; 048import org.apache.hadoop.hbase.UnknownRegionException; 049import org.apache.hadoop.hbase.client.ColumnFamilyDescriptor; 050import org.apache.hadoop.hbase.client.Connection; 051import org.apache.hadoop.hbase.client.MasterSwitchType; 052import org.apache.hadoop.hbase.client.RegionInfo; 053import org.apache.hadoop.hbase.client.RegionInfoBuilder; 054import org.apache.hadoop.hbase.client.TableDescriptor; 055import org.apache.hadoop.hbase.client.TableState; 056import org.apache.hadoop.hbase.client.VersionInfoUtil; 057import org.apache.hadoop.hbase.client.replication.ReplicationPeerConfigUtil; 058import org.apache.hadoop.hbase.coprocessor.MasterCoprocessor; 059import org.apache.hadoop.hbase.errorhandling.ForeignException; 060import org.apache.hadoop.hbase.exceptions.UnknownProtocolException; 061import org.apache.hadoop.hbase.io.hfile.HFile; 062import org.apache.hadoop.hbase.ipc.CoprocessorRpcUtils; 063import org.apache.hadoop.hbase.ipc.PriorityFunction; 064import org.apache.hadoop.hbase.ipc.QosPriority; 065import org.apache.hadoop.hbase.ipc.RpcServer; 066import org.apache.hadoop.hbase.ipc.RpcServer.BlockingServiceAndInterface; 067import org.apache.hadoop.hbase.ipc.RpcServerFactory; 068import org.apache.hadoop.hbase.ipc.RpcServerInterface; 069import org.apache.hadoop.hbase.ipc.ServerRpcController; 070import org.apache.hadoop.hbase.master.assignment.RegionStates; 071import org.apache.hadoop.hbase.master.locking.LockProcedure; 072import org.apache.hadoop.hbase.master.procedure.MasterProcedureEnv; 073import org.apache.hadoop.hbase.master.procedure.MasterProcedureUtil; 074import org.apache.hadoop.hbase.master.procedure.MasterProcedureUtil.NonceProcedureRunnable; 075import org.apache.hadoop.hbase.master.procedure.ServerCrashProcedure; 076import org.apache.hadoop.hbase.mob.MobUtils; 077import org.apache.hadoop.hbase.procedure.MasterProcedureManager; 078import org.apache.hadoop.hbase.procedure2.LockType; 079import org.apache.hadoop.hbase.procedure2.LockedResource; 080import org.apache.hadoop.hbase.procedure2.Procedure; 081import org.apache.hadoop.hbase.procedure2.ProcedureExecutor; 082import org.apache.hadoop.hbase.procedure2.ProcedureUtil; 083import org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos.AccessControlService; 084import org.apache.hadoop.hbase.protobuf.generated.VisibilityLabelsProtos.VisibilityLabelsService; 085import org.apache.hadoop.hbase.quotas.MasterQuotaManager; 086import org.apache.hadoop.hbase.quotas.QuotaObserverChore; 087import org.apache.hadoop.hbase.quotas.QuotaUtil; 088import org.apache.hadoop.hbase.quotas.SpaceQuotaSnapshot; 089import org.apache.hadoop.hbase.regionserver.RSRpcServices; 090import org.apache.hadoop.hbase.regionserver.RpcSchedulerFactory; 091import org.apache.hadoop.hbase.replication.ReplicationException; 092import org.apache.hadoop.hbase.replication.ReplicationPeerConfig; 093import org.apache.hadoop.hbase.replication.ReplicationPeerDescription; 094import org.apache.hadoop.hbase.security.User; 095import org.apache.hadoop.hbase.security.access.AccessChecker; 096import org.apache.hadoop.hbase.security.access.AccessController; 097import org.apache.hadoop.hbase.security.access.Permission; 098import org.apache.hadoop.hbase.security.visibility.VisibilityController; 099import org.apache.hadoop.hbase.snapshot.ClientSnapshotDescriptionUtils; 100import org.apache.hadoop.hbase.snapshot.SnapshotDescriptionUtils; 101import org.apache.hadoop.hbase.util.Bytes; 102import org.apache.hadoop.hbase.util.EnvironmentEdgeManager; 103import org.apache.hadoop.hbase.util.ForeignExceptionUtil; 104import org.apache.hadoop.hbase.util.Pair; 105import org.apache.hadoop.hbase.wal.AbstractFSWALProvider; 106import org.apache.yetus.audience.InterfaceAudience; 107import org.apache.zookeeper.KeeperException; 108import org.slf4j.Logger; 109import org.slf4j.LoggerFactory; 110 111import org.apache.hbase.thirdparty.com.google.protobuf.RpcController; 112import org.apache.hbase.thirdparty.com.google.protobuf.ServiceException; 113import org.apache.hbase.thirdparty.com.google.protobuf.UnsafeByteOperations; 114 115import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil; 116import org.apache.hadoop.hbase.shaded.protobuf.ResponseConverter; 117import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.CompactRegionRequest; 118import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.CompactRegionResponse; 119import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.GetRegionInfoRequest; 120import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.GetRegionInfoResponse; 121import org.apache.hadoop.hbase.shaded.protobuf.generated.ClientProtos; 122import org.apache.hadoop.hbase.shaded.protobuf.generated.ClusterStatusProtos; 123import org.apache.hadoop.hbase.shaded.protobuf.generated.ClusterStatusProtos.RegionStoreSequenceIds; 124import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos; 125import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos.NameStringPair; 126import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos.ProcedureDescription; 127import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos.RegionSpecifier.RegionSpecifierType; 128import org.apache.hadoop.hbase.shaded.protobuf.generated.LockServiceProtos.LockHeartbeatRequest; 129import org.apache.hadoop.hbase.shaded.protobuf.generated.LockServiceProtos.LockHeartbeatResponse; 130import org.apache.hadoop.hbase.shaded.protobuf.generated.LockServiceProtos.LockRequest; 131import org.apache.hadoop.hbase.shaded.protobuf.generated.LockServiceProtos.LockResponse; 132import org.apache.hadoop.hbase.shaded.protobuf.generated.LockServiceProtos.LockService; 133import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos; 134import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.AbortProcedureRequest; 135import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.AbortProcedureResponse; 136import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.AddColumnRequest; 137import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.AddColumnResponse; 138import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.AssignRegionRequest; 139import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.AssignRegionResponse; 140import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.BalanceRequest; 141import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.BalanceResponse; 142import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ClearDeadServersRequest; 143import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ClearDeadServersResponse; 144import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.CreateNamespaceRequest; 145import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.CreateNamespaceResponse; 146import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.CreateTableRequest; 147import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.CreateTableResponse; 148import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.DecommissionRegionServersRequest; 149import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.DecommissionRegionServersResponse; 150import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.DeleteColumnRequest; 151import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.DeleteColumnResponse; 152import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.DeleteNamespaceRequest; 153import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.DeleteNamespaceResponse; 154import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.DeleteSnapshotRequest; 155import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.DeleteSnapshotResponse; 156import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.DeleteTableRequest; 157import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.DeleteTableResponse; 158import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.DisableTableRequest; 159import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.DisableTableResponse; 160import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.EnableCatalogJanitorRequest; 161import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.EnableCatalogJanitorResponse; 162import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.EnableTableRequest; 163import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.EnableTableResponse; 164import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ExecProcedureRequest; 165import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ExecProcedureResponse; 166import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.GetClusterStatusRequest; 167import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.GetClusterStatusResponse; 168import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.GetCompletedSnapshotsRequest; 169import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.GetCompletedSnapshotsResponse; 170import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.GetLocksRequest; 171import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.GetLocksResponse; 172import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.GetNamespaceDescriptorRequest; 173import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.GetNamespaceDescriptorResponse; 174import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.GetProcedureResultRequest; 175import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.GetProcedureResultResponse; 176import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.GetProceduresRequest; 177import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.GetProceduresResponse; 178import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.GetSchemaAlterStatusRequest; 179import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.GetSchemaAlterStatusResponse; 180import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.GetTableDescriptorsRequest; 181import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.GetTableDescriptorsResponse; 182import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.GetTableNamesRequest; 183import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.GetTableNamesResponse; 184import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.GetTableStateRequest; 185import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.GetTableStateResponse; 186import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.HbckService; 187import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.IsBalancerEnabledRequest; 188import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.IsBalancerEnabledResponse; 189import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.IsCatalogJanitorEnabledRequest; 190import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.IsCatalogJanitorEnabledResponse; 191import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.IsCleanerChoreEnabledRequest; 192import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.IsCleanerChoreEnabledResponse; 193import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.IsInMaintenanceModeRequest; 194import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.IsInMaintenanceModeResponse; 195import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.IsMasterRunningRequest; 196import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.IsMasterRunningResponse; 197import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.IsNormalizerEnabledRequest; 198import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.IsNormalizerEnabledResponse; 199import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.IsProcedureDoneRequest; 200import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.IsProcedureDoneResponse; 201import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.IsSnapshotDoneRequest; 202import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.IsSnapshotDoneResponse; 203import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.IsSplitOrMergeEnabledRequest; 204import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.IsSplitOrMergeEnabledResponse; 205import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ListDecommissionedRegionServersRequest; 206import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ListDecommissionedRegionServersResponse; 207import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ListNamespaceDescriptorsRequest; 208import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ListNamespaceDescriptorsResponse; 209import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ListTableDescriptorsByNamespaceRequest; 210import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ListTableDescriptorsByNamespaceResponse; 211import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ListTableNamesByNamespaceRequest; 212import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ListTableNamesByNamespaceResponse; 213import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.MajorCompactionTimestampForRegionRequest; 214import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.MajorCompactionTimestampRequest; 215import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.MajorCompactionTimestampResponse; 216import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.MasterService; 217import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.MergeTableRegionsRequest; 218import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.MergeTableRegionsResponse; 219import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ModifyColumnRequest; 220import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ModifyColumnResponse; 221import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ModifyNamespaceRequest; 222import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ModifyNamespaceResponse; 223import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ModifyTableRequest; 224import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ModifyTableResponse; 225import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.MoveRegionRequest; 226import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.MoveRegionResponse; 227import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.NormalizeRequest; 228import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.NormalizeResponse; 229import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.OfflineRegionRequest; 230import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.OfflineRegionResponse; 231import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.RecommissionRegionServerRequest; 232import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.RecommissionRegionServerResponse; 233import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.RestoreSnapshotRequest; 234import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.RestoreSnapshotResponse; 235import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.RunCatalogScanRequest; 236import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.RunCatalogScanResponse; 237import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.RunCleanerChoreRequest; 238import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.RunCleanerChoreResponse; 239import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.SecurityCapabilitiesRequest; 240import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.SecurityCapabilitiesResponse; 241import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.SetBalancerRunningRequest; 242import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.SetBalancerRunningResponse; 243import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.SetCleanerChoreRunningRequest; 244import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.SetCleanerChoreRunningResponse; 245import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.SetNormalizerRunningRequest; 246import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.SetNormalizerRunningResponse; 247import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.SetQuotaRequest; 248import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.SetQuotaResponse; 249import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.SetSplitOrMergeEnabledRequest; 250import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.SetSplitOrMergeEnabledResponse; 251import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.SetTableStateInMetaRequest; 252import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ShutdownRequest; 253import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ShutdownResponse; 254import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.SnapshotRequest; 255import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.SnapshotResponse; 256import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.SplitTableRegionRequest; 257import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.SplitTableRegionResponse; 258import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.StopMasterRequest; 259import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.StopMasterResponse; 260import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.TruncateTableRequest; 261import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.TruncateTableResponse; 262import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.UnassignRegionRequest; 263import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.UnassignRegionResponse; 264import org.apache.hadoop.hbase.shaded.protobuf.generated.QuotaProtos.GetQuotaStatesRequest; 265import org.apache.hadoop.hbase.shaded.protobuf.generated.QuotaProtos.GetQuotaStatesResponse; 266import org.apache.hadoop.hbase.shaded.protobuf.generated.QuotaProtos.GetQuotaStatesResponse.NamespaceQuotaSnapshot; 267import org.apache.hadoop.hbase.shaded.protobuf.generated.QuotaProtos.GetQuotaStatesResponse.TableQuotaSnapshot; 268import org.apache.hadoop.hbase.shaded.protobuf.generated.QuotaProtos.GetSpaceQuotaRegionSizesRequest; 269import org.apache.hadoop.hbase.shaded.protobuf.generated.QuotaProtos.GetSpaceQuotaRegionSizesResponse; 270import org.apache.hadoop.hbase.shaded.protobuf.generated.QuotaProtos.GetSpaceQuotaRegionSizesResponse.RegionSizes; 271import org.apache.hadoop.hbase.shaded.protobuf.generated.RegionServerStatusProtos.GetLastFlushedSequenceIdRequest; 272import org.apache.hadoop.hbase.shaded.protobuf.generated.RegionServerStatusProtos.GetLastFlushedSequenceIdResponse; 273import org.apache.hadoop.hbase.shaded.protobuf.generated.RegionServerStatusProtos.RegionServerReportRequest; 274import org.apache.hadoop.hbase.shaded.protobuf.generated.RegionServerStatusProtos.RegionServerReportResponse; 275import org.apache.hadoop.hbase.shaded.protobuf.generated.RegionServerStatusProtos.RegionServerStartupRequest; 276import org.apache.hadoop.hbase.shaded.protobuf.generated.RegionServerStatusProtos.RegionServerStartupResponse; 277import org.apache.hadoop.hbase.shaded.protobuf.generated.RegionServerStatusProtos.RegionServerStatusService; 278import org.apache.hadoop.hbase.shaded.protobuf.generated.RegionServerStatusProtos.RegionSpaceUse; 279import org.apache.hadoop.hbase.shaded.protobuf.generated.RegionServerStatusProtos.RegionSpaceUseReportRequest; 280import org.apache.hadoop.hbase.shaded.protobuf.generated.RegionServerStatusProtos.RegionSpaceUseReportResponse; 281import org.apache.hadoop.hbase.shaded.protobuf.generated.RegionServerStatusProtos.ReportRSFatalErrorRequest; 282import org.apache.hadoop.hbase.shaded.protobuf.generated.RegionServerStatusProtos.ReportRSFatalErrorResponse; 283import org.apache.hadoop.hbase.shaded.protobuf.generated.RegionServerStatusProtos.ReportRegionStateTransitionRequest; 284import org.apache.hadoop.hbase.shaded.protobuf.generated.RegionServerStatusProtos.ReportRegionStateTransitionResponse; 285import org.apache.hadoop.hbase.shaded.protobuf.generated.ReplicationProtos.AddReplicationPeerRequest; 286import org.apache.hadoop.hbase.shaded.protobuf.generated.ReplicationProtos.AddReplicationPeerResponse; 287import org.apache.hadoop.hbase.shaded.protobuf.generated.ReplicationProtos.DisableReplicationPeerRequest; 288import org.apache.hadoop.hbase.shaded.protobuf.generated.ReplicationProtos.DisableReplicationPeerResponse; 289import org.apache.hadoop.hbase.shaded.protobuf.generated.ReplicationProtos.EnableReplicationPeerRequest; 290import org.apache.hadoop.hbase.shaded.protobuf.generated.ReplicationProtos.EnableReplicationPeerResponse; 291import org.apache.hadoop.hbase.shaded.protobuf.generated.ReplicationProtos.GetReplicationPeerConfigRequest; 292import org.apache.hadoop.hbase.shaded.protobuf.generated.ReplicationProtos.GetReplicationPeerConfigResponse; 293import org.apache.hadoop.hbase.shaded.protobuf.generated.ReplicationProtos.ListReplicationPeersRequest; 294import org.apache.hadoop.hbase.shaded.protobuf.generated.ReplicationProtos.ListReplicationPeersResponse; 295import org.apache.hadoop.hbase.shaded.protobuf.generated.ReplicationProtos.RemoveReplicationPeerRequest; 296import org.apache.hadoop.hbase.shaded.protobuf.generated.ReplicationProtos.RemoveReplicationPeerResponse; 297import org.apache.hadoop.hbase.shaded.protobuf.generated.ReplicationProtos.ReplicationState; 298import org.apache.hadoop.hbase.shaded.protobuf.generated.ReplicationProtos.UpdateReplicationPeerConfigRequest; 299import org.apache.hadoop.hbase.shaded.protobuf.generated.ReplicationProtos.UpdateReplicationPeerConfigResponse; 300import org.apache.hadoop.hbase.shaded.protobuf.generated.SnapshotProtos.SnapshotDescription; 301 302/** 303 * Implements the master RPC services. 304 */ 305@InterfaceAudience.Private 306@SuppressWarnings("deprecation") 307public class MasterRpcServices extends RSRpcServices 308 implements MasterService.BlockingInterface, RegionServerStatusService.BlockingInterface, 309 LockService.BlockingInterface, HbckService.BlockingInterface { 310 private static final Logger LOG = LoggerFactory.getLogger(MasterRpcServices.class.getName()); 311 312 private final HMaster master; 313 314 /** 315 * @return Subset of configuration to pass initializing regionservers: e.g. 316 * the filesystem to use and root directory to use. 317 */ 318 private RegionServerStartupResponse.Builder createConfigurationSubset() { 319 RegionServerStartupResponse.Builder resp = addConfig( 320 RegionServerStartupResponse.newBuilder(), HConstants.HBASE_DIR); 321 resp = addConfig(resp, "fs.defaultFS"); 322 return addConfig(resp, "hbase.master.info.port"); 323 } 324 325 private RegionServerStartupResponse.Builder addConfig( 326 final RegionServerStartupResponse.Builder resp, final String key) { 327 NameStringPair.Builder entry = NameStringPair.newBuilder() 328 .setName(key) 329 .setValue(master.getConfiguration().get(key)); 330 resp.addMapEntries(entry.build()); 331 return resp; 332 } 333 334 public MasterRpcServices(HMaster m) throws IOException { 335 super(m); 336 master = m; 337 } 338 339 @Override 340 protected RpcServerInterface createRpcServer(Server server, Configuration conf, 341 RpcSchedulerFactory rpcSchedulerFactory, InetSocketAddress bindAddress, String name) 342 throws IOException { 343 // RpcServer at HM by default enable ByteBufferPool iff HM having user table region in it 344 boolean reservoirEnabled = conf.getBoolean(RESERVOIR_ENABLED_KEY, 345 LoadBalancer.isMasterCanHostUserRegions(conf)); 346 try { 347 return RpcServerFactory.createRpcServer(server, name, getServices(), 348 bindAddress, // use final bindAddress for this server. 349 conf, rpcSchedulerFactory.create(conf, this, server), reservoirEnabled); 350 } catch (BindException be) { 351 throw new IOException(be.getMessage() + ". To switch ports use the '" 352 + HConstants.MASTER_PORT + "' configuration property.", 353 be.getCause() != null ? be.getCause() : be); 354 } 355 } 356 357 @Override 358 protected PriorityFunction createPriority() { 359 return new MasterAnnotationReadingPriorityFunction(this); 360 } 361 362 /** 363 * Checks for the following pre-checks in order: 364 * <ol> 365 * <li>Master is initialized</li> 366 * <li>Rpc caller has admin permissions</li> 367 * </ol> 368 * @param requestName name of rpc request. Used in reporting failures to provide context. 369 * @throws ServiceException If any of the above listed pre-check fails. 370 */ 371 private void rpcPreCheck(String requestName) throws ServiceException { 372 try { 373 master.checkInitialized(); 374 requirePermission(requestName, Permission.Action.ADMIN); 375 } catch (IOException ioe) { 376 throw new ServiceException(ioe); 377 } 378 } 379 380 enum BalanceSwitchMode { 381 SYNC, 382 ASYNC 383 } 384 385 /** 386 * Assigns balancer switch according to BalanceSwitchMode 387 * @param b new balancer switch 388 * @param mode BalanceSwitchMode 389 * @return old balancer switch 390 */ 391 boolean switchBalancer(final boolean b, BalanceSwitchMode mode) throws IOException { 392 boolean oldValue = master.loadBalancerTracker.isBalancerOn(); 393 boolean newValue = b; 394 try { 395 if (master.cpHost != null) { 396 master.cpHost.preBalanceSwitch(newValue); 397 } 398 try { 399 if (mode == BalanceSwitchMode.SYNC) { 400 synchronized (master.getLoadBalancer()) { 401 master.loadBalancerTracker.setBalancerOn(newValue); 402 } 403 } else { 404 master.loadBalancerTracker.setBalancerOn(newValue); 405 } 406 } catch (KeeperException ke) { 407 throw new IOException(ke); 408 } 409 LOG.info(master.getClientIdAuditPrefix() + " set balanceSwitch=" + newValue); 410 if (master.cpHost != null) { 411 master.cpHost.postBalanceSwitch(oldValue, newValue); 412 } 413 } catch (IOException ioe) { 414 LOG.warn("Error flipping balance switch", ioe); 415 } 416 return oldValue; 417 } 418 419 boolean synchronousBalanceSwitch(final boolean b) throws IOException { 420 return switchBalancer(b, BalanceSwitchMode.SYNC); 421 } 422 423 /** 424 * @return list of blocking services and their security info classes that this server supports 425 */ 426 @Override 427 protected List<BlockingServiceAndInterface> getServices() { 428 List<BlockingServiceAndInterface> bssi = new ArrayList<>(5); 429 bssi.add(new BlockingServiceAndInterface( 430 MasterService.newReflectiveBlockingService(this), 431 MasterService.BlockingInterface.class)); 432 bssi.add(new BlockingServiceAndInterface( 433 RegionServerStatusService.newReflectiveBlockingService(this), 434 RegionServerStatusService.BlockingInterface.class)); 435 bssi.add(new BlockingServiceAndInterface(LockService.newReflectiveBlockingService(this), 436 LockService.BlockingInterface.class)); 437 bssi.add(new BlockingServiceAndInterface(HbckService.newReflectiveBlockingService(this), 438 HbckService.BlockingInterface.class)); 439 bssi.addAll(super.getServices()); 440 return bssi; 441 } 442 443 @Override 444 @QosPriority(priority = HConstants.ADMIN_QOS) 445 public GetLastFlushedSequenceIdResponse getLastFlushedSequenceId(RpcController controller, 446 GetLastFlushedSequenceIdRequest request) throws ServiceException { 447 try { 448 master.checkServiceStarted(); 449 } catch (IOException ioe) { 450 throw new ServiceException(ioe); 451 } 452 byte[] encodedRegionName = request.getRegionName().toByteArray(); 453 RegionStoreSequenceIds ids = master.getServerManager() 454 .getLastFlushedSequenceId(encodedRegionName); 455 return ResponseConverter.buildGetLastFlushedSequenceIdResponse(ids); 456 } 457 458 @Override 459 public RegionServerReportResponse regionServerReport( 460 RpcController controller, RegionServerReportRequest request) throws ServiceException { 461 try { 462 master.checkServiceStarted(); 463 int version = VersionInfoUtil.getCurrentClientVersionNumber(); 464 ClusterStatusProtos.ServerLoad sl = request.getLoad(); 465 ServerName serverName = ProtobufUtil.toServerName(request.getServer()); 466 ServerMetrics oldLoad = master.getServerManager().getLoad(serverName); 467 ServerMetrics newLoad = ServerMetricsBuilder.toServerMetrics(serverName, version, sl); 468 master.getServerManager().regionServerReport(serverName, newLoad); 469 master.getAssignmentManager() 470 .reportOnlineRegions(serverName, newLoad.getRegionMetrics().keySet()); 471 if (sl != null && master.metricsMaster != null) { 472 // Up our metrics. 473 master.metricsMaster.incrementRequests(sl.getTotalNumberOfRequests() 474 - (oldLoad != null ? oldLoad.getRequestCount() : 0)); 475 } 476 } catch (IOException ioe) { 477 throw new ServiceException(ioe); 478 } 479 return RegionServerReportResponse.newBuilder().build(); 480 } 481 482 @Override 483 public RegionServerStartupResponse regionServerStartup( 484 RpcController controller, RegionServerStartupRequest request) throws ServiceException { 485 // Register with server manager 486 try { 487 master.checkServiceStarted(); 488 int version = VersionInfoUtil.getCurrentClientVersionNumber(); 489 InetAddress ia = master.getRemoteInetAddress( 490 request.getPort(), request.getServerStartCode()); 491 // if regionserver passed hostname to use, 492 // then use it instead of doing a reverse DNS lookup 493 ServerName rs = master.getServerManager().regionServerStartup(request, version, ia); 494 495 // Send back some config info 496 RegionServerStartupResponse.Builder resp = createConfigurationSubset(); 497 NameStringPair.Builder entry = NameStringPair.newBuilder() 498 .setName(HConstants.KEY_FOR_HOSTNAME_SEEN_BY_MASTER) 499 .setValue(rs.getHostname()); 500 resp.addMapEntries(entry.build()); 501 502 return resp.build(); 503 } catch (IOException ioe) { 504 throw new ServiceException(ioe); 505 } 506 } 507 508 @Override 509 public ReportRSFatalErrorResponse reportRSFatalError( 510 RpcController controller, ReportRSFatalErrorRequest request) throws ServiceException { 511 String errorText = request.getErrorMessage(); 512 ServerName sn = ProtobufUtil.toServerName(request.getServer()); 513 String msg = sn + " reported a fatal error:\n" + errorText; 514 LOG.warn(msg); 515 master.rsFatals.add(msg); 516 return ReportRSFatalErrorResponse.newBuilder().build(); 517 } 518 519 @Override 520 public AddColumnResponse addColumn(RpcController controller, 521 AddColumnRequest req) throws ServiceException { 522 try { 523 long procId = master.addColumn( 524 ProtobufUtil.toTableName(req.getTableName()), 525 ProtobufUtil.toColumnFamilyDescriptor(req.getColumnFamilies()), 526 req.getNonceGroup(), 527 req.getNonce()); 528 if (procId == -1) { 529 // This mean operation was not performed in server, so do not set any procId 530 return AddColumnResponse.newBuilder().build(); 531 } else { 532 return AddColumnResponse.newBuilder().setProcId(procId).build(); 533 } 534 } catch (IOException ioe) { 535 throw new ServiceException(ioe); 536 } 537 } 538 539 @Override 540 public AssignRegionResponse assignRegion(RpcController controller, 541 AssignRegionRequest req) throws ServiceException { 542 try { 543 master.checkInitialized(); 544 545 final RegionSpecifierType type = req.getRegion().getType(); 546 if (type != RegionSpecifierType.REGION_NAME) { 547 LOG.warn("assignRegion specifier type: expected: " + RegionSpecifierType.REGION_NAME 548 + " actual: " + type); 549 } 550 551 final byte[] regionName = req.getRegion().getValue().toByteArray(); 552 final RegionInfo regionInfo = master.getAssignmentManager().getRegionInfo(regionName); 553 if (regionInfo == null) throw new UnknownRegionException(Bytes.toStringBinary(regionName)); 554 555 final AssignRegionResponse arr = AssignRegionResponse.newBuilder().build(); 556 if (master.cpHost != null) { 557 master.cpHost.preAssign(regionInfo); 558 } 559 LOG.info(master.getClientIdAuditPrefix() + " assign " + regionInfo.getRegionNameAsString()); 560 master.getAssignmentManager().assign(regionInfo); 561 if (master.cpHost != null) { 562 master.cpHost.postAssign(regionInfo); 563 } 564 return arr; 565 } catch (IOException ioe) { 566 throw new ServiceException(ioe); 567 } 568 } 569 570 571 @Override 572 public BalanceResponse balance(RpcController controller, 573 BalanceRequest request) throws ServiceException { 574 try { 575 return BalanceResponse.newBuilder().setBalancerRan(master.balance( 576 request.hasForce()? request.getForce(): false)).build(); 577 } catch (IOException ex) { 578 throw new ServiceException(ex); 579 } 580 } 581 582 @Override 583 public CreateNamespaceResponse createNamespace(RpcController controller, 584 CreateNamespaceRequest request) throws ServiceException { 585 try { 586 long procId = master.createNamespace( 587 ProtobufUtil.toNamespaceDescriptor(request.getNamespaceDescriptor()), 588 request.getNonceGroup(), 589 request.getNonce()); 590 return CreateNamespaceResponse.newBuilder().setProcId(procId).build(); 591 } catch (IOException e) { 592 throw new ServiceException(e); 593 } 594 } 595 596 @Override 597 public CreateTableResponse createTable(RpcController controller, CreateTableRequest req) 598 throws ServiceException { 599 TableDescriptor tableDescriptor = ProtobufUtil.toTableDescriptor(req.getTableSchema()); 600 byte [][] splitKeys = ProtobufUtil.getSplitKeysArray(req); 601 try { 602 long procId = 603 master.createTable(tableDescriptor, splitKeys, req.getNonceGroup(), req.getNonce()); 604 LOG.info(master.getClientIdAuditPrefix() + " procedure request for creating table: " + 605 req.getTableSchema().getTableName() + " procId is: " + procId); 606 return CreateTableResponse.newBuilder().setProcId(procId).build(); 607 } catch (IOException ioe) { 608 throw new ServiceException(ioe); 609 } 610 } 611 612 @Override 613 public DeleteColumnResponse deleteColumn(RpcController controller, 614 DeleteColumnRequest req) throws ServiceException { 615 try { 616 long procId = master.deleteColumn( 617 ProtobufUtil.toTableName(req.getTableName()), 618 req.getColumnName().toByteArray(), 619 req.getNonceGroup(), 620 req.getNonce()); 621 if (procId == -1) { 622 // This mean operation was not performed in server, so do not set any procId 623 return DeleteColumnResponse.newBuilder().build(); 624 } else { 625 return DeleteColumnResponse.newBuilder().setProcId(procId).build(); 626 } 627 } catch (IOException ioe) { 628 throw new ServiceException(ioe); 629 } 630 } 631 632 @Override 633 public DeleteNamespaceResponse deleteNamespace(RpcController controller, 634 DeleteNamespaceRequest request) throws ServiceException { 635 try { 636 long procId = master.deleteNamespace( 637 request.getNamespaceName(), 638 request.getNonceGroup(), 639 request.getNonce()); 640 return DeleteNamespaceResponse.newBuilder().setProcId(procId).build(); 641 } catch (IOException e) { 642 throw new ServiceException(e); 643 } 644 } 645 646 /** 647 * Execute Delete Snapshot operation. 648 * @return DeleteSnapshotResponse (a protobuf wrapped void) if the snapshot existed and was 649 * deleted properly. 650 * @throws ServiceException wrapping SnapshotDoesNotExistException if specified snapshot did not 651 * exist. 652 */ 653 @Override 654 public DeleteSnapshotResponse deleteSnapshot(RpcController controller, 655 DeleteSnapshotRequest request) throws ServiceException { 656 try { 657 master.checkInitialized(); 658 master.snapshotManager.checkSnapshotSupport(); 659 660 LOG.info(master.getClientIdAuditPrefix() + " delete " + request.getSnapshot()); 661 master.snapshotManager.deleteSnapshot(request.getSnapshot()); 662 return DeleteSnapshotResponse.newBuilder().build(); 663 } catch (IOException e) { 664 throw new ServiceException(e); 665 } 666 } 667 668 @Override 669 public DeleteTableResponse deleteTable(RpcController controller, 670 DeleteTableRequest request) throws ServiceException { 671 try { 672 long procId = master.deleteTable(ProtobufUtil.toTableName( 673 request.getTableName()), request.getNonceGroup(), request.getNonce()); 674 return DeleteTableResponse.newBuilder().setProcId(procId).build(); 675 } catch (IOException ioe) { 676 throw new ServiceException(ioe); 677 } 678 } 679 680 @Override 681 public TruncateTableResponse truncateTable(RpcController controller, TruncateTableRequest request) 682 throws ServiceException { 683 try { 684 long procId = master.truncateTable( 685 ProtobufUtil.toTableName(request.getTableName()), 686 request.getPreserveSplits(), 687 request.getNonceGroup(), 688 request.getNonce()); 689 return TruncateTableResponse.newBuilder().setProcId(procId).build(); 690 } catch (IOException ioe) { 691 throw new ServiceException(ioe); 692 } 693 } 694 695 @Override 696 public DisableTableResponse disableTable(RpcController controller, 697 DisableTableRequest request) throws ServiceException { 698 try { 699 long procId = master.disableTable( 700 ProtobufUtil.toTableName(request.getTableName()), 701 request.getNonceGroup(), 702 request.getNonce()); 703 return DisableTableResponse.newBuilder().setProcId(procId).build(); 704 } catch (IOException ioe) { 705 throw new ServiceException(ioe); 706 } 707 } 708 709 @Override 710 public EnableCatalogJanitorResponse enableCatalogJanitor(RpcController c, 711 EnableCatalogJanitorRequest req) throws ServiceException { 712 rpcPreCheck("enableCatalogJanitor"); 713 return EnableCatalogJanitorResponse.newBuilder().setPrevValue( 714 master.catalogJanitorChore.setEnabled(req.getEnable())).build(); 715 } 716 717 @Override 718 public SetCleanerChoreRunningResponse setCleanerChoreRunning( 719 RpcController c, SetCleanerChoreRunningRequest req) throws ServiceException { 720 rpcPreCheck("setCleanerChoreRunning"); 721 722 boolean prevValue = 723 master.getLogCleaner().getEnabled() && master.getHFileCleaner().getEnabled(); 724 master.getLogCleaner().setEnabled(req.getOn()); 725 master.getHFileCleaner().setEnabled(req.getOn()); 726 return SetCleanerChoreRunningResponse.newBuilder().setPrevValue(prevValue).build(); 727 } 728 729 @Override 730 public EnableTableResponse enableTable(RpcController controller, 731 EnableTableRequest request) throws ServiceException { 732 try { 733 long procId = master.enableTable( 734 ProtobufUtil.toTableName(request.getTableName()), 735 request.getNonceGroup(), 736 request.getNonce()); 737 return EnableTableResponse.newBuilder().setProcId(procId).build(); 738 } catch (IOException ioe) { 739 throw new ServiceException(ioe); 740 } 741 } 742 743 @Override 744 public MergeTableRegionsResponse mergeTableRegions( 745 RpcController c, MergeTableRegionsRequest request) throws ServiceException { 746 try { 747 master.checkInitialized(); 748 } catch (IOException ioe) { 749 throw new ServiceException(ioe); 750 } 751 752 RegionStates regionStates = master.getAssignmentManager().getRegionStates(); 753 754 assert(request.getRegionCount() == 2); 755 RegionInfo[] regionsToMerge = new RegionInfo[request.getRegionCount()]; 756 for (int i = 0; i < request.getRegionCount(); i++) { 757 final byte[] encodedNameOfRegion = request.getRegion(i).getValue().toByteArray(); 758 if (request.getRegion(i).getType() != RegionSpecifierType.ENCODED_REGION_NAME) { 759 LOG.warn("MergeRegions specifier type: expected: " 760 + RegionSpecifierType.ENCODED_REGION_NAME + " actual: region " + i + " =" 761 + request.getRegion(i).getType()); 762 } 763 RegionState regionState = regionStates.getRegionState(Bytes.toString(encodedNameOfRegion)); 764 if (regionState == null) { 765 throw new ServiceException( 766 new UnknownRegionException(Bytes.toStringBinary(encodedNameOfRegion))); 767 } 768 regionsToMerge[i] = regionState.getRegion(); 769 } 770 771 try { 772 long procId = master.mergeRegions( 773 regionsToMerge, 774 request.getForcible(), 775 request.getNonceGroup(), 776 request.getNonce()); 777 return MergeTableRegionsResponse.newBuilder().setProcId(procId).build(); 778 } catch (IOException ioe) { 779 throw new ServiceException(ioe); 780 } 781 } 782 783 @Override 784 public SplitTableRegionResponse splitRegion(final RpcController controller, 785 final SplitTableRegionRequest request) throws ServiceException { 786 try { 787 long procId = master.splitRegion( 788 ProtobufUtil.toRegionInfo(request.getRegionInfo()), 789 request.hasSplitRow() ? request.getSplitRow().toByteArray() : null, 790 request.getNonceGroup(), 791 request.getNonce()); 792 return SplitTableRegionResponse.newBuilder().setProcId(procId).build(); 793 } catch (IOException ie) { 794 throw new ServiceException(ie); 795 } 796 } 797 798 @Override 799 public ClientProtos.CoprocessorServiceResponse execMasterService(final RpcController controller, 800 final ClientProtos.CoprocessorServiceRequest request) throws ServiceException { 801 rpcPreCheck("execMasterService"); 802 try { 803 ServerRpcController execController = new ServerRpcController(); 804 ClientProtos.CoprocessorServiceCall call = request.getCall(); 805 String serviceName = call.getServiceName(); 806 String methodName = call.getMethodName(); 807 if (!master.coprocessorServiceHandlers.containsKey(serviceName)) { 808 throw new UnknownProtocolException(null, 809 "No registered Master Coprocessor Endpoint found for " + serviceName + 810 ". Has it been enabled?"); 811 } 812 813 com.google.protobuf.Service service = master.coprocessorServiceHandlers.get(serviceName); 814 com.google.protobuf.Descriptors.ServiceDescriptor serviceDesc = service.getDescriptorForType(); 815 com.google.protobuf.Descriptors.MethodDescriptor methodDesc = 816 CoprocessorRpcUtils.getMethodDescriptor(methodName, serviceDesc); 817 818 com.google.protobuf.Message execRequest = 819 CoprocessorRpcUtils.getRequest(service, methodDesc, call.getRequest()); 820 final com.google.protobuf.Message.Builder responseBuilder = 821 service.getResponsePrototype(methodDesc).newBuilderForType(); 822 service.callMethod(methodDesc, execController, execRequest, 823 (message) -> { 824 if (message != null) { 825 responseBuilder.mergeFrom(message); 826 } 827 }); 828 com.google.protobuf.Message execResult = responseBuilder.build(); 829 if (execController.getFailedOn() != null) { 830 throw execController.getFailedOn(); 831 } 832 return CoprocessorRpcUtils.getResponse(execResult, HConstants.EMPTY_BYTE_ARRAY); 833 } catch (IOException ie) { 834 throw new ServiceException(ie); 835 } 836 } 837 838 /** 839 * Triggers an asynchronous attempt to run a distributed procedure. 840 * {@inheritDoc} 841 */ 842 @Override 843 public ExecProcedureResponse execProcedure(RpcController controller, 844 ExecProcedureRequest request) throws ServiceException { 845 try { 846 master.checkInitialized(); 847 ProcedureDescription desc = request.getProcedure(); 848 MasterProcedureManager mpm = master.getMasterProcedureManagerHost().getProcedureManager( 849 desc.getSignature()); 850 if (mpm == null) { 851 throw new ServiceException(new DoNotRetryIOException("The procedure is not registered: " 852 + desc.getSignature())); 853 } 854 LOG.info(master.getClientIdAuditPrefix() + " procedure request for: " + desc.getSignature()); 855 mpm.checkPermissions(desc, accessChecker, RpcServer.getRequestUser().orElse(null)); 856 mpm.execProcedure(desc); 857 // send back the max amount of time the client should wait for the procedure 858 // to complete 859 long waitTime = SnapshotDescriptionUtils.DEFAULT_MAX_WAIT_TIME; 860 return ExecProcedureResponse.newBuilder().setExpectedTimeout( 861 waitTime).build(); 862 } catch (ForeignException e) { 863 throw new ServiceException(e.getCause()); 864 } catch (IOException e) { 865 throw new ServiceException(e); 866 } 867 } 868 869 /** 870 * Triggers a synchronous attempt to run a distributed procedure and sets 871 * return data in response. 872 * {@inheritDoc} 873 */ 874 @Override 875 public ExecProcedureResponse execProcedureWithRet(RpcController controller, 876 ExecProcedureRequest request) throws ServiceException { 877 rpcPreCheck("execProcedureWithRet"); 878 try { 879 ProcedureDescription desc = request.getProcedure(); 880 MasterProcedureManager mpm = 881 master.getMasterProcedureManagerHost().getProcedureManager(desc.getSignature()); 882 if (mpm == null) { 883 throw new ServiceException("The procedure is not registered: " + desc.getSignature()); 884 } 885 LOG.info(master.getClientIdAuditPrefix() + " procedure request for: " + desc.getSignature()); 886 byte[] data = mpm.execProcedureWithRet(desc); 887 ExecProcedureResponse.Builder builder = ExecProcedureResponse.newBuilder(); 888 // set return data if available 889 if (data != null) { 890 builder.setReturnData(UnsafeByteOperations.unsafeWrap(data)); 891 } 892 return builder.build(); 893 } catch (IOException e) { 894 throw new ServiceException(e); 895 } 896 } 897 898 @Override 899 public GetClusterStatusResponse getClusterStatus(RpcController controller, 900 GetClusterStatusRequest req) throws ServiceException { 901 GetClusterStatusResponse.Builder response = GetClusterStatusResponse.newBuilder(); 902 try { 903 // We used to check if Master was up at this point but let this call proceed even if 904 // Master is initializing... else we shut out stuff like hbck2 tool from making progress 905 // since it queries this method to figure cluster version. hbck2 wants to be able to work 906 // against Master even if it is 'initializing' so it can do fixup. 907 response.setClusterStatus(ClusterMetricsBuilder.toClusterStatus( 908 master.getClusterMetrics(ClusterMetricsBuilder.toOptions(req.getOptionsList())))); 909 } catch (IOException e) { 910 throw new ServiceException(e); 911 } 912 return response.build(); 913 } 914 915 /** 916 * List the currently available/stored snapshots. Any in-progress snapshots are ignored 917 */ 918 @Override 919 public GetCompletedSnapshotsResponse getCompletedSnapshots(RpcController controller, 920 GetCompletedSnapshotsRequest request) throws ServiceException { 921 try { 922 master.checkInitialized(); 923 GetCompletedSnapshotsResponse.Builder builder = GetCompletedSnapshotsResponse.newBuilder(); 924 List<SnapshotDescription> snapshots = master.snapshotManager.getCompletedSnapshots(); 925 926 // convert to protobuf 927 for (SnapshotDescription snapshot : snapshots) { 928 builder.addSnapshots(snapshot); 929 } 930 return builder.build(); 931 } catch (IOException e) { 932 throw new ServiceException(e); 933 } 934 } 935 936 @Override 937 public GetNamespaceDescriptorResponse getNamespaceDescriptor( 938 RpcController controller, GetNamespaceDescriptorRequest request) 939 throws ServiceException { 940 try { 941 return GetNamespaceDescriptorResponse.newBuilder() 942 .setNamespaceDescriptor(ProtobufUtil.toProtoNamespaceDescriptor( 943 master.getNamespace(request.getNamespaceName()))) 944 .build(); 945 } catch (IOException e) { 946 throw new ServiceException(e); 947 } 948 } 949 950 /** 951 * Get the number of regions of the table that have been updated by the alter. 952 * 953 * @return Pair indicating the number of regions updated Pair.getFirst is the 954 * regions that are yet to be updated Pair.getSecond is the total number 955 * of regions of the table 956 * @throws ServiceException 957 */ 958 @Override 959 public GetSchemaAlterStatusResponse getSchemaAlterStatus( 960 RpcController controller, GetSchemaAlterStatusRequest req) throws ServiceException { 961 // TODO: currently, we query using the table name on the client side. this 962 // may overlap with other table operations or the table operation may 963 // have completed before querying this API. We need to refactor to a 964 // transaction system in the future to avoid these ambiguities. 965 TableName tableName = ProtobufUtil.toTableName(req.getTableName()); 966 967 try { 968 master.checkInitialized(); 969 Pair<Integer,Integer> pair = master.getAssignmentManager().getReopenStatus(tableName); 970 GetSchemaAlterStatusResponse.Builder ret = GetSchemaAlterStatusResponse.newBuilder(); 971 ret.setYetToUpdateRegions(pair.getFirst()); 972 ret.setTotalRegions(pair.getSecond()); 973 return ret.build(); 974 } catch (IOException ioe) { 975 throw new ServiceException(ioe); 976 } 977 } 978 979 /** 980 * Get list of TableDescriptors for requested tables. 981 * @param c Unused (set to null). 982 * @param req GetTableDescriptorsRequest that contains: 983 * - tableNames: requested tables, or if empty, all are requested 984 * @return GetTableDescriptorsResponse 985 * @throws ServiceException 986 */ 987 @Override 988 public GetTableDescriptorsResponse getTableDescriptors(RpcController c, 989 GetTableDescriptorsRequest req) throws ServiceException { 990 try { 991 master.checkInitialized(); 992 993 final String regex = req.hasRegex() ? req.getRegex() : null; 994 final String namespace = req.hasNamespace() ? req.getNamespace() : null; 995 List<TableName> tableNameList = null; 996 if (req.getTableNamesCount() > 0) { 997 tableNameList = new ArrayList<TableName>(req.getTableNamesCount()); 998 for (HBaseProtos.TableName tableNamePB: req.getTableNamesList()) { 999 tableNameList.add(ProtobufUtil.toTableName(tableNamePB)); 1000 } 1001 } 1002 1003 List<TableDescriptor> descriptors = master.listTableDescriptors(namespace, regex, 1004 tableNameList, req.getIncludeSysTables()); 1005 1006 GetTableDescriptorsResponse.Builder builder = GetTableDescriptorsResponse.newBuilder(); 1007 if (descriptors != null && descriptors.size() > 0) { 1008 // Add the table descriptors to the response 1009 for (TableDescriptor htd: descriptors) { 1010 builder.addTableSchema(ProtobufUtil.toTableSchema(htd)); 1011 } 1012 } 1013 return builder.build(); 1014 } catch (IOException ioe) { 1015 throw new ServiceException(ioe); 1016 } 1017 } 1018 1019 /** 1020 * Get list of userspace table names 1021 * @param controller Unused (set to null). 1022 * @param req GetTableNamesRequest 1023 * @return GetTableNamesResponse 1024 * @throws ServiceException 1025 */ 1026 @Override 1027 public GetTableNamesResponse getTableNames(RpcController controller, 1028 GetTableNamesRequest req) throws ServiceException { 1029 try { 1030 master.checkServiceStarted(); 1031 1032 final String regex = req.hasRegex() ? req.getRegex() : null; 1033 final String namespace = req.hasNamespace() ? req.getNamespace() : null; 1034 List<TableName> tableNames = master.listTableNames(namespace, regex, 1035 req.getIncludeSysTables()); 1036 1037 GetTableNamesResponse.Builder builder = GetTableNamesResponse.newBuilder(); 1038 if (tableNames != null && tableNames.size() > 0) { 1039 // Add the table names to the response 1040 for (TableName table: tableNames) { 1041 builder.addTableNames(ProtobufUtil.toProtoTableName(table)); 1042 } 1043 } 1044 return builder.build(); 1045 } catch (IOException e) { 1046 throw new ServiceException(e); 1047 } 1048 } 1049 1050 @Override 1051 public GetTableStateResponse getTableState(RpcController controller, 1052 GetTableStateRequest request) throws ServiceException { 1053 try { 1054 master.checkServiceStarted(); 1055 TableName tableName = ProtobufUtil.toTableName(request.getTableName()); 1056 TableState ts = master.getTableStateManager().getTableState(tableName); 1057 GetTableStateResponse.Builder builder = GetTableStateResponse.newBuilder(); 1058 builder.setTableState(ts.convert()); 1059 return builder.build(); 1060 } catch (IOException e) { 1061 throw new ServiceException(e); 1062 } 1063 } 1064 1065 @Override 1066 public IsCatalogJanitorEnabledResponse isCatalogJanitorEnabled(RpcController c, 1067 IsCatalogJanitorEnabledRequest req) throws ServiceException { 1068 return IsCatalogJanitorEnabledResponse.newBuilder().setValue( 1069 master.isCatalogJanitorEnabled()).build(); 1070 } 1071 1072 @Override 1073 public IsCleanerChoreEnabledResponse isCleanerChoreEnabled(RpcController c, 1074 IsCleanerChoreEnabledRequest req) 1075 throws ServiceException { 1076 return IsCleanerChoreEnabledResponse.newBuilder().setValue(master.isCleanerChoreEnabled()) 1077 .build(); 1078 } 1079 1080 @Override 1081 public IsMasterRunningResponse isMasterRunning(RpcController c, 1082 IsMasterRunningRequest req) throws ServiceException { 1083 try { 1084 master.checkServiceStarted(); 1085 return IsMasterRunningResponse.newBuilder().setIsMasterRunning( 1086 !master.isStopped()).build(); 1087 } catch (IOException e) { 1088 throw new ServiceException(e); 1089 } 1090 } 1091 1092 /** 1093 * Checks if the specified procedure is done. 1094 * @return true if the procedure is done, false if the procedure is in the process of completing 1095 * @throws ServiceException if invalid procedure or failed procedure with progress failure reason. 1096 */ 1097 @Override 1098 public IsProcedureDoneResponse isProcedureDone(RpcController controller, 1099 IsProcedureDoneRequest request) throws ServiceException { 1100 try { 1101 master.checkInitialized(); 1102 ProcedureDescription desc = request.getProcedure(); 1103 MasterProcedureManager mpm = master.getMasterProcedureManagerHost().getProcedureManager( 1104 desc.getSignature()); 1105 if (mpm == null) { 1106 throw new ServiceException("The procedure is not registered: " 1107 + desc.getSignature()); 1108 } 1109 LOG.debug("Checking to see if procedure from request:" 1110 + desc.getSignature() + " is done"); 1111 1112 IsProcedureDoneResponse.Builder builder = 1113 IsProcedureDoneResponse.newBuilder(); 1114 boolean done = mpm.isProcedureDone(desc); 1115 builder.setDone(done); 1116 return builder.build(); 1117 } catch (ForeignException e) { 1118 throw new ServiceException(e.getCause()); 1119 } catch (IOException e) { 1120 throw new ServiceException(e); 1121 } 1122 } 1123 1124 /** 1125 * Checks if the specified snapshot is done. 1126 * @return true if the snapshot is in file system ready to use, 1127 * false if the snapshot is in the process of completing 1128 * @throws ServiceException wrapping UnknownSnapshotException if invalid snapshot, or 1129 * a wrapped HBaseSnapshotException with progress failure reason. 1130 */ 1131 @Override 1132 public IsSnapshotDoneResponse isSnapshotDone(RpcController controller, 1133 IsSnapshotDoneRequest request) throws ServiceException { 1134 LOG.debug("Checking to see if snapshot from request:" + 1135 ClientSnapshotDescriptionUtils.toString(request.getSnapshot()) + " is done"); 1136 try { 1137 master.checkInitialized(); 1138 IsSnapshotDoneResponse.Builder builder = IsSnapshotDoneResponse.newBuilder(); 1139 boolean done = master.snapshotManager.isSnapshotDone(request.getSnapshot()); 1140 builder.setDone(done); 1141 return builder.build(); 1142 } catch (ForeignException e) { 1143 throw new ServiceException(e.getCause()); 1144 } catch (IOException e) { 1145 throw new ServiceException(e); 1146 } 1147 } 1148 1149 @Override 1150 public GetProcedureResultResponse getProcedureResult(RpcController controller, 1151 GetProcedureResultRequest request) throws ServiceException { 1152 LOG.debug("Checking to see if procedure is done pid=" + request.getProcId()); 1153 try { 1154 master.checkInitialized(); 1155 GetProcedureResultResponse.Builder builder = GetProcedureResultResponse.newBuilder(); 1156 long procId = request.getProcId(); 1157 ProcedureExecutor<?> executor = master.getMasterProcedureExecutor(); 1158 Procedure<?> result = executor.getResultOrProcedure(procId); 1159 if (result != null) { 1160 builder.setSubmittedTime(result.getSubmittedTime()); 1161 builder.setLastUpdate(result.getLastUpdate()); 1162 if (executor.isFinished(procId)) { 1163 builder.setState(GetProcedureResultResponse.State.FINISHED); 1164 if (result.isFailed()) { 1165 IOException exception = 1166 MasterProcedureUtil.unwrapRemoteIOException(result); 1167 builder.setException(ForeignExceptionUtil.toProtoForeignException(exception)); 1168 } 1169 byte[] resultData = result.getResult(); 1170 if (resultData != null) { 1171 builder.setResult(UnsafeByteOperations.unsafeWrap(resultData)); 1172 } 1173 master.getMasterProcedureExecutor().removeResult(request.getProcId()); 1174 } else { 1175 builder.setState(GetProcedureResultResponse.State.RUNNING); 1176 } 1177 } else { 1178 builder.setState(GetProcedureResultResponse.State.NOT_FOUND); 1179 } 1180 return builder.build(); 1181 } catch (IOException e) { 1182 throw new ServiceException(e); 1183 } 1184 } 1185 1186 @Override 1187 public AbortProcedureResponse abortProcedure( 1188 RpcController rpcController, AbortProcedureRequest request) throws ServiceException { 1189 try { 1190 AbortProcedureResponse.Builder response = AbortProcedureResponse.newBuilder(); 1191 boolean abortResult = 1192 master.abortProcedure(request.getProcId(), request.getMayInterruptIfRunning()); 1193 response.setIsProcedureAborted(abortResult); 1194 return response.build(); 1195 } catch (IOException e) { 1196 throw new ServiceException(e); 1197 } 1198 } 1199 1200 @Override 1201 public ListNamespaceDescriptorsResponse listNamespaceDescriptors(RpcController c, 1202 ListNamespaceDescriptorsRequest request) throws ServiceException { 1203 try { 1204 ListNamespaceDescriptorsResponse.Builder response = 1205 ListNamespaceDescriptorsResponse.newBuilder(); 1206 for(NamespaceDescriptor ns: master.getNamespaces()) { 1207 response.addNamespaceDescriptor(ProtobufUtil.toProtoNamespaceDescriptor(ns)); 1208 } 1209 return response.build(); 1210 } catch (IOException e) { 1211 throw new ServiceException(e); 1212 } 1213 } 1214 1215 @Override 1216 public GetProceduresResponse getProcedures( 1217 RpcController rpcController, 1218 GetProceduresRequest request) throws ServiceException { 1219 try { 1220 final GetProceduresResponse.Builder response = GetProceduresResponse.newBuilder(); 1221 for (Procedure<?> p: master.getProcedures()) { 1222 response.addProcedure(ProcedureUtil.convertToProtoProcedure(p)); 1223 } 1224 return response.build(); 1225 } catch (IOException e) { 1226 throw new ServiceException(e); 1227 } 1228 } 1229 1230 @Override 1231 public GetLocksResponse getLocks( 1232 RpcController controller, 1233 GetLocksRequest request) throws ServiceException { 1234 try { 1235 final GetLocksResponse.Builder builder = GetLocksResponse.newBuilder(); 1236 1237 for (LockedResource lockedResource: master.getLocks()) { 1238 builder.addLock(ProcedureUtil.convertToProtoLockedResource(lockedResource)); 1239 } 1240 1241 return builder.build(); 1242 } catch (IOException e) { 1243 throw new ServiceException(e); 1244 } 1245 } 1246 1247 @Override 1248 public ListTableDescriptorsByNamespaceResponse listTableDescriptorsByNamespace(RpcController c, 1249 ListTableDescriptorsByNamespaceRequest request) throws ServiceException { 1250 try { 1251 ListTableDescriptorsByNamespaceResponse.Builder b = 1252 ListTableDescriptorsByNamespaceResponse.newBuilder(); 1253 for (TableDescriptor htd : master 1254 .listTableDescriptorsByNamespace(request.getNamespaceName())) { 1255 b.addTableSchema(ProtobufUtil.toTableSchema(htd)); 1256 } 1257 return b.build(); 1258 } catch (IOException e) { 1259 throw new ServiceException(e); 1260 } 1261 } 1262 1263 @Override 1264 public ListTableNamesByNamespaceResponse listTableNamesByNamespace(RpcController c, 1265 ListTableNamesByNamespaceRequest request) throws ServiceException { 1266 try { 1267 ListTableNamesByNamespaceResponse.Builder b = 1268 ListTableNamesByNamespaceResponse.newBuilder(); 1269 for (TableName tableName: master.listTableNamesByNamespace(request.getNamespaceName())) { 1270 b.addTableName(ProtobufUtil.toProtoTableName(tableName)); 1271 } 1272 return b.build(); 1273 } catch (IOException e) { 1274 throw new ServiceException(e); 1275 } 1276 } 1277 1278 @Override 1279 public ModifyColumnResponse modifyColumn(RpcController controller, 1280 ModifyColumnRequest req) throws ServiceException { 1281 try { 1282 long procId = master.modifyColumn( 1283 ProtobufUtil.toTableName(req.getTableName()), 1284 ProtobufUtil.toColumnFamilyDescriptor(req.getColumnFamilies()), 1285 req.getNonceGroup(), 1286 req.getNonce()); 1287 if (procId == -1) { 1288 // This mean operation was not performed in server, so do not set any procId 1289 return ModifyColumnResponse.newBuilder().build(); 1290 } else { 1291 return ModifyColumnResponse.newBuilder().setProcId(procId).build(); 1292 } 1293 } catch (IOException ioe) { 1294 throw new ServiceException(ioe); 1295 } 1296 } 1297 1298 @Override 1299 public ModifyNamespaceResponse modifyNamespace(RpcController controller, 1300 ModifyNamespaceRequest request) throws ServiceException { 1301 try { 1302 long procId = master.modifyNamespace( 1303 ProtobufUtil.toNamespaceDescriptor(request.getNamespaceDescriptor()), 1304 request.getNonceGroup(), 1305 request.getNonce()); 1306 return ModifyNamespaceResponse.newBuilder().setProcId(procId).build(); 1307 } catch (IOException e) { 1308 throw new ServiceException(e); 1309 } 1310 } 1311 1312 @Override 1313 public ModifyTableResponse modifyTable(RpcController controller, 1314 ModifyTableRequest req) throws ServiceException { 1315 try { 1316 long procId = master.modifyTable( 1317 ProtobufUtil.toTableName(req.getTableName()), 1318 ProtobufUtil.toTableDescriptor(req.getTableSchema()), 1319 req.getNonceGroup(), 1320 req.getNonce()); 1321 return ModifyTableResponse.newBuilder().setProcId(procId).build(); 1322 } catch (IOException ioe) { 1323 throw new ServiceException(ioe); 1324 } 1325 } 1326 1327 @Override 1328 public MoveRegionResponse moveRegion(RpcController controller, 1329 MoveRegionRequest req) throws ServiceException { 1330 final byte [] encodedRegionName = req.getRegion().getValue().toByteArray(); 1331 RegionSpecifierType type = req.getRegion().getType(); 1332 final byte [] destServerName = (req.hasDestServerName())? 1333 Bytes.toBytes(ProtobufUtil.toServerName(req.getDestServerName()).getServerName()):null; 1334 MoveRegionResponse mrr = MoveRegionResponse.newBuilder().build(); 1335 1336 if (type != RegionSpecifierType.ENCODED_REGION_NAME) { 1337 LOG.warn("moveRegion specifier type: expected: " + RegionSpecifierType.ENCODED_REGION_NAME 1338 + " actual: " + type); 1339 } 1340 1341 try { 1342 master.checkInitialized(); 1343 master.move(encodedRegionName, destServerName); 1344 } catch (IOException ioe) { 1345 throw new ServiceException(ioe); 1346 } 1347 return mrr; 1348 } 1349 1350 /** 1351 * Offline specified region from master's in-memory state. It will not attempt to 1352 * reassign the region as in unassign. 1353 * 1354 * This is a special method that should be used by experts or hbck. 1355 * 1356 */ 1357 @Override 1358 public OfflineRegionResponse offlineRegion(RpcController controller, 1359 OfflineRegionRequest request) throws ServiceException { 1360 try { 1361 master.checkInitialized(); 1362 1363 final RegionSpecifierType type = request.getRegion().getType(); 1364 if (type != RegionSpecifierType.REGION_NAME) { 1365 LOG.warn("moveRegion specifier type: expected: " + RegionSpecifierType.REGION_NAME 1366 + " actual: " + type); 1367 } 1368 1369 final byte[] regionName = request.getRegion().getValue().toByteArray(); 1370 final RegionInfo hri = master.getAssignmentManager().getRegionInfo(regionName); 1371 if (hri == null) throw new UnknownRegionException(Bytes.toStringBinary(regionName)); 1372 1373 if (master.cpHost != null) { 1374 master.cpHost.preRegionOffline(hri); 1375 } 1376 LOG.info(master.getClientIdAuditPrefix() + " offline " + hri.getRegionNameAsString()); 1377 master.getAssignmentManager().offlineRegion(hri); 1378 if (master.cpHost != null) { 1379 master.cpHost.postRegionOffline(hri); 1380 } 1381 } catch (IOException ioe) { 1382 throw new ServiceException(ioe); 1383 } 1384 return OfflineRegionResponse.newBuilder().build(); 1385 } 1386 1387 /** 1388 * Execute Restore/Clone snapshot operation. 1389 * 1390 * <p>If the specified table exists a "Restore" is executed, replacing the table 1391 * schema and directory data with the content of the snapshot. 1392 * The table must be disabled, or a UnsupportedOperationException will be thrown. 1393 * 1394 * <p>If the table doesn't exist a "Clone" is executed, a new table is created 1395 * using the schema at the time of the snapshot, and the content of the snapshot. 1396 * 1397 * <p>The restore/clone operation does not require copying HFiles. Since HFiles 1398 * are immutable the table can point to and use the same files as the original one. 1399 */ 1400 @Override 1401 public RestoreSnapshotResponse restoreSnapshot(RpcController controller, 1402 RestoreSnapshotRequest request) throws ServiceException { 1403 try { 1404 long procId = master.restoreSnapshot(request.getSnapshot(), request.getNonceGroup(), 1405 request.getNonce(), request.getRestoreACL()); 1406 return RestoreSnapshotResponse.newBuilder().setProcId(procId).build(); 1407 } catch (ForeignException e) { 1408 throw new ServiceException(e.getCause()); 1409 } catch (IOException e) { 1410 throw new ServiceException(e); 1411 } 1412 } 1413 1414 @Override 1415 public RunCatalogScanResponse runCatalogScan(RpcController c, 1416 RunCatalogScanRequest req) throws ServiceException { 1417 rpcPreCheck("runCatalogScan"); 1418 try { 1419 return ResponseConverter.buildRunCatalogScanResponse(master.catalogJanitorChore.scan()); 1420 } catch (IOException ioe) { 1421 throw new ServiceException(ioe); 1422 } 1423 } 1424 1425 @Override 1426 public RunCleanerChoreResponse runCleanerChore(RpcController c, RunCleanerChoreRequest req) 1427 throws ServiceException { 1428 rpcPreCheck("runCleanerChore"); 1429 boolean result = master.getHFileCleaner().runCleaner() && master.getLogCleaner().runCleaner(); 1430 return ResponseConverter.buildRunCleanerChoreResponse(result); 1431 } 1432 1433 @Override 1434 public SetBalancerRunningResponse setBalancerRunning(RpcController c, 1435 SetBalancerRunningRequest req) throws ServiceException { 1436 try { 1437 master.checkInitialized(); 1438 boolean prevValue = (req.getSynchronous())? 1439 synchronousBalanceSwitch(req.getOn()) : master.balanceSwitch(req.getOn()); 1440 return SetBalancerRunningResponse.newBuilder().setPrevBalanceValue(prevValue).build(); 1441 } catch (IOException ioe) { 1442 throw new ServiceException(ioe); 1443 } 1444 } 1445 1446 @Override 1447 public ShutdownResponse shutdown(RpcController controller, 1448 ShutdownRequest request) throws ServiceException { 1449 LOG.info(master.getClientIdAuditPrefix() + " shutdown"); 1450 try { 1451 master.shutdown(); 1452 } catch (IOException e) { 1453 LOG.error("Exception occurred in HMaster.shutdown()", e); 1454 throw new ServiceException(e); 1455 } 1456 return ShutdownResponse.newBuilder().build(); 1457 } 1458 1459 /** 1460 * Triggers an asynchronous attempt to take a snapshot. 1461 * {@inheritDoc} 1462 */ 1463 @Override 1464 public SnapshotResponse snapshot(RpcController controller, 1465 SnapshotRequest request) throws ServiceException { 1466 try { 1467 master.checkInitialized(); 1468 master.snapshotManager.checkSnapshotSupport(); 1469 1470 LOG.info(master.getClientIdAuditPrefix() + " snapshot request for:" + 1471 ClientSnapshotDescriptionUtils.toString(request.getSnapshot())); 1472 // get the snapshot information 1473 SnapshotDescription snapshot = SnapshotDescriptionUtils.validate( 1474 request.getSnapshot(), master.getConfiguration()); 1475 master.snapshotManager.takeSnapshot(snapshot); 1476 1477 // send back the max amount of time the client should wait for the snapshot to complete 1478 long waitTime = SnapshotDescriptionUtils.getMaxMasterTimeout(master.getConfiguration(), 1479 snapshot.getType(), SnapshotDescriptionUtils.DEFAULT_MAX_WAIT_TIME); 1480 return SnapshotResponse.newBuilder().setExpectedTimeout(waitTime).build(); 1481 } catch (ForeignException e) { 1482 throw new ServiceException(e.getCause()); 1483 } catch (IOException e) { 1484 throw new ServiceException(e); 1485 } 1486 } 1487 1488 @Override 1489 public StopMasterResponse stopMaster(RpcController controller, 1490 StopMasterRequest request) throws ServiceException { 1491 LOG.info(master.getClientIdAuditPrefix() + " stop"); 1492 try { 1493 master.stopMaster(); 1494 } catch (IOException e) { 1495 LOG.error("Exception occurred while stopping master", e); 1496 throw new ServiceException(e); 1497 } 1498 return StopMasterResponse.newBuilder().build(); 1499 } 1500 1501 @Override 1502 public IsInMaintenanceModeResponse isMasterInMaintenanceMode( 1503 final RpcController controller, 1504 final IsInMaintenanceModeRequest request) throws ServiceException { 1505 IsInMaintenanceModeResponse.Builder response = IsInMaintenanceModeResponse.newBuilder(); 1506 response.setInMaintenanceMode(master.isInMaintenanceMode()); 1507 return response.build(); 1508 } 1509 1510 @Override 1511 public UnassignRegionResponse unassignRegion(RpcController controller, 1512 UnassignRegionRequest req) throws ServiceException { 1513 try { 1514 final byte [] regionName = req.getRegion().getValue().toByteArray(); 1515 RegionSpecifierType type = req.getRegion().getType(); 1516 final boolean force = req.getForce(); 1517 UnassignRegionResponse urr = UnassignRegionResponse.newBuilder().build(); 1518 1519 master.checkInitialized(); 1520 if (type != RegionSpecifierType.REGION_NAME) { 1521 LOG.warn("unassignRegion specifier type: expected: " + RegionSpecifierType.REGION_NAME 1522 + " actual: " + type); 1523 } 1524 Pair<RegionInfo, ServerName> pair = 1525 MetaTableAccessor.getRegion(master.getConnection(), regionName); 1526 if (Bytes.equals(RegionInfoBuilder.FIRST_META_REGIONINFO.getRegionName(),regionName)) { 1527 pair = new Pair<>(RegionInfoBuilder.FIRST_META_REGIONINFO, 1528 master.getMetaTableLocator().getMetaRegionLocation(master.getZooKeeper())); 1529 } 1530 if (pair == null) { 1531 throw new UnknownRegionException(Bytes.toString(regionName)); 1532 } 1533 1534 RegionInfo hri = pair.getFirst(); 1535 if (master.cpHost != null) { 1536 master.cpHost.preUnassign(hri, force); 1537 } 1538 LOG.debug(master.getClientIdAuditPrefix() + " unassign " + hri.getRegionNameAsString() 1539 + " in current location if it is online and reassign.force=" + force); 1540 master.getAssignmentManager().unassign(hri); 1541 if (master.cpHost != null) { 1542 master.cpHost.postUnassign(hri, force); 1543 } 1544 1545 return urr; 1546 } catch (IOException ioe) { 1547 throw new ServiceException(ioe); 1548 } 1549 } 1550 1551 @Override 1552 public ReportRegionStateTransitionResponse reportRegionStateTransition(RpcController c, 1553 ReportRegionStateTransitionRequest req) throws ServiceException { 1554 try { 1555 master.checkServiceStarted(); 1556 return master.getAssignmentManager().reportRegionStateTransition(req); 1557 } catch (IOException ioe) { 1558 throw new ServiceException(ioe); 1559 } 1560 } 1561 1562 @Override 1563 public SetQuotaResponse setQuota(RpcController c, SetQuotaRequest req) 1564 throws ServiceException { 1565 try { 1566 master.checkInitialized(); 1567 return master.getMasterQuotaManager().setQuota(req); 1568 } catch (Exception e) { 1569 throw new ServiceException(e); 1570 } 1571 } 1572 1573 @Override 1574 public MajorCompactionTimestampResponse getLastMajorCompactionTimestamp(RpcController controller, 1575 MajorCompactionTimestampRequest request) throws ServiceException { 1576 MajorCompactionTimestampResponse.Builder response = 1577 MajorCompactionTimestampResponse.newBuilder(); 1578 try { 1579 master.checkInitialized(); 1580 response.setCompactionTimestamp(master.getLastMajorCompactionTimestamp(ProtobufUtil 1581 .toTableName(request.getTableName()))); 1582 } catch (IOException e) { 1583 throw new ServiceException(e); 1584 } 1585 return response.build(); 1586 } 1587 1588 @Override 1589 public MajorCompactionTimestampResponse getLastMajorCompactionTimestampForRegion( 1590 RpcController controller, MajorCompactionTimestampForRegionRequest request) 1591 throws ServiceException { 1592 MajorCompactionTimestampResponse.Builder response = 1593 MajorCompactionTimestampResponse.newBuilder(); 1594 try { 1595 master.checkInitialized(); 1596 response.setCompactionTimestamp(master.getLastMajorCompactionTimestampForRegion(request 1597 .getRegion().getValue().toByteArray())); 1598 } catch (IOException e) { 1599 throw new ServiceException(e); 1600 } 1601 return response.build(); 1602 } 1603 1604 /** 1605 * Compact a region on the master. 1606 * 1607 * @param controller the RPC controller 1608 * @param request the request 1609 * @throws ServiceException 1610 */ 1611 @Override 1612 @QosPriority(priority=HConstants.ADMIN_QOS) 1613 public CompactRegionResponse compactRegion(final RpcController controller, 1614 final CompactRegionRequest request) throws ServiceException { 1615 try { 1616 master.checkInitialized(); 1617 byte[] regionName = request.getRegion().getValue().toByteArray(); 1618 TableName tableName = RegionInfo.getTable(regionName); 1619 // if the region is a mob region, do the mob file compaction. 1620 if (MobUtils.isMobRegionName(tableName, regionName)) { 1621 checkHFileFormatVersionForMob(); 1622 return compactMob(request, tableName); 1623 } else { 1624 return super.compactRegion(controller, request); 1625 } 1626 } catch (IOException ie) { 1627 throw new ServiceException(ie); 1628 } 1629 } 1630 1631 /** 1632 * check configured hfile format version before to do compaction 1633 * @throws IOException throw IOException 1634 */ 1635 private void checkHFileFormatVersionForMob() throws IOException { 1636 if (HFile.getFormatVersion(master.getConfiguration()) < HFile.MIN_FORMAT_VERSION_WITH_TAGS) { 1637 LOG.error("A minimum HFile version of " + HFile.MIN_FORMAT_VERSION_WITH_TAGS 1638 + " is required for MOB compaction. Compaction will not run."); 1639 throw new IOException("A minimum HFile version of " + HFile.MIN_FORMAT_VERSION_WITH_TAGS 1640 + " is required for MOB feature. Consider setting " + HFile.FORMAT_VERSION_KEY 1641 + " accordingly."); 1642 } 1643 } 1644 1645 @Override 1646 @QosPriority(priority=HConstants.ADMIN_QOS) 1647 public GetRegionInfoResponse getRegionInfo(final RpcController controller, 1648 final GetRegionInfoRequest request) throws ServiceException { 1649 byte[] regionName = request.getRegion().getValue().toByteArray(); 1650 TableName tableName = RegionInfo.getTable(regionName); 1651 if (MobUtils.isMobRegionName(tableName, regionName)) { 1652 // a dummy region info contains the compaction state. 1653 RegionInfo mobRegionInfo = MobUtils.getMobRegionInfo(tableName); 1654 GetRegionInfoResponse.Builder builder = GetRegionInfoResponse.newBuilder(); 1655 builder.setRegionInfo(ProtobufUtil.toRegionInfo(mobRegionInfo)); 1656 if (request.hasCompactionState() && request.getCompactionState()) { 1657 builder.setCompactionState(master.getMobCompactionState(tableName)); 1658 } 1659 return builder.build(); 1660 } else { 1661 return super.getRegionInfo(controller, request); 1662 } 1663 } 1664 1665 /** 1666 * Compacts the mob files in the current table. 1667 * @param request the request. 1668 * @param tableName the current table name. 1669 * @return The response of the mob file compaction. 1670 * @throws IOException 1671 */ 1672 private CompactRegionResponse compactMob(final CompactRegionRequest request, 1673 TableName tableName) throws IOException { 1674 if (!master.getTableStateManager().isTableState(tableName, TableState.State.ENABLED)) { 1675 throw new DoNotRetryIOException("Table " + tableName + " is not enabled"); 1676 } 1677 boolean allFiles = false; 1678 List<ColumnFamilyDescriptor> compactedColumns = new ArrayList<>(); 1679 ColumnFamilyDescriptor[] hcds = master.getTableDescriptors().get(tableName).getColumnFamilies(); 1680 byte[] family = null; 1681 if (request.hasFamily()) { 1682 family = request.getFamily().toByteArray(); 1683 for (ColumnFamilyDescriptor hcd : hcds) { 1684 if (Bytes.equals(family, hcd.getName())) { 1685 if (!hcd.isMobEnabled()) { 1686 LOG.error("Column family " + hcd.getNameAsString() + " is not a mob column family"); 1687 throw new DoNotRetryIOException("Column family " + hcd.getNameAsString() 1688 + " is not a mob column family"); 1689 } 1690 compactedColumns.add(hcd); 1691 } 1692 } 1693 } else { 1694 for (ColumnFamilyDescriptor hcd : hcds) { 1695 if (hcd.isMobEnabled()) { 1696 compactedColumns.add(hcd); 1697 } 1698 } 1699 } 1700 if (compactedColumns.isEmpty()) { 1701 LOG.error("No mob column families are assigned in the mob compaction"); 1702 throw new DoNotRetryIOException( 1703 "No mob column families are assigned in the mob compaction"); 1704 } 1705 if (request.hasMajor() && request.getMajor()) { 1706 allFiles = true; 1707 } 1708 String familyLogMsg = (family != null) ? Bytes.toString(family) : ""; 1709 if (LOG.isTraceEnabled()) { 1710 LOG.trace("User-triggered mob compaction requested for table: " 1711 + tableName.getNameAsString() + " for column family: " + familyLogMsg); 1712 } 1713 master.requestMobCompaction(tableName, compactedColumns, allFiles); 1714 return CompactRegionResponse.newBuilder().build(); 1715 } 1716 1717 @Override 1718 public IsBalancerEnabledResponse isBalancerEnabled(RpcController controller, 1719 IsBalancerEnabledRequest request) throws ServiceException { 1720 IsBalancerEnabledResponse.Builder response = IsBalancerEnabledResponse.newBuilder(); 1721 response.setEnabled(master.isBalancerOn()); 1722 return response.build(); 1723 } 1724 1725 @Override 1726 public SetSplitOrMergeEnabledResponse setSplitOrMergeEnabled(RpcController controller, 1727 SetSplitOrMergeEnabledRequest request) throws ServiceException { 1728 SetSplitOrMergeEnabledResponse.Builder response = SetSplitOrMergeEnabledResponse.newBuilder(); 1729 try { 1730 master.checkInitialized(); 1731 boolean newValue = request.getEnabled(); 1732 for (MasterProtos.MasterSwitchType masterSwitchType: request.getSwitchTypesList()) { 1733 MasterSwitchType switchType = convert(masterSwitchType); 1734 boolean oldValue = master.isSplitOrMergeEnabled(switchType); 1735 response.addPrevValue(oldValue); 1736 if (master.cpHost != null) { 1737 master.cpHost.preSetSplitOrMergeEnabled(newValue, switchType); 1738 } 1739 master.getSplitOrMergeTracker().setSplitOrMergeEnabled(newValue, switchType); 1740 if (master.cpHost != null) { 1741 master.cpHost.postSetSplitOrMergeEnabled(newValue, switchType); 1742 } 1743 } 1744 } catch (IOException e) { 1745 throw new ServiceException(e); 1746 } catch (KeeperException e) { 1747 throw new ServiceException(e); 1748 } 1749 return response.build(); 1750 } 1751 1752 @Override 1753 public IsSplitOrMergeEnabledResponse isSplitOrMergeEnabled(RpcController controller, 1754 IsSplitOrMergeEnabledRequest request) throws ServiceException { 1755 IsSplitOrMergeEnabledResponse.Builder response = IsSplitOrMergeEnabledResponse.newBuilder(); 1756 response.setEnabled(master.isSplitOrMergeEnabled(convert(request.getSwitchType()))); 1757 return response.build(); 1758 } 1759 1760 @Override 1761 public NormalizeResponse normalize(RpcController controller, 1762 NormalizeRequest request) throws ServiceException { 1763 rpcPreCheck("normalize"); 1764 try { 1765 return NormalizeResponse.newBuilder().setNormalizerRan(master.normalizeRegions()).build(); 1766 } catch (IOException ex) { 1767 throw new ServiceException(ex); 1768 } 1769 } 1770 1771 @Override 1772 public SetNormalizerRunningResponse setNormalizerRunning(RpcController controller, 1773 SetNormalizerRunningRequest request) throws ServiceException { 1774 rpcPreCheck("setNormalizerRunning"); 1775 1776 // Sets normalizer on/off flag in ZK. 1777 boolean prevValue = master.getRegionNormalizerTracker().isNormalizerOn(); 1778 boolean newValue = request.getOn(); 1779 try { 1780 master.getRegionNormalizerTracker().setNormalizerOn(newValue); 1781 } catch (KeeperException ke) { 1782 LOG.warn("Error flipping normalizer switch", ke); 1783 } 1784 LOG.info("{} set normalizerSwitch={}", master.getClientIdAuditPrefix(), newValue); 1785 return SetNormalizerRunningResponse.newBuilder().setPrevNormalizerValue(prevValue).build(); 1786 } 1787 1788 @Override 1789 public IsNormalizerEnabledResponse isNormalizerEnabled(RpcController controller, 1790 IsNormalizerEnabledRequest request) throws ServiceException { 1791 IsNormalizerEnabledResponse.Builder response = IsNormalizerEnabledResponse.newBuilder(); 1792 response.setEnabled(master.isNormalizerOn()); 1793 return response.build(); 1794 } 1795 1796 /** 1797 * Returns the security capabilities in effect on the cluster 1798 */ 1799 @Override 1800 public SecurityCapabilitiesResponse getSecurityCapabilities(RpcController controller, 1801 SecurityCapabilitiesRequest request) throws ServiceException { 1802 SecurityCapabilitiesResponse.Builder response = SecurityCapabilitiesResponse.newBuilder(); 1803 try { 1804 master.checkInitialized(); 1805 Set<SecurityCapabilitiesResponse.Capability> capabilities = new HashSet<>(); 1806 // Authentication 1807 if (User.isHBaseSecurityEnabled(master.getConfiguration())) { 1808 capabilities.add(SecurityCapabilitiesResponse.Capability.SECURE_AUTHENTICATION); 1809 } else { 1810 capabilities.add(SecurityCapabilitiesResponse.Capability.SIMPLE_AUTHENTICATION); 1811 } 1812 // A coprocessor that implements AccessControlService can provide AUTHORIZATION and 1813 // CELL_AUTHORIZATION 1814 if (master.cpHost != null && hasAccessControlServiceCoprocessor(master.cpHost)) { 1815 if (AccessChecker.isAuthorizationSupported(master.getConfiguration())) { 1816 capabilities.add(SecurityCapabilitiesResponse.Capability.AUTHORIZATION); 1817 } 1818 if (AccessController.isCellAuthorizationSupported(master.getConfiguration())) { 1819 capabilities.add(SecurityCapabilitiesResponse.Capability.CELL_AUTHORIZATION); 1820 } 1821 } 1822 // A coprocessor that implements VisibilityLabelsService can provide CELL_VISIBILITY. 1823 if (master.cpHost != null && hasVisibilityLabelsServiceCoprocessor(master.cpHost)) { 1824 if (VisibilityController.isCellAuthorizationSupported(master.getConfiguration())) { 1825 capabilities.add(SecurityCapabilitiesResponse.Capability.CELL_VISIBILITY); 1826 } 1827 } 1828 response.addAllCapabilities(capabilities); 1829 } catch (IOException e) { 1830 throw new ServiceException(e); 1831 } 1832 return response.build(); 1833 } 1834 1835 /** 1836 * Determines if there is a MasterCoprocessor deployed which implements 1837 * {@link org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos.AccessControlService.Interface}. 1838 */ 1839 boolean hasAccessControlServiceCoprocessor(MasterCoprocessorHost cpHost) { 1840 return checkCoprocessorWithService( 1841 cpHost.findCoprocessors(MasterCoprocessor.class), AccessControlService.Interface.class); 1842 } 1843 1844 /** 1845 * Determines if there is a MasterCoprocessor deployed which implements 1846 * {@link org.apache.hadoop.hbase.protobuf.generated.VisibilityLabelsProtos.VisibilityLabelsService.Interface}. 1847 */ 1848 boolean hasVisibilityLabelsServiceCoprocessor(MasterCoprocessorHost cpHost) { 1849 return checkCoprocessorWithService( 1850 cpHost.findCoprocessors(MasterCoprocessor.class), 1851 VisibilityLabelsService.Interface.class); 1852 } 1853 1854 /** 1855 * Determines if there is a coprocessor implementation in the provided argument which extends 1856 * or implements the provided {@code service}. 1857 */ 1858 boolean checkCoprocessorWithService( 1859 List<MasterCoprocessor> coprocessorsToCheck, Class<?> service) { 1860 if (coprocessorsToCheck == null || coprocessorsToCheck.isEmpty()) { 1861 return false; 1862 } 1863 for (MasterCoprocessor cp : coprocessorsToCheck) { 1864 if (service.isAssignableFrom(cp.getClass())) { 1865 return true; 1866 } 1867 } 1868 return false; 1869 } 1870 1871 private MasterSwitchType convert(MasterProtos.MasterSwitchType switchType) { 1872 switch (switchType) { 1873 case SPLIT: 1874 return MasterSwitchType.SPLIT; 1875 case MERGE: 1876 return MasterSwitchType.MERGE; 1877 default: 1878 break; 1879 } 1880 return null; 1881 } 1882 1883 @Override 1884 public AddReplicationPeerResponse addReplicationPeer(RpcController controller, 1885 AddReplicationPeerRequest request) throws ServiceException { 1886 try { 1887 master.addReplicationPeer(request.getPeerId(), 1888 ReplicationPeerConfigUtil.convert(request.getPeerConfig()), request.getPeerState() 1889 .getState().equals(ReplicationState.State.ENABLED)); 1890 return AddReplicationPeerResponse.newBuilder().build(); 1891 } catch (ReplicationException | IOException e) { 1892 throw new ServiceException(e); 1893 } 1894 } 1895 1896 @Override 1897 public RemoveReplicationPeerResponse removeReplicationPeer(RpcController controller, 1898 RemoveReplicationPeerRequest request) throws ServiceException { 1899 try { 1900 master.removeReplicationPeer(request.getPeerId()); 1901 return RemoveReplicationPeerResponse.newBuilder().build(); 1902 } catch (ReplicationException | IOException e) { 1903 throw new ServiceException(e); 1904 } 1905 } 1906 1907 @Override 1908 public EnableReplicationPeerResponse enableReplicationPeer(RpcController controller, 1909 EnableReplicationPeerRequest request) throws ServiceException { 1910 try { 1911 master.enableReplicationPeer(request.getPeerId()); 1912 return EnableReplicationPeerResponse.newBuilder().build(); 1913 } catch (ReplicationException | IOException e) { 1914 throw new ServiceException(e); 1915 } 1916 } 1917 1918 @Override 1919 public DisableReplicationPeerResponse disableReplicationPeer(RpcController controller, 1920 DisableReplicationPeerRequest request) throws ServiceException { 1921 try { 1922 master.disableReplicationPeer(request.getPeerId()); 1923 return DisableReplicationPeerResponse.newBuilder().build(); 1924 } catch (ReplicationException | IOException e) { 1925 throw new ServiceException(e); 1926 } 1927 } 1928 1929 @Override 1930 public GetReplicationPeerConfigResponse getReplicationPeerConfig(RpcController controller, 1931 GetReplicationPeerConfigRequest request) throws ServiceException { 1932 GetReplicationPeerConfigResponse.Builder response = GetReplicationPeerConfigResponse 1933 .newBuilder(); 1934 try { 1935 String peerId = request.getPeerId(); 1936 ReplicationPeerConfig peerConfig = master.getReplicationPeerConfig(peerId); 1937 response.setPeerId(peerId); 1938 response.setPeerConfig(ReplicationPeerConfigUtil.convert(peerConfig)); 1939 } catch (ReplicationException | IOException e) { 1940 throw new ServiceException(e); 1941 } 1942 return response.build(); 1943 } 1944 1945 @Override 1946 public UpdateReplicationPeerConfigResponse updateReplicationPeerConfig(RpcController controller, 1947 UpdateReplicationPeerConfigRequest request) throws ServiceException { 1948 try { 1949 master.updateReplicationPeerConfig(request.getPeerId(), 1950 ReplicationPeerConfigUtil.convert(request.getPeerConfig())); 1951 return UpdateReplicationPeerConfigResponse.newBuilder().build(); 1952 } catch (ReplicationException | IOException e) { 1953 throw new ServiceException(e); 1954 } 1955 } 1956 1957 @Override 1958 public ListReplicationPeersResponse listReplicationPeers(RpcController controller, 1959 ListReplicationPeersRequest request) throws ServiceException { 1960 ListReplicationPeersResponse.Builder response = ListReplicationPeersResponse.newBuilder(); 1961 try { 1962 List<ReplicationPeerDescription> peers = master 1963 .listReplicationPeers(request.hasRegex() ? request.getRegex() : null); 1964 for (ReplicationPeerDescription peer : peers) { 1965 response.addPeerDesc(ReplicationPeerConfigUtil.toProtoReplicationPeerDescription(peer)); 1966 } 1967 } catch (ReplicationException | IOException e) { 1968 throw new ServiceException(e); 1969 } 1970 return response.build(); 1971 } 1972 1973 @Override 1974 public ListDecommissionedRegionServersResponse listDecommissionedRegionServers( 1975 RpcController controller, ListDecommissionedRegionServersRequest request) 1976 throws ServiceException { 1977 ListDecommissionedRegionServersResponse.Builder response = 1978 ListDecommissionedRegionServersResponse.newBuilder(); 1979 try { 1980 master.checkInitialized(); 1981 if (master.cpHost != null) { 1982 master.cpHost.preListDecommissionedRegionServers(); 1983 } 1984 List<ServerName> servers = master.listDecommissionedRegionServers(); 1985 response.addAllServerName((servers.stream().map(server -> ProtobufUtil.toServerName(server))) 1986 .collect(Collectors.toList())); 1987 if (master.cpHost != null) { 1988 master.cpHost.postListDecommissionedRegionServers(); 1989 } 1990 } catch (IOException io) { 1991 throw new ServiceException(io); 1992 } 1993 1994 return response.build(); 1995 } 1996 1997 @Override 1998 public DecommissionRegionServersResponse decommissionRegionServers(RpcController controller, 1999 DecommissionRegionServersRequest request) throws ServiceException { 2000 try { 2001 master.checkInitialized(); 2002 List<ServerName> servers = request.getServerNameList().stream() 2003 .map(pbServer -> ProtobufUtil.toServerName(pbServer)).collect(Collectors.toList()); 2004 boolean offload = request.getOffload(); 2005 if (master.cpHost != null) { 2006 master.cpHost.preDecommissionRegionServers(servers, offload); 2007 } 2008 master.decommissionRegionServers(servers, offload); 2009 if (master.cpHost != null) { 2010 master.cpHost.postDecommissionRegionServers(servers, offload); 2011 } 2012 } catch (IOException io) { 2013 throw new ServiceException(io); 2014 } 2015 2016 return DecommissionRegionServersResponse.newBuilder().build(); 2017 } 2018 2019 @Override 2020 public RecommissionRegionServerResponse recommissionRegionServer(RpcController controller, 2021 RecommissionRegionServerRequest request) throws ServiceException { 2022 try { 2023 master.checkInitialized(); 2024 ServerName server = ProtobufUtil.toServerName(request.getServerName()); 2025 List<byte[]> encodedRegionNames = request.getRegionList().stream() 2026 .map(regionSpecifier -> regionSpecifier.getValue().toByteArray()) 2027 .collect(Collectors.toList()); 2028 if (master.cpHost != null) { 2029 master.cpHost.preRecommissionRegionServer(server, encodedRegionNames); 2030 } 2031 master.recommissionRegionServer(server, encodedRegionNames); 2032 if (master.cpHost != null) { 2033 master.cpHost.postRecommissionRegionServer(server, encodedRegionNames); 2034 } 2035 } catch (IOException io) { 2036 throw new ServiceException(io); 2037 } 2038 2039 return RecommissionRegionServerResponse.newBuilder().build(); 2040 } 2041 2042 @Override 2043 public LockResponse requestLock(RpcController controller, final LockRequest request) 2044 throws ServiceException { 2045 try { 2046 if (request.getDescription().isEmpty()) { 2047 throw new IllegalArgumentException("Empty description"); 2048 } 2049 NonceProcedureRunnable npr; 2050 LockType type = LockType.valueOf(request.getLockType().name()); 2051 if (request.getRegionInfoCount() > 0) { 2052 final RegionInfo[] regionInfos = new RegionInfo[request.getRegionInfoCount()]; 2053 for (int i = 0; i < request.getRegionInfoCount(); ++i) { 2054 regionInfos[i] = ProtobufUtil.toRegionInfo(request.getRegionInfo(i)); 2055 } 2056 npr = new NonceProcedureRunnable(master, request.getNonceGroup(), request.getNonce()) { 2057 @Override 2058 protected void run() throws IOException { 2059 setProcId(master.getLockManager().remoteLocks().requestRegionsLock(regionInfos, 2060 request.getDescription(), getNonceKey())); 2061 } 2062 2063 @Override 2064 protected String getDescription() { 2065 return "RequestLock"; 2066 } 2067 }; 2068 } else if (request.hasTableName()) { 2069 final TableName tableName = ProtobufUtil.toTableName(request.getTableName()); 2070 npr = new NonceProcedureRunnable(master, request.getNonceGroup(), request.getNonce()) { 2071 @Override 2072 protected void run() throws IOException { 2073 setProcId(master.getLockManager().remoteLocks().requestTableLock(tableName, type, 2074 request.getDescription(), getNonceKey())); 2075 } 2076 2077 @Override 2078 protected String getDescription() { 2079 return "RequestLock"; 2080 } 2081 }; 2082 } else if (request.hasNamespace()) { 2083 npr = new NonceProcedureRunnable(master, request.getNonceGroup(), request.getNonce()) { 2084 @Override 2085 protected void run() throws IOException { 2086 setProcId(master.getLockManager().remoteLocks().requestNamespaceLock( 2087 request.getNamespace(), type, request.getDescription(), getNonceKey())); 2088 } 2089 2090 @Override 2091 protected String getDescription() { 2092 return "RequestLock"; 2093 } 2094 }; 2095 } else { 2096 throw new IllegalArgumentException("one of table/namespace/region should be specified"); 2097 } 2098 long procId = MasterProcedureUtil.submitProcedure(npr); 2099 return LockResponse.newBuilder().setProcId(procId).build(); 2100 } catch (IllegalArgumentException e) { 2101 LOG.warn("Exception when queuing lock", e); 2102 throw new ServiceException(new DoNotRetryIOException(e)); 2103 } catch (IOException e) { 2104 LOG.warn("Exception when queuing lock", e); 2105 throw new ServiceException(e); 2106 } 2107 } 2108 2109 /** 2110 * @return LOCKED, if procedure is found and it has the lock; else UNLOCKED. 2111 * @throws ServiceException if given proc id is found but it is not a LockProcedure. 2112 */ 2113 @Override 2114 public LockHeartbeatResponse lockHeartbeat(RpcController controller, LockHeartbeatRequest request) 2115 throws ServiceException { 2116 try { 2117 if (master.getLockManager().remoteLocks().lockHeartbeat(request.getProcId(), 2118 request.getKeepAlive())) { 2119 return LockHeartbeatResponse.newBuilder().setTimeoutMs( 2120 master.getConfiguration().getInt(LockProcedure.REMOTE_LOCKS_TIMEOUT_MS_CONF, 2121 LockProcedure.DEFAULT_REMOTE_LOCKS_TIMEOUT_MS)) 2122 .setLockStatus(LockHeartbeatResponse.LockStatus.LOCKED).build(); 2123 } else { 2124 return LockHeartbeatResponse.newBuilder() 2125 .setLockStatus(LockHeartbeatResponse.LockStatus.UNLOCKED).build(); 2126 } 2127 } catch (IOException e) { 2128 throw new ServiceException(e); 2129 } 2130 } 2131 2132 @Override 2133 public RegionSpaceUseReportResponse reportRegionSpaceUse(RpcController controller, 2134 RegionSpaceUseReportRequest request) throws ServiceException { 2135 try { 2136 master.checkInitialized(); 2137 if (!QuotaUtil.isQuotaEnabled(master.getConfiguration())) { 2138 return RegionSpaceUseReportResponse.newBuilder().build(); 2139 } 2140 MasterQuotaManager quotaManager = this.master.getMasterQuotaManager(); 2141 final long now = EnvironmentEdgeManager.currentTime(); 2142 for (RegionSpaceUse report : request.getSpaceUseList()) { 2143 quotaManager.addRegionSize(ProtobufUtil.toRegionInfo( 2144 report.getRegionInfo()), report.getRegionSize(), now); 2145 } 2146 return RegionSpaceUseReportResponse.newBuilder().build(); 2147 } catch (Exception e) { 2148 throw new ServiceException(e); 2149 } 2150 } 2151 2152 @Override 2153 public GetSpaceQuotaRegionSizesResponse getSpaceQuotaRegionSizes( 2154 RpcController controller, GetSpaceQuotaRegionSizesRequest request) throws ServiceException { 2155 try { 2156 master.checkInitialized(); 2157 MasterQuotaManager quotaManager = this.master.getMasterQuotaManager(); 2158 GetSpaceQuotaRegionSizesResponse.Builder builder = 2159 GetSpaceQuotaRegionSizesResponse.newBuilder(); 2160 if (quotaManager != null) { 2161 Map<RegionInfo,Long> regionSizes = quotaManager.snapshotRegionSizes(); 2162 Map<TableName,Long> regionSizesByTable = new HashMap<>(); 2163 // Translate hregioninfo+long -> tablename+long 2164 for (Entry<RegionInfo,Long> entry : regionSizes.entrySet()) { 2165 final TableName tableName = entry.getKey().getTable(); 2166 Long prevSize = regionSizesByTable.get(tableName); 2167 if (prevSize == null) { 2168 prevSize = 0L; 2169 } 2170 regionSizesByTable.put(tableName, prevSize + entry.getValue()); 2171 } 2172 // Serialize them into the protobuf 2173 for (Entry<TableName,Long> tableSize : regionSizesByTable.entrySet()) { 2174 builder.addSizes(RegionSizes.newBuilder() 2175 .setTableName(ProtobufUtil.toProtoTableName(tableSize.getKey())) 2176 .setSize(tableSize.getValue()).build()); 2177 } 2178 return builder.build(); 2179 } 2180 return builder.build(); 2181 } catch (Exception e) { 2182 throw new ServiceException(e); 2183 } 2184 } 2185 2186 @Override 2187 public GetQuotaStatesResponse getQuotaStates( 2188 RpcController controller, GetQuotaStatesRequest request) throws ServiceException { 2189 try { 2190 master.checkInitialized(); 2191 QuotaObserverChore quotaChore = this.master.getQuotaObserverChore(); 2192 GetQuotaStatesResponse.Builder builder = GetQuotaStatesResponse.newBuilder(); 2193 if (quotaChore != null) { 2194 // The "current" view of all tables with quotas 2195 Map<TableName, SpaceQuotaSnapshot> tableSnapshots = quotaChore.getTableQuotaSnapshots(); 2196 for (Entry<TableName, SpaceQuotaSnapshot> entry : tableSnapshots.entrySet()) { 2197 builder.addTableSnapshots( 2198 TableQuotaSnapshot.newBuilder() 2199 .setTableName(ProtobufUtil.toProtoTableName(entry.getKey())) 2200 .setSnapshot(SpaceQuotaSnapshot.toProtoSnapshot(entry.getValue())).build()); 2201 } 2202 // The "current" view of all namespaces with quotas 2203 Map<String, SpaceQuotaSnapshot> nsSnapshots = quotaChore.getNamespaceQuotaSnapshots(); 2204 for (Entry<String, SpaceQuotaSnapshot> entry : nsSnapshots.entrySet()) { 2205 builder.addNsSnapshots( 2206 NamespaceQuotaSnapshot.newBuilder() 2207 .setNamespace(entry.getKey()) 2208 .setSnapshot(SpaceQuotaSnapshot.toProtoSnapshot(entry.getValue())).build()); 2209 } 2210 return builder.build(); 2211 } 2212 return builder.build(); 2213 } catch (Exception e) { 2214 throw new ServiceException(e); 2215 } 2216 } 2217 2218 @Override 2219 public ClearDeadServersResponse clearDeadServers(RpcController controller, 2220 ClearDeadServersRequest request) throws ServiceException { 2221 LOG.debug(master.getClientIdAuditPrefix() + " clear dead region servers."); 2222 ClearDeadServersResponse.Builder response = ClearDeadServersResponse.newBuilder(); 2223 try { 2224 master.checkInitialized(); 2225 if (master.cpHost != null) { 2226 master.cpHost.preClearDeadServers(); 2227 } 2228 2229 if (master.getServerManager().areDeadServersInProgress()) { 2230 LOG.debug("Some dead server is still under processing, won't clear the dead server list"); 2231 response.addAllServerName(request.getServerNameList()); 2232 } else { 2233 for (HBaseProtos.ServerName pbServer : request.getServerNameList()) { 2234 if (!master.getServerManager().getDeadServers() 2235 .removeDeadServer(ProtobufUtil.toServerName(pbServer))) { 2236 response.addServerName(pbServer); 2237 } 2238 } 2239 } 2240 2241 if (master.cpHost != null) { 2242 master.cpHost.postClearDeadServers( 2243 ProtobufUtil.toServerNameList(request.getServerNameList()), 2244 ProtobufUtil.toServerNameList(response.getServerNameList())); 2245 } 2246 } catch (IOException io) { 2247 throw new ServiceException(io); 2248 } 2249 return response.build(); 2250 } 2251 2252 // HBCK Services 2253 2254 /** 2255 * Update state of the table in meta only. This is required by hbck in some situations to cleanup 2256 * stuck assign/ unassign regions procedures for the table. 2257 * 2258 * @return previous state of the table 2259 */ 2260 @Override 2261 public GetTableStateResponse setTableStateInMeta(RpcController controller, 2262 SetTableStateInMetaRequest request) throws ServiceException { 2263 Connection conn = master.getConnection(); 2264 TableName tn = ProtobufUtil.toTableName(request.getTableName()); 2265 2266 try { 2267 HBaseProtos.TableState prevState = MetaTableAccessor.getTableState(conn, tn).convert(); 2268 MetaTableAccessor.updateTableState(conn, tn, 2269 TableState.convert(tn, request.getTableState()).getState()); 2270 return GetTableStateResponse.newBuilder().setTableState(prevState).build(); 2271 } catch (Exception e) { 2272 throw new ServiceException(e); 2273 } 2274 } 2275 2276 /** 2277 * Get RegionInfo from Master using content of RegionSpecifier as key. 2278 * @return RegionInfo found by decoding <code>rs</code> or null if none found 2279 */ 2280 private RegionInfo getRegionInfo(HBaseProtos.RegionSpecifier rs) throws UnknownRegionException { 2281 RegionInfo ri = null; 2282 switch(rs.getType()) { 2283 case REGION_NAME: 2284 final byte[] regionName = rs.getValue().toByteArray(); 2285 ri = this.master.getAssignmentManager().getRegionInfo(regionName); 2286 break; 2287 case ENCODED_REGION_NAME: 2288 String encodedRegionName = Bytes.toString(rs.getValue().toByteArray()); 2289 RegionState regionState = this.master.getAssignmentManager().getRegionStates(). 2290 getRegionState(encodedRegionName); 2291 ri = regionState == null? null: regionState.getRegion(); 2292 break; 2293 default: 2294 break; 2295 } 2296 return ri; 2297 } 2298 2299 /** 2300 * Submit the Procedure that gets created by <code>f</code> 2301 * @return pid of the submitted Procedure. 2302 */ 2303 private long submitProcedure(HBaseProtos.RegionSpecifier rs, boolean override, 2304 BiFunction<RegionInfo, Boolean, Procedure> f) 2305 throws UnknownRegionException { 2306 RegionInfo ri = getRegionInfo(rs); 2307 long pid = Procedure.NO_PROC_ID; 2308 if (ri == null) { 2309 LOG.warn("No RegionInfo found to match {}", rs); 2310 } else { 2311 pid = this.master.getMasterProcedureExecutor().submitProcedure(f.apply(ri, override)); 2312 } 2313 return pid; 2314 } 2315 2316 /** 2317 * A 'raw' version of assign that does bulk and skirts Master state checks (assigns can be made 2318 * during Master startup). For use by Hbck2. 2319 */ 2320 @Override 2321 public MasterProtos.AssignsResponse assigns(RpcController controller, 2322 MasterProtos.AssignsRequest request) 2323 throws ServiceException { 2324 LOG.info(master.getClientIdAuditPrefix() + " assigns"); 2325 if (this.master.getMasterProcedureExecutor() == null) { 2326 throw new ServiceException("Master's ProcedureExecutor not initialized; retry later"); 2327 } 2328 MasterProtos.AssignsResponse.Builder responseBuilder = 2329 MasterProtos.AssignsResponse.newBuilder(); 2330 try { 2331 boolean override = request.getOverride(); 2332 for (HBaseProtos.RegionSpecifier rs: request.getRegionList()) { 2333 long pid = submitProcedure(rs, override, 2334 (r, b) -> this.master.getAssignmentManager().createAssignProcedure(r, b)); 2335 responseBuilder.addPid(pid); 2336 } 2337 return responseBuilder.build(); 2338 } catch (IOException ioe) { 2339 throw new ServiceException(ioe); 2340 } 2341 } 2342 2343 /** 2344 * A 'raw' version of unassign that does bulk and skirts Master state checks (unassigns can be 2345 * made during Master startup). For use by Hbck2. 2346 */ 2347 @Override 2348 public MasterProtos.UnassignsResponse unassigns(RpcController controller, 2349 MasterProtos.UnassignsRequest request) 2350 throws ServiceException { 2351 LOG.info(master.getClientIdAuditPrefix() + " unassigns"); 2352 if (this.master.getMasterProcedureExecutor() == null) { 2353 throw new ServiceException("Master's ProcedureExecutor not initialized; retry later"); 2354 } 2355 MasterProtos.UnassignsResponse.Builder responseBuilder = 2356 MasterProtos.UnassignsResponse.newBuilder(); 2357 try { 2358 boolean override = request.getOverride(); 2359 for (HBaseProtos.RegionSpecifier rs: request.getRegionList()) { 2360 long pid = submitProcedure(rs, override, 2361 (r, b) -> this.master.getAssignmentManager().createUnassignProcedure(r, b)); 2362 responseBuilder.addPid(pid); 2363 } 2364 return responseBuilder.build(); 2365 } catch (IOException ioe) { 2366 throw new ServiceException(ioe); 2367 } 2368 } 2369 2370 /** 2371 * Bypass specified procedure to completion. Procedure is marked completed but no actual work 2372 * is done from the current state/ step onwards. Parents of the procedure are also marked for 2373 * bypass. 2374 * 2375 * NOTE: this is a dangerous operation and may be used to unstuck buggy procedures. This may 2376 * leave system in inconherent state. This may need to be followed by some cleanup steps/ 2377 * actions by operator. 2378 * 2379 * @return BypassProcedureToCompletionResponse indicating success or failure 2380 */ 2381 @Override 2382 public MasterProtos.BypassProcedureResponse bypassProcedure(RpcController controller, 2383 MasterProtos.BypassProcedureRequest request) throws ServiceException { 2384 try { 2385 List<Boolean> ret = 2386 master.getMasterProcedureExecutor().bypassProcedure(request.getProcIdList(), 2387 request.getWaitTime(), request.getOverride(), request.getRecursive()); 2388 return MasterProtos.BypassProcedureResponse.newBuilder().addAllBypassed(ret).build(); 2389 } catch (IOException e) { 2390 throw new ServiceException(e); 2391 } 2392 } 2393 2394 @Override 2395 public MasterProtos.ScheduleServerCrashProcedureResponse scheduleServerCrashProcedure( 2396 RpcController controller, MasterProtos.ScheduleServerCrashProcedureRequest request) 2397 throws ServiceException { 2398 List<HBaseProtos.ServerName> serverNames = request.getServerNameList(); 2399 List<Long> pids = new ArrayList<>(); 2400 try { 2401 for (HBaseProtos.ServerName serverName : serverNames) { 2402 ServerName server = ProtobufUtil.toServerName(serverName); 2403 if (shouldSubmitSCP(server)) { 2404 ProcedureExecutor<MasterProcedureEnv> procExec = this.master.getMasterProcedureExecutor(); 2405 pids.add(procExec.submitProcedure(new ServerCrashProcedure(procExec.getEnvironment(), 2406 server, true, containMetaWals(server)))); 2407 } else { 2408 pids.add(-1L); 2409 } 2410 } 2411 return MasterProtos.ScheduleServerCrashProcedureResponse.newBuilder().addAllPid(pids).build(); 2412 } catch (IOException e) { 2413 throw new ServiceException(e); 2414 } 2415 } 2416 2417 private boolean containMetaWals(ServerName serverName) throws IOException { 2418 Path logDir = new Path(master.getWALRootDir(), 2419 AbstractFSWALProvider.getWALDirectoryName(serverName.toString())); 2420 Path splitDir = logDir.suffix(AbstractFSWALProvider.SPLITTING_EXT); 2421 Path checkDir = master.getFileSystem().exists(splitDir) ? splitDir : logDir; 2422 return master.getFileSystem().listStatus(checkDir, META_FILTER).length > 0; 2423 } 2424 2425 private boolean shouldSubmitSCP(ServerName serverName) { 2426 // check if there is already a SCP of this server running 2427 List<Procedure<MasterProcedureEnv>> procedures = 2428 master.getMasterProcedureExecutor().getProcedures(); 2429 for (Procedure<MasterProcedureEnv> procedure : procedures) { 2430 if (procedure instanceof ServerCrashProcedure) { 2431 if (serverName.compareTo(((ServerCrashProcedure) procedure).getServerName()) == 0 2432 && !procedure.isFinished()) { 2433 LOG.info("there is already a SCP of this server {} running, pid {}", serverName, 2434 procedure.getProcId()); 2435 return false; 2436 } 2437 } 2438 } 2439 return true; 2440 } 2441}