HBASE-24776 [hbtop] Support Batch mode (#2291)

Signed-off-by: stack <stack@apache.org>
This commit is contained in:
Toshihiro Suzuki 2020-09-10 17:04:57 +09:00 committed by GitHub
parent f36c55c6e8
commit bc15b61927
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 411 additions and 80 deletions

View File

@ -17,11 +17,17 @@
*/
package org.apache.hadoop.hbase.hbtop;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.HBaseInterfaceAudience;
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;
@ -56,17 +62,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 DefaultParser().parse(opts, args);
if (commandLine.hasOption("help")) {
@ -74,20 +77,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) {
LOGGER.warn("Delay set too low or invalid, using default");
} else {
initialRefreshDelay = delay * 1000L;
}
}
if (commandLine.hasOption("mode")) {
String mode = commandLine.getOptionValue("mode");
switch (mode) {
@ -107,23 +96,148 @@ public class HBTop extends Configured implements Tool {
initialMode = Mode.REGION_SERVER;
break;
case "u":
initialMode = Mode.USER;
break;
case "c":
initialMode = Mode.CLIENT;
break;
default:
LOGGER.warn("Mode set invalid, using default");
break;
}
}
if (commandLine.hasOption("outputFieldNames")) {
initialMode.getFieldInfos().forEach(f -> System.out.println(f.getField().getHeader()));
return 0;
}
if (commandLine.hasOption("delay")) {
int delay = 0;
try {
delay = Integer.parseInt(commandLine.getOptionValue("delay"));
} catch (NumberFormatException ignored) {
}
if (delay < 1) {
LOGGER.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) {
LOGGER.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;
}
Optional<FieldInfo> fieldInfo = initialMode.getFieldInfos().stream()
.filter(f -> f.getField().getHeader().equals(field)).findFirst();
if (fieldInfo.isPresent()) {
initialSortField = fieldInfo.get().getField();
initialAscendingSort = ascendingSort;
} else {
LOGGER.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) {
Optional<FieldInfo> fieldInfo = initialMode.getFieldInfos().stream()
.filter(f -> f.getField().getHeader().equals(field)).findFirst();
if (fieldInfo.isPresent()) {
initialFields.add(fieldInfo.get().getField());
} else {
LOGGER.warn("The specified field " + field + " is not found, ignoring");
}
}
}
if (commandLine.hasOption("filters")) {
String[] filters = commandLine.getOptionValue("filters").split(",");
List<Field> fields = initialMode.getFieldInfos().stream().map(FieldInfo::getField)
.collect(Collectors.toList());
for (String filter : filters) {
RecordFilter f = RecordFilter.parse(filter, fields, false);
if (f != null) {
if (initialFilters == null) {
initialFilters = new ArrayList<>();
}
initialFilters.add(f);
} else {
LOGGER.warn("The specified filter " + filter + " is invalid, ignoring");
}
}
}
if (commandLine.hasOption("batchMode")) {
batchMode = true;
}
} catch (Exception e) {
LOGGER.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)|u (User)"
+ "|c (Client), 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("");

View File

@ -75,6 +75,7 @@ public abstract class AbstractScreenView implements ScreenView {
return terminal.getTerminalPrinter(startRow);
}
@Nullable
protected TerminalSize getTerminalSize() {
return terminal.getSize();
}

View File

@ -17,18 +17,23 @@
*/
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.hadoop.conf.Configuration;
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;
import org.apache.yetus.audience.InterfaceAudience;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -49,15 +54,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
@ -91,11 +104,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 {

View File

@ -19,13 +19,13 @@ package org.apache.hadoop.hbase.hbtop.screen.top;
import static org.apache.commons.lang3.time.DateFormatUtils.ISO_8601_EXTENDED_TIME_FORMAT;
import edu.umd.cs.findbugs.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import org.apache.hadoop.hbase.ClusterMetrics;
import org.apache.hadoop.hbase.client.Admin;
import org.apache.hadoop.hbase.hbtop.Record;
@ -64,28 +64,55 @@ 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 = Collections.unmodifiableList(currentMode.getFieldInfos().stream()
.map(FieldInfo::getField).collect(Collectors.toList()));
if (initialFields != null) {
List<Field> tmp = new ArrayList<>(initialFields);
tmp.addAll(currentMode.getFieldInfos().stream().map(FieldInfo::getField)
.filter(f -> !initialFields.contains(f))
.collect(Collectors.toList()));
fields = Collections.unmodifiableList(tmp);
} else {
fields = Collections.unmodifiableList(currentMode.getFieldInfos().stream()
.map(FieldInfo::getField).collect(Collectors.toList()));
}
if (keepSortFieldAndSortOrderIfPossible) {
boolean match = fields.stream().anyMatch(f -> f == currentSortField);
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();
@ -173,7 +200,7 @@ public class TopScreenModel {
if (drillDownInfo == null) {
return false;
}
switchMode(drillDownInfo.getNextMode(), drillDownInfo.getInitialFilters(), true);
switchMode(drillDownInfo.getNextMode(), true, drillDownInfo.getInitialFilters());
return true;
}

View File

@ -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;
@ -57,21 +58,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;
@ -82,8 +100,7 @@ public class TopScreenPresenter {
TerminalSize newTerminalSize = topScreenView.doResizeIfNecessary();
if (newTerminalSize != null) {
terminalLength = newTerminalSize.getColumns();
paging.updatePageSize(topScreenView.getPageSize());
updateTerminalLengthAndPageSize(newTerminalSize, topScreenView.getPageSize());
topScreenView.clearTerminal();
}
@ -98,6 +115,7 @@ public class TopScreenPresenter {
topScreenView.refreshTerminal();
lastRefreshTimestamp = System.currentTimeMillis();
iterations++;
return refreshDelay.get();
}
@ -242,7 +260,7 @@ public class TopScreenPresenter {
}
private void switchMode(Mode nextMode) {
topScreenModel.switchMode(nextMode, null, false);
topScreenModel.switchMode(nextMode, false, null);
reset();
}
@ -258,18 +276,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());
}
}
@ -288,7 +310,7 @@ public class TopScreenPresenter {
double delay;
try {
delay = Double.valueOf(inputString);
delay = Double.parseDouble(inputString);
} catch (NumberFormatException e) {
return goToMessageMode(screen, terminal, row, "Unacceptable floating point");
}
@ -329,4 +351,8 @@ public class TopScreenPresenter {
filters.addAll(topScreenModel.getPushDownFilters());
return new FilterDisplayModeScreenView(screen, terminal, row, filters, topScreenView);
}
public boolean isIterationFinished() {
return iterations >= numberOfIterations;
}
}

View File

@ -23,6 +23,8 @@ import java.util.List;
import java.util.stream.Collectors;
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();

View File

@ -29,7 +29,7 @@ import org.apache.yetus.audience.InterfaceAudience;
public interface Terminal extends Closeable {
void clear();
void refresh();
TerminalSize getSize();
@Nullable TerminalSize getSize();
@Nullable TerminalSize doResizeIfNecessary();
@Nullable KeyPress pollKeyPress();
CursorPosition getCursorPosition();

View File

@ -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() {
}
}

View File

@ -0,0 +1,54 @@
/**
* 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 org.apache.hadoop.hbase.hbtop.terminal.TerminalPrinter;
public class BatchTerminalPrinter implements TerminalPrinter {
@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();
}
}

View File

@ -63,7 +63,7 @@ public class TestTopScreenModel {
@Before
public void setup() throws IOException {
when(admin.getClusterMetrics()).thenReturn(TestUtils.createDummyClusterMetrics());
topScreenModel = new TopScreenModel(admin, Mode.REGION);
topScreenModel = new TopScreenModel(admin, Mode.REGION, null, null, null, null);
fields = Mode.REGION.getFieldInfos().stream()
.map(FieldInfo::getField)
@ -84,17 +84,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());
}
@ -168,7 +168,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
@ -176,7 +176,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++) {
@ -186,13 +186,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();

View File

@ -95,7 +95,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