allow to register custom state associated with cluster state
This commit is contained in:
parent
bbe735f2cc
commit
dfa67bf071
|
@ -19,23 +19,81 @@
|
|||
|
||||
package org.elasticsearch.cluster;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import org.elasticsearch.ElasticSearchIllegalArgumentException;
|
||||
import org.elasticsearch.cluster.block.ClusterBlock;
|
||||
import org.elasticsearch.cluster.block.ClusterBlocks;
|
||||
import org.elasticsearch.cluster.metadata.IndexMetaData;
|
||||
import org.elasticsearch.cluster.metadata.IndexTemplateMetaData;
|
||||
import org.elasticsearch.cluster.metadata.MappingMetaData;
|
||||
import org.elasticsearch.cluster.metadata.MetaData;
|
||||
import org.elasticsearch.cluster.node.DiscoveryNode;
|
||||
import org.elasticsearch.cluster.node.DiscoveryNodes;
|
||||
import org.elasticsearch.cluster.routing.RoutingNodes;
|
||||
import org.elasticsearch.cluster.routing.RoutingTable;
|
||||
import org.elasticsearch.cluster.routing.*;
|
||||
import org.elasticsearch.cluster.routing.allocation.AllocationExplanation;
|
||||
import org.elasticsearch.cluster.routing.allocation.RoutingAllocation;
|
||||
import org.elasticsearch.common.Nullable;
|
||||
import org.elasticsearch.common.collect.MapBuilder;
|
||||
import org.elasticsearch.common.compress.CompressedString;
|
||||
import org.elasticsearch.common.io.stream.*;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.settings.SettingsFilter;
|
||||
import org.elasticsearch.common.xcontent.ToXContent;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentFactory;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.index.shard.ShardId;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.elasticsearch.common.collect.MapBuilder.newMapBuilder;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class ClusterState {
|
||||
public class ClusterState implements ToXContent {
|
||||
|
||||
public interface Custom {
|
||||
|
||||
interface Factory<T extends Custom> {
|
||||
|
||||
String type();
|
||||
|
||||
T readFrom(StreamInput in) throws IOException;
|
||||
|
||||
void writeTo(T customState, StreamOutput out) throws IOException;
|
||||
|
||||
void toXContent(T customState, XContentBuilder builder, ToXContent.Params params);
|
||||
}
|
||||
}
|
||||
|
||||
public static Map<String, Custom.Factory> customFactories = new HashMap<String, Custom.Factory>();
|
||||
|
||||
/**
|
||||
* Register a custom index meta data factory. Make sure to call it from a static block.
|
||||
*/
|
||||
public static void registerFactory(String type, Custom.Factory factory) {
|
||||
customFactories.put(type, factory);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static <T extends Custom> Custom.Factory<T> lookupFactory(String type) {
|
||||
return customFactories.get(type);
|
||||
}
|
||||
|
||||
public static <T extends Custom> Custom.Factory<T> lookupFactorySafe(String type) throws ElasticSearchIllegalArgumentException {
|
||||
Custom.Factory<T> factory = customFactories.get(type);
|
||||
if (factory == null) {
|
||||
throw new ElasticSearchIllegalArgumentException("No custom state factory registered for type [" + type + "]");
|
||||
}
|
||||
return factory;
|
||||
}
|
||||
|
||||
|
||||
private final long version;
|
||||
|
||||
|
@ -49,20 +107,25 @@ public class ClusterState {
|
|||
|
||||
private final AllocationExplanation allocationExplanation;
|
||||
|
||||
private final ImmutableMap<String, Custom> customs;
|
||||
|
||||
// built on demand
|
||||
private volatile RoutingNodes routingNodes;
|
||||
|
||||
private SettingsFilter settingsFilter;
|
||||
|
||||
public ClusterState(long version, ClusterState state) {
|
||||
this(version, state.metaData(), state.routingTable(), state.nodes(), state.blocks(), state.allocationExplanation());
|
||||
this(version, state.metaData(), state.routingTable(), state.nodes(), state.blocks(), state.allocationExplanation(), state.customs());
|
||||
}
|
||||
|
||||
public ClusterState(long version, MetaData metaData, RoutingTable routingTable, DiscoveryNodes nodes, ClusterBlocks blocks, AllocationExplanation allocationExplanation) {
|
||||
public ClusterState(long version, MetaData metaData, RoutingTable routingTable, DiscoveryNodes nodes, ClusterBlocks blocks, AllocationExplanation allocationExplanation, ImmutableMap<String, Custom> customs) {
|
||||
this.version = version;
|
||||
this.metaData = metaData;
|
||||
this.routingTable = routingTable;
|
||||
this.nodes = nodes;
|
||||
this.blocks = blocks;
|
||||
this.allocationExplanation = allocationExplanation;
|
||||
this.customs = customs;
|
||||
}
|
||||
|
||||
public long version() {
|
||||
|
@ -121,6 +184,14 @@ public class ClusterState {
|
|||
return allocationExplanation();
|
||||
}
|
||||
|
||||
public ImmutableMap<String, Custom> customs() {
|
||||
return this.customs;
|
||||
}
|
||||
|
||||
public ImmutableMap<String, Custom> getCustoms() {
|
||||
return this.customs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a built (on demand) routing nodes view of the routing table. <b>NOTE, the routing nodes
|
||||
* are mutable, use them just for read operations</b>
|
||||
|
@ -133,6 +204,216 @@ public class ClusterState {
|
|||
return routingNodes;
|
||||
}
|
||||
|
||||
public ClusterState settingsFilter(SettingsFilter settingsFilter) {
|
||||
this.settingsFilter = settingsFilter;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
if (!params.paramAsBoolean("filter_nodes", false)) {
|
||||
builder.field("master_node", nodes().masterNodeId());
|
||||
}
|
||||
|
||||
// blocks
|
||||
if (!params.paramAsBoolean("filter_blocks", false)) {
|
||||
builder.startObject("blocks");
|
||||
|
||||
if (!blocks().global().isEmpty()) {
|
||||
builder.startObject("global");
|
||||
for (ClusterBlock block : blocks().global()) {
|
||||
block.toXContent(builder, params);
|
||||
}
|
||||
builder.endObject();
|
||||
}
|
||||
|
||||
if (!blocks().indices().isEmpty()) {
|
||||
builder.startObject("indices");
|
||||
for (Map.Entry<String, ImmutableSet<ClusterBlock>> entry : blocks().indices().entrySet()) {
|
||||
builder.startObject(entry.getKey());
|
||||
for (ClusterBlock block : entry.getValue()) {
|
||||
block.toXContent(builder, params);
|
||||
}
|
||||
builder.endObject();
|
||||
}
|
||||
builder.endObject();
|
||||
}
|
||||
|
||||
builder.endObject();
|
||||
}
|
||||
|
||||
// nodes
|
||||
if (!params.paramAsBoolean("filter_nodes", false)) {
|
||||
builder.startObject("nodes");
|
||||
for (DiscoveryNode node : nodes()) {
|
||||
builder.startObject(node.id(), XContentBuilder.FieldCaseConversion.NONE);
|
||||
builder.field("name", node.name());
|
||||
builder.field("transport_address", node.address().toString());
|
||||
|
||||
builder.startObject("attributes");
|
||||
for (Map.Entry<String, String> attr : node.attributes().entrySet()) {
|
||||
builder.field(attr.getKey(), attr.getValue());
|
||||
}
|
||||
builder.endObject();
|
||||
|
||||
builder.endObject();
|
||||
}
|
||||
builder.endObject();
|
||||
}
|
||||
|
||||
// meta data
|
||||
if (!params.paramAsBoolean("filter_metadata", false)) {
|
||||
builder.startObject("metadata");
|
||||
|
||||
builder.startObject("templates");
|
||||
for (IndexTemplateMetaData templateMetaData : metaData().templates().values()) {
|
||||
builder.startObject(templateMetaData.name(), XContentBuilder.FieldCaseConversion.NONE);
|
||||
|
||||
builder.field("template", templateMetaData.template());
|
||||
builder.field("order", templateMetaData.order());
|
||||
|
||||
builder.startObject("settings");
|
||||
Settings settings = settingsFilter.filterSettings(templateMetaData.settings());
|
||||
for (Map.Entry<String, String> entry : settings.getAsMap().entrySet()) {
|
||||
builder.field(entry.getKey(), entry.getValue());
|
||||
}
|
||||
builder.endObject();
|
||||
|
||||
builder.startObject("mappings");
|
||||
for (Map.Entry<String, CompressedString> entry : templateMetaData.mappings().entrySet()) {
|
||||
byte[] mappingSource = entry.getValue().uncompressed();
|
||||
XContentParser parser = XContentFactory.xContent(mappingSource).createParser(mappingSource);
|
||||
Map<String, Object> mapping = parser.map();
|
||||
if (mapping.size() == 1 && mapping.containsKey(entry.getKey())) {
|
||||
// the type name is the root value, reduce it
|
||||
mapping = (Map<String, Object>) mapping.get(entry.getKey());
|
||||
}
|
||||
builder.field(entry.getKey());
|
||||
builder.map(mapping);
|
||||
}
|
||||
builder.endObject();
|
||||
|
||||
|
||||
builder.endObject();
|
||||
}
|
||||
builder.endObject();
|
||||
|
||||
builder.startObject("indices");
|
||||
for (IndexMetaData indexMetaData : metaData()) {
|
||||
builder.startObject(indexMetaData.index(), XContentBuilder.FieldCaseConversion.NONE);
|
||||
|
||||
builder.field("state", indexMetaData.state().toString().toLowerCase(Locale.ENGLISH));
|
||||
|
||||
builder.startObject("settings");
|
||||
Settings settings = settingsFilter.filterSettings(indexMetaData.settings());
|
||||
for (Map.Entry<String, String> entry : settings.getAsMap().entrySet()) {
|
||||
builder.field(entry.getKey(), entry.getValue());
|
||||
}
|
||||
builder.endObject();
|
||||
|
||||
builder.startObject("mappings");
|
||||
for (Map.Entry<String, MappingMetaData> entry : indexMetaData.mappings().entrySet()) {
|
||||
byte[] mappingSource = entry.getValue().source().uncompressed();
|
||||
XContentParser parser = XContentFactory.xContent(mappingSource).createParser(mappingSource);
|
||||
Map<String, Object> mapping = parser.map();
|
||||
if (mapping.size() == 1 && mapping.containsKey(entry.getKey())) {
|
||||
// the type name is the root value, reduce it
|
||||
mapping = (Map<String, Object>) mapping.get(entry.getKey());
|
||||
}
|
||||
builder.field(entry.getKey());
|
||||
builder.map(mapping);
|
||||
}
|
||||
builder.endObject();
|
||||
|
||||
builder.startArray("aliases");
|
||||
for (String alias : indexMetaData.aliases().keySet()) {
|
||||
builder.value(alias);
|
||||
}
|
||||
builder.endArray();
|
||||
|
||||
builder.endObject();
|
||||
}
|
||||
builder.endObject();
|
||||
|
||||
builder.endObject();
|
||||
}
|
||||
|
||||
// routing table
|
||||
if (!params.paramAsBoolean("filter_routing_table", false)) {
|
||||
builder.startObject("routing_table");
|
||||
builder.startObject("indices");
|
||||
for (IndexRoutingTable indexRoutingTable : routingTable()) {
|
||||
builder.startObject(indexRoutingTable.index(), XContentBuilder.FieldCaseConversion.NONE);
|
||||
builder.startObject("shards");
|
||||
for (IndexShardRoutingTable indexShardRoutingTable : indexRoutingTable) {
|
||||
builder.startArray(Integer.toString(indexShardRoutingTable.shardId().id()));
|
||||
for (ShardRouting shardRouting : indexShardRoutingTable) {
|
||||
shardRouting.toXContent(builder, params);
|
||||
}
|
||||
builder.endArray();
|
||||
}
|
||||
builder.endObject();
|
||||
builder.endObject();
|
||||
}
|
||||
builder.endObject();
|
||||
builder.endObject();
|
||||
}
|
||||
|
||||
// routing nodes
|
||||
if (!params.paramAsBoolean("filter_routing_table", false)) {
|
||||
builder.startObject("routing_nodes");
|
||||
builder.startArray("unassigned");
|
||||
for (ShardRouting shardRouting : readOnlyRoutingNodes().unassigned()) {
|
||||
shardRouting.toXContent(builder, params);
|
||||
}
|
||||
builder.endArray();
|
||||
|
||||
builder.startObject("nodes");
|
||||
for (RoutingNode routingNode : readOnlyRoutingNodes()) {
|
||||
builder.startArray(routingNode.nodeId(), XContentBuilder.FieldCaseConversion.NONE);
|
||||
for (ShardRouting shardRouting : routingNode) {
|
||||
shardRouting.toXContent(builder, params);
|
||||
}
|
||||
builder.endArray();
|
||||
}
|
||||
builder.endObject();
|
||||
|
||||
builder.endObject();
|
||||
}
|
||||
|
||||
if (!params.paramAsBoolean("filter_routing_table", false)) {
|
||||
builder.startArray("allocations");
|
||||
for (Map.Entry<ShardId, List<AllocationExplanation.NodeExplanation>> entry : allocationExplanation().explanations().entrySet()) {
|
||||
builder.startObject();
|
||||
builder.field("index", entry.getKey().index().name());
|
||||
builder.field("shard", entry.getKey().id());
|
||||
builder.startArray("explanations");
|
||||
for (AllocationExplanation.NodeExplanation nodeExplanation : entry.getValue()) {
|
||||
builder.field("desc", nodeExplanation.description());
|
||||
if (nodeExplanation.node() != null) {
|
||||
builder.startObject("node");
|
||||
builder.field("id", nodeExplanation.node().id());
|
||||
builder.field("name", nodeExplanation.node().name());
|
||||
builder.endObject();
|
||||
}
|
||||
}
|
||||
builder.endArray();
|
||||
builder.endObject();
|
||||
}
|
||||
builder.endArray();
|
||||
}
|
||||
|
||||
if (!params.paramAsBoolean("filter_customs", false)) {
|
||||
for (Map.Entry<String, Custom> entry : customs().entrySet()) {
|
||||
builder.startObject(entry.getKey());
|
||||
lookupFactorySafe(entry.getKey()).toXContent(entry.getValue(), builder, params);
|
||||
builder.endObject();
|
||||
}
|
||||
}
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
@ -155,6 +436,8 @@ public class ClusterState {
|
|||
|
||||
private AllocationExplanation allocationExplanation = AllocationExplanation.EMPTY;
|
||||
|
||||
private MapBuilder<String, Custom> customs = newMapBuilder();
|
||||
|
||||
public Builder nodes(DiscoveryNodes.Builder nodesBuilder) {
|
||||
return nodes(nodesBuilder.build());
|
||||
}
|
||||
|
@ -207,6 +490,20 @@ public class ClusterState {
|
|||
return this;
|
||||
}
|
||||
|
||||
public Custom getCustom(String type) {
|
||||
return customs.get(type);
|
||||
}
|
||||
|
||||
public Builder putCustom(String type, Custom custom) {
|
||||
customs.put(type, custom);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder removeCustom(String type) {
|
||||
customs.remove(type);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder state(ClusterState state) {
|
||||
this.version = state.version();
|
||||
this.nodes = state.nodes();
|
||||
|
@ -214,11 +511,12 @@ public class ClusterState {
|
|||
this.metaData = state.metaData();
|
||||
this.blocks = state.blocks();
|
||||
this.allocationExplanation = state.allocationExplanation();
|
||||
this.customs.clear().putAll(state.customs());
|
||||
return this;
|
||||
}
|
||||
|
||||
public ClusterState build() {
|
||||
return new ClusterState(version, metaData, routingTable, nodes, blocks, allocationExplanation);
|
||||
return new ClusterState(version, metaData, routingTable, nodes, blocks, allocationExplanation, customs.immutableMap());
|
||||
}
|
||||
|
||||
public static byte[] toBytes(ClusterState state) throws IOException {
|
||||
|
@ -243,6 +541,11 @@ public class ClusterState {
|
|||
DiscoveryNodes.Builder.writeTo(state.nodes(), out);
|
||||
ClusterBlocks.Builder.writeClusterBlocks(state.blocks(), out);
|
||||
state.allocationExplanation().writeTo(out);
|
||||
out.writeVInt(state.customs().size());
|
||||
for (Map.Entry<String, Custom> entry : state.customs().entrySet()) {
|
||||
out.writeString(entry.getKey());
|
||||
lookupFactorySafe(entry.getKey()).writeTo(entry.getValue(), out);
|
||||
}
|
||||
}
|
||||
|
||||
public static ClusterState readFrom(StreamInput in, @Nullable DiscoveryNode localNode) throws IOException {
|
||||
|
@ -253,6 +556,12 @@ public class ClusterState {
|
|||
builder.nodes = DiscoveryNodes.Builder.readFrom(in, localNode);
|
||||
builder.blocks = ClusterBlocks.Builder.readClusterBlocks(in);
|
||||
builder.allocationExplanation = AllocationExplanation.readAllocationExplanation(in);
|
||||
int customSize = in.readVInt();
|
||||
for (int i = 0; i < customSize; i++) {
|
||||
String type = in.readString();
|
||||
Custom customIndexMetaData = lookupFactorySafe(type).readFrom(in);
|
||||
builder.putCustom(type, customIndexMetaData);
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -88,7 +88,7 @@ public class MetaData implements Iterable<IndexMetaData> {
|
|||
public static <T extends Custom> Custom.Factory<T> lookupFactorySafe(String type) throws ElasticSearchIllegalArgumentException {
|
||||
Custom.Factory<T> factory = customFactories.get(type);
|
||||
if (factory == null) {
|
||||
throw new ElasticSearchIllegalArgumentException("No custom index metadata factoy registered for type [" + type + "]");
|
||||
throw new ElasticSearchIllegalArgumentException("No custom index metadata factory registered for type [" + type + "]");
|
||||
}
|
||||
return factory;
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import com.google.common.collect.ImmutableList;
|
|||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||
import org.elasticsearch.common.io.stream.Streamable;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.index.shard.ShardId;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -291,4 +292,15 @@ public class ImmutableShardRouting implements Streamable, Serializable, ShardRou
|
|||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
return builder.startObject()
|
||||
.field("state", state())
|
||||
.field("primary", primary())
|
||||
.field("node", currentNodeId())
|
||||
.field("relocating_node", relocatingNodeId())
|
||||
.field("shard", shardId().id())
|
||||
.field("index", shardId().index().name())
|
||||
.endObject();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ package org.elasticsearch.cluster.routing;
|
|||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||
import org.elasticsearch.common.io.stream.Streamable;
|
||||
import org.elasticsearch.common.xcontent.ToXContent;
|
||||
import org.elasticsearch.index.shard.ShardId;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -29,10 +30,8 @@ import java.io.Serializable;
|
|||
|
||||
/**
|
||||
* Shard routing represents the state of a shard instance allocated in the cluster.
|
||||
*
|
||||
*
|
||||
*/
|
||||
public interface ShardRouting extends Streamable, Serializable {
|
||||
public interface ShardRouting extends Streamable, Serializable, ToXContent {
|
||||
|
||||
/**
|
||||
* The shard id.
|
||||
|
|
|
@ -19,40 +19,21 @@
|
|||
|
||||
package org.elasticsearch.rest.action.admin.cluster.state;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
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.client.Requests;
|
||||
import org.elasticsearch.cluster.ClusterState;
|
||||
import org.elasticsearch.cluster.block.ClusterBlock;
|
||||
import org.elasticsearch.cluster.metadata.IndexMetaData;
|
||||
import org.elasticsearch.cluster.metadata.IndexTemplateMetaData;
|
||||
import org.elasticsearch.cluster.metadata.MappingMetaData;
|
||||
import org.elasticsearch.cluster.node.DiscoveryNode;
|
||||
import org.elasticsearch.cluster.routing.IndexRoutingTable;
|
||||
import org.elasticsearch.cluster.routing.IndexShardRoutingTable;
|
||||
import org.elasticsearch.cluster.routing.RoutingNode;
|
||||
import org.elasticsearch.cluster.routing.ShardRouting;
|
||||
import org.elasticsearch.cluster.routing.allocation.AllocationExplanation;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.common.compress.CompressedString;
|
||||
import org.elasticsearch.common.inject.Inject;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.settings.SettingsFilter;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentFactory;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.index.shard.ShardId;
|
||||
import org.elasticsearch.rest.*;
|
||||
import org.elasticsearch.rest.action.support.RestActions;
|
||||
import org.elasticsearch.rest.action.support.RestXContentBuilder;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -86,205 +67,9 @@ public class RestClusterStateAction extends BaseRestHandler {
|
|||
@Override
|
||||
public void onResponse(ClusterStateResponse response) {
|
||||
try {
|
||||
ClusterState state = response.state();
|
||||
XContentBuilder builder = RestXContentBuilder.restContentBuilder(request);
|
||||
builder.startObject();
|
||||
|
||||
builder.field("cluster_name", response.clusterName().value());
|
||||
|
||||
if (!clusterStateRequest.filterNodes()) {
|
||||
builder.field("master_node", state.nodes().masterNodeId());
|
||||
}
|
||||
|
||||
// blocks
|
||||
if (!clusterStateRequest.filterBlocks()) {
|
||||
builder.startObject("blocks");
|
||||
|
||||
if (!state.blocks().global().isEmpty()) {
|
||||
builder.startObject("global");
|
||||
for (ClusterBlock block : state.blocks().global()) {
|
||||
block.toXContent(builder, request);
|
||||
}
|
||||
builder.endObject();
|
||||
}
|
||||
|
||||
if (!state.blocks().indices().isEmpty()) {
|
||||
builder.startObject("indices");
|
||||
for (Map.Entry<String, ImmutableSet<ClusterBlock>> entry : state.blocks().indices().entrySet()) {
|
||||
builder.startObject(entry.getKey());
|
||||
for (ClusterBlock block : entry.getValue()) {
|
||||
block.toXContent(builder, request);
|
||||
}
|
||||
builder.endObject();
|
||||
}
|
||||
builder.endObject();
|
||||
}
|
||||
|
||||
builder.endObject();
|
||||
}
|
||||
|
||||
// nodes
|
||||
if (!clusterStateRequest.filterNodes()) {
|
||||
builder.startObject("nodes");
|
||||
for (DiscoveryNode node : state.nodes()) {
|
||||
builder.startObject(node.id(), XContentBuilder.FieldCaseConversion.NONE);
|
||||
builder.field("name", node.name());
|
||||
builder.field("transport_address", node.address().toString());
|
||||
|
||||
builder.startObject("attributes");
|
||||
for (Map.Entry<String, String> attr : node.attributes().entrySet()) {
|
||||
builder.field(attr.getKey(), attr.getValue());
|
||||
}
|
||||
builder.endObject();
|
||||
|
||||
builder.endObject();
|
||||
}
|
||||
builder.endObject();
|
||||
}
|
||||
|
||||
// meta data
|
||||
if (!clusterStateRequest.filterMetaData()) {
|
||||
builder.startObject("metadata");
|
||||
|
||||
builder.startObject("templates");
|
||||
for (IndexTemplateMetaData templateMetaData : state.metaData().templates().values()) {
|
||||
builder.startObject(templateMetaData.name(), XContentBuilder.FieldCaseConversion.NONE);
|
||||
|
||||
builder.field("template", templateMetaData.template());
|
||||
builder.field("order", templateMetaData.order());
|
||||
|
||||
builder.startObject("settings");
|
||||
Settings settings = settingsFilter.filterSettings(templateMetaData.settings());
|
||||
for (Map.Entry<String, String> entry : settings.getAsMap().entrySet()) {
|
||||
builder.field(entry.getKey(), entry.getValue());
|
||||
}
|
||||
builder.endObject();
|
||||
|
||||
builder.startObject("mappings");
|
||||
for (Map.Entry<String, CompressedString> entry : templateMetaData.mappings().entrySet()) {
|
||||
byte[] mappingSource = entry.getValue().uncompressed();
|
||||
XContentParser parser = XContentFactory.xContent(mappingSource).createParser(mappingSource);
|
||||
Map<String, Object> mapping = parser.map();
|
||||
if (mapping.size() == 1 && mapping.containsKey(entry.getKey())) {
|
||||
// the type name is the root value, reduce it
|
||||
mapping = (Map<String, Object>) mapping.get(entry.getKey());
|
||||
}
|
||||
builder.field(entry.getKey());
|
||||
builder.map(mapping);
|
||||
}
|
||||
builder.endObject();
|
||||
|
||||
|
||||
builder.endObject();
|
||||
}
|
||||
builder.endObject();
|
||||
|
||||
builder.startObject("indices");
|
||||
for (IndexMetaData indexMetaData : state.metaData()) {
|
||||
builder.startObject(indexMetaData.index(), XContentBuilder.FieldCaseConversion.NONE);
|
||||
|
||||
builder.field("state", indexMetaData.state().toString().toLowerCase(Locale.ENGLISH));
|
||||
|
||||
builder.startObject("settings");
|
||||
Settings settings = settingsFilter.filterSettings(indexMetaData.settings());
|
||||
for (Map.Entry<String, String> entry : settings.getAsMap().entrySet()) {
|
||||
builder.field(entry.getKey(), entry.getValue());
|
||||
}
|
||||
builder.endObject();
|
||||
|
||||
builder.startObject("mappings");
|
||||
for (Map.Entry<String, MappingMetaData> entry : indexMetaData.mappings().entrySet()) {
|
||||
byte[] mappingSource = entry.getValue().source().uncompressed();
|
||||
XContentParser parser = XContentFactory.xContent(mappingSource).createParser(mappingSource);
|
||||
Map<String, Object> mapping = parser.map();
|
||||
if (mapping.size() == 1 && mapping.containsKey(entry.getKey())) {
|
||||
// the type name is the root value, reduce it
|
||||
mapping = (Map<String, Object>) mapping.get(entry.getKey());
|
||||
}
|
||||
builder.field(entry.getKey());
|
||||
builder.map(mapping);
|
||||
}
|
||||
builder.endObject();
|
||||
|
||||
builder.startArray("aliases");
|
||||
for (String alias : indexMetaData.aliases().keySet()) {
|
||||
builder.value(alias);
|
||||
}
|
||||
builder.endArray();
|
||||
|
||||
builder.endObject();
|
||||
}
|
||||
builder.endObject();
|
||||
|
||||
builder.endObject();
|
||||
}
|
||||
|
||||
// routing table
|
||||
if (!clusterStateRequest.filterRoutingTable()) {
|
||||
builder.startObject("routing_table");
|
||||
builder.startObject("indices");
|
||||
for (IndexRoutingTable indexRoutingTable : state.routingTable()) {
|
||||
builder.startObject(indexRoutingTable.index(), XContentBuilder.FieldCaseConversion.NONE);
|
||||
builder.startObject("shards");
|
||||
for (IndexShardRoutingTable indexShardRoutingTable : indexRoutingTable) {
|
||||
builder.startArray(Integer.toString(indexShardRoutingTable.shardId().id()));
|
||||
for (ShardRouting shardRouting : indexShardRoutingTable) {
|
||||
jsonShardRouting(builder, shardRouting);
|
||||
}
|
||||
builder.endArray();
|
||||
}
|
||||
builder.endObject();
|
||||
builder.endObject();
|
||||
}
|
||||
builder.endObject();
|
||||
builder.endObject();
|
||||
}
|
||||
|
||||
// routing nodes
|
||||
if (!clusterStateRequest.filterRoutingTable()) {
|
||||
builder.startObject("routing_nodes");
|
||||
builder.startArray("unassigned");
|
||||
for (ShardRouting shardRouting : state.readOnlyRoutingNodes().unassigned()) {
|
||||
jsonShardRouting(builder, shardRouting);
|
||||
}
|
||||
builder.endArray();
|
||||
|
||||
builder.startObject("nodes");
|
||||
for (RoutingNode routingNode : state.readOnlyRoutingNodes()) {
|
||||
builder.startArray(routingNode.nodeId(), XContentBuilder.FieldCaseConversion.NONE);
|
||||
for (ShardRouting shardRouting : routingNode) {
|
||||
jsonShardRouting(builder, shardRouting);
|
||||
}
|
||||
builder.endArray();
|
||||
}
|
||||
builder.endObject();
|
||||
|
||||
builder.endObject();
|
||||
}
|
||||
|
||||
if (!clusterStateRequest.filterRoutingTable()) {
|
||||
builder.startArray("allocations");
|
||||
for (Map.Entry<ShardId, List<AllocationExplanation.NodeExplanation>> entry : state.allocationExplanation().explanations().entrySet()) {
|
||||
builder.startObject();
|
||||
builder.field("index", entry.getKey().index().name());
|
||||
builder.field("shard", entry.getKey().id());
|
||||
builder.startArray("explanations");
|
||||
for (AllocationExplanation.NodeExplanation nodeExplanation : entry.getValue()) {
|
||||
builder.field("desc", nodeExplanation.description());
|
||||
if (nodeExplanation.node() != null) {
|
||||
builder.startObject("node");
|
||||
builder.field("id", nodeExplanation.node().id());
|
||||
builder.field("name", nodeExplanation.node().name());
|
||||
builder.endObject();
|
||||
}
|
||||
}
|
||||
builder.endArray();
|
||||
builder.endObject();
|
||||
}
|
||||
builder.endArray();
|
||||
}
|
||||
|
||||
|
||||
response.state().settingsFilter(settingsFilter).toXContent(builder, request);
|
||||
builder.endObject();
|
||||
channel.sendResponse(new XContentRestResponse(request, RestStatus.OK, builder));
|
||||
} catch (Exception e) {
|
||||
|
@ -292,17 +77,6 @@ public class RestClusterStateAction extends BaseRestHandler {
|
|||
}
|
||||
}
|
||||
|
||||
private void jsonShardRouting(XContentBuilder builder, ShardRouting shardRouting) throws IOException {
|
||||
builder.startObject()
|
||||
.field("state", shardRouting.state())
|
||||
.field("primary", shardRouting.primary())
|
||||
.field("node", shardRouting.currentNodeId())
|
||||
.field("relocating_node", shardRouting.relocatingNodeId())
|
||||
.field("shard", shardRouting.shardId().id())
|
||||
.field("index", shardRouting.shardId().index().name())
|
||||
.endObject();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable e) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
|
|
Loading…
Reference in New Issue