more cat support
- add attributes to each cell - change how it gets rendered, allow for other formats - various other changes
This commit is contained in:
parent
0c2d12bda3
commit
ceb7d55857
|
@ -26,6 +26,7 @@ import com.google.common.collect.Sets;
|
|||
import org.elasticsearch.action.ShardOperationFailedException;
|
||||
import org.elasticsearch.action.support.broadcast.BroadcastOperationResponse;
|
||||
import org.elasticsearch.cluster.ClusterState;
|
||||
import org.elasticsearch.cluster.routing.ShardRouting;
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||
import org.elasticsearch.common.xcontent.ToXContent;
|
||||
|
@ -44,7 +45,7 @@ public class IndicesStatsResponse extends BroadcastOperationResponse implements
|
|||
|
||||
private ShardStats[] shards;
|
||||
|
||||
private ImmutableMap<String, CommonStats> shardStatsMap;
|
||||
private ImmutableMap<ShardRouting, CommonStats> shardStatsMap;
|
||||
|
||||
IndicesStatsResponse() {
|
||||
|
||||
|
@ -53,21 +54,18 @@ public class IndicesStatsResponse extends BroadcastOperationResponse implements
|
|||
IndicesStatsResponse(ShardStats[] shards, ClusterState clusterState, int totalShards, int successfulShards, int failedShards, List<ShardOperationFailedException> shardFailures) {
|
||||
super(totalShards, successfulShards, failedShards, shardFailures);
|
||||
this.shards = shards;
|
||||
this.shardStatsMap = buildShardsStatsMap();
|
||||
}
|
||||
|
||||
private ImmutableMap<String, CommonStats> buildShardsStatsMap() {
|
||||
ImmutableMap.Builder<String, CommonStats> mb = ImmutableMap.builder();
|
||||
public ImmutableMap<ShardRouting, CommonStats> asMap() {
|
||||
if (shardStatsMap == null) {
|
||||
ImmutableMap.Builder<ShardRouting, CommonStats> mb = ImmutableMap.builder();
|
||||
for (ShardStats ss : shards) {
|
||||
mb.put(ss.getShardRouting(), ss.getStats());
|
||||
}
|
||||
|
||||
for (ShardStats ss : shards) {
|
||||
mb.put(ss.getShardRouting().globalId(), ss.getStats());
|
||||
shardStatsMap = mb.build();
|
||||
}
|
||||
|
||||
return mb.build();
|
||||
}
|
||||
|
||||
public ImmutableMap<String, CommonStats> asMap() {
|
||||
return this.shardStatsMap;
|
||||
return shardStatsMap;
|
||||
}
|
||||
|
||||
public ShardStats[] getShards() {
|
||||
|
|
|
@ -84,29 +84,6 @@ public class ImmutableShardRouting implements Streamable, Serializable, ShardRou
|
|||
this.version = version;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String globalId() {
|
||||
String pri = "r";
|
||||
if (this.primary()) {
|
||||
pri = "p";
|
||||
}
|
||||
|
||||
String node = "unassigned";
|
||||
if (null != this.currentNodeId()) {
|
||||
node = this.currentNodeId();
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(getIndex());
|
||||
sb.append("/");
|
||||
sb.append(this.shardId().id());
|
||||
sb.append("/");
|
||||
sb.append(pri);
|
||||
sb.append("/");
|
||||
sb.append(node);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String index() {
|
||||
return this.index;
|
||||
|
@ -201,7 +178,6 @@ public class ImmutableShardRouting implements Streamable, Serializable, ShardRou
|
|||
*
|
||||
* @param in {@link InputStream} to read the entry from
|
||||
* @return {@link ImmutableShardRouting} instances read from the given {@link InputStream}
|
||||
*
|
||||
* @throws IOException if some exception occurs during the read operations
|
||||
*/
|
||||
public static ImmutableShardRouting readShardRoutingEntry(StreamInput in) throws IOException {
|
||||
|
@ -214,11 +190,10 @@ public class ImmutableShardRouting implements Streamable, Serializable, ShardRou
|
|||
* Reads a routingentry from an inputstream with given <code>index</code> and
|
||||
* <code>shardId</code>.
|
||||
*
|
||||
* @param in inputstream to read the entry from
|
||||
* @param in inputstream to read the entry from
|
||||
* @param index shards index
|
||||
* @param id id of the shard
|
||||
* @param id id of the shard
|
||||
* @return Shard routing entry read
|
||||
*
|
||||
* @throws IOException if some exception occurs during the read operations
|
||||
*/
|
||||
public static ImmutableShardRouting readShardRoutingEntry(StreamInput in, String index, int shardId) throws IOException {
|
||||
|
@ -231,10 +206,9 @@ public class ImmutableShardRouting implements Streamable, Serializable, ShardRou
|
|||
* Read information from an inputstream with given <code>index</code> and
|
||||
* <code>shardId</code>.
|
||||
*
|
||||
* @param in inputstream to read the entry from
|
||||
* @param in inputstream to read the entry from
|
||||
* @param index shards index
|
||||
* @param id id of the shard
|
||||
*
|
||||
* @param id id of the shard
|
||||
* @throws IOException if some exception occurs during the read operations
|
||||
*/
|
||||
public void readFrom(StreamInput in, String index, int shardId) throws IOException {
|
||||
|
@ -265,6 +239,7 @@ public class ImmutableShardRouting implements Streamable, Serializable, ShardRou
|
|||
|
||||
/**
|
||||
* Writes shard information to {@link StreamOutput} without writing index name and shard id
|
||||
*
|
||||
* @param out {@link StreamOutput} to write shard information to
|
||||
* @throws IOException if something happens during write
|
||||
*/
|
||||
|
|
|
@ -131,11 +131,6 @@ public interface ShardRouting extends Streamable, Serializable, ToXContent {
|
|||
*/
|
||||
ShardIterator shardsIt();
|
||||
|
||||
/**
|
||||
* String identifier to uniquely refer to this shard routing (once it's assigned).
|
||||
*/
|
||||
String globalId();
|
||||
|
||||
/**
|
||||
* Does not write index name and shard id
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,125 @@
|
|||
/*
|
||||
* Licensed to ElasticSearch and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. ElasticSearch 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.elasticsearch.common;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import org.elasticsearch.ElasticSearchIllegalArgumentException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class Table {
|
||||
|
||||
private List<Cell> headers = new ArrayList<Cell>();
|
||||
private List<List<Cell>> rows = new ArrayList<List<Cell>>();
|
||||
|
||||
private List<Cell> currentCells;
|
||||
|
||||
private boolean inHeaders = false;
|
||||
|
||||
public Table startHeaders() {
|
||||
inHeaders = true;
|
||||
currentCells = new ArrayList<Cell>();
|
||||
return this;
|
||||
}
|
||||
|
||||
public Table endHeaders() {
|
||||
inHeaders = false;
|
||||
headers = currentCells;
|
||||
currentCells = null;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Table startRow() {
|
||||
if (headers.isEmpty()) {
|
||||
throw new ElasticSearchIllegalArgumentException("no headers added...");
|
||||
}
|
||||
currentCells = new ArrayList<Cell>(headers.size());
|
||||
return this;
|
||||
}
|
||||
|
||||
public Table endRow() {
|
||||
if (currentCells.size() != headers.size()) {
|
||||
throw new ElasticSearchIllegalArgumentException("mismatch on number of cells in a row compared to header");
|
||||
}
|
||||
rows.add(currentCells);
|
||||
currentCells = null;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Table addCell(Object value) {
|
||||
return addCell(value, "");
|
||||
}
|
||||
|
||||
public Table addCell(Object value, String attributes) {
|
||||
if (!inHeaders) {
|
||||
if (currentCells.size() == headers.size()) {
|
||||
throw new ElasticSearchIllegalArgumentException("can't add more cells to a row than the header");
|
||||
}
|
||||
}
|
||||
Map<String, String> mAttr;
|
||||
if (attributes.length() == 0) {
|
||||
if (inHeaders) {
|
||||
mAttr = ImmutableMap.of();
|
||||
} else {
|
||||
// get the attributes of the header cell we are going to add to
|
||||
mAttr = headers.get(currentCells.size()).attr;
|
||||
}
|
||||
} else {
|
||||
mAttr = new HashMap<String, String>();
|
||||
if (!inHeaders) {
|
||||
// get the attributes of the header cell we are going to add
|
||||
mAttr.putAll(headers.get(currentCells.size()).attr);
|
||||
}
|
||||
String[] sAttrs = Strings.split(attributes, ";");
|
||||
for (String sAttr : sAttrs) {
|
||||
if (sAttr.length() == 0) {
|
||||
continue;
|
||||
}
|
||||
int idx = sAttr.indexOf('=');
|
||||
mAttr.put(sAttr.substring(0, idx), sAttr.substring(idx + 1));
|
||||
}
|
||||
}
|
||||
currentCells.add(new Cell(value, mAttr));
|
||||
return this;
|
||||
}
|
||||
|
||||
public List<Cell> getHeaders() {
|
||||
return this.headers;
|
||||
}
|
||||
|
||||
public Iterable<List<Cell>> getRows() {
|
||||
return rows;
|
||||
}
|
||||
|
||||
public static class Cell {
|
||||
public final Object value;
|
||||
public final Map<String, String> attr;
|
||||
|
||||
Cell(Object value, Map<String, String> attr) {
|
||||
this.value = value;
|
||||
this.attr = attr;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
/*
|
||||
* Licensed to ElasticSearch and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. ElasticSearch 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.elasticsearch.common.table;
|
||||
|
||||
public enum Align {
|
||||
LEFT((byte) 0),
|
||||
CENTER((byte) 1),
|
||||
RIGHT((byte) 2);
|
||||
|
||||
private byte id;
|
||||
|
||||
Align (byte id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
|
@ -1,89 +0,0 @@
|
|||
/*
|
||||
* Licensed to ElasticSearch and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. ElasticSearch 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.elasticsearch.common.table;
|
||||
|
||||
/**
|
||||
* A String container that supports alignment.
|
||||
*/
|
||||
public class Cell {
|
||||
private final String content;
|
||||
|
||||
private final Align align;
|
||||
|
||||
private final byte width;
|
||||
|
||||
public Cell(String content) {
|
||||
this.content = content;
|
||||
this.align = Align.LEFT;
|
||||
this.width = (byte) content.length();
|
||||
}
|
||||
|
||||
public Cell(String content, Align align) {
|
||||
this.content = content;
|
||||
this.align = align;
|
||||
this.width = (byte) content.length();
|
||||
}
|
||||
|
||||
public Cell(String content, Align align, byte width) {
|
||||
this.content = content;
|
||||
this.align = align;
|
||||
this.width = width;
|
||||
}
|
||||
|
||||
public byte width() {
|
||||
return this.width;
|
||||
}
|
||||
|
||||
public Align align() {
|
||||
return this.align;
|
||||
}
|
||||
|
||||
public static String pad(String orig, byte width, Align align) {
|
||||
StringBuilder s = new StringBuilder();
|
||||
byte leftOver = (byte) (width - orig.length());
|
||||
if (leftOver > 0 && align == Align.LEFT) {
|
||||
s.append(orig);
|
||||
for (byte i = 0; i < leftOver; i++) {
|
||||
s.append(" ");
|
||||
}
|
||||
} else if (leftOver > 0 && align == Align.RIGHT) {
|
||||
for (byte i = 0; i < leftOver; i++) {
|
||||
s.append(" ");
|
||||
}
|
||||
s.append(orig);
|
||||
} else {
|
||||
s.append(orig);
|
||||
}
|
||||
return s.toString();
|
||||
}
|
||||
|
||||
public String toString(byte outWidth, Align outAlign) {
|
||||
return pad(content, outWidth, outAlign);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("[");
|
||||
sb.append(align());
|
||||
sb.append("]");
|
||||
sb.append(content);
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
/*
|
||||
* Licensed to ElasticSearch and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. ElasticSearch 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.elasticsearch.common.table;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class Row {
|
||||
private final ArrayList<Cell> cells;
|
||||
|
||||
private final ArrayList<Byte> widths;
|
||||
|
||||
public Row () {
|
||||
this.cells = new ArrayList<Cell>();
|
||||
this.widths = new ArrayList<Byte>();
|
||||
}
|
||||
|
||||
public ArrayList<Cell> cells() {
|
||||
return this.cells;
|
||||
}
|
||||
|
||||
public int size () {
|
||||
return cells.size();
|
||||
}
|
||||
|
||||
public Row addCell(Cell cell) {
|
||||
cells.add(cell);
|
||||
widths.add(cell.width());
|
||||
return this;
|
||||
}
|
||||
|
||||
public Row addCell(String content) {
|
||||
addCell(new Cell(content));
|
||||
return this;
|
||||
}
|
||||
|
||||
public Row addCell(String content, Align align) {
|
||||
addCell(new Cell(content, align));
|
||||
return this;
|
||||
}
|
||||
}
|
|
@ -1,147 +0,0 @@
|
|||
/*
|
||||
* Licensed to ElasticSearch and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. ElasticSearch 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.elasticsearch.common.table;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* A generic table renderer. Can optionally print header row.
|
||||
* Will justify all cells in a column to the widest one. All rows need
|
||||
* to have same number of cells.
|
||||
*
|
||||
* Eg, new Table.addRow(new Row().addCell("foo").addCell("bar")).render()
|
||||
*/
|
||||
public class Table {
|
||||
private ArrayList<Column> cols;
|
||||
|
||||
private byte numcols;
|
||||
|
||||
private byte height;
|
||||
|
||||
public Table() {
|
||||
this.cols = new ArrayList<Column>();
|
||||
this.numcols = 0;
|
||||
this.height = 0;
|
||||
}
|
||||
|
||||
public Table addRow(Row row) {
|
||||
addRow(row, false);
|
||||
return this;
|
||||
}
|
||||
|
||||
public void ensureCapacity(int size) {
|
||||
if (numcols < size) {
|
||||
for (int i = 0; i < (size - numcols); i++) {
|
||||
cols.add(new Column());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Table addRow(Row row, boolean header) {
|
||||
ensureCapacity(row.size());
|
||||
byte curCol = 0;
|
||||
for (Cell cell : row.cells()) {
|
||||
Column col = cols.get(curCol);
|
||||
col.addCell(cell, header);
|
||||
curCol += 1;
|
||||
}
|
||||
numcols = curCol;
|
||||
height += 1;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String render() {
|
||||
return render(false);
|
||||
}
|
||||
|
||||
public String render(boolean withHeaders) {
|
||||
StringBuilder out = new StringBuilder();
|
||||
for (byte i = 0; i < height; i++) {
|
||||
StringBuilder row = new StringBuilder();
|
||||
for (Column col : cols) {
|
||||
Cell cell = col.getCell(i);
|
||||
boolean headerRowWhenNotWantingHeaders = i == 0 && !withHeaders && col.hasHeader();
|
||||
if (! headerRowWhenNotWantingHeaders) {
|
||||
row.append(cell.toString(col.width(), col.align()));
|
||||
row.append(" ");
|
||||
}
|
||||
}
|
||||
out.append(row.toString().trim());
|
||||
out.append("\n");
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
private class Column {
|
||||
private boolean hasHeader;
|
||||
|
||||
private ArrayList<Cell> cells;
|
||||
|
||||
private byte width;
|
||||
|
||||
private Align align;
|
||||
|
||||
Column () {
|
||||
cells = new ArrayList<Cell>();
|
||||
width = 0;
|
||||
hasHeader = false;
|
||||
align = Align.LEFT;
|
||||
}
|
||||
|
||||
public Column addCell(Cell cell) {
|
||||
addCell(cell, false);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Column addCell(Cell cell, boolean header) {
|
||||
cells.add(cell);
|
||||
|
||||
if (header) {
|
||||
hasHeader = true;
|
||||
}
|
||||
|
||||
if (cell.width() > width) {
|
||||
width = cell.width();
|
||||
}
|
||||
|
||||
if (align != cell.align()) {
|
||||
align = cell.align();
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Cell getCell(int index) {
|
||||
return cells.get(index);
|
||||
}
|
||||
|
||||
public Align align() {
|
||||
return this.align;
|
||||
}
|
||||
|
||||
public byte width() {
|
||||
return this.width;
|
||||
}
|
||||
|
||||
public boolean hasHeader() {
|
||||
return this.hasHeader;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -67,7 +67,6 @@ import org.elasticsearch.rest.action.admin.indices.warmer.delete.RestDeleteWarme
|
|||
import org.elasticsearch.rest.action.admin.indices.warmer.get.RestGetWarmerAction;
|
||||
import org.elasticsearch.rest.action.admin.indices.warmer.put.RestPutWarmerAction;
|
||||
import org.elasticsearch.rest.action.bulk.RestBulkAction;
|
||||
import org.elasticsearch.rest.action.cat.RestMasterAction;
|
||||
import org.elasticsearch.rest.action.cat.RestShardsAction;
|
||||
import org.elasticsearch.rest.action.count.RestCountAction;
|
||||
import org.elasticsearch.rest.action.delete.RestDeleteAction;
|
||||
|
@ -85,9 +84,7 @@ import org.elasticsearch.rest.action.search.RestMultiSearchAction;
|
|||
import org.elasticsearch.rest.action.search.RestSearchAction;
|
||||
import org.elasticsearch.rest.action.search.RestSearchScrollAction;
|
||||
import org.elasticsearch.rest.action.suggest.RestSuggestAction;
|
||||
|
||||
import org.elasticsearch.rest.action.termvector.RestTermVectorAction;
|
||||
|
||||
import org.elasticsearch.rest.action.update.RestUpdateAction;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -186,6 +183,5 @@ public class RestActionModule extends AbstractModule {
|
|||
bind(RestExplainAction.class).asEagerSingleton();
|
||||
|
||||
bind(RestShardsAction.class).asEagerSingleton();
|
||||
bind(RestMasterAction.class).asEagerSingleton();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,85 +0,0 @@
|
|||
/*
|
||||
* Licensed to ElasticSearch and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. ElasticSearch 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.elasticsearch.rest.action.cat;
|
||||
|
||||
import org.elasticsearch.action.ActionListener;
|
||||
import org.elasticsearch.action.admin.cluster.state.ClusterStateRequest;
|
||||
import org.elasticsearch.action.admin.cluster.state.ClusterStateResponse;
|
||||
import org.elasticsearch.client.Client;
|
||||
import org.elasticsearch.common.inject.Inject;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.table.Row;
|
||||
import org.elasticsearch.common.table.Table;
|
||||
import org.elasticsearch.common.transport.InetSocketTransportAddress;
|
||||
import org.elasticsearch.rest.*;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.elasticsearch.rest.RestRequest.Method.GET;
|
||||
|
||||
public class RestMasterAction extends BaseRestHandler {
|
||||
@Inject
|
||||
public RestMasterAction(Settings settings, Client client, RestController controller) {
|
||||
super(settings, client);
|
||||
controller.registerHandler(GET, "/_cat/master", this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleRequest(final RestRequest request, final RestChannel channel) {
|
||||
final boolean verbose = request.paramAsBoolean("verbose", false);
|
||||
final StringBuilder out = new StringBuilder();
|
||||
|
||||
final ClusterStateRequest clusterStateRequest = new ClusterStateRequest(); clusterStateRequest.listenerThreaded(false);
|
||||
clusterStateRequest.filterMetaData(true);
|
||||
clusterStateRequest.local(false);
|
||||
|
||||
client.admin().cluster().state(clusterStateRequest, new ActionListener<ClusterStateResponse>() {
|
||||
@Override
|
||||
public void onResponse(final ClusterStateResponse clusterStateResponse) {
|
||||
try {
|
||||
RestStatus status = RestStatus.OK;
|
||||
Table tab = new Table();
|
||||
tab.addRow(new Row()
|
||||
.addCell("id")
|
||||
.addCell("transport addr")
|
||||
.addCell("name"), true);
|
||||
tab.addRow(new Row()
|
||||
.addCell(clusterStateResponse.getState().nodes().masterNode().id())
|
||||
.addCell(((InetSocketTransportAddress)clusterStateResponse.getState().nodes()
|
||||
.masterNode().address()).address().getAddress().getHostAddress())
|
||||
.addCell(clusterStateResponse.getState().nodes().masterNode().name()));
|
||||
|
||||
channel.sendResponse(new StringRestResponse(status, tab.render(verbose)));
|
||||
} catch (Throwable e) {
|
||||
onFailure(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable e) {
|
||||
try {
|
||||
channel.sendResponse(new XContentThrowableRestResponse(request, e));
|
||||
} catch (IOException e1) {
|
||||
logger.error("Failed to send failure response", e1);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -22,22 +22,24 @@ package org.elasticsearch.rest.action.cat;
|
|||
import org.elasticsearch.action.ActionListener;
|
||||
import org.elasticsearch.action.admin.cluster.state.ClusterStateRequest;
|
||||
import org.elasticsearch.action.admin.cluster.state.ClusterStateResponse;
|
||||
import org.elasticsearch.action.admin.indices.stats.CommonStats;
|
||||
import org.elasticsearch.action.admin.indices.stats.IndicesStatsRequest;
|
||||
import org.elasticsearch.action.admin.indices.stats.IndicesStatsResponse;
|
||||
import org.elasticsearch.client.Client;
|
||||
import org.elasticsearch.cluster.routing.*;
|
||||
import org.elasticsearch.cluster.routing.ShardRouting;
|
||||
import org.elasticsearch.common.Table;
|
||||
import org.elasticsearch.common.inject.Inject;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.table.Row;
|
||||
import org.elasticsearch.common.table.Table;
|
||||
import org.elasticsearch.common.transport.InetSocketTransportAddress;
|
||||
import org.elasticsearch.rest.*;
|
||||
import org.elasticsearch.rest.action.support.RestTable;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.elasticsearch.rest.RestRequest.Method.GET;
|
||||
|
||||
public class RestShardsAction extends BaseRestHandler {
|
||||
|
||||
@Inject
|
||||
public RestShardsAction(Settings settings, Client client, RestController controller) {
|
||||
super(settings, client);
|
||||
|
@ -46,12 +48,10 @@ public class RestShardsAction extends BaseRestHandler {
|
|||
|
||||
@Override
|
||||
public void handleRequest(final RestRequest request, final RestChannel channel) {
|
||||
final boolean verbose = request.paramAsBoolean("verbose", false);
|
||||
final StringBuilder out = new StringBuilder();
|
||||
|
||||
final ClusterStateRequest clusterStateRequest = new ClusterStateRequest(); clusterStateRequest.listenerThreaded(false);
|
||||
final ClusterStateRequest clusterStateRequest = new ClusterStateRequest();
|
||||
clusterStateRequest.filterMetaData(true);
|
||||
clusterStateRequest.local(false);
|
||||
clusterStateRequest.local(request.paramAsBoolean("local", clusterStateRequest.local()));
|
||||
clusterStateRequest.masterNodeTimeout(request.paramAsTime("master_timeout", clusterStateRequest.masterNodeTimeout()));
|
||||
|
||||
client.admin().cluster().state(clusterStateRequest, new ActionListener<ClusterStateResponse>() {
|
||||
@Override
|
||||
|
@ -60,9 +60,8 @@ public class RestShardsAction extends BaseRestHandler {
|
|||
client.admin().indices().stats(indicesStatsRequest, new ActionListener<IndicesStatsResponse>() {
|
||||
@Override
|
||||
public void onResponse(IndicesStatsResponse indicesStatsResponse) {
|
||||
RestStatus status = RestStatus.OK;
|
||||
try {
|
||||
channel.sendResponse(new StringRestResponse(status, process(clusterStateResponse, indicesStatsResponse, verbose)));
|
||||
channel.sendResponse(RestTable.buildResponse(buildTable(clusterStateResponse, indicesStatsResponse), request, channel));
|
||||
} catch (Throwable e) {
|
||||
onFailure(e);
|
||||
}
|
||||
|
@ -90,64 +89,41 @@ public class RestShardsAction extends BaseRestHandler {
|
|||
});
|
||||
}
|
||||
|
||||
private String process(ClusterStateResponse state, IndicesStatsResponse stats, boolean headers) {
|
||||
Table tab = new Table();
|
||||
if (headers) {
|
||||
tab.addRow(new Row()
|
||||
.addCell("index")
|
||||
.addCell("shard")
|
||||
.addCell("replica")
|
||||
.addCell("state")
|
||||
.addCell("docs")
|
||||
.addCell("size")
|
||||
.addCell("bytes")
|
||||
.addCell("host")
|
||||
.addCell("node"), true);
|
||||
}
|
||||
private Table buildTable(ClusterStateResponse state, IndicesStatsResponse stats) {
|
||||
Table table = new Table();
|
||||
table.startHeaders()
|
||||
.addCell("index", "default=true;")
|
||||
.addCell("shard", "default=true;")
|
||||
.addCell("p/r", "default=true;")
|
||||
.addCell("state", "default=true;")
|
||||
.addCell("docs", "default=true;")
|
||||
.addCell("store", "default=true;")
|
||||
.addCell("ip", "default=true;")
|
||||
.addCell("node", "default=true;")
|
||||
.endHeaders();
|
||||
|
||||
for (ShardRouting shard : state.getState().routingTable().allShards()) {
|
||||
Row row = new Row();
|
||||
String pri = "r";
|
||||
StringBuilder host = new StringBuilder();
|
||||
String docs = "";
|
||||
String size = "";
|
||||
String bytes = "";
|
||||
String nodeName = "";
|
||||
CommonStats shardStats = stats.asMap().get(shard);
|
||||
|
||||
table.startRow();
|
||||
|
||||
table.addCell(shard.index());
|
||||
table.addCell(shard.id());
|
||||
table.addCell(shard.primary() ? "p" : "r");
|
||||
table.addCell(shard.state());
|
||||
table.addCell(shardStats == null ? null : shardStats.getDocs().getCount());
|
||||
table.addCell(shardStats == null ? null : shardStats.getStore().getSize());
|
||||
if (shard.assignedToNode()) {
|
||||
host.append(((InetSocketTransportAddress) state.getState().nodes().get(shard.currentNodeId()).address()).address().getAddress().getHostAddress());
|
||||
nodeName = state.getState().nodes().get(shard.currentNodeId()).name();
|
||||
table.addCell(((InetSocketTransportAddress) state.getState().nodes().get(shard.currentNodeId()).address()).address().getAddress().getHostAddress());
|
||||
table.addCell(state.getState().nodes().get(shard.currentNodeId()).name());
|
||||
} else {
|
||||
table.addCell(null);
|
||||
table.addCell(null);
|
||||
}
|
||||
|
||||
if (shard.relocating()) {
|
||||
host.append(" -> ");
|
||||
host.append(((InetSocketTransportAddress) state.getState().nodes().get(shard.relocatingNodeId()).address()).address().getAddress().getHostAddress());
|
||||
host.append(state.getState().nodes().get(shard.relocatingNodeId()).name());
|
||||
}
|
||||
|
||||
if (null != stats.asMap().get(shard.globalId())) {
|
||||
size = stats.asMap().get(shard.globalId()).getStore().size().toString();
|
||||
bytes = new Long(stats.asMap().get(shard.globalId()).getStore().getSizeInBytes()).toString();
|
||||
docs = new Long(stats.asMap().get(shard.globalId()).getDocs().getCount()).toString();
|
||||
}
|
||||
|
||||
if (shard.primary()) {
|
||||
pri = "p";
|
||||
}
|
||||
|
||||
row.addCell(shard.index())
|
||||
.addCell(new Integer(shard.shardId().id()).toString())
|
||||
.addCell(pri)
|
||||
.addCell(shard.state().toString())
|
||||
.addCell(docs)
|
||||
.addCell(size)
|
||||
.addCell(bytes)
|
||||
.addCell(host.toString())
|
||||
.addCell(nodeName);
|
||||
tab.addRow(row);
|
||||
table.endRow();
|
||||
}
|
||||
|
||||
return tab.render(headers);
|
||||
return table;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,215 @@
|
|||
/*
|
||||
* Licensed to ElasticSearch and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. ElasticSearch 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.elasticsearch.rest.action.support;
|
||||
|
||||
import org.elasticsearch.common.Booleans;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.common.Table;
|
||||
import org.elasticsearch.common.unit.ByteSizeValue;
|
||||
import org.elasticsearch.common.unit.SizeValue;
|
||||
import org.elasticsearch.common.unit.TimeValue;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentType;
|
||||
import org.elasticsearch.rest.*;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class RestTable {
|
||||
|
||||
public static RestResponse buildResponse(Table table, RestRequest request, RestChannel channel) throws Exception {
|
||||
XContentType xContentType = XContentType.fromRestContentType(request.param("format", request.header("Content-Type")));
|
||||
if (xContentType != null) {
|
||||
return buildXContentBuilder(table, request, channel);
|
||||
}
|
||||
return buildTextPlainResponse(table, request, channel);
|
||||
}
|
||||
|
||||
public static RestResponse buildXContentBuilder(Table table, RestRequest request, RestChannel channel) throws Exception {
|
||||
XContentBuilder builder = RestXContentBuilder.restContentBuilder(request);
|
||||
Set<String> displayHeaders = buildDisplayHeaders(table, request);
|
||||
|
||||
List<Table.Cell> headers = table.getHeaders();
|
||||
builder.startArray();
|
||||
for (List<Table.Cell> row : table.getRows()) {
|
||||
builder.startObject();
|
||||
for (int i = 0; i < headers.size(); i++) {
|
||||
String headerName = headers.get(i).value.toString();
|
||||
if (displayHeaders.contains(headerName)) {
|
||||
builder.field(headerName, renderValue(request, row.get(i).value));
|
||||
}
|
||||
}
|
||||
builder.endObject();
|
||||
}
|
||||
builder.endArray();
|
||||
return new XContentRestResponse(request, RestStatus.OK, builder);
|
||||
}
|
||||
|
||||
public static RestResponse buildTextPlainResponse(Table table, RestRequest request, RestChannel channel) {
|
||||
int[] width = buildWidths(table, request);
|
||||
Set<String> displayHeaders = buildDisplayHeaders(table, request);
|
||||
|
||||
boolean verbose = request.paramAsBoolean("v", true);
|
||||
StringBuilder out = new StringBuilder();
|
||||
if (verbose) {
|
||||
// print the headers
|
||||
for (int i = 0; i < width.length; i++) {
|
||||
String headerName = table.getHeaders().get(i).value.toString();
|
||||
if (displayHeaders.contains(headerName)) {
|
||||
pad(table.getHeaders().get(i), width[i], request, out);
|
||||
out.append(" ");
|
||||
}
|
||||
}
|
||||
out.append("\n");
|
||||
}
|
||||
for (List<Table.Cell> row : table.getRows()) {
|
||||
for (int i = 0; i < width.length; i++) {
|
||||
String headerName = table.getHeaders().get(i).value.toString();
|
||||
if (displayHeaders.contains(headerName)) {
|
||||
pad(row.get(i), width[i], request, out);
|
||||
out.append(" ");
|
||||
}
|
||||
}
|
||||
out.append("\n");
|
||||
}
|
||||
|
||||
return new StringRestResponse(RestStatus.OK, out.toString());
|
||||
}
|
||||
|
||||
private static Set<String> buildDisplayHeaders(Table table, RestRequest request) {
|
||||
String pHeaders = request.param("headers");
|
||||
Set<String> display;
|
||||
if (pHeaders != null) {
|
||||
display = Strings.commaDelimitedListToSet(pHeaders);
|
||||
} else {
|
||||
display = new HashSet<String>();
|
||||
for (Table.Cell cell : table.getHeaders()) {
|
||||
String d = cell.attr.get("default");
|
||||
if (Booleans.parseBoolean(d, true)) {
|
||||
display.add(cell.value.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
return display;
|
||||
}
|
||||
|
||||
private static int[] buildWidths(Table table, RestRequest request) {
|
||||
int[] width = new int[table.getHeaders().size()];
|
||||
for (int col = 0; col < width.length; col++) {
|
||||
String v = renderValue(request, table.getHeaders().get(col).value);
|
||||
int vWidth = v == null ? 0 : v.length();
|
||||
if (width[col] < vWidth) {
|
||||
width[col] = vWidth;
|
||||
}
|
||||
}
|
||||
|
||||
for (List<Table.Cell> row : table.getRows()) {
|
||||
for (int col = 0; col < width.length; col++) {
|
||||
String v = renderValue(request, row.get(col).value);
|
||||
int vWidth = v == null ? 0 : v.length();
|
||||
if (width[col] < vWidth) {
|
||||
width[col] = vWidth;
|
||||
}
|
||||
}
|
||||
}
|
||||
return width;
|
||||
}
|
||||
|
||||
private static void pad(Table.Cell cell, int width, RestRequest request, StringBuilder out) {
|
||||
String sValue = renderValue(request, cell.value);
|
||||
int length = sValue == null ? 0 : sValue.length();
|
||||
byte leftOver = (byte) (width - length);
|
||||
String textAlign = cell.attr.get("text-align");
|
||||
if (textAlign == null) {
|
||||
textAlign = "left";
|
||||
}
|
||||
if (leftOver > 0 && textAlign.equals("right")) {
|
||||
for (byte i = 0; i < leftOver; i++) {
|
||||
out.append(" ");
|
||||
}
|
||||
if (sValue != null) {
|
||||
out.append(sValue);
|
||||
}
|
||||
} else {
|
||||
if (sValue != null) {
|
||||
out.append(sValue);
|
||||
}
|
||||
for (byte i = 0; i < leftOver; i++) {
|
||||
out.append(" ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static String renderValue(RestRequest request, Object value) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
if (value instanceof ByteSizeValue) {
|
||||
ByteSizeValue v = (ByteSizeValue) value;
|
||||
String resolution = request.param("bytes");
|
||||
if ("b".equals(resolution)) {
|
||||
return Long.toString(v.bytes());
|
||||
} else if ("k".equals(resolution)) {
|
||||
return Long.toString(v.kb());
|
||||
} else if ("m".equals(resolution)) {
|
||||
return Long.toString(v.mb());
|
||||
} else if ("g".equals(resolution)) {
|
||||
return Long.toString(v.gb());
|
||||
} else {
|
||||
return v.toString();
|
||||
}
|
||||
}
|
||||
if (value instanceof SizeValue) {
|
||||
SizeValue v = (SizeValue) value;
|
||||
String resolution = request.param("size");
|
||||
if ("b".equals(resolution)) {
|
||||
return Long.toString(v.singles());
|
||||
} else if ("k".equals(resolution)) {
|
||||
return Long.toString(v.kilo());
|
||||
} else if ("m".equals(resolution)) {
|
||||
return Long.toString(v.mega());
|
||||
} else if ("g".equals(resolution)) {
|
||||
return Long.toString(v.giga());
|
||||
} else {
|
||||
return v.toString();
|
||||
}
|
||||
}
|
||||
if (value instanceof TimeValue) {
|
||||
TimeValue v = (TimeValue) value;
|
||||
String resolution = request.param("time");
|
||||
if ("ms".equals(resolution)) {
|
||||
return Long.toString(v.millis());
|
||||
} else if ("s".equals(resolution)) {
|
||||
return Long.toString(v.seconds());
|
||||
} else if ("m".equals(resolution)) {
|
||||
return Long.toString(v.minutes());
|
||||
} else if ("h".equals(resolution)) {
|
||||
return Long.toString(v.hours());
|
||||
} else {
|
||||
return v.toString();
|
||||
}
|
||||
}
|
||||
// Add additional built in data points we can render based on request parameters?
|
||||
return value.toString();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue