This is an automated email from the ASF dual-hosted git repository. elek pushed a commit to branch HDDS-2240 in repository https://gitbox.apache.org/repos/asf/hadoop-ozone.git
commit 2b4b6a21e198a0ea2fff6c7b6202d8521bc81b48 Author: Hanisha Koneru <hanishakon...@apache.org> AuthorDate: Thu Oct 3 11:53:42 2019 -0700 HDDS-2240. Command line tool for OM HA. --- hadoop-ozone/common/src/main/bin/ozone | 5 ++ .../ozone/om/protocol/OzoneManagerHAProtocol.java | 3 + .../ozone/om/protocol/OzoneManagerProtocol.java | 2 +- .../om/protocol/OzoneManagerServerProtocol.java | 28 -------- ...OzoneManagerProtocolClientSideTranslatorPB.java | 33 ++++++++++ .../src/main/proto/OzoneManagerProtocol.proto | 23 +++++++ .../org/apache/hadoop/ozone/om/OzoneManager.java | 10 ++- .../org/apache/hadoop/ozone/om/OzoneManagerHA.java | 76 ++++++++++++++++++++++ .../ozone/om/ratis/OzoneManagerRatisServer.java | 2 +- ...OzoneManagerProtocolServerSideTranslatorPB.java | 67 +++++++++++++++++++ 10 files changed, 217 insertions(+), 32 deletions(-) diff --git a/hadoop-ozone/common/src/main/bin/ozone b/hadoop-ozone/common/src/main/bin/ozone index cd8f202..4ffd3e9 100755 --- a/hadoop-ozone/common/src/main/bin/ozone +++ b/hadoop-ozone/common/src/main/bin/ozone @@ -55,6 +55,7 @@ function hadoop_usage hadoop_add_subcommand "version" client "print the version" hadoop_add_subcommand "dtutil" client "operations related to delegation tokens" hadoop_add_subcommand "upgrade" client "HDFS to Ozone in-place upgrade tool" + hadoop_add_subcommand "omha" client "OM HA tool" hadoop_generate_usage "${HADOOP_SHELL_EXECNAME}" false } @@ -207,6 +208,10 @@ function ozonecmd_case HADOOP_CLASSNAME=org.apache.hadoop.ozone.upgrade.InPlaceUpgrade OZONE_RUN_ARTIFACT_NAME="hadoop-ozone-upgrade" ;; + omha) + HADOOP_CLASSNAME=org.apache.hadoop.ozone.om.OzoneManagerHA + OZONE_RUN_ARTIFACT_NAME="hadoop-ozone-ozone-manager" + ;; *) HADOOP_CLASSNAME="${subcmd}" if ! hadoop_validate_classname "${HADOOP_CLASSNAME}"; then diff --git a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocol/OzoneManagerHAProtocol.java b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocol/OzoneManagerHAProtocol.java index 1434dca..442c368 100644 --- a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocol/OzoneManagerHAProtocol.java +++ b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocol/OzoneManagerHAProtocol.java @@ -19,6 +19,7 @@ package org.apache.hadoop.ozone.om.protocol; import java.io.IOException; +import java.util.Map; /** * Protocol to talk to OM HA. These methods are needed only called from @@ -34,4 +35,6 @@ public interface OzoneManagerHAProtocol { */ long saveRatisSnapshot() throws IOException; + Map<String, String> getServiceStates(String omServiceId) throws IOException; + } diff --git a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocol/OzoneManagerProtocol.java b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocol/OzoneManagerProtocol.java index a236695..1381134 100644 --- a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocol/OzoneManagerProtocol.java +++ b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocol/OzoneManagerProtocol.java @@ -62,7 +62,7 @@ import org.apache.hadoop.hdds.utils.db.SequenceNumberNotFoundException; serverPrincipal = OMConfigKeys.OZONE_OM_KERBEROS_PRINCIPAL_KEY) @TokenInfo(OzoneDelegationTokenSelector.class) public interface OzoneManagerProtocol - extends OzoneManagerSecurityProtocol, Closeable { + extends OzoneManagerHAProtocol, OzoneManagerSecurityProtocol, Closeable { @SuppressWarnings("checkstyle:ConstantName") /** diff --git a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocol/OzoneManagerServerProtocol.java b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocol/OzoneManagerServerProtocol.java deleted file mode 100644 index 6f58e2d..0000000 --- a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocol/OzoneManagerServerProtocol.java +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * <p> - * http://www.apache.org/licenses/LICENSE-2.0 - * <p> - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.hadoop.ozone.om.protocol; - -/** - * This will be used in the OzoneManager Server, as few of the methods in - * OzoneManagerHAProtocol need not be exposed to Om clients. This interface - * extends both OzoneManagerHAProtocol and OzoneManagerProtocol. - */ -public interface OzoneManagerServerProtocol extends OzoneManagerProtocol, - OzoneManagerHAProtocol { -} diff --git a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocolPB/OzoneManagerProtocolClientSideTranslatorPB.java b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocolPB/OzoneManagerProtocolClientSideTranslatorPB.java index c9dc8ec..dc76107 100644 --- a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocolPB/OzoneManagerProtocolClientSideTranslatorPB.java +++ b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocolPB/OzoneManagerProtocolClientSideTranslatorPB.java @@ -21,7 +21,9 @@ import java.io.EOFException; import java.io.IOException; import java.time.Instant; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.stream.Collectors; import com.google.common.annotations.VisibleForTesting; @@ -109,6 +111,7 @@ import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.ListVol import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.ListVolumeResponse; import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.LookupKeyRequest; import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.LookupKeyResponse; +import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMServiceId; import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.MultipartCommitUploadPartRequest; import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.MultipartCommitUploadPartResponse; import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.MultipartInfoInitiateRequest; @@ -125,6 +128,7 @@ import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.RemoveA import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.RemoveAclResponse; import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.RenameKeyRequest; import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.RenewDelegationTokenResponseProto; +import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.RoleInfo; import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.S3BucketInfoRequest; import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.S3BucketInfoResponse; import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.S3CreateBucketRequest; @@ -133,6 +137,7 @@ import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.S3ListB import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.S3ListBucketsResponse; import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.ServiceListRequest; import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.ServiceListResponse; +import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.ServiceState; import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.SetAclRequest; import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.SetBucketPropertyRequest; import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.SetVolumePropertyRequest; @@ -1566,4 +1571,32 @@ public final class OzoneManagerProtocolClientSideTranslatorPB } return statusList; } + + @Override + public long saveRatisSnapshot() throws IOException { + throw new IOException("SaveRatisSnapshot operation not supported."); + } + + @Override + public Map<String, String> getServiceStates(String omServiceId) + throws IOException { + OMServiceId serviceIDproto = OMServiceId.newBuilder() + .setServiceID(omServiceId) + .build(); + + try { + ServiceState serviceState = rpcProxy.getServiceState( + NULL_RPC_CONTROLLER, serviceIDproto); + + Map<String, String> serviceStateMap = new HashMap<>(); + for (RoleInfo roleInfo : serviceState.getRoleInfosList()) { + serviceStateMap.put(roleInfo.getOmNodeID(), + roleInfo.getRatisServerRole()); + } + + return serviceStateMap; + } catch (ServiceException e) { + throw ProtobufHelper.getRemoteException(e); + } + } } diff --git a/hadoop-ozone/common/src/main/proto/OzoneManagerProtocol.proto b/hadoop-ozone/common/src/main/proto/OzoneManagerProtocol.proto index d82fdf2..4cfe58d 100644 --- a/hadoop-ozone/common/src/main/proto/OzoneManagerProtocol.proto +++ b/hadoop-ozone/common/src/main/proto/OzoneManagerProtocol.proto @@ -1097,6 +1097,25 @@ message UpdateGetS3SecretRequest { required string awsSecret = 2; } +message OMServiceId { + required string serviceID = 1; +} + +/** + This proto is used to define the OM node Id and its ratis server state. +*/ +message RoleInfo { + required string omNodeID = 1; + required string ratisServerRole = 2; +} + +/** + This is used to get the Server States of OMs. +*/ +message ServiceState { + repeated RoleInfo roleInfos = 1; +} + /** The OM service that takes care of Ozone namespace. */ @@ -1104,4 +1123,8 @@ service OzoneManagerService { // A client-to-OM RPC to send client requests to OM Ratis server rpc submitRequest(OMRequest) returns(OMResponse); + + // A client-to-OM RPC to get ratis server states of OMs + rpc getServiceState(OMServiceId) + returns(ServiceState); } diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java index a6503d7..dd3f98e 100644 --- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java +++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java @@ -79,7 +79,7 @@ import org.apache.hadoop.ozone.om.ha.OMHANodeDetails; import org.apache.hadoop.ozone.om.ha.OMNodeDetails; import org.apache.hadoop.ozone.om.helpers.OmMultipartUploadList; import org.apache.hadoop.ozone.om.helpers.S3SecretValue; -import org.apache.hadoop.ozone.om.protocol.OzoneManagerServerProtocol; +import org.apache.hadoop.ozone.om.protocol.OzoneManagerProtocol; import org.apache.hadoop.ozone.om.ratis.OMRatisSnapshotInfo; import org.apache.hadoop.ozone.om.snapshot.OzoneManagerSnapshotProvider; import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos; @@ -225,7 +225,7 @@ import static org.apache.hadoop.ozone.protocol.proto */ @InterfaceAudience.LimitedPrivate({"HDFS", "CBLOCK", "OZONE", "HBASE"}) public final class OzoneManager extends ServiceRuntimeInfoImpl - implements OzoneManagerServerProtocol, OMMXBean, Auditor { + implements OzoneManagerProtocol, OMMXBean, Auditor { public static final Logger LOG = LoggerFactory.getLogger(OzoneManager.class); @@ -1255,6 +1255,12 @@ public final class OzoneManager extends ServiceRuntimeInfoImpl return snapshotIndex; } + @Override + public Map<String, String> getServiceStates(String omServiceId) + throws IOException { + return null; + } + /** * Stop service. */ diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManagerHA.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManagerHA.java new file mode 100644 index 0000000..9f21c94 --- /dev/null +++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManagerHA.java @@ -0,0 +1,76 @@ +package org.apache.hadoop.ozone.om; + +import org.apache.hadoop.hdds.cli.GenericCli; +import org.apache.hadoop.hdds.cli.HddsVersionProvider; +import org.apache.hadoop.hdds.conf.OzoneConfiguration; +import org.apache.hadoop.hdds.tracing.TracingUtil; +import org.apache.hadoop.ozone.om.protocol.OzoneManagerProtocol; +import org.apache.hadoop.ozone.om.protocolPB.OzoneManagerProtocolClientSideTranslatorPB; +import org.apache.hadoop.security.UserGroupInformation; +import org.apache.hadoop.security.authentication.client.AuthenticationException; +import org.apache.ratis.protocol.ClientId; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import picocli.CommandLine; +import picocli.CommandLine.Command; + +import java.io.IOException; +import java.util.Map; + + +/** + * A command line tool for making calls in OM HA protocols. + */ +@Command(name = "ozone omha", + hidden = true, description = "Command line tool for OM HA.", + versionProvider = HddsVersionProvider.class, + mixinStandardHelpOptions = true) +public class OzoneManagerHA extends GenericCli { + private OzoneConfiguration conf; + private static final Logger LOG = + LoggerFactory.getLogger(OzoneManagerHA.class); + + public static void main(String[] args) throws Exception { + TracingUtil.initTracing("OzoneManager"); + new OzoneManagerHA().run(args); + } + + private OzoneManagerHA() { + super(); + } + + /** + * This function implements a sub-command to allow the OM to be + * initialized from the command line. + */ + @CommandLine.Command(name = "--getservicestate", + customSynopsis = "ozone om [global options] --getservicestate " + + "--serviceId=<OMServiceID>", + hidden = false, + description = "Get the Ratis server state of all OMs belonging to given" + + " OM Service ID", + mixinStandardHelpOptions = true, + versionProvider = HddsVersionProvider.class) + public void getRoleInfoOm(@CommandLine.Option(names = { "--serviceId" }, + description = "The OM Service ID of the OMs to get the server states for", + paramLabel = "id") String serviceId) + throws Exception { + conf = createOzoneConfiguration(); + Map<String, String> serviceStates = getServiceStates(conf, serviceId); + for (String nodeId : serviceStates.keySet()) { + System.out.println(nodeId + " : " + serviceStates.get(nodeId)); + } + } + + private Map<String, String> getServiceStates(OzoneConfiguration conf, + String serviceId) throws IOException, AuthenticationException { + + OzoneManagerProtocol omProxy = TracingUtil.createProxy( + new OzoneManagerProtocolClientSideTranslatorPB(conf, + ClientId.randomId().toString(), serviceId, + UserGroupInformation.getCurrentUser()), + OzoneManagerProtocol.class, conf); + + return omProxy.getServiceStates(serviceId); + } +} diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/ratis/OzoneManagerRatisServer.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/ratis/OzoneManagerRatisServer.java index 69a7ae9..4571f67 100644 --- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/ratis/OzoneManagerRatisServer.java +++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/ratis/OzoneManagerRatisServer.java @@ -615,7 +615,7 @@ public final class OzoneManagerRatisServer { } } - private GroupInfoReply getGroupInfo() throws IOException { + public GroupInfoReply getGroupInfo() throws IOException { GroupInfoRequest groupInfoRequest = new GroupInfoRequest(clientId, raftPeerId, raftGroupId, nextCallId()); GroupInfoReply groupInfo = server.getGroupInfo(groupInfoRequest); diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/protocolPB/OzoneManagerProtocolServerSideTranslatorPB.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/protocolPB/OzoneManagerProtocolServerSideTranslatorPB.java index d4c029b..57c1890 100644 --- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/protocolPB/OzoneManagerProtocolServerSideTranslatorPB.java +++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/protocolPB/OzoneManagerProtocolServerSideTranslatorPB.java @@ -31,9 +31,16 @@ import org.apache.hadoop.ozone.om.response.OMClientResponse; import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos; import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMRequest; import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMResponse; +import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMServiceId; +import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.RoleInfo; +import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.ServiceState; import com.google.protobuf.RpcController; import com.google.protobuf.ServiceException; +import org.apache.ratis.proto.RaftProtos.RaftPeerRole; +import org.apache.ratis.proto.RaftProtos.RoleInfoProto; +import org.apache.ratis.proto.RaftProtos.ServerRpcProto; +import org.apache.ratis.protocol.GroupInfoReply; import org.apache.ratis.protocol.RaftPeerId; import org.apache.ratis.util.ExitUtils; import org.slf4j.Logger; @@ -241,4 +248,64 @@ public class OzoneManagerProtocolServerSideTranslatorPB implements ozoneManagerDoubleBuffer.stop(); } } + + @Override + public ServiceState getServiceState(RpcController controller, + OMServiceId request) throws ServiceException { + + if (!omRatisServer.isLeader()) { + throw createNotLeaderException(); + } + try { + GroupInfoReply groupInfo = omRatisServer.getGroupInfo(); + if (groupInfo == null) { + throw createServiceException(ozoneManager.getOMNodeId() + + ": Failed to get GroupInfo."); + } else { + ServiceState.Builder serviceStateBuilder = ServiceState.newBuilder(); + RoleInfoProto roleInfoProto = + omRatisServer.getGroupInfo().getRoleInfoProto(); + String selfNodeId = new String( + roleInfoProto.getSelf().getId().toByteArray()); + String selfRole = roleInfoProto.getRole().name(); + RoleInfo selfRoleInfo = RoleInfo.newBuilder() + .setOmNodeID(selfNodeId) + .setRatisServerRole(selfRole) + .build(); + serviceStateBuilder.addRoleInfos(selfRoleInfo); + + if (roleInfoProto.hasLeaderInfo()) { + for (ServerRpcProto followerInfo : roleInfoProto.getLeaderInfo() + .getFollowerInfoList()) { + String id = new String(followerInfo.getId().getId().toByteArray()); + RoleInfo roleInfo = RoleInfo.newBuilder() + .setOmNodeID(id) + .setRatisServerRole(RaftPeerRole.FOLLOWER.name()) + .build(); + serviceStateBuilder.addRoleInfos(roleInfo); + } + } + if (roleInfoProto.hasFollowerInfo()) { + String leaderNodeId = new String( + roleInfoProto.getFollowerInfo().getLeaderInfo().getId().getId() + .toByteArray()); + RoleInfo leaderRoleInfo = RoleInfo.newBuilder() + .setOmNodeID(selfNodeId) + .setRatisServerRole(RaftPeerRole.FOLLOWER.name()) + .build(); + serviceStateBuilder.addRoleInfos(leaderRoleInfo); + } + return serviceStateBuilder.build(); + } + } catch (IOException e) { + throw new ServiceException(e); + } + } + + private ServiceException createServiceException(String errorMsg) { + if (LOG.isDebugEnabled()) { + LOG.debug(errorMsg); + } + return new ServiceException(errorMsg); + } } --------------------------------------------------------------------- To unsubscribe, e-mail: hdfs-commits-unsubscr...@hadoop.apache.org For additional commands, e-mail: hdfs-commits-h...@hadoop.apache.org