diff --git a/server/src/main/java/org/elasticsearch/cluster/ClusterState.java b/server/src/main/java/org/elasticsearch/cluster/ClusterState.java index 398dd908945a9..ed60bef20984c 100644 --- a/server/src/main/java/org/elasticsearch/cluster/ClusterState.java +++ b/server/src/main/java/org/elasticsearch/cluster/ClusterState.java @@ -19,7 +19,6 @@ package org.elasticsearch.cluster; -import com.carrotsearch.hppc.cursors.IntObjectCursor; import com.carrotsearch.hppc.cursors.ObjectCursor; import com.carrotsearch.hppc.cursors.ObjectObjectCursor; @@ -31,8 +30,6 @@ import org.elasticsearch.cluster.coordination.CoordinationMetaData.VotingConfiguration; import org.elasticsearch.cluster.coordination.CoordinationMetaData.VotingConfigExclusion; 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; @@ -45,10 +42,8 @@ import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.Strings; import org.elasticsearch.common.UUIDs; -import org.elasticsearch.common.bytes.BytesArray; import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.collect.ImmutableOpenMap; -import org.elasticsearch.common.compress.CompressedXContent; import org.elasticsearch.common.io.stream.BytesStreamOutput; import org.elasticsearch.common.io.stream.NamedWriteableAwareStreamInput; import org.elasticsearch.common.io.stream.NamedWriteableRegistry; @@ -58,13 +53,11 @@ import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.xcontent.ToXContentFragment; import org.elasticsearch.common.xcontent.XContentBuilder; -import org.elasticsearch.common.xcontent.XContentHelper; import org.elasticsearch.discovery.Discovery; import java.io.IOException; import java.util.EnumSet; import java.util.HashMap; -import java.util.Locale; import java.util.Map; import java.util.Objects; import java.util.Optional; @@ -492,101 +485,7 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws // meta data if (metrics.contains(Metric.METADATA)) { - builder.startObject("metadata"); - builder.field("cluster_uuid", metaData().clusterUUID()); - - builder.startObject("cluster_coordination"); - coordinationMetaData().toXContent(builder, params); - builder.endObject(); - - builder.startObject("templates"); - for (ObjectCursor cursor : metaData().templates().values()) { - IndexTemplateMetaData templateMetaData = cursor.value; - builder.startObject(templateMetaData.name()); - - builder.field("index_patterns", templateMetaData.patterns()); - builder.field("order", templateMetaData.order()); - - builder.startObject("settings"); - Settings settings = templateMetaData.settings(); - settings.toXContent(builder, params); - builder.endObject(); - - builder.startObject("mappings"); - for (ObjectObjectCursor cursor1 : templateMetaData.mappings()) { - Map mapping = XContentHelper.convertToMap(new BytesArray(cursor1.value.uncompressed()), false).v2(); - if (mapping.size() == 1 && mapping.containsKey(cursor1.key)) { - // the type name is the root value, reduce it - mapping = (Map) mapping.get(cursor1.key); - } - builder.field(cursor1.key); - builder.map(mapping); - } - builder.endObject(); - - - builder.endObject(); - } - builder.endObject(); - - builder.startObject("indices"); - for (IndexMetaData indexMetaData : metaData()) { - builder.startObject(indexMetaData.getIndex().getName()); - - builder.field("state", indexMetaData.getState().toString().toLowerCase(Locale.ENGLISH)); - - builder.startObject("settings"); - Settings settings = indexMetaData.getSettings(); - settings.toXContent(builder, params); - builder.endObject(); - - builder.startObject("mappings"); - for (ObjectObjectCursor cursor : indexMetaData.getMappings()) { - Map mapping = XContentHelper - .convertToMap(new BytesArray(cursor.value.source().uncompressed()), false).v2(); - if (mapping.size() == 1 && mapping.containsKey(cursor.key)) { - // the type name is the root value, reduce it - mapping = (Map) mapping.get(cursor.key); - } - builder.field(cursor.key); - builder.map(mapping); - } - builder.endObject(); - - builder.startArray("aliases"); - for (ObjectCursor cursor : indexMetaData.getAliases().keys()) { - builder.value(cursor.value); - } - builder.endArray(); - - builder.startObject(IndexMetaData.KEY_PRIMARY_TERMS); - for (int shard = 0; shard < indexMetaData.getNumberOfShards(); shard++) { - builder.field(Integer.toString(shard), indexMetaData.primaryTerm(shard)); - } - builder.endObject(); - - builder.startObject(IndexMetaData.KEY_IN_SYNC_ALLOCATIONS); - for (IntObjectCursor> cursor : indexMetaData.getInSyncAllocationIds()) { - builder.startArray(String.valueOf(cursor.key)); - for (String allocationId : cursor.value) { - builder.value(allocationId); - } - builder.endArray(); - } - builder.endObject(); - - // index metadata - builder.endObject(); - } - builder.endObject(); - - for (ObjectObjectCursor cursor : metaData.customs()) { - builder.startObject(cursor.key); - cursor.value.toXContent(builder, params); - builder.endObject(); - } - - builder.endObject(); + metaData.toXContent(builder, params); } // routing table diff --git a/server/src/main/java/org/elasticsearch/cluster/metadata/AliasMetaData.java b/server/src/main/java/org/elasticsearch/cluster/metadata/AliasMetaData.java index 6121e94e2ba04..cdb8e4ec638e8 100644 --- a/server/src/main/java/org/elasticsearch/cluster/metadata/AliasMetaData.java +++ b/server/src/main/java/org/elasticsearch/cluster/metadata/AliasMetaData.java @@ -394,6 +394,8 @@ public static AliasMetaData fromXContent(XContentParser parser) throws IOExcepti builder.indexRouting(parser.text()); } else if ("search_routing".equals(currentFieldName) || "searchRouting".equals(currentFieldName)) { builder.searchRouting(parser.text()); + } else if ("filter".equals(currentFieldName)) { + builder.filter(new CompressedXContent(parser.binaryValue())); } } else if (token == XContentParser.Token.START_ARRAY) { parser.skipChildren(); diff --git a/server/src/main/java/org/elasticsearch/cluster/metadata/IndexMetaData.java b/server/src/main/java/org/elasticsearch/cluster/metadata/IndexMetaData.java index 5500a4ba3aadf..134936ebfc3be 100644 --- a/server/src/main/java/org/elasticsearch/cluster/metadata/IndexMetaData.java +++ b/server/src/main/java/org/elasticsearch/cluster/metadata/IndexMetaData.java @@ -65,6 +65,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.EnumSet; +import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; @@ -73,6 +74,7 @@ import java.util.Set; import java.util.function.Function; +import static org.elasticsearch.cluster.metadata.MetaData.CONTEXT_MODE_PARAM; import static org.elasticsearch.cluster.node.DiscoveryNodeFilters.IP_VALIDATOR; import static org.elasticsearch.cluster.node.DiscoveryNodeFilters.OpType.AND; import static org.elasticsearch.cluster.node.DiscoveryNodeFilters.OpType.OR; @@ -1280,6 +1282,9 @@ public IndexMetaData build() { } public static void toXContent(IndexMetaData indexMetaData, XContentBuilder builder, ToXContent.Params params) throws IOException { + MetaData.XContentContext context = MetaData.XContentContext.valueOf( + params.param(CONTEXT_MODE_PARAM, MetaData.CONTEXT_MODE_API)); + builder.startObject(indexMetaData.getIndex().getName()); builder.field(KEY_VERSION, indexMetaData.getVersion()); @@ -1287,40 +1292,75 @@ public static void toXContent(IndexMetaData indexMetaData, XContentBuilder build builder.field(KEY_SETTINGS_VERSION, indexMetaData.getSettingsVersion()); builder.field(KEY_ALIASES_VERSION, indexMetaData.getAliasesVersion()); builder.field(KEY_ROUTING_NUM_SHARDS, indexMetaData.getRoutingNumShards()); + builder.field(KEY_STATE, indexMetaData.getState().toString().toLowerCase(Locale.ENGLISH)); boolean binary = params.paramAsBoolean("binary", false); builder.startObject(KEY_SETTINGS); - indexMetaData.getSettings().toXContent(builder, new MapParams(Collections.singletonMap("flat_settings", "true"))); + if (context != MetaData.XContentContext.API) { + indexMetaData.getSettings().toXContent(builder, new MapParams(Collections.singletonMap("flat_settings", "true"))); + } else { + indexMetaData.getSettings().toXContent(builder, params); + } builder.endObject(); - builder.startArray(KEY_MAPPINGS); - for (ObjectObjectCursor cursor : indexMetaData.getMappings()) { - if (binary) { - builder.value(cursor.value.source().compressed()); - } else { - builder.map(XContentHelper.convertToMap(new BytesArray(cursor.value.source().uncompressed()), true).v2()); + if (context != MetaData.XContentContext.API) { + builder.startArray(KEY_MAPPINGS); + for (ObjectObjectCursor cursor : indexMetaData.getMappings()) { + if (binary) { + builder.value(cursor.value.source().compressed()); + } else { + builder.map(XContentHelper.convertToMap(new BytesArray(cursor.value.source().uncompressed()), true).v2()); + } + } + builder.endArray(); + } else { + builder.startObject(KEY_MAPPINGS); + for (ObjectObjectCursor cursor : indexMetaData.getMappings()) { + Map mapping = XContentHelper + .convertToMap(new BytesArray(cursor.value.source().uncompressed()), false).v2(); + if (mapping.size() == 1 && mapping.containsKey(cursor.key)) { + // the type name is the root value, reduce it + mapping = (Map) mapping.get(cursor.key); + } + builder.field(cursor.key); + builder.map(mapping); } + builder.endObject(); } - builder.endArray(); for (ObjectObjectCursor cursor : indexMetaData.customData) { builder.field(cursor.key); builder.map(cursor.value); } - builder.startObject(KEY_ALIASES); - for (ObjectCursor cursor : indexMetaData.getAliases().values()) { - AliasMetaData.Builder.toXContent(cursor.value, builder, params); - } - builder.endObject(); + if (context != MetaData.XContentContext.API) { + builder.startObject(KEY_ALIASES); + for (ObjectCursor cursor : indexMetaData.getAliases().values()) { + AliasMetaData.Builder.toXContent(cursor.value, builder, params); + } + builder.endObject(); - builder.startArray(KEY_PRIMARY_TERMS); - for (int i = 0; i < indexMetaData.getNumberOfShards(); i++) { - builder.value(indexMetaData.primaryTerm(i)); + builder.startArray(KEY_PRIMARY_TERMS); + for (int i = 0; i < indexMetaData.getNumberOfShards(); i++) { + builder.value(indexMetaData.primaryTerm(i)); + } + builder.endArray(); + } else { + builder.startArray(KEY_ALIASES); + for (ObjectCursor cursor : indexMetaData.getAliases().keys()) { + builder.value(cursor.value); + } + builder.endArray(); + + builder.startObject(IndexMetaData.KEY_PRIMARY_TERMS); + for (int shard = 0; shard < indexMetaData.getNumberOfShards(); shard++) { + builder.field(Integer.toString(shard), indexMetaData.primaryTerm(shard)); + } + builder.endObject(); } - builder.endArray(); + builder.startObject(KEY_IN_SYNC_ALLOCATIONS); for (IntObjectCursor> cursor : indexMetaData.inSyncAllocationIds) { @@ -1506,7 +1546,13 @@ public static Settings addHumanReadableSettings(Settings settings) { return builder.build(); } - private static final ToXContent.Params FORMAT_PARAMS = new MapParams(Collections.singletonMap("binary", "true")); + private static final ToXContent.Params FORMAT_PARAMS; + static { + Map params = new HashMap<>(2); + params.put("binary", "true"); + params.put(MetaData.CONTEXT_MODE_PARAM, MetaData.CONTEXT_MODE_GATEWAY); + FORMAT_PARAMS = new MapParams(params); + } /** * State format for {@link IndexMetaData} to write to and load from disk diff --git a/server/src/main/java/org/elasticsearch/cluster/metadata/IndexTemplateMetaData.java b/server/src/main/java/org/elasticsearch/cluster/metadata/IndexTemplateMetaData.java index 36a1ae1aad0fa..e401aef57bf49 100644 --- a/server/src/main/java/org/elasticsearch/cluster/metadata/IndexTemplateMetaData.java +++ b/server/src/main/java/org/elasticsearch/cluster/metadata/IndexTemplateMetaData.java @@ -390,7 +390,6 @@ private static void toInnerXContent(IndexTemplateMetaData indexTemplateMetaData, XContentBuilder builder, ToXContent.Params params, boolean includeTypeName) throws IOException { - builder.field("order", indexTemplateMetaData.order()); if (indexTemplateMetaData.version() != null) { builder.field("version", indexTemplateMetaData.version()); diff --git a/server/src/main/java/org/elasticsearch/cluster/metadata/MetaData.java b/server/src/main/java/org/elasticsearch/cluster/metadata/MetaData.java index e9c257c3be51f..9143ffb321712 100644 --- a/server/src/main/java/org/elasticsearch/cluster/metadata/MetaData.java +++ b/server/src/main/java/org/elasticsearch/cluster/metadata/MetaData.java @@ -53,10 +53,8 @@ import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.ToXContentFragment; import org.elasticsearch.common.xcontent.XContentBuilder; -import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentHelper; import org.elasticsearch.common.xcontent.XContentParser; -import org.elasticsearch.common.xcontent.XContentType; import org.elasticsearch.gateway.MetaDataStateFormat; import org.elasticsearch.index.Index; import org.elasticsearch.index.IndexNotFoundException; @@ -158,6 +156,8 @@ public interface Custom extends NamedDiffable, ToXContentFragment, Clust public static final String CONTEXT_MODE_GATEWAY = XContentContext.GATEWAY.toString(); + public static final String CONTEXT_MODE_API = XContentContext.API.toString(); + public static final String GLOBAL_STATE_FILE_PREFIX = "global-"; private static final NamedDiffableValueSerializer CUSTOM_VALUE_SERIALIZER = new NamedDiffableValueSerializer<>(Custom.class); @@ -1447,20 +1447,16 @@ private SortedMap buildAliasAndIndexLookup() { return aliasAndIndexLookup; } - public static String toXContent(MetaData metaData) throws IOException { - XContentBuilder builder = XContentFactory.contentBuilder(XContentType.JSON); - builder.startObject(); - toXContent(metaData, builder, ToXContent.EMPTY_PARAMS); - builder.endObject(); - return Strings.toString(builder); - } - public static void toXContent(MetaData metaData, XContentBuilder builder, ToXContent.Params params) throws IOException { - XContentContext context = XContentContext.valueOf(params.param(CONTEXT_MODE_PARAM, "API")); + XContentContext context = XContentContext.valueOf(params.param(CONTEXT_MODE_PARAM, CONTEXT_MODE_API)); - builder.startObject("meta-data"); + if (context == XContentContext.API) { + builder.startObject("metadata"); + } else { + builder.startObject("meta-data"); + builder.field("version", metaData.version()); + } - builder.field("version", metaData.version()); builder.field("cluster_uuid", metaData.clusterUUID); builder.field("cluster_uuid_committed", metaData.clusterUUIDCommitted); @@ -1468,25 +1464,19 @@ public static void toXContent(MetaData metaData, XContentBuilder builder, ToXCon metaData.coordinationMetaData().toXContent(builder, params); builder.endObject(); - if (!metaData.persistentSettings().isEmpty()) { + if (context != XContentContext.API && !metaData.persistentSettings().isEmpty()) { builder.startObject("settings"); metaData.persistentSettings().toXContent(builder, new MapParams(Collections.singletonMap("flat_settings", "true"))); builder.endObject(); } - if (context == XContentContext.API && !metaData.transientSettings().isEmpty()) { - builder.startObject("transient_settings"); - metaData.transientSettings().toXContent(builder, new MapParams(Collections.singletonMap("flat_settings", "true"))); - builder.endObject(); - } - builder.startObject("templates"); for (ObjectCursor cursor : metaData.templates().values()) { IndexTemplateMetaData.Builder.toXContentWithTypes(cursor.value, builder, params); } builder.endObject(); - if (context == XContentContext.API && !metaData.indices().isEmpty()) { + if (context == XContentContext.API) { builder.startObject("indices"); for (IndexMetaData indexMetaData : metaData) { IndexMetaData.Builder.toXContent(indexMetaData, builder, params); diff --git a/server/src/test/java/org/elasticsearch/action/admin/cluster/reroute/ClusterRerouteResponseTests.java b/server/src/test/java/org/elasticsearch/action/admin/cluster/reroute/ClusterRerouteResponseTests.java index 1999a18a92b31..0a9083fb22b30 100644 --- a/server/src/test/java/org/elasticsearch/action/admin/cluster/reroute/ClusterRerouteResponseTests.java +++ b/server/src/test/java/org/elasticsearch/action/admin/cluster/reroute/ClusterRerouteResponseTests.java @@ -84,6 +84,7 @@ public void testToXContent() throws IOException { " },\n" + " \"metadata\" : {\n" + " \"cluster_uuid\" : \"_na_\",\n" + + " \"cluster_uuid_committed\" : false,\n" + " \"cluster_coordination\" : {\n" + " \"term\" : 0,\n" + " \"last_committed_config\" : [ ],\n" + @@ -93,6 +94,11 @@ public void testToXContent() throws IOException { " \"templates\" : { },\n" + " \"indices\" : {\n" + " \"index\" : {\n" + + " \"version\" : 1,\n" + + " \"mapping_version\" : 1,\n" + + " \"settings_version\" : 1,\n" + + " \"aliases_version\" : 1,\n" + + " \"routing_num_shards\" : 1,\n" + " \"state\" : \"open\",\n" + " \"settings\" : {\n" + " \"index\" : {\n" + @@ -114,7 +120,8 @@ public void testToXContent() throws IOException { " },\n" + " \"in_sync_allocations\" : {\n" + " \"0\" : [ ]\n" + - " }\n" + + " },\n" + + " \"rollover_info\" : { }\n" + " }\n" + " },\n" + " \"index-graveyard\" : {\n" + @@ -179,6 +186,7 @@ public void testToXContent() throws IOException { " \"cluster_uuid\" : \"_na_\",\n" + " \"metadata\" : {\n" + " \"cluster_uuid\" : \"_na_\",\n" + + " \"cluster_uuid_committed\" : false,\n" + " \"cluster_coordination\" : {\n" + " \"term\" : 0,\n" + " \"last_committed_config\" : [ ],\n" + @@ -188,6 +196,11 @@ public void testToXContent() throws IOException { " \"templates\" : { },\n" + " \"indices\" : {\n" + " \"index\" : {\n" + + " \"version\" : 1,\n" + + " \"mapping_version\" : 1,\n" + + " \"settings_version\" : 1,\n" + + " \"aliases_version\" : 1,\n" + + " \"routing_num_shards\" : 1,\n" + " \"state\" : \"open\",\n" + " \"settings\" : {\n" + " \"index\" : {\n" + @@ -204,7 +217,8 @@ public void testToXContent() throws IOException { " },\n" + " \"in_sync_allocations\" : {\n" + " \"0\" : [ ]\n" + - " }\n" + + " },\n" + + " \"rollover_info\" : { }\n" + " }\n" + " },\n" + " \"index-graveyard\" : {\n" + diff --git a/server/src/test/java/org/elasticsearch/cluster/ClusterStateTests.java b/server/src/test/java/org/elasticsearch/cluster/ClusterStateTests.java index 86d3eec9c9c76..9b83752dd0e17 100644 --- a/server/src/test/java/org/elasticsearch/cluster/ClusterStateTests.java +++ b/server/src/test/java/org/elasticsearch/cluster/ClusterStateTests.java @@ -19,14 +19,48 @@ package org.elasticsearch.cluster; import org.elasticsearch.Version; +import org.elasticsearch.action.admin.indices.rollover.RolloverInfo; +import org.elasticsearch.cluster.block.ClusterBlock; +import org.elasticsearch.cluster.block.ClusterBlockLevel; +import org.elasticsearch.cluster.block.ClusterBlocks; +import org.elasticsearch.cluster.coordination.CoordinationMetaData; +import org.elasticsearch.cluster.metadata.AliasMetaData; +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.IndexRoutingTable; +import org.elasticsearch.cluster.routing.IndexShardRoutingTable; +import org.elasticsearch.cluster.routing.RoutingTable; +import org.elasticsearch.cluster.routing.ShardRoutingState; +import org.elasticsearch.cluster.routing.TestShardRouting; +import org.elasticsearch.common.Strings; import org.elasticsearch.common.collect.ImmutableOpenMap; import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.transport.TransportAddress; +import org.elasticsearch.common.xcontent.ToXContent; +import org.elasticsearch.common.xcontent.XContentBuilder; +import org.elasticsearch.common.xcontent.json.JsonXContent; +import org.elasticsearch.index.Index; +import org.elasticsearch.index.shard.ShardId; +import org.elasticsearch.rest.RestStatus; import org.elasticsearch.test.ESTestCase; +import org.elasticsearch.test.TestCustomMetaData; + +import java.io.IOException; +import java.net.InetAddress; +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; import static java.util.Collections.emptyMap; import static java.util.Collections.emptySet; +import static org.elasticsearch.cluster.metadata.IndexMetaData.SETTING_VERSION_CREATED; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; @@ -73,4 +107,741 @@ public void testBuilderRejectsNullInCustoms() { final ImmutableOpenMap map = mapBuilder.build(); assertThat(expectThrows(NullPointerException.class, () -> builder.customs(map)).getMessage(), containsString(key)); } + + public void testToXContent() throws IOException { + final ClusterState clusterState = buildClusterState(); + + IndexRoutingTable index = clusterState.getRoutingTable().getIndicesRouting().get("index"); + + String ephemeralId = clusterState.getNodes().get("nodeId1").getEphemeralId(); + String allocationId = index.getShards().get(1).getAllAllocationIds().iterator().next(); + + XContentBuilder builder = JsonXContent.contentBuilder().prettyPrint(); + builder.startObject(); + clusterState.toXContent(builder, ToXContent.EMPTY_PARAMS); + builder.endObject(); + + assertEquals("{\n" + + " \"cluster_uuid\" : \"clusterUUID\",\n" + + " \"version\" : 0,\n" + + " \"state_uuid\" : \"stateUUID\",\n" + + " \"master_node\" : \"masterNodeId\",\n" + + " \"blocks\" : {\n" + + " \"global\" : {\n" + + " \"1\" : {\n" + + " \"description\" : \"description\",\n" + + " \"retryable\" : true,\n" + + " \"disable_state_persistence\" : true,\n" + + " \"levels\" : [\n" + + " \"read\",\n" + + " \"write\",\n" + + " \"metadata_read\",\n" + + " \"metadata_write\"\n" + + " ]\n" + + " }\n" + + " },\n" + + " \"indices\" : {\n" + + " \"index\" : {\n" + + " \"2\" : {\n" + + " \"description\" : \"description2\",\n" + + " \"retryable\" : false,\n" + + " \"levels\" : [\n" + + " \"read\",\n" + + " \"write\",\n" + + " \"metadata_read\",\n" + + " \"metadata_write\"\n" + + " ]\n" + + " }\n" + + " }\n" + + " }\n" + + " },\n" + + " \"nodes\" : {\n" + + " \"nodeId1\" : {\n" + + " \"name\" : \"\",\n" + + " \"ephemeral_id\" : \"" + ephemeralId + "\",\n" + + " \"transport_address\" : \"127.0.0.1:111\",\n" + + " \"attributes\" : { }\n" + + " }\n" + + " },\n" + + " \"metadata\" : {\n" + + " \"cluster_uuid\" : \"clusterUUID\",\n" + + " \"cluster_uuid_committed\" : false,\n" + + " \"cluster_coordination\" : {\n" + + " \"term\" : 1,\n" + + " \"last_committed_config\" : [\n" + + " \"commitedConfigurationNodeId\"\n" + + " ],\n" + + " \"last_accepted_config\" : [\n" + + " \"acceptedConfigurationNodeId\"\n" + + " ],\n" + + " \"voting_config_exclusions\" : [\n" + + " {\n" + + " \"node_id\" : \"exlucdedNodeId\",\n" + + " \"node_name\" : \"excludedNodeName\"\n" + + " }\n" + + " ]\n" + + " },\n" + + " \"templates\" : {\n" + + " \"template\" : {\n" + + " \"order\" : 0,\n" + + " \"index_patterns\" : [\n" + + " \"pattern1\",\n" + + " \"pattern2\"\n" + + " ],\n" + + " \"settings\" : {\n" + + " \"index\" : {\n" + + " \"version\" : {\n" + + " \"created\" : \"" + Version.CURRENT.id + "\"\n" + + " }\n" + + " }\n" + + " },\n" + + " \"mappings\" : {\n" + + " \"key1\" : { }\n" + + " },\n" + + " \"aliases\" : { }\n" + + " }\n" + + " },\n" + + " \"indices\" : {\n" + + " \"index\" : {\n" + + " \"version\" : 1,\n" + + " \"mapping_version\" : 1,\n" + + " \"settings_version\" : 1,\n" + + " \"aliases_version\" : 1,\n" + + " \"routing_num_shards\" : 1,\n" + + " \"state\" : \"open\",\n" + + " \"settings\" : {\n" + + " \"index\" : {\n" + + " \"number_of_shards\" : \"1\",\n" + + " \"number_of_replicas\" : \"2\",\n" + + " \"version\" : {\n" + + " \"created\" : \"" + Version.CURRENT.id + "\"\n" + + " }\n" + + " }\n" + + " },\n" + + " \"mappings\" : {\n" + + " \"type\" : {\n" + + " \"type1\" : {\n" + + " \"key\" : \"value\"\n" + + " }\n" + + " }\n" + + " },\n" + + " \"aliases\" : [\n" + + " \"alias\"\n" + + " ],\n" + + " \"primary_terms\" : {\n" + + " \"0\" : 1\n" + + " },\n" + + " \"in_sync_allocations\" : {\n" + + " \"0\" : [\n" + + " \"allocationId\"\n" + + " ]\n" + + " },\n" + + " \"rollover_info\" : {\n" + + " \"rolloveAlias\" : {\n" + + " \"met_conditions\" : { },\n" + + " \"time\" : 1\n" + + " }\n" + + " }\n" + + " }\n" + + " },\n" + + " \"index-graveyard\" : {\n" + + " \"tombstones\" : [ ]\n" + + " }\n" + + " },\n" + + " \"routing_table\" : {\n" + + " \"indices\" : {\n" + + " \"index\" : {\n" + + " \"shards\" : {\n" + + " \"1\" : [\n" + + " {\n" + + " \"state\" : \"STARTED\",\n" + + " \"primary\" : true,\n" + + " \"node\" : \"nodeId2\",\n" + + " \"relocating_node\" : null,\n" + + " \"shard\" : 1,\n" + + " \"index\" : \"index\",\n" + + " \"allocation_id\" : {\n" + + " \"id\" : \"" + allocationId + "\"\n" + + " }\n" + + " }\n" + + " ]\n" + + " }\n" + + " }\n" + + " }\n" + + " },\n" + + " \"routing_nodes\" : {\n" + + " \"unassigned\" : [ ],\n" + + " \"nodes\" : {\n" + + " \"nodeId2\" : [\n" + + " {\n" + + " \"state\" : \"STARTED\",\n" + + " \"primary\" : true,\n" + + " \"node\" : \"nodeId2\",\n" + + " \"relocating_node\" : null,\n" + + " \"shard\" : 1,\n" + + " \"index\" : \"index\",\n" + + " \"allocation_id\" : {\n" + + " \"id\" : \"" + allocationId + "\"\n" + + " }\n" + + " }\n" + + " ],\n" + + " \"nodeId1\" : [ ]\n" + + " }\n" + + " }\n" + + "}", Strings.toString(builder)); + + } + + public void testToXContent_FlatSettingTrue_ReduceMappingFalse() throws IOException { + Map mapParams = new HashMap<>(){{ + put("flat_settings", "true"); + put("reduce_mappings", "false"); + }}; + + final ClusterState clusterState = buildClusterState(); + IndexRoutingTable index = clusterState.getRoutingTable().getIndicesRouting().get("index"); + + String ephemeralId = clusterState.getNodes().get("nodeId1").getEphemeralId(); + String allocationId = index.getShards().get(1).getAllAllocationIds().iterator().next(); + + XContentBuilder builder = JsonXContent.contentBuilder().prettyPrint(); + builder.startObject(); + clusterState.toXContent(builder, new ToXContent.MapParams(mapParams)); + builder.endObject(); + + assertEquals("{\n" + + " \"cluster_uuid\" : \"clusterUUID\",\n" + + " \"version\" : 0,\n" + + " \"state_uuid\" : \"stateUUID\",\n" + + " \"master_node\" : \"masterNodeId\",\n" + + " \"blocks\" : {\n" + + " \"global\" : {\n" + + " \"1\" : {\n" + + " \"description\" : \"description\",\n" + + " \"retryable\" : true,\n" + + " \"disable_state_persistence\" : true,\n" + + " \"levels\" : [\n" + + " \"read\",\n" + + " \"write\",\n" + + " \"metadata_read\",\n" + + " \"metadata_write\"\n" + + " ]\n" + + " }\n" + + " },\n" + + " \"indices\" : {\n" + + " \"index\" : {\n" + + " \"2\" : {\n" + + " \"description\" : \"description2\",\n" + + " \"retryable\" : false,\n" + + " \"levels\" : [\n" + + " \"read\",\n" + + " \"write\",\n" + + " \"metadata_read\",\n" + + " \"metadata_write\"\n" + + " ]\n" + + " }\n" + + " }\n" + + " }\n" + + " },\n" + + " \"nodes\" : {\n" + + " \"nodeId1\" : {\n" + + " \"name\" : \"\",\n" + + " \"ephemeral_id\" : \"" + ephemeralId + "\",\n" + + " \"transport_address\" : \"127.0.0.1:111\",\n" + + " \"attributes\" : { }\n" + + " }\n" + + " },\n" + + " \"metadata\" : {\n" + + " \"cluster_uuid\" : \"clusterUUID\",\n" + + " \"cluster_uuid_committed\" : false,\n" + + " \"cluster_coordination\" : {\n" + + " \"term\" : 1,\n" + + " \"last_committed_config\" : [\n" + + " \"commitedConfigurationNodeId\"\n" + + " ],\n" + + " \"last_accepted_config\" : [\n" + + " \"acceptedConfigurationNodeId\"\n" + + " ],\n" + + " \"voting_config_exclusions\" : [\n" + + " {\n" + + " \"node_id\" : \"exlucdedNodeId\",\n" + + " \"node_name\" : \"excludedNodeName\"\n" + + " }\n" + + " ]\n" + + " },\n" + + " \"templates\" : {\n" + + " \"template\" : {\n" + + " \"order\" : 0,\n" + + " \"index_patterns\" : [\n" + + " \"pattern1\",\n" + + " \"pattern2\"\n" + + " ],\n" + + " \"settings\" : {\n" + + " \"index.version.created\" : \"" + Version.CURRENT.id + "\"\n" + + " },\n" + + " \"mappings\" : {\n" + + " \"key1\" : { }\n" + + " },\n" + + " \"aliases\" : { }\n" + + " }\n" + + " },\n" + + " \"indices\" : {\n" + + " \"index\" : {\n" + + " \"version\" : 1,\n" + + " \"mapping_version\" : 1,\n" + + " \"settings_version\" : 1,\n" + + " \"aliases_version\" : 1,\n" + + " \"routing_num_shards\" : 1,\n" + + " \"state\" : \"open\",\n" + + " \"settings\" : {\n" + + " \"index.number_of_replicas\" : \"2\",\n" + + " \"index.number_of_shards\" : \"1\",\n" + + " \"index.version.created\" : \"" + Version.CURRENT.id + "\"\n" + + " },\n" + + " \"mappings\" : {\n" + + " \"type\" : {\n" + + " \"type1\" : {\n" + + " \"key\" : \"value\"\n" + + " }\n" + + " }\n" + + " },\n" + + " \"aliases\" : [\n" + + " \"alias\"\n" + + " ],\n" + + " \"primary_terms\" : {\n" + + " \"0\" : 1\n" + + " },\n" + + " \"in_sync_allocations\" : {\n" + + " \"0\" : [\n" + + " \"allocationId\"\n" + + " ]\n" + + " },\n" + + " \"rollover_info\" : {\n" + + " \"rolloveAlias\" : {\n" + + " \"met_conditions\" : { },\n" + + " \"time\" : 1\n" + + " }\n" + + " }\n" + + " }\n" + + " },\n" + + " \"index-graveyard\" : {\n" + + " \"tombstones\" : [ ]\n" + + " }\n" + + " },\n" + + " \"routing_table\" : {\n" + + " \"indices\" : {\n" + + " \"index\" : {\n" + + " \"shards\" : {\n" + + " \"1\" : [\n" + + " {\n" + + " \"state\" : \"STARTED\",\n" + + " \"primary\" : true,\n" + + " \"node\" : \"nodeId2\",\n" + + " \"relocating_node\" : null,\n" + + " \"shard\" : 1,\n" + + " \"index\" : \"index\",\n" + + " \"allocation_id\" : {\n" + + " \"id\" : \"" + allocationId + "\"\n" + + " }\n" + + " }\n" + + " ]\n" + + " }\n" + + " }\n" + + " }\n" + + " },\n" + + " \"routing_nodes\" : {\n" + + " \"unassigned\" : [ ],\n" + + " \"nodes\" : {\n" + + " \"nodeId2\" : [\n" + + " {\n" + + " \"state\" : \"STARTED\",\n" + + " \"primary\" : true,\n" + + " \"node\" : \"nodeId2\",\n" + + " \"relocating_node\" : null,\n" + + " \"shard\" : 1,\n" + + " \"index\" : \"index\",\n" + + " \"allocation_id\" : {\n" + + " \"id\" : \"" + allocationId + "\"\n" + + " }\n" + + " }\n" + + " ],\n" + + " \"nodeId1\" : [ ]\n" + + " }\n" + + " }\n" + + "}", Strings.toString(builder)); + + } + + public void testToXContent_FlatSettingFalse_ReduceMappingTrue() throws IOException { + Map mapParams = new HashMap<>(){{ + put("flat_settings", "false"); + put("reduce_mappings", "true"); + }}; + + final ClusterState clusterState = buildClusterState(); + + IndexRoutingTable index = clusterState.getRoutingTable().getIndicesRouting().get("index"); + + String ephemeralId = clusterState.getNodes().get("nodeId1").getEphemeralId(); + String allocationId = index.getShards().get(1).getAllAllocationIds().iterator().next(); + + XContentBuilder builder = JsonXContent.contentBuilder().prettyPrint(); + builder.startObject(); + clusterState.toXContent(builder, new ToXContent.MapParams(mapParams)); + builder.endObject(); + + assertEquals("{\n" + + " \"cluster_uuid\" : \"clusterUUID\",\n" + + " \"version\" : 0,\n" + + " \"state_uuid\" : \"stateUUID\",\n" + + " \"master_node\" : \"masterNodeId\",\n" + + " \"blocks\" : {\n" + + " \"global\" : {\n" + + " \"1\" : {\n" + + " \"description\" : \"description\",\n" + + " \"retryable\" : true,\n" + + " \"disable_state_persistence\" : true,\n" + + " \"levels\" : [\n" + + " \"read\",\n" + + " \"write\",\n" + + " \"metadata_read\",\n" + + " \"metadata_write\"\n" + + " ]\n" + + " }\n" + + " },\n" + + " \"indices\" : {\n" + + " \"index\" : {\n" + + " \"2\" : {\n" + + " \"description\" : \"description2\",\n" + + " \"retryable\" : false,\n" + + " \"levels\" : [\n" + + " \"read\",\n" + + " \"write\",\n" + + " \"metadata_read\",\n" + + " \"metadata_write\"\n" + + " ]\n" + + " }\n" + + " }\n" + + " }\n" + + " },\n" + + " \"nodes\" : {\n" + + " \"nodeId1\" : {\n" + + " \"name\" : \"\",\n" + + " \"ephemeral_id\" : \"" + ephemeralId + "\",\n" + + " \"transport_address\" : \"127.0.0.1:111\",\n" + + " \"attributes\" : { }\n" + + " }\n" + + " },\n" + + " \"metadata\" : {\n" + + " \"cluster_uuid\" : \"clusterUUID\",\n" + + " \"cluster_uuid_committed\" : false,\n" + + " \"cluster_coordination\" : {\n" + + " \"term\" : 1,\n" + + " \"last_committed_config\" : [\n" + + " \"commitedConfigurationNodeId\"\n" + + " ],\n" + + " \"last_accepted_config\" : [\n" + + " \"acceptedConfigurationNodeId\"\n" + + " ],\n" + + " \"voting_config_exclusions\" : [\n" + + " {\n" + + " \"node_id\" : \"exlucdedNodeId\",\n" + + " \"node_name\" : \"excludedNodeName\"\n" + + " }\n" + + " ]\n" + + " },\n" + + " \"templates\" : {\n" + + " \"template\" : {\n" + + " \"order\" : 0,\n" + + " \"index_patterns\" : [\n" + + " \"pattern1\",\n" + + " \"pattern2\"\n" + + " ],\n" + + " \"settings\" : {\n" + + " \"index\" : {\n" + + " \"version\" : {\n" + + " \"created\" : \"" + Version.CURRENT.id + "\"\n" + + " }\n" + + " }\n" + + " },\n" + + " \"mappings\" : { },\n" + + " \"aliases\" : { }\n" + + " }\n" + + " },\n" + + " \"indices\" : {\n" + + " \"index\" : {\n" + + " \"version\" : 1,\n" + + " \"mapping_version\" : 1,\n" + + " \"settings_version\" : 1,\n" + + " \"aliases_version\" : 1,\n" + + " \"routing_num_shards\" : 1,\n" + + " \"state\" : \"open\",\n" + + " \"settings\" : {\n" + + " \"index\" : {\n" + + " \"number_of_shards\" : \"1\",\n" + + " \"number_of_replicas\" : \"2\",\n" + + " \"version\" : {\n" + + " \"created\" : \"" + Version.CURRENT.id + "\"\n" + + " }\n" + + " }\n" + + " },\n" + + " \"mappings\" : {\n" + + " \"type\" : {\n" + + " \"type1\" : {\n" + + " \"key\" : \"value\"\n" + + " }\n" + + " }\n" + + " },\n" + + " \"aliases\" : [\n" + + " \"alias\"\n" + + " ],\n" + + " \"primary_terms\" : {\n" + + " \"0\" : 1\n" + + " },\n" + + " \"in_sync_allocations\" : {\n" + + " \"0\" : [\n" + + " \"allocationId\"\n" + + " ]\n" + + " },\n" + + " \"rollover_info\" : {\n" + + " \"rolloveAlias\" : {\n" + + " \"met_conditions\" : { },\n" + + " \"time\" : 1\n" + + " }\n" + + " }\n" + + " }\n" + + " },\n" + + " \"index-graveyard\" : {\n" + + " \"tombstones\" : [ ]\n" + + " }\n" + + " },\n" + + " \"routing_table\" : {\n" + + " \"indices\" : {\n" + + " \"index\" : {\n" + + " \"shards\" : {\n" + + " \"1\" : [\n" + + " {\n" + + " \"state\" : \"STARTED\",\n" + + " \"primary\" : true,\n" + + " \"node\" : \"nodeId2\",\n" + + " \"relocating_node\" : null,\n" + + " \"shard\" : 1,\n" + + " \"index\" : \"index\",\n" + + " \"allocation_id\" : {\n" + + " \"id\" : \"" + allocationId + "\"\n" + + " }\n" + + " }\n" + + " ]\n" + + " }\n" + + " }\n" + + " }\n" + + " },\n" + + " \"routing_nodes\" : {\n" + + " \"unassigned\" : [ ],\n" + + " \"nodes\" : {\n" + + " \"nodeId2\" : [\n" + + " {\n" + + " \"state\" : \"STARTED\",\n" + + " \"primary\" : true,\n" + + " \"node\" : \"nodeId2\",\n" + + " \"relocating_node\" : null,\n" + + " \"shard\" : 1,\n" + + " \"index\" : \"index\",\n" + + " \"allocation_id\" : {\n" + + " \"id\" : \"" + allocationId + "\"\n" + + " }\n" + + " }\n" + + " ],\n" + + " \"nodeId1\" : [ ]\n" + + " }\n" + + " }\n" + + "}", Strings.toString(builder)); + + } + + public void testToXContentSameTypeName() throws IOException { + final ClusterState clusterState = ClusterState.builder(ClusterName.DEFAULT) + .stateUUID("stateUUID") + .metaData(MetaData.builder() + .clusterUUID("clusterUUID") + .coordinationMetaData(CoordinationMetaData.builder() + .build()) + .put(IndexMetaData.builder("index") + .state(IndexMetaData.State.OPEN) + .settings(Settings.builder() + .put(SETTING_VERSION_CREATED, Version.CURRENT.id)) + .putMapping(new MappingMetaData("type", + // the type name is the root value, + // the original logic in ClusterState.toXContent will reduce + new HashMap<>(){{ + put("type", new HashMap(){{ + put("key", "value"); + }}); + }})) + .numberOfShards(1) + .primaryTerm(0, 1L) + .numberOfReplicas(2))) + .build(); + + XContentBuilder builder = JsonXContent.contentBuilder().prettyPrint(); + builder.startObject(); + clusterState.toXContent(builder, ToXContent.EMPTY_PARAMS); + builder.endObject(); + + assertEquals("{\n" + + " \"cluster_uuid\" : \"clusterUUID\",\n" + + " \"version\" : 0,\n" + + " \"state_uuid\" : \"stateUUID\",\n" + + " \"master_node\" : null,\n" + + " \"blocks\" : { },\n" + + " \"nodes\" : { },\n" + + " \"metadata\" : {\n" + + " \"cluster_uuid\" : \"clusterUUID\",\n" + + " \"cluster_uuid_committed\" : false,\n" + + " \"cluster_coordination\" : {\n" + + " \"term\" : 0,\n" + + " \"last_committed_config\" : [ ],\n" + + " \"last_accepted_config\" : [ ],\n" + + " \"voting_config_exclusions\" : [ ]\n" + + " },\n" + + " \"templates\" : { },\n" + + " \"indices\" : {\n" + + " \"index\" : {\n" + + " \"version\" : 2,\n" + + " \"mapping_version\" : 1,\n" + + " \"settings_version\" : 1,\n" + + " \"aliases_version\" : 1,\n" + + " \"routing_num_shards\" : 1,\n" + + " \"state\" : \"open\",\n" + + " \"settings\" : {\n" + + " \"index\" : {\n" + + " \"number_of_shards\" : \"1\",\n" + + " \"number_of_replicas\" : \"2\",\n" + + " \"version\" : {\n" + + " \"created\" : \"" + Version.CURRENT.id + "\"\n" + + " }\n" + + " }\n" + + " },\n" + + " \"mappings\" : {\n" + + " \"type\" : {\n" + + " \"key\" : \"value\"\n" + + " }\n" + + " },\n" + + " \"aliases\" : [ ],\n" + + " \"primary_terms\" : {\n" + + " \"0\" : 1\n" + + " },\n" + + " \"in_sync_allocations\" : {\n" + + " \"0\" : [ ]\n" + + " },\n" + + " \"rollover_info\" : { }\n" + + " }\n" + + " },\n" + + " \"index-graveyard\" : {\n" + + " \"tombstones\" : [ ]\n" + + " }\n" + + " },\n" + + " \"routing_table\" : {\n" + + " \"indices\" : { }\n" + + " },\n" + + " \"routing_nodes\" : {\n" + + " \"unassigned\" : [ ],\n" + + " \"nodes\" : { }\n" + + " }\n" + + "}", Strings.toString(builder)); + } + + private ClusterState buildClusterState() throws IOException { + IndexMetaData indexMetaData = IndexMetaData.builder("index") + .state(IndexMetaData.State.OPEN) + .settings(Settings.builder() + .put(SETTING_VERSION_CREATED, Version.CURRENT.id)) + .putMapping(new MappingMetaData("type", + new HashMap<>() {{ + put("type1", new HashMap(){{ + put("key", "value"); + }}); + }})) + .putAlias(AliasMetaData.builder("alias") + .indexRouting("indexRouting") + .build()) + .numberOfShards(1) + .primaryTerm(0, 1L) + .putInSyncAllocationIds(0, new HashSet<>() {{ + add("allocationId"); + }}) + .numberOfReplicas(2) + .putRolloverInfo(new RolloverInfo("rolloveAlias", new ArrayList<>(), 1L)) + .build(); + + return ClusterState.builder(ClusterName.DEFAULT) + .stateUUID("stateUUID") + .nodes(DiscoveryNodes.builder() + .masterNodeId("masterNodeId") + .add(new DiscoveryNode("nodeId1", new TransportAddress(InetAddress.getByName("127.0.0.1"), 111), + Version.CURRENT)) + .build()) + .blocks(ClusterBlocks.builder() + .addGlobalBlock( + new ClusterBlock(1, "description", true, true, true, RestStatus.ACCEPTED, EnumSet.allOf((ClusterBlockLevel.class)))) + .addBlocks(indexMetaData) + .addIndexBlock("index", + new ClusterBlock(2, "description2", false, false, false, RestStatus.ACCEPTED, EnumSet.allOf((ClusterBlockLevel.class)))) + .build()) + .metaData(MetaData.builder() + .clusterUUID("clusterUUID") + .coordinationMetaData(CoordinationMetaData.builder() + .term(1) + .lastCommittedConfiguration(new CoordinationMetaData.VotingConfiguration(new HashSet<>(){{ + add("commitedConfigurationNodeId"); + }})) + .lastAcceptedConfiguration(new CoordinationMetaData.VotingConfiguration(new HashSet<>(){{ + add("acceptedConfigurationNodeId"); + }})) + .addVotingConfigExclusion(new CoordinationMetaData.VotingConfigExclusion("exlucdedNodeId", "excludedNodeName")) + .build()) + .persistentSettings(Settings.builder() + .put(SETTING_VERSION_CREATED, Version.CURRENT.id).build()) + .transientSettings(Settings.builder() + .put(SETTING_VERSION_CREATED, Version.CURRENT.id).build()) + .put(indexMetaData, false) + .put(IndexTemplateMetaData.builder("template") + .patterns(List.of("pattern1", "pattern2")) + .order(0) + .settings(Settings.builder().put(SETTING_VERSION_CREATED, Version.CURRENT.id)) + .putMapping("type", "{ \"key1\": {} }") + .build())) + .routingTable(RoutingTable.builder() + .add(IndexRoutingTable.builder(new Index("index", "indexUUID")) + .addIndexShard(new IndexShardRoutingTable.Builder(new ShardId("index", "_na_", 1)) + .addShard(TestShardRouting.newShardRouting( + new ShardId("index", "_na_", 1), "nodeId2", true, ShardRoutingState.STARTED)) + .build()) + .build()) + .build()) + .build(); + } + + public static class CustomMetaData extends TestCustomMetaData { + public static final String TYPE = "custom_md"; + + CustomMetaData(String data) { + super(data); + } + + @Override + public String getWriteableName() { + return TYPE; + } + + @Override + public Version getMinimalSupportedVersion() { + return Version.CURRENT; + } + + @Override + public EnumSet context() { + return EnumSet.of(MetaData.XContentContext.GATEWAY, MetaData.XContentContext.SNAPSHOT); + } + } } diff --git a/server/src/test/java/org/elasticsearch/cluster/coordination/ElasticsearchNodeCommandTests.java b/server/src/test/java/org/elasticsearch/cluster/coordination/ElasticsearchNodeCommandTests.java index f3e68dfee19da..9ef39de9c5b26 100644 --- a/server/src/test/java/org/elasticsearch/cluster/coordination/ElasticsearchNodeCommandTests.java +++ b/server/src/test/java/org/elasticsearch/cluster/coordination/ElasticsearchNodeCommandTests.java @@ -19,22 +19,12 @@ package org.elasticsearch.cluster.coordination; -import org.elasticsearch.Version; -import org.elasticsearch.action.admin.indices.rollover.MaxAgeCondition; -import org.elasticsearch.action.admin.indices.rollover.MaxDocsCondition; -import org.elasticsearch.action.admin.indices.rollover.MaxSizeCondition; -import org.elasticsearch.action.admin.indices.rollover.RolloverInfo; import org.elasticsearch.cluster.ClusterModule; import org.elasticsearch.cluster.metadata.IndexGraveyard; -import org.elasticsearch.cluster.metadata.IndexMetaData; import org.elasticsearch.cluster.metadata.MetaData; import org.elasticsearch.common.UUIDs; import org.elasticsearch.common.bytes.BytesReference; -import org.elasticsearch.common.collect.ImmutableOpenMap; -import org.elasticsearch.common.unit.ByteSizeValue; -import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.xcontent.NamedXContentRegistry; -import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.common.xcontent.json.JsonXContent; @@ -44,7 +34,6 @@ import java.io.IOException; import java.nio.file.Path; -import java.util.Arrays; import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -52,7 +41,6 @@ import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.not; -import static org.hamcrest.Matchers.notNullValue; public class ElasticsearchNodeCommandTests extends ESTestCase { @@ -76,7 +64,7 @@ private void runLoadStateTest(boolean hasMissingCustoms, boolean preserveUnknown final MetaData latestMetaData = randomMeta(); final XContentBuilder builder = JsonXContent.contentBuilder(); builder.startObject(); - latestMetaData.toXContent(builder, ToXContent.EMPTY_PARAMS); + MetaData.FORMAT.toXContent(builder, latestMetaData); builder.endObject(); MetaData loadedMetaData; @@ -86,17 +74,6 @@ private void runLoadStateTest(boolean hasMissingCustoms, boolean preserveUnknown } assertThat(loadedMetaData.clusterUUID(), not(equalTo("_na_"))); assertThat(loadedMetaData.clusterUUID(), equalTo(latestMetaData.clusterUUID())); - ImmutableOpenMap indices = loadedMetaData.indices(); - assertThat(indices.size(), equalTo(latestMetaData.indices().size())); - for (IndexMetaData original : latestMetaData) { - IndexMetaData deserialized = indices.get(original.getIndex().getName()); - assertThat(deserialized, notNullValue()); - assertThat(deserialized.getVersion(), equalTo(original.getVersion())); - assertThat(deserialized.getMappingVersion(), equalTo(original.getMappingVersion())); - assertThat(deserialized.getSettingsVersion(), equalTo(original.getSettingsVersion())); - assertThat(deserialized.getNumberOfReplicas(), equalTo(original.getNumberOfReplicas())); - assertThat(deserialized.getNumberOfShards(), equalTo(original.getNumberOfShards())); - } // make sure the index tombstones are the same too if (hasMissingCustoms) { @@ -116,12 +93,8 @@ private void runLoadStateTest(boolean hasMissingCustoms, boolean preserveUnknown } private MetaData randomMeta() { - int numIndices = randomIntBetween(1, 10); MetaData.Builder mdBuilder = MetaData.builder(); mdBuilder.generateClusterUuidIfNeeded(); - for (int i = 0; i < numIndices; i++) { - mdBuilder.put(indexBuilder(randomAlphaOfLength(10) + "idx-"+i)); - } int numDelIndices = randomIntBetween(0, 5); final IndexGraveyard.Builder graveyard = IndexGraveyard.builder(); for (int i = 0; i < numDelIndices; i++) { @@ -131,17 +104,6 @@ private MetaData randomMeta() { return mdBuilder.build(); } - private IndexMetaData.Builder indexBuilder(String index) { - return IndexMetaData.builder(index) - .settings(settings(Version.CURRENT).put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, randomIntBetween(1, 10)) - .put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, randomIntBetween(0, 5))) - .putRolloverInfo(new RolloverInfo("test", randomSubsetOf(Arrays.asList( - new MaxAgeCondition(TimeValue.timeValueSeconds(100)), - new MaxDocsCondition(100L), - new MaxSizeCondition(new ByteSizeValue(100)) - )), 0)); - } - @Override protected NamedXContentRegistry xContentRegistry() { return new NamedXContentRegistry(Stream.of(ClusterModule.getNamedXWriteables().stream(), IndicesModule.getNamedXContents().stream()) diff --git a/server/src/test/java/org/elasticsearch/cluster/metadata/IndexMetaDataTests.java b/server/src/test/java/org/elasticsearch/cluster/metadata/IndexMetaDataTests.java index 8f9f883a7cc8d..272ef4a87e41a 100644 --- a/server/src/test/java/org/elasticsearch/cluster/metadata/IndexMetaDataTests.java +++ b/server/src/test/java/org/elasticsearch/cluster/metadata/IndexMetaDataTests.java @@ -36,7 +36,6 @@ import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.util.set.Sets; import org.elasticsearch.common.xcontent.NamedXContentRegistry; -import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.common.xcontent.json.JsonXContent; @@ -99,7 +98,7 @@ public void testIndexMetaDataSerialization() throws IOException { final XContentBuilder builder = JsonXContent.contentBuilder(); builder.startObject(); - metaData.toXContent(builder, ToXContent.EMPTY_PARAMS); + IndexMetaData.FORMAT.toXContent(builder, metaData); builder.endObject(); XContentParser parser = createParser(JsonXContent.jsonXContent, BytesReference.bytes(builder)); final IndexMetaData fromXContentMeta = IndexMetaData.fromXContent(parser); diff --git a/server/src/test/java/org/elasticsearch/cluster/metadata/MetaDataTests.java b/server/src/test/java/org/elasticsearch/cluster/metadata/MetaDataTests.java index dcd43a3eaf6cc..b48124026d773 100644 --- a/server/src/test/java/org/elasticsearch/cluster/metadata/MetaDataTests.java +++ b/server/src/test/java/org/elasticsearch/cluster/metadata/MetaDataTests.java @@ -34,7 +34,6 @@ import org.elasticsearch.common.settings.Setting; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.util.set.Sets; -import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentHelper; import org.elasticsearch.common.xcontent.XContentParser; @@ -438,7 +437,7 @@ public void testXContentWithIndexGraveyard() throws IOException { final MetaData originalMeta = MetaData.builder().indexGraveyard(graveyard).build(); final XContentBuilder builder = JsonXContent.contentBuilder(); builder.startObject(); - originalMeta.toXContent(builder, ToXContent.EMPTY_PARAMS); + MetaData.FORMAT.toXContent(builder, originalMeta); builder.endObject(); try (XContentParser parser = createParser(JsonXContent.jsonXContent, BytesReference.bytes(builder))) { final MetaData fromXContentMeta = MetaData.fromXContent(parser); @@ -451,7 +450,7 @@ public void testXContentClusterUUID() throws IOException { .clusterUUIDCommitted(randomBoolean()).build(); final XContentBuilder builder = JsonXContent.contentBuilder(); builder.startObject(); - originalMeta.toXContent(builder, ToXContent.EMPTY_PARAMS); + MetaData.FORMAT.toXContent(builder, originalMeta); builder.endObject(); try (XContentParser parser = createParser(JsonXContent.jsonXContent, BytesReference.bytes(builder))) { final MetaData fromXContentMeta = MetaData.fromXContent(parser); @@ -504,7 +503,7 @@ public void testXContentWithCoordinationMetaData() throws IOException { final XContentBuilder builder = JsonXContent.contentBuilder(); builder.startObject(); - metaData.toXContent(builder, ToXContent.EMPTY_PARAMS); + MetaData.FORMAT.toXContent(builder, metaData); builder.endObject(); try (XContentParser parser = createParser(JsonXContent.jsonXContent, BytesReference.bytes(builder))) { diff --git a/server/src/test/java/org/elasticsearch/cluster/metadata/ToAndFromJsonMetaDataTests.java b/server/src/test/java/org/elasticsearch/cluster/metadata/ToAndFromJsonMetaDataTests.java index 05a678f9c9f68..cc0af32591109 100644 --- a/server/src/test/java/org/elasticsearch/cluster/metadata/ToAndFromJsonMetaDataTests.java +++ b/server/src/test/java/org/elasticsearch/cluster/metadata/ToAndFromJsonMetaDataTests.java @@ -20,101 +20,38 @@ package org.elasticsearch.cluster.metadata; import org.elasticsearch.Version; +import org.elasticsearch.action.admin.indices.rollover.RolloverInfo; +import org.elasticsearch.cluster.coordination.CoordinationMetaData; +import org.elasticsearch.common.Strings; import org.elasticsearch.common.compress.CompressedXContent; import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.xcontent.ToXContent; +import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.json.JsonXContent; import org.elasticsearch.test.ESTestCase; +import org.elasticsearch.test.TestCustomMetaData; import java.io.IOException; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.EnumSet; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; import static org.elasticsearch.cluster.metadata.AliasMetaData.newAliasMetaDataBuilder; +import static org.elasticsearch.cluster.metadata.IndexMetaData.SETTING_VERSION_CREATED; +import static org.elasticsearch.cluster.metadata.MetaData.CONTEXT_MODE_API; +import static org.elasticsearch.cluster.metadata.MetaData.CONTEXT_MODE_GATEWAY; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.nullValue; public class ToAndFromJsonMetaDataTests extends ESTestCase { public void testSimpleJsonFromAndTo() throws IOException { MetaData metaData = MetaData.builder() - .put(IndexMetaData.builder("test1") - .settings(settings(Version.CURRENT)) - .numberOfShards(1) - .numberOfReplicas(2) - .primaryTerm(0, 1)) - .put(IndexMetaData.builder("test2") - .settings(settings(Version.CURRENT).put("setting1", "value1").put("setting2", "value2")) - .numberOfShards(2) - .numberOfReplicas(3) - .primaryTerm(0, 2) - .primaryTerm(1, 2)) - .put(IndexMetaData.builder("test3") - .settings(settings(Version.CURRENT)) - .numberOfShards(1) - .numberOfReplicas(2) - .putMapping("mapping1", MAPPING_SOURCE1)) - .put(IndexMetaData.builder("test4") - .settings(settings(Version.CURRENT)) - .numberOfShards(1) - .numberOfReplicas(2) - .creationDate(2L)) - .put(IndexMetaData.builder("test5") - .settings(settings(Version.CURRENT).put("setting1", "value1").put("setting2", "value2")) - .numberOfShards(1) - .numberOfReplicas(2) - .putMapping("mapping1", MAPPING_SOURCE1) - .putMapping("mapping2", MAPPING_SOURCE2)) - .put(IndexMetaData.builder("test6") - .settings(settings(Version.CURRENT).put("setting1", "value1").put("setting2", "value2")) - .numberOfShards(1) - .numberOfReplicas(2) - .creationDate(2L)) - .put(IndexMetaData.builder("test7") - .settings(settings(Version.CURRENT)) - .numberOfShards(1) - .numberOfReplicas(2) - .creationDate(2L) - .putMapping("mapping1", MAPPING_SOURCE1) - .putMapping("mapping2", MAPPING_SOURCE2)) - .put(IndexMetaData.builder("test8") - .settings(settings(Version.CURRENT).put("setting1", "value1").put("setting2", "value2")) - .numberOfShards(1) - .numberOfReplicas(2) - .putMapping("mapping1", MAPPING_SOURCE1) - .putMapping("mapping2", MAPPING_SOURCE2) - .putAlias(newAliasMetaDataBuilder("alias1")) - .putAlias(newAliasMetaDataBuilder("alias2"))) - .put(IndexMetaData.builder("test9") - .settings(settings(Version.CURRENT).put("setting1", "value1").put("setting2", "value2")) - .creationDate(2L) - .numberOfShards(1) - .numberOfReplicas(2) - .putMapping("mapping1", MAPPING_SOURCE1) - .putMapping("mapping2", MAPPING_SOURCE2) - .putAlias(newAliasMetaDataBuilder("alias1")) - .putAlias(newAliasMetaDataBuilder("alias2"))) - .put(IndexMetaData.builder("test10") - .settings(settings(Version.CURRENT) - .put("setting1", "value1") - .put("setting2", "value2")) - .numberOfShards(1) - .numberOfReplicas(2) - .putMapping("mapping1", MAPPING_SOURCE1) - .putMapping("mapping2", MAPPING_SOURCE2) - .putAlias(newAliasMetaDataBuilder("alias1")) - .putAlias(newAliasMetaDataBuilder("alias2"))) - .put(IndexMetaData.builder("test11") - .settings(settings(Version.CURRENT) - .put("setting1", "value1") - .put("setting2", "value2")) - .numberOfShards(1) - .numberOfReplicas(2) - .putMapping("mapping1", MAPPING_SOURCE1) - .putMapping("mapping2", MAPPING_SOURCE2) - .putAlias(newAliasMetaDataBuilder("alias1").filter(ALIAS_FILTER1)) - .putAlias(newAliasMetaDataBuilder("alias2").writeIndex(randomBoolean() ? null : randomBoolean())) - .putAlias(newAliasMetaDataBuilder("alias4").filter(ALIAS_FILTER2))) .put(IndexTemplateMetaData.builder("foo") .patterns(Collections.singletonList("bar")) .order(1) @@ -162,154 +99,12 @@ public void testSimpleJsonFromAndTo() throws IOException { .put(new DataStream("data-stream2", "@timestamp2", Collections.emptyList())) .build(); - String metaDataSource = MetaData.Builder.toXContent(metaData); - - MetaData parsedMetaData = MetaData.Builder.fromXContent(createParser(JsonXContent.jsonXContent, metaDataSource)); - - IndexMetaData indexMetaData = parsedMetaData.index("test1"); - assertThat(indexMetaData.primaryTerm(0), equalTo(1L)); - assertThat(indexMetaData.getNumberOfShards(), equalTo(1)); - assertThat(indexMetaData.getNumberOfReplicas(), equalTo(2)); - assertThat(indexMetaData.getCreationDate(), equalTo(-1L)); - assertThat(indexMetaData.getSettings().size(), equalTo(3)); - assertThat(indexMetaData.getMappings().size(), equalTo(0)); - - indexMetaData = parsedMetaData.index("test2"); - assertThat(indexMetaData.getNumberOfShards(), equalTo(2)); - assertThat(indexMetaData.getNumberOfReplicas(), equalTo(3)); - assertThat(indexMetaData.primaryTerm(0), equalTo(2L)); - assertThat(indexMetaData.primaryTerm(1), equalTo(2L)); - assertThat(indexMetaData.getCreationDate(), equalTo(-1L)); - assertThat(indexMetaData.getSettings().size(), equalTo(5)); - assertThat(indexMetaData.getSettings().get("setting1"), equalTo("value1")); - assertThat(indexMetaData.getSettings().get("setting2"), equalTo("value2")); - assertThat(indexMetaData.getMappings().size(), equalTo(0)); - - indexMetaData = parsedMetaData.index("test3"); - assertThat(indexMetaData.getNumberOfShards(), equalTo(1)); - assertThat(indexMetaData.getNumberOfReplicas(), equalTo(2)); - assertThat(indexMetaData.getCreationDate(), equalTo(-1L)); - assertThat(indexMetaData.getSettings().size(), equalTo(3)); - assertThat(indexMetaData.getMappings().size(), equalTo(1)); - assertThat(indexMetaData.getMappings().get("mapping1").source().string(), equalTo(MAPPING_SOURCE1)); - - indexMetaData = parsedMetaData.index("test4"); - assertThat(indexMetaData.getCreationDate(), equalTo(2L)); - assertThat(indexMetaData.getNumberOfShards(), equalTo(1)); - assertThat(indexMetaData.getNumberOfReplicas(), equalTo(2)); - assertThat(indexMetaData.getSettings().size(), equalTo(4)); - assertThat(indexMetaData.getMappings().size(), equalTo(0)); - - indexMetaData = parsedMetaData.index("test5"); - assertThat(indexMetaData.getNumberOfShards(), equalTo(1)); - assertThat(indexMetaData.getNumberOfReplicas(), equalTo(2)); - assertThat(indexMetaData.getCreationDate(), equalTo(-1L)); - assertThat(indexMetaData.getSettings().size(), equalTo(5)); - assertThat(indexMetaData.getSettings().get("setting1"), equalTo("value1")); - assertThat(indexMetaData.getSettings().get("setting2"), equalTo("value2")); - assertThat(indexMetaData.getMappings().size(), equalTo(2)); - assertThat(indexMetaData.getMappings().get("mapping1").source().string(), equalTo(MAPPING_SOURCE1)); - assertThat(indexMetaData.getMappings().get("mapping2").source().string(), equalTo(MAPPING_SOURCE2)); - - indexMetaData = parsedMetaData.index("test6"); - assertThat(indexMetaData.getNumberOfShards(), equalTo(1)); - assertThat(indexMetaData.getNumberOfReplicas(), equalTo(2)); - assertThat(indexMetaData.getCreationDate(), equalTo(2L)); - assertThat(indexMetaData.getSettings().size(), equalTo(6)); - assertThat(indexMetaData.getSettings().get("setting1"), equalTo("value1")); - assertThat(indexMetaData.getSettings().get("setting2"), equalTo("value2")); - assertThat(indexMetaData.getMappings().size(), equalTo(0)); - - indexMetaData = parsedMetaData.index("test7"); - assertThat(indexMetaData.getNumberOfShards(), equalTo(1)); - assertThat(indexMetaData.getNumberOfReplicas(), equalTo(2)); - assertThat(indexMetaData.getCreationDate(), equalTo(2L)); - assertThat(indexMetaData.getSettings().size(), equalTo(4)); - assertThat(indexMetaData.getMappings().size(), equalTo(2)); - assertThat(indexMetaData.getMappings().get("mapping1").source().string(), equalTo(MAPPING_SOURCE1)); - assertThat(indexMetaData.getMappings().get("mapping2").source().string(), equalTo(MAPPING_SOURCE2)); - - indexMetaData = parsedMetaData.index("test8"); - assertThat(indexMetaData.getNumberOfShards(), equalTo(1)); - assertThat(indexMetaData.getNumberOfReplicas(), equalTo(2)); - assertThat(indexMetaData.getCreationDate(), equalTo(-1L)); - assertThat(indexMetaData.getSettings().size(), equalTo(5)); - assertThat(indexMetaData.getSettings().get("setting1"), equalTo("value1")); - assertThat(indexMetaData.getSettings().get("setting2"), equalTo("value2")); - assertThat(indexMetaData.getMappings().size(), equalTo(2)); - assertThat(indexMetaData.getMappings().get("mapping1").source().string(), equalTo(MAPPING_SOURCE1)); - assertThat(indexMetaData.getMappings().get("mapping2").source().string(), equalTo(MAPPING_SOURCE2)); - assertThat(indexMetaData.getAliases().size(), equalTo(2)); - assertThat(indexMetaData.getAliases().get("alias1").alias(), equalTo("alias1")); - assertThat(indexMetaData.getAliases().get("alias2").alias(), equalTo("alias2")); - - indexMetaData = parsedMetaData.index("test9"); - assertThat(indexMetaData.getNumberOfShards(), equalTo(1)); - assertThat(indexMetaData.getNumberOfReplicas(), equalTo(2)); - assertThat(indexMetaData.getCreationDate(), equalTo(2L)); - assertThat(indexMetaData.getSettings().size(), equalTo(6)); - assertThat(indexMetaData.getSettings().get("setting1"), equalTo("value1")); - assertThat(indexMetaData.getSettings().get("setting2"), equalTo("value2")); - assertThat(indexMetaData.getMappings().size(), equalTo(2)); - assertThat(indexMetaData.getMappings().get("mapping1").source().string(), equalTo(MAPPING_SOURCE1)); - assertThat(indexMetaData.getMappings().get("mapping2").source().string(), equalTo(MAPPING_SOURCE2)); - assertThat(indexMetaData.getAliases().size(), equalTo(2)); - assertThat(indexMetaData.getAliases().get("alias1").alias(), equalTo("alias1")); - assertThat(indexMetaData.getAliases().get("alias2").alias(), equalTo("alias2")); - - indexMetaData = parsedMetaData.index("test10"); - assertThat(indexMetaData.getNumberOfShards(), equalTo(1)); - assertThat(indexMetaData.getNumberOfReplicas(), equalTo(2)); - assertThat(indexMetaData.getCreationDate(), equalTo(-1L)); - assertThat(indexMetaData.getSettings().size(), equalTo(5)); - assertThat(indexMetaData.getSettings().get("setting1"), equalTo("value1")); - assertThat(indexMetaData.getSettings().get("setting2"), equalTo("value2")); - assertThat(indexMetaData.getMappings().size(), equalTo(2)); - assertThat(indexMetaData.getMappings().get("mapping1").source().string(), equalTo(MAPPING_SOURCE1)); - assertThat(indexMetaData.getMappings().get("mapping2").source().string(), equalTo(MAPPING_SOURCE2)); - assertThat(indexMetaData.getAliases().size(), equalTo(2)); - assertThat(indexMetaData.getAliases().get("alias1").alias(), equalTo("alias1")); - assertThat(indexMetaData.getAliases().get("alias2").alias(), equalTo("alias2")); - - indexMetaData = parsedMetaData.index("test11"); - assertThat(indexMetaData.getNumberOfShards(), equalTo(1)); - assertThat(indexMetaData.getNumberOfReplicas(), equalTo(2)); - assertThat(indexMetaData.getCreationDate(), equalTo(-1L)); - assertThat(indexMetaData.getSettings().size(), equalTo(5)); - assertThat(indexMetaData.getSettings().get("setting1"), equalTo("value1")); - assertThat(indexMetaData.getSettings().get("setting2"), equalTo("value2")); - assertThat(indexMetaData.getMappings().size(), equalTo(2)); - assertThat(indexMetaData.getMappings().get("mapping1").source().string(), equalTo(MAPPING_SOURCE1)); - assertThat(indexMetaData.getMappings().get("mapping2").source().string(), equalTo(MAPPING_SOURCE2)); - assertThat(indexMetaData.getAliases().size(), equalTo(3)); - assertThat(indexMetaData.getAliases().get("alias1").alias(), equalTo("alias1")); - assertThat(indexMetaData.getAliases().get("alias1").filter().string(), equalTo(ALIAS_FILTER1)); - assertThat(indexMetaData.getAliases().get("alias2").alias(), equalTo("alias2")); - assertThat(indexMetaData.getAliases().get("alias2").filter(), nullValue()); - assertThat(indexMetaData.getAliases().get("alias2").writeIndex(), - equalTo(metaData.index("test11").getAliases().get("alias2").writeIndex())); - assertThat(indexMetaData.getAliases().get("alias4").alias(), equalTo("alias4")); - assertThat(indexMetaData.getAliases().get("alias4").filter().string(), equalTo(ALIAS_FILTER2)); - - indexMetaData = parsedMetaData.index("test12"); - assertThat(indexMetaData.getNumberOfShards(), equalTo(1)); - assertThat(indexMetaData.getNumberOfReplicas(), equalTo(2)); - assertThat(indexMetaData.getCreationDate(), equalTo(2L)); - assertThat(indexMetaData.getSettings().size(), equalTo(6)); - assertThat(indexMetaData.getSettings().get("setting1"), equalTo("value1")); - assertThat(indexMetaData.getSettings().get("setting2"), equalTo("value2")); - assertThat(indexMetaData.getMappings().size(), equalTo(2)); - assertThat(indexMetaData.getMappings().get("mapping1").source().string(), equalTo(MAPPING_SOURCE1)); - assertThat(indexMetaData.getMappings().get("mapping2").source().string(), equalTo(MAPPING_SOURCE2)); - assertThat(indexMetaData.getAliases().size(), equalTo(3)); - assertThat(indexMetaData.getAliases().get("alias1").alias(), equalTo("alias1")); - assertThat(indexMetaData.getAliases().get("alias1").filter().string(), equalTo(ALIAS_FILTER1)); - assertThat(indexMetaData.getAliases().get("alias3").alias(), equalTo("alias3")); - assertThat(indexMetaData.getAliases().get("alias3").filter(), nullValue()); - assertThat(indexMetaData.getAliases().get("alias3").writeIndex(), - equalTo(metaData.index("test12").getAliases().get("alias3").writeIndex())); - assertThat(indexMetaData.getAliases().get("alias4").alias(), equalTo("alias4")); - assertThat(indexMetaData.getAliases().get("alias4").filter().string(), equalTo(ALIAS_FILTER2)); + XContentBuilder builder = JsonXContent.contentBuilder(); + builder.startObject(); + MetaData.FORMAT.toXContent(builder, metaData); + builder.endObject(); + + MetaData parsedMetaData = MetaData.Builder.fromXContent(createParser(builder)); // templates assertThat(parsedMetaData.templates().get("foo").name(), is("foo")); @@ -363,4 +158,470 @@ public void testSimpleJsonFromAndTo() throws IOException { private static final String MAPPING_SOURCE2 = "{\"mapping2\":{\"text2\":{\"type\":\"string\"}}}"; private static final String ALIAS_FILTER1 = "{\"field1\":\"value1\"}"; private static final String ALIAS_FILTER2 = "{\"field2\":\"value2\"}"; + + public void testToXContentGateway_FlatSettingTrue_ReduceMappingFalse() throws IOException { + Map mapParams = new HashMap<>(){{ + put(MetaData.CONTEXT_MODE_PARAM, CONTEXT_MODE_GATEWAY); + put("flat_settings", "true"); + put("reduce_mappings", "false"); + }}; + + MetaData metaData = buildMetaData(); + XContentBuilder builder = JsonXContent.contentBuilder().prettyPrint(); + builder.startObject(); + metaData.toXContent(builder, new ToXContent.MapParams(mapParams)); + builder.endObject(); + + assertEquals("{\n" + + " \"meta-data\" : {\n" + + " \"version\" : 0,\n" + + " \"cluster_uuid\" : \"clusterUUID\",\n" + + " \"cluster_uuid_committed\" : false,\n" + + " \"cluster_coordination\" : {\n" + + " \"term\" : 1,\n" + + " \"last_committed_config\" : [\n" + + " \"commitedConfigurationNodeId\"\n" + + " ],\n" + + " \"last_accepted_config\" : [\n" + + " \"acceptedConfigurationNodeId\"\n" + + " ],\n" + + " \"voting_config_exclusions\" : [\n" + + " {\n" + + " \"node_id\" : \"exlucdedNodeId\",\n" + + " \"node_name\" : \"excludedNodeName\"\n" + + " }\n" + + " ]\n" + + " },\n" + + " \"settings\" : {\n" + + " \"index.version.created\" : \"" + Version.CURRENT.id + "\"\n" + + " },\n" + + " \"templates\" : {\n" + + " \"template\" : {\n" + + " \"order\" : 0,\n" + + " \"index_patterns\" : [\n" + + " \"pattern1\",\n" + + " \"pattern2\"\n" + + " ],\n" + + " \"settings\" : {\n" + + " \"index.version.created\" : \"" + Version.CURRENT.id + "\"\n" + + " },\n" + + " \"mappings\" : {\n" + + " \"key1\" : { }\n" + + " },\n" + + " \"aliases\" : { }\n" + + " }\n" + + " },\n" + + " \"index-graveyard\" : {\n" + + " \"tombstones\" : [ ]\n" + + " }\n" + + " }\n" + + "}", Strings.toString(builder)); + } + + public void testToXContentAPI_SameTypeName() throws IOException { + Map mapParams = new HashMap<>(){{ + put(MetaData.CONTEXT_MODE_PARAM, CONTEXT_MODE_API); + }}; + + MetaData metaData = MetaData.builder() + .clusterUUID("clusterUUID") + .coordinationMetaData(CoordinationMetaData.builder() + .build()) + .put(IndexMetaData.builder("index") + .state(IndexMetaData.State.OPEN) + .settings(Settings.builder() + .put(SETTING_VERSION_CREATED, Version.CURRENT.id)) + .putMapping(new MappingMetaData("type", + // the type name is the root value, + // the original logic in ClusterState.toXContent will reduce + new HashMap<>(){{ + put("type", new HashMap(){{ + put("key", "value"); + }}); + }})) + .numberOfShards(1) + .primaryTerm(0, 1L) + .numberOfReplicas(2)) + .build(); + XContentBuilder builder = JsonXContent.contentBuilder().prettyPrint(); + builder.startObject(); + metaData.toXContent(builder, new ToXContent.MapParams(mapParams)); + builder.endObject(); + + assertEquals("{\n" + + " \"metadata\" : {\n" + + " \"cluster_uuid\" : \"clusterUUID\",\n" + + " \"cluster_uuid_committed\" : false,\n" + + " \"cluster_coordination\" : {\n" + + " \"term\" : 0,\n" + + " \"last_committed_config\" : [ ],\n" + + " \"last_accepted_config\" : [ ],\n" + + " \"voting_config_exclusions\" : [ ]\n" + + " },\n" + + " \"templates\" : { },\n" + + " \"indices\" : {\n" + + " \"index\" : {\n" + + " \"version\" : 2,\n" + + " \"mapping_version\" : 1,\n" + + " \"settings_version\" : 1,\n" + + " \"aliases_version\" : 1,\n" + + " \"routing_num_shards\" : 1,\n" + + " \"state\" : \"open\",\n" + + " \"settings\" : {\n" + + " \"index\" : {\n" + + " \"number_of_shards\" : \"1\",\n" + + " \"number_of_replicas\" : \"2\",\n" + + " \"version\" : {\n" + + " \"created\" : \"" + Version.CURRENT.id + "\"\n" + + " }\n" + + " }\n" + + " },\n" + + " \"mappings\" : {\n" + + " \"type\" : {\n" + + " \"key\" : \"value\"\n" + + " }\n" + + " },\n" + + " \"aliases\" : [ ],\n" + + " \"primary_terms\" : {\n" + + " \"0\" : 1\n" + + " },\n" + + " \"in_sync_allocations\" : {\n" + + " \"0\" : [ ]\n" + + " },\n" + + " \"rollover_info\" : { }\n" + + " }\n" + + " },\n" + + " \"index-graveyard\" : {\n" + + " \"tombstones\" : [ ]\n" + + " }\n" + + " }\n" + + "}", Strings.toString(builder)); + } + + public void testToXContentGateway_FlatSettingFalse_ReduceMappingTrue() throws IOException { + Map mapParams = new HashMap<>(){{ + put(MetaData.CONTEXT_MODE_PARAM, CONTEXT_MODE_GATEWAY); + put("flat_settings", "false"); + put("reduce_mappings", "true"); + }}; + + MetaData metaData = buildMetaData(); + XContentBuilder builder = JsonXContent.contentBuilder().prettyPrint(); + builder.startObject(); + metaData.toXContent(builder, new ToXContent.MapParams(mapParams)); + builder.endObject(); + + assertEquals("{\n" + + " \"meta-data\" : {\n" + + " \"version\" : 0,\n" + + " \"cluster_uuid\" : \"clusterUUID\",\n" + + " \"cluster_uuid_committed\" : false,\n" + + " \"cluster_coordination\" : {\n" + + " \"term\" : 1,\n" + + " \"last_committed_config\" : [\n" + + " \"commitedConfigurationNodeId\"\n" + + " ],\n" + + " \"last_accepted_config\" : [\n" + + " \"acceptedConfigurationNodeId\"\n" + + " ],\n" + + " \"voting_config_exclusions\" : [\n" + + " {\n" + + " \"node_id\" : \"exlucdedNodeId\",\n" + + " \"node_name\" : \"excludedNodeName\"\n" + + " }\n" + + " ]\n" + + " },\n" + + " \"settings\" : {\n" + + " \"index.version.created\" : \"" + Version.CURRENT.id + "\"\n" + + " },\n" + + " \"templates\" : {\n" + + " \"template\" : {\n" + + " \"order\" : 0,\n" + + " \"index_patterns\" : [\n" + + " \"pattern1\",\n" + + " \"pattern2\"\n" + + " ],\n" + + " \"settings\" : {\n" + + " \"index\" : {\n" + + " \"version\" : {\n" + + " \"created\" : \"" + Version.CURRENT.id + "\"\n" + + " }\n" + + " }\n" + + " },\n" + + " \"mappings\" : { },\n" + + " \"aliases\" : { }\n" + + " }\n" + + " },\n" + + " \"index-graveyard\" : {\n" + + " \"tombstones\" : [ ]\n" + + " }\n" + + " }\n" + + "}", Strings.toString(builder)); + } + + public void testToXContentAPI_FlatSettingTrue_ReduceMappingFalse() throws IOException { + Map mapParams = new HashMap<>(){{ + put(MetaData.CONTEXT_MODE_PARAM, CONTEXT_MODE_API); + put("flat_settings", "true"); + put("reduce_mappings", "false"); + }}; + + final MetaData metaData = buildMetaData(); + + XContentBuilder builder = JsonXContent.contentBuilder().prettyPrint(); + builder.startObject(); + metaData.toXContent(builder, new ToXContent.MapParams(mapParams)); + builder.endObject(); + + assertEquals("{\n" + + " \"metadata\" : {\n" + + " \"cluster_uuid\" : \"clusterUUID\",\n" + + " \"cluster_uuid_committed\" : false,\n" + + " \"cluster_coordination\" : {\n" + + " \"term\" : 1,\n" + + " \"last_committed_config\" : [\n" + + " \"commitedConfigurationNodeId\"\n" + + " ],\n" + + " \"last_accepted_config\" : [\n" + + " \"acceptedConfigurationNodeId\"\n" + + " ],\n" + + " \"voting_config_exclusions\" : [\n" + + " {\n" + + " \"node_id\" : \"exlucdedNodeId\",\n" + + " \"node_name\" : \"excludedNodeName\"\n" + + " }\n" + + " ]\n" + + " },\n" + + " \"templates\" : {\n" + + " \"template\" : {\n" + + " \"order\" : 0,\n" + + " \"index_patterns\" : [\n" + + " \"pattern1\",\n" + + " \"pattern2\"\n" + + " ],\n" + + " \"settings\" : {\n" + + " \"index.version.created\" : \"" + Version.CURRENT.id + "\"\n" + + " },\n" + + " \"mappings\" : {\n" + + " \"key1\" : { }\n" + + " },\n" + + " \"aliases\" : { }\n" + + " }\n" + + " },\n" + + " \"indices\" : {\n" + + " \"index\" : {\n" + + " \"version\" : 2,\n" + + " \"mapping_version\" : 1,\n" + + " \"settings_version\" : 1,\n" + + " \"aliases_version\" : 1,\n" + + " \"routing_num_shards\" : 1,\n" + + " \"state\" : \"open\",\n" + + " \"settings\" : {\n" + + " \"index.number_of_replicas\" : \"2\",\n" + + " \"index.number_of_shards\" : \"1\",\n" + + " \"index.version.created\" : \"" + Version.CURRENT.id + "\"\n" + + " },\n" + + " \"mappings\" : {\n" + + " \"type\" : {\n" + + " \"type1\" : {\n" + + " \"key\" : \"value\"\n" + + " }\n" + + " }\n" + + " },\n" + + " \"aliases\" : [\n" + + " \"alias\"\n" + + " ],\n" + + " \"primary_terms\" : {\n" + + " \"0\" : 1\n" + + " },\n" + + " \"in_sync_allocations\" : {\n" + + " \"0\" : [\n" + + " \"allocationId\"\n" + + " ]\n" + + " },\n" + + " \"rollover_info\" : {\n" + + " \"rolloveAlias\" : {\n" + + " \"met_conditions\" : { },\n" + + " \"time\" : 1\n" + + " }\n" + + " }\n" + + " }\n" + + " },\n" + + " \"index-graveyard\" : {\n" + + " \"tombstones\" : [ ]\n" + + " }\n" + + " }\n" + + "}", Strings.toString(builder)); + } + + public void testToXContentAPI_FlatSettingFalse_ReduceMappingTrue() throws IOException { + Map mapParams = new HashMap<>(){{ + put(MetaData.CONTEXT_MODE_PARAM, CONTEXT_MODE_API); + put("flat_settings", "false"); + put("reduce_mappings", "true"); + }}; + + final MetaData metaData = buildMetaData(); + + XContentBuilder builder = JsonXContent.contentBuilder().prettyPrint(); + builder.startObject(); + metaData.toXContent(builder, new ToXContent.MapParams(mapParams)); + builder.endObject(); + + assertEquals("{\n" + + " \"metadata\" : {\n" + + " \"cluster_uuid\" : \"clusterUUID\",\n" + + " \"cluster_uuid_committed\" : false,\n" + + " \"cluster_coordination\" : {\n" + + " \"term\" : 1,\n" + + " \"last_committed_config\" : [\n" + + " \"commitedConfigurationNodeId\"\n" + + " ],\n" + + " \"last_accepted_config\" : [\n" + + " \"acceptedConfigurationNodeId\"\n" + + " ],\n" + + " \"voting_config_exclusions\" : [\n" + + " {\n" + + " \"node_id\" : \"exlucdedNodeId\",\n" + + " \"node_name\" : \"excludedNodeName\"\n" + + " }\n" + + " ]\n" + + " },\n" + + " \"templates\" : {\n" + + " \"template\" : {\n" + + " \"order\" : 0,\n" + + " \"index_patterns\" : [\n" + + " \"pattern1\",\n" + + " \"pattern2\"\n" + + " ],\n" + + " \"settings\" : {\n" + + " \"index\" : {\n" + + " \"version\" : {\n" + + " \"created\" : \"" + Version.CURRENT.id + "\"\n" + + " }\n" + + " }\n" + + " },\n" + + " \"mappings\" : { },\n" + + " \"aliases\" : { }\n" + + " }\n" + + " },\n" + + " \"indices\" : {\n" + + " \"index\" : {\n" + + " \"version\" : 2,\n" + + " \"mapping_version\" : 1,\n" + + " \"settings_version\" : 1,\n" + + " \"aliases_version\" : 1,\n" + + " \"routing_num_shards\" : 1,\n" + + " \"state\" : \"open\",\n" + + " \"settings\" : {\n" + + " \"index\" : {\n" + + " \"number_of_shards\" : \"1\",\n" + + " \"number_of_replicas\" : \"2\",\n" + + " \"version\" : {\n" + + " \"created\" : \"" + Version.CURRENT.id + "\"\n" + + " }\n" + + " }\n" + + " },\n" + + " \"mappings\" : {\n" + + " \"type\" : {\n" + + " \"type1\" : {\n" + + " \"key\" : \"value\"\n" + + " }\n" + + " }\n" + + " },\n" + + " \"aliases\" : [\n" + + " \"alias\"\n" + + " ],\n" + + " \"primary_terms\" : {\n" + + " \"0\" : 1\n" + + " },\n" + + " \"in_sync_allocations\" : {\n" + + " \"0\" : [\n" + + " \"allocationId\"\n" + + " ]\n" + + " },\n" + + " \"rollover_info\" : {\n" + + " \"rolloveAlias\" : {\n" + + " \"met_conditions\" : { },\n" + + " \"time\" : 1\n" + + " }\n" + + " }\n" + + " }\n" + + " },\n" + + " \"index-graveyard\" : {\n" + + " \"tombstones\" : [ ]\n" + + " }\n" + + " }\n" + + "}", Strings.toString(builder)); + } + + + private MetaData buildMetaData() throws IOException { + return MetaData.builder() + .clusterUUID("clusterUUID") + .coordinationMetaData(CoordinationMetaData.builder() + .term(1) + .lastCommittedConfiguration(new CoordinationMetaData.VotingConfiguration(new HashSet<>(){{ + add("commitedConfigurationNodeId"); + }})) + .lastAcceptedConfiguration(new CoordinationMetaData.VotingConfiguration(new HashSet<>(){{ + add("acceptedConfigurationNodeId"); + }})) + .addVotingConfigExclusion(new CoordinationMetaData.VotingConfigExclusion("exlucdedNodeId", "excludedNodeName")) + .build()) + .persistentSettings(Settings.builder() + .put(SETTING_VERSION_CREATED, Version.CURRENT.id).build()) + .transientSettings(Settings.builder() + .put(SETTING_VERSION_CREATED, Version.CURRENT.id).build()) + .put(IndexMetaData.builder("index") + .state(IndexMetaData.State.OPEN) + .settings(Settings.builder() + .put(SETTING_VERSION_CREATED, Version.CURRENT.id)) + .putMapping(new MappingMetaData("type", + new HashMap<>(){{ + put("type1", new HashMap(){{ + put("key", "value"); + }}); + }})) + .putAlias(AliasMetaData.builder("alias") + .indexRouting("indexRouting") + .build()) + .numberOfShards(1) + .primaryTerm(0, 1L) + .putInSyncAllocationIds(0, new HashSet<>(){{ + add("allocationId"); + }}) + .numberOfReplicas(2) + .putRolloverInfo(new RolloverInfo("rolloveAlias", new ArrayList<>(), 1L))) + .put(IndexTemplateMetaData.builder("template") + .patterns(List.of("pattern1", "pattern2")) + .order(0) + .settings(Settings.builder().put(SETTING_VERSION_CREATED, Version.CURRENT.id)) + .putMapping("type", "{ \"key1\": {} }") + .build()) + .build(); + } + + public static class CustomMetaData extends TestCustomMetaData { + public static final String TYPE = "custom_md"; + + CustomMetaData(String data) { + super(data); + } + + @Override + public String getWriteableName() { + return TYPE; + } + + @Override + public Version getMinimalSupportedVersion() { + return Version.CURRENT; + } + + @Override + public EnumSet context() { + return EnumSet.of(MetaData.XContentContext.GATEWAY, MetaData.XContentContext.SNAPSHOT); + } + } } diff --git a/test/framework/src/main/java/org/elasticsearch/test/ESIntegTestCase.java b/test/framework/src/main/java/org/elasticsearch/test/ESIntegTestCase.java index 6175998870b87..321432d0d6620 100644 --- a/test/framework/src/main/java/org/elasticsearch/test/ESIntegTestCase.java +++ b/test/framework/src/main/java/org/elasticsearch/test/ESIntegTestCase.java @@ -102,9 +102,10 @@ import org.elasticsearch.common.xcontent.NamedXContentRegistry; import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.XContentBuilder; +import org.elasticsearch.common.xcontent.XContentHelper; import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.common.xcontent.XContentType; -import org.elasticsearch.common.xcontent.json.JsonXContent; +import org.elasticsearch.common.xcontent.smile.SmileXContent; import org.elasticsearch.core.internal.io.IOUtils; import org.elasticsearch.discovery.Discovery; import org.elasticsearch.discovery.zen.ElectMasterService; @@ -1104,20 +1105,85 @@ protected void ensureClusterStateCanBeReadByNodeTool() throws IOException { if (cluster() != null && cluster().size() > 0) { final Client masterClient = client(); MetaData metaData = masterClient.admin().cluster().prepareState().all().get().getState().metaData(); - final XContentBuilder builder = JsonXContent.contentBuilder(); - builder.startObject(); - metaData.toXContent(builder, ToXContent.EMPTY_PARAMS); - builder.endObject(); - - final MetaData loadedMetaData; - try (XContentParser parser = createParser(ElasticsearchNodeCommand.namedXContentRegistry, - JsonXContent.jsonXContent, BytesReference.bytes(builder))) { - loadedMetaData = MetaData.fromXContent(parser); + final Map serializationParams = new HashMap<>(2); + serializationParams.put("binary", "true"); + serializationParams.put(MetaData.CONTEXT_MODE_PARAM, MetaData.CONTEXT_MODE_GATEWAY); + final ToXContent.Params serializationFormatParams = new ToXContent.MapParams(serializationParams); + + // when comparing XContent output, do not use binary format + final Map compareParams = new HashMap<>(2); + compareParams.put(MetaData.CONTEXT_MODE_PARAM, MetaData.CONTEXT_MODE_GATEWAY); + final ToXContent.Params compareFormatParams = new ToXContent.MapParams(compareParams); + + { + MetaData metaDataWithoutIndices = MetaData.builder(metaData).removeAllIndices().build(); + + XContentBuilder builder = SmileXContent.contentBuilder(); + builder.startObject(); + metaDataWithoutIndices.toXContent(builder, serializationFormatParams); + builder.endObject(); + final BytesReference originalBytes = BytesReference.bytes(builder); + + XContentBuilder compareBuilder = SmileXContent.contentBuilder(); + compareBuilder.startObject(); + metaDataWithoutIndices.toXContent(compareBuilder, compareFormatParams); + compareBuilder.endObject(); + final BytesReference compareOriginalBytes = BytesReference.bytes(compareBuilder); + + final MetaData loadedMetaData; + try (XContentParser parser = createParser(ElasticsearchNodeCommand.namedXContentRegistry, + SmileXContent.smileXContent, originalBytes)) { + loadedMetaData = MetaData.fromXContent(parser); + } + builder = SmileXContent.contentBuilder(); + builder.startObject(); + loadedMetaData.toXContent(builder, compareFormatParams); + builder.endObject(); + final BytesReference parsedBytes = BytesReference.bytes(builder); + + assertNull( + "cluster state XContent serialization does not match, expected " + + XContentHelper.convertToMap(compareOriginalBytes, false, XContentType.SMILE) + + " but got " + + XContentHelper.convertToMap(parsedBytes, false, XContentType.SMILE), + differenceBetweenMapsIgnoringArrayOrder( + XContentHelper.convertToMap(compareOriginalBytes, false, XContentType.SMILE).v2(), + XContentHelper.convertToMap(parsedBytes, false, XContentType.SMILE).v2())); } - assertNull( - "cluster state JSON serialization does not match", - differenceBetweenMapsIgnoringArrayOrder(convertToMap(metaData), convertToMap(loadedMetaData))); + for (IndexMetaData indexMetaData : metaData) { + XContentBuilder builder = SmileXContent.contentBuilder(); + builder.startObject(); + indexMetaData.toXContent(builder, serializationFormatParams); + builder.endObject(); + final BytesReference originalBytes = BytesReference.bytes(builder); + + XContentBuilder compareBuilder = SmileXContent.contentBuilder(); + compareBuilder.startObject(); + indexMetaData.toXContent(compareBuilder, compareFormatParams); + compareBuilder.endObject(); + final BytesReference compareOriginalBytes = BytesReference.bytes(compareBuilder); + + final IndexMetaData loadedIndexMetaData; + try (XContentParser parser = createParser(ElasticsearchNodeCommand.namedXContentRegistry, + SmileXContent.smileXContent, originalBytes)) { + loadedIndexMetaData = IndexMetaData.fromXContent(parser); + } + builder = SmileXContent.contentBuilder(); + builder.startObject(); + loadedIndexMetaData.toXContent(builder, compareFormatParams); + builder.endObject(); + final BytesReference parsedBytes = BytesReference.bytes(builder); + + assertNull( + "cluster state XContent serialization does not match, expected " + + XContentHelper.convertToMap(compareOriginalBytes, false, XContentType.SMILE) + + " but got " + + XContentHelper.convertToMap(parsedBytes, false, XContentType.SMILE), + differenceBetweenMapsIgnoringArrayOrder( + XContentHelper.convertToMap(compareOriginalBytes, false, XContentType.SMILE).v2(), + XContentHelper.convertToMap(parsedBytes, false, XContentType.SMILE).v2())); + } } }