diff --git a/hadoop-hdfs-project/hadoop-hdfs-rbf/src/main/java/org/apache/hadoop/hdfs/server/federation/resolver/MountTableResolver.java b/hadoop-hdfs-project/hadoop-hdfs-rbf/src/main/java/org/apache/hadoop/hdfs/server/federation/resolver/MountTableResolver.java index d45441fe4a..bdd75c70f5 100644 --- a/hadoop-hdfs-project/hadoop-hdfs-rbf/src/main/java/org/apache/hadoop/hdfs/server/federation/resolver/MountTableResolver.java +++ b/hadoop-hdfs-project/hadoop-hdfs-rbf/src/main/java/org/apache/hadoop/hdfs/server/federation/resolver/MountTableResolver.java @@ -20,6 +20,8 @@ import static org.apache.hadoop.hdfs.client.HdfsClientConfigKeys.DFS_NAMESERVICES; import static org.apache.hadoop.hdfs.client.HdfsClientConfigKeys.DeprecatedKeys.DFS_NAMESERVICE_ID; import static org.apache.hadoop.hdfs.server.federation.router.RBFConfigKeys.DFS_ROUTER_DEFAULT_NAMESERVICE; +import static org.apache.hadoop.hdfs.server.federation.router.RBFConfigKeys.DFS_ROUTER_DEFAULT_NAMESERVICE_ENABLE; +import static org.apache.hadoop.hdfs.server.federation.router.RBFConfigKeys.DFS_ROUTER_DEFAULT_NAMESERVICE_ENABLE_DEFAULT; import static org.apache.hadoop.hdfs.server.federation.router.RBFConfigKeys.FEDERATION_MOUNT_TABLE_MAX_CACHE_SIZE; import static org.apache.hadoop.hdfs.server.federation.router.RBFConfigKeys.FEDERATION_MOUNT_TABLE_MAX_CACHE_SIZE_DEFAULT; import static org.apache.hadoop.hdfs.server.federation.router.RBFConfigKeys.FEDERATION_MOUNT_TABLE_CACHE_ENABLE; @@ -95,6 +97,8 @@ public class MountTableResolver /** Default nameservice when no mount matches the math. */ private String defaultNameService = ""; + /** If use default nameservice to read and write files. */ + private boolean defaultNSEnable = true; /** Synchronization for both the tree and the cache. */ private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock(); @@ -163,6 +167,10 @@ private void initDefaultNameService(Configuration conf) { DFS_ROUTER_DEFAULT_NAMESERVICE, DFSUtil.getNamenodeNameServiceId(conf)); + this.defaultNSEnable = conf.getBoolean( + DFS_ROUTER_DEFAULT_NAMESERVICE_ENABLE, + DFS_ROUTER_DEFAULT_NAMESERVICE_ENABLE_DEFAULT); + if (defaultNameService == null) { LOG.warn( "{} and {} is not set. Fallback to {} as the default name service.", @@ -176,9 +184,12 @@ private void initDefaultNameService(Configuration conf) { } if (this.defaultNameService.equals("")) { + this.defaultNSEnable = false; LOG.warn("Default name service is not set."); } else { - LOG.info("Default name service: {}", this.defaultNameService); + String enable = this.defaultNSEnable ? "enabled" : "disabled"; + LOG.info("Default name service: {}, {} to read or write", + this.defaultNameService, enable); } } @@ -406,13 +417,17 @@ public PathLocation call() throws Exception { * @param path Path to check/insert. * @return New remote location. */ - public PathLocation lookupLocation(final String path) { + public PathLocation lookupLocation(final String path) throws IOException { PathLocation ret = null; MountTable entry = findDeepest(path); if (entry != null) { ret = buildLocation(path, entry); } else { // Not found, use default location + if (!defaultNSEnable) { + throw new IOException("Cannot find locations for " + path + ", " + + "because the default nameservice is disabled to read or write"); + } RemoteLocation remoteLocation = new RemoteLocation(defaultNameService, path, path); List locations = @@ -623,4 +638,24 @@ protected long getCacheSize() throws IOException{ } throw new IOException("localCache is null"); } + + @VisibleForTesting + public String getDefaultNameService() { + return defaultNameService; + } + + @VisibleForTesting + public void setDefaultNameService(String defaultNameService) { + this.defaultNameService = defaultNameService; + } + + @VisibleForTesting + public boolean isDefaultNSEnable() { + return defaultNSEnable; + } + + @VisibleForTesting + public void setDefaultNSEnable(boolean defaultNSRWEnable) { + this.defaultNSEnable = defaultNSRWEnable; + } } diff --git a/hadoop-hdfs-project/hadoop-hdfs-rbf/src/main/java/org/apache/hadoop/hdfs/server/federation/router/RBFConfigKeys.java b/hadoop-hdfs-project/hadoop-hdfs-rbf/src/main/java/org/apache/hadoop/hdfs/server/federation/router/RBFConfigKeys.java index 997e1dda2f..bbd4250b26 100644 --- a/hadoop-hdfs-project/hadoop-hdfs-rbf/src/main/java/org/apache/hadoop/hdfs/server/federation/router/RBFConfigKeys.java +++ b/hadoop-hdfs-project/hadoop-hdfs-rbf/src/main/java/org/apache/hadoop/hdfs/server/federation/router/RBFConfigKeys.java @@ -42,6 +42,10 @@ public class RBFConfigKeys extends CommonConfigurationKeysPublic { "dfs.federation.router."; public static final String DFS_ROUTER_DEFAULT_NAMESERVICE = FEDERATION_ROUTER_PREFIX + "default.nameserviceId"; + public static final String DFS_ROUTER_DEFAULT_NAMESERVICE_ENABLE = + FEDERATION_ROUTER_PREFIX + "default.nameservice.enable"; + public static final boolean DFS_ROUTER_DEFAULT_NAMESERVICE_ENABLE_DEFAULT = + true; public static final String DFS_ROUTER_HANDLER_COUNT_KEY = FEDERATION_ROUTER_PREFIX + "handler.count"; public static final int DFS_ROUTER_HANDLER_COUNT_DEFAULT = 10; diff --git a/hadoop-hdfs-project/hadoop-hdfs-rbf/src/main/java/org/apache/hadoop/hdfs/server/federation/router/RouterRpcServer.java b/hadoop-hdfs-project/hadoop-hdfs-rbf/src/main/java/org/apache/hadoop/hdfs/server/federation/router/RouterRpcServer.java index 2deda9ffff..165b429cc6 100644 --- a/hadoop-hdfs-project/hadoop-hdfs-rbf/src/main/java/org/apache/hadoop/hdfs/server/federation/router/RouterRpcServer.java +++ b/hadoop-hdfs-project/hadoop-hdfs-rbf/src/main/java/org/apache/hadoop/hdfs/server/federation/router/RouterRpcServer.java @@ -1339,7 +1339,7 @@ protected List getLocationsForPath(String path, this.subclusterResolver.getDestinationForPath(path); if (location == null) { throw new IOException("Cannot find locations for " + path + " in " + - this.subclusterResolver); + this.subclusterResolver.getClass().getSimpleName()); } // We may block some write operations diff --git a/hadoop-hdfs-project/hadoop-hdfs-rbf/src/main/resources/hdfs-rbf-default.xml b/hadoop-hdfs-project/hadoop-hdfs-rbf/src/main/resources/hdfs-rbf-default.xml index ed39d4b5f5..3f560431ac 100644 --- a/hadoop-hdfs-project/hadoop-hdfs-rbf/src/main/resources/hdfs-rbf-default.xml +++ b/hadoop-hdfs-project/hadoop-hdfs-rbf/src/main/resources/hdfs-rbf-default.xml @@ -31,6 +31,14 @@ + + dfs.federation.router.default.nameservice.enable + true + + The default subcluster is enabled to read and write files. + + + dfs.federation.router.rpc.enable true diff --git a/hadoop-hdfs-project/hadoop-hdfs-rbf/src/test/java/org/apache/hadoop/hdfs/server/federation/resolver/TestMountTableResolver.java b/hadoop-hdfs-project/hadoop-hdfs-rbf/src/test/java/org/apache/hadoop/hdfs/server/federation/resolver/TestMountTableResolver.java index b19a973294..5e3b861df2 100644 --- a/hadoop-hdfs-project/hadoop-hdfs-rbf/src/test/java/org/apache/hadoop/hdfs/server/federation/resolver/TestMountTableResolver.java +++ b/hadoop-hdfs-project/hadoop-hdfs-rbf/src/test/java/org/apache/hadoop/hdfs/server/federation/resolver/TestMountTableResolver.java @@ -21,6 +21,7 @@ import static org.apache.hadoop.hdfs.server.federation.router.RBFConfigKeys.FEDERATION_MOUNT_TABLE_MAX_CACHE_SIZE; import static org.apache.hadoop.hdfs.server.federation.router.RBFConfigKeys.DFS_ROUTER_DEFAULT_NAMESERVICE; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -175,6 +176,31 @@ public void testDestination() throws IOException { } + @Test + public void testDefaultNameServiceEnable() throws IOException { + assertTrue(mountTable.isDefaultNSEnable()); + mountTable.setDefaultNameService("3"); + mountTable.removeEntry("/"); + + assertEquals("3->/unknown", + mountTable.getDestinationForPath("/unknown").toString()); + + Map map = getMountTableEntry("4", "/unknown"); + mountTable.addEntry(MountTable.newInstance("/unknown", map)); + mountTable.setDefaultNSEnable(false); + assertFalse(mountTable.isDefaultNSEnable()); + + assertEquals("4->/unknown", + mountTable.getDestinationForPath("/unknown").toString()); + try { + mountTable.getDestinationForPath("/"); + fail("The getDestinationForPath call should fail."); + } catch (IOException ioe) { + GenericTestUtils.assertExceptionContains( + "the default nameservice is disabled to read or write", ioe); + } + } + private void compareLists(List list1, String[] list2) { assertEquals(list1.size(), list2.length); for (String item : list2) {