blob: 2b3883cdd783384e9f7941132189afaa34381b1d [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
* <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.hdds.scm.container.replication;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.hadoop.hdds.client.ReplicationConfig;
import org.apache.hadoop.hdds.conf.OzoneConfiguration;
import org.apache.hadoop.hdds.protocol.DatanodeDetails;
import org.apache.hadoop.hdds.protocol.MockDatanodeDetails;
import org.apache.hadoop.hdds.protocol.proto.HddsProtos;
import org.apache.hadoop.hdds.protocol.proto.StorageContainerDatanodeProtocolProtos.ContainerReplicaProto;
import org.apache.hadoop.hdds.scm.PlacementPolicy;
import org.apache.hadoop.hdds.scm.SCMCommonPlacementPolicy;
import org.apache.hadoop.hdds.scm.container.ContainerID;
import org.apache.hadoop.hdds.scm.container.ContainerInfo;
import org.apache.hadoop.hdds.scm.container.ContainerReplica;
import org.apache.hadoop.hdds.scm.exceptions.SCMException;
import org.apache.hadoop.hdds.scm.node.NodeManager;
import org.apache.hadoop.hdds.scm.pipeline.PipelineID;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import static org.apache.hadoop.hdds.protocol.proto.HddsProtos.NodeOperationalState.IN_SERVICE;
import static org.apache.hadoop.hdds.protocol.proto.StorageContainerDatanodeProtocolProtos.ContainerReplicaProto.State.CLOSED;
import static org.apache.hadoop.hdds.scm.exceptions.SCMException.ResultCodes.FAILED_TO_FIND_SUITABLE_NODE;
/**
* Helper class to provide common methods used to test ReplicationManager.
*/
public final class ReplicationTestUtil {
private ReplicationTestUtil() {
}
@SafeVarargs
public static Set<ContainerReplica> createReplicas(ContainerID containerID,
Pair<HddsProtos.NodeOperationalState, Integer>... nodes) {
return createReplicas(containerID, CLOSED, nodes);
}
@SafeVarargs
public static Set<ContainerReplica> createReplicas(ContainerID containerID,
ContainerReplicaProto.State replicaState,
Pair<HddsProtos.NodeOperationalState, Integer>... nodes) {
Set<ContainerReplica> replicas = new HashSet<>();
for (Pair<HddsProtos.NodeOperationalState, Integer> p : nodes) {
replicas.add(createContainerReplica(
containerID, p.getRight(), p.getLeft(), replicaState));
}
return replicas;
}
public static Set<ContainerReplica> createReplicas(ContainerID containerID,
int... indexes) {
return createReplicas(containerID, CLOSED, indexes);
}
public static Set<ContainerReplica> createReplicas(ContainerID containerID,
ContainerReplicaProto.State replicaState, int... indexes) {
Set<ContainerReplica> replicas = new HashSet<>();
for (int i : indexes) {
replicas.add(createContainerReplica(
containerID, i, IN_SERVICE, replicaState));
}
return replicas;
}
public static ContainerReplica createContainerReplica(ContainerID containerID,
int replicaIndex, HddsProtos.NodeOperationalState opState,
ContainerReplicaProto.State replicaState) {
ContainerReplica.ContainerReplicaBuilder builder
= ContainerReplica.newBuilder();
DatanodeDetails datanodeDetails
= MockDatanodeDetails.randomDatanodeDetails();
datanodeDetails.setPersistedOpState(opState);
builder.setContainerID(containerID);
builder.setReplicaIndex(replicaIndex);
builder.setKeyCount(123);
builder.setBytesUsed(1234);
builder.setContainerState(replicaState);
builder.setDatanodeDetails(datanodeDetails);
builder.setSequenceId(0);
builder.setOriginNodeId(datanodeDetails.getUuid());
return builder.build();
}
public static ContainerInfo createContainerInfo(ReplicationConfig repConfig) {
return createContainerInfo(repConfig, 1, HddsProtos.LifeCycleState.CLOSED);
}
public static ContainerInfo createContainerInfo(
ReplicationConfig replicationConfig, long containerID,
HddsProtos.LifeCycleState containerState) {
ContainerInfo.Builder builder = new ContainerInfo.Builder();
builder.setContainerID(containerID);
builder.setOwner("Ozone");
builder.setPipelineID(PipelineID.randomId());
builder.setReplicationConfig(replicationConfig);
builder.setState(containerState);
return builder.build();
}
public static ContainerInfo createContainer(HddsProtos.LifeCycleState state,
ReplicationConfig replicationConfig) {
return new ContainerInfo.Builder()
.setContainerID(1).setState(state)
.setReplicationConfig(replicationConfig).build();
}
@SafeVarargs
public static Set<ContainerReplica> createReplicas(
Pair<HddsProtos.NodeOperationalState, Integer>... states) {
return createReplicas(CLOSED,
states);
}
@SafeVarargs
public static Set<ContainerReplica> createReplicas(
ContainerReplicaProto.State replicaState,
Pair<HddsProtos.NodeOperationalState, Integer>... states) {
Set<ContainerReplica> replica = new HashSet<>();
for (Pair<HddsProtos.NodeOperationalState, Integer> s : states) {
replica.add(createContainerReplica(ContainerID.valueOf(1), s.getRight(),
s.getLeft(), replicaState));
}
return replica;
}
public static PlacementPolicy getSimpleTestPlacementPolicy(
final NodeManager nodeManager, final OzoneConfiguration conf) {
return new SCMCommonPlacementPolicy(nodeManager, conf) {
@Override
protected List<DatanodeDetails> chooseDatanodesInternal(
List<DatanodeDetails> excludedNodes,
List<DatanodeDetails> favoredNodes, int nodesRequiredToChoose,
long metadataSizeRequired, long dataSizeRequired) {
List<DatanodeDetails> dns = new ArrayList<>();
for (int i = 0; i < nodesRequiredToChoose; i++) {
dns.add(MockDatanodeDetails.randomDatanodeDetails());
}
return dns;
}
@Override
public DatanodeDetails chooseNode(List<DatanodeDetails> healthyNodes) {
return null;
}
};
}
public static PlacementPolicy getSameNodeTestPlacementPolicy(
final NodeManager nodeManager, final OzoneConfiguration conf,
DatanodeDetails nodeToReturn) {
return new SCMCommonPlacementPolicy(nodeManager, conf) {
@Override
protected List<DatanodeDetails> chooseDatanodesInternal(
List<DatanodeDetails> excludedNodes,
List<DatanodeDetails> favoredNodes, int nodesRequiredToChoose,
long metadataSizeRequired, long dataSizeRequired)
throws SCMException {
if (nodesRequiredToChoose > 1) {
throw new IllegalArgumentException("Only one node is allowed");
}
if (excludedNodes.contains(nodeToReturn)) {
throw new SCMException("Insufficient Nodes available to choose",
SCMException.ResultCodes.FAILED_TO_FIND_HEALTHY_NODES);
}
List<DatanodeDetails> dns = new ArrayList<>();
dns.add(nodeToReturn);
return dns;
}
@Override
public DatanodeDetails chooseNode(List<DatanodeDetails> healthyNodes) {
return null;
}
};
}
public static PlacementPolicy getNoNodesTestPlacementPolicy(
final NodeManager nodeManager, final OzoneConfiguration conf) {
return new SCMCommonPlacementPolicy(nodeManager, conf) {
@Override
protected List<DatanodeDetails> chooseDatanodesInternal(
List<DatanodeDetails> excludedNodes,
List<DatanodeDetails> favoredNodes, int nodesRequiredToChoose,
long metadataSizeRequired, long dataSizeRequired)
throws SCMException {
throw new SCMException("No nodes available",
FAILED_TO_FIND_SUITABLE_NODE);
}
@Override
public DatanodeDetails chooseNode(List<DatanodeDetails> healthyNodes) {
return null;
}
};
}
}