HDFS-12865. RequestHedgingProxyProvider should handle case when none of the proxies are available. Contributed by Mukul Kumar Singh.
This commit is contained in:
parent
1e84e46f16
commit
c30a26abc5
|
@ -17,6 +17,7 @@
|
|||
*/
|
||||
package org.apache.hadoop.hdfs.server.namenode.ha;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
@ -87,6 +88,11 @@ public class RequestHedgingProxyProvider<T> extends
|
|||
// Optimization : if only 2 proxies are configured and one had failed
|
||||
// over, then we dont need to create a threadpool etc.
|
||||
targetProxies.remove(toIgnore);
|
||||
if (targetProxies.size() == 0) {
|
||||
LOG.trace("No valid proxies left");
|
||||
throw new RemoteException(IOException.class.getName(),
|
||||
"No valid proxies left. All NameNode proxies have failed over.");
|
||||
}
|
||||
if (targetProxies.size() == 1) {
|
||||
ProxyInfo<T> proxyInfo = targetProxies.values().iterator().next();
|
||||
try {
|
||||
|
|
|
@ -28,6 +28,7 @@ import java.util.Iterator;
|
|||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.apache.commons.lang.RandomStringUtils;
|
||||
import org.apache.hadoop.conf.Configuration;
|
||||
import org.apache.hadoop.hdfs.client.HdfsClientConfigKeys;
|
||||
import org.apache.hadoop.hdfs.protocol.ClientProtocol;
|
||||
|
@ -289,6 +290,50 @@ public class TestRequestHedgingProxyProvider {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSingleProxyFailover() throws Exception {
|
||||
String singleNS = "mycluster-" + Time.monotonicNow();
|
||||
URI singleNNUri = new URI("hdfs://" + singleNS);
|
||||
Configuration singleConf = new Configuration();
|
||||
singleConf.set(HdfsClientConfigKeys.DFS_NAMESERVICES, singleNS);
|
||||
singleConf.set(HdfsClientConfigKeys.
|
||||
DFS_HA_NAMENODES_KEY_PREFIX + "." + singleNS, "nn1");
|
||||
|
||||
singleConf.set(HdfsClientConfigKeys.
|
||||
DFS_NAMENODE_RPC_ADDRESS_KEY + "." + singleNS + ".nn1",
|
||||
RandomStringUtils.randomAlphabetic(8) + ".foo.bar:9820");
|
||||
ClientProtocol active = Mockito.mock(ClientProtocol.class);
|
||||
Mockito
|
||||
.when(active.getBlockLocations(Matchers.anyString(),
|
||||
Matchers.anyLong(), Matchers.anyLong()))
|
||||
.thenThrow(new RemoteException("java.io.FileNotFoundException",
|
||||
"File does not exist!"));
|
||||
|
||||
RequestHedgingProxyProvider<ClientProtocol> provider =
|
||||
new RequestHedgingProxyProvider<>(singleConf, singleNNUri,
|
||||
ClientProtocol.class, createFactory(active));
|
||||
try {
|
||||
provider.getProxy().proxy.getBlockLocations("/tmp/test.file", 0L, 20L);
|
||||
Assert.fail("Should fail since the active namenode throws"
|
||||
+ " FileNotFoundException!");
|
||||
} catch (RemoteException ex) {
|
||||
Exception rEx = ex.unwrapRemoteException();
|
||||
Assert.assertTrue(rEx instanceof FileNotFoundException);
|
||||
}
|
||||
//Perform failover now, there will be no active proxies now
|
||||
provider.performFailover(active);
|
||||
try {
|
||||
provider.getProxy().proxy.getBlockLocations("/tmp/test.file", 0L, 20L);
|
||||
Assert.fail("Should fail since the active namenode throws"
|
||||
+ " FileNotFoundException!");
|
||||
} catch (RemoteException ex) {
|
||||
Exception rEx = ex.unwrapRemoteException();
|
||||
Assert.assertTrue(rEx instanceof IOException);
|
||||
Assert.assertTrue(rEx.getMessage().equals("No valid proxies left."
|
||||
+ " All NameNode proxies have failed over."));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPerformFailoverWith3Proxies() throws Exception {
|
||||
conf.set(HdfsClientConfigKeys.DFS_HA_NAMENODES_KEY_PREFIX + "." + ns,
|
||||
|
|
Loading…
Reference in New Issue