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 f4c010c0f4f..7251fffcf14 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 @@ -2329,18 +2329,11 @@ public class RouterRpcServer extends AbstractService private Map getMountPointDates(String path) { Map ret = new TreeMap<>(); if (subclusterResolver instanceof MountTableResolver) { - MountTableResolver mountTable = (MountTableResolver)subclusterResolver; - String srcPath; try { final List children = subclusterResolver.getMountPoints(path); for (String child : children) { - if (path.equals(Path.SEPARATOR)) { - srcPath = Path.SEPARATOR + child; - } else { - srcPath = path + Path.SEPARATOR + child; - } - MountTable entry = mountTable.getMountPoint(srcPath); - ret.put(child, entry.getDateModified()); + Long modTime = getModifiedTime(ret, path, child); + ret.put(child, modTime); } } catch (IOException e) { LOG.error("Cannot get mount point", e); @@ -2349,6 +2342,50 @@ public class RouterRpcServer extends AbstractService return ret; } + /** + * Get modified time for child. If the child is present in mount table it + * will return the modified time. If the child is not present but subdirs of + * this child are present then it will return latest modified subdir's time + * as modified time of the requested child. + * @param ret contains children and modified times. + * @param mountTable. + * @param path Name of the path to start checking dates from. + * @param child child of the requested path. + * @return modified time. + */ + private long getModifiedTime(Map ret, String path, + String child) { + MountTableResolver mountTable = (MountTableResolver)subclusterResolver; + String srcPath; + if (path.equals(Path.SEPARATOR)) { + srcPath = Path.SEPARATOR + child; + } else { + srcPath = path + Path.SEPARATOR + child; + } + Long modTime = 0L; + try { + // Get mount table entry for the srcPath + MountTable entry = mountTable.getMountPoint(srcPath); + // if srcPath is not in mount table but its subdirs are in mount + // table we will display latest modified subdir date/time. + if (entry == null) { + List entries = mountTable.getMounts(srcPath); + for (MountTable eachEntry : entries) { + // Get the latest date + if (ret.get(child) == null || + ret.get(child) < eachEntry.getDateModified()) { + modTime = eachEntry.getDateModified(); + } + } + } else { + modTime = entry.getDateModified(); + } + } catch (IOException e) { + LOG.error("Cannot get mount point", e); + } + return modTime; + } + /** * Create a new file status for a mount point. * diff --git a/hadoop-hdfs-project/hadoop-hdfs-rbf/src/test/java/org/apache/hadoop/hdfs/server/federation/router/TestRouterMountTable.java b/hadoop-hdfs-project/hadoop-hdfs-rbf/src/test/java/org/apache/hadoop/hdfs/server/federation/router/TestRouterMountTable.java index b33b9983d63..4d8ffe10fcd 100644 --- a/hadoop-hdfs-project/hadoop-hdfs-rbf/src/test/java/org/apache/hadoop/hdfs/server/federation/router/TestRouterMountTable.java +++ b/hadoop-hdfs-project/hadoop-hdfs-rbf/src/test/java/org/apache/hadoop/hdfs/server/federation/router/TestRouterMountTable.java @@ -24,6 +24,7 @@ import static org.junit.Assert.fail; import java.io.IOException; import java.util.Collections; import java.util.Iterator; +import java.util.List; import java.util.Map; import java.util.TreeMap; @@ -167,6 +168,12 @@ public class TestRouterMountTable { addEntry = MountTable.newInstance( "/testdir/subdir", Collections.singletonMap("ns0", "/testdir/subdir")); assertTrue(addMountTable(addEntry)); + addEntry = MountTable.newInstance( + "/testdir3/subdir1", Collections.singletonMap("ns0", "/testdir3")); + assertTrue(addMountTable(addEntry)); + addEntry = MountTable.newInstance( + "/testA/testB/testC/testD", Collections.singletonMap("ns0", "/test")); + assertTrue(addMountTable(addEntry)); // Create test dir in NN final FileSystem nnFs = nnContext.getFileSystem(); @@ -174,8 +181,18 @@ public class TestRouterMountTable { Map pathModTime = new TreeMap<>(); for (String mount : mountTable.getMountPoints("/")) { - pathModTime.put(mount, mountTable.getMountPoint("/"+mount) - .getDateModified()); + if (mountTable.getMountPoint("/"+mount) != null) { + pathModTime.put(mount, mountTable.getMountPoint("/"+mount) + .getDateModified()); + } else { + List entries = mountTable.getMounts("/"+mount); + for (MountTable entry : entries) { + if (pathModTime.get(mount) == null || + pathModTime.get(mount) < entry.getDateModified()) { + pathModTime.put(mount, entry.getDateModified()); + } + } + } } FileStatus[] iterator = nnFs.listStatus(new Path("/")); for (FileStatus file : iterator) {