From b432c98b80786a33e017b2f65fe876f97f4e4fcb Mon Sep 17 00:00:00 2001 From: Neil Joshi Date: Mon, 26 Jul 2021 18:41:29 -0600 Subject: [PATCH 1/5] Commit new workflow def for repeated test of HDDS-5358. --- .github/workflows/single-test.yml | 42 +++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 .github/workflows/single-test.yml diff --git a/.github/workflows/single-test.yml b/.github/workflows/single-test.yml new file mode 100644 index 000000000000..846f84d31614 --- /dev/null +++ b/.github/workflows/single-test.yml @@ -0,0 +1,42 @@ +name: it-client +on: + schedule: + - cron: '*/1 * * * *' +env: + MAVEN_OPTS: -Dhttp.keepAlive=false -Dmaven.wagon.http.pool=false -Dmaven.wagon.http.retryHandler.class=standard -Dmaven.wagon.http.retryHandler.count=3 +jobs: + it-client: + name: it-client + runs-on: ubuntu-18.04 + steps: + - uses: actions/checkout@v2 + with: + ref: HDDS-5358 + - name: Cache for maven dependencies + uses: actions/cache@v2 + with: + path: ~/.m2/repository + key: maven-repo-${{ hashFiles('**/pom.xml') }}-8-single + restore-keys: | + maven-repo-${{ hashFiles('**/pom.xml') }}-8 + maven-repo-${{ hashFiles('**/pom.xml') }} + maven-repo- + - name: Execute tests + run: hadoop-ozone/dev-support/checks/integration.sh -Dtest=TestOzoneRpcClient + env: + ITERATIONS: 60 + - name: Summary of failures + run: cat target/integration/summary.txt + if: always() + - name: Archive build results + uses: actions/upload-artifact@v2 + if: always() + with: + name: it-client + path: target/integration + - name: Delete temporary build artifacts before caching + run: | + #Never cache local artifacts + rm -rf ~/.m2/repository/org/apache/ozone/hdds* + rm -rf ~/.m2/repository/org/apache/ozone/ozone* + if: always() \ No newline at end of file From 8eb2cba348ee9037196f76b540bae440670f6b68 Mon Sep 17 00:00:00 2001 From: neils-dev Date: Wed, 12 Apr 2023 22:59:03 -0600 Subject: [PATCH 2/5] ScmDecommissioning scm admin client command support. Includes removing scm from ratis ring, error handling. Includes client and server side unit tests. TODO - scm revocation for decommissioning.' --- .github/workflows/single-test.yml | 42 ------ .../hadoop/hdds/scm/client/ScmClient.java | 5 + .../StorageContainerLocationProtocol.java | 7 + ...ocationProtocolClientSideTranslatorPB.java | 18 +++ .../src/main/proto/ScmAdminProtocol.proto | 12 ++ ...ocationProtocolServerSideTranslatorPB.java | 16 +++ .../scm/server/SCMClientProtocolServer.java | 39 ++++++ .../server/TestSCMClientProtocolServer.java | 103 +++++++++++++++ .../scm/cli/ContainerOperationClient.java | 10 ++ .../hadoop/ozone/admin/scm/ScmAdmin.java | 3 +- .../admin/scm/ScmDecommissionSubcommand.java | 67 ++++++++++ .../scm/TestScmDecommissionSubcommand.java | 124 ++++++++++++++++++ 12 files changed, 403 insertions(+), 43 deletions(-) delete mode 100644 .github/workflows/single-test.yml create mode 100644 hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/server/TestSCMClientProtocolServer.java create mode 100644 hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/admin/scm/ScmDecommissionSubcommand.java create mode 100644 hadoop-ozone/tools/src/test/java/org/apache/hadoop/ozone/scm/TestScmDecommissionSubcommand.java diff --git a/.github/workflows/single-test.yml b/.github/workflows/single-test.yml deleted file mode 100644 index 846f84d31614..000000000000 --- a/.github/workflows/single-test.yml +++ /dev/null @@ -1,42 +0,0 @@ -name: it-client -on: - schedule: - - cron: '*/1 * * * *' -env: - MAVEN_OPTS: -Dhttp.keepAlive=false -Dmaven.wagon.http.pool=false -Dmaven.wagon.http.retryHandler.class=standard -Dmaven.wagon.http.retryHandler.count=3 -jobs: - it-client: - name: it-client - runs-on: ubuntu-18.04 - steps: - - uses: actions/checkout@v2 - with: - ref: HDDS-5358 - - name: Cache for maven dependencies - uses: actions/cache@v2 - with: - path: ~/.m2/repository - key: maven-repo-${{ hashFiles('**/pom.xml') }}-8-single - restore-keys: | - maven-repo-${{ hashFiles('**/pom.xml') }}-8 - maven-repo-${{ hashFiles('**/pom.xml') }} - maven-repo- - - name: Execute tests - run: hadoop-ozone/dev-support/checks/integration.sh -Dtest=TestOzoneRpcClient - env: - ITERATIONS: 60 - - name: Summary of failures - run: cat target/integration/summary.txt - if: always() - - name: Archive build results - uses: actions/upload-artifact@v2 - if: always() - with: - name: it-client - path: target/integration - - name: Delete temporary build artifacts before caching - run: | - #Never cache local artifacts - rm -rf ~/.m2/repository/org/apache/ozone/hdds* - rm -rf ~/.m2/repository/org/apache/ozone/ozone* - if: always() \ No newline at end of file diff --git a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/scm/client/ScmClient.java b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/scm/client/ScmClient.java index 916bd7fdfb03..15bbe8de5382 100644 --- a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/scm/client/ScmClient.java +++ b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/scm/client/ScmClient.java @@ -21,8 +21,10 @@ import org.apache.hadoop.hdds.annotation.InterfaceStability; import org.apache.hadoop.hdds.client.ReplicationConfig; import org.apache.hadoop.hdds.protocol.proto.HddsProtos.DeletedBlocksTransactionInfo; +import org.apache.hadoop.hdds.protocol.proto.StorageContainerLocationProtocolProtos.DecommissionScmResponseProto; import org.apache.hadoop.hdds.protocol.proto.StorageContainerLocationProtocolProtos.StartContainerBalancerResponseProto; import org.apache.hadoop.hdds.scm.DatanodeAdminError; +import org.apache.hadoop.hdds.scm.RemoveSCMRequest; import org.apache.hadoop.hdds.scm.container.ContainerReplicaInfo; import org.apache.hadoop.hdds.scm.container.ReplicationManagerReport; import org.apache.hadoop.hdds.scm.container.common.helpers.ContainerWithPipeline; @@ -420,4 +422,7 @@ StatusAndMessages finalizeScmUpgrade(String upgradeClientID) StatusAndMessages queryUpgradeFinalizationProgress( String upgradeClientID, boolean force, boolean readonly) throws IOException; + + DecommissionScmResponseProto decommissionScm( + RemoveSCMRequest removeScmRequest) throws IOException; } diff --git a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/scm/protocol/StorageContainerLocationProtocol.java b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/scm/protocol/StorageContainerLocationProtocol.java index 7690b2eefb32..c05155fd8d6a 100644 --- a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/scm/protocol/StorageContainerLocationProtocol.java +++ b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/scm/protocol/StorageContainerLocationProtocol.java @@ -21,9 +21,11 @@ import org.apache.hadoop.hdds.client.ReplicationConfig; import org.apache.hadoop.hdds.protocol.proto.HddsProtos; import org.apache.hadoop.hdds.protocol.proto.HddsProtos.DeletedBlocksTransactionInfo; +import org.apache.hadoop.hdds.protocol.proto.StorageContainerLocationProtocolProtos.DecommissionScmResponseProto; import org.apache.hadoop.hdds.protocol.proto.StorageContainerLocationProtocolProtos.StartContainerBalancerResponseProto; import org.apache.hadoop.hdds.protocol.proto.StorageContainerLocationProtocolProtos.Type; import org.apache.hadoop.hdds.scm.DatanodeAdminError; +import org.apache.hadoop.hdds.scm.RemoveSCMRequest; import org.apache.hadoop.hdds.scm.ScmConfig; import org.apache.hadoop.hdds.scm.ScmInfo; import org.apache.hadoop.hdds.scm.container.ContainerID; @@ -349,6 +351,7 @@ List getFailedDeletedBlockTxn(int count, Map> getSafeModeRuleStatuses() throws IOException; + /** * Force SCM out of Safe mode. * @@ -441,6 +444,7 @@ StatusAndMessages finalizeScmUpgrade(String upgradeClientID) StatusAndMessages queryUpgradeFinalizationProgress( String upgradeClientID, boolean force, boolean readonly) throws IOException; + /** * Obtain a token which can be used to let datanodes verify authentication of * commands operating on {@code containerID}. @@ -455,4 +459,7 @@ long getContainerCount(HddsProtos.LifeCycleState state) List getListOfContainers( long startContainerID, int count, HddsProtos.LifeCycleState state) throws IOException; + + DecommissionScmResponseProto decommissionScm( + RemoveSCMRequest removeScmRequest) throws IOException; } diff --git a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/scm/protocolPB/StorageContainerLocationProtocolClientSideTranslatorPB.java b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/scm/protocolPB/StorageContainerLocationProtocolClientSideTranslatorPB.java index c664a42ae661..31724fa7c88d 100644 --- a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/scm/protocolPB/StorageContainerLocationProtocolClientSideTranslatorPB.java +++ b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/scm/protocolPB/StorageContainerLocationProtocolClientSideTranslatorPB.java @@ -49,6 +49,8 @@ import org.apache.hadoop.hdds.protocol.proto.StorageContainerLocationProtocolProtos.DeactivatePipelineRequestProto; import org.apache.hadoop.hdds.protocol.proto.StorageContainerLocationProtocolProtos.DecommissionNodesRequestProto; import org.apache.hadoop.hdds.protocol.proto.StorageContainerLocationProtocolProtos.DecommissionNodesResponseProto; +import org.apache.hadoop.hdds.protocol.proto.StorageContainerLocationProtocolProtos.DecommissionScmRequestProto; +import org.apache.hadoop.hdds.protocol.proto.StorageContainerLocationProtocolProtos.DecommissionScmResponseProto; import org.apache.hadoop.hdds.protocol.proto.StorageContainerLocationProtocolProtos.ForceExitSafeModeRequestProto; import org.apache.hadoop.hdds.protocol.proto.StorageContainerLocationProtocolProtos.ForceExitSafeModeResponseProto; import org.apache.hadoop.hdds.protocol.proto.StorageContainerLocationProtocolProtos.GetContainerRequestProto; @@ -94,6 +96,7 @@ import org.apache.hadoop.hdds.protocol.proto.StorageContainerLocationProtocolProtos.ResetDeletedBlockRetryCountRequestProto; import org.apache.hadoop.hdds.protocol.proto.StorageContainerLocationProtocolProtos.Type; import org.apache.hadoop.hdds.scm.DatanodeAdminError; +import org.apache.hadoop.hdds.scm.RemoveSCMRequest; import org.apache.hadoop.hdds.scm.ScmInfo; import org.apache.hadoop.hdds.scm.container.ContainerID; import org.apache.hadoop.hdds.scm.container.ContainerInfo; @@ -1076,4 +1079,19 @@ public List getListOfContainers( throws IOException { return listContainer(startContainerID, count, state); } + + @Override + public DecommissionScmResponseProto decommissionScm( + RemoveSCMRequest removeScmRequest) throws IOException { + + DecommissionScmRequestProto request = DecommissionScmRequestProto + .newBuilder() + .setRemoveScmRequest(removeScmRequest.getProtobuf()) + .build(); + DecommissionScmResponseProto response = + submitRequest(Type.DecommissionScm, + builder -> builder.setDecommissionScmRequest(request)) + .getDecommissionScmResponse(); + return response; + } } diff --git a/hadoop-hdds/interface-admin/src/main/proto/ScmAdminProtocol.proto b/hadoop-hdds/interface-admin/src/main/proto/ScmAdminProtocol.proto index d5a3c6f65ac7..3e8549081727 100644 --- a/hadoop-hdds/interface-admin/src/main/proto/ScmAdminProtocol.proto +++ b/hadoop-hdds/interface-admin/src/main/proto/ScmAdminProtocol.proto @@ -80,6 +80,7 @@ message ScmContainerLocationRequest { optional ResetDeletedBlockRetryCountRequestProto resetDeletedBlockRetryCountRequest = 41; optional TransferLeadershipRequestProto transferScmLeadershipRequest = 42; optional GetFailedDeletedBlocksTxnRequestProto getFailedDeletedBlocksTxnRequest = 43; + optional DecommissionScmRequestProto decommissionScmRequest = 44; } message ScmContainerLocationResponse { @@ -131,6 +132,7 @@ message ScmContainerLocationResponse { optional ResetDeletedBlockRetryCountResponseProto resetDeletedBlockRetryCountResponse = 41; optional TransferLeadershipResponseProto transferScmLeadershipResponse = 42; optional GetFailedDeletedBlocksTxnResponseProto getFailedDeletedBlocksTxnResponse = 43; + optional DecommissionScmResponseProto decommissionScmResponse = 44; enum Status { OK = 1; @@ -181,6 +183,7 @@ enum Type { GetClosedContainerCount = 37; TransferLeadership = 38; GetFailedDeletedBlocksTransaction = 39; + DecommissionScm = 40; } /** @@ -573,6 +576,15 @@ message ContainerBalancerStatusResponseProto { required bool isRunning = 1; } +message DecommissionScmRequestProto { + required hadoop.hdds.RemoveScmRequestProto removeScmRequest = 1; +} + +message DecommissionScmResponseProto { + required hadoop.hdds.RemoveScmResponseProto removeScmResponse = 1; + required string removeScmError = 2; +} + /** * Protocol used from an HDFS node to StorageContainerManager. See the request * and response messages for details of the RPC calls. diff --git a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/protocol/StorageContainerLocationProtocolServerSideTranslatorPB.java b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/protocol/StorageContainerLocationProtocolServerSideTranslatorPB.java index 2dc3c5b04fa8..c4da5466e5e1 100644 --- a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/protocol/StorageContainerLocationProtocolServerSideTranslatorPB.java +++ b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/protocol/StorageContainerLocationProtocolServerSideTranslatorPB.java @@ -43,6 +43,8 @@ import org.apache.hadoop.hdds.protocol.proto.StorageContainerLocationProtocolProtos.DeactivatePipelineResponseProto; import org.apache.hadoop.hdds.protocol.proto.StorageContainerLocationProtocolProtos.DecommissionNodesRequestProto; import org.apache.hadoop.hdds.protocol.proto.StorageContainerLocationProtocolProtos.DecommissionNodesResponseProto; +import org.apache.hadoop.hdds.protocol.proto.StorageContainerLocationProtocolProtos.DecommissionScmRequestProto; +import org.apache.hadoop.hdds.protocol.proto.StorageContainerLocationProtocolProtos.DecommissionScmResponseProto; import org.apache.hadoop.hdds.protocol.proto.StorageContainerLocationProtocolProtos.FinalizeScmUpgradeRequestProto; import org.apache.hadoop.hdds.protocol.proto.StorageContainerLocationProtocolProtos.FinalizeScmUpgradeResponseProto; import org.apache.hadoop.hdds.protocol.proto.StorageContainerLocationProtocolProtos.ForceExitSafeModeRequestProto; @@ -103,6 +105,7 @@ import org.apache.hadoop.hdds.protocol.proto.StorageContainerLocationProtocolProtos.ResetDeletedBlockRetryCountRequestProto; import org.apache.hadoop.hdds.protocol.proto.StorageContainerLocationProtocolProtos.ResetDeletedBlockRetryCountResponseProto; import org.apache.hadoop.hdds.scm.DatanodeAdminError; +import org.apache.hadoop.hdds.scm.RemoveSCMRequest; import org.apache.hadoop.hdds.scm.ScmInfo; import org.apache.hadoop.hdds.scm.container.ContainerID; import org.apache.hadoop.hdds.scm.container.ContainerInfo; @@ -683,6 +686,13 @@ public ScmContainerLocationResponse processRequest( transferScmLeadership( request.getTransferScmLeadershipRequest())) .build(); + case DecommissionScm: + return ScmContainerLocationResponse.newBuilder() + .setCmdType(request.getCmdType()) + .setStatus(Status.OK) + .setDecommissionScmResponse(decommissionScm( + request.getDecommissionScmRequest())) + .build(); default: throw new IllegalArgumentException( "Unknown command type: " + request.getCmdType()); @@ -1210,4 +1220,10 @@ public TransferLeadershipResponseProto transferScmLeadership( impl.transferLeadership(newLeaderId); return TransferLeadershipResponseProto.getDefaultInstance(); } + + public DecommissionScmResponseProto decommissionScm( + DecommissionScmRequestProto request) throws IOException { + return impl.decommissionScm( + RemoveSCMRequest.getFromProtobuf(request.getRemoveScmRequest())); + } } diff --git a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/server/SCMClientProtocolServer.java b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/server/SCMClientProtocolServer.java index 6ee278b7a7eb..b6419cf39e52 100644 --- a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/server/SCMClientProtocolServer.java +++ b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/server/SCMClientProtocolServer.java @@ -38,12 +38,16 @@ import org.apache.hadoop.hdds.protocol.proto.HddsProtos; import org.apache.hadoop.hdds.protocol.proto.ReconfigureProtocolProtos.ReconfigureProtocolService; import org.apache.hadoop.hdds.protocol.proto.HddsProtos.DeletedBlocksTransactionInfo; +import org.apache.hadoop.hdds.protocol.proto.HddsProtos.RemoveScmResponseProto; +import org.apache.hadoop.hdds.protocol.proto.HddsProtos.RemoveScmResponseProto.Builder; import org.apache.hadoop.hdds.protocol.proto.StorageContainerLocationProtocolProtos; +import org.apache.hadoop.hdds.protocol.proto.StorageContainerLocationProtocolProtos.DecommissionScmResponseProto; import org.apache.hadoop.hdds.protocol.proto.StorageContainerLocationProtocolProtos.StartContainerBalancerResponseProto; import org.apache.hadoop.hdds.protocolPB.ReconfigureProtocolPB; import org.apache.hadoop.hdds.protocolPB.ReconfigureProtocolServerSideTranslatorPB; import org.apache.hadoop.hdds.ratis.RatisHelper; import org.apache.hadoop.hdds.scm.DatanodeAdminError; +import org.apache.hadoop.hdds.scm.RemoveSCMRequest; import org.apache.hadoop.hdds.scm.ScmInfo; import org.apache.hadoop.hdds.scm.container.ContainerID; import org.apache.hadoop.hdds.scm.container.ContainerInfo; @@ -1324,4 +1328,39 @@ public List listReconfigureProperties() throws IOException { public void close() throws IOException { stop(); } + + @Override + public DecommissionScmResponseProto decommissionScm( + RemoveSCMRequest removeScm) { + String removeScmError = ""; + Builder removeScmResponseBuilder = + RemoveScmResponseProto.newBuilder() + .setScmId(removeScm.getScmId()); + + RemoveSCMRequest removeScmRequest = removeScm; + + // set ratis address in server if not supplied by scm client + if (removeScm.getRatisAddr().equals("")) { + removeScmRequest = new RemoveSCMRequest( + removeScm.getClusterId(), + removeScm.getScmId(), + "localhost:" + scm.getScmHAManager().getRatisServer() + .getDivision().getRaftServer().getServerRpc() + .getInetSocketAddress().getPort()); + } + + try { + removeScmResponseBuilder + .setSuccess(scm.removePeerFromHARing(removeScmRequest)); + } catch (IOException ex) { + removeScmResponseBuilder + .setSuccess(false); + removeScmError = ex.getMessage(); + } + + return DecommissionScmResponseProto.newBuilder() + .setRemoveScmResponse(removeScmResponseBuilder.build()) + .setRemoveScmError(removeScmError) + .build(); + } } diff --git a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/server/TestSCMClientProtocolServer.java b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/server/TestSCMClientProtocolServer.java new file mode 100644 index 000000000000..f0fac01d7d6a --- /dev/null +++ b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/server/TestSCMClientProtocolServer.java @@ -0,0 +1,103 @@ +/** + * 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 + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * 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.hdds.scm.server; + +import org.apache.hadoop.hdds.HddsConfigKeys; +import org.apache.hadoop.hdds.conf.OzoneConfiguration; +import org.apache.hadoop.hdds.protocol.proto.HddsProtos.RemoveScmRequestProto; +import org.apache.hadoop.hdds.protocol.proto.StorageContainerLocationProtocolProtos.DecommissionScmResponseProto; +import org.apache.hadoop.hdds.protocol.proto.StorageContainerLocationProtocolProtos.DecommissionScmRequestProto; +import org.apache.hadoop.hdds.scm.HddsTestUtils; +import org.apache.hadoop.hdds.scm.ha.SCMContext; +import org.apache.hadoop.hdds.scm.ha.SCMHAManagerStub; +import org.apache.hadoop.hdds.scm.protocol.StorageContainerLocationProtocolServerSideTranslatorPB; +import org.apache.hadoop.hdds.utils.ProtocolMessageMetrics; +import org.apache.ozone.test.GenericTestUtils; + +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.mockito.Mockito; + +import java.io.File; +import java.util.UUID; + +/** + * Unit tests to validate the SCMClientProtocolServer + * servicing commands from the scm client. + */ +public class TestSCMClientProtocolServer { + private OzoneConfiguration config; + private SCMClientProtocolServer server; + private StorageContainerManager scm; + private StorageContainerLocationProtocolServerSideTranslatorPB service; + + @BeforeEach + public void setUp() throws Exception { + config = new OzoneConfiguration(); + File dir = GenericTestUtils.getRandomizedTestDir(); + config.set(HddsConfigKeys.OZONE_METADATA_DIRS, dir.toString()); + SCMConfigurator configurator = new SCMConfigurator(); + configurator.setSCMHAManager(SCMHAManagerStub.getInstance(true)); + configurator.setScmContext(SCMContext.emptyContext()); + scm = HddsTestUtils.getScm(config, configurator); + scm.start(); + scm.exitSafeMode(); + + server = scm.getClientProtocolServer(); + service = new StorageContainerLocationProtocolServerSideTranslatorPB(server, + scm, Mockito.mock(ProtocolMessageMetrics.class)); + } + + @AfterEach + public void tearDown() throws Exception { + if (scm != null) { + scm.stop(); + scm.join(); + } + } + + /** + * Tests decommissioning of scm. + */ + @Test + public void testScmDecommissionScmRemoveErrors() throws Exception { + String scmId = scm.getScmId(); + String clusterId = "CID-" + UUID.randomUUID(); + String err = "Cannot remove current leader."; + + RemoveScmRequestProto removeScmRequest = + RemoveScmRequestProto.newBuilder() + .setScmId(scmId) + .setClusterId(clusterId) + .setRatisAddr("localhost") // ratis addr not avail in utils scm + .build(); + + DecommissionScmRequestProto request = + DecommissionScmRequestProto.newBuilder() + .setRemoveScmRequest(removeScmRequest) + .build(); + + DecommissionScmResponseProto resp = + service.decommissionScm(request); + + assertTrue(resp.getRemoveScmError() + .equals(err)); + } +} diff --git a/hadoop-hdds/tools/src/main/java/org/apache/hadoop/hdds/scm/cli/ContainerOperationClient.java b/hadoop-hdds/tools/src/main/java/org/apache/hadoop/hdds/scm/cli/ContainerOperationClient.java index 22050f194009..05b885d059cc 100644 --- a/hadoop-hdds/tools/src/main/java/org/apache/hadoop/hdds/scm/cli/ContainerOperationClient.java +++ b/hadoop-hdds/tools/src/main/java/org/apache/hadoop/hdds/scm/cli/ContainerOperationClient.java @@ -27,8 +27,10 @@ import org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos.ReadContainerResponseProto; import org.apache.hadoop.hdds.protocol.proto.HddsProtos; import org.apache.hadoop.hdds.protocol.proto.HddsProtos.DeletedBlocksTransactionInfo; +import org.apache.hadoop.hdds.protocol.proto.StorageContainerLocationProtocolProtos.DecommissionScmResponseProto; import org.apache.hadoop.hdds.protocol.proto.StorageContainerLocationProtocolProtos.StartContainerBalancerResponseProto; import org.apache.hadoop.hdds.scm.DatanodeAdminError; +import org.apache.hadoop.hdds.scm.RemoveSCMRequest; import org.apache.hadoop.hdds.scm.ScmConfigKeys; import org.apache.hadoop.hdds.scm.XceiverClientManager; import org.apache.hadoop.hdds.scm.XceiverClientSpi; @@ -509,4 +511,12 @@ public StatusAndMessages queryUpgradeFinalizationProgress( return storageContainerLocationClient.queryUpgradeFinalizationProgress( upgradeClientID, force, readonly); } + + @Override + public DecommissionScmResponseProto decommissionScm( + RemoveSCMRequest removeScmRequest) + throws IOException { + return storageContainerLocationClient.decommissionScm(removeScmRequest); + } + } diff --git a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/admin/scm/ScmAdmin.java b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/admin/scm/ScmAdmin.java index a7f96dee84b3..8156660f0e6f 100644 --- a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/admin/scm/ScmAdmin.java +++ b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/admin/scm/ScmAdmin.java @@ -39,7 +39,8 @@ FinalizeScmUpgradeSubcommand.class, FinalizationScmStatusSubcommand.class, TransferScmLeaderSubCommand.class, - DeletedBlocksTxnCommands.class + DeletedBlocksTxnCommands.class, + ScmDecommissionSubcommand.class }) @MetaInfServices(SubcommandWithParent.class) public class ScmAdmin extends GenericCli implements SubcommandWithParent { diff --git a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/admin/scm/ScmDecommissionSubcommand.java b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/admin/scm/ScmDecommissionSubcommand.java new file mode 100644 index 000000000000..cee00ed57273 --- /dev/null +++ b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/admin/scm/ScmDecommissionSubcommand.java @@ -0,0 +1,67 @@ +/* + * 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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.admin.scm; + +import org.apache.hadoop.hdds.cli.HddsVersionProvider; +import org.apache.hadoop.hdds.protocol.proto.HddsProtos; +import org.apache.hadoop.hdds.scm.RemoveSCMRequest; +import org.apache.hadoop.hdds.protocol.proto.StorageContainerLocationProtocolProtos.DecommissionScmResponseProto; +import org.apache.hadoop.hdds.scm.cli.ScmSubcommand; +import org.apache.hadoop.hdds.scm.client.ScmClient; +import picocli.CommandLine; + +import java.io.IOException; + +/** + * Handler of ozone admin scm decommission command. + */ +@CommandLine.Command( + name = "decommissionScm", + description = "Decommission SCM . Includes removing from ratis " + + "ring and removing its certificate from certStore", + mixinStandardHelpOptions = true, + versionProvider = HddsVersionProvider.class) + + +public class ScmDecommissionSubcommand extends ScmSubcommand { + @CommandLine.ParentCommand + private ScmAdmin parent; + + @CommandLine.Parameters(description = "clusterId") + private String clusterId; + + @CommandLine.Parameters(description = "nodeId") + private String nodeId; + + @Override + public void execute(ScmClient scmClient) throws IOException { + DecommissionScmResponseProto response = scmClient + .decommissionScm(new RemoveSCMRequest(clusterId, nodeId, "")); + HddsProtos.RemoveScmResponseProto removeResponse = + response.getRemoveScmResponse(); + if (!removeResponse.getSuccess()) { + System.out.println("Error decommissioning Scm " + + removeResponse.getScmId()); + System.out.println(response.getRemoveScmError()); + } else { + System.out.println("Decommissioned Scm " + removeResponse.getScmId() + + " from cluster " + clusterId); + } + } +} + diff --git a/hadoop-ozone/tools/src/test/java/org/apache/hadoop/ozone/scm/TestScmDecommissionSubcommand.java b/hadoop-ozone/tools/src/test/java/org/apache/hadoop/ozone/scm/TestScmDecommissionSubcommand.java new file mode 100644 index 000000000000..944bae052983 --- /dev/null +++ b/hadoop-ozone/tools/src/test/java/org/apache/hadoop/ozone/scm/TestScmDecommissionSubcommand.java @@ -0,0 +1,124 @@ +/* + * 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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.scm; + +import org.apache.hadoop.hdds.cli.OzoneAdmin; +import org.apache.hadoop.hdds.protocol.proto.HddsProtos.RemoveScmResponseProto; +import org.apache.hadoop.hdds.protocol.proto.StorageContainerLocationProtocolProtos.DecommissionScmResponseProto; +import org.apache.hadoop.hdds.scm.client.ScmClient; +import org.apache.hadoop.ozone.admin.scm.ScmDecommissionSubcommand; +import org.apache.ozone.test.GenericTestUtils; + +import java.util.UUID; + +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import picocli.CommandLine; +import org.mockito.Mockito; + +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.mock; + +/** + * Unit tests to validate the TestScmDecommissionSubCommand class includes the + * correct output when executed against a mock client. + */ +public class TestScmDecommissionSubcommand { + + @Test + public void testScmDecommissionInputParams() throws Exception { + // requires String and String + ScmDecommissionSubcommand cmd = new ScmDecommissionSubcommand(); + ScmClient client = mock(ScmClient.class); + OzoneAdmin admin = new OzoneAdmin(); + + try (GenericTestUtils.SystemErrCapturer capture = + new GenericTestUtils.SystemErrCapturer()) { + String[] args = {"scm", "decommissionScm"}; + admin.execute(args); + assertTrue(capture.getOutput().contains( + "Usage: ozone admin scm decommissionScm")); + } + + // now give required String and String + CommandLine c1 = new CommandLine(cmd); + String scmId = UUID.randomUUID().toString(); + c1.parseArgs("CID-" + UUID.randomUUID().toString(), scmId); + RemoveScmResponseProto removeScmResponse = + RemoveScmResponseProto.newBuilder() + .setScmId(scmId) + .setSuccess(true) + .build(); + + DecommissionScmResponseProto response = + DecommissionScmResponseProto.newBuilder() + .setRemoveScmResponse(removeScmResponse) + .build(); + + Mockito.when(client.decommissionScm(any())) + .thenAnswer(invocation -> ( + response)); + + try (GenericTestUtils.SystemOutCapturer capture = + new GenericTestUtils.SystemOutCapturer()) { + cmd.execute(client); + assertTrue(capture.getOutput().contains( + "CID-")); + } + } + + @Test + public void testScmDecommissionScmRemoveErrors() throws Exception { + // requires String and String + ScmDecommissionSubcommand cmd = new ScmDecommissionSubcommand(); + ScmClient client = mock(ScmClient.class); + + CommandLine c1 = new CommandLine(cmd); + String scmId = UUID.randomUUID().toString(); + c1.parseArgs("CID-" + UUID.randomUUID().toString(), scmId); + RemoveScmResponseProto removeScmResponse = + RemoveScmResponseProto.newBuilder() + .setScmId(scmId) + .setSuccess(false) + .build(); + + DecommissionScmResponseProto response = + DecommissionScmResponseProto.newBuilder() + .setRemoveScmResponse(removeScmResponse) + .setRemoveScmError("Removal of primordial node is not supported") + .build(); + + Mockito.when(client.decommissionScm(any())) + .thenAnswer(invocation -> ( + response)); + + try (GenericTestUtils.SystemOutCapturer capture = + new GenericTestUtils.SystemOutCapturer()) { + cmd.execute(client); + assertTrue(capture.getOutput().contains( + "Removal of primordial")); + } + } + + // TO DO : test decommission revoke certificate + @Test + public void testScmDecommissionScmCertRevokeErrors() throws Exception { + } + +} From e54f95a0e9f3655e98e0e98a0e12f8e7483dc759 Mon Sep 17 00:00:00 2001 From: neils-dev Date: Fri, 14 Apr 2023 18:36:27 -0600 Subject: [PATCH 3/5] Minor changes for scm decommission cli. Renamed command to be consistent with existing decommissioning commands, ozone admin decommission, and minor changes to parameters to be consistent with decommissioning commands. --- ...nd.java => DecommissionScmSubcommand.java} | 12 ++++++--- .../hadoop/ozone/admin/scm/ScmAdmin.java | 2 +- ...ava => TestDecommissionScmSubcommand.java} | 25 +++++++++++-------- 3 files changed, 23 insertions(+), 16 deletions(-) rename hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/admin/scm/{ScmDecommissionSubcommand.java => DecommissionScmSubcommand.java} (85%) rename hadoop-ozone/tools/src/test/java/org/apache/hadoop/ozone/scm/{TestScmDecommissionSubcommand.java => TestDecommissionScmSubcommand.java} (83%) diff --git a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/admin/scm/ScmDecommissionSubcommand.java b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/admin/scm/DecommissionScmSubcommand.java similarity index 85% rename from hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/admin/scm/ScmDecommissionSubcommand.java rename to hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/admin/scm/DecommissionScmSubcommand.java index cee00ed57273..27ec7b10568c 100644 --- a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/admin/scm/ScmDecommissionSubcommand.java +++ b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/admin/scm/DecommissionScmSubcommand.java @@ -31,21 +31,25 @@ * Handler of ozone admin scm decommission command. */ @CommandLine.Command( - name = "decommissionScm", + name = "decommission", description = "Decommission SCM . Includes removing from ratis " + "ring and removing its certificate from certStore", mixinStandardHelpOptions = true, versionProvider = HddsVersionProvider.class) -public class ScmDecommissionSubcommand extends ScmSubcommand { +public class DecommissionScmSubcommand extends ScmSubcommand { @CommandLine.ParentCommand private ScmAdmin parent; - @CommandLine.Parameters(description = "clusterId") + @CommandLine.Option(names = {"-clusterid", "--clusterid"}, + description = "ClusterID of the SCM cluster to decommission node from.", + required = true) private String clusterId; - @CommandLine.Parameters(description = "nodeId") + @CommandLine.Option(names = {"-nodeid", "--nodeid"}, + description = "NodeID of the SCM to be decommissioned.", + required = true) private String nodeId; @Override diff --git a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/admin/scm/ScmAdmin.java b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/admin/scm/ScmAdmin.java index 8156660f0e6f..fbc5a3b52b00 100644 --- a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/admin/scm/ScmAdmin.java +++ b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/admin/scm/ScmAdmin.java @@ -40,7 +40,7 @@ FinalizationScmStatusSubcommand.class, TransferScmLeaderSubCommand.class, DeletedBlocksTxnCommands.class, - ScmDecommissionSubcommand.class + DecommissionScmSubcommand.class }) @MetaInfServices(SubcommandWithParent.class) public class ScmAdmin extends GenericCli implements SubcommandWithParent { diff --git a/hadoop-ozone/tools/src/test/java/org/apache/hadoop/ozone/scm/TestScmDecommissionSubcommand.java b/hadoop-ozone/tools/src/test/java/org/apache/hadoop/ozone/scm/TestDecommissionScmSubcommand.java similarity index 83% rename from hadoop-ozone/tools/src/test/java/org/apache/hadoop/ozone/scm/TestScmDecommissionSubcommand.java rename to hadoop-ozone/tools/src/test/java/org/apache/hadoop/ozone/scm/TestDecommissionScmSubcommand.java index 944bae052983..a2998054d0e8 100644 --- a/hadoop-ozone/tools/src/test/java/org/apache/hadoop/ozone/scm/TestScmDecommissionSubcommand.java +++ b/hadoop-ozone/tools/src/test/java/org/apache/hadoop/ozone/scm/TestDecommissionScmSubcommand.java @@ -21,7 +21,7 @@ import org.apache.hadoop.hdds.protocol.proto.HddsProtos.RemoveScmResponseProto; import org.apache.hadoop.hdds.protocol.proto.StorageContainerLocationProtocolProtos.DecommissionScmResponseProto; import org.apache.hadoop.hdds.scm.client.ScmClient; -import org.apache.hadoop.ozone.admin.scm.ScmDecommissionSubcommand; +import org.apache.hadoop.ozone.admin.scm.DecommissionScmSubcommand; import org.apache.ozone.test.GenericTestUtils; import java.util.UUID; @@ -39,27 +39,28 @@ * Unit tests to validate the TestScmDecommissionSubCommand class includes the * correct output when executed against a mock client. */ -public class TestScmDecommissionSubcommand { +public class TestDecommissionScmSubcommand { @Test - public void testScmDecommissionInputParams() throws Exception { + public void testDecommissionScmInputParams() throws Exception { // requires String and String - ScmDecommissionSubcommand cmd = new ScmDecommissionSubcommand(); + DecommissionScmSubcommand cmd = new DecommissionScmSubcommand(); ScmClient client = mock(ScmClient.class); OzoneAdmin admin = new OzoneAdmin(); try (GenericTestUtils.SystemErrCapturer capture = new GenericTestUtils.SystemErrCapturer()) { - String[] args = {"scm", "decommissionScm"}; + String[] args = {"scm", "decommission"}; admin.execute(args); assertTrue(capture.getOutput().contains( - "Usage: ozone admin scm decommissionScm")); + "Usage: ozone admin scm decommission")); } // now give required String and String CommandLine c1 = new CommandLine(cmd); String scmId = UUID.randomUUID().toString(); - c1.parseArgs("CID-" + UUID.randomUUID().toString(), scmId); + c1.parseArgs("--clusterid=CID-" + UUID.randomUUID(), + "--nodeid=" + scmId); RemoveScmResponseProto removeScmResponse = RemoveScmResponseProto.newBuilder() .setScmId(scmId) @@ -68,6 +69,7 @@ public void testScmDecommissionInputParams() throws Exception { DecommissionScmResponseProto response = DecommissionScmResponseProto.newBuilder() + .setRemoveScmError("") .setRemoveScmResponse(removeScmResponse) .build(); @@ -84,14 +86,15 @@ public void testScmDecommissionInputParams() throws Exception { } @Test - public void testScmDecommissionScmRemoveErrors() throws Exception { + public void testDecommissionScmScmRemoveErrors() throws Exception { // requires String and String - ScmDecommissionSubcommand cmd = new ScmDecommissionSubcommand(); + DecommissionScmSubcommand cmd = new DecommissionScmSubcommand(); ScmClient client = mock(ScmClient.class); CommandLine c1 = new CommandLine(cmd); String scmId = UUID.randomUUID().toString(); - c1.parseArgs("CID-" + UUID.randomUUID().toString(), scmId); + c1.parseArgs("--clusterid=CID-" + UUID.randomUUID(), + "--nodeid=" + scmId); RemoveScmResponseProto removeScmResponse = RemoveScmResponseProto.newBuilder() .setScmId(scmId) @@ -118,7 +121,7 @@ public void testScmDecommissionScmRemoveErrors() throws Exception { // TO DO : test decommission revoke certificate @Test - public void testScmDecommissionScmCertRevokeErrors() throws Exception { + public void testDecommissionScmCertRevokeErrors() throws Exception { } } From 7b7b0d6453a82b8a5bee31d6970a59a4257be802 Mon Sep 17 00:00:00 2001 From: neils-dev Date: Tue, 18 Apr 2023 18:55:38 -0600 Subject: [PATCH 4/5] Modifications made to scm decommission command client side to only require the scmid (nodeid) for decommissioning an SCM. Previously required ratisaddress and clusterid now will be handled on handling and validation of scm decommission command server side, opened HDDS-8452. --- .../hadoop/hdds/scm/client/ScmClient.java | 3 +- .../StorageContainerLocationProtocol.java | 3 +- ...ocationProtocolClientSideTranslatorPB.java | 5 +-- .../src/main/proto/ScmAdminProtocol.proto | 6 +-- ...ocationProtocolServerSideTranslatorPB.java | 3 +- .../scm/server/SCMClientProtocolServer.java | 40 ++++++------------- .../server/TestSCMClientProtocolServer.java | 18 +++------ .../scm/cli/ContainerOperationClient.java | 5 +-- .../dev-support/intellij/ozone-site.xml | 6 ++- .../admin/scm/DecommissionScmSubcommand.java | 24 ++++------- .../scm/TestDecommissionScmSubcommand.java | 31 +++++--------- 11 files changed, 48 insertions(+), 96 deletions(-) diff --git a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/scm/client/ScmClient.java b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/scm/client/ScmClient.java index 15bbe8de5382..1dffca6d573a 100644 --- a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/scm/client/ScmClient.java +++ b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/scm/client/ScmClient.java @@ -24,7 +24,6 @@ import org.apache.hadoop.hdds.protocol.proto.StorageContainerLocationProtocolProtos.DecommissionScmResponseProto; import org.apache.hadoop.hdds.protocol.proto.StorageContainerLocationProtocolProtos.StartContainerBalancerResponseProto; import org.apache.hadoop.hdds.scm.DatanodeAdminError; -import org.apache.hadoop.hdds.scm.RemoveSCMRequest; import org.apache.hadoop.hdds.scm.container.ContainerReplicaInfo; import org.apache.hadoop.hdds.scm.container.ReplicationManagerReport; import org.apache.hadoop.hdds.scm.container.common.helpers.ContainerWithPipeline; @@ -424,5 +423,5 @@ StatusAndMessages queryUpgradeFinalizationProgress( throws IOException; DecommissionScmResponseProto decommissionScm( - RemoveSCMRequest removeScmRequest) throws IOException; + String scmId) throws IOException; } diff --git a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/scm/protocol/StorageContainerLocationProtocol.java b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/scm/protocol/StorageContainerLocationProtocol.java index c05155fd8d6a..7cdb7bf7d576 100644 --- a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/scm/protocol/StorageContainerLocationProtocol.java +++ b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/scm/protocol/StorageContainerLocationProtocol.java @@ -25,7 +25,6 @@ import org.apache.hadoop.hdds.protocol.proto.StorageContainerLocationProtocolProtos.StartContainerBalancerResponseProto; import org.apache.hadoop.hdds.protocol.proto.StorageContainerLocationProtocolProtos.Type; import org.apache.hadoop.hdds.scm.DatanodeAdminError; -import org.apache.hadoop.hdds.scm.RemoveSCMRequest; import org.apache.hadoop.hdds.scm.ScmConfig; import org.apache.hadoop.hdds.scm.ScmInfo; import org.apache.hadoop.hdds.scm.container.ContainerID; @@ -461,5 +460,5 @@ List getListOfContainers( throws IOException; DecommissionScmResponseProto decommissionScm( - RemoveSCMRequest removeScmRequest) throws IOException; + String scmId) throws IOException; } diff --git a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/scm/protocolPB/StorageContainerLocationProtocolClientSideTranslatorPB.java b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/scm/protocolPB/StorageContainerLocationProtocolClientSideTranslatorPB.java index 31724fa7c88d..79ea96693315 100644 --- a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/scm/protocolPB/StorageContainerLocationProtocolClientSideTranslatorPB.java +++ b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/scm/protocolPB/StorageContainerLocationProtocolClientSideTranslatorPB.java @@ -96,7 +96,6 @@ import org.apache.hadoop.hdds.protocol.proto.StorageContainerLocationProtocolProtos.ResetDeletedBlockRetryCountRequestProto; import org.apache.hadoop.hdds.protocol.proto.StorageContainerLocationProtocolProtos.Type; import org.apache.hadoop.hdds.scm.DatanodeAdminError; -import org.apache.hadoop.hdds.scm.RemoveSCMRequest; import org.apache.hadoop.hdds.scm.ScmInfo; import org.apache.hadoop.hdds.scm.container.ContainerID; import org.apache.hadoop.hdds.scm.container.ContainerInfo; @@ -1082,11 +1081,11 @@ public List getListOfContainers( @Override public DecommissionScmResponseProto decommissionScm( - RemoveSCMRequest removeScmRequest) throws IOException { + String scmId) throws IOException { DecommissionScmRequestProto request = DecommissionScmRequestProto .newBuilder() - .setRemoveScmRequest(removeScmRequest.getProtobuf()) + .setScmId(scmId) .build(); DecommissionScmResponseProto response = submitRequest(Type.DecommissionScm, diff --git a/hadoop-hdds/interface-admin/src/main/proto/ScmAdminProtocol.proto b/hadoop-hdds/interface-admin/src/main/proto/ScmAdminProtocol.proto index 3e8549081727..b4ffd37a249a 100644 --- a/hadoop-hdds/interface-admin/src/main/proto/ScmAdminProtocol.proto +++ b/hadoop-hdds/interface-admin/src/main/proto/ScmAdminProtocol.proto @@ -577,12 +577,12 @@ message ContainerBalancerStatusResponseProto { } message DecommissionScmRequestProto { - required hadoop.hdds.RemoveScmRequestProto removeScmRequest = 1; + required string scmId = 1; } message DecommissionScmResponseProto { - required hadoop.hdds.RemoveScmResponseProto removeScmResponse = 1; - required string removeScmError = 2; + required bool success = 1; + optional string errorMsg = 2; } /** diff --git a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/protocol/StorageContainerLocationProtocolServerSideTranslatorPB.java b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/protocol/StorageContainerLocationProtocolServerSideTranslatorPB.java index c4da5466e5e1..6bbe250a4ec7 100644 --- a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/protocol/StorageContainerLocationProtocolServerSideTranslatorPB.java +++ b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/protocol/StorageContainerLocationProtocolServerSideTranslatorPB.java @@ -105,7 +105,6 @@ import org.apache.hadoop.hdds.protocol.proto.StorageContainerLocationProtocolProtos.ResetDeletedBlockRetryCountRequestProto; import org.apache.hadoop.hdds.protocol.proto.StorageContainerLocationProtocolProtos.ResetDeletedBlockRetryCountResponseProto; import org.apache.hadoop.hdds.scm.DatanodeAdminError; -import org.apache.hadoop.hdds.scm.RemoveSCMRequest; import org.apache.hadoop.hdds.scm.ScmInfo; import org.apache.hadoop.hdds.scm.container.ContainerID; import org.apache.hadoop.hdds.scm.container.ContainerInfo; @@ -1224,6 +1223,6 @@ public TransferLeadershipResponseProto transferScmLeadership( public DecommissionScmResponseProto decommissionScm( DecommissionScmRequestProto request) throws IOException { return impl.decommissionScm( - RemoveSCMRequest.getFromProtobuf(request.getRemoveScmRequest())); + request.getScmId()); } } diff --git a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/server/SCMClientProtocolServer.java b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/server/SCMClientProtocolServer.java index b6419cf39e52..92e2d220c677 100644 --- a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/server/SCMClientProtocolServer.java +++ b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/server/SCMClientProtocolServer.java @@ -38,10 +38,9 @@ import org.apache.hadoop.hdds.protocol.proto.HddsProtos; import org.apache.hadoop.hdds.protocol.proto.ReconfigureProtocolProtos.ReconfigureProtocolService; import org.apache.hadoop.hdds.protocol.proto.HddsProtos.DeletedBlocksTransactionInfo; -import org.apache.hadoop.hdds.protocol.proto.HddsProtos.RemoveScmResponseProto; -import org.apache.hadoop.hdds.protocol.proto.HddsProtos.RemoveScmResponseProto.Builder; import org.apache.hadoop.hdds.protocol.proto.StorageContainerLocationProtocolProtos; import org.apache.hadoop.hdds.protocol.proto.StorageContainerLocationProtocolProtos.DecommissionScmResponseProto; +import org.apache.hadoop.hdds.protocol.proto.StorageContainerLocationProtocolProtos.DecommissionScmResponseProto.Builder; import org.apache.hadoop.hdds.protocol.proto.StorageContainerLocationProtocolProtos.StartContainerBalancerResponseProto; import org.apache.hadoop.hdds.protocolPB.ReconfigureProtocolPB; import org.apache.hadoop.hdds.protocolPB.ReconfigureProtocolServerSideTranslatorPB; @@ -1331,36 +1330,21 @@ public void close() throws IOException { @Override public DecommissionScmResponseProto decommissionScm( - RemoveSCMRequest removeScm) { - String removeScmError = ""; - Builder removeScmResponseBuilder = - RemoveScmResponseProto.newBuilder() - .setScmId(removeScm.getScmId()); - - RemoveSCMRequest removeScmRequest = removeScm; - - // set ratis address in server if not supplied by scm client - if (removeScm.getRatisAddr().equals("")) { - removeScmRequest = new RemoveSCMRequest( - removeScm.getClusterId(), - removeScm.getScmId(), - "localhost:" + scm.getScmHAManager().getRatisServer() - .getDivision().getRaftServer().getServerRpc() - .getInetSocketAddress().getPort()); - } + String scmId) { + // TODO: update to use modified scm.removePeerFromHARing, HDDS-8452 + RemoveSCMRequest removeScmRequest = new RemoveSCMRequest( + scm.getClusterId(), scmId, ""); + Builder decommissionScmResponseBuilder = + DecommissionScmResponseProto.newBuilder(); try { - removeScmResponseBuilder + decommissionScmResponseBuilder .setSuccess(scm.removePeerFromHARing(removeScmRequest)); } catch (IOException ex) { - removeScmResponseBuilder - .setSuccess(false); - removeScmError = ex.getMessage(); + decommissionScmResponseBuilder + .setSuccess(false) + .setErrorMsg(ex.getMessage()); } - - return DecommissionScmResponseProto.newBuilder() - .setRemoveScmResponse(removeScmResponseBuilder.build()) - .setRemoveScmError(removeScmError) - .build(); + return decommissionScmResponseBuilder.build(); } } diff --git a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/server/TestSCMClientProtocolServer.java b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/server/TestSCMClientProtocolServer.java index f0fac01d7d6a..e6df13e924a8 100644 --- a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/server/TestSCMClientProtocolServer.java +++ b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/server/TestSCMClientProtocolServer.java @@ -19,7 +19,6 @@ import org.apache.hadoop.hdds.HddsConfigKeys; import org.apache.hadoop.hdds.conf.OzoneConfiguration; -import org.apache.hadoop.hdds.protocol.proto.HddsProtos.RemoveScmRequestProto; import org.apache.hadoop.hdds.protocol.proto.StorageContainerLocationProtocolProtos.DecommissionScmResponseProto; import org.apache.hadoop.hdds.protocol.proto.StorageContainerLocationProtocolProtos.DecommissionScmRequestProto; import org.apache.hadoop.hdds.scm.HddsTestUtils; @@ -36,7 +35,6 @@ import org.mockito.Mockito; import java.io.File; -import java.util.UUID; /** * Unit tests to validate the SCMClientProtocolServer @@ -77,27 +75,21 @@ public void tearDown() throws Exception { * Tests decommissioning of scm. */ @Test - public void testScmDecommissionScmRemoveErrors() throws Exception { + public void testScmDecommissionRemoveScmErrors() throws Exception { String scmId = scm.getScmId(); - String clusterId = "CID-" + UUID.randomUUID(); String err = "Cannot remove current leader."; - RemoveScmRequestProto removeScmRequest = - RemoveScmRequestProto.newBuilder() - .setScmId(scmId) - .setClusterId(clusterId) - .setRatisAddr("localhost") // ratis addr not avail in utils scm - .build(); - DecommissionScmRequestProto request = DecommissionScmRequestProto.newBuilder() - .setRemoveScmRequest(removeScmRequest) + .setScmId(scmId) .build(); DecommissionScmResponseProto resp = service.decommissionScm(request); - assertTrue(resp.getRemoveScmError() + // should have optional error message set in response + assertTrue(resp.hasErrorMsg()); + assertTrue(resp.getErrorMsg() .equals(err)); } } diff --git a/hadoop-hdds/tools/src/main/java/org/apache/hadoop/hdds/scm/cli/ContainerOperationClient.java b/hadoop-hdds/tools/src/main/java/org/apache/hadoop/hdds/scm/cli/ContainerOperationClient.java index 05b885d059cc..e8b657ecb192 100644 --- a/hadoop-hdds/tools/src/main/java/org/apache/hadoop/hdds/scm/cli/ContainerOperationClient.java +++ b/hadoop-hdds/tools/src/main/java/org/apache/hadoop/hdds/scm/cli/ContainerOperationClient.java @@ -30,7 +30,6 @@ import org.apache.hadoop.hdds.protocol.proto.StorageContainerLocationProtocolProtos.DecommissionScmResponseProto; import org.apache.hadoop.hdds.protocol.proto.StorageContainerLocationProtocolProtos.StartContainerBalancerResponseProto; import org.apache.hadoop.hdds.scm.DatanodeAdminError; -import org.apache.hadoop.hdds.scm.RemoveSCMRequest; import org.apache.hadoop.hdds.scm.ScmConfigKeys; import org.apache.hadoop.hdds.scm.XceiverClientManager; import org.apache.hadoop.hdds.scm.XceiverClientSpi; @@ -514,9 +513,9 @@ public StatusAndMessages queryUpgradeFinalizationProgress( @Override public DecommissionScmResponseProto decommissionScm( - RemoveSCMRequest removeScmRequest) + String scmId) throws IOException { - return storageContainerLocationClient.decommissionScm(removeScmRequest); + return storageContainerLocationClient.decommissionScm(scmId); } } diff --git a/hadoop-ozone/dev-support/intellij/ozone-site.xml b/hadoop-ozone/dev-support/intellij/ozone-site.xml index 4052c096104d..455509782e2f 100644 --- a/hadoop-ozone/dev-support/intellij/ozone-site.xml +++ b/hadoop-ozone/dev-support/intellij/ozone-site.xml @@ -15,6 +15,10 @@ limitations under the License. --> + + ozone.default.bucket.layout + LEGACY + hdds.profiler.endpoint.enabled true @@ -96,4 +100,4 @@ ozone.metastore.rocksdb.statistics ALL - \ No newline at end of file + diff --git a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/admin/scm/DecommissionScmSubcommand.java b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/admin/scm/DecommissionScmSubcommand.java index 27ec7b10568c..e1a77561d8ae 100644 --- a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/admin/scm/DecommissionScmSubcommand.java +++ b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/admin/scm/DecommissionScmSubcommand.java @@ -18,8 +18,6 @@ package org.apache.hadoop.ozone.admin.scm; import org.apache.hadoop.hdds.cli.HddsVersionProvider; -import org.apache.hadoop.hdds.protocol.proto.HddsProtos; -import org.apache.hadoop.hdds.scm.RemoveSCMRequest; import org.apache.hadoop.hdds.protocol.proto.StorageContainerLocationProtocolProtos.DecommissionScmResponseProto; import org.apache.hadoop.hdds.scm.cli.ScmSubcommand; import org.apache.hadoop.hdds.scm.client.ScmClient; @@ -42,11 +40,6 @@ public class DecommissionScmSubcommand extends ScmSubcommand { @CommandLine.ParentCommand private ScmAdmin parent; - @CommandLine.Option(names = {"-clusterid", "--clusterid"}, - description = "ClusterID of the SCM cluster to decommission node from.", - required = true) - private String clusterId; - @CommandLine.Option(names = {"-nodeid", "--nodeid"}, description = "NodeID of the SCM to be decommissioned.", required = true) @@ -54,17 +47,14 @@ public class DecommissionScmSubcommand extends ScmSubcommand { @Override public void execute(ScmClient scmClient) throws IOException { - DecommissionScmResponseProto response = scmClient - .decommissionScm(new RemoveSCMRequest(clusterId, nodeId, "")); - HddsProtos.RemoveScmResponseProto removeResponse = - response.getRemoveScmResponse(); - if (!removeResponse.getSuccess()) { - System.out.println("Error decommissioning Scm " - + removeResponse.getScmId()); - System.out.println(response.getRemoveScmError()); + DecommissionScmResponseProto response = scmClient.decommissionScm(nodeId); + if (!response.getSuccess()) { + System.out.println("Error decommissioning Scm " + nodeId); + if (response.hasErrorMsg()) { + System.out.println(response.getErrorMsg()); + } } else { - System.out.println("Decommissioned Scm " + removeResponse.getScmId() - + " from cluster " + clusterId); + System.out.println("Decommissioned Scm " + nodeId); } } } diff --git a/hadoop-ozone/tools/src/test/java/org/apache/hadoop/ozone/scm/TestDecommissionScmSubcommand.java b/hadoop-ozone/tools/src/test/java/org/apache/hadoop/ozone/scm/TestDecommissionScmSubcommand.java index a2998054d0e8..cea583eaf5d9 100644 --- a/hadoop-ozone/tools/src/test/java/org/apache/hadoop/ozone/scm/TestDecommissionScmSubcommand.java +++ b/hadoop-ozone/tools/src/test/java/org/apache/hadoop/ozone/scm/TestDecommissionScmSubcommand.java @@ -43,7 +43,7 @@ public class TestDecommissionScmSubcommand { @Test public void testDecommissionScmInputParams() throws Exception { - // requires String and String + // requires String DecommissionScmSubcommand cmd = new DecommissionScmSubcommand(); ScmClient client = mock(ScmClient.class); OzoneAdmin admin = new OzoneAdmin(); @@ -56,21 +56,14 @@ public void testDecommissionScmInputParams() throws Exception { "Usage: ozone admin scm decommission")); } - // now give required String and String + // now give required String CommandLine c1 = new CommandLine(cmd); String scmId = UUID.randomUUID().toString(); - c1.parseArgs("--clusterid=CID-" + UUID.randomUUID(), - "--nodeid=" + scmId); - RemoveScmResponseProto removeScmResponse = - RemoveScmResponseProto.newBuilder() - .setScmId(scmId) - .setSuccess(true) - .build(); + c1.parseArgs("--nodeid=" + scmId); DecommissionScmResponseProto response = DecommissionScmResponseProto.newBuilder() - .setRemoveScmError("") - .setRemoveScmResponse(removeScmResponse) + .setSuccess(true) .build(); Mockito.when(client.decommissionScm(any())) @@ -81,30 +74,24 @@ public void testDecommissionScmInputParams() throws Exception { new GenericTestUtils.SystemOutCapturer()) { cmd.execute(client); assertTrue(capture.getOutput().contains( - "CID-")); + scmId)); } } @Test public void testDecommissionScmScmRemoveErrors() throws Exception { - // requires String and String + // requires String DecommissionScmSubcommand cmd = new DecommissionScmSubcommand(); ScmClient client = mock(ScmClient.class); CommandLine c1 = new CommandLine(cmd); String scmId = UUID.randomUUID().toString(); - c1.parseArgs("--clusterid=CID-" + UUID.randomUUID(), - "--nodeid=" + scmId); - RemoveScmResponseProto removeScmResponse = - RemoveScmResponseProto.newBuilder() - .setScmId(scmId) - .setSuccess(false) - .build(); + c1.parseArgs("--nodeid=" + scmId); DecommissionScmResponseProto response = DecommissionScmResponseProto.newBuilder() - .setRemoveScmResponse(removeScmResponse) - .setRemoveScmError("Removal of primordial node is not supported") + .setSuccess(false) + .setErrorMsg("Removal of primordial node is not supported") .build(); Mockito.when(client.decommissionScm(any())) From e68e701cbf3045a0b483c03baf9188acb051e158 Mon Sep 17 00:00:00 2001 From: neils-dev Date: Tue, 25 Apr 2023 13:15:54 -0600 Subject: [PATCH 5/5] Merged to master to pick up needed changed for this PR from HDDS-8452 recently merged to master. --- .../hdds/scm/server/SCMClientProtocolServer.java | 6 +----- .../ozone/scm/TestDecommissionScmSubcommand.java | 10 ++-------- 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/server/SCMClientProtocolServer.java b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/server/SCMClientProtocolServer.java index 92e2d220c677..f62697fb7a5b 100644 --- a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/server/SCMClientProtocolServer.java +++ b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/server/SCMClientProtocolServer.java @@ -46,7 +46,6 @@ import org.apache.hadoop.hdds.protocolPB.ReconfigureProtocolServerSideTranslatorPB; import org.apache.hadoop.hdds.ratis.RatisHelper; import org.apache.hadoop.hdds.scm.DatanodeAdminError; -import org.apache.hadoop.hdds.scm.RemoveSCMRequest; import org.apache.hadoop.hdds.scm.ScmInfo; import org.apache.hadoop.hdds.scm.container.ContainerID; import org.apache.hadoop.hdds.scm.container.ContainerInfo; @@ -1331,15 +1330,12 @@ public void close() throws IOException { @Override public DecommissionScmResponseProto decommissionScm( String scmId) { - // TODO: update to use modified scm.removePeerFromHARing, HDDS-8452 - RemoveSCMRequest removeScmRequest = new RemoveSCMRequest( - scm.getClusterId(), scmId, ""); Builder decommissionScmResponseBuilder = DecommissionScmResponseProto.newBuilder(); try { decommissionScmResponseBuilder - .setSuccess(scm.removePeerFromHARing(removeScmRequest)); + .setSuccess(scm.removePeerFromHARing(scmId)); } catch (IOException ex) { decommissionScmResponseBuilder .setSuccess(false) diff --git a/hadoop-ozone/tools/src/test/java/org/apache/hadoop/ozone/scm/TestDecommissionScmSubcommand.java b/hadoop-ozone/tools/src/test/java/org/apache/hadoop/ozone/scm/TestDecommissionScmSubcommand.java index cea583eaf5d9..794a99e5271c 100644 --- a/hadoop-ozone/tools/src/test/java/org/apache/hadoop/ozone/scm/TestDecommissionScmSubcommand.java +++ b/hadoop-ozone/tools/src/test/java/org/apache/hadoop/ozone/scm/TestDecommissionScmSubcommand.java @@ -18,7 +18,6 @@ package org.apache.hadoop.ozone.scm; import org.apache.hadoop.hdds.cli.OzoneAdmin; -import org.apache.hadoop.hdds.protocol.proto.HddsProtos.RemoveScmResponseProto; import org.apache.hadoop.hdds.protocol.proto.StorageContainerLocationProtocolProtos.DecommissionScmResponseProto; import org.apache.hadoop.hdds.scm.client.ScmClient; import org.apache.hadoop.ozone.admin.scm.DecommissionScmSubcommand; @@ -28,12 +27,10 @@ import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertTrue; - -import picocli.CommandLine; import org.mockito.Mockito; - import static org.mockito.Mockito.any; import static org.mockito.Mockito.mock; +import picocli.CommandLine; /** * Unit tests to validate the TestScmDecommissionSubCommand class includes the @@ -106,9 +103,6 @@ public void testDecommissionScmScmRemoveErrors() throws Exception { } } - // TO DO : test decommission revoke certificate - @Test - public void testDecommissionScmCertRevokeErrors() throws Exception { - } + // TODO: test decommission revoke certificate }