diff --git a/src/Nest/IndexModules/IndexSettings/Settings/FixedIndexSettings.cs b/src/Nest/IndexModules/IndexSettings/Settings/FixedIndexSettings.cs index 3f0a84356f6..1dd037b4301 100644 --- a/src/Nest/IndexModules/IndexSettings/Settings/FixedIndexSettings.cs +++ b/src/Nest/IndexModules/IndexSettings/Settings/FixedIndexSettings.cs @@ -10,6 +10,12 @@ public static class FixedIndexSettings public const string NumberOfShards = "index.number_of_shards"; public const string RoutingPartitionSize = "index.routing_partition_size"; + /// + /// Indicates whether the index should be hidden by default. + /// Hidden indices are not returned by default when using a wildcard expression. + /// + public const string Hidden = "index.hidden"; + /// /// If a field referred to in a percolator query does not exist, /// it will be handled as a default text field so that adding the percolator query doesn't fail. diff --git a/src/Nest/IndexModules/IndexSettings/Settings/IndexSettings.cs b/src/Nest/IndexModules/IndexSettings/Settings/IndexSettings.cs index 69eb8ae2677..2dca0dea11b 100644 --- a/src/Nest/IndexModules/IndexSettings/Settings/IndexSettings.cs +++ b/src/Nest/IndexModules/IndexSettings/Settings/IndexSettings.cs @@ -39,6 +39,12 @@ public interface IIndexSettings : IDynamicIndexSettings /// int? RoutingPartitionSize { get; set; } + /// + /// Indicates whether the index should be hidden by default. + /// Hidden indices are not returned by default when using a wildcard expression. + /// + bool? Hidden { get; set; } + /// /// Settings associated with index sorting. /// https://www.elastic.co/guide/en/elasticsearch/reference/6.0/index-modules-index-sorting.html @@ -71,6 +77,9 @@ public IndexSettings(IDictionary container) : base(container) { /// public int? RoutingPartitionSize { get; set; } + /// + public bool? Hidden { get; set; } + /// public ISortingSettings Sorting { get; set; } @@ -95,6 +104,10 @@ public IndexSettingsDescriptor NumberOfRoutingShards(int? numberOfRoutingShards) public IndexSettingsDescriptor RoutingPartitionSize(int? routingPartitionSize) => Assign(routingPartitionSize, (a, v) => a.RoutingPartitionSize = v); + /// + public IndexSettingsDescriptor Hidden(bool? hidden = true) => + Assign(hidden, (a, v) => a.Hidden = v); + /// public IndexSettingsDescriptor FileSystemStorageImplementation(FileSystemStorageImplementation? fs) => Assign(fs, (a, v) => a.FileSystemStorageImplementation = v); diff --git a/src/Nest/IndexModules/IndexSettings/Settings/IndexSettingsFormatter.cs b/src/Nest/IndexModules/IndexSettings/Settings/IndexSettingsFormatter.cs index 72ed7242591..bb6581c993f 100644 --- a/src/Nest/IndexModules/IndexSettings/Settings/IndexSettingsFormatter.cs +++ b/src/Nest/IndexModules/IndexSettings/Settings/IndexSettingsFormatter.cs @@ -124,6 +124,7 @@ void Set(string knownKey, object newValue) Set(NumberOfShards, indexSettings.NumberOfShards); Set(NumberOfRoutingShards, indexSettings.NumberOfRoutingShards); Set(RoutingPartitionSize, indexSettings.RoutingPartitionSize); + Set(Hidden, indexSettings.Hidden); if (indexSettings.SoftDeletes != null) { #pragma warning disable 618 @@ -159,7 +160,7 @@ private static Dictionary Flatten(Dictionary ori Dictionary current = null ) { - current = current ?? new Dictionary(); + current ??= new Dictionary(); foreach (var property in original) { if (property.Value is Dictionary objects && @@ -251,6 +252,7 @@ private static void SetKnownIndexSettings(ref JsonReader reader, IJsonFormatterR Set(s, settings, NumberOfShards, v => s.NumberOfShards = v, formatterResolver); Set(s, settings, NumberOfRoutingShards, v => s.NumberOfRoutingShards = v, formatterResolver); Set(s, settings, RoutingPartitionSize, v => s.RoutingPartitionSize = v, formatterResolver); + Set(s, settings, Hidden, v => s.Hidden = v, formatterResolver); Set(s, settings, StoreType, v => s.FileSystemStorageImplementation = v, formatterResolver); var sorting = s.Sorting = new SortingSettings(); diff --git a/src/Nest/Indices/AliasManagement/Alias.cs b/src/Nest/Indices/AliasManagement/Alias.cs index 5b0c2b6f962..7a84045779c 100644 --- a/src/Nest/Indices/AliasManagement/Alias.cs +++ b/src/Nest/Indices/AliasManagement/Alias.cs @@ -23,10 +23,21 @@ public interface IAlias [DataMember(Name = "index_routing")] Routing IndexRouting { get; set; } - /// + /// + /// If an alias points to multiple indices, Elasticsearch will reject the write operations + /// unless one is explicitly marked as the write alias using this property. + /// [DataMember(Name = "is_write_index")] bool? IsWriteIndex { get; set; } + /// + /// If true, the alias will be excluded from wildcard expressions by default, unless overriden in the request using + /// the expand_wildcards parameter, similar to hidden indices. + /// This property must be set to the same value on all indices that share an alias. Defaults to false. + /// + [DataMember(Name = "is_hidden")] + bool? IsHidden { get; set; } + /// /// Associates routing values with aliases for both index and search operations. This feature can be used together /// with filtering aliases in order to avoid unnecessary shard operations. @@ -51,6 +62,9 @@ public class Alias : IAlias public Routing IndexRouting { get; set; } /// public bool? IsWriteIndex { get; set; } + /// + public bool? IsHidden { get; set; } + /// public Routing Routing { get; set; } /// @@ -65,6 +79,7 @@ public class AliasDescriptor : DescriptorBase, IAlias bool? IAlias.IsWriteIndex { get; set; } Routing IAlias.Routing { get; set; } Routing IAlias.SearchRouting { get; set; } + bool? IAlias.IsHidden { get; set; } /// public AliasDescriptor Filter(Func, QueryContainer> filterSelector) where T : class => @@ -76,6 +91,9 @@ public AliasDescriptor Filter(Func, QueryContaine /// public AliasDescriptor IsWriteIndex(bool? isWriteIndex = true) => Assign(isWriteIndex, (a, v) => a.IsWriteIndex = v); + /// + public AliasDescriptor IsHidden(bool? isHidden = true) => Assign(isHidden, (a, v) => a.IsHidden = v); + /// public AliasDescriptor Routing(Routing routing) => Assign(routing, (a, v) => a.Routing = v); diff --git a/src/Nest/Indices/AliasManagement/Alias/Actions/AliasAdd.cs b/src/Nest/Indices/AliasManagement/Alias/Actions/AliasAdd.cs index b96cb693987..ecfb83efeb9 100644 --- a/src/Nest/Indices/AliasManagement/Alias/Actions/AliasAdd.cs +++ b/src/Nest/Indices/AliasManagement/Alias/Actions/AliasAdd.cs @@ -22,54 +22,70 @@ public class AliasAddDescriptor : DescriptorBase public AliasAddDescriptor Index(string index) { Self.Add.Index = index; return this; } + /// public AliasAddDescriptor Index(Type index) { Self.Add.Index = index; return this; } + /// public AliasAddDescriptor Index() where T : class { Self.Add.Index = typeof(T); return this; } + /// public AliasAddDescriptor Alias(string alias) { Self.Add.Alias = alias; return this; } + /// public AliasAddDescriptor Routing(string routing) { Self.Add.Routing = routing; return this; } + /// public AliasAddDescriptor IndexRouting(string indexRouting) { Self.Add.IndexRouting = indexRouting; return this; } + /// public AliasAddDescriptor SearchRouting(string searchRouting) { Self.Add.SearchRouting = searchRouting; return this; } + /// public AliasAddDescriptor IsWriteIndex(bool? isWriteIndex = true) { Self.Add.IsWriteIndex = isWriteIndex; return this; } + /// + public AliasAddDescriptor IsHidden(bool? isHidden = true) + { + Self.Add.IsHidden = isHidden; + return this; + } + + /// public AliasAddDescriptor Filter(Func, QueryContainer> filterSelector) where T : class { diff --git a/src/Nest/Indices/AliasManagement/Alias/Actions/AliasAddOperation.cs b/src/Nest/Indices/AliasManagement/Alias/Actions/AliasAddOperation.cs index 2f9652fd77c..6ac5bec12e1 100644 --- a/src/Nest/Indices/AliasManagement/Alias/Actions/AliasAddOperation.cs +++ b/src/Nest/Indices/AliasManagement/Alias/Actions/AliasAddOperation.cs @@ -4,28 +4,42 @@ namespace Nest { public class AliasAddOperation { + /// + /// The name of the alias + /// [DataMember(Name ="alias")] public string Alias { get; set; } + /// + /// Filter query used to limit the index alias. + /// If specified, the index alias only applies to documents returned by the filter. + /// [DataMember(Name ="filter")] public QueryContainer Filter { get; set; } + /// + /// The index to which to add the alias + /// [DataMember(Name ="index")] public IndexName Index { get; set; } + /// [DataMember(Name ="index_routing")] public string IndexRouting { get; set; } - /// - /// If an alias points to multiple indices, Elasticsearch will reject the write operations - /// unless one is explicitly marked as the write alias using this property. - /// + /// [DataMember(Name ="is_write_index")] public bool? IsWriteIndex { get; set; } + /// + [DataMember(Name ="is_hidden")] + public bool? IsHidden { get; set; } + + /// [DataMember(Name ="routing")] public string Routing { get; set; } + /// [DataMember(Name ="search_routing")] public string SearchRouting { get; set; } } diff --git a/tests/Tests/Indices/IndexManagement/CreateIndex/CreateIndexApiTests.cs b/tests/Tests/Indices/IndexManagement/CreateIndex/CreateIndexApiTests.cs index b170a67c1ad..9779d32e19d 100644 --- a/tests/Tests/Indices/IndexManagement/CreateIndex/CreateIndexApiTests.cs +++ b/tests/Tests/Indices/IndexManagement/CreateIndex/CreateIndexApiTests.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using Elastic.Xunit.XunitPlumbing; using Elasticsearch.Net; using FluentAssertions; using Nest; @@ -317,4 +318,90 @@ protected override void ExpectResponse(CreateIndexResponse response) aliases[CallIsolatedValue + "-alias"].IsWriteIndex.Should().BeTrue(); } } + + + [SkipVersion("<7.7.0", "hidden indices and aliases introduced in 7.7.0")] + public class CreateHiddenIndexApiTests + : ApiIntegrationTestBase + { + public CreateHiddenIndexApiTests(WritableCluster cluster, EndpointUsage usage) : base(cluster, usage) { } + + protected override bool ExpectIsValid => true; + + protected override object ExpectJson => new + { + settings = new Dictionary + { + { "index.number_of_replicas", 0 }, + { "index.number_of_shards", 1 }, + { "index.hidden", true } + }, + aliases = new Dictionary + { + { CallIsolatedValue + "-alias", new { is_write_index = true, is_hidden = true } } + } + }; + + protected override int ExpectStatusCode => 200; + + protected override Func Fluent => d => d + .Settings(s => s + .NumberOfReplicas(0) + .NumberOfShards(1) + .Hidden() + ) + .Aliases(a => a + .Alias(CallIsolatedValue + "-alias", aa => aa + .IsWriteIndex() + .IsHidden() + ) + ); + + protected override HttpMethod HttpMethod => HttpMethod.PUT; + + protected override CreateIndexRequest Initializer => new CreateIndexRequest(CallIsolatedValue) + { + Settings = new Nest.IndexSettings + { + NumberOfReplicas = 0, + NumberOfShards = 1, + Hidden = true + }, + Aliases = new Aliases + { + { CallIsolatedValue + "-alias", new Alias { IsWriteIndex = true, IsHidden = true} } + } + }; + + protected override string UrlPath => $"/{CallIsolatedValue}"; + + protected override LazyResponses ClientUsage() => Calls( + (client, f) => client.Indices.Create(CallIsolatedValue, f), + (client, f) => client.Indices.CreateAsync(CallIsolatedValue, f), + (client, r) => client.Indices.Create(r), + (client, r) => client.Indices.CreateAsync(r) + ); + + protected override CreateIndexDescriptor NewDescriptor() => new CreateIndexDescriptor(CallIsolatedValue); + + protected override void ExpectResponse(CreateIndexResponse response) + { + response.ShouldBeValid(); + response.Acknowledged.Should().BeTrue(); + response.ShardsAcknowledged.Should().BeTrue(); + + var indexResponse = Client.Indices.Get(CallIsolatedValue); + + indexResponse.ShouldBeValid(); + indexResponse.Indices.Should().NotBeEmpty().And.ContainKey(CallIsolatedValue); + var index = indexResponse.Indices[CallIsolatedValue]; + + index.Settings.Hidden.Should().BeTrue(); + + var aliases = indexResponse.Indices[CallIsolatedValue].Aliases; + aliases.Count.Should().Be(1); + aliases[CallIsolatedValue + "-alias"].IsWriteIndex.Should().BeTrue(); + aliases[CallIsolatedValue + "-alias"].IsHidden.Should().BeTrue(); + } + } }