Start cat api with shards endpoint.
This commit is contained in:
parent
8919e7e602
commit
7aa9d4bc9f
|
@ -19,6 +19,7 @@
|
|||
|
||||
package org.elasticsearch.action.admin.indices.stats;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
|
@ -43,6 +44,8 @@ public class IndicesStatsResponse extends BroadcastOperationResponse implements
|
|||
|
||||
private ShardStats[] shards;
|
||||
|
||||
private ImmutableMap<String, CommonStats> shardStatsMap;
|
||||
|
||||
IndicesStatsResponse() {
|
||||
|
||||
}
|
||||
|
@ -50,6 +53,21 @@ 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();
|
||||
|
||||
for (ShardStats ss : shards) {
|
||||
mb.put(ss.getShardRouting().globalId(), ss.getStats());
|
||||
}
|
||||
|
||||
return mb.build();
|
||||
}
|
||||
|
||||
public ImmutableMap<String, CommonStats> asMap() {
|
||||
return this.shardStatsMap;
|
||||
}
|
||||
|
||||
public ShardStats[] getShards() {
|
||||
|
|
|
@ -84,6 +84,29 @@ 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;
|
||||
|
|
|
@ -131,6 +131,11 @@ 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,32 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* 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();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,147 @@
|
|||
/*
|
||||
* 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().trim();
|
||||
}
|
||||
|
||||
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,6 +67,7 @@ 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.RestShardsAction;
|
||||
import org.elasticsearch.rest.action.count.RestCountAction;
|
||||
import org.elasticsearch.rest.action.delete.RestDeleteAction;
|
||||
import org.elasticsearch.rest.action.deletebyquery.RestDeleteByQueryAction;
|
||||
|
@ -83,7 +84,9 @@ 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;
|
||||
|
@ -180,5 +183,7 @@ public class RestActionModule extends AbstractModule {
|
|||
bind(RestMoreLikeThisAction.class).asEagerSingleton();
|
||||
|
||||
bind(RestExplainAction.class).asEagerSingleton();
|
||||
|
||||
bind(RestShardsAction.class).asEagerSingleton();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,147 @@
|
|||
/*
|
||||
* 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.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.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 RestShardsAction extends BaseRestHandler {
|
||||
@Inject
|
||||
public RestShardsAction(Settings settings, Client client, RestController controller) {
|
||||
super(settings, client);
|
||||
controller.registerHandler(GET, "/_cat/shards", 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) {
|
||||
IndicesStatsRequest indicesStatsRequest = new IndicesStatsRequest();
|
||||
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)));
|
||||
} 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);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable e) {
|
||||
try {
|
||||
channel.sendResponse(new XContentThrowableRestResponse(request, e));
|
||||
} catch (IOException e1) {
|
||||
logger.error("Failed to send failure response", e1);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
for (ShardRouting shard : state.getState().routingTable().allShards()) {
|
||||
Row row = new Row();
|
||||
String pri = "r";
|
||||
String host = "";
|
||||
String docs = "";
|
||||
String size = "";
|
||||
String bytes = "";
|
||||
String nodeName = "";
|
||||
|
||||
if (shard.assignedToNode()) {
|
||||
host = ((InetSocketTransportAddress) state.getState().nodes().get(shard.currentNodeId()).address()).address().getHostString();
|
||||
nodeName = state.getState().nodes().get(shard.currentNodeId()).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)
|
||||
.addCell(nodeName);
|
||||
tab.addRow(row);
|
||||
}
|
||||
|
||||
return tab.render(headers);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* 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.test.unit.common.table;
|
||||
|
||||
import org.elasticsearch.common.table.Row;
|
||||
import org.testng.annotations.Test;
|
||||
import org.elasticsearch.common.table.Table;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
|
||||
public class TableTests {
|
||||
@Test
|
||||
public void testTable() {
|
||||
Table tab = new Table();
|
||||
tab.addRow(new Row().addCell("123").addCell("4567"));
|
||||
tab.addRow(new Row().addCell("1234").addCell("567890123"));
|
||||
assertThat(tab.render(), equalTo("123 4567\n1234 567890123"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHeader() {
|
||||
Table tab = new Table();
|
||||
tab.addRow(new Row().addCell("loooong").addCell("short"), true);
|
||||
tab.addRow(new Row().addCell("012").addCell("3456789"));
|
||||
assertThat(tab.render(true), equalTo("loooong short\n012 3456789"));
|
||||
assertThat(tab.render(), equalTo("012 3456789"));
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue