diff --git a/hadoop-hdds/common/pom.xml b/hadoop-hdds/common/pom.xml index 10e5c3209b01..cebee64d1409 100644 --- a/hadoop-hdds/common/pom.xml +++ b/hadoop-hdds/common/pom.xml @@ -200,6 +200,11 @@ https://maven.apache.org/xsd/maven-4.0.0.xsd"> hamcrest-all test + + com.github.spotbugs + spotbugs-annotations + test + diff --git a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/ratis/ServerNotLeaderException.java b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/ratis/ServerNotLeaderException.java index 71b26f587882..d100b4a0490a 100644 --- a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/ratis/ServerNotLeaderException.java +++ b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/ratis/ServerNotLeaderException.java @@ -33,7 +33,8 @@ public class ServerNotLeaderException extends IOException { private static final Pattern CURRENT_PEER_ID_PATTERN = Pattern.compile("Server:(.*) is not the leader[.]+.*", Pattern.DOTALL); private static final Pattern SUGGESTED_LEADER_PATTERN = - Pattern.compile(".*Suggested leader is Server:([^.]*).*", Pattern.DOTALL); + Pattern.compile(".*Suggested leader is Server:([^:]*)(:[0-9]+).*", + Pattern.DOTALL); public ServerNotLeaderException(RaftPeerId currentPeerId) { super("Server:" + currentPeerId + " is not the leader. Could not " + @@ -60,7 +61,17 @@ public ServerNotLeaderException(String message) { Matcher suggestedLeaderMatcher = SUGGESTED_LEADER_PATTERN.matcher(message); if (suggestedLeaderMatcher.matches()) { - this.leader = suggestedLeaderMatcher.group(1); + if (suggestedLeaderMatcher.groupCount() == 2) { + if (suggestedLeaderMatcher.group(1).isEmpty() + || suggestedLeaderMatcher.group(2).isEmpty()) { + this.leader = null; + } else { + this.leader = suggestedLeaderMatcher.group(1) + + suggestedLeaderMatcher.group(2); + } + } else { + this.leader = null; + } } else { this.leader = null; } diff --git a/hadoop-hdds/common/src/test/java/org/apache/hadoop/hdds/ratis/TestServerNotLeaderException.java b/hadoop-hdds/common/src/test/java/org/apache/hadoop/hdds/ratis/TestServerNotLeaderException.java new file mode 100644 index 000000000000..3bdcf85cdf7c --- /dev/null +++ b/hadoop-hdds/common/src/test/java/org/apache/hadoop/hdds/ratis/TestServerNotLeaderException.java @@ -0,0 +1,82 @@ +/* + * 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.ratis; + +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; +import org.junit.Assert; +import org.junit.Test; + +/** Class to test {@link ServerNotLeaderException} parsing. **/ + +@SuppressFBWarnings("NM_CLASS_NOT_EXCEPTION") +public class TestServerNotLeaderException { + @Test + public void testServerNotLeaderException() { + + // Test hostname with "." + final String msg = + "Server:cf0bc565-a41b-4784-a24d-3048d5a5b013 is not the leader. " + + "Suggested leader is Server:scm5-3.scm5.root.hwx.site:9863"; + ServerNotLeaderException snle = new ServerNotLeaderException(msg); + Assert.assertEquals(snle.getSuggestedLeader(), "scm5-3.scm5.root.hwx" + + ".site:9863"); + + String message = "Server:7fdd7170-75cc-4e11-b343-c2657c2f2f39 is not the " + + "leader.Suggested leader is Server:scm5-3.scm5.root.hwx.site:9863 \n" + + "at org.apache.hadoop.hdds.ratis.ServerNotLeaderException" + + ".convertToNotLeaderException(ServerNotLeaderException.java:96)"; + snle = new ServerNotLeaderException(message); + Assert.assertEquals("scm5-3.scm5.root.hwx.site:9863", + snle.getSuggestedLeader()); + + // Test hostname with out "." + message = "Server:7fdd7170-75cc-4e11-b343-c2657c2f2f39 is not the " + + "leader.Suggested leader is Server:localhost:98634 \n" + + "at org.apache.hadoop.hdds.ratis.ServerNotLeaderException" + + ".convertToNotLeaderException(ServerNotLeaderException.java:96)"; + snle = new ServerNotLeaderException(message); + Assert.assertEquals("localhost:98634", + snle.getSuggestedLeader()); + + message = "Server:7fdd7170-75cc-4e11-b343-c2657c2f2f39 is not the " + + "leader.Suggested leader is Server::98634 \n" + + "at org.apache.hadoop.hdds.ratis.ServerNotLeaderException" + + ".convertToNotLeaderException(ServerNotLeaderException.java:96)"; + snle = new ServerNotLeaderException(message); + Assert.assertEquals(null, + snle.getSuggestedLeader()); + + message = "Server:7fdd7170-75cc-4e11-b343-c2657c2f2f39 is not the " + + "leader.Suggested leader is Server:localhost:98634:8988 \n" + + "at org.apache.hadoop.hdds.ratis.ServerNotLeaderException" + + ".convertToNotLeaderException(ServerNotLeaderException.java:96)"; + snle = new ServerNotLeaderException(message); + Assert.assertEquals("localhost:98634", + snle.getSuggestedLeader()); + + message = "Server:7fdd7170-75cc-4e11-b343-c2657c2f2f39 is not the " + + "leader.Suggested leader is Server:localhost \n" + + "at org.apache.hadoop.hdds.ratis.ServerNotLeaderException" + + ".convertToNotLeaderException(ServerNotLeaderException.java)"; + snle = new ServerNotLeaderException(message); + Assert.assertEquals(null, + snle.getSuggestedLeader()); + } + +} diff --git a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/scm/proxy/SCMBlockLocationFailoverProxyProvider.java b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/scm/proxy/SCMBlockLocationFailoverProxyProvider.java index b0188facea26..70787407919c 100644 --- a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/scm/proxy/SCMBlockLocationFailoverProxyProvider.java +++ b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/scm/proxy/SCMBlockLocationFailoverProxyProvider.java @@ -41,9 +41,11 @@ import java.io.IOException; import java.net.InetSocketAddress; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Optional; import static org.apache.hadoop.ozone.OzoneConsts.SCM_DUMMY_SERVICE_ID; @@ -161,11 +163,19 @@ public synchronized void performFailoverToAssignedLeader(String newLeader, ServerNotLeaderException snle = (ServerNotLeaderException) SCMHAUtils.getServerNotLeaderException(e); if (snle != null && snle.getSuggestedLeader() != null) { - newLeader = scmProxyInfoMap.values().stream().filter( - proxyInfo -> NetUtils.getHostPortString(proxyInfo.getAddress()) - .equals(snle.getSuggestedLeader())).findFirst().get().getNodeId(); - LOG.debug("Performing failover to suggested leader {}, nodeId {}", - snle.getSuggestedLeader(), newLeader); + Optional matchedProxyInfo = + scmProxyInfoMap.values().stream().filter( + proxyInfo -> NetUtils.getHostPortString(proxyInfo.getAddress()) + .equals(snle.getSuggestedLeader())).findFirst(); + if (matchedProxyInfo.isPresent()) { + newLeader = matchedProxyInfo.get().getNodeId(); + LOG.debug("Performing failover to suggested leader {}, nodeId {}", + snle.getSuggestedLeader(), newLeader); + } else { + LOG.debug("Suggested leader {} does not match with any of the " + + "proxyInfo adress {}", snle.getSuggestedLeader(), + Arrays.toString(scmProxyInfoMap.values().toArray())); + } } if (newLeader == null) { // If newLeader is not assigned, it will fail over to next proxy. diff --git a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/scm/proxy/SCMContainerLocationFailoverProxyProvider.java b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/scm/proxy/SCMContainerLocationFailoverProxyProvider.java index 96e627555535..1cff58a87267 100644 --- a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/scm/proxy/SCMContainerLocationFailoverProxyProvider.java +++ b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/scm/proxy/SCMContainerLocationFailoverProxyProvider.java @@ -41,9 +41,11 @@ import java.io.IOException; import java.net.InetSocketAddress; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.stream.Collectors; /** @@ -167,11 +169,19 @@ public synchronized void performFailoverToAssignedLeader(String newLeader, ServerNotLeaderException snle = (ServerNotLeaderException) SCMHAUtils.getServerNotLeaderException(e); if (snle != null && snle.getSuggestedLeader() != null) { - newLeader = scmProxyInfoMap.values().stream().filter( - proxyInfo -> NetUtils.getHostPortString(proxyInfo.getAddress()) - .equals(snle.getSuggestedLeader())).findFirst().get().getNodeId(); - LOG.debug("Performing failover to suggested leader {}, nodeId {}", - snle.getSuggestedLeader(), newLeader); + Optional matchedProxyInfo = + scmProxyInfoMap.values().stream().filter( + proxyInfo -> NetUtils.getHostPortString(proxyInfo.getAddress()) + .equals(snle.getSuggestedLeader())).findFirst(); + if (matchedProxyInfo.isPresent()) { + newLeader = matchedProxyInfo.get().getNodeId(); + LOG.debug("Performing failover to suggested leader {}, nodeId {}", + snle.getSuggestedLeader(), newLeader); + } else { + LOG.debug("Suggested leader {} does not match with any of the " + + "proxyInfo adress {}", snle.getSuggestedLeader(), + Arrays.toString(scmProxyInfoMap.values().toArray())); + } } if (newLeader == null) { // If newLeader is not assigned, it will fail over to next proxy. diff --git a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/scm/proxy/SCMSecurityProtocolFailoverProxyProvider.java b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/scm/proxy/SCMSecurityProtocolFailoverProxyProvider.java index 23f3a3e6cbea..2e49b61eb55d 100644 --- a/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/scm/proxy/SCMSecurityProtocolFailoverProxyProvider.java +++ b/hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/scm/proxy/SCMSecurityProtocolFailoverProxyProvider.java @@ -41,9 +41,11 @@ import java.io.IOException; import java.net.InetSocketAddress; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Optional; /** * Failover proxy provider for SCMSecurityProtocol server. @@ -187,11 +189,19 @@ public synchronized void performFailoverToAssignedLeader(String newLeader, ServerNotLeaderException snle = (ServerNotLeaderException) SCMHAUtils.getServerNotLeaderException(e); if (snle != null && snle.getSuggestedLeader() != null) { - newLeader = scmProxyInfoMap.values().stream().filter( - proxyInfo -> NetUtils.getHostPortString(proxyInfo.getAddress()) - .equals(snle.getSuggestedLeader())).findFirst().get().getNodeId(); - LOG.debug("Performing failover to suggested leader {}, nodeId {}", - snle.getSuggestedLeader(), newLeader); + Optional< SCMProxyInfo > matchedProxyInfo = + scmProxyInfoMap.values().stream().filter( + proxyInfo -> NetUtils.getHostPortString(proxyInfo.getAddress()) + .equals(snle.getSuggestedLeader())).findFirst(); + if (matchedProxyInfo.isPresent()) { + newLeader = matchedProxyInfo.get().getNodeId(); + LOG.debug("Performing failover to suggested leader {}, nodeId {}", + snle.getSuggestedLeader(), newLeader); + } else { + LOG.debug("Suggested leader {} does not match with any of the " + + "proxyInfo adress {}", snle.getSuggestedLeader(), + Arrays.toString(scmProxyInfoMap.values().toArray())); + } } if (newLeader == null) { // If newLeader is not assigned, it will fail over to next proxy.