diff --git a/hadoop-hdds/client/src/main/java/org/apache/hadoop/hdds/scm/storage/ChunkInputStream.java b/hadoop-hdds/client/src/main/java/org/apache/hadoop/hdds/scm/storage/ChunkInputStream.java index 34ef7a71bd3..ea2f25faa44 100644 --- a/hadoop-hdds/client/src/main/java/org/apache/hadoop/hdds/scm/storage/ChunkInputStream.java +++ b/hadoop-hdds/client/src/main/java/org/apache/hadoop/hdds/scm/storage/ChunkInputStream.java @@ -27,7 +27,6 @@ import java.util.Arrays; import java.util.List; import java.util.function.Supplier; -import org.apache.commons.lang3.tuple.Pair; import org.apache.hadoop.fs.ByteBufferReadable; import org.apache.hadoop.fs.CanUnbuffer; import org.apache.hadoop.fs.Seekable; @@ -382,10 +381,10 @@ private synchronized void readChunkFromContainer(int len) throws IOException { if (verifyChecksum) { // Adjust the chunk offset and length to include required checksum // boundaries - Pair adjustedOffsetAndLength = + ChecksumBoundaries adjustedOffsetAndLength = computeChecksumBoundaries(startByteIndex, len); - adjustedBuffersOffset = adjustedOffsetAndLength.getLeft(); - adjustedBuffersLen = adjustedOffsetAndLength.getRight(); + adjustedBuffersOffset = adjustedOffsetAndLength.offset; + adjustedBuffersLen = adjustedOffsetAndLength.length; } else { // Read from the startByteIndex adjustedBuffersOffset = startByteIndex; @@ -517,7 +516,7 @@ private void validateChunk( * @return Adjusted (Chunk Offset, Chunk Length) which needs to be read * from Container */ - private Pair computeChecksumBoundaries(long startByteIndex, + private ChecksumBoundaries computeChecksumBoundaries(long startByteIndex, int dataLen) { int bytesPerChecksum = chunkInfo.getChecksumData().getBytesPerChecksum(); @@ -529,7 +528,20 @@ private Pair computeChecksumBoundaries(long startByteIndex, final long endIndex = ((endByteIndex / bytesPerChecksum) + 1) * bytesPerChecksum; // exclusive long adjustedChunkLen = Math.min(endIndex, length) - adjustedChunkOffset; - return Pair.of(adjustedChunkOffset, adjustedChunkLen); + return new ChecksumBoundaries(adjustedChunkOffset, adjustedChunkLen); + } + + /** + * Checksum-aligned chunk boundaries for a read operation. + */ + private static final class ChecksumBoundaries { + private final long offset; + private final long length; + + private ChecksumBoundaries(long offset, long length) { + this.offset = offset; + this.length = length; + } } /** diff --git a/hadoop-hdds/client/src/main/java/org/apache/hadoop/ozone/client/io/ECBlockReconstructedStripeInputStream.java b/hadoop-hdds/client/src/main/java/org/apache/hadoop/ozone/client/io/ECBlockReconstructedStripeInputStream.java index c71db0e41ed..ed27aee5f5e 100644 --- a/hadoop-hdds/client/src/main/java/org/apache/hadoop/ozone/client/io/ECBlockReconstructedStripeInputStream.java +++ b/hadoop-hdds/client/src/main/java/org/apache/hadoop/ozone/client/io/ECBlockReconstructedStripeInputStream.java @@ -43,7 +43,6 @@ import java.util.concurrent.Future; import java.util.function.Function; import org.apache.commons.lang3.NotImplementedException; -import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.hadoop.hdds.client.BlockID; import org.apache.hadoop.hdds.client.ECReplicationConfig; import org.apache.hadoop.hdds.protocol.DatanodeDetails; @@ -570,11 +569,11 @@ private void clearInternalBuffers() { protected void loadDataBuffersFromStream() throws IOException, InterruptedException { - Queue>> pendingReads + Queue pendingReads = new ArrayDeque<>(); for (int i : selectedIndexes) { ByteBuffer buf = decoderInputBuffers[i]; - pendingReads.add(new ImmutablePair<>(i, executor.submit(() -> { + pendingReads.add(new PendingRead(i, executor.submit(() -> { readIntoBuffer(i, buf); return null; }))); @@ -583,8 +582,8 @@ protected void loadDataBuffersFromStream() while (!pendingReads.isEmpty()) { int index = -1; try { - ImmutablePair> pair = pendingReads.poll(); - index = pair.getKey(); + PendingRead pendingRead = pendingReads.poll(); + index = pendingRead.index; // Should this future.get() have a timeout? At the end of the call chain // we eventually call a grpc or ratis client to read the block data. Its // the call to the DNs which could potentially block. There is a timeout @@ -593,7 +592,7 @@ protected void loadDataBuffersFromStream() // Which defaults to 30s. So if there is a DN communication problem, it // should timeout in the client which should propagate up the stack as // an IOException. - pair.getValue().get(); + pendingRead.future.get(); } catch (ExecutionException ee) { boolean added = failedDataIndexes.add(index); Throwable t = ee.getCause() != null ? ee.getCause() : ee; @@ -624,6 +623,19 @@ protected void loadDataBuffersFromStream() } } + /** + * A pending block read tracked by stripe reconstruction. + */ + private static final class PendingRead { + private final int index; + private final Future future; + + private PendingRead(int index, Future future) { + this.index = index; + this.future = future; + } + } + private void readIntoBuffer(int ind, ByteBuffer buf) throws IOException { List failedLocations = new LinkedList<>(); while (true) { diff --git a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/scm/SafeModeRuleStatus.java b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/scm/SafeModeRuleStatus.java new file mode 100644 index 00000000000..eda831f78b0 --- /dev/null +++ b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/scm/SafeModeRuleStatus.java @@ -0,0 +1,68 @@ +/* + * 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 java.util.Objects; + +/** + * Status of SCM safe mode exit rule. + */ +public final class SafeModeRuleStatus { + + private final boolean validated; + private final String statusText; + + public SafeModeRuleStatus(boolean validated, String statusText) { + this.validated = validated; + this.statusText = statusText; + } + + public boolean isValidated() { + return validated; + } + + public String getStatusText() { + return statusText; + } + + @Override + public boolean equals(Object other) { + if (this == other) { + return true; + } + if (!(other instanceof SafeModeRuleStatus)) { + return false; + } + SafeModeRuleStatus that = (SafeModeRuleStatus) other; + return validated == that.validated + && Objects.equals(statusText, that.statusText); + } + + @Override + public int hashCode() { + return Objects.hash(validated, statusText); + } + + @Override + public String toString() { + return "SafeModeRuleStatus{" + + "validated=" + validated + + ", statusText='" + statusText + '\'' + + '}'; + } +} diff --git a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/tracing/TraceAllMethod.java b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/tracing/TraceAllMethod.java index 623e004a96e..9b961bb4d40 100644 --- a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/tracing/TraceAllMethod.java +++ b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/tracing/TraceAllMethod.java @@ -25,7 +25,6 @@ import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; -import org.apache.commons.lang3.tuple.Pair; /** * A Java proxy invocation handler to trace all the methods of the delegate @@ -38,7 +37,7 @@ public class TraceAllMethod implements InvocationHandler { /** * Cache for all the method objects of the delegate class. */ - private final Map[], Pair>> methods = new HashMap<>(); + private final Map[], DelegatedMethodInfo>> methods = new HashMap<>(); private final T delegate; private final String name; @@ -52,19 +51,19 @@ public TraceAllMethod(T delegate, String name) { } boolean shouldSkip = method.isAnnotationPresent(SkipTracing.class); methods.computeIfAbsent(method.getName(), any -> new HashMap<>()) - .put(method.getParameterTypes(), Pair.of(shouldSkip, method)); + .put(method.getParameterTypes(), new DelegatedMethodInfo(shouldSkip, method)); } } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - Pair methodInfo = findDelegatedMethod(method); + DelegatedMethodInfo methodInfo = findDelegatedMethod(method); if (methodInfo == null) { throw new NoSuchMethodException("Method not found: " + method.getName()); } - boolean shouldSkip = methodInfo.getLeft(); - Method delegateMethod = methodInfo.getRight(); + boolean shouldSkip = methodInfo.shouldSkip; + Method delegateMethod = methodInfo.delegateMethod; if (shouldSkip) { try { return delegateMethod.invoke(delegate, args); @@ -90,8 +89,8 @@ public Object invoke(Object proxy, Method method, Object[] args) } } - private Pair findDelegatedMethod(Method method) { - for (Entry[], Pair> entry : methods.getOrDefault( + private DelegatedMethodInfo findDelegatedMethod(Method method) { + for (Entry[], DelegatedMethodInfo> entry : methods.getOrDefault( method.getName(), emptyMap()).entrySet()) { if (Arrays.equals(entry.getKey(), method.getParameterTypes())) { return entry.getValue(); @@ -99,4 +98,17 @@ private Pair findDelegatedMethod(Method method) { } return null; } + + /** + * Whether a method should be skipped and the delegate method to invoke. + */ + private static final class DelegatedMethodInfo { + private final boolean shouldSkip; + private final Method delegateMethod; + + private DelegatedMethodInfo(boolean shouldSkip, Method delegateMethod) { + this.shouldSkip = shouldSkip; + this.delegateMethod = delegateMethod; + } + } } diff --git a/hadoop-hdds/common/src/main/java/org/apache/hadoop/ipc_/Client.java b/hadoop-hdds/common/src/main/java/org/apache/hadoop/ipc_/Client.java index e54844672b2..3ede424d4cd 100644 --- a/hadoop-hdds/common/src/main/java/org/apache/hadoop/ipc_/Client.java +++ b/hadoop-hdds/common/src/main/java/org/apache/hadoop/ipc_/Client.java @@ -18,7 +18,6 @@ package org.apache.hadoop.ipc_; -import org.apache.commons.lang3.tuple.Pair; import org.apache.hadoop.security.AccessControlException; import com.google.common.base.Preconditions; import org.apache.hadoop.conf.Configuration; @@ -333,7 +332,7 @@ private class Connection extends Thread { private IOException closeException; // close reason private final Thread rpcRequestThread; - private final SynchronousQueue> rpcRequestQueue = + private final SynchronousQueue rpcRequestQueue = new SynchronousQueue<>(true); private AtomicReference connectingThread = new AtomicReference<>(); @@ -1048,15 +1047,15 @@ public void run() { while (!shouldCloseConnection.get()) { ResponseBuffer buf = null; try { - Pair pair = + RpcRequest rpcRequest = rpcRequestQueue.poll(maxIdleTime, TimeUnit.MILLISECONDS); - if (pair == null || shouldCloseConnection.get()) { + if (rpcRequest == null || shouldCloseConnection.get()) { continue; } - buf = pair.getRight(); + buf = rpcRequest.buffer; synchronized (ipcStreams.out) { if (LOG.isDebugEnabled()) { - Call call = pair.getLeft(); + Call call = rpcRequest.call; LOG.debug(getName() + "{} sending #{} {}", getName(), call.id, call.rpcRequest); } @@ -1115,12 +1114,25 @@ public void sendRpcRequest(final Call call) // prevent a race condition between checking the shouldCloseConnection // and the stopping of the polling thread while (!shouldCloseConnection.get()) { - if (rpcRequestQueue.offer(Pair.of(call, buf), 1, TimeUnit.SECONDS)) { + if (rpcRequestQueue.offer(new RpcRequest(call, buf), 1, TimeUnit.SECONDS)) { break; } } } + /** + * A queued RPC call and its response buffer. + */ + private final class RpcRequest { + private final Call call; + private final ResponseBuffer buffer; + + private RpcRequest(Call call, ResponseBuffer buffer) { + this.call = call; + this.buffer = buffer; + } + } + /* Receive a response. * Because only one receiver, so no synchronization on in. */ @@ -1553,7 +1565,6 @@ void setAddress(InetSocketAddress address) { this.address = address; } - Class getProtocol() { return protocol; } 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 356e5887745..63595d4083b 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 @@ -55,7 +55,6 @@ import java.util.stream.Stream; import javax.management.ObjectName; import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.tuple.Pair; import org.apache.hadoop.conf.Configurable; import org.apache.hadoop.hdds.DatanodeVersion; import org.apache.hadoop.hdds.HddsConfigKeys; @@ -84,6 +83,7 @@ import org.apache.hadoop.hdds.utils.HddsServerUtil; import org.apache.hadoop.hdds.utils.HddsVersionInfo; import org.apache.hadoop.hdds.utils.IOUtils; +import org.apache.hadoop.hdds.utils.ScmNodeAddress; import org.apache.hadoop.metrics2.util.MBeans; import org.apache.hadoop.ozone.container.common.DatanodeLayoutStorage; import org.apache.hadoop.ozone.container.common.helpers.ContainerUtils; @@ -790,12 +790,12 @@ private String reconfigScmNodes(String value) { LOG.info("Reconfiguring SCM nodes for service ID {} with new SCM nodes {} and remove SCM nodes {}", scmServiceId, scmNodesIdsToAdd, scmNodesIdsToRemove); - final Collection> scmToAdd = HddsServerUtil.getSCMAddressForDatanodes( + final Collection scmToAdd = HddsServerUtil.getSCMAddressForDatanodes( getConf(), scmServiceId, scmNodesIdsToAdd); if (scmToAdd == null) { throw new IllegalStateException("Reconfiguration failed to get SCM address to add due to wrong configuration"); } - final Collection> scmToRemove = HddsServerUtil.getSCMAddressForDatanodes( + final Collection scmToRemove = HddsServerUtil.getSCMAddressForDatanodes( getConf(), scmServiceId, scmNodesIdsToRemove); if (scmToRemove == null) { throw new IllegalArgumentException( @@ -816,9 +816,9 @@ private String reconfigScmNodes(String value) { } // Add the new SCM servers - for (Pair pair : scmToAdd) { - String scmNodeId = pair.getLeft(); - final HostAndPort scmAddress = pair.getRight(); + for (ScmNodeAddress entry : scmToAdd) { + String scmNodeId = entry.getScmNodeId(); + final HostAndPort scmAddress = entry.getHostAndPort(); if (scmAddress.getAddress().isUnresolved()) { LOG.warn("Reconfiguration failed to add SCM address {} for SCM service {} since it can't " + "be resolved, skipping", scmAddress, scmServiceId); @@ -835,9 +835,9 @@ private String reconfigScmNodes(String value) { } // Remove the old SCM server - for (Pair pair : scmToRemove) { - String scmNodeId = pair.getLeft(); - final HostAndPort scmAddress = pair.getRight(); + for (ScmNodeAddress entry : scmToRemove) { + String scmNodeId = entry.getScmNodeId(); + final HostAndPort scmAddress = entry.getHostAndPort(); try { connectionManager.removeSCMServer(scmAddress); context.removeEndpoint(scmAddress); diff --git a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/checksum/ContainerMerkleTreeTestUtils.java b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/checksum/ContainerMerkleTreeTestUtils.java index 444ab7eef28..00ef375eb6a 100644 --- a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/checksum/ContainerMerkleTreeTestUtils.java +++ b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/checksum/ContainerMerkleTreeTestUtils.java @@ -36,7 +36,6 @@ import java.util.Map; import java.util.Random; import java.util.stream.Collectors; -import org.apache.commons.lang3.tuple.Pair; import org.apache.hadoop.hdds.client.BlockID; import org.apache.hadoop.hdds.conf.ConfigurationSource; import org.apache.hadoop.hdds.conf.OzoneConfiguration; @@ -183,9 +182,9 @@ public static List getDeletedBlockData(ConfigurationSource conf, long } /** - * Returns a Pair of merkle tree and the expected container diff for that merkle tree. + * Returns the merkle tree and expected diff for that tree. */ - public static Pair + public static ContainerDiffResult buildTestTreeWithMismatches(ContainerMerkleTreeWriter originalTree, int numMissingBlocks, int numMissingChunks, int numCorruptChunks) { @@ -196,7 +195,7 @@ public static List getDeletedBlockData(ConfigurationSource conf, long introduceMissingChunks(treeBuilder, numMissingChunks, diff); introduceCorruptChunks(treeBuilder, numCorruptChunks, diff); ContainerProtos.ContainerMerkleTree build = treeBuilder.build(); - return Pair.of(build, diff); + return new ContainerDiffResult(build, diff); } /** @@ -421,4 +420,34 @@ public static BlockData buildBlockData(ConfigurationSource config, long containe blockData.addChunk(buildChunk(config, 2, ByteBuffer.wrap(new byte[]{byteValue++, byteValue++, byteValue++}))); return blockData; } + + /** + * Result of building a test merkle tree with mismatches. + */ + public static final class ContainerDiffResult { + private final ContainerProtos.ContainerMerkleTree tree; + private final ContainerDiffReport diff; + + private ContainerDiffResult(ContainerProtos.ContainerMerkleTree tree, + ContainerDiffReport diff) { + this.tree = tree; + this.diff = diff; + } + + public ContainerProtos.ContainerMerkleTree getTree() { + return tree; + } + + public ContainerDiffReport getDiff() { + return diff; + } + + @Override + public String toString() { + return "ContainerDiffResult{" + + "tree=" + tree + + ", diff=" + diff + + '}'; + } + } } diff --git a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/checksum/TestContainerDiff.java b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/checksum/TestContainerDiff.java index c1331ab65bb..e5a341338ac 100644 --- a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/checksum/TestContainerDiff.java +++ b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/checksum/TestContainerDiff.java @@ -33,7 +33,6 @@ import java.util.Arrays; import java.util.List; import java.util.stream.Stream; -import org.apache.commons.lang3.tuple.Pair; import org.apache.hadoop.hdds.conf.ConfigurationSource; import org.apache.hadoop.hdds.conf.OzoneConfiguration; import org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos; @@ -106,10 +105,10 @@ public static Stream getContainerDiffMismatches() { public void testContainerDiffWithMismatches(int numMissingBlock, int numMissingChunk, int numCorruptChunk) throws Exception { ContainerMerkleTreeWriter peerMerkleTree = buildTestTree(config); - Pair buildResult = + ContainerMerkleTreeTestUtils.ContainerDiffResult buildResult = buildTestTreeWithMismatches(peerMerkleTree, numMissingBlock, numMissingChunk, numCorruptChunk); - ContainerDiffReport expectedDiff = buildResult.getRight(); - ContainerProtos.ContainerMerkleTree ourMerkleTree = buildResult.getLeft(); + ContainerDiffReport expectedDiff = buildResult.getDiff(); + ContainerProtos.ContainerMerkleTree ourMerkleTree = buildResult.getTree(); updateTreeProto(container, ourMerkleTree); ContainerProtos.ContainerChecksumInfo peerChecksumInfo = ContainerProtos.ContainerChecksumInfo.newBuilder() .setContainerID(container.getContainerID()) @@ -134,9 +133,9 @@ public void testContainerDiffWithMismatches(int numMissingBlock, int numMissingC public void testPeerWithMismatchesHasNoDiff(int numMissingBlock, int numMissingChunk, int numCorruptChunk) throws Exception { ContainerMerkleTreeWriter ourMerkleTree = buildTestTree(config); - Pair buildResult = + ContainerMerkleTreeTestUtils.ContainerDiffResult buildResult = buildTestTreeWithMismatches(ourMerkleTree, numMissingBlock, numMissingChunk, numCorruptChunk); - ContainerProtos.ContainerMerkleTree peerMerkleTree = buildResult.getLeft(); + ContainerProtos.ContainerMerkleTree peerMerkleTree = buildResult.getTree(); checksumManager.updateTree(container, ourMerkleTree); ContainerProtos.ContainerChecksumInfo peerChecksumInfo = ContainerProtos.ContainerChecksumInfo.newBuilder() .setContainerID(container.getContainerID()) @@ -173,7 +172,7 @@ void testContainerDiffWithBlockDeletionInPeer() throws Exception { // Create only 5 blocks in our tree. The peer has 5 more blocks that it has deleted. ContainerMerkleTreeWriter dummy = buildTestTree(config, 5); // Introduce block corruption in our merkle tree. - ContainerProtos.ContainerMerkleTree ourMerkleTree = buildTestTreeWithMismatches(dummy, 3, 3, 3).getLeft(); + ContainerProtos.ContainerMerkleTree ourMerkleTree = buildTestTreeWithMismatches(dummy, 3, 3, 3).getTree(); ContainerProtos.ContainerChecksumInfo.Builder peerChecksumInfoBuilder = ContainerProtos.ContainerChecksumInfo .newBuilder() @@ -217,7 +216,7 @@ void testDeletedBlocksInPeerAndBoth() throws Exception { ContainerProtos.ContainerMerkleTree peerMerkleTree = buildTestTree(config, 5, 1, 2, 3, 4, 5); // Introduce missing blocks in our merkle tree ContainerProtos.ContainerMerkleTree ourMerkleTree = - buildTestTreeWithMismatches(new ContainerMerkleTreeWriter(peerMerkleTree), 3, 0, 0).getLeft(); + buildTestTreeWithMismatches(new ContainerMerkleTreeWriter(peerMerkleTree), 3, 0, 0).getTree(); // List deletedBlockList = new ArrayList<>(); // List blockIDs = Arrays.asList(1L, 2L, 3L, 4L, 5L); @@ -262,7 +261,7 @@ void testDeletedBlocksInOurContainerOnly() throws Exception { // Setup deleted blocks only in the peer container checksum ContainerMerkleTreeWriter peerMerkleTree = buildTestTree(config); // Introduce block corruption in our merkle tree. - ContainerProtos.ContainerMerkleTree ourMerkleTree = buildTestTreeWithMismatches(peerMerkleTree, 0, 3, 3).getLeft(); + ContainerProtos.ContainerMerkleTree ourMerkleTree = buildTestTreeWithMismatches(peerMerkleTree, 0, 3, 3).getTree(); ContainerProtos.ContainerChecksumInfo peerChecksumInfo = ContainerProtos.ContainerChecksumInfo .newBuilder().setContainerMerkleTree(peerMerkleTree.toProto()).setContainerID(CONTAINER_ID).build(); @@ -289,7 +288,7 @@ void testCorruptionInOurMerkleTreeAndDeletedBlocksInPeer() throws Exception { ContainerProtos.ContainerMerkleTree peerMerkleTree = buildTestTree(config, 5, 1, 2, 3, 4, 5); // Create our tree the same as the peer, but introduce corruption instead of deleting blocks. ContainerProtos.ContainerMerkleTree ourMerkleTree = - buildTestTreeWithMismatches(buildTestTree(config, 5), 0, 3, 3).getLeft(); + buildTestTreeWithMismatches(buildTestTree(config, 5), 0, 3, 3).getTree(); ContainerProtos.ContainerChecksumInfo peerChecksumInfo = ContainerProtos.ContainerChecksumInfo .newBuilder() diff --git a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/scm/client/ScmClient.java b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/scm/client/ScmClient.java index cb4b8471a00..febec213df6 100644 --- a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/scm/client/ScmClient.java +++ b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/scm/client/ScmClient.java @@ -23,7 +23,6 @@ import java.util.Map; import java.util.Optional; import java.util.UUID; -import org.apache.commons.lang3.tuple.Pair; import org.apache.hadoop.hdds.annotation.InterfaceStability; import org.apache.hadoop.hdds.client.ReplicationConfig; import org.apache.hadoop.hdds.protocol.DatanodeDetails; @@ -34,6 +33,7 @@ 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.SafeModeRuleStatus; import org.apache.hadoop.hdds.scm.container.ContainerID; import org.apache.hadoop.hdds.scm.container.ContainerInfo; import org.apache.hadoop.hdds.scm.container.ContainerListResult; @@ -342,7 +342,7 @@ Pipeline createReplicationPipeline(HddsProtos.ReplicationType type, * @return map of rule statuses. * @throws IOException */ - Map> getSafeModeRuleStatuses() + Map getSafeModeRuleStatuses() throws IOException; /** diff --git a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/scm/protocol/StorageContainerLocationProtocol.java b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/scm/protocol/StorageContainerLocationProtocol.java index 98f8efa9ae3..3c857e97fe5 100644 --- a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/scm/protocol/StorageContainerLocationProtocol.java +++ b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/scm/protocol/StorageContainerLocationProtocol.java @@ -27,7 +27,6 @@ import java.util.Optional; import java.util.Set; import java.util.UUID; -import org.apache.commons.lang3.tuple.Pair; import org.apache.hadoop.hdds.client.ReplicationConfig; import org.apache.hadoop.hdds.protocol.DatanodeDetails; import org.apache.hadoop.hdds.protocol.proto.HddsProtos; @@ -38,6 +37,7 @@ 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.SafeModeRuleStatus; import org.apache.hadoop.hdds.scm.ScmConfig; import org.apache.hadoop.hdds.scm.ScmInfo; import org.apache.hadoop.hdds.scm.container.ContainerID; @@ -395,7 +395,6 @@ List getFailedDeletedBlockTxn(int count, @Deprecated int resetDeletedBlockRetryCount(List txIDs) throws IOException; - /** * Get deleted block summary. * @throws IOException @@ -411,7 +410,7 @@ List getFailedDeletedBlockTxn(int count, */ boolean inSafeMode() throws IOException; - Map> getSafeModeRuleStatuses() + Map getSafeModeRuleStatuses() 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 7808cb286a2..c3d030e4664 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 @@ -37,7 +37,6 @@ import java.util.UUID; import java.util.function.Consumer; import java.util.stream.Collectors; -import org.apache.commons.lang3.tuple.Pair; import org.apache.hadoop.hdds.annotation.InterfaceAudience; import org.apache.hadoop.hdds.client.ECReplicationConfig; import org.apache.hadoop.hdds.client.ReplicatedReplicationConfig; @@ -131,6 +130,7 @@ import org.apache.hadoop.hdds.protocol.proto.StorageContainerLocationProtocolProtos.SuppressContainerResponseProto; import org.apache.hadoop.hdds.protocol.proto.StorageContainerLocationProtocolProtos.Type; import org.apache.hadoop.hdds.scm.DatanodeAdminError; +import org.apache.hadoop.hdds.scm.SafeModeRuleStatus; import org.apache.hadoop.hdds.scm.ScmInfo; import org.apache.hadoop.hdds.scm.container.ContainerID; import org.apache.hadoop.hdds.scm.container.ContainerInfo; @@ -881,7 +881,7 @@ public boolean inSafeMode() throws IOException { } @Override - public Map> getSafeModeRuleStatuses() + public Map getSafeModeRuleStatuses() throws IOException { GetSafeModeRuleStatusesRequestProto request = GetSafeModeRuleStatusesRequestProto.getDefaultInstance(); @@ -896,12 +896,12 @@ public Map> getSafeModeRuleStatuses() * Helper method to build a map from GetSafeModeRuleStatusesResponseProto. * Extracts rule names and their status information. */ - private Map> buildSafeModeRuleStatusesMap( + private Map buildSafeModeRuleStatusesMap( GetSafeModeRuleStatusesResponseProto response) { - Map> ruleStatuses = new HashMap<>(); + Map ruleStatuses = new HashMap<>(); for (SafeModeRuleStatusProto statusProto : response.getSafeModeRuleStatusesProtoList()) { ruleStatuses.put(statusProto.getRuleName(), - Pair.of(statusProto.getValidate(), statusProto.getStatusText())); + new SafeModeRuleStatus(statusProto.getValidate(), statusProto.getStatusText())); } return ruleStatuses; } diff --git a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/authority/profile/DefaultProfile.java b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/authority/profile/DefaultProfile.java index 7749ac99dd8..4769b943b72 100644 --- a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/authority/profile/DefaultProfile.java +++ b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/security/x509/certificate/authority/profile/DefaultProfile.java @@ -22,7 +22,6 @@ import java.net.InetAddress; import java.net.UnknownHostException; -import java.util.AbstractMap.SimpleEntry; import java.util.Arrays; import java.util.BitSet; import java.util.HashSet; @@ -66,6 +65,7 @@ public class DefaultProfile implements PKIProfile { VALIDATE_SAN = DefaultProfile::validateSubjectAlternativeName; private static final BiPredicate VALIDATE_EXTENDED_KEY_USAGE = DefaultProfile::validateExtendedKeyUsage; + // If we decide to add more General Names, we should add those here and // also update the logic in validateGeneralName function. private static final int[] GENERAL_NAMES = { @@ -76,11 +76,11 @@ public class DefaultProfile implements PKIProfile { // Map that handles all the Extensions lookup and validations. protected static final Map> EXTENSIONS_MAP = Stream.of( - new SimpleEntry<>(Extension.keyUsage, VALIDATE_KEY_USAGE), - new SimpleEntry<>(Extension.subjectAlternativeName, VALIDATE_SAN), - new SimpleEntry<>(Extension.authorityKeyIdentifier, + new ExtensionValidator(Extension.keyUsage, VALIDATE_KEY_USAGE), + new ExtensionValidator(Extension.subjectAlternativeName, VALIDATE_SAN), + new ExtensionValidator(Extension.authorityKeyIdentifier, VALIDATE_AUTHORITY_KEY_IDENTIFIER), - new SimpleEntry<>(Extension.extendedKeyUsage, + new ExtensionValidator(Extension.extendedKeyUsage, VALIDATE_EXTENDED_KEY_USAGE), // Ozone certs are issued only for the use of Ozone. // However, some users will discover that this is a full scale CA @@ -89,9 +89,9 @@ public class DefaultProfile implements PKIProfile { // the Ozone Logo inside these certs. So if a browser is used to // connect these logos will show up. // https://www.ietf.org/rfc/rfc3709.txt - new SimpleEntry<>(Extension.logoType, VALIDATE_LOGO_TYPE)) - .collect(Collectors.toMap(SimpleEntry::getKey, - SimpleEntry::getValue)); + new ExtensionValidator(Extension.logoType, VALIDATE_LOGO_TYPE)) + .collect(Collectors.toMap(ExtensionValidator::getExtension, + ExtensionValidator::getValidator)); // If we decide to add more General Names, we should add those here and // also update the logic in validateGeneralName function. private static final KeyPurposeId[] EXTENDED_KEY_USAGE = { @@ -102,6 +102,55 @@ public class DefaultProfile implements PKIProfile { private final Set extendKeyPurposeSet; private final Set generalNameSet; + /** + * A certificate extension and the validator used for it. + */ + private static final class ExtensionValidator { + + private final ASN1ObjectIdentifier extension; + private final BiPredicate validator; + + private ExtensionValidator(ASN1ObjectIdentifier extension, + BiPredicate validator) { + this.extension = extension; + this.validator = validator; + } + + private ASN1ObjectIdentifier getExtension() { + return extension; + } + + private BiPredicate getValidator() { + return validator; + } + + @Override + public boolean equals(Object other) { + if (this == other) { + return true; + } + if (!(other instanceof ExtensionValidator)) { + return false; + } + ExtensionValidator that = (ExtensionValidator) other; + return Objects.equals(extension, that.extension) + && Objects.equals(validator, that.validator); + } + + @Override + public int hashCode() { + return Objects.hash(extension, validator); + } + + @Override + public String toString() { + return "ExtensionValidator{" + + "extension=" + extension + + ", validator=" + validator + + '}'; + } + } + /** * Construct DefaultProfile. */ diff --git a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/utils/HddsServerUtil.java b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/utils/HddsServerUtil.java index 49a71025c76..66de4063588 100644 --- a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/utils/HddsServerUtil.java +++ b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/utils/HddsServerUtil.java @@ -85,7 +85,7 @@ import org.apache.commons.compress.archivers.tar.TarArchiveEntry; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.SystemUtils; -import org.apache.commons.lang3.tuple.Pair; +import org.apache.commons.validator.routines.InetAddressValidator; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hdds.HddsConfigKeys; import org.apache.hadoop.hdds.HddsUtils; @@ -435,7 +435,6 @@ public static long getStaleNodeInterval(ConfigurationSource conf) { long heartbeatIntervalMs = getScmHeartbeatInterval(conf); - // Make sure that StaleNodeInterval is configured way above the frequency // at which we run the heartbeat thread. // @@ -926,9 +925,10 @@ public static Collection getSCMAddressForDatanodes(ConfigurationSou * Null if there is any wrongly configured SCM address. Note that the returned collection * might not be ordered the same way as the requested SCM node IDs */ - public static Collection> getSCMAddressForDatanodes( + public static Collection getSCMAddressForDatanodes( ConfigurationSource conf, String scmServiceId, Set scmNodeIds) { - Collection> scmNodeAddress = new HashSet<>(scmNodeIds.size()); + Collection scmNodeAddresses = + new HashSet<>(scmNodeIds.size()); for (String scmNodeId : scmNodeIds) { String addressKey = ConfUtils.addKeySuffixes( OZONE_SCM_ADDRESS_KEY, scmServiceId, scmNodeId); @@ -942,9 +942,10 @@ public static Collection> getSCMAddressForDatanodes( OZONE_SCM_DATANODE_ADDRESS_KEY, OZONE_SCM_DATANODE_PORT_KEY, OZONE_SCM_DATANODE_PORT_DEFAULT); - scmNodeAddress.add(Pair.of(scmNodeId, new HostAndPort(scmAddress, scmDatanodePort))); + scmNodeAddresses.add(new ScmNodeAddress( + scmNodeId, new HostAndPort(scmAddress, scmDatanodePort))); } - return scmNodeAddress; + return scmNodeAddresses; } /** diff --git a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/utils/ScmNodeAddress.java b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/utils/ScmNodeAddress.java new file mode 100644 index 00000000000..6c2c0300f16 --- /dev/null +++ b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/utils/ScmNodeAddress.java @@ -0,0 +1,69 @@ +/* + * 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.utils; + +import java.util.Objects; +import org.apache.hadoop.hdds.scm.net.HostAndPort; + +/** + * SCM node identifier and its datanode address. + */ +public final class ScmNodeAddress { + + private final String scmNodeId; + private final HostAndPort hostAndPort; + + public ScmNodeAddress(String scmNodeId, HostAndPort hostAndPort) { + this.scmNodeId = scmNodeId; + this.hostAndPort = hostAndPort; + } + + public String getScmNodeId() { + return scmNodeId; + } + + public HostAndPort getHostAndPort() { + return hostAndPort; + } + + @Override + public boolean equals(Object other) { + if (this == other) { + return true; + } + if (!(other instanceof ScmNodeAddress)) { + return false; + } + ScmNodeAddress that = (ScmNodeAddress) other; + return Objects.equals(scmNodeId, that.scmNodeId) + && Objects.equals(hostAndPort, that.hostAndPort); + } + + @Override + public int hashCode() { + return Objects.hash(scmNodeId, hostAndPort); + } + + @Override + public String toString() { + return "ScmNodeAddress{" + + "scmNodeId='" + scmNodeId + '\'' + + ", hostAndPort=" + hostAndPort + + '}'; + } +} diff --git a/hadoop-hdds/rocks-native/pom.xml b/hadoop-hdds/rocks-native/pom.xml index acd8dbefc85..e4fcd62d7fd 100644 --- a/hadoop-hdds/rocks-native/pom.xml +++ b/hadoop-hdds/rocks-native/pom.xml @@ -31,10 +31,6 @@ commons-io commons-io - - org.apache.commons - commons-lang3 - org.apache.ozone hdds-common @@ -52,6 +48,11 @@ org.slf4j slf4j-api + + org.apache.commons + commons-lang3 + test + diff --git a/hadoop-hdds/rocks-native/src/main/java/org/apache/hadoop/hdds/utils/NativeLibraryLoader.java b/hadoop-hdds/rocks-native/src/main/java/org/apache/hadoop/hdds/utils/NativeLibraryLoader.java index 39bb0b3ca56..d2e64a88f71 100644 --- a/hadoop-hdds/rocks-native/src/main/java/org/apache/hadoop/hdds/utils/NativeLibraryLoader.java +++ b/hadoop-hdds/rocks-native/src/main/java/org/apache/hadoop/hdds/utils/NativeLibraryLoader.java @@ -26,14 +26,12 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardCopyOption; -import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; import org.apache.commons.io.FileUtils; -import org.apache.commons.lang3.tuple.Pair; import org.apache.hadoop.ozone.util.ShutdownHookManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -128,9 +126,9 @@ public synchronized boolean loadLibrary(final String libraryName, final List, List> files = copyResourceFromJarToTemp(libraryName, dependentFiles); - if (files.getKey().isPresent()) { - System.load(files.getKey().get().getAbsolutePath()); + LoadedFiles files = copyResourceFromJarToTemp(libraryName, dependentFiles); + if (files.libraryFile.isPresent()) { + System.load(files.libraryFile.get().getAbsolutePath()); loaded = true; } } @@ -154,7 +152,7 @@ static InputStream getResourceStream(String libraryFileName) throws IOException .getResourceAsStream(libraryFileName); } - private Pair, List> copyResourceFromJarToTemp(final String libraryName, + private LoadedFiles copyResourceFromJarToTemp(final String libraryName, final List dependentFileNames) throws IOException { final String libraryFileName = getJniLibraryFileName(libraryName); @@ -162,7 +160,7 @@ private Pair, List> copyResourceFromJarToTemp(final String try { is = getResourceStream(libraryFileName); if (is == null) { - return Pair.of(Optional.empty(), null); + return new LoadedFiles(Optional.empty()); } final String nativeLibDir = @@ -174,7 +172,7 @@ private Pair, List> copyResourceFromJarToTemp(final String final Path tempPath = Files.createTempDirectory(dir.toPath(), libraryName); final File tempDir = tempPath.toFile(); if (!tempDir.exists()) { - return Pair.of(Optional.empty(), null); + return new LoadedFiles(Optional.empty()); } Path libPath = tempPath.resolve(libraryFileName); @@ -184,7 +182,6 @@ private Pair, List> copyResourceFromJarToTemp(final String libFile.deleteOnExit(); } - List dependentFiles = new ArrayList<>(); for (String fileName : dependentFileNames) { if (is != null) { is.close(); @@ -196,16 +193,26 @@ private Pair, List> copyResourceFromJarToTemp(final String if (file.exists()) { file.deleteOnExit(); } - dependentFiles.add(file); } ShutdownHookManager.get().addShutdownHook( () -> FileUtils.deleteQuietly(tempDir), LIBRARY_SHUTDOWN_HOOK_PRIORITY); - return Pair.of(Optional.of(libFile), dependentFiles); + return new LoadedFiles(Optional.of(libFile)); } finally { if (is != null) { is.close(); } } } + + /** + * The extracted library file. + */ + private static final class LoadedFiles { + private final Optional libraryFile; + + private LoadedFiles(Optional libraryFile) { + this.libraryFile = libraryFile; + } + } } diff --git a/hadoop-hdds/rocks-native/src/test/java/org/apache/hadoop/hdds/utils/db/TestManagedRawSSTFileIterator.java b/hadoop-hdds/rocks-native/src/test/java/org/apache/hadoop/hdds/utils/db/TestManagedRawSSTFileIterator.java index f7a700b172f..eca99f1c510 100644 --- a/hadoop-hdds/rocks-native/src/test/java/org/apache/hadoop/hdds/utils/db/TestManagedRawSSTFileIterator.java +++ b/hadoop-hdds/rocks-native/src/test/java/org/apache/hadoop/hdds/utils/db/TestManagedRawSSTFileIterator.java @@ -36,14 +36,13 @@ import java.util.stream.IntStream; import java.util.stream.Stream; import org.apache.commons.lang3.RandomStringUtils; -import org.apache.commons.lang3.tuple.Pair; import org.apache.hadoop.hdds.StringUtils; -import org.apache.hadoop.hdds.utils.NativeLibraryNotLoadedException; import org.apache.hadoop.hdds.utils.RocksTestUtils; import org.apache.hadoop.hdds.utils.db.managed.ManagedEnvOptions; import org.apache.hadoop.hdds.utils.db.managed.ManagedOptions; import org.apache.hadoop.hdds.utils.db.managed.ManagedSlice; import org.apache.hadoop.hdds.utils.db.managed.ManagedSstFileWriter; +import org.junit.jupiter.api.Assumptions; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Named; import org.junit.jupiter.api.condition.EnabledIfSystemProperty; @@ -62,13 +61,13 @@ class TestManagedRawSSTFileIterator { private Path tempDir; private File createSSTFileWithKeys( - TreeMap, String> keys) throws Exception { + TreeMap keys) throws Exception { File file = Files.createFile(tempDir.resolve("tmp_sst_file.sst")).toFile(); try (ManagedEnvOptions envOptions = new ManagedEnvOptions(); ManagedOptions managedOptions = new ManagedOptions(); ManagedSstFileWriter sstFileWriter = new ManagedSstFileWriter(envOptions, managedOptions)) { sstFileWriter.open(file.getAbsolutePath()); - for (Map.Entry, String> entry : keys.entrySet()) { + for (Map.Entry entry : keys.entrySet()) { if (entry.getKey().getValue() == 0) { sstFileWriter.delete(entry.getKey().getKey().getBytes(StandardCharsets.UTF_8)); } else { @@ -105,16 +104,18 @@ private static Stream keyValueFormatArgs() { } @BeforeAll - public static void init() throws NativeLibraryNotLoadedException { - ManagedRawSSTFileReader.loadLibrary(); + public static void init() { + Assumptions.assumeTrue( + ManagedRawSSTFileReader.tryLoadLibrary(), + "Rocks native tools library is not available"); } @ParameterizedTest @MethodSource("keyValueFormatArgs") public void testSSTDumpIteratorWithKeyFormat(String keyFormat, String valueFormat, IteratorType type) throws Exception { - TreeMap, String> keys = IntStream.range(0, 100).boxed().collect(Collectors.toMap( - i -> Pair.of(String.format(keyFormat, i), i % 2), + TreeMap keys = IntStream.range(0, 100).boxed().collect(Collectors.toMap( + i -> new KeySpec(String.format(keyFormat, i), i % 2), i -> i % 2 == 0 ? "" : String.format(valueFormat, i), (v1, v2) -> v2, TreeMap::new)); File file = createSSTFileWithKeys(keys); @@ -122,10 +123,10 @@ public void testSSTDumpIteratorWithKeyFormat(String keyFormat, String valueForma ManagedRawSSTFileReader reader = new ManagedRawSSTFileReader( options, file.getAbsolutePath(), 2 * 1024 * 1024)) { List> testBounds = RocksTestUtils.getTestingBounds(keys.keySet().stream() - .collect(Collectors.toMap(Pair::getKey, Pair::getValue, (v1, v2) -> v1, TreeMap::new))); + .collect(Collectors.toMap(KeySpec::getKey, KeySpec::getValue, (v1, v2) -> v1, TreeMap::new))); for (Optional keyStart : testBounds) { for (Optional keyEnd : testBounds) { - Map, String> expectedKeys = keys.entrySet().stream() + Map expectedKeys = keys.entrySet().stream() .filter(e -> keyStart.map(s -> e.getKey().getKey().compareTo(s) >= 0).orElse(true)) .filter(e -> keyEnd.map(s -> e.getKey().getKey().compareTo(s) < 0).orElse(true)) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (v1, v2) -> v1, TreeMap::new)); @@ -134,11 +135,11 @@ public void testSSTDumpIteratorWithKeyFormat(String keyFormat, String valueForma Optional upperBound = keyEnd.map(s -> new ManagedSlice(StringUtils.string2Bytes(s))); try (ManagedRawSSTFileIterator iterator = reader.newIterator(Function.identity(), lowerBound.orElse(null), upperBound.orElse(null), type)) { - Iterator, String>> expectedKeyItr = expectedKeys.entrySet().iterator(); + Iterator> expectedKeyItr = expectedKeys.entrySet().iterator(); while (iterator.hasNext()) { ManagedRawSSTFileIterator.KeyValue r = iterator.next(); assertTrue(expectedKeyItr.hasNext()); - Map.Entry, String> expectedKey = expectedKeyItr.next(); + Map.Entry expectedKey = expectedKeyItr.next(); String key = r.getKey() == null ? null : StringCodec.get().fromCodecBuffer(r.getKey()); assertEquals(type.readKey() ? expectedKey.getKey().getKey() : null, key); assertEquals(type.readValue() ? expectedKey.getValue() : null, @@ -154,4 +155,59 @@ public void testSSTDumpIteratorWithKeyFormat(String keyFormat, String valueForma } } } + + /** + * A key and sequence used to build test SST entries. + */ + private static final class KeySpec implements Comparable { + private final String key; + private final int value; + + KeySpec(String key, int value) { + this.key = key; + this.value = value; + } + + String getKey() { + return key; + } + + int getValue() { + return value; + } + + @Override + public int compareTo(KeySpec other) { + int keyComparison = key.compareTo(other.key); + if (keyComparison != 0) { + return keyComparison; + } + return Integer.compare(value, other.value); + } + + @Override + public boolean equals(Object other) { + if (this == other) { + return true; + } + if (!(other instanceof KeySpec)) { + return false; + } + KeySpec that = (KeySpec) other; + return value == that.value && java.util.Objects.equals(key, that.key); + } + + @Override + public int hashCode() { + return java.util.Objects.hash(key, value); + } + + @Override + public String toString() { + return "KeySpec{" + + "key='" + key + '\'' + + ", value=" + value + + '}'; + } + } } diff --git a/hadoop-hdds/rocksdb-checkpoint-differ/src/main/java/org/apache/ozone/rocksdiff/RocksDBCheckpointDiffer.java b/hadoop-hdds/rocksdb-checkpoint-differ/src/main/java/org/apache/ozone/rocksdiff/RocksDBCheckpointDiffer.java index 956a0caac7c..3935975f1cd 100644 --- a/hadoop-hdds/rocksdb-checkpoint-differ/src/main/java/org/apache/ozone/rocksdiff/RocksDBCheckpointDiffer.java +++ b/hadoop-hdds/rocksdb-checkpoint-differ/src/main/java/org/apache/ozone/rocksdiff/RocksDBCheckpointDiffer.java @@ -67,7 +67,6 @@ import java.util.stream.Stream; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.io.FilenameUtils; -import org.apache.commons.lang3.tuple.Pair; import org.apache.hadoop.hdds.StringUtils; import org.apache.hadoop.hdds.conf.ConfigurationSource; import org.apache.hadoop.hdds.protocol.proto.HddsProtos.CompactionLogEntryProto; @@ -1092,10 +1091,10 @@ public void pruneOlderSnapshotsWithCompactionHistory() { if (!shouldRun()) { return; } - Pair, List> fileNodeToKeyPair = + OlderFileNodes fileNodeToKeyPair = getOlderFileNodes(); - Set lastCompactionSstFiles = fileNodeToKeyPair.getLeft(); - List keysToRemove = fileNodeToKeyPair.getRight(); + Set lastCompactionSstFiles = fileNodeToKeyPair.lastCompactionSstFiles; + List keysToRemove = fileNodeToKeyPair.keysToRemove; Set sstFileNodesRemoved = pruneSstFileNodesFromDag(lastCompactionSstFiles); @@ -1117,7 +1116,7 @@ public void pruneOlderSnapshotsWithCompactionHistory() { * Returns the list of input files from the compaction entries which are * older than the maximum allowed in the compaction DAG. */ - private synchronized Pair, List> getOlderFileNodes() { + private synchronized OlderFileNodes getOlderFileNodes() { long compactionLogPruneStartTime = System.currentTimeMillis(); Set compactionNodes = new HashSet<>(); List keysToRemove = new ArrayList<>(); @@ -1146,7 +1145,7 @@ private synchronized Pair, List> getOlderFileNodes() { // TODO: Handle this properly before merging the PR. throw new RuntimeException(exception); } - return Pair.of(compactionNodes, keysToRemove); + return new OlderFileNodes(compactionNodes, keysToRemove); } private synchronized void removeKeyFromCompactionLogTable( @@ -1364,16 +1363,16 @@ public void pruneSstFileValues() { private void removeValueFromSSTFile(ManagedOptions options, String sstFilePath, File prunedFile) throws IOException { try (ManagedRawSSTFileReader sstFileReader = new ManagedRawSSTFileReader(options, sstFilePath, SST_READ_AHEAD_SIZE); - ManagedRawSSTFileIterator> itr = sstFileReader.newIterator( - keyValue -> Pair.of(keyValue.getKey(), keyValue.getType()), null, null, KEY_ONLY); + ManagedRawSSTFileIterator itr = sstFileReader.newIterator( + keyValue -> new CodecBufferType(keyValue.getKey(), keyValue.getType()), null, null, KEY_ONLY); RDBSstFileWriter sstFileWriter = new RDBSstFileWriter(prunedFile); CodecBuffer emptyCodecBuffer = CodecBuffer.getEmptyBuffer()) { while (itr.hasNext()) { - Pair keyValue = itr.next(); - if (keyValue.getValue() == 0) { - sstFileWriter.delete(keyValue.getKey()); + CodecBufferType keyValue = itr.next(); + if (keyValue.getType() == 0) { + sstFileWriter.delete(keyValue.getCodecBuffer()); } else { - sstFileWriter.put(keyValue.getKey(), emptyCodecBuffer); + sstFileWriter.put(keyValue.getCodecBuffer(), emptyCodecBuffer); } } } @@ -1463,4 +1462,65 @@ ConcurrentMap getInflightCompactions() { public SSTFilePruningMetrics getPruningMetrics() { return sstFilePruningMetrics; } + + /** + * SST files that belong to the older compaction level and their keys. + */ + private static final class OlderFileNodes { + private final Set lastCompactionSstFiles; + private final List keysToRemove; + + private OlderFileNodes(Set lastCompactionSstFiles, + List keysToRemove) { + this.lastCompactionSstFiles = lastCompactionSstFiles; + this.keysToRemove = keysToRemove; + } + } + + /** + * A codec buffer paired with its encoded value type. + */ + private static final class CodecBufferType { + private final CodecBuffer codecBuffer; + private final int type; + + private CodecBufferType(CodecBuffer codecBuffer, int type) { + this.codecBuffer = codecBuffer; + this.type = type; + } + + private CodecBuffer getCodecBuffer() { + return codecBuffer; + } + + private int getType() { + return type; + } + + @Override + public boolean equals(Object other) { + if (this == other) { + return true; + } + if (!(other instanceof CodecBufferType)) { + return false; + } + CodecBufferType that = (CodecBufferType) other; + return type == that.type + && Objects.equals(codecBuffer, that.codecBuffer); + } + + @Override + public int hashCode() { + return Objects.hash(codecBuffer, type); + } + + @Override + public String toString() { + return "CodecBufferType{" + + "codecBuffer=" + codecBuffer + + ", type=" + type + + '}'; + } + } } diff --git a/hadoop-hdds/rocksdb-checkpoint-differ/src/test/java/org/apache/hadoop/hdds/utils/db/TestSstFileSetReader.java b/hadoop-hdds/rocksdb-checkpoint-differ/src/test/java/org/apache/hadoop/hdds/utils/db/TestSstFileSetReader.java index 0d247fc26c1..48efda1dce3 100644 --- a/hadoop-hdds/rocksdb-checkpoint-differ/src/test/java/org/apache/hadoop/hdds/utils/db/TestSstFileSetReader.java +++ b/hadoop-hdds/rocksdb-checkpoint-differ/src/test/java/org/apache/hadoop/hdds/utils/db/TestSstFileSetReader.java @@ -36,7 +36,6 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; import java.util.stream.IntStream; -import org.apache.commons.lang3.tuple.Pair; import org.apache.hadoop.hdds.StringUtils; import org.apache.hadoop.hdds.utils.RocksTestUtils; import org.apache.hadoop.hdds.utils.db.managed.ManagedEnvOptions; @@ -121,7 +120,7 @@ private Map createKeys(int startRange, int endRange) { * @return Pair containing the complete sorted key map and list of SST file paths * @throws RocksDBException if there's an error during SST file creation */ - private Pair, List> createDummyData(int numberOfFiles) throws RocksDBException { + private DummyData createDummyData(int numberOfFiles) throws RocksDBException { List files = new ArrayList<>(); int numberOfKeysPerFile = 1000; TreeMap keys = @@ -139,7 +138,7 @@ private Pair, List> createDummyData(int numberO Path tmpSSTFile = createRandomSSTFile(fileKeys); files.add(tmpSSTFile); } - return Pair.of(keys, files); + return new DummyData(keys, files); } /** @@ -153,9 +152,9 @@ private Pair, List> createDummyData(int numberO @ValueSource(ints = {0, 1, 2, 3, 7, 10}) public void testGetKeyStream(int numberOfFiles) throws RocksDBException, CodecException { - Pair, List> data = createDummyData(numberOfFiles); - List files = data.getRight(); - SortedMap keys = data.getLeft(); + DummyData data = createDummyData(numberOfFiles); + List files = data.getFiles(); + SortedMap keys = data.getKeys(); // Getting every possible combination of 2 elements from the sampled keys. // Reading the sst file lying within the given bounds and // validating the keys read from the sst file. @@ -195,10 +194,10 @@ public void testGetKeyStream(int numberOfFiles) public void testGetKeyStreamWithTombstone(int numberOfFiles) throws RocksDBException, CodecException { assumeTrue(ManagedRawSSTFileReader.tryLoadLibrary()); - Pair, List> data = + DummyData data = createDummyData(numberOfFiles); - List files = data.getRight(); - SortedMap keys = data.getLeft(); + List files = data.getFiles(); + SortedMap keys = data.getKeys(); // Getting every possible combination of 2 elements from the sampled keys. // Reading the sst file lying within the given bounds and // validating the keys read from the sst file. @@ -360,4 +359,50 @@ public void testDuplicateKeyHandlingWithLatestFilePrecedence(int numberOfFiles) "Should have correct total number of distinct keys"); } + /** + * The keys and files used to simulate SST reader input. + */ + private static final class DummyData { + private final SortedMap keys; + private final List files; + + private DummyData(SortedMap keys, List files) { + this.keys = keys; + this.files = files; + } + + private SortedMap getKeys() { + return keys; + } + + private List getFiles() { + return files; + } + + @Override + public boolean equals(Object other) { + if (this == other) { + return true; + } + if (!(other instanceof DummyData)) { + return false; + } + DummyData that = (DummyData) other; + return java.util.Objects.equals(keys, that.keys) + && java.util.Objects.equals(files, that.files); + } + + @Override + public int hashCode() { + return java.util.Objects.hash(keys, files); + } + + @Override + public String toString() { + return "DummyData{" + + "keys=" + keys + + ", files=" + files + + '}'; + } + } } diff --git a/hadoop-hdds/rocksdb-checkpoint-differ/src/test/java/org/apache/ozone/rocksdiff/TestRocksDBCheckpointDiffer.java b/hadoop-hdds/rocksdb-checkpoint-differ/src/test/java/org/apache/ozone/rocksdiff/TestRocksDBCheckpointDiffer.java index 0fc2df2a596..799b7432e26 100644 --- a/hadoop-hdds/rocksdb-checkpoint-differ/src/test/java/org/apache/ozone/rocksdiff/TestRocksDBCheckpointDiffer.java +++ b/hadoop-hdds/rocksdb-checkpoint-differ/src/test/java/org/apache/ozone/rocksdiff/TestRocksDBCheckpointDiffer.java @@ -88,7 +88,6 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import org.apache.commons.lang3.RandomStringUtils; -import org.apache.commons.lang3.tuple.Pair; import org.apache.hadoop.hdds.StringUtils; import org.apache.hadoop.hdds.conf.ConfigurationSource; import org.apache.hadoop.hdds.utils.IOUtils; @@ -1610,7 +1609,6 @@ private static Stream casesGetSSTDiffListWithoutDB2() { ); } - /** * Test that backup SST files are pruned on loading previous compaction logs. */ @@ -1623,10 +1621,10 @@ public void testPruneSSTFileValues() throws Exception { assertEquals(0L, sstFilePruningMetrics.getCompactionsProcessed()); assertEquals(0L, sstFilePruningMetrics.getFilesRemovedTotal()); - List> keys = new ArrayList>(); - keys.add(Pair.of("key1", Integer.valueOf(1))); - keys.add(Pair.of("key2", Integer.valueOf(0))); - keys.add(Pair.of("key3", Integer.valueOf(1))); + List> keys = new ArrayList>(); + keys.add(new SstEntry<>("key1", Integer.valueOf(1))); + keys.add(new SstEntry<>("key2", Integer.valueOf(0))); + keys.add(new SstEntry<>("key3", Integer.valueOf(1))); String inputFile78 = "000078"; String inputFile73 = "000073"; @@ -1660,10 +1658,10 @@ public void testPruneSSTFileValues() throws Exception { MockedConstruction mockedRawSSTReader = Mockito.mockConstruction( ManagedRawSSTFileReader.class, (mock, context) -> { ManagedRawSSTFileIterator mockedRawSSTFileItr = mock(ManagedRawSSTFileIterator.class); - Iterator> keyItr = keys.stream().map(i -> { + Iterator keyItr = keys.stream().map(i -> { keyCodecBuffer.clear(); keyCodecBuffer.put(ByteBuffer.wrap(i.getKey().getBytes(UTF_8))); - return Pair.of(keyCodecBuffer, i.getValue()); + return createCodecBufferType(keyCodecBuffer, i.getValue()); }).iterator(); doAnswer(i -> keyItr.hasNext()).when(mockedRawSSTFileItr).hasNext(); doAnswer(i -> keyItr.next()).when(mockedRawSSTFileItr).next(); @@ -1714,12 +1712,12 @@ public void testPruneSSTFileValues() throws Exception { assertEquals(1L, sstFilePruningMetrics.getFilesRemovedTotal()); } - private void createSSTFileWithKeys(File file, List> keys) throws RocksDatabaseException { + private void createSSTFileWithKeys(File file, List> keys) throws RocksDatabaseException { byte[] value = "dummyValue".getBytes(UTF_8); try (RDBSstFileWriter sstFileWriter = new RDBSstFileWriter(file)) { - Iterator> itr = keys.iterator(); + Iterator> itr = keys.iterator(); while (itr.hasNext()) { - Pair entry = itr.next(); + SstEntry entry = itr.next(); if (entry.getValue() == 0) { sstFileWriter.delete(entry.getKey().getBytes(UTF_8)); } else { @@ -1729,6 +1727,19 @@ private void createSSTFileWithKeys(File file, List> keys) } } + private static Object createCodecBufferType(CodecBuffer keyCodecBuffer, int type) { + try { + Class codecBufferTypeClass = Class.forName( + "org.apache.ozone.rocksdiff.RocksDBCheckpointDiffer$CodecBufferType"); + java.lang.reflect.Constructor ctor = codecBufferTypeClass + .getDeclaredConstructor(CodecBuffer.class, int.class); + ctor.setAccessible(true); + return ctor.newInstance(keyCodecBuffer, type); + } catch (ReflectiveOperationException e) { + throw new RuntimeException("Failed to create CodecBufferType for test", e); + } + } + /** * Tests core SST diff list logic. Does not involve DB. * Focuses on testing edge cases in internalGetSSTDiffList(). @@ -1958,4 +1969,51 @@ public void testShouldSkipFile(String description, assertEquals(expectedResult, rocksDBCheckpointDiffer .shouldSkipCompaction(columnFamilyBytes, inputFiles, outputFiles)); } + + /** + * A simple key/value pair used in checkpoint differ tests. + */ + private static final class SstEntry { + private final K key; + private final V value; + + private SstEntry(K key, V value) { + this.key = key; + this.value = value; + } + + private K getKey() { + return key; + } + + private V getValue() { + return value; + } + + @Override + public boolean equals(Object other) { + if (this == other) { + return true; + } + if (!(other instanceof SstEntry)) { + return false; + } + SstEntry that = (SstEntry) other; + return java.util.Objects.equals(key, that.key) + && java.util.Objects.equals(value, that.value); + } + + @Override + public int hashCode() { + return java.util.Objects.hash(key, value); + } + + @Override + public String toString() { + return "SstEntry{" + + "key=" + key + + ", value=" + value + + '}'; + } + } } diff --git a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/replication/ECUnderReplicationHandler.java b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/replication/ECUnderReplicationHandler.java index 5d41952b58e..7c8b444f1bc 100644 --- a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/replication/ECUnderReplicationHandler.java +++ b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/replication/ECUnderReplicationHandler.java @@ -29,9 +29,9 @@ import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.stream.Collectors; -import org.apache.commons.lang3.tuple.Pair; import org.apache.hadoop.hdds.client.ECReplicationConfig; import org.apache.hadoop.hdds.conf.ConfigurationSource; import org.apache.hadoop.hdds.conf.StorageUnit; @@ -144,10 +144,10 @@ public int processAndSendCommands( } } - Map> sources = + Map sources = filterSources(replicas, deletionInFlight); List availableSourceNodes = - sources.values().stream().map(Pair::getLeft) + sources.values().stream().map(SourceReplica::getReplica) .map(ContainerReplica::getDatanodeDetails) .filter(datanodeDetails -> datanodeDetails.getPersistedOpState() == @@ -229,7 +229,7 @@ public int processAndSendCommands( return commandsSent; } - private Map> filterSources( + private Map filterSources( Set replicas, List deletionInFlight) { return replicas.stream().filter(r -> r .getState() == State.CLOSED) @@ -239,14 +239,14 @@ private Map> filterSources( .filter(r -> !deletionInFlight.contains(r.getDatanodeDetails())) .map(r -> { try { - return Pair.of(r, + return new SourceReplica(r, replicationManager.getNodeStatus(r.getDatanodeDetails())); } catch (NodeNotFoundException e) { throw new IllegalStateException("Unable to find NodeStatus for " + r.getDatanodeDetails(), e); } }) - .filter(pair -> pair.getRight().isHealthy()) + .filter(sourceReplica -> sourceReplica.getNodeStatus().isHealthy()) // If there are multiple nodes online for a given index, we just // pick any IN_SERVICE one. At the moment, the input streams cannot // handle multiple replicas for the same index, so if we passed them @@ -254,13 +254,13 @@ private Map> filterSources( // If neither of the nodes are in service, we just pass one through, // as it will be decommission or maintenance. .collect(Collectors.toMap( - pair -> pair.getLeft().getReplicaIndex(), - pair -> pair, - (p1, p2) -> { - if (p1.getRight().getOperationalState() == IN_SERVICE) { - return p1; + sourceReplica -> sourceReplica.getReplica().getReplicaIndex(), + sourceReplica -> sourceReplica, + (first, second) -> { + if (first.getNodeStatus().getOperationalState() == IN_SERVICE) { + return first; } else { - return p2; + return second; } })); } @@ -272,7 +272,7 @@ private Map> filterSources( */ private int processMissingIndexes( ECContainerReplicaCount replicaCount, Map> sources, + SourceReplica> sources, List availableSourceNodes, List excludedNodes, List usedNodes) throws IOException { @@ -353,12 +353,12 @@ private int processMissingIndexes( availableSourceNodes.addAll(selectedDatanodes); List sourceDatanodesWithIndex = new ArrayList<>(); - for (Pair src : sources.values()) { + for (SourceReplica src : sources.values()) { sourceDatanodesWithIndex.add( new ReconstructECContainersCommand .DatanodeDetailsAndReplicaIndex( - src.getLeft().getDatanodeDetails(), - src.getLeft().getReplicaIndex())); + src.getReplica().getDatanodeDetails(), + src.getReplica().getReplicaIndex())); } final ReconstructECContainersCommand reconstructionCommand = @@ -421,7 +421,7 @@ private List getTargetDatanodes( */ private int processDecommissioningIndexes( ECContainerReplicaCount replicaCount, - Map> sources, + Map sources, List availableSourceNodes, List excludedNodes, List usedNodes) throws IOException { @@ -451,19 +451,19 @@ private int processDecommissioningIndexes( // In this case we need to do one to one copy. CommandTargetOverloadedException overloadedException = null; for (Integer decomIndex : decomIndexes) { - Pair source = sources.get(decomIndex); + SourceReplica source = sources.get(decomIndex); if (source == null) { LOG.warn("Cannot find source replica for decommissioning index " + "{} in container {}", decomIndex, container.containerID()); continue; } - ContainerReplica sourceReplica = source.getLeft(); + ContainerReplica sourceReplica = source.getReplica(); if (!iterator.hasNext()) { LOG.warn("Couldn't find enough targets. Available source" + " nodes: {}, the target nodes: {}, excluded nodes: {}," + " usedNodes: {}, and the decommission indexes: {}", sources.values().stream() - .map(Pair::getLeft).collect(Collectors.toSet()), + .map(SourceReplica::getReplica).collect(Collectors.toSet()), selectedDatanodes, excludedNodes, usedNodes, decomIndexes); break; } @@ -508,7 +508,7 @@ private int processDecommissioningIndexes( */ private int processMaintenanceOnlyIndexes( ECContainerReplicaCount replicaCount, - Map> sources, + Map sources, List excludedNodes, List usedNodes) throws IOException { Set maintIndexes = replicaCount.maintenanceOnlyIndexes(true); @@ -542,20 +542,20 @@ private int processMaintenanceOnlyIndexes( if (additionalMaintenanceCopiesNeeded <= 0) { break; } - Pair source = sources.get(maintIndex); + SourceReplica source = sources.get(maintIndex); if (source == null) { LOG.warn("Cannot find source replica for maintenance index " + "{} in container {}", maintIndex, container.containerID()); continue; } - ContainerReplica sourceReplica = source.getLeft(); + ContainerReplica sourceReplica = source.getReplica(); if (!iterator.hasNext()) { LOG.warn("Couldn't find enough targets. Available source" + " nodes: {}, target nodes: {}, excluded nodes: {}," + " usedNodes: {} and" + " maintenance indexes: {}", sources.values().stream() - .map(Pair::getLeft).collect(Collectors.toSet()), + .map(SourceReplica::getReplica).collect(Collectors.toSet()), targets, excludedNodes, usedNodes, maintIndexes); break; } @@ -715,4 +715,51 @@ private void checkAndRemoveUnhealthyReplica( } } + /** + * A source replica and the status of the node that hosts it. + */ + private static final class SourceReplica { + private final ContainerReplica replica; + private final NodeStatus nodeStatus; + + private SourceReplica(ContainerReplica replica, NodeStatus nodeStatus) { + this.replica = replica; + this.nodeStatus = nodeStatus; + } + + private ContainerReplica getReplica() { + return replica; + } + + private NodeStatus getNodeStatus() { + return nodeStatus; + } + + @Override + public boolean equals(Object other) { + if (this == other) { + return true; + } + if (!(other instanceof SourceReplica)) { + return false; + } + SourceReplica that = (SourceReplica) other; + return Objects.equals(replica, that.replica) + && Objects.equals(nodeStatus, that.nodeStatus); + } + + @Override + public int hashCode() { + return Objects.hash(replica, nodeStatus); + } + + @Override + public String toString() { + return "SourceReplica{" + + "replica=" + replica + + ", nodeStatus=" + nodeStatus + + '}'; + } + } + } diff --git a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/replication/ReplicationManager.java b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/replication/ReplicationManager.java index f890fb6a082..e5e961474e8 100644 --- a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/replication/ReplicationManager.java +++ b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/replication/ReplicationManager.java @@ -34,13 +34,13 @@ import java.util.Comparator; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; -import org.apache.commons.lang3.tuple.Pair; import org.apache.hadoop.hdds.HddsConfigKeys; import org.apache.hadoop.hdds.client.ReplicationConfig; import org.apache.hadoop.hdds.conf.Config; @@ -516,7 +516,7 @@ public void sendThrottledReplicationCommand(ContainerInfo containerInfo, List sources, DatanodeDetails target, int replicaIndex) throws CommandTargetOverloadedException, NotLeaderException { long containerID = containerInfo.getContainerID(); - List> sourceWithCmds = + List sourceWithCmds = getAvailableDatanodesForReplication(sources); if (sourceWithCmds.isEmpty()) { metrics.incrReplicateContainerCmdsDeferredTotal(); @@ -537,7 +537,7 @@ public void sendThrottledReconstructionCommand(ContainerInfo containerInfo, ReconstructECContainersCommand command) throws CommandTargetOverloadedException, NotLeaderException { List targets = command.getTargetDatanodes(); - List> targetWithCmds = + List targetWithCmds = getAvailableDatanodesForReplication(targets); if (targetWithCmds.isEmpty()) { metrics.incrECReconstructionCmdsDeferredTotal(); @@ -550,14 +550,14 @@ public void sendThrottledReconstructionCommand(ContainerInfo containerInfo, } private DatanodeDetails selectAndOptionallyExcludeDatanode( - int additionalCmdCount, List> datanodes) { + int additionalCmdCount, List datanodes) { if (datanodes.isEmpty()) { return null; } // Put the least loaded datanode first - datanodes.sort(Comparator.comparingInt(Pair::getLeft)); - DatanodeDetails datanode = datanodes.get(0).getRight(); - int currentCount = datanodes.get(0).getLeft(); + datanodes.sort(Comparator.comparingInt(DatanodeCommandCount::getCommandCount)); + DatanodeDetails datanode = datanodes.get(0).getDatanodeDetails(); + int currentCount = datanodes.get(0).getCommandCount(); if (currentCount + additionalCmdCount >= getReplicationLimit(datanode)) { addExcludedNode(datanode); } @@ -574,9 +574,9 @@ private DatanodeDetails selectAndOptionallyExcludeDatanode( * @return List of datanodes with the current command count that are not over * the limit. */ - private List> + private List getAvailableDatanodesForReplication(List datanodes) { - List> datanodeWithCommandCount + List datanodeWithCommandCount = new ArrayList<>(); for (DatanodeDetails dn : datanodes) { try { @@ -589,7 +589,7 @@ private DatanodeDetails selectAndOptionallyExcludeDatanode( addExcludedNode(dn); continue; } - datanodeWithCommandCount.add(Pair.of(totalCount, dn)); + datanodeWithCommandCount.add(new DatanodeCommandCount(totalCount, dn)); } catch (NodeNotFoundException e) { LOG.error("Node {} not found in NodeManager. Should not happen", dn, e); @@ -598,6 +598,53 @@ private DatanodeDetails selectAndOptionallyExcludeDatanode( return datanodeWithCommandCount; } + /** + * A datanode and the number of commands currently scheduled for it. + */ + private static final class DatanodeCommandCount { + private final int commandCount; + private final DatanodeDetails datanodeDetails; + + private DatanodeCommandCount(int commandCount, DatanodeDetails datanodeDetails) { + this.commandCount = commandCount; + this.datanodeDetails = datanodeDetails; + } + + private int getCommandCount() { + return commandCount; + } + + private DatanodeDetails getDatanodeDetails() { + return datanodeDetails; + } + + @Override + public boolean equals(Object other) { + if (this == other) { + return true; + } + if (!(other instanceof DatanodeCommandCount)) { + return false; + } + DatanodeCommandCount that = (DatanodeCommandCount) other; + return commandCount == that.commandCount + && Objects.equals(datanodeDetails, that.datanodeDetails); + } + + @Override + public int hashCode() { + return Objects.hash(commandCount, datanodeDetails); + } + + @Override + public String toString() { + return "DatanodeCommandCount{" + + "commandCount=" + commandCount + + ", datanodeDetails=" + datanodeDetails + + '}'; + } + } + private int getQueuedReplicationCount(DatanodeDetails datanode) throws NodeNotFoundException { Map counts = nodeManager.getTotalDatanodeCommandCounts( diff --git a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/node/NodeDecommissionManager.java b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/node/NodeDecommissionManager.java index e279a63a4ae..7659607a0bc 100644 --- a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/node/NodeDecommissionManager.java +++ b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/node/NodeDecommissionManager.java @@ -29,12 +29,12 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; -import org.apache.commons.lang3.tuple.Pair; import org.apache.hadoop.hdds.HddsConfigKeys; import org.apache.hadoop.hdds.client.ECReplicationConfig; import org.apache.hadoop.hdds.conf.OzoneConfiguration; @@ -115,6 +115,53 @@ private void parseHostname() throws InvalidHostStringException { } } + /** + * A datanode and the timestamp of its last heartbeat. + */ + private static final class HeartbeatInfo { + private final DatanodeDetails datanodeDetails; + private final long lastHeartbeat; + + private HeartbeatInfo(DatanodeDetails datanodeDetails, long lastHeartbeat) { + this.datanodeDetails = datanodeDetails; + this.lastHeartbeat = lastHeartbeat; + } + + private DatanodeDetails getDatanodeDetails() { + return datanodeDetails; + } + + private long getLastHeartbeat() { + return lastHeartbeat; + } + + @Override + public boolean equals(Object other) { + if (this == other) { + return true; + } + if (!(other instanceof HeartbeatInfo)) { + return false; + } + HeartbeatInfo that = (HeartbeatInfo) other; + return lastHeartbeat == that.lastHeartbeat + && Objects.equals(datanodeDetails, that.datanodeDetails); + } + + @Override + public int hashCode() { + return Objects.hash(datanodeDetails, lastHeartbeat); + } + + @Override + public String toString() { + return "HeartbeatInfo{" + + "datanodeDetails=" + datanodeDetails + + ", lastHeartbeat=" + lastHeartbeat + + '}'; + } + } + private List mapHostnamesToDatanodes(List hosts, List errors) { List results = new LinkedList<>(); @@ -230,18 +277,18 @@ private DatanodeDetails findDnWithMostRecentHeartbeat( if (dns.size() < 2) { return dns.isEmpty() ? null : dns.get(0); } - List> dnsWithHeartbeat = dns.stream() - .map(dn -> Pair.of(dn, nodeManager.getLastHeartbeat(dn))) - .sorted(Comparator.comparingLong(Pair::getRight)) + List dnsWithHeartbeat = dns.stream() + .map(dn -> new HeartbeatInfo(dn, nodeManager.getLastHeartbeat(dn))) + .sorted(Comparator.comparingLong(HeartbeatInfo::getLastHeartbeat)) .collect(Collectors.toList()); // The last element should have the largest (newest) heartbeat. But also // check it is not identical to the last but 1 element, as then we cannot // determine which node to decommission. - Pair last = dnsWithHeartbeat.get( + HeartbeatInfo last = dnsWithHeartbeat.get( dnsWithHeartbeat.size() - 1); - if (last.getRight() > dnsWithHeartbeat.get( - dnsWithHeartbeat.size() - 2).getRight()) { - return last.getLeft(); + if (last.getLastHeartbeat() > dnsWithHeartbeat.get( + dnsWithHeartbeat.size() - 2).getLastHeartbeat()) { + return last.getDatanodeDetails(); } return null; } 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 00a9b6b3a0c..5faf4c5ea8d 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 @@ -38,7 +38,6 @@ import java.util.List; import java.util.Map; import java.util.Optional; -import org.apache.commons.lang3.tuple.Pair; import org.apache.hadoop.hdds.annotation.InterfaceAudience; import org.apache.hadoop.hdds.client.ECReplicationConfig; import org.apache.hadoop.hdds.client.ReplicationConfig; @@ -140,6 +139,7 @@ import org.apache.hadoop.hdds.protocol.proto.StorageContainerLocationProtocolProtos.SuppressContainerRequestProto; import org.apache.hadoop.hdds.protocol.proto.StorageContainerLocationProtocolProtos.SuppressContainerResponseProto; import org.apache.hadoop.hdds.scm.DatanodeAdminError; +import org.apache.hadoop.hdds.scm.SafeModeRuleStatus; import org.apache.hadoop.hdds.scm.ScmInfo; import org.apache.hadoop.hdds.scm.container.ContainerID; import org.apache.hadoop.hdds.scm.container.ContainerInfo; @@ -1057,13 +1057,13 @@ public InSafeModeResponseProto inSafeMode( public GetSafeModeRuleStatusesResponseProto getSafeModeRuleStatues( GetSafeModeRuleStatusesRequestProto request) throws IOException { - Map> + Map map = impl.getSafeModeRuleStatuses(); List proto = new ArrayList(); - for (Map.Entry> entry : map.entrySet()) { + for (Map.Entry entry : map.entrySet()) { proto.add(SafeModeRuleStatusProto.newBuilder().setRuleName(entry.getKey()) - .setValidate(entry.getValue().getLeft()) - .setStatusText(entry.getValue().getRight()) + .setValidate(entry.getValue().isValidated()) + .setStatusText(entry.getValue().getStatusText()) .build()); } return GetSafeModeRuleStatusesResponseProto.newBuilder() diff --git a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/safemode/SCMSafeModeManager.java b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/safemode/SCMSafeModeManager.java index b185f3a37fc..365bdc708ba 100644 --- a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/safemode/SCMSafeModeManager.java +++ b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/safemode/SCMSafeModeManager.java @@ -32,9 +32,9 @@ import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; -import org.apache.commons.lang3.tuple.Pair; import org.apache.hadoop.hdds.HddsConfigKeys; import org.apache.hadoop.hdds.conf.ConfigurationSource; +import org.apache.hadoop.hdds.scm.SafeModeRuleStatus; import org.apache.hadoop.hdds.scm.container.ContainerManager; import org.apache.hadoop.hdds.scm.ha.SCMContext; import org.apache.hadoop.hdds.scm.ha.SCMService.Event; @@ -271,11 +271,11 @@ public boolean getInSafeMode() { } /** Get the safe mode status of all rules. */ - public Map> getRuleStatus() { - Map> map = new HashMap<>(); + public Map getRuleStatus() { + Map map = new HashMap<>(); for (SafeModeExitRule exitRule : exitRules.values()) { map.put(exitRule.getRuleName(), - Pair.of(exitRule.validate(), exitRule.getStatusText())); + new SafeModeRuleStatus(exitRule.validate(), exitRule.getStatusText())); } return map; } 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 acb3e64a3ca..2fc6b21a22e 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 @@ -49,7 +49,6 @@ import java.util.UUID; import java.util.stream.Collectors; import java.util.stream.Stream; -import org.apache.commons.lang3.tuple.Pair; import org.apache.hadoop.fs.CommonConfigurationKeysPublic; import org.apache.hadoop.hdds.client.ReplicationConfig; import org.apache.hadoop.hdds.conf.OzoneConfiguration; @@ -71,6 +70,7 @@ import org.apache.hadoop.hdds.ratis.RatisHelper; import org.apache.hadoop.hdds.scm.DatanodeAdminError; import org.apache.hadoop.hdds.scm.FetchMetrics; +import org.apache.hadoop.hdds.scm.SafeModeRuleStatus; import org.apache.hadoop.hdds.scm.ScmInfo; import org.apache.hadoop.hdds.scm.container.ContainerID; import org.apache.hadoop.hdds.scm.container.ContainerInfo; @@ -1064,10 +1064,10 @@ public boolean inSafeMode() throws IOException { } @Override - public Map> getSafeModeRuleStatuses() + public Map getSafeModeRuleStatuses() throws IOException { try { - Map> result = scm.getRuleStatus(); + Map result = scm.getRuleStatus(); AUDIT.logReadSuccess(buildAuditMessageForSuccess( SCMAction.GET_SAFE_MODE_RULE_STATUSES, null)); return result; diff --git a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/server/StorageContainerManager.java b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/server/StorageContainerManager.java index 100c9feb9b6..b512266e35d 100644 --- a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/server/StorageContainerManager.java +++ b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/server/StorageContainerManager.java @@ -55,7 +55,6 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import javax.management.ObjectName; -import org.apache.commons.lang3.tuple.Pair; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hdds.HddsConfigKeys; import org.apache.hadoop.hdds.HddsUtils; @@ -72,6 +71,7 @@ import org.apache.hadoop.hdds.scm.PlacementPolicy; import org.apache.hadoop.hdds.scm.PlacementPolicyValidateProxy; import org.apache.hadoop.hdds.scm.RemoveSCMRequest; +import org.apache.hadoop.hdds.scm.SafeModeRuleStatus; import org.apache.hadoop.hdds.scm.ScmConfig; import org.apache.hadoop.hdds.scm.ScmConfigKeys; import org.apache.hadoop.hdds.scm.ScmInfo; @@ -918,7 +918,6 @@ private void initializeCAnSecurityProtocol(OzoneConfiguration conf, new SCMCertStore.Builder().setMetadaStore(scmMetadataStore) .setRatisServer(scmHAManager.getRatisServer()).build(); - final CertificateServer scmCertificateServer; final CertificateServer rootCertificateServer; @@ -1311,7 +1310,6 @@ public static boolean scmInit(OzoneConfiguration conf, scmStorageConfig.setClusterId(clusterId); } - if (OzoneSecurityUtil.isSecurityEnabled(conf)) { HASecurityUtils.initializeSecurity(scmStorageConfig, conf, getScmAddress(haDetails, conf).getHostName(), true); @@ -1425,7 +1423,6 @@ private static InetSocketAddress getScmAddress(SCMHANodeDetails haDetails, } } - return scmAddress; } @@ -2097,17 +2094,17 @@ public String getNamespace() { * * @return map of rule statuses. */ - public Map> getRuleStatus() { + public Map getRuleStatus() { return scmSafeModeManager.getRuleStatus(); } @Override public Map getSafeModeRuleStatus() { Map map = new HashMap<>(); - for (Map.Entry> entry : + for (Map.Entry entry : scmSafeModeManager.getRuleStatus().entrySet()) { String[] status = - {entry.getValue().getRight(), entry.getValue().getLeft().toString()}; + {entry.getValue().getStatusText(), Boolean.toString(entry.getValue().isValidated())}; map.put(entry.getKey(), status); } return map; diff --git a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/MisReplicationHandlerTests.java b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/MisReplicationHandlerTests.java index 4d3c42d84f4..353d102903a 100644 --- a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/MisReplicationHandlerTests.java +++ b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/MisReplicationHandlerTests.java @@ -44,7 +44,6 @@ import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.IntStream; -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; @@ -62,6 +61,7 @@ import org.apache.hadoop.ozone.container.common.SCMTestUtils; import org.apache.hadoop.ozone.protocol.commands.ReplicateContainerCommand; import org.apache.hadoop.ozone.protocol.commands.SCMCommand; +import org.apache.ozone.test.TestEntry; import org.apache.ratis.protocol.exceptions.NotLeaderException; /** @@ -72,7 +72,7 @@ public abstract class MisReplicationHandlerTests { private ContainerInfo container; private OzoneConfiguration conf; private ReplicationManager replicationManager; - private Set>> commandsSent; + private Set>> commandsSent; private final AtomicBoolean throwThrottledException = new AtomicBoolean(false); private ReplicationManagerMetrics metrics; @@ -221,14 +221,14 @@ protected void testMisReplication(Set availableReplicas, pendingOp, result, maintenanceCnt); } finally { assertEquals(expectedNumberOfCommands, commandsSent.size()); - for (Pair> pair : commandsSent) { - SCMCommand command = pair.getValue(); + for (TestEntry> commandEntry : commandsSent) { + SCMCommand command = commandEntry.getValue(); assertSame(replicateContainerCommand, command.getType()); ReplicateContainerCommand replicateContainerCommand = (ReplicateContainerCommand) command; assertEquals(replicateContainerCommand.getContainerID(), container.getContainerID()); - DatanodeDetails replicateSrcDn = pair.getKey(); + DatanodeDetails replicateSrcDn = commandEntry.getKey(); DatanodeDetails target = replicateContainerCommand.getTargetDatanode(); assertThat(sourceDns).contains(replicateSrcDn); assertThat(targetNodes).contains(target); diff --git a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/ReplicationTestUtil.java b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/ReplicationTestUtil.java index 63f4c6c9f33..c237805747a 100644 --- a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/ReplicationTestUtil.java +++ b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/ReplicationTestUtil.java @@ -33,7 +33,6 @@ import java.util.List; import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; -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.conf.StorageUnit; @@ -59,6 +58,7 @@ import org.apache.hadoop.ozone.protocol.commands.ReconstructECContainersCommand; import org.apache.hadoop.ozone.protocol.commands.ReplicateContainerCommand; import org.apache.hadoop.ozone.protocol.commands.SCMCommand; +import org.apache.ozone.test.TestEntry; import org.apache.ratis.protocol.exceptions.NotLeaderException; import org.mockito.stubbing.Answer; @@ -72,18 +72,18 @@ private ReplicationTestUtil() { @SafeVarargs public static Set createReplicas(ContainerID containerID, - Pair... nodes) { + TestEntry... nodes) { return createReplicas(containerID, CLOSED, nodes); } @SafeVarargs public static Set createReplicas(ContainerID containerID, ContainerReplicaProto.State replicaState, - Pair... nodes) { + TestEntry... nodes) { Set replicas = new HashSet<>(); - for (Pair p : nodes) { + for (TestEntry p : nodes) { replicas.add(createContainerReplica( - containerID, p.getRight(), p.getLeft(), replicaState)); + containerID, p.getValue(), p.getKey(), replicaState)); } return replicas; } @@ -151,12 +151,12 @@ public static ContainerReplica createEmptyContainerReplica(ContainerID container public static Set createReplicasWithOriginAndOpState( ContainerID containerID, ContainerReplicaProto.State replicaState, - Pair... nodes) { + TestEntry... nodes) { Set replicas = new HashSet<>(); - for (Pair i : nodes) { + for (TestEntry i : nodes) { replicas.add(createContainerReplica( - containerID, 0, i.getRight(), replicaState, 123L, 1234L, - MockDatanodeDetails.randomDatanodeDetails(), i.getLeft())); + containerID, 0, i.getValue(), replicaState, 123L, 1234L, + MockDatanodeDetails.randomDatanodeDetails(), i.getKey())); } return replicas; } @@ -291,7 +291,7 @@ public static ContainerInfo createContainer(HddsProtos.LifeCycleState state, @SafeVarargs public static Set createReplicas( - Pair... states) { + TestEntry... states) { return createReplicas(CLOSED, states); } @@ -299,11 +299,11 @@ public static Set createReplicas( @SafeVarargs public static Set createReplicas( ContainerReplicaProto.State replicaState, - Pair... states) { + TestEntry... states) { Set replica = new HashSet<>(); - for (Pair s : states) { - replica.add(createContainerReplica(ContainerID.valueOf(1), s.getRight(), - s.getLeft(), replicaState)); + for (TestEntry s : states) { + replica.add(createContainerReplica(ContainerID.valueOf(1), s.getValue(), + s.getKey(), replicaState)); } return replica; } @@ -447,7 +447,7 @@ public DatanodeDetails chooseNode(List healthyNodes) { * to false, instead of creating the replicate command. */ public static void mockRMSendThrottleReplicateCommand(ReplicationManager mock, - Set>> commandsSent, + Set>> commandsSent, AtomicBoolean throwOverloaded) throws NotLeaderException, CommandTargetOverloadedException { doAnswer((Answer) invocationOnMock -> { @@ -461,7 +461,7 @@ public static void mockRMSendThrottleReplicateCommand(ReplicationManager mock, .toTarget(containerInfo.getContainerID(), invocationOnMock.getArgument(2)); command.setReplicaIndex(invocationOnMock.getArgument(3)); - commandsSent.add(Pair.of(sources.get(0), command)); + commandsSent.add(new TestEntry<>(sources.get(0), command)); return null; }).when(mock).sendThrottledReplicationCommand( any(ContainerInfo.class), anyList(), any(DatanodeDetails.class), anyInt()); @@ -479,7 +479,7 @@ public static void mockRMSendThrottleReplicateCommand(ReplicationManager mock, */ public static void mockSendThrottledReconstructionCommand( ReplicationManager mock, - Set>> commandsSent, + Set>> commandsSent, AtomicBoolean throwOverloaded) throws NotLeaderException, CommandTargetOverloadedException { doAnswer((Answer) invocationOnMock -> { @@ -488,7 +488,7 @@ public static void mockSendThrottledReconstructionCommand( throw new CommandTargetOverloadedException("Overloaded"); } ReconstructECContainersCommand cmd = invocationOnMock.getArgument(1); - commandsSent.add(Pair.of(cmd.getTargetDatanodes().get(0), cmd)); + commandsSent.add(new TestEntry<>(cmd.getTargetDatanodes().get(0), cmd)); return null; }).when(mock).sendThrottledReconstructionCommand(any(ContainerInfo.class), any()); } @@ -501,12 +501,12 @@ public static void mockSendThrottledReconstructionCommand( * @param commandsSent Set to add the command to rather than sending it. */ public static void mockRMSendDatanodeCommand(ReplicationManager mock, - Set>> commandsSent) + Set>> commandsSent) throws NotLeaderException { doAnswer((Answer) invocationOnMock -> { DatanodeDetails target = invocationOnMock.getArgument(2); SCMCommand command = invocationOnMock.getArgument(0); - commandsSent.add(Pair.of(target, command)); + commandsSent.add(new TestEntry<>(target, command)); return null; }).when(mock).sendDatanodeCommand(any(), any(), any()); } @@ -519,7 +519,7 @@ public static void mockRMSendDatanodeCommand(ReplicationManager mock, * @param commandsSent Set to add the command to rather than sending it. */ public static void mockRMSendDeleteCommand(ReplicationManager mock, - Set>> commandsSent) + Set>> commandsSent) throws NotLeaderException { doAnswer((Answer) invocationOnMock -> { ContainerInfo containerInfo = invocationOnMock.getArgument(0); @@ -529,7 +529,7 @@ public static void mockRMSendDeleteCommand(ReplicationManager mock, DeleteContainerCommand deleteCommand = new DeleteContainerCommand( containerInfo.getContainerID(), forceDelete); deleteCommand.setReplicaIndex(replicaIndex); - commandsSent.add(Pair.of(target, deleteCommand)); + commandsSent.add(new TestEntry<>(target, deleteCommand)); return null; }).when(mock).sendDeleteCommand(any(), anyInt(), any(), anyBoolean()); } @@ -542,7 +542,7 @@ public static void mockRMSendDeleteCommand(ReplicationManager mock, * @param commandsSent Set to add the command to rather than sending it. */ public static void mockRMSendThrottledDeleteCommand(ReplicationManager mock, - Set>> commandsSent) + Set>> commandsSent) throws NotLeaderException, CommandTargetOverloadedException { mockRMSendThrottledDeleteCommand(mock, commandsSent, new AtomicBoolean(false)); } @@ -558,7 +558,7 @@ public static void mockRMSendThrottledDeleteCommand(ReplicationManager mock, * to false, instead of creating the replicate command. */ public static void mockRMSendThrottledDeleteCommand(ReplicationManager mock, - Set>> commandsSent, AtomicBoolean throwOverloaded) + Set>> commandsSent, AtomicBoolean throwOverloaded) throws NotLeaderException, CommandTargetOverloadedException { doAnswer((Answer) invocationOnMock -> { if (throwOverloaded.get()) { @@ -572,7 +572,7 @@ public static void mockRMSendThrottledDeleteCommand(ReplicationManager mock, DeleteContainerCommand deleteCommand = new DeleteContainerCommand( containerInfo.getContainerID(), forceDelete); deleteCommand.setReplicaIndex(replicaIndex); - commandsSent.add(Pair.of(target, deleteCommand)); + commandsSent.add(new TestEntry<>(target, deleteCommand)); return null; }).when(mock) .sendThrottledDeleteCommand(any(), anyInt(), any(), anyBoolean()); diff --git a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/TestECContainerReplicaCount.java b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/TestECContainerReplicaCount.java index bb31e9cb8e1..a738d17376f 100644 --- a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/TestECContainerReplicaCount.java +++ b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/TestECContainerReplicaCount.java @@ -38,13 +38,13 @@ import java.util.HashSet; import java.util.List; import java.util.Set; -import org.apache.commons.lang3.tuple.Pair; import org.apache.hadoop.hdds.client.ECReplicationConfig; 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.container.ContainerInfo; import org.apache.hadoop.hdds.scm.container.ContainerReplica; +import org.apache.ozone.test.TestEntry; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -66,9 +66,9 @@ public void setup() { @Test public void testPerfectlyReplicatedContainer() { Set replica = ReplicationTestUtil - .createReplicas(Pair.of(IN_SERVICE, 1), Pair.of(IN_SERVICE, 2), - Pair.of(IN_SERVICE, 3), Pair.of(IN_SERVICE, 4), - Pair.of(IN_SERVICE, 5)); + .createReplicas(new TestEntry<>(IN_SERVICE, 1), new TestEntry<>(IN_SERVICE, 2), + new TestEntry<>(IN_SERVICE, 3), new TestEntry<>(IN_SERVICE, 4), + new TestEntry<>(IN_SERVICE, 5)); ECContainerReplicaCount rcnt = new ECContainerReplicaCount(container, replica, Collections.emptyList(), 1); @@ -79,8 +79,8 @@ public void testPerfectlyReplicatedContainer() { @Test public void testContainerMissingReplica() { Set replica = ReplicationTestUtil - .createReplicas(Pair.of(IN_SERVICE, 1), Pair.of(IN_SERVICE, 2), - Pair.of(IN_SERVICE, 3), Pair.of(IN_SERVICE, 4)); + .createReplicas(new TestEntry<>(IN_SERVICE, 1), new TestEntry<>(IN_SERVICE, 2), + new TestEntry<>(IN_SERVICE, 3), new TestEntry<>(IN_SERVICE, 4)); ECContainerReplicaCount rcnt = new ECContainerReplicaCount(container, replica, Collections.emptyList(), 1); @@ -101,9 +101,9 @@ public void testContainerMissingReplica() { @Test public void testContainerMissingReplicaDueToPendingDelete() { Set replica = ReplicationTestUtil - .createReplicas(Pair.of(IN_SERVICE, 1), Pair.of(IN_SERVICE, 2), - Pair.of(IN_SERVICE, 3), Pair.of(IN_SERVICE, 4), - Pair.of(IN_SERVICE, 5)); + .createReplicas(new TestEntry<>(IN_SERVICE, 1), new TestEntry<>(IN_SERVICE, 2), + new TestEntry<>(IN_SERVICE, 3), new TestEntry<>(IN_SERVICE, 4), + new TestEntry<>(IN_SERVICE, 5)); List pending = getContainerReplicaOps(ImmutableList.of(), ImmutableList.of(1)); @@ -139,10 +139,10 @@ public void testUnderReplicationDueToUnhealthyReplica() { @Test public void testContainerExcessReplicasAndPendingDelete() { Set replica = ReplicationTestUtil - .createReplicas(Pair.of(IN_SERVICE, 1), Pair.of(IN_SERVICE, 2), - Pair.of(IN_SERVICE, 3), Pair.of(IN_SERVICE, 4), - Pair.of(IN_SERVICE, 5), Pair.of(IN_SERVICE, 1), - Pair.of(IN_SERVICE, 2)); + .createReplicas(new TestEntry<>(IN_SERVICE, 1), new TestEntry<>(IN_SERVICE, 2), + new TestEntry<>(IN_SERVICE, 3), new TestEntry<>(IN_SERVICE, 4), + new TestEntry<>(IN_SERVICE, 5), new TestEntry<>(IN_SERVICE, 1), + new TestEntry<>(IN_SERVICE, 2)); List pending = getContainerReplicaOps(ImmutableList.of(), ImmutableList.of(1, 2)); @@ -155,10 +155,10 @@ public void testContainerExcessReplicasAndPendingDelete() { @Test public void testUnderRepContainerWithExcessReplicasAndPendingDelete() { Set replica = ReplicationTestUtil - .createReplicas(Pair.of(IN_SERVICE, 1), Pair.of(IN_SERVICE, 2), - Pair.of(IN_SERVICE, 3), Pair.of(IN_SERVICE, 4), - Pair.of(IN_SERVICE, 5), Pair.of(IN_SERVICE, 1), - Pair.of(IN_SERVICE, 2)); + .createReplicas(new TestEntry<>(IN_SERVICE, 1), new TestEntry<>(IN_SERVICE, 2), + new TestEntry<>(IN_SERVICE, 3), new TestEntry<>(IN_SERVICE, 4), + new TestEntry<>(IN_SERVICE, 5), new TestEntry<>(IN_SERVICE, 1), + new TestEntry<>(IN_SERVICE, 2)); List pending = getContainerReplicaOps(ImmutableList.of(), ImmutableList.of(1, 2, 2)); @@ -173,9 +173,9 @@ public void testUnderRepContainerWithExcessReplicasAndPendingDelete() { @Test public void testContainerWithMaintenanceReplicasSufficientlyReplicated() { Set replica = ReplicationTestUtil - .createReplicas(Pair.of(IN_SERVICE, 1), Pair.of(IN_SERVICE, 2), - Pair.of(IN_SERVICE, 3), Pair.of(IN_MAINTENANCE, 4), - Pair.of(IN_MAINTENANCE, 5)); + .createReplicas(new TestEntry<>(IN_SERVICE, 1), new TestEntry<>(IN_SERVICE, 2), + new TestEntry<>(IN_SERVICE, 3), new TestEntry<>(IN_MAINTENANCE, 4), + new TestEntry<>(IN_MAINTENANCE, 5)); ECContainerReplicaCount rcnt = new ECContainerReplicaCount(container, replica, Collections.emptyList(), 0); @@ -192,10 +192,10 @@ public void testContainerWithMaintenanceReplicasSufficientlyReplicated() { @Test public void testOverReplicatedContainer() { Set replica = ReplicationTestUtil - .createReplicas(Pair.of(IN_SERVICE, 1), Pair.of(IN_SERVICE, 2), - Pair.of(IN_SERVICE, 3), Pair.of(IN_SERVICE, 4), - Pair.of(IN_SERVICE, 5), Pair.of(IN_SERVICE, 1), - Pair.of(IN_SERVICE, 2)); + .createReplicas(new TestEntry<>(IN_SERVICE, 1), new TestEntry<>(IN_SERVICE, 2), + new TestEntry<>(IN_SERVICE, 3), new TestEntry<>(IN_SERVICE, 4), + new TestEntry<>(IN_SERVICE, 5), new TestEntry<>(IN_SERVICE, 1), + new TestEntry<>(IN_SERVICE, 2)); List pending = getContainerReplicaOps(ImmutableList.of(), ImmutableList.of(1)); @@ -220,10 +220,10 @@ public void testOverReplicatedContainer() { @Test public void testOverReplicatedContainerFixedWithPendingDelete() { Set replica = ReplicationTestUtil - .createReplicas(Pair.of(IN_SERVICE, 1), Pair.of(IN_SERVICE, 2), - Pair.of(IN_SERVICE, 3), Pair.of(IN_SERVICE, 4), - Pair.of(IN_SERVICE, 5), Pair.of(IN_SERVICE, 1), - Pair.of(IN_SERVICE, 2)); + .createReplicas(new TestEntry<>(IN_SERVICE, 1), new TestEntry<>(IN_SERVICE, 2), + new TestEntry<>(IN_SERVICE, 3), new TestEntry<>(IN_SERVICE, 4), + new TestEntry<>(IN_SERVICE, 5), new TestEntry<>(IN_SERVICE, 1), + new TestEntry<>(IN_SERVICE, 2)); List pending = getContainerReplicaOps(ImmutableList.of(), ImmutableList.of(1)); @@ -243,10 +243,10 @@ public void testOverReplicatedContainerFixedWithPendingDelete() { @Test public void testOverReplicatedAndUnderReplicatedContainer() { Set replica = ReplicationTestUtil - .createReplicas(Pair.of(DECOMMISSIONING, 1), Pair.of(IN_SERVICE, 2), - Pair.of(IN_SERVICE, 3), Pair.of(IN_SERVICE, 4), - Pair.of(IN_SERVICE, 5), Pair.of(IN_SERVICE, 1), - Pair.of(IN_SERVICE, 2)); + .createReplicas(new TestEntry<>(DECOMMISSIONING, 1), new TestEntry<>(IN_SERVICE, 2), + new TestEntry<>(IN_SERVICE, 3), new TestEntry<>(IN_SERVICE, 4), + new TestEntry<>(IN_SERVICE, 5), new TestEntry<>(IN_SERVICE, 1), + new TestEntry<>(IN_SERVICE, 2)); // this copy of index 4 is unhealthy, so it should not cause over // replication of index 4 ContainerReplica unhealthyIndex4 = @@ -267,10 +267,10 @@ public void testOverReplicatedAndUnderReplicatedContainer() { @Test public void testAdditionalMaintenanceCopiesAllMaintenance() { Set replica = ReplicationTestUtil - .createReplicas(Pair.of(IN_MAINTENANCE, 1), - Pair.of(ENTERING_MAINTENANCE, 2), Pair.of(IN_MAINTENANCE, 3), - Pair.of(IN_MAINTENANCE, 4), Pair.of(IN_MAINTENANCE, 5), - Pair.of(IN_MAINTENANCE, 1)); + .createReplicas(new TestEntry<>(IN_MAINTENANCE, 1), + new TestEntry<>(ENTERING_MAINTENANCE, 2), new TestEntry<>(IN_MAINTENANCE, 3), + new TestEntry<>(IN_MAINTENANCE, 4), new TestEntry<>(IN_MAINTENANCE, 5), + new TestEntry<>(IN_MAINTENANCE, 1)); ECContainerReplicaCount rcnt = new ECContainerReplicaCount(container, replica, Collections.emptyList(), 1); @@ -294,9 +294,9 @@ public void testAdditionalMaintenanceCopiesAllMaintenance() { @Test public void testAdditionalMaintenanceCopiesAlreadyReplicated() { Set replica = ReplicationTestUtil - .createReplicas(Pair.of(IN_SERVICE, 1), Pair.of(IN_SERVICE, 2), - Pair.of(IN_SERVICE, 3), Pair.of(IN_SERVICE, 4), - Pair.of(IN_MAINTENANCE, 5), Pair.of(IN_MAINTENANCE, 1)); + .createReplicas(new TestEntry<>(IN_SERVICE, 1), new TestEntry<>(IN_SERVICE, 2), + new TestEntry<>(IN_SERVICE, 3), new TestEntry<>(IN_SERVICE, 4), + new TestEntry<>(IN_MAINTENANCE, 5), new TestEntry<>(IN_MAINTENANCE, 1)); ECContainerReplicaCount rcnt = new ECContainerReplicaCount(container, replica, Collections.emptyList(), 1); @@ -323,9 +323,9 @@ public void testAdditionalMaintenanceCopiesAlreadyReplicated() { @Test public void testAdditionalMaintenanceCopiesAlreadyReplicatedWithDelete() { Set replica = ReplicationTestUtil - .createReplicas(Pair.of(IN_SERVICE, 1), Pair.of(IN_SERVICE, 2), - Pair.of(IN_SERVICE, 3), Pair.of(IN_SERVICE, 4), - Pair.of(IN_MAINTENANCE, 5), Pair.of(IN_MAINTENANCE, 1)); + .createReplicas(new TestEntry<>(IN_SERVICE, 1), new TestEntry<>(IN_SERVICE, 2), + new TestEntry<>(IN_SERVICE, 3), new TestEntry<>(IN_SERVICE, 4), + new TestEntry<>(IN_MAINTENANCE, 5), new TestEntry<>(IN_MAINTENANCE, 1)); List pending = getContainerReplicaOps(ImmutableList.of(), ImmutableList.of(1)); @@ -345,10 +345,10 @@ public void testAdditionalMaintenanceCopiesAlreadyReplicatedWithDelete() { @Test public void testAdditionalMaintenanceCopiesDuplicatesInMaintenance() { Set replica = ReplicationTestUtil - .createReplicas(Pair.of(IN_SERVICE, 1), Pair.of(IN_SERVICE, 2), - Pair.of(IN_SERVICE, 3), Pair.of(IN_SERVICE, 4), - Pair.of(IN_MAINTENANCE, 5), Pair.of(IN_MAINTENANCE, 1), - Pair.of(IN_MAINTENANCE, 1), Pair.of(IN_MAINTENANCE, 5)); + .createReplicas(new TestEntry<>(IN_SERVICE, 1), new TestEntry<>(IN_SERVICE, 2), + new TestEntry<>(IN_SERVICE, 3), new TestEntry<>(IN_SERVICE, 4), + new TestEntry<>(IN_MAINTENANCE, 5), new TestEntry<>(IN_MAINTENANCE, 1), + new TestEntry<>(IN_MAINTENANCE, 1), new TestEntry<>(IN_MAINTENANCE, 5)); ECContainerReplicaCount rcnt = new ECContainerReplicaCount(container, replica, Collections.emptyList(), 1); @@ -375,9 +375,9 @@ public void testAdditionalMaintenanceCopiesDuplicatesInMaintenance() { @Test public void testMaintenanceRedundancyGreaterThanParity() { Set replica = ReplicationTestUtil - .createReplicas(Pair.of(IN_SERVICE, 1), Pair.of(IN_SERVICE, 2), - Pair.of(IN_SERVICE, 3), Pair.of(IN_MAINTENANCE, 4), - Pair.of(IN_MAINTENANCE, 5)); + .createReplicas(new TestEntry<>(IN_SERVICE, 1), new TestEntry<>(IN_SERVICE, 2), + new TestEntry<>(IN_SERVICE, 3), new TestEntry<>(IN_MAINTENANCE, 4), + new TestEntry<>(IN_MAINTENANCE, 5)); ECContainerReplicaCount rcnt = new ECContainerReplicaCount(container, replica, Collections.emptyList(), 5); @@ -387,10 +387,10 @@ public void testMaintenanceRedundancyGreaterThanParity() { assertEquals(2, rcnt.additionalMaintenanceCopiesNeeded(false)); // After replication, zero should be needed replica = ReplicationTestUtil - .createReplicas(Pair.of(IN_SERVICE, 1), Pair.of(IN_SERVICE, 2), - Pair.of(IN_SERVICE, 3), Pair.of(IN_MAINTENANCE, 4), - Pair.of(IN_MAINTENANCE, 5), Pair.of(IN_SERVICE, 4), - Pair.of(IN_SERVICE, 5)); + .createReplicas(new TestEntry<>(IN_SERVICE, 1), new TestEntry<>(IN_SERVICE, 2), + new TestEntry<>(IN_SERVICE, 3), new TestEntry<>(IN_MAINTENANCE, 4), + new TestEntry<>(IN_MAINTENANCE, 5), new TestEntry<>(IN_SERVICE, 4), + new TestEntry<>(IN_SERVICE, 5)); rcnt = new ECContainerReplicaCount(container, replica, Collections.emptyList(), 5); assertEquals(0, rcnt.additionalMaintenanceCopiesNeeded(false)); @@ -400,8 +400,8 @@ public void testMaintenanceRedundancyGreaterThanParity() { @Test public void testUnderReplicatedNoMaintenance() { Set replica = ReplicationTestUtil - .createReplicas(Pair.of(IN_SERVICE, 1), Pair.of(IN_SERVICE, 2), - Pair.of(IN_SERVICE, 3)); + .createReplicas(new TestEntry<>(IN_SERVICE, 1), new TestEntry<>(IN_SERVICE, 2), + new TestEntry<>(IN_SERVICE, 3)); ECContainerReplicaCount rcnt = new ECContainerReplicaCount(container, replica, @@ -421,9 +421,9 @@ public void testUnderReplicatedNoMaintenance() { @Test public void testMaintenanceRedundancyIsMetWithPendingAdd() { Set replica = ReplicationTestUtil - .createReplicas(Pair.of(IN_MAINTENANCE, 1), - Pair.of(ENTERING_MAINTENANCE, 2), Pair.of(IN_MAINTENANCE, 3), - Pair.of(IN_MAINTENANCE, 4), Pair.of(IN_MAINTENANCE, 5)); + .createReplicas(new TestEntry<>(IN_MAINTENANCE, 1), + new TestEntry<>(ENTERING_MAINTENANCE, 2), new TestEntry<>(IN_MAINTENANCE, 3), + new TestEntry<>(IN_MAINTENANCE, 4), new TestEntry<>(IN_MAINTENANCE, 5)); List pending = getContainerReplicaOps(ImmutableList.of(1, 2, 3, 4), ImmutableList.of(1)); @@ -444,8 +444,8 @@ public void testMaintenanceRedundancyIsMetWithPendingAdd() { @Test public void testUnderReplicatedFixedWithPending() { Set replica = ReplicationTestUtil - .createReplicas(Pair.of(IN_SERVICE, 1), Pair.of(IN_SERVICE, 2), - Pair.of(IN_SERVICE, 3)); + .createReplicas(new TestEntry<>(IN_SERVICE, 1), new TestEntry<>(IN_SERVICE, 2), + new TestEntry<>(IN_SERVICE, 3)); List pending = getContainerReplicaOps(ImmutableList.of(4, 5), ImmutableList.of()); @@ -468,8 +468,8 @@ public void testUnderReplicatedFixedWithPending() { @Test public void testMissingNonMaintenanceReplicas() { Set replica = ReplicationTestUtil - .createReplicas(Pair.of(IN_SERVICE, 1), Pair.of(IN_SERVICE, 2), - Pair.of(IN_SERVICE, 3), Pair.of(IN_MAINTENANCE, 4)); + .createReplicas(new TestEntry<>(IN_SERVICE, 1), new TestEntry<>(IN_SERVICE, 2), + new TestEntry<>(IN_SERVICE, 3), new TestEntry<>(IN_MAINTENANCE, 4)); List pending = getContainerReplicaOps(ImmutableList.of(), ImmutableList.of(1)); @@ -487,9 +487,9 @@ public void testMissingNonMaintenanceReplicas() { @Test public void testMissingNonMaintenanceReplicasAllMaintenance() { Set replica = ReplicationTestUtil - .createReplicas(Pair.of(IN_MAINTENANCE, 1), Pair.of(IN_MAINTENANCE, 2), - Pair.of(IN_MAINTENANCE, 3), Pair.of(IN_MAINTENANCE, 4), - Pair.of(IN_MAINTENANCE, 5)); + .createReplicas(new TestEntry<>(IN_MAINTENANCE, 1), new TestEntry<>(IN_MAINTENANCE, 2), + new TestEntry<>(IN_MAINTENANCE, 3), new TestEntry<>(IN_MAINTENANCE, 4), + new TestEntry<>(IN_MAINTENANCE, 5)); List pending = getContainerReplicaOps(ImmutableList.of(1), ImmutableList.of()); @@ -509,8 +509,8 @@ public void testMissingNonMaintenanceReplicasAllMaintenance() { @Test public void testMissingNonMaintenanceReplicasPendingAdd() { Set replica = ReplicationTestUtil - .createReplicas(Pair.of(IN_SERVICE, 1), Pair.of(IN_SERVICE, 2), - Pair.of(IN_SERVICE, 3), Pair.of(IN_SERVICE, 4)); + .createReplicas(new TestEntry<>(IN_SERVICE, 1), new TestEntry<>(IN_SERVICE, 2), + new TestEntry<>(IN_SERVICE, 3), new TestEntry<>(IN_SERVICE, 4)); // 5 is missing, but there is a pending add. List pending = @@ -553,11 +553,11 @@ public void testUnRecoverable() { assertEquals(5, rcnt.unavailableIndexes(true).size()); Set replica = ReplicationTestUtil - .createReplicas(Pair.of(IN_SERVICE, 1), Pair.of(IN_MAINTENANCE, 2)); + .createReplicas(new TestEntry<>(IN_SERVICE, 1), new TestEntry<>(IN_MAINTENANCE, 2)); // The unhealthy replica does not help with recovery even though we now // have 3 replicas. replica.addAll(ReplicationTestUtil.createReplicas( - UNHEALTHY, Pair.of(IN_SERVICE, 3))); + UNHEALTHY, new TestEntry<>(IN_SERVICE, 3))); rcnt = new ECContainerReplicaCount(container, replica, Collections.emptyList(), 1); assertTrue(rcnt.isUnrecoverable()); @@ -565,9 +565,9 @@ public void testUnRecoverable() { assertEquals(0, rcnt.additionalMaintenanceCopiesNeeded(false)); replica = ReplicationTestUtil - .createReplicas(Pair.of(DECOMMISSIONED, 1), Pair.of(DECOMMISSIONED, 2), - Pair.of(DECOMMISSIONED, 3), Pair.of(DECOMMISSIONED, 4), - Pair.of(DECOMMISSIONED, 5)); + .createReplicas(new TestEntry<>(DECOMMISSIONED, 1), new TestEntry<>(DECOMMISSIONED, 2), + new TestEntry<>(DECOMMISSIONED, 3), new TestEntry<>(DECOMMISSIONED, 4), + new TestEntry<>(DECOMMISSIONED, 5)); rcnt = new ECContainerReplicaCount(container, replica, Collections.emptyList(), 1); // Not missing as the decommission replicas are still online @@ -576,9 +576,9 @@ public void testUnRecoverable() { // All unhealthy replicas is still un-recoverable. replica = ReplicationTestUtil.createReplicas( - UNHEALTHY, Pair.of(IN_SERVICE, 1), - Pair.of(IN_SERVICE, 2), Pair.of(IN_SERVICE, 3), - Pair.of(IN_SERVICE, 4), Pair.of(IN_SERVICE, 5)); + UNHEALTHY, new TestEntry<>(IN_SERVICE, 1), + new TestEntry<>(IN_SERVICE, 2), new TestEntry<>(IN_SERVICE, 3), + new TestEntry<>(IN_SERVICE, 4), new TestEntry<>(IN_SERVICE, 5)); rcnt = new ECContainerReplicaCount(container, replica, Collections.emptyList(), 1); // Not missing as the decommission replicas are still online @@ -596,7 +596,7 @@ public void testIsMissingAndUnhealthy() { // 1 unhealthy Set replica = ReplicationTestUtil - .createReplicas(UNHEALTHY, Pair.of(IN_SERVICE, 1)); + .createReplicas(UNHEALTHY, new TestEntry<>(IN_SERVICE, 1)); rcnt = new ECContainerReplicaCount(container, replica, Collections.emptyList(), 1); assertTrue(rcnt.isMissing()); @@ -604,8 +604,8 @@ public void testIsMissingAndUnhealthy() { // 2 unhealthy replica = ReplicationTestUtil - .createReplicas(UNHEALTHY, Pair.of(IN_SERVICE, 1), - Pair.of(IN_SERVICE, 2)); + .createReplicas(UNHEALTHY, new TestEntry<>(IN_SERVICE, 1), + new TestEntry<>(IN_SERVICE, 2)); rcnt = new ECContainerReplicaCount(container, replica, Collections.emptyList(), 1); assertTrue(rcnt.isMissing()); @@ -613,19 +613,18 @@ public void testIsMissingAndUnhealthy() { // 3 unhealthy replica = ReplicationTestUtil - .createReplicas(UNHEALTHY, Pair.of(IN_SERVICE, 1), - Pair.of(IN_SERVICE, 2), Pair.of(IN_SERVICE, 3)); + .createReplicas(UNHEALTHY, new TestEntry<>(IN_SERVICE, 1), + new TestEntry<>(IN_SERVICE, 2), new TestEntry<>(IN_SERVICE, 3)); rcnt = new ECContainerReplicaCount(container, replica, Collections.emptyList(), 1); assertFalse(rcnt.isMissing()); assertTrue(rcnt.isUnrecoverable()); - // 3 replicas, with 1 unhealthy replica = ReplicationTestUtil - .createReplicas(Pair.of(IN_SERVICE, 1), Pair.of(IN_SERVICE, 2)); + .createReplicas(new TestEntry<>(IN_SERVICE, 1), new TestEntry<>(IN_SERVICE, 2)); replica.addAll(ReplicationTestUtil.createReplicas( - UNHEALTHY, Pair.of(IN_SERVICE, 3))); + UNHEALTHY, new TestEntry<>(IN_SERVICE, 3))); rcnt = new ECContainerReplicaCount(container, replica, Collections.emptyList(), 1); assertFalse(rcnt.isMissing()); @@ -633,10 +632,10 @@ public void testIsMissingAndUnhealthy() { // 4 replicas, with 1 unhealthy replica = ReplicationTestUtil - .createReplicas(Pair.of(IN_SERVICE, 1), Pair.of(IN_SERVICE, 2), - Pair.of(IN_SERVICE, 3)); + .createReplicas(new TestEntry<>(IN_SERVICE, 1), new TestEntry<>(IN_SERVICE, 2), + new TestEntry<>(IN_SERVICE, 3)); replica.addAll(ReplicationTestUtil.createReplicas( - UNHEALTHY, Pair.of(IN_SERVICE, 4))); + UNHEALTHY, new TestEntry<>(IN_SERVICE, 4))); rcnt = new ECContainerReplicaCount(container, replica, Collections.emptyList(), 1); assertFalse(rcnt.isMissing()); @@ -646,9 +645,9 @@ public void testIsMissingAndUnhealthy() { @Test public void testDecommissioningOnlyIndexes() { Set replica = ReplicationTestUtil - .createReplicas(Pair.of(DECOMMISSIONING, 1), Pair.of(IN_SERVICE, 2), - Pair.of(IN_SERVICE, 3), Pair.of(IN_SERVICE, 4), - Pair.of(IN_SERVICE, 5)); + .createReplicas(new TestEntry<>(DECOMMISSIONING, 1), new TestEntry<>(IN_SERVICE, 2), + new TestEntry<>(IN_SERVICE, 3), new TestEntry<>(IN_SERVICE, 4), + new TestEntry<>(IN_SERVICE, 5)); List pending = getContainerReplicaOps(ImmutableList.of(1), ImmutableList.of()); @@ -662,7 +661,7 @@ public void testDecommissioningOnlyIndexes() { @Test public void testSufficientlyReplicatedForOffline() { Set replica = ReplicationTestUtil - .createReplicas(Pair.of(IN_SERVICE, 2)); + .createReplicas(new TestEntry<>(IN_SERVICE, 2)); ContainerReplica inServiceReplica = ReplicationTestUtil.createContainerReplica(container.containerID(), @@ -701,11 +700,11 @@ public void testSufficientlyReplicatedForOffline() { @Test public void testSufficientlyReplicatedWithUnhealthyAndPendingDelete() { Set replica = ReplicationTestUtil - .createReplicas(Pair.of(IN_SERVICE, 1), - Pair.of(IN_SERVICE, 2), - Pair.of(IN_SERVICE, 3), - Pair.of(IN_SERVICE, 4), - Pair.of(IN_SERVICE, 5)); + .createReplicas(new TestEntry<>(IN_SERVICE, 1), + new TestEntry<>(IN_SERVICE, 2), + new TestEntry<>(IN_SERVICE, 3), + new TestEntry<>(IN_SERVICE, 4), + new TestEntry<>(IN_SERVICE, 5)); ContainerReplica unhealthyReplica = ReplicationTestUtil.createContainerReplica(container.containerID(), diff --git a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/TestECMisReplicationHandler.java b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/TestECMisReplicationHandler.java index 5bcba983a2c..1ae7075b486 100644 --- a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/TestECMisReplicationHandler.java +++ b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/TestECMisReplicationHandler.java @@ -36,7 +36,6 @@ import java.util.List; import java.util.Map; import java.util.Set; -import org.apache.commons.lang3.tuple.Pair; import org.apache.hadoop.hdds.client.ECReplicationConfig; import org.apache.hadoop.hdds.conf.OzoneConfiguration; import org.apache.hadoop.hdds.protocol.DatanodeDetails; @@ -47,6 +46,7 @@ import org.apache.hadoop.hdds.scm.exceptions.SCMException; import org.apache.hadoop.hdds.scm.node.states.NodeNotFoundException; import org.apache.hadoop.hdds.scm.pipeline.InsufficientDatanodesException; +import org.apache.ozone.test.TestEntry; import org.apache.ratis.protocol.exceptions.NotLeaderException; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -73,9 +73,9 @@ void setup(@TempDir File testDir) throws NodeNotFoundException, public void testMisReplicationWithAllNodesAvailable(int misreplicationCount) throws IOException { Set availableReplicas = ReplicationTestUtil - .createReplicas(Pair.of(IN_SERVICE, 1), Pair.of(IN_SERVICE, 2), - Pair.of(IN_SERVICE, 3), Pair.of(IN_SERVICE, 4), - Pair.of(IN_SERVICE, 5)); + .createReplicas(new TestEntry<>(IN_SERVICE, 1), new TestEntry<>(IN_SERVICE, 2), + new TestEntry<>(IN_SERVICE, 3), new TestEntry<>(IN_SERVICE, 4), + new TestEntry<>(IN_SERVICE, 5)); testMisReplication(availableReplicas, Collections.emptyList(), 0, misreplicationCount, Math.min(misreplicationCount, 5)); } @@ -83,9 +83,9 @@ public void testMisReplicationWithAllNodesAvailable(int misreplicationCount) @Test public void testMisReplicationWithNoNodesReturned() throws IOException { Set availableReplicas = ReplicationTestUtil - .createReplicas(Pair.of(IN_SERVICE, 1), Pair.of(IN_SERVICE, 2), - Pair.of(IN_SERVICE, 3), Pair.of(IN_SERVICE, 4), - Pair.of(IN_SERVICE, 5)); + .createReplicas(new TestEntry<>(IN_SERVICE, 1), new TestEntry<>(IN_SERVICE, 2), + new TestEntry<>(IN_SERVICE, 3), new TestEntry<>(IN_SERVICE, 4), + new TestEntry<>(IN_SERVICE, 5)); PlacementPolicy placementPolicy = mock(PlacementPolicy.class); ContainerPlacementStatus mockedContainerPlacementStatus = mock(ContainerPlacementStatus.class); @@ -105,9 +105,9 @@ public void testMisReplicationWithNoNodesReturned() throws IOException { public void testMisReplicationWithSomeNodesNotInService( int misreplicationCount) throws IOException { Set availableReplicas = ReplicationTestUtil - .createReplicas(Pair.of(IN_SERVICE, 1), Pair.of(IN_SERVICE, 2), - Pair.of(IN_MAINTENANCE, 3), Pair.of(IN_MAINTENANCE, 4), - Pair.of(IN_SERVICE, 5)); + .createReplicas(new TestEntry<>(IN_SERVICE, 1), new TestEntry<>(IN_SERVICE, 2), + new TestEntry<>(IN_MAINTENANCE, 3), new TestEntry<>(IN_MAINTENANCE, 4), + new TestEntry<>(IN_SERVICE, 5)); testMisReplication(availableReplicas, Collections.emptyList(), 0, misreplicationCount, Math.min(misreplicationCount, 3)); } @@ -115,18 +115,18 @@ public void testMisReplicationWithSomeNodesNotInService( @Test public void testMisReplicationWithUndereplication() throws IOException { Set availableReplicas = ReplicationTestUtil - .createReplicas(Pair.of(IN_SERVICE, 2), - Pair.of(IN_SERVICE, 3), Pair.of(IN_SERVICE, 4), - Pair.of(IN_SERVICE, 5)); + .createReplicas(new TestEntry<>(IN_SERVICE, 2), + new TestEntry<>(IN_SERVICE, 3), new TestEntry<>(IN_SERVICE, 4), + new TestEntry<>(IN_SERVICE, 5)); testMisReplication(availableReplicas, Collections.emptyList(), 0, 1, 0); } @Test public void testMisReplicationWithOvereplication() throws IOException { Set availableReplicas = ReplicationTestUtil - .createReplicas(Pair.of(IN_SERVICE, 1), Pair.of(IN_SERVICE, 1), - Pair.of(IN_SERVICE, 2), Pair.of(IN_SERVICE, 3), - Pair.of(IN_SERVICE, 4), Pair.of(IN_SERVICE, 5)); + .createReplicas(new TestEntry<>(IN_SERVICE, 1), new TestEntry<>(IN_SERVICE, 1), + new TestEntry<>(IN_SERVICE, 2), new TestEntry<>(IN_SERVICE, 3), + new TestEntry<>(IN_SERVICE, 4), new TestEntry<>(IN_SERVICE, 5)); testMisReplication(availableReplicas, Collections.emptyList(), 0, 1, 0); } @@ -134,9 +134,9 @@ public void testMisReplicationWithOvereplication() throws IOException { public void testMisReplicationWithSatisfiedPlacementPolicy() throws IOException { Set availableReplicas = ReplicationTestUtil - .createReplicas(Pair.of(IN_SERVICE, 1), Pair.of(IN_SERVICE, 2), - Pair.of(IN_SERVICE, 3), Pair.of(IN_SERVICE, 4), - Pair.of(IN_SERVICE, 5)); + .createReplicas(new TestEntry<>(IN_SERVICE, 1), new TestEntry<>(IN_SERVICE, 2), + new TestEntry<>(IN_SERVICE, 3), new TestEntry<>(IN_SERVICE, 4), + new TestEntry<>(IN_SERVICE, 5)); PlacementPolicy placementPolicy = mock(PlacementPolicy.class); ContainerPlacementStatus mockedContainerPlacementStatus = mock(ContainerPlacementStatus.class); @@ -151,9 +151,9 @@ public void testMisReplicationWithSatisfiedPlacementPolicy() public void testMisReplicationWithPendingOps() throws IOException { Set availableReplicas = ReplicationTestUtil - .createReplicas(Pair.of(IN_SERVICE, 1), Pair.of(IN_SERVICE, 2), - Pair.of(IN_SERVICE, 3), Pair.of(IN_SERVICE, 4), - Pair.of(IN_SERVICE, 5)); + .createReplicas(new TestEntry<>(IN_SERVICE, 1), new TestEntry<>(IN_SERVICE, 2), + new TestEntry<>(IN_SERVICE, 3), new TestEntry<>(IN_SERVICE, 4), + new TestEntry<>(IN_SERVICE, 5)); PlacementPolicy placementPolicy = mock(PlacementPolicy.class); ContainerPlacementStatus mockedContainerPlacementStatus = mock(ContainerPlacementStatus.class); @@ -179,9 +179,9 @@ public void testAllSourcesOverloaded() throws IOException { .when(replicationManager).sendThrottledReplicationCommand(any(), anyList(), any(), anyInt()); Set availableReplicas = ReplicationTestUtil - .createReplicas(Pair.of(IN_SERVICE, 1), Pair.of(IN_SERVICE, 2), - Pair.of(IN_SERVICE, 3), Pair.of(IN_SERVICE, 4), - Pair.of(IN_SERVICE, 5)); + .createReplicas(new TestEntry<>(IN_SERVICE, 1), new TestEntry<>(IN_SERVICE, 2), + new TestEntry<>(IN_SERVICE, 3), new TestEntry<>(IN_SERVICE, 4), + new TestEntry<>(IN_SERVICE, 5)); assertThrows(CommandTargetOverloadedException.class, () -> testMisReplication(availableReplicas, mockPlacementPolicy(), Collections.emptyList(), 0, 1, 1, 0)); @@ -191,9 +191,9 @@ public void testAllSourcesOverloaded() throws IOException { public void testFirstSourcesOverloaded() { setThrowThrottledException(true); Set availableReplicas = ReplicationTestUtil - .createReplicas(Pair.of(IN_SERVICE, 1), Pair.of(IN_SERVICE, 2), - Pair.of(IN_SERVICE, 3), Pair.of(IN_SERVICE, 4), - Pair.of(IN_SERVICE, 5)); + .createReplicas(new TestEntry<>(IN_SERVICE, 1), new TestEntry<>(IN_SERVICE, 2), + new TestEntry<>(IN_SERVICE, 3), new TestEntry<>(IN_SERVICE, 4), + new TestEntry<>(IN_SERVICE, 5)); assertThrows(CommandTargetOverloadedException.class, () -> testMisReplication(availableReplicas, mockPlacementPolicy(), Collections.emptyList(), 0, 2, 2, 1)); @@ -202,9 +202,9 @@ public void testFirstSourcesOverloaded() { @Test public void commandsForFewerThanRequiredNodes() throws IOException { Set availableReplicas = ReplicationTestUtil - .createReplicas(Pair.of(IN_SERVICE, 1), Pair.of(IN_SERVICE, 2), - Pair.of(IN_SERVICE, 3), Pair.of(IN_SERVICE, 4), - Pair.of(IN_SERVICE, 5)); + .createReplicas(new TestEntry<>(IN_SERVICE, 1), new TestEntry<>(IN_SERVICE, 2), + new TestEntry<>(IN_SERVICE, 3), new TestEntry<>(IN_SERVICE, 4), + new TestEntry<>(IN_SERVICE, 5)); PlacementPolicy placementPolicy = mock(PlacementPolicy.class); List targetDatanodes = singletonList( availableReplicas.iterator().next().getDatanodeDetails()); diff --git a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/TestECOverReplicationHandler.java b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/TestECOverReplicationHandler.java index 533ac898392..c305f6ef0a6 100644 --- a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/TestECOverReplicationHandler.java +++ b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/TestECOverReplicationHandler.java @@ -48,7 +48,6 @@ import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; import java.util.stream.Collectors; -import org.apache.commons.lang3.tuple.Pair; import org.apache.hadoop.hdds.client.ECReplicationConfig; import org.apache.hadoop.hdds.conf.OzoneConfiguration; import org.apache.hadoop.hdds.protocol.DatanodeDetails; @@ -66,6 +65,7 @@ import org.apache.hadoop.ozone.container.common.SCMTestUtils; import org.apache.hadoop.ozone.protocol.commands.DeleteContainerCommand; import org.apache.hadoop.ozone.protocol.commands.SCMCommand; +import org.apache.ozone.test.TestEntry; import org.apache.ratis.protocol.exceptions.NotLeaderException; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -80,7 +80,7 @@ public class TestECOverReplicationHandler { private ReplicationManager replicationManager; private PlacementPolicy policy; private DatanodeDetails staleNode; - private Set>> commandsSent; + private Set>> commandsSent; @BeforeEach void setup(@TempDir File testDir) throws NodeNotFoundException, NotLeaderException, @@ -117,9 +117,9 @@ void setup(@TempDir File testDir) throws NodeNotFoundException, NotLeaderExcepti public void testNoOverReplication() throws NotLeaderException, CommandTargetOverloadedException { Set availableReplicas = ReplicationTestUtil - .createReplicas(Pair.of(IN_SERVICE, 1), - Pair.of(IN_SERVICE, 2), Pair.of(IN_SERVICE, 3), - Pair.of(IN_SERVICE, 4), Pair.of(IN_SERVICE, 5)); + .createReplicas(new TestEntry<>(IN_SERVICE, 1), + new TestEntry<>(IN_SERVICE, 2), new TestEntry<>(IN_SERVICE, 3), + new TestEntry<>(IN_SERVICE, 4), new TestEntry<>(IN_SERVICE, 5)); testOverReplicationWithIndexes(availableReplicas, Collections.emptyMap(), ImmutableList.of()); } @@ -128,9 +128,9 @@ public void testNoOverReplication() public void testOverReplicationFixedByPendingDelete() throws NotLeaderException, CommandTargetOverloadedException { Set availableReplicas = ReplicationTestUtil - .createReplicas(Pair.of(IN_SERVICE, 1), - Pair.of(IN_SERVICE, 2), Pair.of(IN_SERVICE, 3), - Pair.of(IN_SERVICE, 4), Pair.of(IN_SERVICE, 5)); + .createReplicas(new TestEntry<>(IN_SERVICE, 1), + new TestEntry<>(IN_SERVICE, 2), new TestEntry<>(IN_SERVICE, 3), + new TestEntry<>(IN_SERVICE, 4), new TestEntry<>(IN_SERVICE, 5)); ContainerReplica excess = ReplicationTestUtil.createContainerReplica( container.containerID(), 5, IN_SERVICE, ContainerReplicaProto.State.CLOSED); @@ -146,10 +146,10 @@ public void testOverReplicationFixedByPendingDelete() public void testOverReplicationWithDecommissionIndexes() throws NotLeaderException, CommandTargetOverloadedException { Set availableReplicas = ReplicationTestUtil - .createReplicas(Pair.of(IN_SERVICE, 1), - Pair.of(IN_SERVICE, 2), Pair.of(IN_SERVICE, 3), - Pair.of(IN_SERVICE, 4), Pair.of(IN_SERVICE, 5), - Pair.of(DECOMMISSIONING, 5)); + .createReplicas(new TestEntry<>(IN_SERVICE, 1), + new TestEntry<>(IN_SERVICE, 2), new TestEntry<>(IN_SERVICE, 3), + new TestEntry<>(IN_SERVICE, 4), new TestEntry<>(IN_SERVICE, 5), + new TestEntry<>(DECOMMISSIONING, 5)); testOverReplicationWithIndexes(availableReplicas, Collections.emptyMap(), ImmutableList.of()); } @@ -158,9 +158,9 @@ public void testOverReplicationWithDecommissionIndexes() public void testOverReplicationWithStaleIndexes() throws NotLeaderException, CommandTargetOverloadedException { Set availableReplicas = ReplicationTestUtil - .createReplicas(Pair.of(IN_SERVICE, 1), - Pair.of(IN_SERVICE, 2), Pair.of(IN_SERVICE, 3), - Pair.of(IN_SERVICE, 4), Pair.of(IN_SERVICE, 5)); + .createReplicas(new TestEntry<>(IN_SERVICE, 1), + new TestEntry<>(IN_SERVICE, 2), new TestEntry<>(IN_SERVICE, 3), + new TestEntry<>(IN_SERVICE, 4), new TestEntry<>(IN_SERVICE, 5)); ContainerReplica stale = ReplicationTestUtil.createContainerReplica( container.containerID(), 5, IN_SERVICE, ContainerReplicaProto.State.CLOSED); @@ -176,9 +176,9 @@ public void testOverReplicationWithStaleIndexes() public void testOverReplicationWithOpenReplica() throws NotLeaderException, CommandTargetOverloadedException { Set availableReplicas = ReplicationTestUtil - .createReplicas(Pair.of(IN_SERVICE, 1), - Pair.of(IN_SERVICE, 2), Pair.of(IN_SERVICE, 3), - Pair.of(IN_SERVICE, 4), Pair.of(IN_SERVICE, 5)); + .createReplicas(new TestEntry<>(IN_SERVICE, 1), + new TestEntry<>(IN_SERVICE, 2), new TestEntry<>(IN_SERVICE, 3), + new TestEntry<>(IN_SERVICE, 4), new TestEntry<>(IN_SERVICE, 5)); ContainerReplica open = ReplicationTestUtil.createContainerReplica( container.containerID(), 5, IN_SERVICE, ContainerReplicaProto.State.OPEN); @@ -196,9 +196,9 @@ public void testOverReplicationWithOpenReplica() public void testOverReplicationButPolicyReturnsWrongIndexes() throws NotLeaderException, CommandTargetOverloadedException { Set availableReplicas = ReplicationTestUtil - .createReplicas(Pair.of(IN_SERVICE, 2), Pair.of(IN_SERVICE, 3), - Pair.of(IN_SERVICE, 4), Pair.of(IN_SERVICE, 5), - Pair.of(IN_SERVICE, 5)); + .createReplicas(new TestEntry<>(IN_SERVICE, 2), new TestEntry<>(IN_SERVICE, 3), + new TestEntry<>(IN_SERVICE, 4), new TestEntry<>(IN_SERVICE, 5), + new TestEntry<>(IN_SERVICE, 5)); ContainerReplica toReturn = ReplicationTestUtil.createContainerReplica( container.containerID(), 1, IN_SERVICE, ContainerReplicaProto.State.CLOSED); @@ -213,10 +213,10 @@ public void testOverReplicationButPolicyReturnsWrongIndexes() public void testOverReplicationWithOneSameIndexes() throws NotLeaderException, CommandTargetOverloadedException { Set availableReplicas = ReplicationTestUtil - .createReplicas(Pair.of(IN_SERVICE, 1), - Pair.of(IN_SERVICE, 1), Pair.of(IN_SERVICE, 1), - Pair.of(IN_SERVICE, 2), Pair.of(IN_SERVICE, 3), - Pair.of(IN_SERVICE, 4), Pair.of(IN_SERVICE, 5)); + .createReplicas(new TestEntry<>(IN_SERVICE, 1), + new TestEntry<>(IN_SERVICE, 1), new TestEntry<>(IN_SERVICE, 1), + new TestEntry<>(IN_SERVICE, 2), new TestEntry<>(IN_SERVICE, 3), + new TestEntry<>(IN_SERVICE, 4), new TestEntry<>(IN_SERVICE, 5)); testOverReplicationWithIndexes(availableReplicas, //num of index 1 is 3, but it should be 1, so 2 excess @@ -228,13 +228,13 @@ public void testOverReplicationWithOneSameIndexes() public void testOverReplicationWithMultiSameIndexes() throws NotLeaderException, CommandTargetOverloadedException { Set availableReplicas = ReplicationTestUtil - .createReplicas(Pair.of(IN_SERVICE, 1), - Pair.of(IN_SERVICE, 1), Pair.of(IN_SERVICE, 1), - Pair.of(IN_SERVICE, 2), Pair.of(IN_SERVICE, 2), - Pair.of(IN_SERVICE, 2), Pair.of(IN_SERVICE, 3), - Pair.of(IN_SERVICE, 3), Pair.of(IN_SERVICE, 3), - Pair.of(IN_SERVICE, 4), Pair.of(IN_SERVICE, 4), - Pair.of(IN_SERVICE, 5), Pair.of(IN_SERVICE, 5)); + .createReplicas(new TestEntry<>(IN_SERVICE, 1), + new TestEntry<>(IN_SERVICE, 1), new TestEntry<>(IN_SERVICE, 1), + new TestEntry<>(IN_SERVICE, 2), new TestEntry<>(IN_SERVICE, 2), + new TestEntry<>(IN_SERVICE, 2), new TestEntry<>(IN_SERVICE, 3), + new TestEntry<>(IN_SERVICE, 3), new TestEntry<>(IN_SERVICE, 3), + new TestEntry<>(IN_SERVICE, 4), new TestEntry<>(IN_SERVICE, 4), + new TestEntry<>(IN_SERVICE, 5), new TestEntry<>(IN_SERVICE, 5)); testOverReplicationWithIndexes(availableReplicas, //num of index 1 is 3, but it should be 1, so 2 excess @@ -253,10 +253,10 @@ public void testOverReplicationWithUnderReplication() throws NotLeaderException, CommandTargetOverloadedException { Set availableReplicas = ReplicationTestUtil .createReplicas( - Pair.of(IN_SERVICE, 1), Pair.of(IN_SERVICE, 1), - Pair.of(IN_SERVICE, 3), - Pair.of(IN_SERVICE, 4), - Pair.of(IN_SERVICE, 5)); + new TestEntry<>(IN_SERVICE, 1), new TestEntry<>(IN_SERVICE, 1), + new TestEntry<>(IN_SERVICE, 3), + new TestEntry<>(IN_SERVICE, 4), + new TestEntry<>(IN_SERVICE, 5)); ContainerHealthResult.UnderReplicatedHealthResult health = new ContainerHealthResult.UnderReplicatedHealthResult( @@ -277,11 +277,11 @@ public void testOverReplicationWithUnderReplication() public void testDeleteThrottling() throws IOException { Set availableReplicas = ReplicationTestUtil .createReplicas( - Pair.of(IN_SERVICE, 1), Pair.of(IN_SERVICE, 1), - Pair.of(IN_SERVICE, 2), Pair.of(IN_SERVICE, 2), - Pair.of(IN_SERVICE, 3), - Pair.of(IN_SERVICE, 4), - Pair.of(IN_SERVICE, 5)); + new TestEntry<>(IN_SERVICE, 1), new TestEntry<>(IN_SERVICE, 1), + new TestEntry<>(IN_SERVICE, 2), new TestEntry<>(IN_SERVICE, 2), + new TestEntry<>(IN_SERVICE, 3), + new TestEntry<>(IN_SERVICE, 4), + new TestEntry<>(IN_SERVICE, 5)); ContainerHealthResult.UnderReplicatedHealthResult health = new ContainerHealthResult.UnderReplicatedHealthResult( @@ -302,7 +302,7 @@ public void testDeleteThrottling() throws IOException { DeleteContainerCommand deleteCommand = new DeleteContainerCommand( containerInfo.getContainerID(), forceDelete); deleteCommand.setReplicaIndex(replicaIndex); - commandsSent.add(Pair.of(target, deleteCommand)); + commandsSent.add(new TestEntry<>(target, deleteCommand)); return null; }).when(replicationManager) .sendThrottledDeleteCommand(any(), anyInt(), any(), anyBoolean()); @@ -336,8 +336,8 @@ private void testOverReplicationWithIndexes( assertEquals(totalDeleteCommandNum, commandsSent.size()); // Each command should have a non-zero replica index - commandsSent.forEach(pair -> assertNotEquals(0, - ((DeleteContainerCommand) pair.getValue()).getReplicaIndex())); + commandsSent.forEach(commandEntry -> assertNotEquals(0, + ((DeleteContainerCommand) commandEntry.getValue()).getReplicaIndex())); // command num of each index should be equal to the excess num // of this index @@ -346,8 +346,8 @@ private void testOverReplicationWithIndexes( ContainerReplica::getDatanodeDetails, ContainerReplica::getReplicaIndex)); Map index2commandNum = new HashMap<>(); - commandsSent.forEach(pair -> index2commandNum.merge( - datanodeDetails2Index.get(pair.getKey()), 1, Integer::sum) + commandsSent.forEach(commandEntry -> index2commandNum.merge( + datanodeDetails2Index.get(commandEntry.getKey()), 1, Integer::sum) ); index2commandNum.keySet().forEach(i -> { diff --git a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/TestECUnderReplicationHandler.java b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/TestECUnderReplicationHandler.java index 5d2af561196..fe121319a40 100644 --- a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/TestECUnderReplicationHandler.java +++ b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/TestECUnderReplicationHandler.java @@ -63,12 +63,10 @@ import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; -import java.util.Map; import java.util.Set; import java.util.TreeSet; import java.util.concurrent.atomic.AtomicBoolean; import java.util.stream.IntStream; -import org.apache.commons.lang3.tuple.Pair; import org.apache.hadoop.hdds.client.ECReplicationConfig; import org.apache.hadoop.hdds.conf.OzoneConfiguration; import org.apache.hadoop.hdds.protocol.DatanodeDetails; @@ -95,6 +93,7 @@ import org.apache.hadoop.ozone.protocol.commands.ReconstructECContainersCommand; import org.apache.hadoop.ozone.protocol.commands.ReplicateContainerCommand; import org.apache.hadoop.ozone.protocol.commands.SCMCommand; +import org.apache.ozone.test.TestEntry; import org.apache.ratis.protocol.exceptions.NotLeaderException; import org.assertj.core.util.Lists; import org.junit.jupiter.api.AfterEach; @@ -119,7 +118,7 @@ public class TestECUnderReplicationHandler { private static final int PARITY = 2; private PlacementPolicy ecPlacementPolicy; private int remainingMaintenanceRedundancy = 1; - private Set>> commandsSent; + private Set>> commandsSent; private final AtomicBoolean throwOverloadedExceptionOnReplication = new AtomicBoolean(false); private final AtomicBoolean throwOverloadedExceptionOnReconstruction @@ -326,8 +325,8 @@ public void testUnderReplicationWithMissingParityIndex5() throws IOException { @Test public void testUnderReplicationWithMissingIndex34() throws IOException { Set availableReplicas = ReplicationTestUtil - .createReplicas(Pair.of(IN_SERVICE, 1), Pair.of(IN_SERVICE, 2), - Pair.of(IN_SERVICE, 5)); + .createReplicas(new TestEntry<>(IN_SERVICE, 1), new TestEntry<>(IN_SERVICE, 2), + new TestEntry<>(IN_SERVICE, 5)); testUnderReplicationWithMissingIndexes(ImmutableList.of(3, 4), availableReplicas, 0, 0, policy); } @@ -362,10 +361,10 @@ public void testThrowsWhenTargetsOverloaded() throws IOException { @Test public void testUnderReplicationWithDecomIndex1() throws IOException { Set availableReplicas = ReplicationTestUtil - .createReplicas(Pair.of(DECOMMISSIONING, 1), Pair.of(IN_SERVICE, 2), - Pair.of(IN_SERVICE, 3), Pair.of(IN_SERVICE, 4), - Pair.of(IN_SERVICE, 5)); - Set>> cmds = + .createReplicas(new TestEntry<>(DECOMMISSIONING, 1), new TestEntry<>(IN_SERVICE, 2), + new TestEntry<>(IN_SERVICE, 3), new TestEntry<>(IN_SERVICE, 4), + new TestEntry<>(IN_SERVICE, 5)); + Set>> cmds = testUnderReplicationWithMissingIndexes( Lists.emptyList(), availableReplicas, 1, 0, policy); assertEquals(1, cmds.size()); @@ -375,7 +374,6 @@ public void testUnderReplicationWithDecomIndex1() throws IOException { assertEquals(1, cmd.getReplicaIndex()); } - // Test used to reproduce the issue reported in HDDS-8171 and then adjusted // to ensure only a single command is sent for HDDS-8172. @Test @@ -399,20 +397,20 @@ public NodeStatus getNodeStatus(DatanodeDetails dd) { }; availableReplicas.addAll(ReplicationTestUtil - .createReplicas(Pair.of(DECOMMISSIONING, 1), - Pair.of(IN_MAINTENANCE, 2), - Pair.of(IN_SERVICE, 3), Pair.of(IN_SERVICE, 4), - Pair.of(IN_SERVICE, 5))); + .createReplicas(new TestEntry<>(DECOMMISSIONING, 1), + new TestEntry<>(IN_MAINTENANCE, 2), + new TestEntry<>(IN_SERVICE, 3), new TestEntry<>(IN_SERVICE, 4), + new TestEntry<>(IN_SERVICE, 5))); // Note that maintenanceIndexes is set to zero as we do not expect any // maintenance commands to be created, as they are solved by the earlier // decommission command. - Set>> cmds = + Set>> cmds = testUnderReplicationWithMissingIndexes( Lists.emptyList(), availableReplicas, 1, 0, policy); assertEquals(1, cmds.size()); // Check the replicate command has index 1 set - for (Pair> c : cmds) { + for (TestEntry> c : cmds) { // Ensure neither of the commands are for the dead maintenance node assertNotEquals(deadMaintenance.getDatanodeDetails(), c.getKey()); @@ -423,9 +421,9 @@ public NodeStatus getNodeStatus(DatanodeDetails dd) { public void testUnderReplicationWithDecomNodesOverloaded() throws IOException { Set availableReplicas = ReplicationTestUtil - .createReplicas(Pair.of(DECOMMISSIONING, 1), Pair.of(IN_SERVICE, 2), - Pair.of(IN_SERVICE, 3), Pair.of(IN_SERVICE, 4), - Pair.of(IN_SERVICE, 5)); + .createReplicas(new TestEntry<>(DECOMMISSIONING, 1), new TestEntry<>(IN_SERVICE, 2), + new TestEntry<>(IN_SERVICE, 3), new TestEntry<>(IN_SERVICE, 4), + new TestEntry<>(IN_SERVICE, 5)); doThrow(new CommandTargetOverloadedException("Overloaded")) .when(replicationManager).sendThrottledReplicationCommand( any(), anyList(), any(), anyInt()); @@ -438,9 +436,9 @@ public void testUnderReplicationWithDecomNodesOverloaded() @Test public void testUnderReplicationWithDecomIndex12() throws IOException { Set availableReplicas = ReplicationTestUtil - .createReplicas(Pair.of(DECOMMISSIONING, 1), - Pair.of(DECOMMISSIONING, 2), Pair.of(IN_SERVICE, 3), - Pair.of(IN_SERVICE, 4), Pair.of(IN_SERVICE, 5)); + .createReplicas(new TestEntry<>(DECOMMISSIONING, 1), + new TestEntry<>(DECOMMISSIONING, 2), new TestEntry<>(IN_SERVICE, 3), + new TestEntry<>(IN_SERVICE, 4), new TestEntry<>(IN_SERVICE, 5)); testUnderReplicationWithMissingIndexes(Lists.emptyList(), availableReplicas, 2, 0, policy); } @@ -449,9 +447,9 @@ public void testUnderReplicationWithDecomIndex12() throws IOException { public void testUnderReplicationWithMixedDecomAndMissingIndexes() throws IOException { Set availableReplicas = ReplicationTestUtil - .createReplicas(Pair.of(DECOMMISSIONING, 1), - Pair.of(DECOMMISSIONING, 2), Pair.of(IN_SERVICE, 3), - Pair.of(IN_SERVICE, 4)); + .createReplicas(new TestEntry<>(DECOMMISSIONING, 1), + new TestEntry<>(DECOMMISSIONING, 2), new TestEntry<>(IN_SERVICE, 3), + new TestEntry<>(IN_SERVICE, 4)); testUnderReplicationWithMissingIndexes(ImmutableList.of(5), availableReplicas, 2, 0, policy); } @@ -459,9 +457,9 @@ public void testUnderReplicationWithMixedDecomAndMissingIndexes() @Test public void testUnderReplicationWithMaintenanceIndex12() throws IOException { Set availableReplicas = ReplicationTestUtil - .createReplicas(Pair.of(IN_MAINTENANCE, 1), - Pair.of(IN_MAINTENANCE, 2), Pair.of(IN_SERVICE, 3), - Pair.of(IN_SERVICE, 4), Pair.of(IN_SERVICE, 5)); + .createReplicas(new TestEntry<>(IN_MAINTENANCE, 1), + new TestEntry<>(IN_MAINTENANCE, 2), new TestEntry<>(IN_SERVICE, 3), + new TestEntry<>(IN_SERVICE, 4), new TestEntry<>(IN_SERVICE, 5)); testUnderReplicationWithMissingIndexes(Lists.emptyList(), availableReplicas, 0, 2, policy); } @@ -470,9 +468,9 @@ public void testUnderReplicationWithMaintenanceIndex12() throws IOException { public void testUnderReplicationWithMaintenanceAndMissingIndexes() throws IOException { Set availableReplicas = ReplicationTestUtil - .createReplicas(Pair.of(IN_MAINTENANCE, 1), - Pair.of(IN_MAINTENANCE, 2), Pair.of(IN_SERVICE, 3), - Pair.of(IN_SERVICE, 4)); + .createReplicas(new TestEntry<>(IN_MAINTENANCE, 1), + new TestEntry<>(IN_MAINTENANCE, 2), new TestEntry<>(IN_SERVICE, 3), + new TestEntry<>(IN_SERVICE, 4)); testUnderReplicationWithMissingIndexes(ImmutableList.of(5), availableReplicas, 0, 2, policy); } @@ -481,9 +479,9 @@ public void testUnderReplicationWithMaintenanceAndMissingIndexes() public void testUnderReplicationWithMissingDecomAndMaintenanceIndexes() throws IOException { Set availableReplicas = ReplicationTestUtil - .createReplicas(Pair.of(IN_MAINTENANCE, 1), - Pair.of(IN_MAINTENANCE, 2), Pair.of(DECOMMISSIONING, 3), - Pair.of(IN_SERVICE, 4)); + .createReplicas(new TestEntry<>(IN_MAINTENANCE, 1), + new TestEntry<>(IN_MAINTENANCE, 2), new TestEntry<>(DECOMMISSIONING, 3), + new TestEntry<>(IN_SERVICE, 4)); testUnderReplicationWithMissingIndexes(ImmutableList.of(5), availableReplicas, 1, 2, policy); } @@ -496,9 +494,9 @@ public void testUnderReplicationWithMissingDecomAndMaintenanceIndexes() public void testUnderReplicationWithInvalidPlacement() throws IOException { Set availableReplicas = ReplicationTestUtil - .createReplicas(Pair.of(DECOMMISSIONING, 1), - Pair.of(DECOMMISSIONING, 2), Pair.of(IN_SERVICE, 3), - Pair.of(IN_SERVICE, 4)); + .createReplicas(new TestEntry<>(DECOMMISSIONING, 1), + new TestEntry<>(DECOMMISSIONING, 2), new TestEntry<>(IN_SERVICE, 3), + new TestEntry<>(IN_SERVICE, 4)); PlacementPolicy mockedPolicy = spy(policy); ContainerPlacementStatus mockedContainerPlacementStatus = mock(ContainerPlacementStatus.class); @@ -525,9 +523,9 @@ public void testExceptionIfNoNodesFound() { PlacementPolicy noNodesPolicy = ReplicationTestUtil .getNoNodesTestPlacementPolicy(nodeManager, conf); Set availableReplicas = ReplicationTestUtil - .createReplicas(Pair.of(DECOMMISSIONING, 1), - Pair.of(DECOMMISSIONING, 2), Pair.of(IN_SERVICE, 3), - Pair.of(IN_SERVICE, 4)); + .createReplicas(new TestEntry<>(DECOMMISSIONING, 1), + new TestEntry<>(DECOMMISSIONING, 2), new TestEntry<>(IN_SERVICE, 3), + new TestEntry<>(IN_SERVICE, 4)); assertThrows(SCMException.class, () -> testUnderReplicationWithMissingIndexes(ImmutableList.of(5), availableReplicas, 2, 0, noNodesPolicy)); @@ -643,9 +641,9 @@ public void testUnhealthyNodeDeletedIfNoTargetsFound() for (ContainerReplica toAdd : replicasToAdd) { clearInvocations(replicationManager); Set existingReplicas = ReplicationTestUtil - .createReplicas(Pair.of(IN_SERVICE, 5), - Pair.of(IN_SERVICE, 2), Pair.of(IN_SERVICE, 3), - Pair.of(IN_SERVICE, 4)); + .createReplicas(new TestEntry<>(IN_SERVICE, 5), + new TestEntry<>(IN_SERVICE, 2), new TestEntry<>(IN_SERVICE, 3), + new TestEntry<>(IN_SERVICE, 4)); if (toAdd != null) { existingReplicas.add(toAdd); } @@ -675,7 +673,7 @@ public void testUnhealthyNodeDeletedIfNoTargetsFound() */ commandsSent.clear(); doAnswer(invocation -> { - commandsSent.add(Pair.of(invocation.getArgument(2), + commandsSent.add(new TestEntry<>(invocation.getArgument(2), createDeleteContainerCommand(invocation.getArgument(0), invocation.getArgument(1)))); return null; @@ -693,7 +691,7 @@ public void testUnhealthyNodeDeletedIfNoTargetsFound() unhealthyReplica.getReplicaIndex(), unhealthyReplica.getDatanodeDetails(), true); assertEquals(1, commandsSent.size()); - Pair> command = + TestEntry> command = commandsSent.iterator().next(); assertEquals(SCMCommandProto.Type.deleteContainerCommand, command.getValue().getType()); @@ -733,8 +731,8 @@ public void testPartialReconstructionIfNotEnoughNodes() { @Test public void testOverloadedReconstructionContinuesNextStages() { Set availableReplicas = ReplicationTestUtil - .createReplicas(Pair.of(IN_SERVICE, 1), - Pair.of(IN_SERVICE, 2), Pair.of(DECOMMISSIONING, 3)); + .createReplicas(new TestEntry<>(IN_SERVICE, 1), + new TestEntry<>(IN_SERVICE, 2), new TestEntry<>(DECOMMISSIONING, 3)); ECUnderReplicationHandler ecURH = new ECUnderReplicationHandler( policy, conf, replicationManager); @@ -757,9 +755,9 @@ public void testOverloadedReconstructionContinuesNextStages() { @Test public void testPartialDecommissionIfNotEnoughNodes() { Set availableReplicas = ReplicationTestUtil - .createReplicas(Pair.of(IN_SERVICE, 1), - Pair.of(IN_SERVICE, 2), Pair.of(IN_SERVICE, 3), - Pair.of(DECOMMISSIONING, 4), Pair.of(DECOMMISSIONING, 5)); + .createReplicas(new TestEntry<>(IN_SERVICE, 1), + new TestEntry<>(IN_SERVICE, 2), new TestEntry<>(IN_SERVICE, 3), + new TestEntry<>(DECOMMISSIONING, 4), new TestEntry<>(DECOMMISSIONING, 5)); PlacementPolicy placementPolicy = ReplicationTestUtil .getInsufficientNodesTestPlacementPolicy(nodeManager, conf, 2); ECUnderReplicationHandler ecURH = new ECUnderReplicationHandler( @@ -783,9 +781,9 @@ public void testPartialDecommissionIfNotEnoughNodes() { @Test public void testPartialDecommissionOverloadedNodes() { Set availableReplicas = ReplicationTestUtil - .createReplicas(Pair.of(IN_SERVICE, 1), - Pair.of(IN_SERVICE, 2), Pair.of(IN_SERVICE, 3), - Pair.of(DECOMMISSIONING, 4), Pair.of(DECOMMISSIONING, 5)); + .createReplicas(new TestEntry<>(IN_SERVICE, 1), + new TestEntry<>(IN_SERVICE, 2), new TestEntry<>(IN_SERVICE, 3), + new TestEntry<>(DECOMMISSIONING, 4), new TestEntry<>(DECOMMISSIONING, 5)); ECUnderReplicationHandler ecURH = new ECUnderReplicationHandler( policy, conf, replicationManager); @@ -811,10 +809,10 @@ public void testPartialDecommissionOverloadedNodes() { @Test public void testPartialMaintenanceIfNotEnoughNodes() { Set availableReplicas = ReplicationTestUtil - .createReplicas(Pair.of(IN_SERVICE, 1), - Pair.of(IN_SERVICE, 2), Pair.of(IN_SERVICE, 3), - Pair.of(ENTERING_MAINTENANCE, 4), - Pair.of(ENTERING_MAINTENANCE, 5)); + .createReplicas(new TestEntry<>(IN_SERVICE, 1), + new TestEntry<>(IN_SERVICE, 2), new TestEntry<>(IN_SERVICE, 3), + new TestEntry<>(ENTERING_MAINTENANCE, 4), + new TestEntry<>(ENTERING_MAINTENANCE, 5)); PlacementPolicy placementPolicy = ReplicationTestUtil .getInsufficientNodesTestPlacementPolicy(nodeManager, conf, 2); ECUnderReplicationHandler ecURH = new ECUnderReplicationHandler( @@ -838,10 +836,10 @@ public void testPartialMaintenanceIfNotEnoughNodes() { @Test public void testPartialMaintenanceOverloadedNodes() { Set availableReplicas = ReplicationTestUtil - .createReplicas(Pair.of(IN_SERVICE, 1), - Pair.of(IN_SERVICE, 2), Pair.of(IN_SERVICE, 3), - Pair.of(ENTERING_MAINTENANCE, 4), - Pair.of(ENTERING_MAINTENANCE, 5)); + .createReplicas(new TestEntry<>(IN_SERVICE, 1), + new TestEntry<>(IN_SERVICE, 2), new TestEntry<>(IN_SERVICE, 3), + new TestEntry<>(ENTERING_MAINTENANCE, 4), + new TestEntry<>(ENTERING_MAINTENANCE, 5)); ECUnderReplicationHandler ecURH = new ECUnderReplicationHandler( policy, conf, replicationManager); @@ -900,8 +898,8 @@ public void testUnderRepWithDecommissionAndNotEnoughNodes() // entering_maintenance replica 5. Set availableReplicas = ReplicationTestUtil .createReplicas( - Pair.of(IN_SERVICE, 2), Pair.of(IN_SERVICE, 3), - Pair.of(IN_SERVICE, 4), Pair.of(IN_SERVICE, 4)); + new TestEntry<>(IN_SERVICE, 2), new TestEntry<>(IN_SERVICE, 3), + new TestEntry<>(IN_SERVICE, 4), new TestEntry<>(IN_SERVICE, 4)); if (toAdd != null) { availableReplicas.add(toAdd); } @@ -913,12 +911,12 @@ public void testUnderRepWithDecommissionAndNotEnoughNodes() verify(replicationManager, times(1)) .processOverReplicatedContainer(underRep); assertEquals(1, commandsSent.size()); - Pair> pair = + TestEntry> commandEntry = commandsSent.iterator().next(); - assertEquals(newNode, pair.getKey()); + assertEquals(newNode, commandEntry.getKey()); assertEquals( SCMCommandProto.Type.reconstructECContainersCommand, - pair.getValue().getType()); + commandEntry.getValue().getType()); clearInvocations(replicationManager); commandsSent.clear(); } @@ -933,9 +931,9 @@ public void testUnderRepDueToDecomAndOverRep() // found. This will cause an exception to be thrown out, as the container is // not also over replicated. Set availableReplicas = ReplicationTestUtil - .createReplicas(Pair.of(IN_SERVICE, 1), - Pair.of(IN_SERVICE, 2), Pair.of(IN_SERVICE, 3), - Pair.of(IN_SERVICE, 4), Pair.of(DECOMMISSIONING, 5)); + .createReplicas(new TestEntry<>(IN_SERVICE, 1), + new TestEntry<>(IN_SERVICE, 2), new TestEntry<>(IN_SERVICE, 3), + new TestEntry<>(IN_SERVICE, 4), new TestEntry<>(DECOMMISSIONING, 5)); ECUnderReplicationHandler ecURH = new ECUnderReplicationHandler( @@ -956,8 +954,8 @@ public void testUnderRepDueToDecomAndOverRep() 4, IN_SERVICE, CLOSED); availableReplicas.add(overRepReplica); - Set>> expectedDelete = new HashSet<>(); - expectedDelete.add(Pair.of(overRepReplica.getDatanodeDetails(), + Set>> expectedDelete = new HashSet<>(); + expectedDelete.add(new TestEntry<>(overRepReplica.getDatanodeDetails(), createDeleteContainerCommand(container, overRepReplica.getReplicaIndex()))); @@ -981,9 +979,9 @@ public void testMissingAndDecomIndexWithOnlyOneNewNodeAvailable() .getSameNodeTestPlacementPolicy(nodeManager, conf, newDn); // Just have a missing index, this should return OK. Set availableReplicas = ReplicationTestUtil - .createReplicas(Pair.of(IN_SERVICE, 1), - Pair.of(IN_SERVICE, 2), Pair.of(IN_SERVICE, 3), - Pair.of(IN_SERVICE, 4)); + .createReplicas(new TestEntry<>(IN_SERVICE, 1), + new TestEntry<>(IN_SERVICE, 2), new TestEntry<>(IN_SERVICE, 3), + new TestEntry<>(IN_SERVICE, 4)); // Passing zero for decommIndexes, as we don't expect the decom command to // get created due to the placement policy returning an already used node testUnderReplicationWithMissingIndexes(ImmutableList.of(5), @@ -995,9 +993,9 @@ public void testMissingAndDecomIndexWithOnlyOneNewNodeAvailable() // come up the stack and be thrown out to indicate this container must be // retried. Set replicas = ReplicationTestUtil - .createReplicas(Pair.of(DECOMMISSIONING, 1), - Pair.of(IN_SERVICE, 2), Pair.of(IN_SERVICE, 3), - Pair.of(IN_SERVICE, 4), Pair.of(IN_SERVICE, 4)); + .createReplicas(new TestEntry<>(DECOMMISSIONING, 1), + new TestEntry<>(IN_SERVICE, 2), new TestEntry<>(IN_SERVICE, 3), + new TestEntry<>(IN_SERVICE, 4), new TestEntry<>(IN_SERVICE, 4)); assertThrows(SCMException.class, () -> testUnderReplicationWithMissingIndexes(ImmutableList.of(5), replicas, @@ -1007,10 +1005,10 @@ public void testMissingAndDecomIndexWithOnlyOneNewNodeAvailable() @Test public void testUnderAndOverReplication() throws IOException { Set availableReplicas = ReplicationTestUtil - .createReplicas(Pair.of(DECOMMISSIONING, 1), Pair.of(IN_SERVICE, 1), - Pair.of(IN_MAINTENANCE, 1), Pair.of(IN_MAINTENANCE, 1), - Pair.of(IN_SERVICE, 4), Pair.of(IN_SERVICE, 5)); - Set>> cmds = + .createReplicas(new TestEntry<>(DECOMMISSIONING, 1), new TestEntry<>(IN_SERVICE, 1), + new TestEntry<>(IN_MAINTENANCE, 1), new TestEntry<>(IN_MAINTENANCE, 1), + new TestEntry<>(IN_SERVICE, 4), new TestEntry<>(IN_SERVICE, 5)); + Set>> cmds = testUnderReplicationWithMissingIndexes(ImmutableList.of(2, 3), availableReplicas, 0, 0, policy); assertEquals(1, cmds.size()); @@ -1033,9 +1031,9 @@ public void testUnderAndOverReplication() throws IOException { @Test public void testMaintenanceDoesNotRequestZeroNodes() throws IOException { Set availableReplicas = ReplicationTestUtil - .createReplicas(Pair.of(DECOMMISSIONING, 1), Pair.of(IN_SERVICE, 2), - Pair.of(IN_MAINTENANCE, 3), Pair.of(IN_SERVICE, 4), - Pair.of(IN_SERVICE, 5)); + .createReplicas(new TestEntry<>(DECOMMISSIONING, 1), new TestEntry<>(IN_SERVICE, 2), + new TestEntry<>(IN_MAINTENANCE, 3), new TestEntry<>(IN_SERVICE, 4), + new TestEntry<>(IN_SERVICE, 5)); when(ecPlacementPolicy.chooseDatanodes(anyList(), anyList(), isNull(), anyInt(), anyLong(), anyLong())) @@ -1110,11 +1108,11 @@ public void testDatanodesPendingAddAreNotSelectedAsTargets() public void testDecommissioningIndexCopiedWhenContainerUnRecoverable() throws IOException { Set availableReplicas = ReplicationTestUtil - .createReplicas(Pair.of(IN_SERVICE, 1)); + .createReplicas(new TestEntry<>(IN_SERVICE, 1)); ContainerReplica decomReplica = createContainerReplica( container.containerID(), 2, DECOMMISSIONING, CLOSED); availableReplicas.add(decomReplica); - Set>> cmds = + Set>> cmds = testUnderReplicationWithMissingIndexes(emptyList(), availableReplicas, 1, 0, policy); assertEquals(1, cmds.size()); @@ -1128,12 +1126,12 @@ public void testDecommissioningIndexCopiedWhenContainerUnRecoverable() public void testMaintenanceIndexCopiedWhenContainerUnRecoverable() throws IOException { Set availableReplicas = ReplicationTestUtil - .createReplicas(Pair.of(IN_SERVICE, 1)); + .createReplicas(new TestEntry<>(IN_SERVICE, 1)); ContainerReplica maintReplica = createContainerReplica( container.containerID(), 2, ENTERING_MAINTENANCE, CLOSED); availableReplicas.add(maintReplica); - Set>> cmds = + Set>> cmds = testUnderReplicationWithMissingIndexes(emptyList(), availableReplicas, 0, 1, policy); assertEquals(0, cmds.size()); @@ -1150,7 +1148,7 @@ public void testMaintenanceIndexCopiedWhenContainerUnRecoverable() assertEquals(maintReplica.getDatanodeDetails(), target); } - public Set>> + public Set>> testUnderReplicationWithMissingIndexes( List missingIndexes, Set availableReplicas, int decomIndexes, int maintenanceIndexes, @@ -1170,7 +1168,7 @@ public void testMaintenanceIndexCopiedWhenContainerUnRecoverable() boolean shouldReconstructCommandExist = !missingIndexes.isEmpty() && missingIndexes.size() <= repConfig .getParity(); - for (Map.Entry> dnCommand : commandsSent) { + for (TestEntry> dnCommand : commandsSent) { if (dnCommand.getValue() instanceof ReplicateContainerCommand) { replicateCommand++; } else if (dnCommand diff --git a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/TestQuasiClosedStuckOverReplicationHandler.java b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/TestQuasiClosedStuckOverReplicationHandler.java index b1aa7491673..4310036b0fa 100644 --- a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/TestQuasiClosedStuckOverReplicationHandler.java +++ b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/TestQuasiClosedStuckOverReplicationHandler.java @@ -33,7 +33,6 @@ import java.util.List; import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; -import org.apache.commons.lang3.tuple.Pair; import org.apache.hadoop.hdds.client.RatisReplicationConfig; import org.apache.hadoop.hdds.conf.OzoneConfiguration; import org.apache.hadoop.hdds.protocol.DatanodeDetails; @@ -46,6 +45,7 @@ import org.apache.hadoop.hdds.scm.node.NodeStatus; import org.apache.hadoop.hdds.scm.node.states.NodeNotFoundException; import org.apache.hadoop.ozone.protocol.commands.SCMCommand; +import org.apache.ozone.test.TestEntry; import org.apache.ratis.protocol.exceptions.NotLeaderException; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -58,7 +58,7 @@ public class TestQuasiClosedStuckOverReplicationHandler { private static final RatisReplicationConfig RATIS_REPLICATION_CONFIG = RatisReplicationConfig.getInstance(THREE); private ContainerInfo container; private ReplicationManager replicationManager; - private Set>> commandsSent; + private Set>> commandsSent; private QuasiClosedStuckOverReplicationHandler handler; private final DatanodeID origin1 = DatanodeID.randomID(); private final DatanodeID origin2 = DatanodeID.randomID(); @@ -98,10 +98,10 @@ void setup() throws NodeNotFoundException, public void testReturnsZeroIfNotOverReplicated() throws IOException { Set replicas = ReplicationTestUtil.createReplicasWithOriginAndOpState(container.containerID(), QUASI_CLOSED, - Pair.of(origin1, IN_SERVICE), - Pair.of(origin1, IN_SERVICE), - Pair.of(origin2, IN_SERVICE), - Pair.of(origin2, IN_SERVICE)); + new TestEntry<>(origin1, IN_SERVICE), + new TestEntry<>(origin1, IN_SERVICE), + new TestEntry<>(origin2, IN_SERVICE), + new TestEntry<>(origin2, IN_SERVICE)); int count = handler.processAndSendCommands(replicas, Collections.emptyList(), getOverReplicatedHealthResult(), 1); assertEquals(0, count); @@ -111,12 +111,12 @@ public void testReturnsZeroIfNotOverReplicated() throws IOException { public void testNoCommandsScheduledIfPendingOps() throws IOException { Set replicas = ReplicationTestUtil.createReplicasWithOriginAndOpState(container.containerID(), QUASI_CLOSED, - Pair.of(origin1, IN_SERVICE), - Pair.of(origin1, IN_SERVICE), - Pair.of(origin1, IN_SERVICE), - Pair.of(origin2, IN_SERVICE), - Pair.of(origin2, IN_SERVICE), - Pair.of(origin2, IN_SERVICE)); + new TestEntry<>(origin1, IN_SERVICE), + new TestEntry<>(origin1, IN_SERVICE), + new TestEntry<>(origin1, IN_SERVICE), + new TestEntry<>(origin2, IN_SERVICE), + new TestEntry<>(origin2, IN_SERVICE), + new TestEntry<>(origin2, IN_SERVICE)); List pendingOps = new ArrayList<>(); pendingOps.add(new ContainerReplicaOp( ContainerReplicaOp.PendingOpType.DELETE, @@ -150,7 +150,7 @@ public void testCommandScheduledForOverReplicatedContainer() throws IOException int count = handler.processAndSendCommands(replicas, Collections.emptyList(), getOverReplicatedHealthResult(), 1); assertEquals(1, count); - SCMCommand command = commandsSent.iterator().next().getRight(); + SCMCommand command = commandsSent.iterator().next().getValue(); assertEquals(StorageContainerDatanodeProtocolProtos.SCMCommandProto.Type.deleteContainerCommand, command.getType()); } diff --git a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/TestQuasiClosedStuckReplicaCount.java b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/TestQuasiClosedStuckReplicaCount.java index bfa27006d54..d5a327b5128 100644 --- a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/TestQuasiClosedStuckReplicaCount.java +++ b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/TestQuasiClosedStuckReplicaCount.java @@ -30,10 +30,10 @@ import java.util.HashSet; import java.util.List; import java.util.Set; -import org.apache.commons.lang3.tuple.Pair; import org.apache.hadoop.hdds.protocol.DatanodeID; import org.apache.hadoop.hdds.scm.container.ContainerID; import org.apache.hadoop.hdds.scm.container.ContainerReplica; +import org.apache.ozone.test.TestEntry; import org.junit.jupiter.api.Test; /** @@ -80,9 +80,12 @@ public void testCorrectReplicationWithTwoOrigins() { @Test public void testCorrectReplicationWithOneOrigin() { - Set replicas = ReplicationTestUtil.createReplicasWithOriginAndOpState( - ContainerID.valueOf(1), QUASI_CLOSED, - Pair.of(origin1, IN_SERVICE), Pair.of(origin1, IN_SERVICE), Pair.of(origin1, IN_SERVICE)); + Set replicas = + ReplicationTestUtil.createReplicasWithOriginAndOpState( + ContainerID.valueOf(1), QUASI_CLOSED, + new TestEntry<>(origin1, IN_SERVICE), + new TestEntry<>(origin1, IN_SERVICE), + new TestEntry<>(origin1, IN_SERVICE)); QuasiClosedStuckReplicaCount replicaCount = new QuasiClosedStuckReplicaCount(replicas, 1, 3, 2); assertFalse(replicaCount.isUnderReplicated()); @@ -155,7 +158,7 @@ public void testUnderReplicationWithTwoOrigins() { public void testUnderReplicationWithOneOrigin() { Set replicas = ReplicationTestUtil.createReplicasWithOriginAndOpState( ContainerID.valueOf(1), QUASI_CLOSED, - Pair.of(origin1, IN_SERVICE)); + new TestEntry<>(origin1, IN_SERVICE)); QuasiClosedStuckReplicaCount replicaCount = new QuasiClosedStuckReplicaCount(replicas, 1, 3, 2); assertTrue(replicaCount.isUnderReplicated()); @@ -200,10 +203,13 @@ public void testOverReplicationWithTwoOrigins() { @Test public void testOverReplicationWithOneOrigin() { - Set replicas = ReplicationTestUtil.createReplicasWithOriginAndOpState( - ContainerID.valueOf(1), QUASI_CLOSED, - Pair.of(origin1, IN_SERVICE), Pair.of(origin1, IN_SERVICE), Pair.of(origin1, IN_SERVICE), - Pair.of(origin1, IN_SERVICE)); + Set replicas = + ReplicationTestUtil.createReplicasWithOriginAndOpState( + ContainerID.valueOf(1), QUASI_CLOSED, + new TestEntry<>(origin1, IN_SERVICE), + new TestEntry<>(origin1, IN_SERVICE), + new TestEntry<>(origin1, IN_SERVICE), + new TestEntry<>(origin1, IN_SERVICE)); QuasiClosedStuckReplicaCount replicaCount = new QuasiClosedStuckReplicaCount(replicas, 1, 3, 2); assertFalse(replicaCount.isUnderReplicated()); @@ -249,9 +255,12 @@ public void testUnderReplicationDueToDecommissionWithTwoOrigins() { @Test public void testUnderReplicationDueToDecommissionWithOneOrigin() { - Set replicas = ReplicationTestUtil.createReplicasWithOriginAndOpState( - ContainerID.valueOf(1), QUASI_CLOSED, - Pair.of(origin1, IN_SERVICE), Pair.of(origin1, DECOMMISSIONING), Pair.of(origin1, DECOMMISSIONING)); + Set replicas = + ReplicationTestUtil.createReplicasWithOriginAndOpState( + ContainerID.valueOf(1), QUASI_CLOSED, + new TestEntry<>(origin1, IN_SERVICE), + new TestEntry<>(origin1, DECOMMISSIONING), + new TestEntry<>(origin1, DECOMMISSIONING)); QuasiClosedStuckReplicaCount replicaCount = new QuasiClosedStuckReplicaCount(replicas, 1, 3, 2); assertTrue(replicaCount.isUnderReplicated()); @@ -298,10 +307,13 @@ public void testNoOverReplicationWithOutOfServiceReplicasWithTwoOrigins() { @Test public void testNoOverReplicationWithOutOfServiceReplicasWithOneOrigin() { - Set replicas = ReplicationTestUtil.createReplicasWithOriginAndOpState( - ContainerID.valueOf(1), QUASI_CLOSED, - Pair.of(origin1, IN_SERVICE), Pair.of(origin1, IN_SERVICE), Pair.of(origin1, IN_SERVICE), - Pair.of(origin1, DECOMMISSIONED)); + Set replicas = + ReplicationTestUtil.createReplicasWithOriginAndOpState( + ContainerID.valueOf(1), QUASI_CLOSED, + new TestEntry<>(origin1, IN_SERVICE), + new TestEntry<>(origin1, IN_SERVICE), + new TestEntry<>(origin1, IN_SERVICE), + new TestEntry<>(origin1, DECOMMISSIONED)); QuasiClosedStuckReplicaCount replicaCount = new QuasiClosedStuckReplicaCount(replicas, 1, 3, 2); assertFalse(replicaCount.isUnderReplicated()); @@ -310,17 +322,23 @@ public void testNoOverReplicationWithOutOfServiceReplicasWithOneOrigin() { @Test public void testUnderReplicationWithMaintenanceWithOneOrigin() { - Set replicas = ReplicationTestUtil.createReplicasWithOriginAndOpState( - ContainerID.valueOf(1), QUASI_CLOSED, - Pair.of(origin1, IN_SERVICE), Pair.of(origin1, IN_SERVICE), Pair.of(origin1, ENTERING_MAINTENANCE)); + Set replicas = + ReplicationTestUtil.createReplicasWithOriginAndOpState( + ContainerID.valueOf(1), QUASI_CLOSED, + new TestEntry<>(origin1, IN_SERVICE), + new TestEntry<>(origin1, IN_SERVICE), + new TestEntry<>(origin1, ENTERING_MAINTENANCE)); QuasiClosedStuckReplicaCount replicaCount = new QuasiClosedStuckReplicaCount(replicas, 1, 3, 2); assertFalse(replicaCount.isUnderReplicated()); assertFalse(replicaCount.isOverReplicated()); - replicas = ReplicationTestUtil.createReplicasWithOriginAndOpState( - ContainerID.valueOf(1), QUASI_CLOSED, - Pair.of(origin1, IN_SERVICE), Pair.of(origin1, ENTERING_MAINTENANCE), Pair.of(origin1, ENTERING_MAINTENANCE)); + replicas = + ReplicationTestUtil.createReplicasWithOriginAndOpState( + ContainerID.valueOf(1), QUASI_CLOSED, + new TestEntry<>(origin1, IN_SERVICE), + new TestEntry<>(origin1, ENTERING_MAINTENANCE), + new TestEntry<>(origin1, ENTERING_MAINTENANCE)); replicaCount = new QuasiClosedStuckReplicaCount(replicas, 2, 3, 2); assertTrue(replicaCount.isUnderReplicated()); @@ -379,10 +397,13 @@ public void testNoOverReplicationWithExcessMaintenanceReplicasTwoOrigins() { @Test public void testNoOverReplicationWithExcessMaintenanceReplicasOneOrigin() { - Set replicas = ReplicationTestUtil.createReplicasWithOriginAndOpState( - ContainerID.valueOf(1), QUASI_CLOSED, - Pair.of(origin1, IN_SERVICE), Pair.of(origin1, IN_SERVICE), Pair.of(origin1, IN_SERVICE), - Pair.of(origin1, IN_MAINTENANCE)); + Set replicas = + ReplicationTestUtil.createReplicasWithOriginAndOpState( + ContainerID.valueOf(1), QUASI_CLOSED, + new TestEntry<>(origin1, IN_SERVICE), + new TestEntry<>(origin1, IN_SERVICE), + new TestEntry<>(origin1, IN_SERVICE), + new TestEntry<>(origin1, IN_MAINTENANCE)); QuasiClosedStuckReplicaCount replicaCount = new QuasiClosedStuckReplicaCount(replicas, 1, 3, 2); assertFalse(replicaCount.isUnderReplicated()); diff --git a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/TestQuasiClosedStuckUnderReplicationHandler.java b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/TestQuasiClosedStuckUnderReplicationHandler.java index 73734b37367..d35617e3730 100644 --- a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/TestQuasiClosedStuckUnderReplicationHandler.java +++ b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/TestQuasiClosedStuckUnderReplicationHandler.java @@ -34,7 +34,6 @@ import java.util.List; import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; -import org.apache.commons.lang3.tuple.Pair; import org.apache.hadoop.hdds.client.RatisReplicationConfig; import org.apache.hadoop.hdds.conf.OzoneConfiguration; import org.apache.hadoop.hdds.protocol.DatanodeDetails; @@ -51,6 +50,7 @@ import org.apache.hadoop.hdds.scm.pipeline.InsufficientDatanodesException; import org.apache.hadoop.ozone.container.common.SCMTestUtils; import org.apache.hadoop.ozone.protocol.commands.SCMCommand; +import org.apache.ozone.test.TestEntry; import org.apache.ratis.protocol.exceptions.NotLeaderException; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -66,7 +66,7 @@ public class TestQuasiClosedStuckUnderReplicationHandler { private NodeManager nodeManager; private OzoneConfiguration conf; private ReplicationManager replicationManager; - private Set>> commandsSent; + private Set>> commandsSent; private QuasiClosedStuckUnderReplicationHandler handler; @BeforeEach @@ -113,8 +113,12 @@ void setup(@TempDir File testDir) throws NodeNotFoundException, @Test public void testReturnsZeroIfNotUnderReplicated() throws IOException { final DatanodeID origin = DatanodeID.randomID(); - Set replicas = ReplicationTestUtil.createReplicasWithOriginAndOpState(container.containerID(), - QUASI_CLOSED, Pair.of(origin, IN_SERVICE), Pair.of(origin, IN_SERVICE), Pair.of(origin, IN_SERVICE)); + Set replicas = + ReplicationTestUtil.createReplicasWithOriginAndOpState( + container.containerID(), QUASI_CLOSED, + new TestEntry<>(origin, IN_SERVICE), + new TestEntry<>(origin, IN_SERVICE), + new TestEntry<>(origin, IN_SERVICE)); int count = handler.processAndSendCommands(replicas, Collections.emptyList(), getUnderReplicatedHealthResult(), 1); assertEquals(0, count); @@ -124,7 +128,7 @@ public void testReturnsZeroIfNotUnderReplicated() throws IOException { public void testNoCommandsScheduledIfPendingOps() throws IOException { final DatanodeID origin = DatanodeID.randomID(); Set replicas = ReplicationTestUtil.createReplicasWithOriginAndOpState(container.containerID(), - QUASI_CLOSED, Pair.of(origin, IN_SERVICE), Pair.of(origin, IN_SERVICE)); + QUASI_CLOSED, new TestEntry<>(origin, IN_SERVICE), new TestEntry<>(origin, IN_SERVICE)); List pendingOps = new ArrayList<>(); pendingOps.add(new ContainerReplicaOp( ContainerReplicaOp.PendingOpType.ADD, MockDatanodeDetails.randomDatanodeDetails(), 0, null, Long.MAX_VALUE, 0)); @@ -137,7 +141,7 @@ public void testNoCommandsScheduledIfPendingOps() throws IOException { public void testCommandScheduledForUnderReplicatedContainer() throws IOException { final DatanodeID origin = DatanodeID.randomID(); Set replicas = ReplicationTestUtil.createReplicasWithOriginAndOpState(container.containerID(), - QUASI_CLOSED, Pair.of(origin, IN_SERVICE)); + QUASI_CLOSED, new TestEntry<>(origin, IN_SERVICE)); int count = handler.processAndSendCommands(replicas, Collections.emptyList(), getUnderReplicatedHealthResult(), 1); assertEquals(2, count); @@ -168,7 +172,7 @@ public void testInsufficientNodesExceptionThrown() { final DatanodeID origin1 = DatanodeID.randomID(); final DatanodeID origin2 = DatanodeID.randomID(); Set replicas = ReplicationTestUtil.createReplicasWithOriginAndOpState(container.containerID(), - QUASI_CLOSED, Pair.of(origin1, IN_SERVICE), Pair.of(origin2, IN_SERVICE)); + QUASI_CLOSED, new TestEntry<>(origin1, IN_SERVICE), new TestEntry<>(origin2, IN_SERVICE)); PlacementPolicy policy = ReplicationTestUtil.getNoNodesTestPlacementPolicy(nodeManager, conf); handler = new QuasiClosedStuckUnderReplicationHandler(policy, conf, replicationManager); @@ -182,7 +186,7 @@ public void testInsufficientNodesExceptionThrown() { public void testPartialReplicationExceptionThrown() { final DatanodeID origin1 = DatanodeID.randomID(); Set replicas = ReplicationTestUtil.createReplicasWithOriginAndOpState(container.containerID(), - QUASI_CLOSED, Pair.of(origin1, IN_SERVICE)); + QUASI_CLOSED, new TestEntry<>(origin1, IN_SERVICE)); PlacementPolicy policy = ReplicationTestUtil.getInsufficientNodesTestPlacementPolicy(nodeManager, conf, 2); handler = new QuasiClosedStuckUnderReplicationHandler(policy, conf, replicationManager); diff --git a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/TestRatisMisReplicationHandler.java b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/TestRatisMisReplicationHandler.java index e5b25f8be4d..003f78ac106 100644 --- a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/TestRatisMisReplicationHandler.java +++ b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/TestRatisMisReplicationHandler.java @@ -35,7 +35,6 @@ import java.util.List; import java.util.Map; import java.util.Set; -import org.apache.commons.lang3.tuple.Pair; import org.apache.hadoop.hdds.client.RatisReplicationConfig; import org.apache.hadoop.hdds.conf.OzoneConfiguration; import org.apache.hadoop.hdds.protocol.DatanodeDetails; @@ -47,6 +46,7 @@ import org.apache.hadoop.hdds.scm.container.ContainerReplica; import org.apache.hadoop.hdds.scm.exceptions.SCMException; import org.apache.hadoop.hdds.scm.node.states.NodeNotFoundException; +import org.apache.ozone.test.TestEntry; import org.apache.ratis.protocol.exceptions.NotLeaderException; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -72,8 +72,8 @@ void setup(@TempDir File testDir) throws NodeNotFoundException, public void testMisReplicationWithAllNodesAvailable(int misreplicationCount) throws IOException { Set availableReplicas = ReplicationTestUtil - .createReplicas(Pair.of(IN_SERVICE, 0), Pair.of(IN_SERVICE, 0), - Pair.of(IN_SERVICE, 0)); + .createReplicas(new TestEntry<>(IN_SERVICE, 0), new TestEntry<>(IN_SERVICE, 0), + new TestEntry<>(IN_SERVICE, 0)); testMisReplication(availableReplicas, Collections.emptyList(), 0, misreplicationCount, Math.min(misreplicationCount, 3)); } @@ -83,8 +83,8 @@ public void testMisReplicationWithAllNodesAvailable(int misreplicationCount) public void testMisReplicationWithAllNodesAvailableQuasiClosed( int misreplicationCount) throws IOException { Set availableReplicas = ReplicationTestUtil - .createReplicas(State.QUASI_CLOSED, Pair.of(IN_SERVICE, 0), - Pair.of(IN_SERVICE, 0), Pair.of(IN_SERVICE, 0)); + .createReplicas(State.QUASI_CLOSED, new TestEntry<>(IN_SERVICE, 0), + new TestEntry<>(IN_SERVICE, 0), new TestEntry<>(IN_SERVICE, 0)); testMisReplication(availableReplicas, Collections.emptyList(), 0, misreplicationCount, Math.min(misreplicationCount, 3)); } @@ -92,8 +92,8 @@ public void testMisReplicationWithAllNodesAvailableQuasiClosed( @Test public void testMisReplicationWithNoNodesReturned() throws IOException { Set availableReplicas = ReplicationTestUtil - .createReplicas(Pair.of(IN_SERVICE, 0), Pair.of(IN_SERVICE, 0), - Pair.of(IN_SERVICE, 0)); + .createReplicas(new TestEntry<>(IN_SERVICE, 0), new TestEntry<>(IN_SERVICE, 0), + new TestEntry<>(IN_SERVICE, 0)); PlacementPolicy placementPolicy = mock(PlacementPolicy.class); ContainerPlacementStatus mockedContainerPlacementStatus = mock(ContainerPlacementStatus.class); when(mockedContainerPlacementStatus.isPolicySatisfied()).thenReturn(false); @@ -113,8 +113,8 @@ public void testMisReplicationWithNoNodesReturned() throws IOException { public void testMisReplicationWithSomeNodesNotInService( int misreplicationCount) throws IOException { Set availableReplicas = ReplicationTestUtil - .createReplicas(Pair.of(IN_SERVICE, 0), Pair.of(IN_SERVICE, 0), - Pair.of(IN_MAINTENANCE, 0)); + .createReplicas(new TestEntry<>(IN_SERVICE, 0), new TestEntry<>(IN_SERVICE, 0), + new TestEntry<>(IN_MAINTENANCE, 0)); testMisReplication(availableReplicas, Collections.emptyList(), 0, misreplicationCount, Math.min(misreplicationCount, 2)); } @@ -122,16 +122,16 @@ public void testMisReplicationWithSomeNodesNotInService( @Test public void testMisReplicationWithUndereplication() throws IOException { Set availableReplicas = ReplicationTestUtil - .createReplicas(Pair.of(IN_SERVICE, 0), - Pair.of(IN_SERVICE, 0)); + .createReplicas(new TestEntry<>(IN_SERVICE, 0), + new TestEntry<>(IN_SERVICE, 0)); testMisReplication(availableReplicas, Collections.emptyList(), 0, 1, 0); } @Test public void testMisReplicationWithOvereplication() throws IOException { Set availableReplicas = ReplicationTestUtil - .createReplicas(Pair.of(IN_SERVICE, 0), Pair.of(IN_SERVICE, 0), - Pair.of(IN_SERVICE, 0), Pair.of(IN_SERVICE, 0)); + .createReplicas(new TestEntry<>(IN_SERVICE, 0), new TestEntry<>(IN_SERVICE, 0), + new TestEntry<>(IN_SERVICE, 0), new TestEntry<>(IN_SERVICE, 0)); testMisReplication(availableReplicas, Collections.emptyList(), 0, 1, 0); } @@ -139,8 +139,8 @@ public void testMisReplicationWithOvereplication() throws IOException { public void testMisReplicationWithSatisfiedPlacementPolicy() throws IOException { Set availableReplicas = ReplicationTestUtil - .createReplicas(Pair.of(IN_SERVICE, 0), Pair.of(IN_SERVICE, 0), - Pair.of(IN_SERVICE, 0)); + .createReplicas(new TestEntry<>(IN_SERVICE, 0), new TestEntry<>(IN_SERVICE, 0), + new TestEntry<>(IN_SERVICE, 0)); PlacementPolicy placementPolicy = mock(PlacementPolicy.class); ContainerPlacementStatus mockedContainerPlacementStatus = mock(ContainerPlacementStatus.class); when(mockedContainerPlacementStatus.isPolicySatisfied()).thenReturn(true); @@ -154,8 +154,8 @@ public void testMisReplicationWithSatisfiedPlacementPolicy() public void testMisReplicationWithPendingOps() throws IOException { Set availableReplicas = ReplicationTestUtil - .createReplicas(Pair.of(IN_SERVICE, 0), Pair.of(IN_SERVICE, 0), - Pair.of(IN_SERVICE, 0)); + .createReplicas(new TestEntry<>(IN_SERVICE, 0), new TestEntry<>(IN_SERVICE, 0), + new TestEntry<>(IN_SERVICE, 0)); PlacementPolicy placementPolicy = mock(PlacementPolicy.class); ContainerPlacementStatus mockedContainerPlacementStatus = mock(ContainerPlacementStatus.class); when(mockedContainerPlacementStatus.isPolicySatisfied()).thenReturn(true); @@ -181,8 +181,8 @@ public void testAllSourcesOverloaded() throws IOException { anyList(), any(), anyInt()); Set availableReplicas = ReplicationTestUtil - .createReplicas(Pair.of(IN_SERVICE, 0), Pair.of(IN_SERVICE, 0), - Pair.of(IN_SERVICE, 0)); + .createReplicas(new TestEntry<>(IN_SERVICE, 0), new TestEntry<>(IN_SERVICE, 0), + new TestEntry<>(IN_SERVICE, 0)); assertThrows(CommandTargetOverloadedException.class, () -> testMisReplication(availableReplicas, mockPlacementPolicy(), Collections.emptyList(), 0, 1, 1, 0)); diff --git a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/TestRatisOverReplicationHandler.java b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/TestRatisOverReplicationHandler.java index 84dabae7686..0327b979814 100644 --- a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/TestRatisOverReplicationHandler.java +++ b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/TestRatisOverReplicationHandler.java @@ -47,7 +47,6 @@ import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; import java.util.stream.Collectors; -import org.apache.commons.lang3.tuple.Pair; import org.apache.hadoop.hdds.client.RatisReplicationConfig; import org.apache.hadoop.hdds.protocol.DatanodeDetails; import org.apache.hadoop.hdds.protocol.MockDatanodeDetails; @@ -63,6 +62,7 @@ import org.apache.hadoop.ozone.protocol.commands.DeleteContainerCommand; import org.apache.hadoop.ozone.protocol.commands.SCMCommand; import org.apache.ozone.test.GenericTestUtils; +import org.apache.ozone.test.TestEntry; import org.apache.ratis.protocol.exceptions.NotLeaderException; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -78,7 +78,7 @@ public class TestRatisOverReplicationHandler { RatisReplicationConfig.getInstance(HddsProtos.ReplicationFactor.THREE); private PlacementPolicy policy; private ReplicationManager replicationManager; - private Set>> commandsSent; + private Set>> commandsSent; @BeforeEach public void setup() throws NodeNotFoundException, NotLeaderException, @@ -238,11 +238,11 @@ public void testClosedOverReplicatedWithExcessUnhealthy() throws IOException { State.UNHEALTHY); replicas.add(unhealthyReplica); - Set>> commands = + Set>> commands = testProcessing(replicas, Collections.emptyList(), getOverReplicatedHealthResult(), 1); - Pair> command = commands.iterator().next(); + TestEntry> command = commands.iterator().next(); assertEquals(unhealthyReplica.getDatanodeDetails(), command.getKey()); } @@ -310,13 +310,13 @@ public void testOverReplicatedAllUnhealthySameBCSID() .sorted(Comparator.comparingLong(ContainerReplica::hashCode)) .findFirst().get(); - Set>> commands = + Set>> commands = testProcessing(replicas, Collections.emptyList(), getOverReplicatedHealthResult(), 1); - Pair> commandPair + TestEntry> commandEntry = commands.iterator().next(); assertEquals(shouldDelete.getDatanodeDetails(), - commandPair.getKey()); + commandEntry.getKey()); } @Test @@ -331,13 +331,13 @@ public void testOverReplicatedAllUnhealthyPicksLowestBCSID() replicas.add(createContainerReplica(container.containerID(), 0, IN_SERVICE, State.UNHEALTHY, sequenceID + i)); } - Set>> commands = + Set>> commands = testProcessing(replicas, Collections.emptyList(), getOverReplicatedHealthResult(), 1); - Pair> commandPair + TestEntry> commandEntry = commands.iterator().next(); assertEquals(lowestSequenceIDReplica.getDatanodeDetails(), - commandPair.getKey()); + commandEntry.getKey()); } /** @@ -366,10 +366,10 @@ public void testOverReplicatedClosedContainerWithQuasiClosedReplica() argThat(list -> list.size() <= 4), anyInt())) .thenReturn(new ContainerPlacementStatusDefault(1, 2, 3)); - Set>> commands = testProcessing( + Set>> commands = testProcessing( replicas, Collections.emptyList(), getOverReplicatedHealthResult(), 2); Set datanodes = - commands.stream().map(Pair::getKey).collect(Collectors.toSet()); + commands.stream().map(TestEntry::getKey).collect(Collectors.toSet()); assertThat(datanodes).contains(quasiClosedReplica.getDatanodeDetails()); } @@ -389,10 +389,10 @@ public void testOverReplicatedWithDecomAndMaintenanceReplicas() replicas.add(decommissioningReplica); replicas.add(maintenanceReplica); - Set>> commands = testProcessing( + Set>> commands = testProcessing( replicas, Collections.emptyList(), getOverReplicatedHealthResult(), 1); Set datanodes = - commands.stream().map(Pair::getKey).collect(Collectors.toSet()); + commands.stream().map(TestEntry::getKey).collect(Collectors.toSet()); assertThat(datanodes).doesNotContain(decommissioningReplica.getDatanodeDetails()); assertThat(datanodes).doesNotContain(maintenanceReplica.getDatanodeDetails()); } @@ -476,7 +476,7 @@ public void testDeleteThrottlingMisMatchedReplica() throws IOException { () -> handler.processAndSendCommands(replicas, Collections.emptyList(), getOverReplicatedHealthResult(), 2)); assertEquals(1, commandsSent.size()); - Pair> cmd = commandsSent.iterator().next(); + TestEntry> cmd = commandsSent.iterator().next(); assertNotEquals(quasiClosedReplica.getDatanodeDetails(), cmd.getKey()); } @@ -501,7 +501,7 @@ public void testDeleteThrottling() throws IOException { DeleteContainerCommand deleteCommand = new DeleteContainerCommand( containerInfo.getContainerID(), forceDelete); deleteCommand.setReplicaIndex(replicaIndex); - commandsSent.add(Pair.of(target, deleteCommand)); + commandsSent.add(new TestEntry<>(target, deleteCommand)); return null; }).when(replicationManager) .sendThrottledDeleteCommand(any(), anyInt(), any(), anyBoolean()); @@ -530,7 +530,7 @@ public void testDeleteThrottling() throws IOException { * the handler * @return set of commands */ - private Set>> testProcessing( + private Set>> testProcessing( Set replicas, List pendingOps, ContainerHealthResult healthResult, int expectNumCommands) throws IOException { diff --git a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/TestRatisUnderReplicationHandler.java b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/TestRatisUnderReplicationHandler.java index b368e56150e..45a9cd78f03 100644 --- a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/TestRatisUnderReplicationHandler.java +++ b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/TestRatisUnderReplicationHandler.java @@ -49,7 +49,6 @@ import java.util.List; import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; -import org.apache.commons.lang3.tuple.Pair; import org.apache.hadoop.hdds.client.RatisReplicationConfig; import org.apache.hadoop.hdds.conf.OzoneConfiguration; import org.apache.hadoop.hdds.protocol.DatanodeDetails; @@ -68,6 +67,7 @@ import org.apache.hadoop.hdds.scm.pipeline.InsufficientDatanodesException; import org.apache.hadoop.ozone.container.common.SCMTestUtils; import org.apache.hadoop.ozone.protocol.commands.SCMCommand; +import org.apache.ozone.test.TestEntry; import org.apache.ratis.protocol.exceptions.NotLeaderException; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -85,7 +85,7 @@ public class TestRatisUnderReplicationHandler { RatisReplicationConfig.getInstance(THREE); private PlacementPolicy policy; private ReplicationManager replicationManager; - private Set>> commandsSent; + private Set>> commandsSent; private ReplicationManagerMetrics metrics; @BeforeEach @@ -179,8 +179,8 @@ public void testUnderReplicatedFixedByPendingAdd() throws IOException { public void testUnderReplicatedBecauseOfDecommissioningReplica() throws IOException { Set replicas = ReplicationTestUtil - .createReplicas(Pair.of(DECOMMISSIONING, 0), Pair.of(IN_SERVICE, 0), - Pair.of(IN_SERVICE, 0)); + .createReplicas(new TestEntry<>(DECOMMISSIONING, 0), new TestEntry<>(IN_SERVICE, 0), + new TestEntry<>(IN_SERVICE, 0)); testProcessing(replicas, Collections.emptyList(), getUnderReplicatedHealthResult(), 2, 1); @@ -195,8 +195,8 @@ public void testUnderReplicatedBecauseOfDecommissioningReplica() public void testUnderReplicatedBecauseOfMaintenanceReplica() throws IOException { Set replicas = ReplicationTestUtil - .createReplicas(Pair.of(ENTERING_MAINTENANCE, 0), - Pair.of(IN_SERVICE, 0), Pair.of(IN_SERVICE, 0)); + .createReplicas(new TestEntry<>(ENTERING_MAINTENANCE, 0), + new TestEntry<>(IN_SERVICE, 0), new TestEntry<>(IN_SERVICE, 0)); testProcessing(replicas, Collections.emptyList(), getUnderReplicatedHealthResult(), 3, 1); @@ -210,8 +210,8 @@ public void testUnderReplicatedBecauseOfMaintenanceReplica() public void testSufficientlyReplicatedDespiteMaintenanceReplica() throws IOException { Set replicas = ReplicationTestUtil - .createReplicas(Pair.of(ENTERING_MAINTENANCE, 0), - Pair.of(IN_SERVICE, 0), Pair.of(IN_SERVICE, 0)); + .createReplicas(new TestEntry<>(ENTERING_MAINTENANCE, 0), + new TestEntry<>(IN_SERVICE, 0), new TestEntry<>(IN_SERVICE, 0)); testProcessing(replicas, Collections.emptyList(), getUnderReplicatedHealthResult(), 2, 0); @@ -315,7 +315,7 @@ public void testNoTargetsFoundBecauseOfPlacementPolicyRemoveUnhealthy() { () -> handler.processAndSendCommands(replicas, Collections.emptyList(), getUnderReplicatedHealthResult(), 2)); assertEquals(1, commandsSent.size()); - Pair> cmd = commandsSent.iterator().next(); + TestEntry> cmd = commandsSent.iterator().next(); assertEquals(shouldDelete.getDatanodeDetails(), cmd.getKey()); assertEquals(StorageContainerDatanodeProtocolProtos.SCMCommandProto .Type.deleteContainerCommand, cmd.getValue().getType()); @@ -375,7 +375,7 @@ public void testNoTargetsFoundRemoveQuasiClosedWithLowestSeq() { () -> handler.processAndSendCommands(replicas, Collections.emptyList(), getUnderReplicatedHealthResult(), 2)); assertEquals(1, commandsSent.size()); - Pair> cmd = commandsSent.iterator().next(); + TestEntry> cmd = commandsSent.iterator().next(); assertEquals(shouldDelete.getDatanodeDetails(), cmd.getKey()); assertEquals(StorageContainerDatanodeProtocolProtos.SCMCommandProto .Type.deleteContainerCommand, cmd.getValue().getType()); @@ -400,7 +400,7 @@ public void testDecommissionWithAllUnhealthyReplicas() Set replicas = createReplicas(container.containerID(), State.UNHEALTHY, 0, 0); replicas.addAll(createReplicas(container.containerID(), State.UNHEALTHY, - Pair.of(DECOMMISSIONING, 0))); + new TestEntry<>(DECOMMISSIONING, 0))); testProcessing(replicas, Collections.emptyList(), getUnderReplicatedHealthResult(), 2, 1); @@ -415,7 +415,7 @@ public void onlyHealthyReplicasShouldBeReplicatedWhenAvailable() container.containerID(), 0, IN_SERVICE, State.CLOSED); replicas.add(closedReplica); - Set>> commands = + Set>> commands = testProcessing(replicas, Collections.emptyList(), getUnderReplicatedHealthResult(), 2, 2); commands.forEach( @@ -438,7 +438,7 @@ public void testUnderReplicationBecauseOfUnhealthyReplica() container.containerID(), 0, IN_SERVICE, State.UNHEALTHY); replicas.add(unhealthyReplica); - Set>> commands = + Set>> commands = testProcessing(replicas, Collections.emptyList(), getUnderReplicatedHealthResult(), 2, 1); commands.forEach( @@ -510,7 +510,6 @@ public void testCorrectUsedAndExcludedNodesPassed() throws IOException { handler.processAndSendCommands(replicas, pendingOps, getUnderReplicatedHealthResult(), 2); - verify(mockPolicy, times(1)).chooseDatanodes( usedNodesCaptor.capture(), excludedNodesCaptor.capture(), any(), anyInt(), anyLong(), anyLong()); @@ -543,7 +542,7 @@ public void testUnderReplicationDueToQuasiClosedReplicaWithWrongSequenceID() IN_SERVICE, State.QUASI_CLOSED, sequenceID - 1); replicas.add(quasiClosedReplica); - final Set>> commands = + final Set>> commands = testProcessing(replicas, Collections.emptyList(), getUnderReplicatedHealthResult(), 2, 2); commands.forEach( @@ -575,7 +574,7 @@ public void testUnderReplicationWithVulnerableReplicas() throws IOException { UnderReplicatedHealthResult result = getUnderReplicatedHealthResult(); when(result.hasVulnerableUnhealthy()).thenReturn(true); - final Set>> commands = testProcessing(replicas, Collections.emptyList(), + final Set>> commands = testProcessing(replicas, Collections.emptyList(), result, 2, 1); assertEquals(unhealthyReplica.getDatanodeDetails(), commands.iterator().next().getKey()); } @@ -604,7 +603,7 @@ public void testUnderReplicationWithVulnerableReplicasOnUniqueOrigins() throws I UnderReplicatedHealthResult result = getUnderReplicatedHealthResult(); when(result.hasVulnerableUnhealthy()).thenReturn(true); - final Set>> commands = testProcessing(replicas, Collections.emptyList(), + final Set>> commands = testProcessing(replicas, Collections.emptyList(), result, 2, 1); assertEquals(unhealthyReplica.getDatanodeDetails(), commands.iterator().next().getKey()); } @@ -664,7 +663,7 @@ public void testOnlyQuasiClosedReplicaWithWrongSequenceIdIsAvailable() IN_SERVICE, State.QUASI_CLOSED, sequenceID - 1); replicas.add(quasiClosedReplica); - final Set>> commands = + final Set>> commands = testProcessing(replicas, Collections.emptyList(), getUnderReplicatedHealthResult(), 2, 2); commands.forEach( @@ -687,7 +686,7 @@ public void testOnlyClosedReplicasOfClosedContainersAreSources() replicas.add(createContainerReplica(container.containerID(), 0, IN_SERVICE, State.QUASI_CLOSED, 1)); - final Set>> commands = + final Set>> commands = testProcessing(replicas, Collections.emptyList(), getUnderReplicatedHealthResult(), 2, 1); commands.forEach( @@ -733,7 +732,7 @@ public void testQuasiClosedReplicasAreSourcesWhenOnlyTheyAreAvailable() * @param expectNumCommands number of commands expected to be created by * the handler */ - private Set>> testProcessing( + private Set>> testProcessing( Set replicas, List pendingOps, ContainerHealthResult healthResult, int minHealthyForMaintenance, int expectNumCommands) throws IOException { diff --git a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/TestReplicationManager.java b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/TestReplicationManager.java index bcb3dea9768..1ddf98d76eb 100644 --- a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/TestReplicationManager.java +++ b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/TestReplicationManager.java @@ -64,7 +64,6 @@ import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Function; -import org.apache.commons.lang3.tuple.Pair; import org.apache.hadoop.hdds.client.ECReplicationConfig; import org.apache.hadoop.hdds.client.RatisReplicationConfig; import org.apache.hadoop.hdds.client.ReplicationConfig; @@ -102,6 +101,7 @@ import org.apache.hadoop.ozone.protocol.commands.SCMCommand; import org.apache.ozone.test.GenericTestUtils; import org.apache.ozone.test.MockClock; +import org.apache.ozone.test.TestEntry; import org.apache.ratis.protocol.exceptions.NotLeaderException; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -133,7 +133,7 @@ public class TestReplicationManager { private ReplicationConfig repConfig; private ReplicationManagerReport repReport; private ReplicationQueue repQueue; - private Set>> commandsSent; + private Set>> commandsSent; @BeforeEach public void setup() throws IOException { @@ -155,7 +155,7 @@ public void setup() throws IOException { commandsSent = new HashSet<>(); eventPublisher = mock(EventPublisher.class); doAnswer(invocation -> { - commandsSent.add(Pair.of(invocation.getArgument(0), + commandsSent.add(new TestEntry<>(invocation.getArgument(0), invocation.getArgument(1))); return null; }).when(nodeManager).addDatanodeCommand(any(), any()); @@ -682,7 +682,6 @@ public void testUnrecoverableAndEmpty() ContainerHealthState.EMPTY)); } - /** * A closed EC container with 3 closed and 2 unhealthy replicas is under * replicated. RM should add it to under replicated queue. @@ -872,7 +871,7 @@ public void testUnderReplicationBlockedByUnhealthyReplicas() // a delete command should also have been sent for UNHEALTHY replica of // index 1 assertEquals(1, commandsSent.size()); - Pair> command = commandsSent.iterator().next(); + TestEntry> command = commandsSent.iterator().next(); assertEquals(SCMCommandProto.Type.deleteContainerCommand, command.getValue().getType()); DeleteContainerCommand deleteCommand = @@ -1025,9 +1024,9 @@ public void testUnderReplicationQueuePopulated() { ContainerInfo decomContainer = createContainerInfo(repConfig, 1, HddsProtos.LifeCycleState.CLOSED); addReplicas(decomContainer, ContainerReplicaProto.State.CLOSED, - Pair.of(DECOMMISSIONING, 1), - Pair.of(DECOMMISSIONING, 2), Pair.of(DECOMMISSIONING, 3), - Pair.of(DECOMMISSIONING, 4), Pair.of(DECOMMISSIONING, 5)); + new TestEntry<>(DECOMMISSIONING, 1), + new TestEntry<>(DECOMMISSIONING, 2), new TestEntry<>(DECOMMISSIONING, 3), + new TestEntry<>(DECOMMISSIONING, 4), new TestEntry<>(DECOMMISSIONING, 5)); ContainerInfo underRep1 = createContainerInfo(repConfig, 2, HddsProtos.LifeCycleState.CLOSED); @@ -1310,12 +1309,12 @@ private void testReplicationCommand( container, new ArrayList<>(sourceNodes), destination, replicaIndex); assertEquals(1, commandsSent.size()); - Pair> cmdWithTarget = commandsSent.iterator().next(); - assertEquals(expectedTarget.getID(), cmdWithTarget.getLeft()); + TestEntry> cmdWithTarget = commandsSent.iterator().next(); + assertEquals(expectedTarget.getID(), cmdWithTarget.getKey()); assertEquals(ReplicateContainerCommand.class, - cmdWithTarget.getRight().getClass()); + cmdWithTarget.getValue().getClass()); ReplicateContainerCommand cmd = - (ReplicateContainerCommand) cmdWithTarget.getRight(); + (ReplicateContainerCommand) cmdWithTarget.getValue(); assertEquals(destination, cmd.getTargetDatanode()); assertEquals(replicaIndex, cmd.getReplicaIndex()); } @@ -1372,8 +1371,8 @@ public void testSendThrottledReconstructionCommand() replicationManager.sendThrottledReconstructionCommand(container, command); assertEquals(1, commandsSent.size()); - Pair> cmd = commandsSent.iterator().next(); - assertEquals(cmdTarget.getID(), cmd.getLeft()); + TestEntry> cmd = commandsSent.iterator().next(); + assertEquals(cmdTarget.getID(), cmd.getKey()); assertEquals(0, replicationManager.getMetrics() .getEcReconstructionCmdsDeferredTotal()); } @@ -1579,10 +1578,10 @@ public void testPendingOpExpiry() throws ContainerNotFoundException { replicationManager.opCompleted(delOp, ContainerID.valueOf(1L), true); assertEquals(1, commandsSent.size()); - Pair> sentCommand = commandsSent.iterator().next(); + TestEntry> sentCommand = commandsSent.iterator().next(); // The target should be DN2 and the deadline should have been updated from the value set in commandDeadline above - assertEquals(dn2.getID(), sentCommand.getLeft()); - assertNotEquals(commandDeadline, sentCommand.getRight().getDeadline()); + assertEquals(dn2.getID(), sentCommand.getKey()); + assertNotEquals(commandDeadline, sentCommand.getValue().getDeadline()); } @ParameterizedTest @@ -1700,7 +1699,7 @@ public void testReconfigureContainerSampleLimit() { @SafeVarargs private final Set addReplicas(ContainerInfo container, ContainerReplicaProto.State replicaState, - Pair... nodes) { + TestEntry... nodes) { final Set replicas = createReplicas(container.containerID(), replicaState, nodes); storeContainerAndReplicas(container, replicas); diff --git a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/TestReplicationManagerScenarios.java b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/TestReplicationManagerScenarios.java index 7662ed5ba78..d038134d632 100644 --- a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/TestReplicationManagerScenarios.java +++ b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/TestReplicationManagerScenarios.java @@ -44,7 +44,6 @@ import java.util.Map; import java.util.Set; import java.util.stream.Stream; -import org.apache.commons.lang3.tuple.Pair; import org.apache.hadoop.hdds.client.ECReplicationConfig; import org.apache.hadoop.hdds.client.RatisReplicationConfig; import org.apache.hadoop.hdds.client.ReplicationConfig; @@ -70,6 +69,7 @@ import org.apache.hadoop.ozone.protocol.commands.ReplicateContainerCommand; import org.apache.hadoop.ozone.protocol.commands.SCMCommand; import org.apache.ozone.test.MockClock; +import org.apache.ozone.test.TestEntry; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.params.ParameterizedTest; @@ -101,7 +101,7 @@ public class TestReplicationManagerScenarios { private Map> containerReplicaMap; private Set containerInfoSet; private ContainerReplicaPendingOps containerReplicaPendingOps; - private Set>> commandsSent; + private Set>> commandsSent; private OzoneConfiguration configuration; private ContainerManager containerManager; @@ -178,7 +178,7 @@ public void setup() throws IOException, NodeNotFoundException { commandsSent = new HashSet<>(); eventPublisher = mock(EventPublisher.class); doAnswer(invocation -> { - commandsSent.add(Pair.of(invocation.getArgument(0), + commandsSent.add(new TestEntry<>(invocation.getArgument(0), invocation.getArgument(1))); return null; }).when(nodeManager).addDatanodeCommand(any(), any()); @@ -332,8 +332,8 @@ private void assertExpectedCommands(Scenario scenario, // datanodes. for (ExpectedCommands expectedCommand : expectedCommands) { boolean found = false; - for (Pair> command : commandsSent) { - if (command.getRight().getType() == expectedCommand.getType()) { + for (TestEntry> command : commandsSent) { + if (command.getValue().getType() == expectedCommand.getType()) { if (expectedCommand.hasExpectedDatanode()) { // We need to assert against the command the datanode is sent to DatanodeDetails commandDatanode = findDatanode(command.getKey()); diff --git a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/health/TestECMisReplicationCheckHandler.java b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/health/TestECMisReplicationCheckHandler.java index d4ce26a8cc5..1f165a69ffd 100644 --- a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/health/TestECMisReplicationCheckHandler.java +++ b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/health/TestECMisReplicationCheckHandler.java @@ -37,7 +37,6 @@ import java.util.Collections; import java.util.List; import java.util.Set; -import org.apache.commons.lang3.tuple.Pair; import org.apache.hadoop.hdds.client.ECReplicationConfig; import org.apache.hadoop.hdds.client.RatisReplicationConfig; import org.apache.hadoop.hdds.protocol.DatanodeDetails; @@ -55,6 +54,7 @@ import org.apache.hadoop.hdds.scm.container.replication.ContainerReplicaOp; import org.apache.hadoop.hdds.scm.container.replication.ReplicationManager; import org.apache.hadoop.hdds.scm.container.replication.ReplicationQueue; +import org.apache.ozone.test.TestEntry; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -134,9 +134,9 @@ public void shouldHandleMisReplicatedContainer() { new ContainerPlacementStatusDefault(4, 5, 9)); Set replicas = createReplicas(container.containerID(), - Pair.of(IN_SERVICE, 1), Pair.of(IN_SERVICE, 2), - Pair.of(IN_SERVICE, 3), Pair.of(IN_SERVICE, 4), - Pair.of(IN_SERVICE, 5)); + new TestEntry<>(IN_SERVICE, 1), new TestEntry<>(IN_SERVICE, 2), + new TestEntry<>(IN_SERVICE, 3), new TestEntry<>(IN_SERVICE, 4), + new TestEntry<>(IN_SERVICE, 5)); ContainerCheckRequest request = requestBuilder .setContainerReplicas(replicas) .setContainerInfo(container) @@ -180,9 +180,9 @@ public void shouldReturnFalseForMisReplicatedContainerFixedByPending() { ADD, MockDatanodeDetails.randomDatanodeDetails(), 1, null, Long.MAX_VALUE, 0)); Set replicas = createReplicas(container.containerID(), - Pair.of(IN_SERVICE, 1), Pair.of(IN_SERVICE, 2), - Pair.of(IN_SERVICE, 3), Pair.of(IN_SERVICE, 4), - Pair.of(IN_SERVICE, 5)); + new TestEntry<>(IN_SERVICE, 1), new TestEntry<>(IN_SERVICE, 2), + new TestEntry<>(IN_SERVICE, 3), new TestEntry<>(IN_SERVICE, 4), + new TestEntry<>(IN_SERVICE, 5)); ContainerCheckRequest request = requestBuilder .setContainerReplicas(replicas) .setContainerInfo(container) @@ -225,9 +225,9 @@ public void testMisReplicationWithUnhealthyReplica() { }); Set replicas = createReplicas(container.containerID(), - Pair.of(IN_SERVICE, 1), Pair.of(IN_SERVICE, 2), - Pair.of(IN_SERVICE, 3), Pair.of(IN_SERVICE, 4), - Pair.of(IN_SERVICE, 5)); + new TestEntry<>(IN_SERVICE, 1), new TestEntry<>(IN_SERVICE, 2), + new TestEntry<>(IN_SERVICE, 3), new TestEntry<>(IN_SERVICE, 4), + new TestEntry<>(IN_SERVICE, 5)); ContainerReplica unhealthyReplica = createContainerReplica(container.containerID(), 1, IN_SERVICE, State.UNHEALTHY); diff --git a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/health/TestECReplicationCheckHandler.java b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/health/TestECReplicationCheckHandler.java index 1647a035add..6ea08c057d9 100644 --- a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/health/TestECReplicationCheckHandler.java +++ b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/health/TestECReplicationCheckHandler.java @@ -42,7 +42,6 @@ import java.util.Collections; import java.util.List; import java.util.Set; -import org.apache.commons.lang3.tuple.Pair; import org.apache.hadoop.hdds.client.ECReplicationConfig; import org.apache.hadoop.hdds.protocol.MockDatanodeDetails; import org.apache.hadoop.hdds.protocol.proto.HddsProtos; @@ -62,6 +61,7 @@ import org.apache.hadoop.hdds.scm.container.replication.ReplicationManager; import org.apache.hadoop.hdds.scm.container.replication.ReplicationQueue; import org.apache.hadoop.hdds.scm.container.replication.ReplicationTestUtil; +import org.apache.ozone.test.TestEntry; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -170,9 +170,9 @@ public void testUnderReplicatedContainerFixedWithPending() { public void testUnderReplicatedDueToOutOfService() { ContainerInfo container = createContainerInfo(repConfig); Set replicas = createReplicas(container.containerID(), - Pair.of(IN_SERVICE, 1), Pair.of(IN_SERVICE, 2), - Pair.of(IN_SERVICE, 3), Pair.of(DECOMMISSIONING, 4), - Pair.of(DECOMMISSIONED, 5)); + new TestEntry<>(IN_SERVICE, 1), new TestEntry<>(IN_SERVICE, 2), + new TestEntry<>(IN_SERVICE, 3), new TestEntry<>(DECOMMISSIONING, 4), + new TestEntry<>(DECOMMISSIONED, 5)); ContainerCheckRequest request = requestBuilder .setContainerReplicas(replicas) .setContainerInfo(container) @@ -197,9 +197,9 @@ public void testUnderReplicatedDueToOutOfService() { public void testUnderReplicatedDueToOutOfServiceFixedWithPending() { ContainerInfo container = createContainerInfo(repConfig); Set replicas = createReplicas(container.containerID(), - Pair.of(IN_SERVICE, 1), Pair.of(IN_SERVICE, 2), - Pair.of(IN_SERVICE, 3), Pair.of(DECOMMISSIONING, 4), - Pair.of(IN_SERVICE, 4), Pair.of(DECOMMISSIONED, 5)); + new TestEntry<>(IN_SERVICE, 1), new TestEntry<>(IN_SERVICE, 2), + new TestEntry<>(IN_SERVICE, 3), new TestEntry<>(DECOMMISSIONING, 4), + new TestEntry<>(IN_SERVICE, 4), new TestEntry<>(DECOMMISSIONED, 5)); List pending = new ArrayList<>(); pending.add(new ContainerReplicaOp( ADD, MockDatanodeDetails.randomDatanodeDetails(), 5, null, Long.MAX_VALUE, 0)); @@ -229,8 +229,8 @@ public void testUnderReplicatedDueToOutOfServiceFixedWithPending() { public void testUnderReplicatedDueToOutOfServiceAndMissingReplica() { ContainerInfo container = createContainerInfo(repConfig); Set replicas = createReplicas(container.containerID(), - Pair.of(IN_SERVICE, 1), Pair.of(IN_SERVICE, 2), - Pair.of(DECOMMISSIONING, 4), Pair.of(DECOMMISSIONED, 5)); + new TestEntry<>(IN_SERVICE, 1), new TestEntry<>(IN_SERVICE, 2), + new TestEntry<>(DECOMMISSIONING, 4), new TestEntry<>(DECOMMISSIONED, 5)); List pending = new ArrayList<>(); pending.add(new ContainerReplicaOp( ADD, MockDatanodeDetails.randomDatanodeDetails(), 3, null, Long.MAX_VALUE, 0)); @@ -258,7 +258,7 @@ public void testUnderReplicatedDueToOutOfServiceAndMissingReplica() { public void testUnderReplicatedAndUnrecoverable() { ContainerInfo container = createContainerInfo(repConfig); Set replicas = createReplicas(container.containerID(), - Pair.of(IN_SERVICE, 1), Pair.of(IN_SERVICE, 2)); + new TestEntry<>(IN_SERVICE, 1), new TestEntry<>(IN_SERVICE, 2)); ContainerCheckRequest request = requestBuilder .setContainerReplicas(replicas) .setContainerInfo(container) @@ -288,9 +288,9 @@ public void testUnderReplicatedAndUnrecoverable() { public void testUnderReplicatedAndUnhealthy() { ContainerInfo container = createContainerInfo(repConfig); Set replicas = createReplicas(container.containerID(), - Pair.of(IN_SERVICE, 1), Pair.of(IN_SERVICE, 2)); - replicas.addAll(createReplicas(UNHEALTHY, Pair.of(IN_SERVICE, 3), - Pair.of(IN_SERVICE, 4))); + new TestEntry<>(IN_SERVICE, 1), new TestEntry<>(IN_SERVICE, 2)); + replicas.addAll(createReplicas(UNHEALTHY, new TestEntry<>(IN_SERVICE, 3), + new TestEntry<>(IN_SERVICE, 4))); ContainerCheckRequest request = requestBuilder .setContainerReplicas(replicas) .setContainerInfo(container) @@ -331,7 +331,7 @@ private void testUnderReplicatedAndUnrecoverableWithOffline( HddsProtos.NodeOperationalState offlineState) { ContainerInfo container = createContainerInfo(repConfig); Set replicas = createReplicas(container.containerID(), - Pair.of(IN_SERVICE, 1), Pair.of(offlineState, 2)); + new TestEntry<>(IN_SERVICE, 1), new TestEntry<>(offlineState, 2)); ContainerCheckRequest request = requestBuilder .setContainerReplicas(replicas) .setContainerInfo(container) @@ -373,7 +373,7 @@ private void testUnderReplicatedAndUnrecoverableWithOfflinePending( HddsProtos.NodeOperationalState offlineState) { ContainerInfo container = createContainerInfo(repConfig); Set replicas = createReplicas(container.containerID(), - Pair.of(IN_SERVICE, 1), Pair.of(offlineState, 2)); + new TestEntry<>(IN_SERVICE, 1), new TestEntry<>(offlineState, 2)); List pending = new ArrayList<>(); pending.add(new ContainerReplicaOp( ADD, MockDatanodeDetails.randomDatanodeDetails(), 2, null, Long.MAX_VALUE, 0)); @@ -479,10 +479,10 @@ public void testSufficientlyReplicatedDespiteUnhealthyReplicas() { public void testOverReplicatedContainer() { ContainerInfo container = createContainerInfo(repConfig); Set replicas = createReplicas(container.containerID(), - Pair.of(IN_SERVICE, 1), Pair.of(IN_SERVICE, 2), - Pair.of(IN_SERVICE, 3), Pair.of(IN_SERVICE, 4), - Pair.of(IN_SERVICE, 5), - Pair.of(IN_SERVICE, 1), Pair.of(IN_SERVICE, 2)); + new TestEntry<>(IN_SERVICE, 1), new TestEntry<>(IN_SERVICE, 2), + new TestEntry<>(IN_SERVICE, 3), new TestEntry<>(IN_SERVICE, 4), + new TestEntry<>(IN_SERVICE, 5), + new TestEntry<>(IN_SERVICE, 1), new TestEntry<>(IN_SERVICE, 2)); ContainerCheckRequest request = requestBuilder .setContainerReplicas(replicas) @@ -506,10 +506,10 @@ public void testOverReplicatedContainer() { public void testOverReplicatedContainerFixedByPending() { ContainerInfo container = createContainerInfo(repConfig); Set replicas = createReplicas(container.containerID(), - Pair.of(IN_SERVICE, 1), Pair.of(IN_SERVICE, 2), - Pair.of(IN_SERVICE, 3), Pair.of(IN_SERVICE, 4), - Pair.of(IN_SERVICE, 5), - Pair.of(IN_SERVICE, 1), Pair.of(IN_SERVICE, 2)); + new TestEntry<>(IN_SERVICE, 1), new TestEntry<>(IN_SERVICE, 2), + new TestEntry<>(IN_SERVICE, 3), new TestEntry<>(IN_SERVICE, 4), + new TestEntry<>(IN_SERVICE, 5), + new TestEntry<>(IN_SERVICE, 1), new TestEntry<>(IN_SERVICE, 2)); List pending = new ArrayList<>(); pending.add(new ContainerReplicaOp( @@ -539,10 +539,10 @@ public void testOverReplicatedContainerFixedByPending() { public void testOverReplicatedContainerDueToMaintenance() { ContainerInfo container = createContainerInfo(repConfig); Set replicas = createReplicas(container.containerID(), - Pair.of(IN_SERVICE, 1), Pair.of(IN_SERVICE, 2), - Pair.of(IN_SERVICE, 3), Pair.of(IN_SERVICE, 4), - Pair.of(IN_SERVICE, 5), - Pair.of(IN_MAINTENANCE, 1), Pair.of(IN_MAINTENANCE, 2)); + new TestEntry<>(IN_SERVICE, 1), new TestEntry<>(IN_SERVICE, 2), + new TestEntry<>(IN_SERVICE, 3), new TestEntry<>(IN_SERVICE, 4), + new TestEntry<>(IN_SERVICE, 5), + new TestEntry<>(IN_MAINTENANCE, 1), new TestEntry<>(IN_MAINTENANCE, 2)); ContainerCheckRequest request = requestBuilder .setContainerReplicas(replicas) .setContainerInfo(container) @@ -563,9 +563,9 @@ public void testOverReplicatedContainerDueToMaintenance() { public void testOverAndUnderReplicated() { ContainerInfo container = createContainerInfo(repConfig); Set replicas = createReplicas(container.containerID(), - Pair.of(IN_SERVICE, 1), Pair.of(IN_SERVICE, 2), - Pair.of(IN_SERVICE, 3), Pair.of(IN_SERVICE, 4), - Pair.of(IN_SERVICE, 1), Pair.of(IN_SERVICE, 2)); + new TestEntry<>(IN_SERVICE, 1), new TestEntry<>(IN_SERVICE, 2), + new TestEntry<>(IN_SERVICE, 3), new TestEntry<>(IN_SERVICE, 4), + new TestEntry<>(IN_SERVICE, 1), new TestEntry<>(IN_SERVICE, 2)); ContainerCheckRequest request = requestBuilder .setContainerReplicas(replicas) .setContainerInfo(container) @@ -596,8 +596,8 @@ public void testUnderAndMisReplicatedContainer() { new ContainerPlacementStatusDefault(4, 5, 9)); Set replicas = createReplicas(container.containerID(), - Pair.of(IN_SERVICE, 1), Pair.of(IN_SERVICE, 2), - Pair.of(IN_SERVICE, 3), Pair.of(IN_SERVICE, 4)); + new TestEntry<>(IN_SERVICE, 1), new TestEntry<>(IN_SERVICE, 2), + new TestEntry<>(IN_SERVICE, 3), new TestEntry<>(IN_SERVICE, 4)); ContainerCheckRequest request = requestBuilder .setContainerReplicas(replicas) .setContainerInfo(container) @@ -631,9 +631,9 @@ public void testOverAndMisReplicatedContainer() { new ContainerPlacementStatusDefault(4, 5, 9)); Set replicas = createReplicas(container.containerID(), - Pair.of(IN_SERVICE, 1), Pair.of(IN_SERVICE, 2), - Pair.of(IN_SERVICE, 3), Pair.of(IN_SERVICE, 4), - Pair.of(IN_SERVICE, 5), Pair.of(IN_SERVICE, 5)); + new TestEntry<>(IN_SERVICE, 1), new TestEntry<>(IN_SERVICE, 2), + new TestEntry<>(IN_SERVICE, 3), new TestEntry<>(IN_SERVICE, 4), + new TestEntry<>(IN_SERVICE, 5), new TestEntry<>(IN_SERVICE, 5)); ContainerCheckRequest request = requestBuilder .setContainerReplicas(replicas) .setContainerInfo(container) @@ -659,9 +659,9 @@ public void testOverAndMisReplicatedContainer() { public void testUnhealthyReplicaWithOtherCopyAndPendingDelete() { ContainerInfo container = createContainerInfo(repConfig); Set replicas = createReplicas(container.containerID(), - Pair.of(IN_SERVICE, 1), Pair.of(IN_SERVICE, 2), - Pair.of(IN_SERVICE, 3), Pair.of(IN_SERVICE, 4), - Pair.of(IN_SERVICE, 5)); + new TestEntry<>(IN_SERVICE, 1), new TestEntry<>(IN_SERVICE, 2), + new TestEntry<>(IN_SERVICE, 3), new TestEntry<>(IN_SERVICE, 4), + new TestEntry<>(IN_SERVICE, 5)); ContainerReplica unhealthyReplica = ReplicationTestUtil .createContainerReplica(container.containerID(), 1, IN_SERVICE, diff --git a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/health/TestQuasiClosedStuckReplicationCheck.java b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/health/TestQuasiClosedStuckReplicationCheck.java index 1d8738787c4..1e222cac185 100644 --- a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/health/TestQuasiClosedStuckReplicationCheck.java +++ b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/health/TestQuasiClosedStuckReplicationCheck.java @@ -30,7 +30,6 @@ import java.util.HashSet; import java.util.List; import java.util.Set; -import org.apache.commons.lang3.tuple.Pair; import org.apache.hadoop.hdds.client.RatisReplicationConfig; import org.apache.hadoop.hdds.conf.OzoneConfiguration; import org.apache.hadoop.hdds.protocol.DatanodeID; @@ -45,6 +44,7 @@ import org.apache.hadoop.hdds.scm.container.replication.ReplicationManager; import org.apache.hadoop.hdds.scm.container.replication.ReplicationQueue; import org.apache.hadoop.hdds.scm.container.replication.ReplicationTestUtil; +import org.apache.ozone.test.TestEntry; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -78,7 +78,7 @@ public void testClosedContainerReturnsFalse() { Set containerReplicas = ReplicationTestUtil .createReplicasWithOriginAndOpState(containerInfo.containerID(), State.QUASI_CLOSED, - Pair.of(origin1, IN_SERVICE)); + new TestEntry<>(origin1, IN_SERVICE)); ContainerCheckRequest request = new ContainerCheckRequest.Builder() .setPendingOps(Collections.emptyList()) .setReport(new ReplicationManagerReport(rmConf.getContainerSampleLimit())) @@ -100,8 +100,11 @@ public void testQuasiClosedNotStuckReturnsFalse() { RatisReplicationConfig.getInstance(THREE), 1, QUASI_CLOSED); Set containerReplicas = ReplicationTestUtil - .createReplicasWithOriginAndOpState(containerInfo.containerID(), State.QUASI_CLOSED, - Pair.of(origin1, IN_SERVICE), Pair.of(origin2, IN_SERVICE), Pair.of(origin3, IN_SERVICE)); + .createReplicasWithOriginAndOpState( + containerInfo.containerID(), State.QUASI_CLOSED, + new TestEntry<>(origin1, IN_SERVICE), + new TestEntry<>(origin2, IN_SERVICE), + new TestEntry<>(origin3, IN_SERVICE)); ContainerCheckRequest request = new ContainerCheckRequest.Builder() .setPendingOps(Collections.emptyList()) .setReport(report) @@ -124,10 +127,10 @@ public void testQuasiClosedStuckWithOpenReturnsFalse() { Set containerReplicas = ReplicationTestUtil .createReplicasWithOriginAndOpState(containerInfo.containerID(), State.QUASI_CLOSED, - Pair.of(origin1, IN_SERVICE), Pair.of(origin2, IN_SERVICE)); + new TestEntry<>(origin1, IN_SERVICE), new TestEntry<>(origin2, IN_SERVICE)); containerReplicas.addAll(ReplicationTestUtil .createReplicasWithOriginAndOpState(containerInfo.containerID(), State.OPEN, - Pair.of(origin3, IN_SERVICE))); + new TestEntry<>(origin3, IN_SERVICE))); ContainerCheckRequest request = new ContainerCheckRequest.Builder() .setPendingOps(Collections.emptyList()) .setReport(report) @@ -201,7 +204,7 @@ public void testUnderReplicatedOneOriginNotHandled() { Set containerReplicas = ReplicationTestUtil .createReplicasWithOriginAndOpState(containerInfo.containerID(), State.QUASI_CLOSED, - Pair.of(origin1, IN_SERVICE), Pair.of(origin1, IN_SERVICE)); + new TestEntry<>(origin1, IN_SERVICE), new TestEntry<>(origin1, IN_SERVICE)); ContainerCheckRequest request = new ContainerCheckRequest.Builder() .setPendingOps(Collections.emptyList()) @@ -221,7 +224,7 @@ public void testUnderReplicatedWithPendingAddIsNotQueued() { Set containerReplicas = ReplicationTestUtil .createReplicasWithOriginAndOpState(containerInfo.containerID(), State.QUASI_CLOSED, - Pair.of(origin1, IN_SERVICE), Pair.of(origin2, IN_SERVICE)); + new TestEntry<>(origin1, IN_SERVICE), new TestEntry<>(origin2, IN_SERVICE)); List pendingOps = new ArrayList<>(); pendingOps.add(new ContainerReplicaOp( diff --git a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/health/TestRatisReplicationCheckHandler.java b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/health/TestRatisReplicationCheckHandler.java index 5fbf6cceff2..1a07b3366bd 100644 --- a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/health/TestRatisReplicationCheckHandler.java +++ b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/container/replication/health/TestRatisReplicationCheckHandler.java @@ -41,7 +41,6 @@ import java.util.HashSet; import java.util.List; import java.util.Set; -import org.apache.commons.lang3.tuple.Pair; import org.apache.hadoop.hdds.client.ECReplicationConfig; import org.apache.hadoop.hdds.client.RatisReplicationConfig; import org.apache.hadoop.hdds.client.ReplicationConfig; @@ -69,6 +68,7 @@ import org.apache.hadoop.hdds.scm.container.replication.ReplicationTestUtil; import org.apache.hadoop.hdds.scm.node.NodeStatus; import org.apache.hadoop.hdds.scm.node.states.NodeNotFoundException; +import org.apache.ozone.test.TestEntry; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; @@ -220,8 +220,8 @@ public void testUnderReplicatedContainerFixedWithPending() { public void testUnderReplicatedDueToOutOfService() { ContainerInfo container = createContainerInfo(repConfig); Set replicas = createReplicas(container.containerID(), - Pair.of(IN_SERVICE, 0), Pair.of(DECOMMISSIONING, 0), - Pair.of(DECOMMISSIONED, 0)); + new TestEntry<>(IN_SERVICE, 0), new TestEntry<>(DECOMMISSIONING, 0), + new TestEntry<>(DECOMMISSIONED, 0)); requestBuilder.setContainerReplicas(replicas) .setContainerInfo(container); @@ -243,11 +243,12 @@ public void testUnderReplicatedDueToOutOfService() { @MethodSource("org.apache.hadoop.hdds.scm.node.NodeStatus#outOfServiceStates") void testUnderReplicatedDueToAllOutOfService( HddsProtos.NodeOperationalState state) { - Pair pair = Pair.of(state, 0); + TestEntry nodeState = + new TestEntry<>(state, 0); ContainerInfo container = createContainerInfo(repConfig); Set replicas = createReplicas(container.containerID(), - pair, pair, pair); + nodeState, nodeState, nodeState); ContainerCheckRequest checkRequest = requestBuilder .setContainerReplicas(replicas) @@ -275,8 +276,8 @@ void testUnderReplicatedDueToAllOutOfService( public void testUnderReplicatedDueToOutOfServiceFixedWithPending() { ContainerInfo container = createContainerInfo(repConfig); Set replicas = createReplicas(container.containerID(), - Pair.of(IN_SERVICE, 0), Pair.of(IN_SERVICE, 0), - Pair.of(DECOMMISSIONED, 0)); + new TestEntry<>(IN_SERVICE, 0), new TestEntry<>(IN_SERVICE, 0), + new TestEntry<>(DECOMMISSIONED, 0)); List pending = new ArrayList<>(); pending.add(new ContainerReplicaOp( ADD, MockDatanodeDetails.randomDatanodeDetails(), 0, null, Long.MAX_VALUE, 0)); @@ -304,7 +305,7 @@ public void testUnderReplicatedDueToOutOfServiceFixedWithPending() { public void testUnderReplicatedDueToOutOfServiceAndMissing() { ContainerInfo container = createContainerInfo(repConfig); Set replicas = createReplicas(container.containerID(), - Pair.of(IN_SERVICE, 0), Pair.of(DECOMMISSIONED, 0)); + new TestEntry<>(IN_SERVICE, 0), new TestEntry<>(DECOMMISSIONED, 0)); List pending = new ArrayList<>(); pending.add(new ContainerReplicaOp( ADD, MockDatanodeDetails.randomDatanodeDetails(), 0, null, Long.MAX_VALUE, 0)); @@ -450,10 +451,10 @@ public void testHandlerReturnsFalseWhenAllReplicasAreUnhealthy() { public void testOverReplicatedContainer() { ContainerInfo container = createContainerInfo(repConfig); Set replicas = createReplicas(container.containerID(), - Pair.of(IN_SERVICE, 0), Pair.of(IN_SERVICE, 0), - Pair.of(IN_SERVICE, 0), Pair.of(IN_SERVICE, 0), - Pair.of(IN_SERVICE, 0), - Pair.of(IN_SERVICE, 0), Pair.of(IN_SERVICE, 0)); + new TestEntry<>(IN_SERVICE, 0), new TestEntry<>(IN_SERVICE, 0), + new TestEntry<>(IN_SERVICE, 0), new TestEntry<>(IN_SERVICE, 0), + new TestEntry<>(IN_SERVICE, 0), + new TestEntry<>(IN_SERVICE, 0), new TestEntry<>(IN_SERVICE, 0)); List pending = new ArrayList<>(); pending.add(new ContainerReplicaOp( @@ -666,8 +667,8 @@ public void testHandlerAddsToQueueWhenExcessUnhealthyReplicas() { public void testOverReplicatedContainerFixedByPending() { ContainerInfo container = createContainerInfo(repConfig); Set replicas = createReplicas(container.containerID(), - Pair.of(IN_SERVICE, 0), Pair.of(IN_SERVICE, 0), - Pair.of(IN_SERVICE, 0), Pair.of(IN_SERVICE, 0)); + new TestEntry<>(IN_SERVICE, 0), new TestEntry<>(IN_SERVICE, 0), + new TestEntry<>(IN_SERVICE, 0), new TestEntry<>(IN_SERVICE, 0)); List pending = new ArrayList<>(); pending.add(new ContainerReplicaOp( @@ -695,9 +696,9 @@ public void testOverReplicatedContainerFixedByPending() { public void testOverReplicatedContainerWithMaintenance() { ContainerInfo container = createContainerInfo(repConfig); Set replicas = createReplicas(container.containerID(), - Pair.of(IN_SERVICE, 0), Pair.of(IN_SERVICE, 0), - Pair.of(IN_SERVICE, 0), Pair.of(IN_SERVICE, 0), - Pair.of(IN_MAINTENANCE, 0), Pair.of(DECOMMISSIONED, 0)); + new TestEntry<>(IN_SERVICE, 0), new TestEntry<>(IN_SERVICE, 0), + new TestEntry<>(IN_SERVICE, 0), new TestEntry<>(IN_SERVICE, 0), + new TestEntry<>(IN_MAINTENANCE, 0), new TestEntry<>(DECOMMISSIONED, 0)); requestBuilder.setContainerReplicas(replicas) .setContainerInfo(container); @@ -718,9 +719,9 @@ public void testOverReplicatedContainerWithMaintenance() { public void testOverReplicatedContainerDueToMaintenanceIsHealthy() { ContainerInfo container = createContainerInfo(repConfig); Set replicas = createReplicas(container.containerID(), - Pair.of(IN_SERVICE, 0), Pair.of(IN_SERVICE, 0), - Pair.of(IN_SERVICE, 0), Pair.of(IN_MAINTENANCE, 0), - Pair.of(IN_MAINTENANCE, 0)); + new TestEntry<>(IN_SERVICE, 0), new TestEntry<>(IN_SERVICE, 0), + new TestEntry<>(IN_SERVICE, 0), new TestEntry<>(IN_MAINTENANCE, 0), + new TestEntry<>(IN_MAINTENANCE, 0)); requestBuilder.setContainerReplicas(replicas) .setContainerInfo(container); diff --git a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/safemode/TestSCMSafeModeManager.java b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/safemode/TestSCMSafeModeManager.java index cf262873eb0..6f7e79a9dce 100644 --- a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/safemode/TestSCMSafeModeManager.java +++ b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/safemode/TestSCMSafeModeManager.java @@ -38,7 +38,6 @@ import java.util.Map; import java.util.Set; import java.util.stream.Stream; -import org.apache.commons.lang3.tuple.Pair; import org.apache.hadoop.hdds.HddsConfigKeys; import org.apache.hadoop.hdds.client.RatisReplicationConfig; import org.apache.hadoop.hdds.conf.OzoneConfiguration; @@ -48,6 +47,7 @@ import org.apache.hadoop.hdds.protocol.proto.HddsProtos.ReplicationType; import org.apache.hadoop.hdds.protocol.proto.StorageContainerDatanodeProtocolProtos; import org.apache.hadoop.hdds.scm.HddsTestUtils; +import org.apache.hadoop.hdds.scm.SafeModeRuleStatus; import org.apache.hadoop.hdds.scm.ScmConfigKeys; import org.apache.hadoop.hdds.scm.container.ContainerInfo; import org.apache.hadoop.hdds.scm.container.ContainerManager; @@ -465,7 +465,6 @@ public void testSafeModeExitRuleWithPipelineAvailabilityCheck( scmSafeModeManager.getSafeModeMetrics() .getCurrentPipelinesWithAtleastOneReplicaCount().value()); - GenericTestUtils.waitFor(() -> !scmSafeModeManager.getInSafeMode(), 100, 1000 * 5); GenericTestUtils.waitFor(() -> @@ -478,13 +477,13 @@ public void testSafeModeExitRuleWithPipelineAvailabilityCheck( * @param stringToMatch string to match in the rule status. */ private void validateRuleStatus(String safeModeRule, String stringToMatch) { - Set>> ruleStatuses = + Set> ruleStatuses = scmSafeModeManager.getRuleStatus().entrySet(); - for (Map.Entry> entry : ruleStatuses) { + for (Map.Entry entry : ruleStatuses) { if (entry.getKey().equals(safeModeRule)) { - Pair value = entry.getValue(); - assertEquals(false, value.getLeft()); - assertThat(value.getRight()).containsIgnoringCase(stringToMatch); + SafeModeRuleStatus value = entry.getValue(); + assertFalse(value.isValidated()); + assertThat(value.getStatusText()).containsIgnoringCase(stringToMatch); } } } @@ -1108,7 +1107,7 @@ public void testSafeModePeriodicLoggingStopsOnNormalExit() throws Exception { */ private void verifyPeriodicLoggingActive(GenericTestUtils.LogCapturer logCapturer) throws InterruptedException { - Map> ruleStatuses = scmSafeModeManager.getRuleStatus(); + Map ruleStatuses = scmSafeModeManager.getRuleStatus(); for (int i = 0; i < 2; i++) { logCapturer.clearOutput(); // Wait for configured interval (500ms + small buffer) for next log message diff --git a/hadoop-hdds/test-utils/pom.xml b/hadoop-hdds/test-utils/pom.xml index f4ac1fe73d3..b8fef37f5ac 100644 --- a/hadoop-hdds/test-utils/pom.xml +++ b/hadoop-hdds/test-utils/pom.xml @@ -42,10 +42,6 @@ jakarta.annotation jakarta.annotation-api - - org.apache.commons - commons-lang3 - org.apache.logging.log4j log4j-api diff --git a/hadoop-hdds/test-utils/src/main/java/org/apache/ozone/test/GenericTestUtils.java b/hadoop-hdds/test-utils/src/main/java/org/apache/ozone/test/GenericTestUtils.java index accb3595b85..a6c63465705 100644 --- a/hadoop-hdds/test-utils/src/main/java/org/apache/ozone/test/GenericTestUtils.java +++ b/hadoop-hdds/test-utils/src/main/java/org/apache/ozone/test/GenericTestUtils.java @@ -43,7 +43,6 @@ import java.util.stream.Collectors; import org.apache.commons.io.IOUtils; import org.apache.commons.io.input.CharSequenceInputStream; -import org.apache.commons.lang3.tuple.Pair; import org.apache.log4j.Layout; import org.apache.log4j.Level; import org.apache.log4j.LogManager; @@ -221,8 +220,8 @@ public static T getFieldReflection(Object object, String fieldName) public static Map getReverseMap(Map> map) { return map.entrySet().stream().flatMap(entry -> entry.getValue().stream() - .map(v -> Pair.of(v, entry.getKey()))) - .collect(Collectors.toMap(Pair::getKey, Pair::getValue)); + .map(v -> new TestEntry<>(v, entry.getKey()))) + .collect(Collectors.toMap(TestEntry::getKey, TestEntry::getValue)); } /** diff --git a/hadoop-hdds/test-utils/src/main/java/org/apache/ozone/test/TestEntry.java b/hadoop-hdds/test-utils/src/main/java/org/apache/ozone/test/TestEntry.java new file mode 100644 index 00000000000..eb5755359b8 --- /dev/null +++ b/hadoop-hdds/test-utils/src/main/java/org/apache/ozone/test/TestEntry.java @@ -0,0 +1,68 @@ +/* + * 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.ozone.test; + +import java.util.Objects; + +/** + * Immutable two-value test helper with semantic getters. + */ +public final class TestEntry { + + private final K key; + private final V value; + + public TestEntry(K key, V value) { + this.key = key; + this.value = value; + } + + public K getKey() { + return key; + } + + public V getValue() { + return value; + } + + @Override + public boolean equals(Object other) { + if (this == other) { + return true; + } + if (!(other instanceof TestEntry)) { + return false; + } + TestEntry that = (TestEntry) other; + return Objects.equals(key, that.key) + && Objects.equals(value, that.value); + } + + @Override + public int hashCode() { + return Objects.hash(key, value); + } + + @Override + public String toString() { + return "TestEntry{" + + "key=" + key + + ", value=" + value + + '}'; + } +} diff --git a/hadoop-ozone/cli-admin/src/main/java/org/apache/hadoop/hdds/scm/cli/ContainerOperationClient.java b/hadoop-ozone/cli-admin/src/main/java/org/apache/hadoop/hdds/scm/cli/ContainerOperationClient.java index c1973891d0a..fe01db347da 100644 --- a/hadoop-ozone/cli-admin/src/main/java/org/apache/hadoop/hdds/scm/cli/ContainerOperationClient.java +++ b/hadoop-ozone/cli-admin/src/main/java/org/apache/hadoop/hdds/scm/cli/ContainerOperationClient.java @@ -29,7 +29,6 @@ import java.util.Map; import java.util.Optional; import java.util.UUID; -import org.apache.commons.lang3.tuple.Pair; import org.apache.hadoop.conf.StorageUnit; import org.apache.hadoop.hdds.client.ReplicationConfig; import org.apache.hadoop.hdds.conf.ConfigurationSource; @@ -44,6 +43,7 @@ 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.SafeModeRuleStatus; import org.apache.hadoop.hdds.scm.ScmConfigKeys; import org.apache.hadoop.hdds.scm.XceiverClientManager; import org.apache.hadoop.hdds.scm.XceiverClientSpi; @@ -497,7 +497,7 @@ public boolean inSafeMode() throws IOException { } @Override - public Map> getSafeModeRuleStatuses() + public Map getSafeModeRuleStatuses() throws IOException { return storageContainerLocationClient.getSafeModeRuleStatuses(); } diff --git a/hadoop-ozone/cli-admin/src/main/java/org/apache/hadoop/hdds/scm/cli/SafeModeCheckSubcommand.java b/hadoop-ozone/cli-admin/src/main/java/org/apache/hadoop/hdds/scm/cli/SafeModeCheckSubcommand.java index 1fb97d6e01a..5c5329858ae 100644 --- a/hadoop-ozone/cli-admin/src/main/java/org/apache/hadoop/hdds/scm/cli/SafeModeCheckSubcommand.java +++ b/hadoop-ozone/cli-admin/src/main/java/org/apache/hadoop/hdds/scm/cli/SafeModeCheckSubcommand.java @@ -23,11 +23,11 @@ import java.util.concurrent.Callable; import java.util.stream.Collectors; import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.tuple.Pair; import org.apache.hadoop.hdds.HddsUtils; import org.apache.hadoop.hdds.cli.AbstractSubcommand; import org.apache.hadoop.hdds.cli.HddsVersionProvider; import org.apache.hadoop.hdds.conf.OzoneConfiguration; +import org.apache.hadoop.hdds.scm.SafeModeRuleStatus; import org.apache.hadoop.hdds.scm.client.ScmClient; import org.apache.hadoop.hdds.scm.ha.SCMNodeInfo; import org.apache.hadoop.hdds.scm.protocolPB.StorageContainerLocationProtocolClientSideTranslatorPB.ScmNodeTarget; @@ -165,7 +165,8 @@ private void queryNode(ScmClient scmClient, ScmNodeTarget targetScmNode, SCMNode } if (isVerbose()) { - Map> rules = scmClient.getSafeModeRuleStatuses(); + Map rules = + scmClient.getSafeModeRuleStatuses(); if (rules != null && !rules.isEmpty()) { printSafeModeRules(rules); } @@ -209,11 +210,11 @@ private boolean matchesAddress(String address1, String address2) { } } - private void printSafeModeRules(Map> rules) { - for (Map.Entry> entry : rules.entrySet()) { - Pair value = entry.getValue(); + private void printSafeModeRules(Map rules) { + for (Map.Entry entry : rules.entrySet()) { + SafeModeRuleStatus value = entry.getValue(); System.out.printf("validated:%s, %s, %s%n", - value.getLeft(), entry.getKey(), value.getRight()); + value.isValidated(), entry.getKey(), value.getStatusText()); } } }