stroom.index.client.presenter.IndexShardPresenter.java Source code

Java tutorial

Introduction

Here is the source code for stroom.index.client.presenter.IndexShardPresenter.java

Source

/*
 * Copyright 2016 Crown Copyright
 *
 * Licensed 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 stroom.index.client.presenter;

import com.google.gwt.cell.client.TextCell;
import com.google.gwt.core.shared.GWT;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.ImageResource;
import com.google.gwt.user.cellview.client.Column;
import com.google.gwt.user.cellview.client.Header;
import com.google.inject.Inject;
import com.google.web.bindery.event.shared.EventBus;
import com.gwtplatform.mvp.client.MyPresenterWidget;
import stroom.alert.client.event.AlertEvent;
import stroom.alert.client.event.ConfirmEvent;
import stroom.cell.info.client.InfoColumn;
import stroom.cell.tickbox.client.TickBoxCell;
import stroom.cell.tickbox.shared.TickBoxState;
import stroom.data.grid.client.DataGridView;
import stroom.data.grid.client.DataGridViewImpl;
import stroom.data.grid.client.EndColumn;
import stroom.data.table.client.Refreshable;
import stroom.dispatch.client.AsyncCallbackAdaptor;
import stroom.dispatch.client.ClientDispatchAsync;
import stroom.entity.client.presenter.HasRead;
import stroom.entity.shared.EntityServiceFindAction;
import stroom.entity.shared.ResultList;
import stroom.index.shared.CloseIndexShardAction;
import stroom.index.shared.DeleteIndexShardAction;
import stroom.index.shared.FindIndexShardCriteria;
import stroom.index.shared.FlushIndexShardAction;
import stroom.index.shared.Index;
import stroom.index.shared.IndexShard;
import stroom.node.shared.Node;
import stroom.node.shared.Volume;
import stroom.streamstore.client.presenter.ActionDataProvider;
import stroom.util.shared.ModelStringUtil;
import stroom.util.shared.VoidResult;
import stroom.widget.button.client.GlyphButtonView;
import stroom.widget.button.client.GlyphIcons;
import stroom.widget.button.client.ImageButtonView;
import stroom.widget.customdatebox.client.ClientDateUtil;
import stroom.widget.popup.client.event.ShowPopupEvent;
import stroom.widget.popup.client.presenter.PopupPosition;
import stroom.widget.popup.client.presenter.PopupView.PopupType;
import stroom.widget.tooltip.client.presenter.TooltipPresenter;
import stroom.widget.tooltip.client.presenter.TooltipUtil;

import java.util.HashSet;
import java.util.Set;

public class IndexShardPresenter extends MyPresenterWidget<DataGridView<IndexShard>>
        implements Refreshable, HasRead<Index> {
    private final TooltipPresenter tooltipPresenter;
    private final ClientDispatchAsync dispatcher;
    private ActionDataProvider<IndexShard> dataProvider;
    private ResultList<IndexShard> resultList = null;
    private final FindIndexShardCriteria criteria = new FindIndexShardCriteria();
    private final ImageButtonView buttonFlush;
    private final ImageButtonView buttonClose;
    private final GlyphButtonView buttonDelete;
    private Index index;

    @Inject
    public IndexShardPresenter(final EventBus eventBus, final Resources resources,
            final TooltipPresenter tooltipPresenter, final ClientDispatchAsync dispatcher) {
        super(eventBus, new DataGridViewImpl<>(false));
        this.tooltipPresenter = tooltipPresenter;
        this.dispatcher = dispatcher;

        buttonFlush = getView().addButton("Flush Selected Shards", resources.flush(), resources.flushDisabled(),
                false);
        buttonClose = getView().addButton("Close Selected Shards", resources.close(), resources.closeDisabled(),
                false);
        buttonDelete = getView().addButton(GlyphIcons.DELETE);
        buttonDelete.setTitle("Delete Selected Shards");

        addColumns();
    }

    @Override
    protected void onBind() {
        super.onBind();
        registerHandler(buttonFlush.addClickHandler(event -> {
            if (NativeEvent.BUTTON_LEFT == event.getNativeButton()) {
                flush();
            }
        }));
        registerHandler(buttonClose.addClickHandler(event -> {
            if (NativeEvent.BUTTON_LEFT == event.getNativeButton()) {
                close();
            }
        }));
        registerHandler(buttonDelete.addClickHandler(event -> {
            if (NativeEvent.BUTTON_LEFT == event.getNativeButton()) {
                delete();
            }
        }));
    }

    private void enableButtons() {
        final boolean enabled = !criteria.getIndexShardSet().isMatchNothing();
        buttonFlush.setEnabled(enabled);
        buttonClose.setEnabled(enabled);
        buttonDelete.setEnabled(enabled);
    }

    private void addColumns() {
        addSelectedColumn();
        addInfoColumn();
        addNodeColumn();
        addPartitionColumn();
        addPathColumn();
        addStatusColumn();
        addDocCountColumn();
        addFileSizeColumn();
        addBytesPDColumn();
        addCommitColumn();
        addCommitDurationColumn();
        addCommitCountColumn();
        addVersionColumn();
        getView().addEndColumn(new EndColumn<>());
    }

    private void addSelectedColumn() {
        final TickBoxCell.MarginAppearance tickBoxAppearance = GWT.create(TickBoxCell.MarginAppearance.class);

        // Select Column
        final Column<IndexShard, TickBoxState> column = new Column<IndexShard, TickBoxState>(
                new TickBoxCell(tickBoxAppearance, false, false)) {
            @Override
            public TickBoxState getValue(final IndexShard indexShard) {
                final boolean match = Boolean.TRUE.equals(criteria.getIndexShardSet().getMatchAll())
                        || criteria.getIndexShardSet().contains(indexShard.getId());
                return TickBoxState.fromBoolean(match);
            }

        };
        final Header<TickBoxState> header = new Header<TickBoxState>(
                new TickBoxCell(tickBoxAppearance, false, false)) {
            @Override
            public TickBoxState getValue() {
                if (Boolean.TRUE.equals(criteria.getIndexShardSet().getMatchAll())) {
                    return TickBoxState.TICK;
                } else if (criteria.getIndexShardSet().getSet().size() > 0) {
                    return TickBoxState.HALF_TICK;
                }
                return TickBoxState.UNTICK;
            }
        };
        getView().addColumn(column, header, 15);

        // Add Handlers
        header.setUpdater(value -> {
            if (value.equals(TickBoxState.UNTICK)) {
                criteria.getIndexShardSet().clear();
                criteria.getIndexShardSet().setMatchAll(false);
            } else if (value.equals(TickBoxState.TICK)) {
                criteria.getIndexShardSet().clear();
                criteria.getIndexShardSet().setMatchAll(true);
            }

            if (dataProvider != null) {
                dataProvider.updateRowData(dataProvider.getRanges()[0].getStart(), resultList);
            }

            enableButtons();
        });
        column.setFieldUpdater((index, row, value) -> {
            if (value.toBoolean()) {
                criteria.getIndexShardSet().add(row);
            } else {
                // De-selecting one and currently matching all ?
                if (Boolean.TRUE.equals(criteria.getIndexShardSet().getMatchAll())) {
                    criteria.getIndexShardSet().setMatchAll(false);
                    criteria.getIndexShardSet().addAll(getResultStreamIdSet());
                }
                criteria.getIndexShardSet().remove(row);
            }
            enableButtons();
        });
    }

    private void addInfoColumn() {
        // Info column.
        final InfoColumn<IndexShard> infoColumn = new InfoColumn<IndexShard>() {
            @Override
            protected void showInfo(final IndexShard indexShard, final int x, final int y) {
                final StringBuilder html = new StringBuilder();

                if (index != null) {
                    TooltipUtil.addRowData(html, "Index Id", String.valueOf(index.getId()));
                }
                TooltipUtil.addRowData(html, "Shard Id", String.valueOf(indexShard.getId()));
                TooltipUtil.addRowData(html, "Node", indexShard.getNode().getName());
                TooltipUtil.addRowData(html, "Partition", indexShard.getPartition());
                if (indexShard.getPartitionFromTime() != null) {
                    TooltipUtil.addRowData(html, "Partition From",
                            ClientDateUtil.createDateTimeString(indexShard.getPartitionFromTime()));
                }
                if (indexShard.getPartitionToTime() != null) {
                    TooltipUtil.addRowData(html, "Partition To",
                            ClientDateUtil.createDateTimeString(indexShard.getPartitionToTime()));
                }
                TooltipUtil.addRowData(html, "Path", indexShard.getVolume().getPath());
                TooltipUtil.addRowData(html, "Status", indexShard.getStatus().getDisplayValue());
                TooltipUtil.addRowData(html, "Document Count", intToString(indexShard.getDocumentCount()));
                TooltipUtil.addRowData(html, "File Size", indexShard.getFileSizeString());
                TooltipUtil.addRowData(html, "Bytes Per Document", intToString(indexShard.getBytesPerDocument()));
                TooltipUtil.addRowData(html, "Commit",
                        ClientDateUtil.createDateTimeString(indexShard.getCommitMs()));
                TooltipUtil.addRowData(html, "Commit Duration",
                        ModelStringUtil.formatDurationString(indexShard.getCommitDurationMs()));
                TooltipUtil.addRowData(html, "Commit Document Count",
                        intToString(indexShard.getCommitDocumentCount()));
                TooltipUtil.addRowData(html, "Index Version", indexShard.getIndexVersion());

                tooltipPresenter.setHTML(html.toString());

                final PopupPosition popupPosition = new PopupPosition(x, y);
                ShowPopupEvent.fire(IndexShardPresenter.this, tooltipPresenter, PopupType.POPUP, popupPosition,
                        null);
            }
        };
        getView().addColumn(infoColumn, "<br/>", 15);
    }

    private void addNodeColumn() {
        getView().addResizableColumn(new Column<IndexShard, String>(new TextCell()) {
            @Override
            public String getValue(final IndexShard indexShard) {
                return indexShard.getNode().getName();
            }
        }, "Node", 100);
    }

    private void addPartitionColumn() {
        getView().addResizableColumn(new Column<IndexShard, String>(new TextCell()) {
            @Override
            public String getValue(final IndexShard indexShard) {
                return indexShard.getPartition();
            }
        }, "Partition", 100);
    }

    private void addPathColumn() {
        getView().addResizableColumn(new Column<IndexShard, String>(new TextCell()) {
            @Override
            public String getValue(final IndexShard indexShard) {
                return indexShard.getVolume().getPath();
            }
        }, "Path", 200);
    }

    private void addStatusColumn() {
        getView().addResizableColumn(new Column<IndexShard, String>(new TextCell()) {
            @Override
            public String getValue(final IndexShard indexShard) {
                return indexShard.getStatus().getDisplayValue();
            }
        }, "Status", 100);
    }

    private void addDocCountColumn() {
        getView().addResizableColumn(new Column<IndexShard, String>(new TextCell()) {
            @Override
            public String getValue(final IndexShard indexShard) {
                return intToString(indexShard.getDocumentCount());
            }
        }, "Doc Count", 100);
    }

    private void addFileSizeColumn() {
        getView().addResizableColumn(new Column<IndexShard, String>(new TextCell()) {
            @Override
            public String getValue(final IndexShard indexShard) {
                return indexShard.getFileSizeString();
            }
        }, "File Size", 100);
    }

    private void addBytesPDColumn() {
        getView().addResizableColumn(new Column<IndexShard, String>(new TextCell()) {
            @Override
            public String getValue(final IndexShard indexShard) {
                return intToString(indexShard.getBytesPerDocument());
            }
        }, "Bytes pd", 100);
    }

    private void addCommitColumn() {
        getView().addResizableColumn(new Column<IndexShard, String>(new TextCell()) {
            @Override
            public String getValue(final IndexShard indexShard) {
                return ClientDateUtil.createDateTimeString(indexShard.getCommitMs());
            }
        }, "Commit", 150);
    }

    private void addCommitDurationColumn() {
        getView().addResizableColumn(new Column<IndexShard, String>(new TextCell()) {
            @Override
            public String getValue(final IndexShard indexShard) {
                return ModelStringUtil.formatDurationString(indexShard.getCommitDurationMs());
            }
        }, "Commit Duration", 100);
    }

    private void addCommitCountColumn() {
        getView().addResizableColumn(new Column<IndexShard, String>(new TextCell()) {
            @Override
            public String getValue(final IndexShard indexShard) {
                return intToString(indexShard.getCommitDocumentCount());
            }
        }, "Commit Doc Count", 120);
    }

    private void addVersionColumn() {
        getView().addResizableColumn(new Column<IndexShard, String>(new TextCell()) {
            @Override
            public String getValue(final IndexShard indexShard) {
                return indexShard.getIndexVersion();
            }
        }, "Index Version", 100);
    }

    private String intToString(final Integer integer) {
        if (integer == null) {
            return null;
        }
        return integer.toString();
    }

    private Set<Long> getResultStreamIdSet() {
        final HashSet<Long> rtn = new HashSet<>();
        if (resultList != null) {
            for (final IndexShard e : resultList) {
                rtn.add(e.getId());
            }
        }
        return rtn;

    }

    @Override
    public void refresh() {
        dataProvider.refresh();
    }

    @Override
    public void read(final Index index) {
        this.index = index;
        criteria.getIndexIdSet().add(index);
        criteria.getFetchSet().add(Node.ENTITY_TYPE);
        criteria.getFetchSet().add(Volume.ENTITY_TYPE);

        if (dataProvider == null) {
            final EntityServiceFindAction<FindIndexShardCriteria, IndexShard> findAction = new EntityServiceFindAction<>(
                    criteria);
            dataProvider = new ActionDataProvider<IndexShard>(dispatcher, findAction) {
                @Override
                protected void changeData(final ResultList<IndexShard> data) {
                    super.changeData(data);
                    onChangeData(data);
                }
            };
            dataProvider.addDataDisplay(getView().getDataDisplay());
        }
    }

    private void onChangeData(final ResultList<IndexShard> data) {
        resultList = data;

        if (!Boolean.TRUE.equals(criteria.getIndexShardSet().getMatchAll())) {
            if (criteria.getIndexShardSet().getSet().retainAll(getResultStreamIdSet())) {
                enableButtons();
            }
        }

        //        IndexShard selected = getView().getSelectionModel().getSelected();
        //        if (selected != null) {
        //            if (!resultList.contains(selected)) {
        //                getView().getSelectionModel().clear();
        //            }
        //        }
    }

    private void flush() {
        if (Boolean.TRUE.equals(criteria.getIndexShardSet().getMatchAll())) {
            ConfirmEvent.fire(this, "Are you sure you want to flush the selected index shards?", result -> {
                if (result) {
                    ConfirmEvent.fire(IndexShardPresenter.this,
                            "You have selected to flush all filtered index shards! Are you absolutely sure you want to do this?",
                            result1 -> {
                                if (result1) {
                                    doFlush();
                                }
                            });
                }
            });
        } else if (criteria.getIndexShardSet().isConstrained()) {
            ConfirmEvent.fire(this, "Are you sure you want to flush the selected index shards?", result -> {
                if (result) {
                    doFlush();
                }
            });

        } else {
            AlertEvent.fireWarn(this, "No index shards have been selected for flushing!", null);
        }
    }

    private void close() {
        if (Boolean.TRUE.equals(criteria.getIndexShardSet().getMatchAll())) {
            ConfirmEvent.fire(this, "Are you sure you want to close the selected index shards?", result -> {
                if (result) {
                    ConfirmEvent.fire(IndexShardPresenter.this,
                            "You have selected to close all filtered index shards! Are you absolutely sure you want to do this?",
                            result1 -> {
                                if (result1) {
                                    doClose();
                                }
                            });
                }
            });
        } else if (criteria.getIndexShardSet().isConstrained()) {
            ConfirmEvent.fire(this, "Are you sure you want to close the selected index shards?", result -> {
                if (result) {
                    doClose();
                }
            });

        } else {
            AlertEvent.fireWarn(this, "No index shards have been selected for closing!", null);
        }
    }

    private void delete() {
        if (Boolean.TRUE.equals(criteria.getIndexShardSet().getMatchAll())) {
            ConfirmEvent.fire(this, "Are you sure you want to delete the selected index shards?", result -> {
                if (result) {
                    ConfirmEvent.fire(IndexShardPresenter.this,
                            "You have selected to delete all filtered index shards! Are you absolutely sure you want to do this?",
                            result1 -> {
                                if (result1) {
                                    doDelete();
                                }
                            });
                }
            });
        } else if (criteria.getIndexShardSet().isConstrained()) {
            ConfirmEvent.fire(this, "Are you sure you want to delete the selected index shards?", result -> {
                if (result) {
                    doDelete();
                }
            });

        } else {
            AlertEvent.fireWarn(this, "No index shards have been selected for deletion!", null);
        }
    }

    private void doFlush() {
        final FlushIndexShardAction action = new FlushIndexShardAction(criteria);
        dispatcher.execute(action, new AsyncCallbackAdaptor<VoidResult>() {
            @Override
            public void onSuccess(final VoidResult result) {
                AlertEvent.fireInfo(IndexShardPresenter.this,
                        "Selected index shards will be flushed. Please be patient as this may take some time.",
                        () -> refresh());
            }
        });
    }

    private void doClose() {
        final CloseIndexShardAction action = new CloseIndexShardAction(criteria);
        dispatcher.execute(action, new AsyncCallbackAdaptor<VoidResult>() {
            @Override
            public void onSuccess(final VoidResult result) {
                AlertEvent.fireInfo(IndexShardPresenter.this,
                        "Selected index shards will be closed. Please be patient as this may take some time.",
                        () -> refresh());
            }
        });
    }

    private void doDelete() {
        final DeleteIndexShardAction action = new DeleteIndexShardAction(criteria);
        dispatcher.execute(action, new AsyncCallbackAdaptor<VoidResult>() {
            @Override
            public void onSuccess(final VoidResult result) {
                AlertEvent.fireInfo(IndexShardPresenter.this,
                        "Selected index shards will be deleted. Please be patient as this may take some time.",
                        () -> refresh());
            }
        });
    }

    public interface Resources extends ClientBundle {
        ImageResource flush();

        ImageResource flushDisabled();

        ImageResource close();

        ImageResource closeDisabled();
    }
}