diff --git a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/HddsDatanodeService.java b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/HddsDatanodeService.java index 7dc8c591119..bf33b9780d2 100644 --- a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/HddsDatanodeService.java +++ b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/HddsDatanodeService.java @@ -102,6 +102,9 @@ public class HddsDatanodeService extends GenericCli implements ServicePlugin { private static final Logger LOG = LoggerFactory.getLogger( HddsDatanodeService.class); + public static final String TESTING_DATANODE_VERSION_INITIAL = "testing.hdds.datanode.version.initial"; + public static final String TESTING_DATANODE_VERSION_CURRENT = "testing.hdds.datanode.version.current"; + private OzoneConfiguration conf; private SecurityConfig secConf; private DatanodeDetails datanodeDetails; @@ -432,15 +435,14 @@ private DatanodeDetails initializeDatanodeDetails() DatanodeDetails details; if (idFile.exists()) { details = ContainerUtils.readDatanodeDetailsFrom(idFile); - // Current version is always overridden to the latest - details.setCurrentVersion(getDefaultCurrentVersion()); } else { // There is no datanode.id file, this might be the first time datanode // is started. details = DatanodeDetails.newBuilder().setUuid(UUID.randomUUID()).build(); - details.setInitialVersion(getDefaultInitialVersion()); - details.setCurrentVersion(getDefaultCurrentVersion()); + details.setInitialVersion(getInitialVersion()); } + // Current version is always overridden to the latest + details.setCurrentVersion(getCurrentVersion()); return details; } @@ -680,16 +682,14 @@ private String reconfigReplicationStreamsLimit(String value) { /** * Returns the initial version of the datanode. */ - @VisibleForTesting - public static int getDefaultInitialVersion() { - return DatanodeVersion.CURRENT_VERSION; + private int getInitialVersion() { + return conf.getInt(TESTING_DATANODE_VERSION_INITIAL, DatanodeVersion.CURRENT_VERSION); } /** * Returns the current version of the datanode. */ - @VisibleForTesting - public static int getDefaultCurrentVersion() { - return DatanodeVersion.CURRENT_VERSION; + private int getCurrentVersion() { + return conf.getInt(TESTING_DATANODE_VERSION_CURRENT, DatanodeVersion.CURRENT_VERSION); } } diff --git a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/MiniOzoneCluster.java b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/MiniOzoneCluster.java index ff55ee83c17..1da5496fc94 100644 --- a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/MiniOzoneCluster.java +++ b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/MiniOzoneCluster.java @@ -22,7 +22,6 @@ import java.util.UUID; import java.util.concurrent.TimeoutException; -import org.apache.hadoop.hdds.DatanodeVersion; import org.apache.hadoop.hdds.HddsConfigKeys; import org.apache.hadoop.hdds.conf.OzoneConfiguration; import org.apache.hadoop.hdds.protocol.DatanodeDetails; @@ -305,9 +304,6 @@ abstract class Builder { protected boolean includeRecon = false; protected boolean includeS3G = false; - protected int dnInitialVersion = DatanodeVersion.FUTURE_VERSION.toProtoValue(); - protected int dnCurrentVersion = DatanodeVersion.COMBINED_PUTBLOCK_WRITECHUNK_RPC.toProtoValue(); - protected int numOfDatanodes = 3; protected boolean startDataNodes = true; protected CertificateClient certClient; @@ -379,30 +375,6 @@ public Builder setNumDatanodes(int val) { return this; } - /** - * Set the initialVersion for all datanodes. - * - * @param val initialVersion value to be set for all datanodes. - * - * @return MiniOzoneCluster.Builder - */ - public Builder setDatanodeInitialVersion(int val) { - dnInitialVersion = val; - return this; - } - - /** - * Set the currentVersion for all datanodes. - * - * @param val currentVersion value to be set for all datanodes. - * - * @return MiniOzoneCluster.Builder - */ - public Builder setDatanodeCurrentVersion(int val) { - dnCurrentVersion = val; - return this; - } - public Builder setDatanodeFactory(DatanodeFactory factory) { this.dnFactory = factory; return this; diff --git a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/MiniOzoneClusterImpl.java b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/MiniOzoneClusterImpl.java index 3594996856a..30e41764d3f 100644 --- a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/MiniOzoneClusterImpl.java +++ b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/MiniOzoneClusterImpl.java @@ -41,7 +41,6 @@ import com.amazonaws.services.s3.AmazonS3; import com.amazonaws.services.s3.AmazonS3ClientBuilder; import org.apache.commons.lang3.StringUtils; -import org.apache.hadoop.hdds.DatanodeVersion; import org.apache.hadoop.hdds.HddsConfigKeys; import org.apache.hadoop.hdds.annotation.InterfaceAudience; import org.apache.hadoop.hdds.client.RatisReplicationConfig; @@ -110,8 +109,6 @@ import static org.apache.ozone.test.GenericTestUtils.PortAllocator.localhostWithFreePort; import org.hadoop.ozone.recon.codegen.ReconSqlDbConfig; -import org.mockito.MockedStatic; -import org.mockito.Mockito; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -145,7 +142,6 @@ public class MiniOzoneClusterImpl implements MiniOzoneCluster { private CertificateClient caClient; private final Set clients = ConcurrentHashMap.newKeySet(); private SecretKeyClient secretKeyClient; - private static MockedStatic mockDNStatic = Mockito.mockStatic(HddsDatanodeService.class); /** * Creates a new MiniOzoneCluster with Recon. @@ -427,16 +423,6 @@ private void waitForHddsDatanodeToStop(DatanodeDetails dn) }, 1000, waitForClusterToBeReadyTimeout); } - private static void overrideDatanodeVersions(int dnInitialVersion, int dnCurrentVersion) { - // FUTURE_VERSION (-1) is not a valid version for a datanode, using it as a marker when version is not overridden - if (dnInitialVersion != DatanodeVersion.FUTURE_VERSION.toProtoValue()) { - mockDNStatic.when(HddsDatanodeService::getDefaultInitialVersion).thenReturn(dnInitialVersion); - } - if (dnCurrentVersion != DatanodeVersion.FUTURE_VERSION.toProtoValue()) { - mockDNStatic.when(HddsDatanodeService::getDefaultCurrentVersion).thenReturn(dnCurrentVersion); - } - } - @Override public void restartHddsDatanode(int i, boolean waitForDatanode) throws InterruptedException, TimeoutException { @@ -869,9 +855,6 @@ protected List createHddsDatanodes() throws IOException { List hddsDatanodes = new ArrayList<>(); - // Override default datanode initial and current version if necessary - overrideDatanodeVersions(dnInitialVersion, dnCurrentVersion); - for (int i = 0; i < numOfDatanodes; i++) { OzoneConfiguration dnConf = dnFactory.apply(conf); diff --git a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/UniformDatanodesFactory.java b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/UniformDatanodesFactory.java index 8f79605ab05..ecf281a1a86 100644 --- a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/UniformDatanodesFactory.java +++ b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/UniformDatanodesFactory.java @@ -17,6 +17,7 @@ */ package org.apache.hadoop.ozone; +import org.apache.hadoop.hdds.DatanodeVersion; import org.apache.hadoop.hdds.conf.ConfigurationTarget; import org.apache.hadoop.hdds.conf.OzoneConfiguration; import org.apache.hadoop.ozone.container.common.DatanodeLayoutStorage; @@ -39,6 +40,8 @@ import static org.apache.hadoop.hdds.scm.ScmConfigKeys.HDDS_DATANODE_DIR_DU_RESERVED; import static org.apache.hadoop.hdds.scm.ScmConfigKeys.HDDS_DATANODE_DIR_KEY; import static org.apache.hadoop.hdds.scm.ScmConfigKeys.HDDS_REST_HTTP_ADDRESS_KEY; +import static org.apache.hadoop.ozone.HddsDatanodeService.TESTING_DATANODE_VERSION_CURRENT; +import static org.apache.hadoop.ozone.HddsDatanodeService.TESTING_DATANODE_VERSION_INITIAL; import static org.apache.hadoop.ozone.OzoneConfigKeys.HDDS_CONTAINER_IPC_PORT; import static org.apache.hadoop.ozone.OzoneConfigKeys.HDDS_CONTAINER_RATIS_ADMIN_PORT; import static org.apache.hadoop.ozone.OzoneConfigKeys.HDDS_CONTAINER_RATIS_DATANODE_STORAGE_DIR; @@ -58,11 +61,15 @@ public class UniformDatanodesFactory implements MiniOzoneCluster.DatanodeFactory private final int numDataVolumes; private final String reservedSpace; private final Integer layoutVersion; + private final DatanodeVersion initialVersion; + private final DatanodeVersion currentVersion; protected UniformDatanodesFactory(Builder builder) { numDataVolumes = builder.numDataVolumes; layoutVersion = builder.layoutVersion; reservedSpace = builder.reservedSpace; + currentVersion = builder.currentVersion; + initialVersion = builder.initialVersion != null ? builder.initialVersion : builder.currentVersion; } @Override @@ -104,6 +111,13 @@ public OzoneConfiguration apply(OzoneConfiguration conf) throws IOException { layoutStorage.initialize(); } + if (initialVersion != null) { + dnConf.setInt(TESTING_DATANODE_VERSION_INITIAL, initialVersion.toProtoValue()); + } + if (currentVersion != null) { + dnConf.setInt(TESTING_DATANODE_VERSION_CURRENT, currentVersion.toProtoValue()); + } + return dnConf; } @@ -131,6 +145,8 @@ public static class Builder { private int numDataVolumes = 1; private String reservedSpace; private Integer layoutVersion; + private DatanodeVersion initialVersion; + private DatanodeVersion currentVersion; /** * Sets the number of data volumes per datanode. @@ -158,6 +174,16 @@ public Builder setLayoutVersion(int layoutVersion) { return this; } + public Builder setInitialVersion(DatanodeVersion version) { + this.initialVersion = version; + return this; + } + + public Builder setCurrentVersion(DatanodeVersion version) { + this.currentVersion = version; + return this; + } + public UniformDatanodesFactory build() { return new UniformDatanodesFactory(this); } diff --git a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/client/rpc/TestBlockDataStreamOutput.java b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/client/rpc/TestBlockDataStreamOutput.java index 90a3f1d6893..5bcf7084054 100644 --- a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/client/rpc/TestBlockDataStreamOutput.java +++ b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/client/rpc/TestBlockDataStreamOutput.java @@ -33,6 +33,7 @@ import org.apache.hadoop.ozone.HddsDatanodeService; import org.apache.hadoop.ozone.MiniOzoneCluster; import org.apache.hadoop.ozone.OzoneConfigKeys; +import org.apache.hadoop.ozone.UniformDatanodesFactory; import org.apache.hadoop.ozone.client.ObjectStore; import org.apache.hadoop.ozone.client.OzoneClient; import org.apache.hadoop.ozone.client.OzoneClientFactory; @@ -74,7 +75,7 @@ public class TestBlockDataStreamOutput { private static String volumeName; private static String bucketName; private static String keyString; - private static final int DN_OLD_VERSION = DatanodeVersion.SEPARATE_RATIS_PORTS_AVAILABLE.toProtoValue(); + private static final DatanodeVersion DN_OLD_VERSION = DatanodeVersion.SEPARATE_RATIS_PORTS_AVAILABLE; /** * Create a MiniDFSCluster for testing. @@ -110,7 +111,9 @@ public static void init() throws Exception { cluster = MiniOzoneCluster.newBuilder(conf) .setNumDatanodes(5) - .setDatanodeCurrentVersion(DN_OLD_VERSION) + .setDatanodeFactory(UniformDatanodesFactory.newBuilder() + .setCurrentVersion(DN_OLD_VERSION) + .build()) .build(); cluster.waitForClusterToBeReady(); //the easiest way to create an open container is creating a key @@ -281,7 +284,7 @@ public void testDatanodeVersion() throws Exception { List dns = cluster.getHddsDatanodes(); for (HddsDatanodeService dn : dns) { DatanodeDetails details = dn.getDatanodeDetails(); - assertEquals(DN_OLD_VERSION, details.getCurrentVersion()); + assertEquals(DN_OLD_VERSION.toProtoValue(), details.getCurrentVersion()); } String keyName = getKeyName(); @@ -292,7 +295,7 @@ public void testDatanodeVersion() throws Exception { // Now check 3 DNs in a random pipeline returns the correct DN versions List streamDnDetails = stream.getPipeline().getNodes(); for (DatanodeDetails details : streamDnDetails) { - assertEquals(DN_OLD_VERSION, details.getCurrentVersion()); + assertEquals(DN_OLD_VERSION.toProtoValue(), details.getCurrentVersion()); } } diff --git a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/client/rpc/TestDatanodeVersion.java b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/client/rpc/TestDatanodeVersion.java deleted file mode 100644 index 5e7d8a4b052..00000000000 --- a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/client/rpc/TestDatanodeVersion.java +++ /dev/null @@ -1,143 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with this - * work for additional information regarding copyright ownership. The ASF - * licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * 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.client.rpc; - -import org.apache.hadoop.hdds.DatanodeVersion; -import org.apache.hadoop.hdds.client.ReplicationType; -import org.apache.hadoop.hdds.conf.OzoneConfiguration; -import org.apache.hadoop.hdds.conf.StorageUnit; -import org.apache.hadoop.hdds.protocol.DatanodeDetails; -import org.apache.hadoop.hdds.scm.OzoneClientConfig; -import org.apache.hadoop.hdds.utils.IOUtils; -import org.apache.hadoop.ozone.ClientConfigForTesting; -import org.apache.hadoop.ozone.HddsDatanodeService; -import org.apache.hadoop.ozone.MiniOzoneCluster; -import org.apache.hadoop.ozone.OzoneConfigKeys; -import org.apache.hadoop.ozone.client.ObjectStore; -import org.apache.hadoop.ozone.client.OzoneClient; -import org.apache.hadoop.ozone.client.OzoneClientFactory; -import org.apache.hadoop.ozone.client.io.BlockDataStreamOutputEntry; -import org.apache.hadoop.ozone.client.io.KeyDataStreamOutput; -import org.apache.hadoop.ozone.client.io.OzoneDataStreamOutput; -import org.apache.hadoop.ozone.container.TestHelper; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.Timeout; - -import java.util.List; -import java.util.UUID; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -/** - * Tests DatanodeVersion in client stream. - */ -@Timeout(120) -public class TestDatanodeVersion { - private static MiniOzoneCluster cluster; - private static OzoneConfiguration conf = new OzoneConfiguration(); - private static OzoneClient client; - private static ObjectStore objectStore; - private static int chunkSize; - private static int flushSize; - private static int maxFlushSize; - private static int blockSize; - private static String volumeName; - private static String bucketName; - private static final int DN_OLD_VERSION = DatanodeVersion.SEPARATE_RATIS_PORTS_AVAILABLE.toProtoValue(); - - /** - * Create a MiniDFSCluster for testing. - *

- * Ozone is made active by setting OZONE_ENABLED = true - */ - @BeforeAll - public static void init() throws Exception { - chunkSize = 100; - flushSize = 2 * chunkSize; - maxFlushSize = 2 * flushSize; - blockSize = 2 * maxFlushSize; - - OzoneClientConfig clientConfig = conf.getObject(OzoneClientConfig.class); - conf.setFromObject(clientConfig); - - conf.setQuietMode(false); - conf.setStorageSize(OzoneConfigKeys.OZONE_SCM_BLOCK_SIZE, 4, StorageUnit.MB); - - ClientConfigForTesting.newBuilder(StorageUnit.BYTES) - .setBlockSize(blockSize) - .setChunkSize(chunkSize) - .setStreamBufferFlushSize(flushSize) - .setStreamBufferMaxSize(maxFlushSize) - .setDataStreamBufferFlushSize(maxFlushSize) - .setDataStreamMinPacketSize(chunkSize) - .setDataStreamWindowSize(5 * chunkSize) - .applyTo(conf); - - cluster = MiniOzoneCluster.newBuilder(conf) - .setNumDatanodes(3) - .setDatanodeCurrentVersion(DN_OLD_VERSION) - .build(); - cluster.waitForClusterToBeReady(); - //the easiest way to create an open container is creating a key - client = OzoneClientFactory.getRpcClient(conf); - objectStore = client.getObjectStore(); - volumeName = "testblockoutputstream"; - bucketName = volumeName; - objectStore.createVolume(volumeName); - objectStore.getVolume(volumeName).createBucket(bucketName); - } - - /** - * Shutdown MiniDFSCluster. - */ - @AfterAll - public static void shutdown() { - IOUtils.closeQuietly(client); - if (cluster != null) { - cluster.shutdown(); - } - } - - static OzoneDataStreamOutput createKey(String keyName, ReplicationType type, long size) throws Exception { - return TestHelper.createStreamKey(keyName, type, size, objectStore, volumeName, bucketName); - } - - @Test - public void testStreamDatanodeVersion() throws Exception { - // Verify all DNs internally have versions set correctly - List dns = cluster.getHddsDatanodes(); - for (HddsDatanodeService dn : dns) { - DatanodeDetails details = dn.getDatanodeDetails(); - assertEquals(DN_OLD_VERSION, details.getCurrentVersion()); - } - - String keyName = UUID.randomUUID().toString(); - OzoneDataStreamOutput key = createKey(keyName, ReplicationType.RATIS, 0); - KeyDataStreamOutput keyDataStreamOutput = (KeyDataStreamOutput) key.getByteBufStreamOutput(); - BlockDataStreamOutputEntry stream = keyDataStreamOutput.getStreamEntries().get(0); - - // Now check 3 DNs in a random pipeline returns the correct DN versions - List streamDnDetails = stream.getPipeline().getNodes(); - for (DatanodeDetails details : streamDnDetails) { - assertEquals(DN_OLD_VERSION, details.getCurrentVersion()); - } - } - -}