|
@@ -20,33 +20,50 @@
|
|
|
package org.elasticsearch.action.admin.indices.get;
|
|
|
|
|
|
import com.carrotsearch.hppc.cursors.ObjectObjectCursor;
|
|
|
+import org.apache.lucene.util.CollectionUtil;
|
|
|
+import org.elasticsearch.Version;
|
|
|
import org.elasticsearch.action.ActionResponse;
|
|
|
import org.elasticsearch.cluster.metadata.AliasMetaData;
|
|
|
import org.elasticsearch.cluster.metadata.MappingMetaData;
|
|
|
+import org.elasticsearch.common.Strings;
|
|
|
import org.elasticsearch.common.collect.ImmutableOpenMap;
|
|
|
import org.elasticsearch.common.io.stream.StreamInput;
|
|
|
import org.elasticsearch.common.io.stream.StreamOutput;
|
|
|
import org.elasticsearch.common.settings.Settings;
|
|
|
+import org.elasticsearch.common.xcontent.ToXContentObject;
|
|
|
+import org.elasticsearch.common.xcontent.XContentBuilder;
|
|
|
+import org.elasticsearch.common.xcontent.XContentParser;
|
|
|
+import org.elasticsearch.common.xcontent.XContentParser.Token;
|
|
|
|
|
|
import java.io.IOException;
|
|
|
import java.util.ArrayList;
|
|
|
+import java.util.Arrays;
|
|
|
import java.util.Collections;
|
|
|
+import java.util.Comparator;
|
|
|
import java.util.List;
|
|
|
+import java.util.Objects;
|
|
|
+
|
|
|
+import static org.elasticsearch.common.xcontent.XContentParserUtils.ensureExpectedToken;
|
|
|
|
|
|
/**
|
|
|
- * A response for a delete index action.
|
|
|
+ * A response for a get index action.
|
|
|
*/
|
|
|
-public class GetIndexResponse extends ActionResponse {
|
|
|
+public class GetIndexResponse extends ActionResponse implements ToXContentObject {
|
|
|
|
|
|
private ImmutableOpenMap<String, ImmutableOpenMap<String, MappingMetaData>> mappings = ImmutableOpenMap.of();
|
|
|
private ImmutableOpenMap<String, List<AliasMetaData>> aliases = ImmutableOpenMap.of();
|
|
|
private ImmutableOpenMap<String, Settings> settings = ImmutableOpenMap.of();
|
|
|
+ private ImmutableOpenMap<String, Settings> defaultSettings = ImmutableOpenMap.of();
|
|
|
private String[] indices;
|
|
|
|
|
|
GetIndexResponse(String[] indices,
|
|
|
- ImmutableOpenMap<String, ImmutableOpenMap<String, MappingMetaData>> mappings,
|
|
|
- ImmutableOpenMap<String, List<AliasMetaData>> aliases, ImmutableOpenMap<String, Settings> settings) {
|
|
|
+ ImmutableOpenMap<String, ImmutableOpenMap<String, MappingMetaData>> mappings,
|
|
|
+ ImmutableOpenMap<String, List<AliasMetaData>> aliases,
|
|
|
+ ImmutableOpenMap<String, Settings> settings,
|
|
|
+ ImmutableOpenMap<String, Settings> defaultSettings) {
|
|
|
this.indices = indices;
|
|
|
+ // to have deterministic order
|
|
|
+ Arrays.sort(indices);
|
|
|
if (mappings != null) {
|
|
|
this.mappings = mappings;
|
|
|
}
|
|
@@ -56,6 +73,9 @@ public class GetIndexResponse extends ActionResponse {
|
|
|
if (settings != null) {
|
|
|
this.settings = settings;
|
|
|
}
|
|
|
+ if (defaultSettings != null) {
|
|
|
+ this.defaultSettings = defaultSettings;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
GetIndexResponse() {
|
|
@@ -89,14 +109,51 @@ public class GetIndexResponse extends ActionResponse {
|
|
|
return settings;
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * If the originating {@link GetIndexRequest} object was configured to include
|
|
|
+ * defaults, this will contain a mapping of index name to {@link Settings} objects.
|
|
|
+ * The returned {@link Settings} objects will contain only those settings taking
|
|
|
+ * effect as defaults. Any settings explicitly set on the index will be available
|
|
|
+ * via {@link #settings()}.
|
|
|
+ * See also {@link GetIndexRequest#includeDefaults(boolean)}
|
|
|
+ */
|
|
|
+ public ImmutableOpenMap<String, Settings> defaultSettings() {
|
|
|
+ return defaultSettings;
|
|
|
+ }
|
|
|
+
|
|
|
public ImmutableOpenMap<String, Settings> getSettings() {
|
|
|
return settings();
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Returns the string value for the specified index and setting. If the includeDefaults flag was not set or set to
|
|
|
+ * false on the {@link GetIndexRequest}, this method will only return a value where the setting was explicitly set
|
|
|
+ * on the index. If the includeDefaults flag was set to true on the {@link GetIndexRequest}, this method will fall
|
|
|
+ * back to return the default value if the setting was not explicitly set.
|
|
|
+ */
|
|
|
+ public String getSetting(String index, String setting) {
|
|
|
+ Settings indexSettings = settings.get(index);
|
|
|
+ if (setting != null) {
|
|
|
+ if (indexSettings != null && indexSettings.hasValue(setting)) {
|
|
|
+ return indexSettings.get(setting);
|
|
|
+ } else {
|
|
|
+ Settings defaultIndexSettings = defaultSettings.get(index);
|
|
|
+ if (defaultIndexSettings != null) {
|
|
|
+ return defaultIndexSettings.get(setting);
|
|
|
+ } else {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
@Override
|
|
|
public void readFrom(StreamInput in) throws IOException {
|
|
|
super.readFrom(in);
|
|
|
this.indices = in.readStringArray();
|
|
|
+
|
|
|
int mappingsSize = in.readVInt();
|
|
|
ImmutableOpenMap.Builder<String, ImmutableOpenMap<String, MappingMetaData>> mappingsMapBuilder = ImmutableOpenMap.builder();
|
|
|
for (int i = 0; i < mappingsSize; i++) {
|
|
@@ -109,6 +166,7 @@ public class GetIndexResponse extends ActionResponse {
|
|
|
mappingsMapBuilder.put(key, mappingEntryBuilder.build());
|
|
|
}
|
|
|
mappings = mappingsMapBuilder.build();
|
|
|
+
|
|
|
int aliasesSize = in.readVInt();
|
|
|
ImmutableOpenMap.Builder<String, List<AliasMetaData>> aliasesMapBuilder = ImmutableOpenMap.builder();
|
|
|
for (int i = 0; i < aliasesSize; i++) {
|
|
@@ -121,6 +179,7 @@ public class GetIndexResponse extends ActionResponse {
|
|
|
aliasesMapBuilder.put(key, Collections.unmodifiableList(aliasEntryBuilder));
|
|
|
}
|
|
|
aliases = aliasesMapBuilder.build();
|
|
|
+
|
|
|
int settingsSize = in.readVInt();
|
|
|
ImmutableOpenMap.Builder<String, Settings> settingsMapBuilder = ImmutableOpenMap.builder();
|
|
|
for (int i = 0; i < settingsSize; i++) {
|
|
@@ -128,6 +187,15 @@ public class GetIndexResponse extends ActionResponse {
|
|
|
settingsMapBuilder.put(key, Settings.readSettingsFromStream(in));
|
|
|
}
|
|
|
settings = settingsMapBuilder.build();
|
|
|
+
|
|
|
+ ImmutableOpenMap.Builder<String, Settings> defaultSettingsMapBuilder = ImmutableOpenMap.builder();
|
|
|
+ if (in.getVersion().onOrAfter(Version.V_6_4_0)) {
|
|
|
+ int defaultSettingsSize = in.readVInt();
|
|
|
+ for (int i = 0; i < defaultSettingsSize ; i++) {
|
|
|
+ defaultSettingsMapBuilder.put(in.readString(), Settings.readSettingsFromStream(in));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ defaultSettings = defaultSettingsMapBuilder.build();
|
|
|
}
|
|
|
|
|
|
@Override
|
|
@@ -156,5 +224,202 @@ public class GetIndexResponse extends ActionResponse {
|
|
|
out.writeString(indexEntry.key);
|
|
|
Settings.writeSettingsToStream(indexEntry.value, out);
|
|
|
}
|
|
|
+ if (out.getVersion().onOrAfter(Version.V_6_4_0)) {
|
|
|
+ out.writeVInt(defaultSettings.size());
|
|
|
+ for (ObjectObjectCursor<String, Settings> indexEntry : defaultSettings) {
|
|
|
+ out.writeString(indexEntry.key);
|
|
|
+ Settings.writeSettingsToStream(indexEntry.value, out);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
|
|
+ builder.startObject();
|
|
|
+ {
|
|
|
+ for (final String index : indices) {
|
|
|
+ builder.startObject(index);
|
|
|
+ {
|
|
|
+ builder.startObject("aliases");
|
|
|
+ List<AliasMetaData> indexAliases = aliases.get(index);
|
|
|
+ if (indexAliases != null) {
|
|
|
+ for (final AliasMetaData alias : indexAliases) {
|
|
|
+ AliasMetaData.Builder.toXContent(alias, builder, params);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ builder.endObject();
|
|
|
+
|
|
|
+ builder.startObject("mappings");
|
|
|
+ ImmutableOpenMap<String, MappingMetaData> indexMappings = mappings.get(index);
|
|
|
+ if (indexMappings != null) {
|
|
|
+ for (final ObjectObjectCursor<String, MappingMetaData> typeEntry : indexMappings) {
|
|
|
+ builder.field(typeEntry.key);
|
|
|
+ builder.map(typeEntry.value.sourceAsMap());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ builder.endObject();
|
|
|
+
|
|
|
+ builder.startObject("settings");
|
|
|
+ Settings indexSettings = settings.get(index);
|
|
|
+ if (indexSettings != null) {
|
|
|
+ indexSettings.toXContent(builder, params);
|
|
|
+ }
|
|
|
+ builder.endObject();
|
|
|
+
|
|
|
+ Settings defaultIndexSettings = defaultSettings.get(index);
|
|
|
+ if (defaultIndexSettings != null && defaultIndexSettings.isEmpty() == false) {
|
|
|
+ builder.startObject("defaults");
|
|
|
+ defaultIndexSettings.toXContent(builder, params);
|
|
|
+ builder.endObject();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ builder.endObject();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ builder.endObject();
|
|
|
+ return builder;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static List<AliasMetaData> parseAliases(XContentParser parser) throws IOException {
|
|
|
+ List<AliasMetaData> indexAliases = new ArrayList<>();
|
|
|
+ // We start at START_OBJECT since parseIndexEntry ensures that
|
|
|
+ while (parser.nextToken() != Token.END_OBJECT) {
|
|
|
+ ensureExpectedToken(Token.FIELD_NAME, parser.currentToken(), parser::getTokenLocation);
|
|
|
+ indexAliases.add(AliasMetaData.Builder.fromXContent(parser));
|
|
|
+ }
|
|
|
+ return indexAliases;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static ImmutableOpenMap<String, MappingMetaData> parseMappings(XContentParser parser) throws IOException {
|
|
|
+ ImmutableOpenMap.Builder<String, MappingMetaData> indexMappings = ImmutableOpenMap.builder();
|
|
|
+ // We start at START_OBJECT since parseIndexEntry ensures that
|
|
|
+ while (parser.nextToken() != Token.END_OBJECT) {
|
|
|
+ ensureExpectedToken(Token.FIELD_NAME, parser.currentToken(), parser::getTokenLocation);
|
|
|
+ parser.nextToken();
|
|
|
+ if (parser.currentToken() == Token.START_OBJECT) {
|
|
|
+ String mappingType = parser.currentName();
|
|
|
+ indexMappings.put(mappingType, new MappingMetaData(mappingType, parser.map()));
|
|
|
+ } else if (parser.currentToken() == Token.START_ARRAY) {
|
|
|
+ parser.skipChildren();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return indexMappings.build();
|
|
|
+ }
|
|
|
+
|
|
|
+ private static IndexEntry parseIndexEntry(XContentParser parser) throws IOException {
|
|
|
+ List<AliasMetaData> indexAliases = null;
|
|
|
+ ImmutableOpenMap<String, MappingMetaData> indexMappings = null;
|
|
|
+ Settings indexSettings = null;
|
|
|
+ Settings indexDefaultSettings = null;
|
|
|
+ // We start at START_OBJECT since fromXContent ensures that
|
|
|
+ while (parser.nextToken() != Token.END_OBJECT) {
|
|
|
+ ensureExpectedToken(Token.FIELD_NAME, parser.currentToken(), parser::getTokenLocation);
|
|
|
+ parser.nextToken();
|
|
|
+ if (parser.currentToken() == Token.START_OBJECT) {
|
|
|
+ switch (parser.currentName()) {
|
|
|
+ case "aliases":
|
|
|
+ indexAliases = parseAliases(parser);
|
|
|
+ break;
|
|
|
+ case "mappings":
|
|
|
+ indexMappings = parseMappings(parser);
|
|
|
+ break;
|
|
|
+ case "settings":
|
|
|
+ indexSettings = Settings.fromXContent(parser);
|
|
|
+ break;
|
|
|
+ case "defaults":
|
|
|
+ indexDefaultSettings = Settings.fromXContent(parser);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ parser.skipChildren();
|
|
|
+ }
|
|
|
+ } else if (parser.currentToken() == Token.START_ARRAY) {
|
|
|
+ parser.skipChildren();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return new IndexEntry(indexAliases, indexMappings, indexSettings, indexDefaultSettings);
|
|
|
+ }
|
|
|
+
|
|
|
+ // This is just an internal container to make stuff easier for returning
|
|
|
+ private static class IndexEntry {
|
|
|
+ List<AliasMetaData> indexAliases = new ArrayList<>();
|
|
|
+ ImmutableOpenMap<String, MappingMetaData> indexMappings = ImmutableOpenMap.of();
|
|
|
+ Settings indexSettings = Settings.EMPTY;
|
|
|
+ Settings indexDefaultSettings = Settings.EMPTY;
|
|
|
+ IndexEntry(List<AliasMetaData> indexAliases, ImmutableOpenMap<String, MappingMetaData> indexMappings,
|
|
|
+ Settings indexSettings, Settings indexDefaultSettings) {
|
|
|
+ if (indexAliases != null) this.indexAliases = indexAliases;
|
|
|
+ if (indexMappings != null) this.indexMappings = indexMappings;
|
|
|
+ if (indexSettings != null) this.indexSettings = indexSettings;
|
|
|
+ if (indexDefaultSettings != null) this.indexDefaultSettings = indexDefaultSettings;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public static GetIndexResponse fromXContent(XContentParser parser) throws IOException {
|
|
|
+ ImmutableOpenMap.Builder<String, List<AliasMetaData>> aliases = ImmutableOpenMap.builder();
|
|
|
+ ImmutableOpenMap.Builder<String, ImmutableOpenMap<String, MappingMetaData>> mappings = ImmutableOpenMap.builder();
|
|
|
+ ImmutableOpenMap.Builder<String, Settings> settings = ImmutableOpenMap.builder();
|
|
|
+ ImmutableOpenMap.Builder<String, Settings> defaultSettings = ImmutableOpenMap.builder();
|
|
|
+ List<String> indices = new ArrayList<>();
|
|
|
+
|
|
|
+ if (parser.currentToken() == null) {
|
|
|
+ parser.nextToken();
|
|
|
+ }
|
|
|
+ ensureExpectedToken(Token.START_OBJECT, parser.currentToken(), parser::getTokenLocation);
|
|
|
+ parser.nextToken();
|
|
|
+
|
|
|
+ while (!parser.isClosed()) {
|
|
|
+ if (parser.currentToken() == Token.START_OBJECT) {
|
|
|
+ // we assume this is an index entry
|
|
|
+ String indexName = parser.currentName();
|
|
|
+ indices.add(indexName);
|
|
|
+ IndexEntry indexEntry = parseIndexEntry(parser);
|
|
|
+ // make the order deterministic
|
|
|
+ CollectionUtil.timSort(indexEntry.indexAliases, Comparator.comparing(AliasMetaData::alias));
|
|
|
+ aliases.put(indexName, Collections.unmodifiableList(indexEntry.indexAliases));
|
|
|
+ mappings.put(indexName, indexEntry.indexMappings);
|
|
|
+ settings.put(indexName, indexEntry.indexSettings);
|
|
|
+ if (indexEntry.indexDefaultSettings.isEmpty() == false) {
|
|
|
+ defaultSettings.put(indexName, indexEntry.indexDefaultSettings);
|
|
|
+ }
|
|
|
+ } else if (parser.currentToken() == Token.START_ARRAY) {
|
|
|
+ parser.skipChildren();
|
|
|
+ } else {
|
|
|
+ parser.nextToken();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return
|
|
|
+ new GetIndexResponse(
|
|
|
+ indices.toArray(new String[0]), mappings.build(), aliases.build(),
|
|
|
+ settings.build(), defaultSettings.build()
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public String toString() {
|
|
|
+ return Strings.toString(this);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public boolean equals(Object o) {
|
|
|
+ if (this == o) return true;
|
|
|
+ if (o== null || getClass() != o.getClass()) return false;
|
|
|
+ GetIndexResponse that = (GetIndexResponse) o;
|
|
|
+ return Arrays.equals(indices, that.indices) &&
|
|
|
+ Objects.equals(aliases, that.aliases) &&
|
|
|
+ Objects.equals(mappings, that.mappings) &&
|
|
|
+ Objects.equals(settings, that.settings) &&
|
|
|
+ Objects.equals(defaultSettings, that.defaultSettings);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public int hashCode() {
|
|
|
+ return
|
|
|
+ Objects.hash(
|
|
|
+ Arrays.hashCode(indices),
|
|
|
+ aliases,
|
|
|
+ mappings,
|
|
|
+ settings,
|
|
|
+ defaultSettings
|
|
|
+ );
|
|
|
}
|
|
|
}
|