blob: 50bd6980d62f7c5db18a0cce1ed6dac20cd2f87c [file] [log] [blame]
/*
* 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;
import org.apache.hadoop.fs.FileUtil;
import org.apache.hadoop.hdds.client.RatisReplicationConfig;
import org.apache.hadoop.hdds.conf.OzoneConfiguration;
import org.apache.hadoop.hdds.scm.container.ContainerID;
import org.apache.hadoop.hdds.scm.container.ContainerManager;
import org.apache.hadoop.hdds.scm.ha.SCMNodeDetails;
import org.apache.hadoop.hdds.scm.ha.SCMSnapshotProvider;
import org.apache.hadoop.hdds.scm.ha.SCMStateMachine;
import org.apache.hadoop.hdds.scm.metadata.SCMDBDefinition;
import org.apache.hadoop.hdds.scm.pipeline.Pipeline;
import org.apache.hadoop.hdds.scm.pipeline.PipelineID;
import org.apache.hadoop.hdds.scm.pipeline.PipelineManager;
import org.apache.hadoop.hdds.scm.server.StorageContainerManager;
import org.apache.hadoop.hdds.utils.HAUtils;
import org.apache.hadoop.hdds.utils.TransactionInfo;
import org.apache.hadoop.hdds.utils.db.DBCheckpoint;
import org.apache.hadoop.hdds.utils.db.DBStore;
import org.apache.hadoop.ozone.MiniOzoneCluster;
import org.apache.hadoop.ozone.OzoneConsts;
import org.apache.ozone.test.GenericTestUtils;
import org.apache.ozone.test.tag.Flaky;
import org.junit.jupiter.api.AfterAll;
import org.junit.Assert;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import java.io.File;
import java.net.InetSocketAddress;
import java.util.HashMap;
import java.util.Map;
import static org.apache.hadoop.hdds.protocol.proto.HddsProtos.ReplicationFactor.ONE;
import static org.apache.hadoop.hdds.protocol.proto.HddsProtos.ReplicationFactor.THREE;
/**
* Class to test install snapshot feature for SCM HA.
*/
public class TestSCMInstallSnapshot {
private static MiniOzoneCluster cluster;
private static OzoneConfiguration conf;
@BeforeAll
public static void setup() throws Exception {
conf = new OzoneConfiguration();
conf.setBoolean(ScmConfigKeys.OZONE_SCM_HA_ENABLE_KEY, true);
conf.set(ScmConfigKeys.OZONE_SCM_PIPELINE_CREATION_INTERVAL, "10s");
conf.setLong(ScmConfigKeys.OZONE_SCM_HA_RATIS_SNAPSHOT_THRESHOLD, 1L);
conf.set(ScmConfigKeys.OZONE_SCM_HA_RATIS_SNAPSHOT_DIR,
GenericTestUtils.getRandomizedTempPath() + "/snapshot");
cluster = MiniOzoneCluster
.newBuilder(conf)
.setNumDatanodes(3)
.build();
cluster.waitForClusterToBeReady();
}
@AfterAll
public static void shutdown() throws Exception {
if (cluster != null) {
cluster.shutdown();
}
}
@Test
public void testDownloadSnapshot() throws Exception {
downloadSnapshot();
}
private DBCheckpoint downloadSnapshot() throws Exception {
StorageContainerManager scm = cluster.getStorageContainerManager();
ContainerManager containerManager = scm.getContainerManager();
PipelineManager pipelineManager = scm.getPipelineManager();
Pipeline ratisPipeline1 = pipelineManager.getPipeline(
containerManager.allocateContainer(
RatisReplicationConfig.getInstance(THREE), "Owner1")
.getPipelineID());
pipelineManager.openPipeline(ratisPipeline1.getId());
Pipeline ratisPipeline2 = pipelineManager.getPipeline(
containerManager.allocateContainer(
RatisReplicationConfig.getInstance(ONE), "Owner2")
.getPipelineID());
pipelineManager.openPipeline(ratisPipeline2.getId());
SCMNodeDetails scmNodeDetails = new SCMNodeDetails.Builder()
.setRpcAddress(new InetSocketAddress("0.0.0.0", 0))
.setGrpcPort(ScmConfigKeys.OZONE_SCM_GRPC_PORT_DEFAULT)
.setSCMNodeId("scm1")
.build();
Map<String, SCMNodeDetails> peerMap = new HashMap<>();
peerMap.put(scmNodeDetails.getNodeId(), scmNodeDetails);
SCMSnapshotProvider provider =
scm.getScmHAManager().getSCMSnapshotProvider();
provider.setPeerNodesMap(peerMap);
DBCheckpoint checkpoint =
provider.getSCMDBSnapshot(scmNodeDetails.getNodeId());
final File[] files = FileUtil.listFiles(provider.getScmSnapshotDir());
Assert.assertTrue(files[0].getName().startsWith(
OzoneConsts.SCM_DB_NAME + "-" + scmNodeDetails.getNodeId()));
return checkpoint;
}
@Test
@Flaky("HDDS-6116")
public void testInstallCheckPoint() throws Exception {
DBCheckpoint checkpoint = downloadSnapshot();
StorageContainerManager scm = cluster.getStorageContainerManager();
DBStore db = HAUtils
.loadDB(conf, checkpoint.getCheckpointLocation().getParent().toFile(),
checkpoint.getCheckpointLocation().getFileName().toString(),
new SCMDBDefinition());
// Hack the transaction index in the checkpoint so as to ensure the
// checkpointed transaction index is higher than when it was downloaded
// from.
Assert.assertNotNull(db);
HAUtils.getTransactionInfoTable(db, new SCMDBDefinition())
.put(OzoneConsts.TRANSACTION_INFO_KEY, TransactionInfo.builder()
.setCurrentTerm(10).setTransactionIndex(100).build());
db.close();
ContainerID cid =
scm.getContainerManager().getContainers().get(0).containerID();
PipelineID pipelineID =
scm.getPipelineManager().getPipelines().get(0).getId();
scm.getScmMetadataStore().getPipelineTable().delete(pipelineID);
scm.getContainerManager().deleteContainer(cid);
Assert.assertNull(
scm.getScmMetadataStore().getPipelineTable().get(pipelineID));
Assert.assertFalse(scm.getContainerManager().containerExist(cid));
SCMStateMachine sm =
scm.getScmHAManager().getRatisServer().getSCMStateMachine();
sm.pause();
sm.setInstallingDBCheckpoint(checkpoint);
sm.reinitialize();
Assert.assertNotNull(
scm.getScmMetadataStore().getPipelineTable().get(pipelineID));
Assert.assertNotNull(
scm.getScmMetadataStore().getContainerTable().get(cid));
Assert.assertTrue(scm.getPipelineManager().containsPipeline(pipelineID));
Assert.assertTrue(scm.getContainerManager().containerExist(cid));
Assert.assertEquals(100, scm.getScmMetadataStore().
getTransactionInfoTable().get(OzoneConsts.TRANSACTION_INFO_KEY)
.getTransactionIndex());
Assert.assertEquals(100,
scm.getScmHAManager().asSCMHADBTransactionBuffer().getLatestTrxInfo()
.getTermIndex().getIndex());
}
}