This is an automated email from the ASF dual-hosted git repository. avijayan pushed a commit to branch HDDS-3698-upgrade in repository https://gitbox.apache.org/repos/asf/hadoop-ozone.git
The following commit(s) were added to refs/heads/HDDS-3698-upgrade by this push: new c6f51ee3 HDDS-4252. Add the current layout versions to DN - SCM proto payload. (#1432) c6f51ee3 is described below commit c6f51ee3aa304ed42d4aee6f0606d2134ab09164 Author: prashantpogde <prashant.po...@gmail.com> AuthorDate: Mon Sep 28 11:28:22 2020 -0700 HDDS-4252. Add the current layout versions to DN - SCM proto payload. (#1432) --- .../hdds/upgrade/HDDSLayoutVersionManager.java | 21 +--- .../java/org/apache/hadoop/ozone/OzoneConsts.java | 2 + .../upgrade/AbstractLayoutVersionManager.java | 9 +- .../upgrade/TestAbstractLayoutVersionManager.java | 30 +++-- .../common/statemachine/DatanodeStateMachine.java | 19 +++- .../FinalizeNewLayoutVersionCommandHandler.java | 121 +++++++++++++++++++++ .../states/endpoint/HeartbeatEndpointTask.java | 65 ++++++++++- .../states/endpoint/RegisterEndpointTask.java | 57 +++++++++- .../upgrade/DataNodeLayoutVersionManager.java | 119 ++++++++++++++++++++ .../ozone/container/upgrade/package-info.java | 21 ++++ .../protocol/StorageContainerDatanodeProtocol.java | 12 +- .../commands/FinalizeNewLayoutVersionCommand.java | 73 +++++++++++++ ...inerDatanodeProtocolClientSideTranslatorPB.java | 9 +- ...inerDatanodeProtocolServerSideTranslatorPB.java | 7 +- .../hadoop/ozone/container/common/ScmTestMock.java | 12 +- .../states/endpoint/TestHeartbeatEndpointTask.java | 12 +- .../proto/ScmServerDatanodeHeartbeatProtocol.proto | 1 + .../hdds/scm/server/SCMDatanodeProtocolServer.java | 4 +- .../ozone/container/common/TestEndPoint.java | 22 +++- .../om/upgrade/OMLayoutVersionManagerImpl.java | 12 +- .../hadoop/ozone/recon/api/TestEndpoints.java | 12 +- 21 files changed, 579 insertions(+), 61 deletions(-) diff --git a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/upgrade/HDDSLayoutVersionManager.java b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/upgrade/HDDSLayoutVersionManager.java index 3ed28b2..8c3ff3d 100644 --- a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/upgrade/HDDSLayoutVersionManager.java +++ b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/upgrade/HDDSLayoutVersionManager.java @@ -32,7 +32,8 @@ import com.google.common.annotations.VisibleForTesting; * Class to manage layout versions and features for Storage Container Manager * and DataNodes. */ -public final class HDDSLayoutVersionManager extends +@SuppressWarnings("FinalClass") +public class HDDSLayoutVersionManager extends AbstractLayoutVersionManager { private static HDDSLayoutVersionManager hddsLayoutVersionManager; @@ -62,26 +63,12 @@ public final class HDDSLayoutVersionManager extends throws IOException { if (hddsLayoutVersionManager == null) { hddsLayoutVersionManager = new HDDSLayoutVersionManager(); - hddsLayoutVersionManager.init(hddsStorage); + hddsLayoutVersionManager.init(hddsStorage.getLayoutVersion(), + HDDSLayoutFeature.values()); } return hddsLayoutVersionManager; } - /** - * Initialize the HDDS Layout Features and current Layout Version. - * @param storage to read the current layout version. - * @throws IOException on error. - */ - private void init(Storage storage) throws IOException { - init(storage.getLayoutVersion(), HDDSLayoutFeature.values()); - if (metadataLayoutVersion > softwareLayoutVersion) { - throw new IOException( - String.format("Cannot initialize VersionManager. Metadata " + - "layout version (%d) > software layout version (%d)", - metadataLayoutVersion, softwareLayoutVersion)); - } - } - @VisibleForTesting protected synchronized static void resetLayoutVersionManager() { if (hddsLayoutVersionManager != null) { diff --git a/hadoop-hdds/common/src/main/java/org/apache/hadoop/ozone/OzoneConsts.java b/hadoop-hdds/common/src/main/java/org/apache/hadoop/ozone/OzoneConsts.java index 9854d40..0954bf0 100644 --- a/hadoop-hdds/common/src/main/java/org/apache/hadoop/ozone/OzoneConsts.java +++ b/hadoop-hdds/common/src/main/java/org/apache/hadoop/ozone/OzoneConsts.java @@ -38,6 +38,8 @@ public final class OzoneConsts { public static final String STORAGE_DIR = "scm"; public static final String SCM_ID = "scmUuid"; + public static final String DATANODE_STORAGE_CONFIG = "datanode.config"; + public static final String OZONE_SIMPLE_ROOT_USER = "root"; public static final String OZONE_SIMPLE_HDFS_USER = "hdfs"; diff --git a/hadoop-hdds/common/src/main/java/org/apache/hadoop/ozone/upgrade/AbstractLayoutVersionManager.java b/hadoop-hdds/common/src/main/java/org/apache/hadoop/ozone/upgrade/AbstractLayoutVersionManager.java index 99f72c8..158900b 100644 --- a/hadoop-hdds/common/src/main/java/org/apache/hadoop/ozone/upgrade/AbstractLayoutVersionManager.java +++ b/hadoop-hdds/common/src/main/java/org/apache/hadoop/ozone/upgrade/AbstractLayoutVersionManager.java @@ -18,6 +18,7 @@ package org.apache.hadoop.ozone.upgrade; +import java.io.IOException; import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; @@ -40,12 +41,18 @@ public abstract class AbstractLayoutVersionManager implements protected Map<String, LayoutFeature> featureMap = new HashMap<>(); protected volatile boolean isInitialized = false; - protected void init(int version, LayoutFeature[] lfs) { + protected void init(int version, LayoutFeature[] lfs) throws IOException { if (!isInitialized) { metadataLayoutVersion = version; initializeFeatures(lfs); softwareLayoutVersion = features.lastKey(); isInitialized = true; + if (metadataLayoutVersion > softwareLayoutVersion) { + throw new IOException( + String.format("Cannot initialize VersionManager. Metadata " + + "layout version (%d) > software layout version (%d)", + metadataLayoutVersion, softwareLayoutVersion)); + } } } diff --git a/hadoop-hdds/common/src/test/java/org/apache/hadoop/ozone/upgrade/TestAbstractLayoutVersionManager.java b/hadoop-hdds/common/src/test/java/org/apache/hadoop/ozone/upgrade/TestAbstractLayoutVersionManager.java index 44fa100..b7faf74 100644 --- a/hadoop-hdds/common/src/test/java/org/apache/hadoop/ozone/upgrade/TestAbstractLayoutVersionManager.java +++ b/hadoop-hdds/common/src/test/java/org/apache/hadoop/ozone/upgrade/TestAbstractLayoutVersionManager.java @@ -22,6 +22,8 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import java.io.IOException; + import org.junit.Before; import org.junit.Test; @@ -40,19 +42,29 @@ public class TestAbstractLayoutVersionManager { @Test public void testInit() { - versionManager.init(1, - getTestLayoutFeatures(2)); - assertEquals(2, versionManager.features.size()); - assertEquals(2, versionManager.featureMap.size()); - assertEquals(1, versionManager.getMetadataLayoutVersion()); - assertEquals(2, versionManager.getSoftwareLayoutVersion()); - assertTrue(versionManager.needsFinalization()); + try { + versionManager.init(1, + getTestLayoutFeatures(2)); + assertEquals(2, versionManager.features.size()); + assertEquals(2, versionManager.featureMap.size()); + assertEquals(1, versionManager.getMetadataLayoutVersion()); + assertEquals(2, versionManager.getSoftwareLayoutVersion()); + assertTrue(versionManager.needsFinalization()); + } catch (IOException e) { + // We don't expect it to throw IOException. + assertTrue(false); + } } @Test public void testNeedsFinalization() { - versionManager.init(2, getTestLayoutFeatures(2)); - assertFalse(versionManager.needsFinalization()); + try { + versionManager.init(2, getTestLayoutFeatures(2)); + assertFalse(versionManager.needsFinalization()); + } catch (IOException e) { + // We don't expect it to throw IOException. + assertTrue(false); + } } private LayoutFeature[] getTestLayoutFeatures(int num) { diff --git a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/statemachine/DatanodeStateMachine.java b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/statemachine/DatanodeStateMachine.java index 425074d..40c24f0 100644 --- a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/statemachine/DatanodeStateMachine.java +++ b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/statemachine/DatanodeStateMachine.java @@ -27,6 +27,7 @@ import java.util.concurrent.locks.ReentrantReadWriteLock; import org.apache.hadoop.hdds.HddsUtils; import org.apache.hadoop.hdds.conf.ConfigurationSource; +import org.apache.hadoop.hdds.conf.OzoneConfiguration; import org.apache.hadoop.hdds.protocol.DatanodeDetails; import org.apache.hadoop.hdds.protocol.proto.StorageContainerDatanodeProtocolProtos.CommandStatusReportsProto; import org.apache.hadoop.hdds.protocol.proto.StorageContainerDatanodeProtocolProtos.ContainerReportsProto; @@ -42,6 +43,7 @@ import org.apache.hadoop.ozone.container.common.statemachine.commandhandler.Comm import org.apache.hadoop.ozone.container.common.statemachine.commandhandler.CreatePipelineCommandHandler; import org.apache.hadoop.ozone.container.common.statemachine.commandhandler.DeleteBlocksCommandHandler; import org.apache.hadoop.ozone.container.common.statemachine.commandhandler.DeleteContainerCommandHandler; +import org.apache.hadoop.ozone.container.common.statemachine.commandhandler.FinalizeNewLayoutVersionCommandHandler; import org.apache.hadoop.ozone.container.common.statemachine.commandhandler.ReplicateContainerCommandHandler; import org.apache.hadoop.ozone.container.keyvalue.TarContainerPacker; import org.apache.hadoop.ozone.container.ozoneimpl.OzoneContainer; @@ -49,6 +51,7 @@ import org.apache.hadoop.ozone.container.replication.ContainerReplicator; import org.apache.hadoop.ozone.container.replication.DownloadAndImportReplicator; import org.apache.hadoop.ozone.container.replication.ReplicationSupervisor; import org.apache.hadoop.ozone.container.replication.SimpleContainerDownloader; +import org.apache.hadoop.ozone.container.upgrade.DataNodeLayoutVersionManager; import org.apache.hadoop.ozone.protocol.commands.SCMCommand; import org.apache.hadoop.util.JvmPauseMonitor; import org.apache.hadoop.util.Time; @@ -82,6 +85,9 @@ public class DatanodeStateMachine implements Closeable { private JvmPauseMonitor jvmPauseMonitor; private CertificateClient dnCertClient; private final HddsDatanodeStopService hddsDatanodeStopService; + + private DataNodeLayoutVersionManager dataNodeVersionManager; + /** * Used to synchronize to the OzoneContainer object created in the * constructor in a non-thread-safe way - see HDDS-3116. @@ -96,14 +102,17 @@ public class DatanodeStateMachine implements Closeable { * enabled */ public DatanodeStateMachine(DatanodeDetails datanodeDetails, - ConfigurationSource conf, CertificateClient certClient, - HddsDatanodeStopService hddsDatanodeStopService) throws IOException { + OzoneConfiguration conf, + CertificateClient certClient, + HddsDatanodeStopService hddsDatanodeStopService) + throws IOException { DatanodeConfiguration dnConf = conf.getObject(DatanodeConfiguration.class); this.hddsDatanodeStopService = hddsDatanodeStopService; this.conf = conf; this.datanodeDetails = datanodeDetails; + dataNodeVersionManager = DataNodeLayoutVersionManager.initialize(conf); executorService = Executors.newFixedThreadPool( getEndPointTaskThreadPoolSize(), new ThreadFactoryBuilder() @@ -145,6 +154,7 @@ public class DatanodeStateMachine implements Closeable { dnConf.getContainerDeleteThreads())) .addHandler(new ClosePipelineCommandHandler()) .addHandler(new CreatePipelineCommandHandler(conf)) + .addHandler(new FinalizeNewLayoutVersionCommandHandler()) .setConnectionManager(connectionManager) .setContainer(container) .setContext(context) @@ -545,4 +555,9 @@ public class DatanodeStateMachine implements Closeable { public ReplicationSupervisor getSupervisor() { return supervisor; } + + @VisibleForTesting + public DataNodeLayoutVersionManager getDataNodeVersionManager() { + return dataNodeVersionManager; + } } diff --git a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/statemachine/commandhandler/FinalizeNewLayoutVersionCommandHandler.java b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/statemachine/commandhandler/FinalizeNewLayoutVersionCommandHandler.java new file mode 100644 index 0000000..dc0fdfe --- /dev/null +++ b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/statemachine/commandhandler/FinalizeNewLayoutVersionCommandHandler.java @@ -0,0 +1,121 @@ +/** + * 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.container.common.statemachine.commandhandler; + +import org.apache.hadoop.hdds.protocol.DatanodeDetails; +import org.apache.hadoop.hdds.protocol.proto + .StorageContainerDatanodeProtocolProtos.SCMCommandProto; +import org.apache.hadoop.hdds.protocol.proto + .StorageContainerDatanodeProtocolProtos + .FinalizeNewLayoutVersionCommandProto; +import org.apache.hadoop.ozone.container.common.statemachine + .SCMConnectionManager; +import org.apache.hadoop.ozone.container.common.statemachine.StateContext; +import org.apache.hadoop.ozone.container.ozoneimpl.ContainerController; +import org.apache.hadoop.ozone.container.ozoneimpl.OzoneContainer; +import org.apache.hadoop.ozone.protocol.commands.FinalizeNewLayoutVersionCommand; +import org.apache.hadoop.ozone.protocol.commands.SCMCommand; +import org.apache.hadoop.util.Time; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.concurrent.atomic.AtomicLong; + +/** + * Handler for FinalizeNewLayoutVersion command received from SCM. + */ +public class FinalizeNewLayoutVersionCommandHandler implements CommandHandler { + + private static final Logger LOG = + LoggerFactory.getLogger(FinalizeNewLayoutVersionCommandHandler.class); + + private AtomicLong invocationCount = new AtomicLong(0); + private long totalTime; + + /** + * Constructs a FinalizeNewLayoutVersionCommandHandler. + */ + public FinalizeNewLayoutVersionCommandHandler() { + } + + /** + * Handles a given SCM command. + * + * @param command - SCM Command + * @param ozoneContainer - Ozone Container. + * @param context - Current Context. + * @param connectionManager - The SCMs that we are talking to. + */ + @Override + public void handle(SCMCommand command, OzoneContainer ozoneContainer, + StateContext context, SCMConnectionManager connectionManager) { + LOG.debug("Processing FinalizeNewLayoutVersionCommandHandler command."); + invocationCount.incrementAndGet(); + final long startTime = Time.monotonicNow(); + final DatanodeDetails datanodeDetails = context.getParent() + .getDatanodeDetails(); + final FinalizeNewLayoutVersionCommandProto finalizeCommand = + ((FinalizeNewLayoutVersionCommand)command).getProto(); + final ContainerController controller = ozoneContainer.getController(); + final boolean finalizeUpgrade = + finalizeCommand.getFinalizeNewLayoutVersion(); + try { + // TODO : finalization logic + if (LOG.isDebugEnabled()) { + LOG.debug("Finalize Upgrade called!"); + } + } catch (Exception e) { + LOG.debug("Unexpected Error: {} ", e); + } finally { + long endTime = Time.monotonicNow(); + totalTime += endTime - startTime; + } + } + + /** + * Returns the command type that this command handler handles. + * + * @return Type + */ + @Override + public SCMCommandProto.Type getCommandType() { + return SCMCommandProto.Type.finalizeNewLayoutVersionCommand; + } + + /** + * Returns number of times this handler has been invoked. + * + * @return int + */ + @Override + public int getInvocationCount() { + return (int)invocationCount.get(); + } + + /** + * Returns the average time this function takes to run. + * + * @return long + */ + @Override + public long getAverageRunTime() { + if (invocationCount.get() > 0) { + return totalTime / invocationCount.get(); + } + return 0; + } +} diff --git a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/states/endpoint/HeartbeatEndpointTask.java b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/states/endpoint/HeartbeatEndpointTask.java index da2034d..63ccff6 100644 --- a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/states/endpoint/HeartbeatEndpointTask.java +++ b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/states/endpoint/HeartbeatEndpointTask.java @@ -25,6 +25,8 @@ import org.apache.hadoop.hdds.conf.ConfigurationSource; import org.apache.hadoop.hdds.protocol.DatanodeDetails; import org.apache.hadoop.hdds.protocol.proto.HddsProtos.DatanodeDetailsProto; import org.apache.hadoop.hdds.protocol.proto + .StorageContainerDatanodeProtocolProtos.LayoutVersionProto; +import org.apache.hadoop.hdds.protocol.proto .StorageContainerDatanodeProtocolProtos.PipelineActionsProto; import org.apache.hadoop.hdds.protocol.proto .StorageContainerDatanodeProtocolProtos.PipelineAction; @@ -45,11 +47,13 @@ import org.apache.hadoop.ozone.container.common.statemachine import org.apache.hadoop.ozone.container.common.statemachine .EndpointStateMachine.EndPointStates; import org.apache.hadoop.ozone.container.common.statemachine.StateContext; +import org.apache.hadoop.ozone.container.upgrade.DataNodeLayoutVersionManager; import org.apache.hadoop.ozone.protocol.commands.CloseContainerCommand; import org.apache.hadoop.ozone.protocol.commands.ClosePipelineCommand; import org.apache.hadoop.ozone.protocol.commands.CreatePipelineCommand; import org.apache.hadoop.ozone.protocol.commands.DeleteBlocksCommand; import org.apache.hadoop.ozone.protocol.commands.DeleteContainerCommand; +import org.apache.hadoop.ozone.protocol.commands.FinalizeNewLayoutVersionCommand; import org.apache.hadoop.ozone.protocol.commands.ReplicateContainerCommand; import org.slf4j.Logger; @@ -83,14 +87,32 @@ public class HeartbeatEndpointTask private StateContext context; private int maxContainerActionsPerHB; private int maxPipelineActionsPerHB; + private DataNodeLayoutVersionManager layoutVersionManager; /** * Constructs a SCM heart beat. * + * @param rpcEndpoint rpc Endpoint * @param conf Config. + * @param context State context */ public HeartbeatEndpointTask(EndpointStateMachine rpcEndpoint, - ConfigurationSource conf, StateContext context) { + ConfigurationSource conf, StateContext context) { + this(rpcEndpoint, conf, context, + context.getParent().getDataNodeVersionManager()); + } + + /** + * Constructs a SCM heart beat. + * + * @param rpcEndpoint rpc Endpoint + * @param conf Config. + * @param context State context + * @param versionManager Layout version Manager + */ + public HeartbeatEndpointTask(EndpointStateMachine rpcEndpoint, + ConfigurationSource conf, StateContext context, + DataNodeLayoutVersionManager versionManager) { this.rpcEndpoint = rpcEndpoint; this.conf = conf; this.context = context; @@ -98,6 +120,12 @@ public class HeartbeatEndpointTask HDDS_CONTAINER_ACTION_MAX_LIMIT_DEFAULT); this.maxPipelineActionsPerHB = conf.getInt(HDDS_PIPELINE_ACTION_MAX_LIMIT, HDDS_PIPELINE_ACTION_MAX_LIMIT_DEFAULT); + if (versionManager != null) { + this.layoutVersionManager = versionManager; + } else { + this.layoutVersionManager = + context.getParent().getDataNodeVersionManager(); + } } /** @@ -132,8 +160,16 @@ public class HeartbeatEndpointTask try { Preconditions.checkState(this.datanodeDetailsProto != null); + LayoutVersionProto layoutinfo = LayoutVersionProto.newBuilder() + .setSoftwareLayoutVersion( + layoutVersionManager.getSoftwareLayoutVersion()) + .setMetadataLayoutVersion( + layoutVersionManager.getMetadataLayoutVersion()) + .build(); + requestBuilder = SCMHeartbeatRequestProto.newBuilder() - .setDatanodeDetails(datanodeDetailsProto); + .setDatanodeDetails(datanodeDetailsProto) + .setDataNodeLayoutVersion(layoutinfo); addReports(requestBuilder); addContainerActions(requestBuilder); addPipelineActions(requestBuilder); @@ -331,6 +367,16 @@ public class HeartbeatEndpointTask } this.context.addCommand(closePipelineCommand); break; + case finalizeNewLayoutVersionCommand: + FinalizeNewLayoutVersionCommand finalizeNewLayoutVersionCommand = + FinalizeNewLayoutVersionCommand.getFromProtobuf( + commandResponseProto.getFinalizeNewLayoutVersionCommandProto()); + if (LOG.isDebugEnabled()) { + LOG.debug("Received SCM finalize command {}", + finalizeNewLayoutVersionCommand.getId()); + } + this.context.addCommand(finalizeNewLayoutVersionCommand); + break; default: throw new IllegalArgumentException("Unknown response : " + commandResponseProto.getCommandType().name()); @@ -346,6 +392,7 @@ public class HeartbeatEndpointTask private ConfigurationSource conf; private DatanodeDetails datanodeDetails; private StateContext context; + private DataNodeLayoutVersionManager versionManager; /** * Constructs the builder class. @@ -365,6 +412,18 @@ public class HeartbeatEndpointTask } /** + * Sets the LayoutVersionManager. + * + * @param versionMgr - config + * @return Builder + */ + public Builder setLayoutVersionManager( + DataNodeLayoutVersionManager versionMgr) { + this.versionManager = versionMgr; + return this; + } + + /** * Sets the Config. * * @param config - config @@ -416,7 +475,7 @@ public class HeartbeatEndpointTask } HeartbeatEndpointTask task = new HeartbeatEndpointTask(this - .endPointStateMachine, this.conf, this.context); + .endPointStateMachine, this.conf, this.context, this.versionManager); task.setDatanodeDetailsProto(datanodeDetails.getProtoBufMessage()); return task; } diff --git a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/states/endpoint/RegisterEndpointTask.java b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/states/endpoint/RegisterEndpointTask.java index be95f01..6f8baa6 100644 --- a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/states/endpoint/RegisterEndpointTask.java +++ b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/states/endpoint/RegisterEndpointTask.java @@ -31,8 +31,11 @@ import org.apache.hadoop.hdds.protocol.proto .StorageContainerDatanodeProtocolProtos.ContainerReportsProto; import org.apache.hadoop.hdds.protocol.proto .StorageContainerDatanodeProtocolProtos.SCMRegisteredResponseProto; +import org.apache.hadoop.hdds.protocol.proto + .StorageContainerDatanodeProtocolProtos.LayoutVersionProto; import org.apache.hadoop.ozone.container.common.statemachine.StateContext; import org.apache.hadoop.ozone.container.ozoneimpl.OzoneContainer; +import org.apache.hadoop.ozone.container.upgrade.DataNodeLayoutVersionManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -54,6 +57,24 @@ public final class RegisterEndpointTask implements private DatanodeDetails datanodeDetails; private final OzoneContainer datanodeContainerManager; private StateContext stateContext; + private DataNodeLayoutVersionManager layoutVersionManager; + + /** + * Creates a register endpoint task. + * + * @param rpcEndPoint - endpoint + * @param conf - conf + * @param ozoneContainer - container + * @param context - State context + */ + @VisibleForTesting + public RegisterEndpointTask(EndpointStateMachine rpcEndPoint, + ConfigurationSource conf, + OzoneContainer ozoneContainer, + StateContext context) { + this(rpcEndPoint, conf, ozoneContainer, context, + context.getParent().getDataNodeVersionManager()); + } /** * Creates a register endpoint task. @@ -61,16 +82,23 @@ public final class RegisterEndpointTask implements * @param rpcEndPoint - endpoint * @param conf - conf * @param ozoneContainer - container + * @param context - State context + * @param versionManager - layout version Manager */ @VisibleForTesting public RegisterEndpointTask(EndpointStateMachine rpcEndPoint, ConfigurationSource conf, OzoneContainer ozoneContainer, - StateContext context) { + StateContext context, DataNodeLayoutVersionManager versionManager) { this.rpcEndPoint = rpcEndPoint; this.conf = conf; this.datanodeContainerManager = ozoneContainer; this.stateContext = context; - + if (versionManager != null) { + this.layoutVersionManager = versionManager; + } else { + this.layoutVersionManager = + context.getParent().getDataNodeVersionManager(); + } } /** @@ -112,6 +140,12 @@ public final class RegisterEndpointTask implements if (rpcEndPoint.getState() .equals(EndpointStateMachine.EndPointStates.REGISTER)) { + LayoutVersionProto layoutInfo = LayoutVersionProto.newBuilder() + .setMetadataLayoutVersion( + layoutVersionManager.getMetadataLayoutVersion()) + .setSoftwareLayoutVersion( + layoutVersionManager.getSoftwareLayoutVersion()) + .build(); ContainerReportsProto containerReport = datanodeContainerManager.getController().getContainerReport(); NodeReportProto nodeReport = datanodeContainerManager.getNodeReport(); @@ -120,7 +154,7 @@ public final class RegisterEndpointTask implements // TODO : Add responses to the command Queue. SCMRegisteredResponseProto response = rpcEndPoint.getEndPoint() .register(datanodeDetails.getProtoBufMessage(), nodeReport, - containerReport, pipelineReportsProto); + containerReport, pipelineReportsProto, layoutInfo); Preconditions.checkState(UUID.fromString(response.getDatanodeUUID()) .equals(datanodeDetails.getUuid()), "Unexpected datanode ID in the response."); @@ -167,6 +201,7 @@ public final class RegisterEndpointTask implements private DatanodeDetails datanodeDetails; private OzoneContainer container; private StateContext context; + private DataNodeLayoutVersionManager versionManager; /** * Constructs the builder class. @@ -197,6 +232,18 @@ public final class RegisterEndpointTask implements } /** + * Sets the LayoutVersionManager. + * + * @param versionMgr - config + * @return Builder. + */ + public Builder setLayoutVersionManager( + DataNodeLayoutVersionManager versionMgr) { + this.versionManager = versionMgr; + return this; + } + + /** * Sets the NodeID. * * @param dnDetails - NodeID proto @@ -255,10 +302,10 @@ public final class RegisterEndpointTask implements } RegisterEndpointTask task = new RegisterEndpointTask(this - .endPointStateMachine, this.conf, this.container, this.context); + .endPointStateMachine, this.conf, this.container, this.context, + this.versionManager); task.setDatanodeDetails(datanodeDetails); return task; } - } } diff --git a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/upgrade/DataNodeLayoutVersionManager.java b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/upgrade/DataNodeLayoutVersionManager.java new file mode 100644 index 0000000..c075938 --- /dev/null +++ b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/upgrade/DataNodeLayoutVersionManager.java @@ -0,0 +1,119 @@ +/** + * 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.container.upgrade; + + +import static org.apache.hadoop.ozone.container.common.volume.HddsVolume.HDDS_VOLUME_DIR; +import static org.apache.hadoop.ozone.container.common.volume.MutableVolumeSet.getDatanodeStorageDirs; + +import java.io.File; +import java.io.IOException; +import java.util.Collection; +import java.util.Properties; + +import org.apache.hadoop.hdds.conf.ConfigurationSource; +import org.apache.hadoop.hdds.upgrade.HDDSLayoutFeatureCatalog.HDDSLayoutFeature; +import org.apache.hadoop.hdfs.server.datanode.StorageLocation; +import org.apache.hadoop.ozone.container.common.helpers.DatanodeVersionFile; +import org.apache.hadoop.ozone.container.common.utils.HddsVolumeUtil; +import org.apache.hadoop.ozone.container.common.volume.HddsVolume; +import org.apache.hadoop.ozone.upgrade.AbstractLayoutVersionManager; +import org.apache.hadoop.ozone.upgrade.LayoutVersionManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.annotations.VisibleForTesting; + +/** + * Class to manage layout versions and features for Storage Container Manager + * and DataNodes. + */ +@SuppressWarnings("FinalClass") +public class DataNodeLayoutVersionManager extends + AbstractLayoutVersionManager { + private static final Logger LOG = LoggerFactory.getLogger( + DataNodeLayoutVersionManager.class); + private static DataNodeLayoutVersionManager dataNodeLayoutVersionManager; + + private DataNodeLayoutVersionManager() { + } + + /** + * Read only instance to DataNode Version Manager. + * @return version manager instance. + */ + public static synchronized LayoutVersionManager getInstance() { + if (dataNodeLayoutVersionManager == null) { + throw new RuntimeException("DataNode Layout Version Manager not yet " + + "initialized."); + } + return dataNodeLayoutVersionManager; + } + + /** + * Initialize DataNode version manager from version file stored on the + * DataNode. + * @param conf - Ozone Configuration + * @return version manager instance. + */ + public static synchronized DataNodeLayoutVersionManager initialize( + ConfigurationSource conf) + throws IOException { + if (dataNodeLayoutVersionManager == null) { + dataNodeLayoutVersionManager = new DataNodeLayoutVersionManager(); + int layoutVersion = 0; + Collection<String> rawLocations = getDatanodeStorageDirs(conf); + for (String locationString : rawLocations) { + StorageLocation location = StorageLocation.parse(locationString); + File hddsRootDir = new File(location.getUri().getPath(), + HDDS_VOLUME_DIR); + // Read the version from VersionFile Stored on the data node. + File versionFile = HddsVolumeUtil.getVersionFile(hddsRootDir); + if (!versionFile.exists()) { + // Volume Root is non empty but VERSION file does not exist. + LOG.warn("VERSION file does not exist in volume {}," + + " current volume state: {}.", + hddsRootDir.getPath(), HddsVolume.VolumeState.INCONSISTENT); + continue; + } else { + LOG.debug("Reading version file {} from disk.", versionFile); + } + Properties props = DatanodeVersionFile.readFrom(versionFile); + if (props.isEmpty()) { + continue; + } + int storedVersion = HddsVolumeUtil.getLayOutVersion(props, versionFile); + if (storedVersion > layoutVersion) { + layoutVersion = storedVersion; + } + } + dataNodeLayoutVersionManager.init(layoutVersion, + HDDSLayoutFeature.values()); + } + return dataNodeLayoutVersionManager; + } + + @VisibleForTesting + protected synchronized static void resetLayoutVersionManager() { + if (dataNodeLayoutVersionManager != null) { + dataNodeLayoutVersionManager.reset(); + dataNodeLayoutVersionManager = null; + } + } +} diff --git a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/upgrade/package-info.java b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/upgrade/package-info.java new file mode 100644 index 0000000..275e0db --- /dev/null +++ b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/upgrade/package-info.java @@ -0,0 +1,21 @@ +/** + * 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.container.upgrade; +/** + Contains upgrade related classes. + **/ diff --git a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/protocol/StorageContainerDatanodeProtocol.java b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/protocol/StorageContainerDatanodeProtocol.java index b62f712..22bb09f 100644 --- a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/protocol/StorageContainerDatanodeProtocol.java +++ b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/protocol/StorageContainerDatanodeProtocol.java @@ -21,6 +21,8 @@ import org.apache.hadoop.hdds.protocol.proto.HddsProtos.DatanodeDetailsProto; import org.apache.hadoop.hdds.protocol.proto .StorageContainerDatanodeProtocolProtos.PipelineReportsProto; import org.apache.hadoop.hdds.protocol.proto + .StorageContainerDatanodeProtocolProtos.LayoutVersionProto; +import org.apache.hadoop.hdds.protocol.proto .StorageContainerDatanodeProtocolProtos.SCMHeartbeatRequestProto; import org.apache.hadoop.hdds.protocol.proto .StorageContainerDatanodeProtocolProtos.ContainerReportsProto; @@ -76,12 +78,14 @@ public interface StorageContainerDatanodeProtocol { * @param datanodeDetails - Datanode Details. * @param nodeReport - Node Report. * @param containerReportsRequestProto - Container Reports. + * @param layoutInfo - Layout Version Information. * @return SCM Command. */ SCMRegisteredResponseProto register( - DatanodeDetailsProto datanodeDetails, - NodeReportProto nodeReport, - ContainerReportsProto containerReportsRequestProto, - PipelineReportsProto pipelineReports) throws IOException; + DatanodeDetailsProto datanodeDetails, + NodeReportProto nodeReport, + ContainerReportsProto containerReportsRequestProto, + PipelineReportsProto pipelineReports, + LayoutVersionProto layoutInfo) throws IOException; } diff --git a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/protocol/commands/FinalizeNewLayoutVersionCommand.java b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/protocol/commands/FinalizeNewLayoutVersionCommand.java new file mode 100644 index 0000000..e373f6e --- /dev/null +++ b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/protocol/commands/FinalizeNewLayoutVersionCommand.java @@ -0,0 +1,73 @@ +/** + * 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.protocol.commands; + +import com.google.common.base.Preconditions; + +import org.apache.hadoop.hdds.protocol.proto + .StorageContainerDatanodeProtocolProtos + .LayoutVersionProto; +import org.apache.hadoop.hdds.protocol.proto + .StorageContainerDatanodeProtocolProtos.SCMCommandProto; +import org.apache.hadoop.hdds.protocol.proto + .StorageContainerDatanodeProtocolProtos + .FinalizeNewLayoutVersionCommandProto; + +/** + * Asks DataNode to Finalize new upgrade version. + */ +public class FinalizeNewLayoutVersionCommand + extends SCMCommand<FinalizeNewLayoutVersionCommandProto> { + + private boolean finalizeUpgrade = false; + private LayoutVersionProto layoutInfo; + + public FinalizeNewLayoutVersionCommand(boolean finalizeNewLayoutVersion, + LayoutVersionProto layoutInfo, + long id) { + super(id); + finalizeUpgrade = finalizeNewLayoutVersion; + this.layoutInfo = layoutInfo; + } + + /** + * Returns the type of this command. + * + * @return Type + */ + @Override + public SCMCommandProto.Type getType() { + return SCMCommandProto.Type.finalizeNewLayoutVersionCommand; + } + + @Override + public FinalizeNewLayoutVersionCommandProto getProto() { + return FinalizeNewLayoutVersionCommandProto.newBuilder() + .setFinalizeNewLayoutVersion(finalizeUpgrade) + .setCmdId(getId()) + .setDataNodeLayoutVersion(layoutInfo) + .build(); + } + + public static FinalizeNewLayoutVersionCommand getFromProtobuf( + FinalizeNewLayoutVersionCommandProto finalizeProto) { + Preconditions.checkNotNull(finalizeProto); + return new FinalizeNewLayoutVersionCommand( + finalizeProto.getFinalizeNewLayoutVersion(), + finalizeProto.getDataNodeLayoutVersion(), finalizeProto.getCmdId()); + } +} diff --git a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/protocolPB/StorageContainerDatanodeProtocolClientSideTranslatorPB.java b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/protocolPB/StorageContainerDatanodeProtocolClientSideTranslatorPB.java index 9b44666..0eac359 100644 --- a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/protocolPB/StorageContainerDatanodeProtocolClientSideTranslatorPB.java +++ b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/protocolPB/StorageContainerDatanodeProtocolClientSideTranslatorPB.java @@ -20,6 +20,8 @@ import com.google.protobuf.RpcController; import com.google.protobuf.ServiceException; import org.apache.hadoop.hdds.protocol.proto.HddsProtos.DatanodeDetailsProto; import org.apache.hadoop.hdds.protocol.proto + .StorageContainerDatanodeProtocolProtos.LayoutVersionProto; +import org.apache.hadoop.hdds.protocol.proto .StorageContainerDatanodeProtocolProtos.PipelineReportsProto; import org.apache.hadoop.hdds.protocol.proto .StorageContainerDatanodeProtocolProtos.ContainerReportsProto; @@ -156,13 +158,15 @@ public class StorageContainerDatanodeProtocolClientSideTranslatorPB * @param datanodeDetailsProto - Datanode Details * @param nodeReport - Node Report. * @param containerReportsRequestProto - Container Reports. + * @param layoutInfo - Layout Version Information. * @return SCM Command. */ @Override public SCMRegisteredResponseProto register( DatanodeDetailsProto datanodeDetailsProto, NodeReportProto nodeReport, ContainerReportsProto containerReportsRequestProto, - PipelineReportsProto pipelineReportsProto) + PipelineReportsProto pipelineReportsProto, + LayoutVersionProto layoutInfo) throws IOException { SCMRegisterRequestProto.Builder req = SCMRegisterRequestProto.newBuilder(); @@ -170,6 +174,9 @@ public class StorageContainerDatanodeProtocolClientSideTranslatorPB req.setContainerReport(containerReportsRequestProto); req.setPipelineReports(pipelineReportsProto); req.setNodeReport(nodeReport); + if (layoutInfo != null) { + req.setDataNodeLayoutVersion(layoutInfo); + } return submitRequest(Type.Register, (builder) -> builder.setRegisterRequest(req)) .getRegisterResponse(); diff --git a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/protocolPB/StorageContainerDatanodeProtocolServerSideTranslatorPB.java b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/protocolPB/StorageContainerDatanodeProtocolServerSideTranslatorPB.java index e99cbae..c50e5e1 100644 --- a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/protocolPB/StorageContainerDatanodeProtocolServerSideTranslatorPB.java +++ b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/protocolPB/StorageContainerDatanodeProtocolServerSideTranslatorPB.java @@ -21,6 +21,7 @@ import java.io.IOException; import org.apache.hadoop.hdds.protocol.proto.StorageContainerDatanodeProtocolProtos.ContainerReportsProto; import org.apache.hadoop.hdds.protocol.proto.StorageContainerDatanodeProtocolProtos.NodeReportProto; import org.apache.hadoop.hdds.protocol.proto.StorageContainerDatanodeProtocolProtos.PipelineReportsProto; +import org.apache.hadoop.hdds.protocol.proto.StorageContainerDatanodeProtocolProtos.LayoutVersionProto; import org.apache.hadoop.hdds.protocol.proto.StorageContainerDatanodeProtocolProtos.SCMDatanodeRequest; import org.apache.hadoop.hdds.protocol.proto.StorageContainerDatanodeProtocolProtos.SCMDatanodeResponse; import org.apache.hadoop.hdds.protocol.proto.StorageContainerDatanodeProtocolProtos.SCMRegisterRequestProto; @@ -68,8 +69,12 @@ public class StorageContainerDatanodeProtocolServerSideTranslatorPB .getContainerReport(); NodeReportProto dnNodeReport = request.getNodeReport(); PipelineReportsProto pipelineReport = request.getPipelineReports(); + LayoutVersionProto layoutInfo = null; + if (request.hasDataNodeLayoutVersion()) { + layoutInfo = request.getDataNodeLayoutVersion(); + } return impl.register(request.getDatanodeDetails(), dnNodeReport, - containerRequestProto, pipelineReport); + containerRequestProto, pipelineReport, layoutInfo); } diff --git a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/ScmTestMock.java b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/ScmTestMock.java index c4b29ba..2af3cde 100644 --- a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/ScmTestMock.java +++ b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/ScmTestMock.java @@ -17,7 +17,10 @@ package org.apache.hadoop.ozone.container.common; import com.google.common.base.Preconditions; -import org.apache.hadoop.hdds.protocol.proto.StorageContainerDatanodeProtocolProtos; +import org.apache.hadoop.hdds.protocol.proto + .StorageContainerDatanodeProtocolProtos; +import org.apache.hadoop.hdds.protocol.proto + .StorageContainerDatanodeProtocolProtos.LayoutVersionProto; import org.apache.hadoop.hdds.protocol.proto .StorageContainerDatanodeProtocolProtos.ContainerReplicaProto; import org.apache.hadoop.hdds.protocol.proto @@ -217,9 +220,10 @@ public class ScmTestMock implements StorageContainerDatanodeProtocol { @Override public StorageContainerDatanodeProtocolProtos .SCMRegisteredResponseProto register( - DatanodeDetailsProto datanodeDetailsProto, NodeReportProto nodeReport, - ContainerReportsProto containerReportsRequestProto, - PipelineReportsProto pipelineReportsProto) + DatanodeDetailsProto datanodeDetailsProto, NodeReportProto nodeReport, + ContainerReportsProto containerReportsRequestProto, + PipelineReportsProto pipelineReportsProto, + LayoutVersionProto layoutInfo) throws IOException { rpcCount.incrementAndGet(); updateNodeReport(datanodeDetailsProto, nodeReport); diff --git a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/states/endpoint/TestHeartbeatEndpointTask.java b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/states/endpoint/TestHeartbeatEndpointTask.java index 9b238a1..29d5ce3 100644 --- a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/states/endpoint/TestHeartbeatEndpointTask.java +++ b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/states/endpoint/TestHeartbeatEndpointTask.java @@ -34,6 +34,7 @@ import org.apache.hadoop.ozone.container.common.statemachine.DatanodeStateMachin import org.apache.hadoop.ozone.container.common.statemachine.DatanodeStateMachine.DatanodeStates; import org.apache.hadoop.ozone.container.common.statemachine.EndpointStateMachine; import org.apache.hadoop.ozone.container.common.statemachine.StateContext; +import org.apache.hadoop.ozone.container.upgrade.DataNodeLayoutVersionManager; import org.apache.hadoop.ozone.protocolPB.StorageContainerDatanodeProtocolClientSideTranslatorPB; import org.junit.Assert; @@ -48,6 +49,8 @@ public class TestHeartbeatEndpointTask { private static final InetSocketAddress TEST_SCM_ENDPOINT = new InetSocketAddress("test-scm-1", 9861); + private static final int TEST_SOFTWARE_LAYOUT_VERSION = 0; + private static final int TEST_METADATA_LAYOUT_VERSION = 0; @Test public void testheartbeatWithoutReports() throws Exception { @@ -277,10 +280,17 @@ public class TestHeartbeatEndpointTask { Mockito.when(endpointStateMachine.getEndPoint()).thenReturn(proxy); Mockito.when(endpointStateMachine.getAddress()) .thenReturn(TEST_SCM_ENDPOINT); + DataNodeLayoutVersionManager layoutVersionManager = + Mockito.mock(DataNodeLayoutVersionManager.class); + Mockito.when(layoutVersionManager.getSoftwareLayoutVersion()) + .thenReturn(TEST_SOFTWARE_LAYOUT_VERSION); + Mockito.when(layoutVersionManager.getMetadataLayoutVersion()) + .thenReturn(TEST_METADATA_LAYOUT_VERSION); return HeartbeatEndpointTask.newBuilder() .setConfig(conf) .setDatanodeDetails(datanodeDetails) .setContext(context) + .setLayoutVersionManager(layoutVersionManager) .setEndpointStateMachine(endpointStateMachine) .build(); } @@ -292,4 +302,4 @@ public class TestHeartbeatEndpointTask { .setReason(ContainerAction.Reason.CONTAINER_FULL); return builder.build(); } -} \ No newline at end of file +} diff --git a/hadoop-hdds/interface-server/src/main/proto/ScmServerDatanodeHeartbeatProtocol.proto b/hadoop-hdds/interface-server/src/main/proto/ScmServerDatanodeHeartbeatProtocol.proto index 17ec667..b02ba20 100644 --- a/hadoop-hdds/interface-server/src/main/proto/ScmServerDatanodeHeartbeatProtocol.proto +++ b/hadoop-hdds/interface-server/src/main/proto/ScmServerDatanodeHeartbeatProtocol.proto @@ -410,6 +410,7 @@ message ClosePipelineCommandProto { message FinalizeNewLayoutVersionCommandProto { required bool finalizeNewLayoutVersion = 1 [default = false]; required LayoutVersionProto dataNodeLayoutVersion = 2; + required int64 cmdId = 3; } /** diff --git a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/server/SCMDatanodeProtocolServer.java b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/server/SCMDatanodeProtocolServer.java index ad7f65a..a1ee9e5 100644 --- a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/server/SCMDatanodeProtocolServer.java +++ b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/server/SCMDatanodeProtocolServer.java @@ -206,8 +206,10 @@ public class SCMDatanodeProtocolServer implements HddsProtos.DatanodeDetailsProto datanodeDetailsProto, NodeReportProto nodeReport, ContainerReportsProto containerReportsProto, - PipelineReportsProto pipelineReportsProto) + PipelineReportsProto pipelineReportsProto, + StorageContainerDatanodeProtocolProtos.LayoutVersionProto layoutInfo) throws IOException { + //TODO : DataNode-Upgrade: layoutinfo related processing. DatanodeDetails datanodeDetails = DatanodeDetails .getFromProtoBuf(datanodeDetailsProto); boolean auditSuccess = true; diff --git a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/ozone/container/common/TestEndPoint.java b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/ozone/container/common/TestEndPoint.java index 663ac8c..5eb7d6c 100644 --- a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/ozone/container/common/TestEndPoint.java +++ b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/ozone/container/common/TestEndPoint.java @@ -27,6 +27,8 @@ import org.apache.hadoop.hdds.HddsConfigKeys; import org.apache.hadoop.hdds.conf.OzoneConfiguration; import org.apache.hadoop.hdds.protocol.DatanodeDetails; import org.apache.hadoop.hdds.protocol.proto.HddsProtos; +import org.apache.hadoop.hdds.protocol.proto + .StorageContainerDatanodeProtocolProtos.LayoutVersionProto; import org.apache.hadoop.hdds.protocol.proto.StorageContainerDatanodeProtocolProtos.CloseContainerCommandProto; import org.apache.hadoop.hdds.protocol.proto.StorageContainerDatanodeProtocolProtos.CommandStatus.Status; import org.apache.hadoop.hdds.protocol.proto.StorageContainerDatanodeProtocolProtos.DeleteBlocksCommandProto; @@ -53,6 +55,7 @@ import org.apache.hadoop.ozone.container.common.states.endpoint.VersionEndpointT import org.apache.hadoop.ozone.container.common.volume.HddsVolume; import org.apache.hadoop.ozone.container.ozoneimpl.ContainerController; import org.apache.hadoop.ozone.container.ozoneimpl.OzoneContainer; +import org.apache.hadoop.ozone.container.upgrade.DataNodeLayoutVersionManager; import org.apache.hadoop.ozone.protocol.commands.CommandStatus; import org.apache.hadoop.test.GenericTestUtils; import org.apache.hadoop.test.PathUtils; @@ -83,6 +86,8 @@ public class TestEndPoint { private static ScmTestMock scmServerImpl; private static File testDir; private static OzoneConfiguration config; + private static final int TEST_SOFTWARE_LAYOUT_VERSION = 0; + private static final int TEST_METADATA_LAYOUT_VERSION = 0; @AfterClass public static void tearDown() throws Exception { @@ -266,6 +271,10 @@ public class TestEndPoint { @Test public void testRegister() throws Exception { DatanodeDetails nodeToRegister = randomDatanodeDetails(); + LayoutVersionProto layoutInfo = LayoutVersionProto.newBuilder() + .setMetadataLayoutVersion(TEST_METADATA_LAYOUT_VERSION) + .setSoftwareLayoutVersion(TEST_SOFTWARE_LAYOUT_VERSION) + .build(); try (EndpointStateMachine rpcEndPoint = createEndpoint( SCMTestUtils.getConf(), serverAddress, 1000)) { SCMRegisteredResponseProto responseProto = rpcEndPoint.getEndPoint() @@ -273,7 +282,7 @@ public class TestEndPoint { .createNodeReport( getStorageReports(nodeToRegister.getUuid())), TestUtils.getRandomContainerReports(10), - TestUtils.getRandomPipelineReports()); + TestUtils.getRandomPipelineReports(), layoutInfo); Assert.assertNotNull(responseProto); Assert.assertEquals(nodeToRegister.getUuidString(), responseProto.getDatanodeUUID()); @@ -305,9 +314,15 @@ public class TestEndPoint { when(ozoneContainer.getController()).thenReturn(controller); when(ozoneContainer.getPipelineReport()).thenReturn( TestUtils.getRandomPipelineReports()); + DataNodeLayoutVersionManager versionManager = + Mockito.mock(DataNodeLayoutVersionManager.class); + when(versionManager.getMetadataLayoutVersion()) + .thenReturn(TEST_METADATA_LAYOUT_VERSION); + when(versionManager.getSoftwareLayoutVersion()) + .thenReturn(TEST_SOFTWARE_LAYOUT_VERSION); RegisterEndpointTask endpointTask = new RegisterEndpointTask(rpcEndPoint, conf, ozoneContainer, - mock(StateContext.class)); + mock(StateContext.class), versionManager); if (!clearDatanodeDetails) { DatanodeDetails datanodeDetails = randomDatanodeDetails(); endpointTask.setDatanodeDetails(datanodeDetails); @@ -475,7 +490,8 @@ public class TestEndPoint { stateMachine); HeartbeatEndpointTask endpointTask = - new HeartbeatEndpointTask(rpcEndPoint, conf, stateContext); + new HeartbeatEndpointTask(rpcEndPoint, conf, stateContext, + stateMachine.getDataNodeVersionManager()); endpointTask.setDatanodeDetailsProto(datanodeDetailsProto); endpointTask.call(); Assert.assertNotNull(endpointTask.getDatanodeDetailsProto()); diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/upgrade/OMLayoutVersionManagerImpl.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/upgrade/OMLayoutVersionManagerImpl.java index 70a8d6b..3533dc8 100644 --- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/upgrade/OMLayoutVersionManagerImpl.java +++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/upgrade/OMLayoutVersionManagerImpl.java @@ -21,6 +21,7 @@ package org.apache.hadoop.ozone.om.upgrade; import static org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes.NOT_SUPPORTED_OPERATION; import static org.apache.hadoop.ozone.om.upgrade.OMLayoutFeature.INITIAL_VERSION; +import java.io.IOException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.Set; @@ -90,13 +91,10 @@ public final class OMLayoutVersionManagerImpl * @throws OMException on error. */ private void init(Storage storage) throws OMException { - init(storage.getLayoutVersion(), OMLayoutFeature.values()); - - if (metadataLayoutVersion > softwareLayoutVersion) { - throw new OMException( - String.format("Cannot initialize VersionManager. Metadata " + - "layout version (%d) > software layout version (%d)", - metadataLayoutVersion, softwareLayoutVersion), + try { + init(storage.getLayoutVersion(), OMLayoutFeature.values()); + } catch (IOException e) { + throw new OMException(String.format(e.getMessage()), NOT_SUPPORTED_OPERATION); } registerOzoneManagerRequests(); diff --git a/hadoop-ozone/recon/src/test/java/org/apache/hadoop/ozone/recon/api/TestEndpoints.java b/hadoop-ozone/recon/src/test/java/org/apache/hadoop/ozone/recon/api/TestEndpoints.java index c7392a7..bbfcade 100644 --- a/hadoop-ozone/recon/src/test/java/org/apache/hadoop/ozone/recon/api/TestEndpoints.java +++ b/hadoop-ozone/recon/src/test/java/org/apache/hadoop/ozone/recon/api/TestEndpoints.java @@ -25,6 +25,8 @@ import org.apache.hadoop.hdds.protocol.proto.HddsProtos.ReplicationType; import org.apache.hadoop.hdds.protocol.proto.HddsProtos.LifeCycleState; import org.apache.hadoop.hdds.protocol.proto.HddsProtos.PipelineID; import org.apache.hadoop.hdds.protocol.proto.HddsProtos.ReplicationFactor; +import org.apache.hadoop.hdds.protocol.proto + .StorageContainerDatanodeProtocolProtos.LayoutVersionProto; import org.apache.hadoop.hdds.protocol.proto.StorageContainerDatanodeProtocolProtos.ContainerReplicaProto; import org.apache.hadoop.hdds.protocol.proto.StorageContainerDatanodeProtocolProtos.PipelineReport; import org.apache.hadoop.hdds.protocol.proto.StorageContainerDatanodeProtocolProtos.SCMHeartbeatRequestProto; @@ -119,6 +121,8 @@ public class TestEndpoints extends AbstractReconSqlDBTest { private final String host2 = "host2.datanode"; private final String ip1 = "1.1.1.1"; private final String ip2 = "2.2.2.2"; + private static final int TEST_SOFTWARE_LAYOUT_VERSION = 0; + private static final int TEST_METADATA_LAYOUT_VERSION = 0; @Rule public TemporaryFolder temporaryFolder = new TemporaryFolder(); @@ -272,15 +276,19 @@ public class TestEndpoints extends AbstractReconSqlDBTest { NodeReportProto.newBuilder() .addStorageReport(storageReportProto3) .addStorageReport(storageReportProto4).build(); + LayoutVersionProto layoutInfo = LayoutVersionProto.newBuilder() + .setMetadataLayoutVersion(TEST_METADATA_LAYOUT_VERSION) + .setSoftwareLayoutVersion(TEST_SOFTWARE_LAYOUT_VERSION) + .build(); try { reconScm.getDatanodeProtocolServer() .register(datanodeDetailsProto, nodeReportProto, - containerReportsProto, pipelineReportsProto); + containerReportsProto, pipelineReportsProto, layoutInfo); reconScm.getDatanodeProtocolServer() .register(datanodeDetailsProto2, nodeReportProto2, ContainerReportsProto.newBuilder().build(), - PipelineReportsProto.newBuilder().build()); + PipelineReportsProto.newBuilder().build(), layoutInfo); // Process all events in the event queue reconScm.getEventQueue().processAll(1000); } catch (Exception ex) { --------------------------------------------------------------------- To unsubscribe, e-mail: ozone-commits-unsubscr...@hadoop.apache.org For additional commands, e-mail: ozone-commits-h...@hadoop.apache.org