You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by br...@apache.org on 2021/03/20 02:16:55 UTC
[hbase] branch branch-1 updated: HBASE-25258 Backport HBASE-24776
"[hbtop] Support Batch mode" to branch-1 (#3065)
This is an automated email from the ASF dual-hosted git repository.
brfrn169 pushed a commit to branch branch-1
in repository https://gitbox.apache.org/repos/asf/hbase.git
The following commit(s) were added to refs/heads/branch-1 by this push:
new f807800 HBASE-25258 Backport HBASE-24776 "[hbtop] Support Batch mode" to branch-1 (#3065)
f807800 is described below
commit f8078009e9e8cadee76fd38d1e35ea6812b866de
Author: Toshihiro Suzuki <br...@gmail.com>
AuthorDate: Sat Mar 20 11:16:26 2021 +0900
HBASE-25258 Backport HBASE-24776 "[hbtop] Support Batch mode" to branch-1 (#3065)
Signed-off-by: stack stack@apache.org
---
.../java/org/apache/hadoop/hbase/hbtop/HBTop.java | 169 ++++++++++++++++++---
.../hbase/hbtop/screen/AbstractScreenView.java | 1 +
.../apache/hadoop/hbase/hbtop/screen/Screen.java | 26 +++-
.../hbase/hbtop/screen/top/TopScreenModel.java | 44 ++++--
.../hbase/hbtop/screen/top/TopScreenPresenter.java | 46 ++++--
.../hbase/hbtop/screen/top/TopScreenView.java | 48 ++++--
.../hadoop/hbase/hbtop/terminal/Terminal.java | 2 +-
.../hbtop/terminal/impl/batch/BatchTerminal.java | 80 ++++++++++
.../batch/BatchTerminalPrinter.java} | 52 ++++---
.../hbase/hbtop/screen/top/TestTopScreenModel.java | 16 +-
.../hbtop/screen/top/TestTopScreenPresenter.java | 3 +-
11 files changed, 391 insertions(+), 96 deletions(-)
diff --git a/hbase-hbtop/src/main/java/org/apache/hadoop/hbase/hbtop/HBTop.java b/hbase-hbtop/src/main/java/org/apache/hadoop/hbase/hbtop/HBTop.java
index ac05bb2..b0f4710 100644
--- a/hbase-hbtop/src/main/java/org/apache/hadoop/hbase/hbtop/HBTop.java
+++ b/hbase-hbtop/src/main/java/org/apache/hadoop/hbase/hbtop/HBTop.java
@@ -17,6 +17,8 @@
*/
package org.apache.hadoop.hbase.hbtop;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Objects;
import org.apache.commons.cli.BasicParser;
@@ -30,6 +32,8 @@ import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.HBaseInterfaceAudience;
import org.apache.hadoop.hbase.classification.InterfaceAudience;
+import org.apache.hadoop.hbase.hbtop.field.Field;
+import org.apache.hadoop.hbase.hbtop.field.FieldInfo;
import org.apache.hadoop.hbase.hbtop.mode.Mode;
import org.apache.hadoop.hbase.hbtop.screen.Screen;
import org.apache.hadoop.util.Tool;
@@ -55,17 +59,14 @@ public class HBTop extends Configured implements Tool {
public int run(String[] args) throws Exception {
long initialRefreshDelay = 3 * 1000;
Mode initialMode = Mode.REGION;
+ List<Field> initialFields = null;
+ Field initialSortField = null;
+ Boolean initialAscendingSort = null;
+ List<RecordFilter> initialFilters = null;
+ long numberOfIterations = Long.MAX_VALUE;
+ boolean batchMode = false;
try {
- // Command line options
- Options opts = new Options();
- opts.addOption("h", "help", false,
- "Print usage; for help while the tool is running press 'h'");
- opts.addOption("d", "delay", true,
- "The refresh delay (in seconds); default is 3 seconds");
- opts.addOption("m", "mode", true,
- "The mode; n (Namespace)|t (Table)|r (Region)|s (RegionServer)"
- + ", default is r (Region)");
-
+ Options opts = getOptions();
CommandLine commandLine = new BasicParser().parse(opts, args);
if (commandLine.hasOption("help")) {
@@ -73,20 +74,6 @@ public class HBTop extends Configured implements Tool {
return 0;
}
- if (commandLine.hasOption("delay")) {
- int delay = 0;
- try {
- delay = Integer.parseInt(commandLine.getOptionValue("delay"));
- } catch (NumberFormatException ignored) {
- }
-
- if (delay < 1) {
- LOG.warn("Delay set too low or invalid, using default");
- } else {
- initialRefreshDelay = delay * 1000L;
- }
- }
-
if (commandLine.hasOption("mode")) {
String mode = commandLine.getOptionValue("mode");
switch (mode) {
@@ -111,18 +98,150 @@ public class HBTop extends Configured implements Tool {
break;
}
}
+
+ if (commandLine.hasOption("outputFieldNames")) {
+ for (FieldInfo fieldInfo : initialMode.getFieldInfos()) {
+ System.out.println(fieldInfo.getField().getHeader());
+ }
+ return 0;
+ }
+
+ if (commandLine.hasOption("delay")) {
+ int delay = 0;
+ try {
+ delay = Integer.parseInt(commandLine.getOptionValue("delay"));
+ } catch (NumberFormatException ignored) {
+ }
+
+ if (delay < 1) {
+ LOG.warn("Delay set too low or invalid, using default");
+ } else {
+ initialRefreshDelay = delay * 1000L;
+ }
+ }
+
+ if (commandLine.hasOption("numberOfIterations")) {
+ try {
+ numberOfIterations = Long.parseLong(commandLine.getOptionValue("numberOfIterations"));
+ } catch (NumberFormatException ignored) {
+ LOG.warn("The number of iterations set invalid, ignoring");
+ }
+ }
+
+ if (commandLine.hasOption("sortField")) {
+ String sortField = commandLine.getOptionValue("sortField");
+
+ String field;
+ boolean ascendingSort;
+ if (sortField.startsWith("+")) {
+ field = sortField.substring(1);
+ ascendingSort = false;
+ } else if (sortField.startsWith("-")) {
+ field = sortField.substring(1);
+ ascendingSort = true;
+ } else {
+ field = sortField;
+ ascendingSort = false;
+ }
+
+ FieldInfo fieldInfo = null;
+ for (FieldInfo info : initialMode.getFieldInfos()) {
+ if (info.getField().getHeader().equals(field)) {
+ fieldInfo = info;
+ break;
+ }
+ }
+ if (fieldInfo != null) {
+ initialSortField = fieldInfo.getField();
+ initialAscendingSort = ascendingSort;
+ } else {
+ LOG.warn("The specified sort field " + field + " is not found, using default");
+ }
+ }
+
+ if (commandLine.hasOption("fields")) {
+ String[] fields = commandLine.getOptionValue("fields").split(",");
+ initialFields = new ArrayList<>();
+ for (String field : fields) {
+ FieldInfo fieldInfo = null;
+ for (FieldInfo info : initialMode.getFieldInfos()) {
+ if (info.getField().getHeader().equals(field)) {
+ fieldInfo = info;
+ break;
+ }
+ }
+ if (fieldInfo != null) {
+ initialFields.add(fieldInfo.getField());
+ } else {
+ LOG.warn("The specified field " + field + " is not found, ignoring");
+ }
+ }
+ }
+
+ if (commandLine.hasOption("filters")) {
+ String[] filters = commandLine.getOptionValue("filters").split(",");
+
+ List<Field> fields = new ArrayList<>();
+ for (FieldInfo fieldInfo : initialMode.getFieldInfos()) {
+ fields.add(fieldInfo.getField());
+ }
+
+ for (String filter : filters) {
+ RecordFilter f = RecordFilter.parse(filter, fields, false);
+ if (f != null) {
+ if (initialFilters == null) {
+ initialFilters = new ArrayList<>();
+ }
+ initialFilters.add(f);
+ } else {
+ LOG.warn("The specified filter " + filter + " is invalid, ignoring");
+ }
+ }
+ }
+
+ if (commandLine.hasOption("batchMode")) {
+ batchMode = true;
+ }
} catch (Exception e) {
LOG.error("Unable to parse options", e);
return 1;
}
- try (Screen screen = new Screen(getConf(), initialRefreshDelay, initialMode)) {
+ try (Screen screen = new Screen(getConf(), initialRefreshDelay, initialMode, initialFields,
+ initialSortField, initialAscendingSort, initialFilters, numberOfIterations, batchMode)) {
screen.run();
}
return 0;
}
+ private Options getOptions() {
+ Options opts = new Options();
+ opts.addOption("h", "help", false,
+ "Print usage; for help while the tool is running press 'h'");
+ opts.addOption("d", "delay", true,
+ "The refresh delay (in seconds); default is 3 seconds");
+ opts.addOption("m", "mode", true,
+ "The mode; n (Namespace)|t (Table)|r (Region)|s (RegionServer), default is r");
+ opts.addOption("n", "numberOfIterations", true,
+ "The number of iterations");
+ opts.addOption("s", "sortField", true,
+ "The initial sort field. You can prepend a `+' or `-' to the field name to also override"
+ + " the sort direction. A leading `+' will force sorting high to low, whereas a `-' will"
+ + " ensure a low to high ordering");
+ opts.addOption("O", "outputFieldNames", false,
+ "Print each of the available field names on a separate line, then quit");
+ opts.addOption("f", "fields", true,
+ "Show only the given fields. Specify comma separated fields to show multiple fields");
+ opts.addOption("i", "filters", true,
+ "The initial filters. Specify comma separated filters to set multiple filters");
+ opts.addOption("b", "batchMode", false,
+ "Starts hbtop in Batch mode, which could be useful for sending output from hbtop to other"
+ + " programs or to a file. In this mode, hbtop will not accept input and runs until the"
+ + " iterations limit you've set with the `-n' command-line option or until killed");
+ return opts;
+ }
+
private void printUsage(Options opts) {
new HelpFormatter().printHelp("hbase hbtop [opts] [-D<property=value>]*", opts);
System.out.println("");
diff --git a/hbase-hbtop/src/main/java/org/apache/hadoop/hbase/hbtop/screen/AbstractScreenView.java b/hbase-hbtop/src/main/java/org/apache/hadoop/hbase/hbtop/screen/AbstractScreenView.java
index 32dfb53..8c885a4 100644
--- a/hbase-hbtop/src/main/java/org/apache/hadoop/hbase/hbtop/screen/AbstractScreenView.java
+++ b/hbase-hbtop/src/main/java/org/apache/hadoop/hbase/hbtop/screen/AbstractScreenView.java
@@ -75,6 +75,7 @@ public abstract class AbstractScreenView implements ScreenView {
return terminal.getTerminalPrinter(startRow);
}
+ @Nullable
protected TerminalSize getTerminalSize() {
return terminal.getSize();
}
diff --git a/hbase-hbtop/src/main/java/org/apache/hadoop/hbase/hbtop/screen/Screen.java b/hbase-hbtop/src/main/java/org/apache/hadoop/hbase/hbtop/screen/Screen.java
index bbcbba2..7629052 100644
--- a/hbase-hbtop/src/main/java/org/apache/hadoop/hbase/hbtop/screen/Screen.java
+++ b/hbase-hbtop/src/main/java/org/apache/hadoop/hbase/hbtop/screen/Screen.java
@@ -17,8 +17,10 @@
*/
package org.apache.hadoop.hbase.hbtop.screen;
+import edu.umd.cs.findbugs.annotations.Nullable;
import java.io.Closeable;
import java.io.IOException;
+import java.util.List;
import java.util.concurrent.TimeUnit;
import org.apache.commons.logging.Log;
@@ -28,11 +30,14 @@ import org.apache.hadoop.hbase.classification.InterfaceAudience;
import org.apache.hadoop.hbase.client.Admin;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;
+import org.apache.hadoop.hbase.hbtop.RecordFilter;
+import org.apache.hadoop.hbase.hbtop.field.Field;
import org.apache.hadoop.hbase.hbtop.mode.Mode;
import org.apache.hadoop.hbase.hbtop.screen.top.TopScreenView;
import org.apache.hadoop.hbase.hbtop.terminal.KeyPress;
import org.apache.hadoop.hbase.hbtop.terminal.Terminal;
import org.apache.hadoop.hbase.hbtop.terminal.impl.TerminalImpl;
+import org.apache.hadoop.hbase.hbtop.terminal.impl.batch.BatchTerminal;
/**
* This dispatches key presses and timers to the current {@link ScreenView}.
@@ -51,15 +56,23 @@ public class Screen implements Closeable {
private ScreenView currentScreenView;
private Long timerTimestamp;
- public Screen(Configuration conf, long initialRefreshDelay, Mode initialMode)
+ public Screen(Configuration conf, long initialRefreshDelay, Mode initialMode,
+ @Nullable List<Field> initialFields, @Nullable Field initialSortField,
+ @Nullable Boolean initialAscendingSort, @Nullable List<RecordFilter> initialFilters,
+ long numberOfIterations, boolean batchMode)
throws IOException {
connection = ConnectionFactory.createConnection(conf);
admin = connection.getAdmin();
// The first screen is the top screen
- this.terminal = new TerminalImpl("hbtop");
+ if (batchMode) {
+ terminal = new BatchTerminal();
+ } else {
+ terminal = new TerminalImpl("hbtop");
+ }
currentScreenView = new TopScreenView(this, terminal, initialRefreshDelay, admin,
- initialMode);
+ initialMode, initialFields, initialSortField, initialAscendingSort, initialFilters,
+ numberOfIterations);
}
@Override
@@ -93,11 +106,8 @@ public class Screen implements Closeable {
timerTimestamp = null;
nextScreenView = currentScreenView.handleTimer();
} else {
- if (timerTimestamp - now < SLEEP_TIMEOUT_MILLISECONDS) {
- TimeUnit.MILLISECONDS.sleep(timerTimestamp - now);
- } else {
- TimeUnit.MILLISECONDS.sleep(SLEEP_TIMEOUT_MILLISECONDS);
- }
+ TimeUnit.MILLISECONDS
+ .sleep(Math.min(timerTimestamp - now, SLEEP_TIMEOUT_MILLISECONDS));
continue;
}
} else {
diff --git a/hbase-hbtop/src/main/java/org/apache/hadoop/hbase/hbtop/screen/top/TopScreenModel.java b/hbase-hbtop/src/main/java/org/apache/hadoop/hbase/hbtop/screen/top/TopScreenModel.java
index f795c4a..05780da 100644
--- a/hbase-hbtop/src/main/java/org/apache/hadoop/hbase/hbtop/screen/top/TopScreenModel.java
+++ b/hbase-hbtop/src/main/java/org/apache/hadoop/hbase/hbtop/screen/top/TopScreenModel.java
@@ -17,6 +17,7 @@
*/
package org.apache.hadoop.hbase.hbtop.screen.top;
+import edu.umd.cs.findbugs.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
@@ -61,20 +62,34 @@ public class TopScreenModel {
private boolean ascendingSort;
- public TopScreenModel(Admin admin, Mode initialMode) {
+ public TopScreenModel(Admin admin, Mode initialMode, @Nullable List<Field> initialFields,
+ @Nullable Field initialSortField, @Nullable Boolean initialAscendingSort,
+ @Nullable List<RecordFilter> initialFilters) {
this.admin = Objects.requireNonNull(admin);
- switchMode(Objects.requireNonNull(initialMode), null, false);
+ switchMode(Objects.requireNonNull(initialMode), initialSortField, false, initialFields,
+ initialAscendingSort, initialFilters);
}
- public void switchMode(Mode nextMode, List<RecordFilter> initialFilters,
- boolean keepSortFieldAndSortOrderIfPossible) {
+ public void switchMode(Mode nextMode, boolean keepSortFieldAndSortOrderIfPossible,
+ List<RecordFilter> initialFilters) {
+ switchMode(nextMode, null, keepSortFieldAndSortOrderIfPossible, null, null, initialFilters);
+ }
+ public void switchMode(Mode nextMode, Field initialSortField,
+ boolean keepSortFieldAndSortOrderIfPossible, @Nullable List<Field> initialFields,
+ @Nullable Boolean initialAscendingSort, @Nullable List<RecordFilter> initialFilters) {
currentMode = nextMode;
fieldInfos = Collections.unmodifiableList(new ArrayList<>(currentMode.getFieldInfos()));
fields = new ArrayList<>();
for (FieldInfo fieldInfo : currentMode.getFieldInfos()) {
- fields.add(fieldInfo.getField());
+ if (initialFields != null) {
+ if (initialFields.contains(fieldInfo.getField())) {
+ fields.add(fieldInfo.getField());
+ }
+ } else {
+ fields.add(fieldInfo.getField());
+ }
}
fields = Collections.unmodifiableList(fields);
@@ -88,13 +103,22 @@ public class TopScreenModel {
}
if (!match) {
+ if (initialSortField != null && initialAscendingSort != null) {
+ currentSortField = initialSortField;
+ ascendingSort = initialAscendingSort;
+ } else {
+ currentSortField = nextMode.getDefaultSortField();
+ ascendingSort = false;
+ }
+ }
+ } else {
+ if (initialSortField != null && initialAscendingSort != null) {
+ currentSortField = initialSortField;
+ ascendingSort = initialAscendingSort;
+ } else {
currentSortField = nextMode.getDefaultSortField();
ascendingSort = false;
}
-
- } else {
- currentSortField = nextMode.getDefaultSortField();
- ascendingSort = false;
}
clearFilters();
@@ -197,7 +221,7 @@ public class TopScreenModel {
if (drillDownInfo == null) {
return false;
}
- switchMode(drillDownInfo.getNextMode(), drillDownInfo.getInitialFilters(), true);
+ switchMode(drillDownInfo.getNextMode(), true, drillDownInfo.getInitialFilters());
return true;
}
diff --git a/hbase-hbtop/src/main/java/org/apache/hadoop/hbase/hbtop/screen/top/TopScreenPresenter.java b/hbase-hbtop/src/main/java/org/apache/hadoop/hbase/hbtop/screen/top/TopScreenPresenter.java
index 02c35b8..266166c 100644
--- a/hbase-hbtop/src/main/java/org/apache/hadoop/hbase/hbtop/screen/top/TopScreenPresenter.java
+++ b/hbase-hbtop/src/main/java/org/apache/hadoop/hbase/hbtop/screen/top/TopScreenPresenter.java
@@ -17,6 +17,7 @@
*/
package org.apache.hadoop.hbase.hbtop.screen.top;
+import edu.umd.cs.findbugs.annotations.Nullable;
import java.util.ArrayList;
import java.util.EnumMap;
import java.util.List;
@@ -56,21 +57,38 @@ public class TopScreenPresenter {
private final EnumMap<Field, Boolean> fieldDisplayMap = new EnumMap<>(Field.class);
private final EnumMap<Field, Integer> fieldLengthMap = new EnumMap<>(Field.class);
+ private final long numberOfIterations;
+ private long iterations;
+
public TopScreenPresenter(TopScreenView topScreenView, long initialRefreshDelay,
- TopScreenModel topScreenModel) {
+ TopScreenModel topScreenModel, @Nullable List<Field> initialFields, long numberOfIterations) {
this.topScreenView = Objects.requireNonNull(topScreenView);
this.refreshDelay = new AtomicLong(initialRefreshDelay);
this.topScreenModel = Objects.requireNonNull(topScreenModel);
+ this.numberOfIterations = numberOfIterations;
- initFieldDisplayMapAndFieldLengthMap();
+ initFieldDisplayMapAndFieldLengthMap(initialFields);
}
public void init() {
- terminalLength = topScreenView.getTerminalSize().getColumns();
- paging.updatePageSize(topScreenView.getPageSize());
+ updateTerminalLengthAndPageSize(topScreenView.getTerminalSize(), topScreenView.getPageSize());
topScreenView.hideCursor();
}
+ private void updateTerminalLengthAndPageSize(@Nullable TerminalSize terminalSize,
+ @Nullable Integer pageSize) {
+ if (terminalSize != null) {
+ terminalLength = terminalSize.getColumns();
+ } else {
+ terminalLength = Integer.MAX_VALUE;
+ }
+ if (pageSize != null) {
+ paging.updatePageSize(pageSize);
+ } else {
+ paging.updatePageSize(Integer.MAX_VALUE);
+ }
+ }
+
public long refresh(boolean force) {
if (!force) {
long delay = System.currentTimeMillis() - lastRefreshTimestamp;
@@ -81,8 +99,7 @@ public class TopScreenPresenter {
TerminalSize newTerminalSize = topScreenView.doResizeIfNecessary();
if (newTerminalSize != null) {
- terminalLength = newTerminalSize.getColumns();
- paging.updatePageSize(topScreenView.getPageSize());
+ updateTerminalLengthAndPageSize(newTerminalSize, topScreenView.getPageSize());
topScreenView.clearTerminal();
}
@@ -97,6 +114,7 @@ public class TopScreenPresenter {
topScreenView.refreshTerminal();
lastRefreshTimestamp = System.currentTimeMillis();
+ iterations++;
return refreshDelay.get();
}
@@ -260,7 +278,7 @@ public class TopScreenPresenter {
}
private void switchMode(Mode nextMode) {
- topScreenModel.switchMode(nextMode, null, false);
+ topScreenModel.switchMode(nextMode, false, null);
reset();
}
@@ -276,18 +294,22 @@ public class TopScreenPresenter {
}
private void reset() {
- initFieldDisplayMapAndFieldLengthMap();
+ initFieldDisplayMapAndFieldLengthMap(null);
adjustFieldLength.set(true);
paging.init();
horizontalScroll = 0;
topScreenView.clearTerminal();
}
- private void initFieldDisplayMapAndFieldLengthMap() {
+ private void initFieldDisplayMapAndFieldLengthMap(@Nullable List<Field> initialFields) {
fieldDisplayMap.clear();
fieldLengthMap.clear();
for (FieldInfo fieldInfo : topScreenModel.getFieldInfos()) {
- fieldDisplayMap.put(fieldInfo.getField(), fieldInfo.isDisplayByDefault());
+ if (initialFields != null) {
+ fieldDisplayMap.put(fieldInfo.getField(), initialFields.contains(fieldInfo.getField()));
+ } else {
+ fieldDisplayMap.put(fieldInfo.getField(), fieldInfo.isDisplayByDefault());
+ }
fieldLengthMap.put(fieldInfo.getField(), fieldInfo.getDefaultLength());
}
}
@@ -353,4 +375,8 @@ public class TopScreenPresenter {
return new FilterDisplayModeScreenView(screen, terminal, row, topScreenModel.getFilters(),
topScreenView);
}
+
+ public boolean isIterationFinished() {
+ return iterations >= numberOfIterations;
+ }
}
diff --git a/hbase-hbtop/src/main/java/org/apache/hadoop/hbase/hbtop/screen/top/TopScreenView.java b/hbase-hbtop/src/main/java/org/apache/hadoop/hbase/hbtop/screen/top/TopScreenView.java
index 6d9348b..b24b4df 100644
--- a/hbase-hbtop/src/main/java/org/apache/hadoop/hbase/hbtop/screen/top/TopScreenView.java
+++ b/hbase-hbtop/src/main/java/org/apache/hadoop/hbase/hbtop/screen/top/TopScreenView.java
@@ -25,6 +25,8 @@ import org.apache.commons.lang3.StringUtils;
import org.apache.hadoop.hbase.classification.InterfaceAudience;
import org.apache.hadoop.hbase.client.Admin;
import org.apache.hadoop.hbase.hbtop.Record;
+import org.apache.hadoop.hbase.hbtop.RecordFilter;
+import org.apache.hadoop.hbase.hbtop.field.Field;
import org.apache.hadoop.hbase.hbtop.mode.Mode;
import org.apache.hadoop.hbase.hbtop.screen.AbstractScreenView;
import org.apache.hadoop.hbase.hbtop.screen.Screen;
@@ -50,13 +52,16 @@ public class TopScreenView extends AbstractScreenView {
private static final int RECORD_START_ROW = 9;
private final TopScreenPresenter topScreenPresenter;
- private int pageSize;
+ private Integer pageSize;
public TopScreenView(Screen screen, Terminal terminal, long initialRefreshDelay, Admin admin,
- Mode initialMode) {
+ Mode initialMode, @Nullable List<Field> initialFields, @Nullable Field initialSortField,
+ @Nullable Boolean initialAscendingSort, @Nullable List<RecordFilter> initialFilters,
+ long numberOfIterations) {
super(screen, terminal);
this.topScreenPresenter = new TopScreenPresenter(this, initialRefreshDelay,
- new TopScreenModel(admin, initialMode));
+ new TopScreenModel(admin, initialMode, initialFields, initialSortField,
+ initialAscendingSort, initialFilters), initialFields, numberOfIterations);
}
@Override
@@ -66,11 +71,12 @@ public class TopScreenView extends AbstractScreenView {
setTimer(delay);
}
+ @Nullable
@Override
public ScreenView handleTimer() {
long delay = topScreenPresenter.refresh(false);
setTimer(delay);
- return this;
+ return topScreenPresenter.isIterationFinished() ? null : this;
}
@Nullable
@@ -79,39 +85,39 @@ public class TopScreenView extends AbstractScreenView {
switch (keyPress.getType()) {
case Enter:
topScreenPresenter.refresh(true);
- return this;
+ return topScreenPresenter.isIterationFinished() ? null : this;
case ArrowUp:
topScreenPresenter.arrowUp();
- return this;
+ return topScreenPresenter.isIterationFinished() ? null : this;
case ArrowDown:
topScreenPresenter.arrowDown();
- return this;
+ return topScreenPresenter.isIterationFinished() ? null : this;
case ArrowLeft:
topScreenPresenter.arrowLeft();
- return this;
+ return topScreenPresenter.isIterationFinished() ? null : this;
case ArrowRight:
topScreenPresenter.arrowRight();
- return this;
+ return topScreenPresenter.isIterationFinished() ? null : this;
case PageUp:
topScreenPresenter.pageUp();
- return this;
+ return topScreenPresenter.isIterationFinished() ? null : this;
case PageDown:
topScreenPresenter.pageDown();
- return this;
+ return topScreenPresenter.isIterationFinished() ? null : this;
case Home:
topScreenPresenter.home();
- return this;
+ return topScreenPresenter.isIterationFinished() ? null : this;
case End:
topScreenPresenter.end();
- return this;
+ return topScreenPresenter.isIterationFinished() ? null : this;
case Escape:
return null;
@@ -182,13 +188,18 @@ public class TopScreenView extends AbstractScreenView {
return this;
}
+ @Nullable
@Override
public TerminalSize getTerminalSize() {
TerminalSize terminalSize = super.getTerminalSize();
+ if (terminalSize == null) {
+ return null;
+ }
updatePageSize(terminalSize);
return terminalSize;
}
+ @Nullable
@Override
public TerminalSize doResizeIfNecessary() {
TerminalSize terminalSize = super.doResizeIfNecessary();
@@ -206,7 +217,8 @@ public class TopScreenView extends AbstractScreenView {
}
}
- public int getPageSize() {
+ @Nullable
+ public Integer getPageSize() {
return pageSize;
}
@@ -244,8 +256,14 @@ public class TopScreenView extends AbstractScreenView {
private void showRecords(List<Header> headers, List<Record> records, Record selectedRecord) {
TerminalPrinter printer = getTerminalPrinter(RECORD_START_ROW);
+ int size;
+ if (pageSize != null) {
+ size = pageSize;
+ } else {
+ size = records.size();
+ }
List<String> buf = new ArrayList<>(headers.size());
- for (int i = 0; i < pageSize; i++) {
+ for (int i = 0; i < size; i++) {
if(i < records.size()) {
Record record = records.get(i);
buf.clear();
diff --git a/hbase-hbtop/src/main/java/org/apache/hadoop/hbase/hbtop/terminal/Terminal.java b/hbase-hbtop/src/main/java/org/apache/hadoop/hbase/hbtop/terminal/Terminal.java
index 8da71af..44c77d5 100644
--- a/hbase-hbtop/src/main/java/org/apache/hadoop/hbase/hbtop/terminal/Terminal.java
+++ b/hbase-hbtop/src/main/java/org/apache/hadoop/hbase/hbtop/terminal/Terminal.java
@@ -29,7 +29,7 @@ import org.apache.hadoop.hbase.classification.InterfaceAudience;
public interface Terminal extends Closeable {
void clear();
void refresh();
- TerminalSize getSize();
+ @Nullable TerminalSize getSize();
@Nullable TerminalSize doResizeIfNecessary();
@Nullable KeyPress pollKeyPress();
CursorPosition getCursorPosition();
diff --git a/hbase-hbtop/src/main/java/org/apache/hadoop/hbase/hbtop/terminal/impl/batch/BatchTerminal.java b/hbase-hbtop/src/main/java/org/apache/hadoop/hbase/hbtop/terminal/impl/batch/BatchTerminal.java
new file mode 100644
index 0000000..19d6426
--- /dev/null
+++ b/hbase-hbtop/src/main/java/org/apache/hadoop/hbase/hbtop/terminal/impl/batch/BatchTerminal.java
@@ -0,0 +1,80 @@
+/**
+ * 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.hbtop.terminal.impl.batch;
+
+import edu.umd.cs.findbugs.annotations.Nullable;
+import org.apache.hadoop.hbase.hbtop.terminal.CursorPosition;
+import org.apache.hadoop.hbase.hbtop.terminal.KeyPress;
+import org.apache.hadoop.hbase.hbtop.terminal.Terminal;
+import org.apache.hadoop.hbase.hbtop.terminal.TerminalPrinter;
+import org.apache.hadoop.hbase.hbtop.terminal.TerminalSize;
+
+public class BatchTerminal implements Terminal {
+
+ private static final TerminalPrinter TERMINAL_PRINTER = new BatchTerminalPrinter();
+
+ @Override
+ public void clear() {
+ }
+
+ @Override
+ public void refresh() {
+ // Add a new line
+ TERMINAL_PRINTER.endOfLine();
+ }
+
+ @Nullable
+ @Override
+ public TerminalSize getSize() {
+ return null;
+ }
+
+ @Nullable
+ @Override
+ public TerminalSize doResizeIfNecessary() {
+ return null;
+ }
+
+ @Nullable
+ @Override
+ public KeyPress pollKeyPress() {
+ return null;
+ }
+
+ @Override
+ public CursorPosition getCursorPosition() {
+ return null;
+ }
+
+ @Override
+ public void setCursorPosition(int column, int row) {
+ }
+
+ @Override
+ public void hideCursor() {
+ }
+
+ @Override
+ public TerminalPrinter getTerminalPrinter(int startRow) {
+ return TERMINAL_PRINTER;
+ }
+
+ @Override
+ public void close() {
+ }
+}
diff --git a/hbase-hbtop/src/main/java/org/apache/hadoop/hbase/hbtop/terminal/Terminal.java b/hbase-hbtop/src/main/java/org/apache/hadoop/hbase/hbtop/terminal/impl/batch/BatchTerminalPrinter.java
similarity index 52%
copy from hbase-hbtop/src/main/java/org/apache/hadoop/hbase/hbtop/terminal/Terminal.java
copy to hbase-hbtop/src/main/java/org/apache/hadoop/hbase/hbtop/terminal/impl/batch/BatchTerminalPrinter.java
index 8da71af..afae5e8 100644
--- a/hbase-hbtop/src/main/java/org/apache/hadoop/hbase/hbtop/terminal/Terminal.java
+++ b/hbase-hbtop/src/main/java/org/apache/hadoop/hbase/hbtop/terminal/impl/batch/BatchTerminalPrinter.java
@@ -15,25 +15,41 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.hadoop.hbase.hbtop.terminal;
+package org.apache.hadoop.hbase.hbtop.terminal.impl.batch;
-import edu.umd.cs.findbugs.annotations.Nullable;
-import java.io.Closeable;
+import org.apache.hadoop.hbase.hbtop.terminal.AbstractTerminalPrinter;
+import org.apache.hadoop.hbase.hbtop.terminal.TerminalPrinter;
-import org.apache.hadoop.hbase.classification.InterfaceAudience;
+public class BatchTerminalPrinter extends AbstractTerminalPrinter {
-/**
- * The terminal interface that is an abstraction of terminal screen.
- */
-@InterfaceAudience.Private
-public interface Terminal extends Closeable {
- void clear();
- void refresh();
- TerminalSize getSize();
- @Nullable TerminalSize doResizeIfNecessary();
- @Nullable KeyPress pollKeyPress();
- CursorPosition getCursorPosition();
- void setCursorPosition(int column, int row);
- void hideCursor();
- TerminalPrinter getTerminalPrinter(int startRow);
+ @Override
+ public TerminalPrinter print(String value) {
+ System.out.print(value);
+ return this;
+ }
+
+ @Override
+ public TerminalPrinter startHighlight() {
+ return this;
+ }
+
+ @Override
+ public TerminalPrinter stopHighlight() {
+ return this;
+ }
+
+ @Override
+ public TerminalPrinter startBold() {
+ return this;
+ }
+
+ @Override
+ public TerminalPrinter stopBold() {
+ return this;
+ }
+
+ @Override
+ public void endOfLine() {
+ System.out.println();
+ }
}
diff --git a/hbase-hbtop/src/test/java/org/apache/hadoop/hbase/hbtop/screen/top/TestTopScreenModel.java b/hbase-hbtop/src/test/java/org/apache/hadoop/hbase/hbtop/screen/top/TestTopScreenModel.java
index 9dec535..5b6f884 100644
--- a/hbase-hbtop/src/test/java/org/apache/hadoop/hbase/hbtop/screen/top/TestTopScreenModel.java
+++ b/hbase-hbtop/src/test/java/org/apache/hadoop/hbase/hbtop/screen/top/TestTopScreenModel.java
@@ -56,7 +56,7 @@ public class TestTopScreenModel {
@Before
public void setup() throws IOException {
when(admin.getClusterStatus()).thenReturn(TestUtils.createDummyClusterStatus());
- topScreenModel = new TopScreenModel(admin, Mode.REGION);
+ topScreenModel = new TopScreenModel(admin, Mode.REGION, null, null, null, null);
fields = new ArrayList<>();
for (FieldInfo fieldInfo : Mode.REGION.getFieldInfos()) {
@@ -78,17 +78,17 @@ public class TestTopScreenModel {
TestUtils.assertRecordsInRegionMode(topScreenModel.getRecords());
// Namespace Mode
- topScreenModel.switchMode(Mode.NAMESPACE, null, false);
+ topScreenModel.switchMode(Mode.NAMESPACE, false, null);
topScreenModel.refreshMetricsData();
TestUtils.assertRecordsInNamespaceMode(topScreenModel.getRecords());
// Table Mode
- topScreenModel.switchMode(Mode.TABLE, null, false);
+ topScreenModel.switchMode(Mode.TABLE, false, null);
topScreenModel.refreshMetricsData();
TestUtils.assertRecordsInTableMode(topScreenModel.getRecords());
// Namespace Mode
- topScreenModel.switchMode(Mode.REGION_SERVER, null, false);
+ topScreenModel.switchMode(Mode.REGION_SERVER, false, null);
topScreenModel.refreshMetricsData();
TestUtils.assertRecordsInRegionServerMode(topScreenModel.getRecords());
}
@@ -162,7 +162,7 @@ public class TestTopScreenModel {
@Test
public void testSwitchMode() {
- topScreenModel.switchMode(Mode.TABLE, null, false);
+ topScreenModel.switchMode(Mode.TABLE, false, null);
assertThat(topScreenModel.getCurrentMode(), is(Mode.TABLE));
// Test for initialFilters
@@ -170,7 +170,7 @@ public class TestTopScreenModel {
RecordFilter.parse("TABLE==table1", fields, true),
RecordFilter.parse("TABLE==table2", fields, true));
- topScreenModel.switchMode(Mode.TABLE, initialFilters, false);
+ topScreenModel.switchMode(Mode.TABLE, false, initialFilters);
assertThat(topScreenModel.getFilters().size(), is(initialFilters.size()));
for (int i = 0; i < topScreenModel.getFilters().size(); i++) {
@@ -180,13 +180,13 @@ public class TestTopScreenModel {
// Test when keepSortFieldAndSortOrderIfPossible is true
topScreenModel.setSortFieldAndFields(Field.NAMESPACE, fields);
- topScreenModel.switchMode(Mode.NAMESPACE, null, true);
+ topScreenModel.switchMode(Mode.NAMESPACE, true, null);
assertThat(topScreenModel.getCurrentSortField(), is(Field.NAMESPACE));
}
@Test
public void testDrillDown() {
- topScreenModel.switchMode(Mode.TABLE, null, false);
+ topScreenModel.switchMode(Mode.TABLE, false, null);
topScreenModel.setSortFieldAndFields(Field.NAMESPACE, fields);
topScreenModel.refreshMetricsData();
diff --git a/hbase-hbtop/src/test/java/org/apache/hadoop/hbase/hbtop/screen/top/TestTopScreenPresenter.java b/hbase-hbtop/src/test/java/org/apache/hadoop/hbase/hbtop/screen/top/TestTopScreenPresenter.java
index b16b260..8bb036e 100644
--- a/hbase-hbtop/src/test/java/org/apache/hadoop/hbase/hbtop/screen/top/TestTopScreenPresenter.java
+++ b/hbase-hbtop/src/test/java/org/apache/hadoop/hbase/hbtop/screen/top/TestTopScreenPresenter.java
@@ -94,7 +94,8 @@ public class TestTopScreenPresenter {
when(topScreenModel.getRecords()).thenReturn(TEST_RECORDS);
when(topScreenModel.getSummary()).thenReturn(TEST_SUMMARY);
- topScreenPresenter = new TopScreenPresenter(topScreenView, 3000, topScreenModel);
+ topScreenPresenter = new TopScreenPresenter(topScreenView, 3000, topScreenModel,
+ null, Long.MAX_VALUE);
}
@Test