From ec6638c902a976638b85503c5f47059ef08102ff Mon Sep 17 00:00:00 2001 From: Artem Ervits Date: Tue, 18 Jun 2019 11:48:18 -0400 Subject: [PATCH] HBASE-22561 modify HFilePrettyPrinter to accept non-rootdir directories Signed-off-by: huzheng --- .../hbase/io/hfile/HFilePrettyPrinter.java | 36 +++--- .../hbase-webapps/regionserver/storeFile.jsp | 2 +- .../io/hfile/TestHFilePrettyPrinter.java | 110 ++++++++++++++++++ 3 files changed, 131 insertions(+), 17 deletions(-) create mode 100644 hbase-server/src/test/java/org/apache/hadoop/hbase/io/hfile/TestHFilePrettyPrinter.java diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/HFilePrettyPrinter.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/HFilePrettyPrinter.java index 5a6f6c12e96..b7506e67556 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/HFilePrettyPrinter.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/HFilePrettyPrinter.java @@ -174,7 +174,7 @@ public class HFilePrettyPrinter extends Configured implements Tool { IOException { if (args.length == 0) { HelpFormatter formatter = new HelpFormatter(); - formatter.printHelp("HFile", options, true); + formatter.printHelp("hfile", options, true); return false; } CommandLineParser parser = new PosixParser(); @@ -267,7 +267,7 @@ public class HFilePrettyPrinter extends Configured implements Tool { // iterate over all files found for (Path fileName : files) { try { - int exitCode = processFile(fileName); + int exitCode = processFile(fileName, false); if (exitCode != 0) { return exitCode; } @@ -284,22 +284,26 @@ public class HFilePrettyPrinter extends Configured implements Tool { return 0; } - public int processFile(Path file) throws IOException { - if (verbose) + // HBASE-22561 introduces boolean checkRootDir for WebUI specificly + public int processFile(Path file, boolean checkRootDir) throws IOException { + if (verbose) { out.println("Scanning -> " + file); + } - Path rootPath = FSUtils.getRootDir(getConf()); - String rootString = rootPath + rootPath.SEPARATOR; - if (!file.toString().startsWith(rootString)) { - // First we see if fully-qualified URI matches the root dir. It might - // also be an absolute path in the same filesystem, so we prepend the FS - // of the root dir and see if that fully-qualified URI matches. - FileSystem rootFS = rootPath.getFileSystem(getConf()); - String qualifiedFile = rootFS.getUri().toString() + file.toString(); - if (!qualifiedFile.startsWith(rootString)) { - err.println("ERROR, file (" + file + - ") is not in HBase's root directory (" + rootString + ")"); - return -2; + if (checkRootDir) { + Path rootPath = FSUtils.getRootDir(getConf()); + String rootString = rootPath + rootPath.SEPARATOR; + if (!file.toString().startsWith(rootString)) { + // First we see if fully-qualified URI matches the root dir. It might + // also be an absolute path in the same filesystem, so we prepend the FS + // of the root dir and see if that fully-qualified URI matches. + FileSystem rootFS = rootPath.getFileSystem(getConf()); + String qualifiedFile = rootFS.getUri().toString() + file.toString(); + if (!qualifiedFile.startsWith(rootString)) { + err.println( + "ERROR, file (" + file + ") is not in HBase's root directory (" + rootString + ")"); + return -2; + } } } diff --git a/hbase-server/src/main/resources/hbase-webapps/regionserver/storeFile.jsp b/hbase-server/src/main/resources/hbase-webapps/regionserver/storeFile.jsp index 0def4e45c81..c1de41c3672 100644 --- a/hbase-server/src/main/resources/hbase-webapps/regionserver/storeFile.jsp +++ b/hbase-server/src/main/resources/hbase-webapps/regionserver/storeFile.jsp @@ -51,7 +51,7 @@ printer.setConf(conf); String[] options = {"-s"}; printer.parseOptions(options); - printer.processFile(new Path(storeFile)); + printer.processFile(new Path(storeFile), true); String text = byteStream.toString();%> <%= text diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/io/hfile/TestHFilePrettyPrinter.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/io/hfile/TestHFilePrettyPrinter.java new file mode 100644 index 00000000000..e0a168eddf1 --- /dev/null +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/io/hfile/TestHFilePrettyPrinter.java @@ -0,0 +1,110 @@ +/** + * 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.hbase.io.hfile; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertTrue; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; + +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.fs.FileSystem; +import org.apache.hadoop.fs.Path; +import org.apache.hadoop.hbase.HBaseClassTestRule; +import org.apache.hadoop.hbase.HBaseTestingUtility; +import org.apache.hadoop.hbase.regionserver.TestHRegionServerBulkLoad; +import org.apache.hadoop.hbase.testclassification.IOTests; +import org.apache.hadoop.hbase.testclassification.SmallTests; +import org.apache.hadoop.hbase.util.Bytes; +import org.apache.hadoop.hbase.util.FSUtils; +import org.junit.After; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@Category({IOTests.class, SmallTests.class}) +public class TestHFilePrettyPrinter { + + @ClassRule + public static final HBaseClassTestRule CLASS_RULE = + HBaseClassTestRule.forClass(TestHFilePrettyPrinter.class); + + private static final Logger LOG = LoggerFactory.getLogger(TestHFilePrettyPrinter.class); + + private final static HBaseTestingUtility UTIL = new HBaseTestingUtility(); + private static FileSystem fs; + private static Configuration conf; + private static byte [] cf = Bytes.toBytes("cf"); + private static byte [] fam = Bytes.toBytes("fam"); + private static byte [] value = Bytes.toBytes("val"); + private static PrintStream original; + private static PrintStream ps; + private static ByteArrayOutputStream stream; + + @Before + public void setup() throws Exception { + conf = UTIL.getConfiguration(); + fs = UTIL.getTestFileSystem(); + stream = new ByteArrayOutputStream(); + ps = new PrintStream(stream); + } + + @After + public void teardown() { + original = System.out; + System.setOut(original); + } + + @Test + public void testHFilePrettyPrinterNonRootDir() throws Exception { + Path fileNotInRootDir = UTIL.getDataTestDir("hfile"); + TestHRegionServerBulkLoad.createHFile(fs, fileNotInRootDir, cf, fam, value, 1000); + assertNotEquals("directory used is not an HBase root dir", + UTIL.getDefaultRootDirPath(), fileNotInRootDir); + + System.setOut(ps); + new HFilePrettyPrinter(conf).run(new String[]{"-v", String.valueOf(fileNotInRootDir)}); + String result = new String(stream.toByteArray()); + String expectedResult = "Scanning -> " + fileNotInRootDir + "\n" + "Scanned kv count -> 1000\n"; + assertEquals(expectedResult, result); + } + + @Test + public void testHFilePrettyPrinterRootDir() throws Exception { + Path rootPath = FSUtils.getRootDir(conf); + String rootString = rootPath + rootPath.SEPARATOR; + Path fileInRootDir = new Path(rootString + "hfile"); + TestHRegionServerBulkLoad.createHFile(fs, fileInRootDir, cf, fam, value, 1000); + assertTrue("directory used is a root dir", + fileInRootDir.toString().startsWith(rootString)); + + System.setOut(ps); + HFilePrettyPrinter printer = new HFilePrettyPrinter(); + printer.setConf(conf); + printer.processFile(fileInRootDir, true); + printer.run(new String[]{"-v", String.valueOf(fileInRootDir)}); + String result = new String(stream.toByteArray()); + String expectedResult = "Scanning -> " + fileInRootDir + "\n" + "Scanned kv count -> 1000\n"; + assertEquals(expectedResult, result); + } +}