Skip to content

Commit aefc43d

Browse files
authored
Add indices resolve index API (#4874)
This commit adds the indices resolve index API to the high level client.
1 parent 6b3aed2 commit aefc43d

File tree

9 files changed

+280
-1
lines changed

9 files changed

+280
-1
lines changed

src/ApiGenerator/Configuration/CodeConfiguration.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ public static class CodeConfiguration
3636

3737
public static string[] IgnoredApisHighLevel { get; } =
3838
{
39-
"indices.resolve_index.json", // TODO: implement
4039
"security.clear_cached_privileges.json", // TODO: implement
4140

4241
"autoscaling.get_autoscaling_decision.json", // 7.7 experimental

src/Nest/Descriptors.Indices.cs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1105,6 +1105,29 @@ public ReloadSearchAnalyzersDescriptor Index<TOther>()
11051105
public ReloadSearchAnalyzersDescriptor IgnoreUnavailable(bool? ignoreunavailable = true) => Qs("ignore_unavailable", ignoreunavailable);
11061106
}
11071107

1108+
///<summary>Descriptor for Resolve <para>https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-resolve-index.html</para></summary>
1109+
public partial class ResolveIndexDescriptor : RequestDescriptorBase<ResolveIndexDescriptor, ResolveIndexRequestParameters, IResolveIndexRequest>, IResolveIndexRequest
1110+
{
1111+
internal override ApiUrls ApiUrls => ApiUrlsLookups.IndicesResolve;
1112+
///<summary>/_resolve/index/{name}</summary>
1113+
///<param name = "name">this parameter is required</param>
1114+
public ResolveIndexDescriptor(Names name): base(r => r.Required("name", name))
1115+
{
1116+
}
1117+
1118+
///<summary>Used for serialization purposes, making sure we have a parameterless constructor</summary>
1119+
[SerializationConstructor]
1120+
protected ResolveIndexDescriptor(): base()
1121+
{
1122+
}
1123+
1124+
// values part of the url path
1125+
Names IResolveIndexRequest.Name => Self.RouteValues.Get<Names>("name");
1126+
// Request parameters
1127+
///<summary>Whether wildcard expressions should get expanded to open or closed indices (default: open)</summary>
1128+
public ResolveIndexDescriptor ExpandWildcards(ExpandWildcards? expandwildcards) => Qs("expand_wildcards", expandwildcards);
1129+
}
1130+
11081131
///<summary>Descriptor for Rollover <para>https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-rollover-index.html</para></summary>
11091132
public partial class RolloverIndexDescriptor : RequestDescriptorBase<RolloverIndexDescriptor, RolloverIndexRequestParameters, IRolloverIndexRequest>, IRolloverIndexRequest
11101133
{

src/Nest/ElasticClient.Indices.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -739,6 +739,30 @@ public Task<PutMappingResponse> PutMappingAsync<TDocument>(Func<PutMappingDescri
739739
/// </summary>
740740
public Task<ReloadSearchAnalyzersResponse> ReloadSearchAnalyzersAsync(IReloadSearchAnalyzersRequest request, CancellationToken ct = default) => DoRequestAsync<IReloadSearchAnalyzersRequest, ReloadSearchAnalyzersResponse>(request, request.RequestParameters, ct);
741741
/// <summary>
742+
/// <c>GET</c> request to the <c>indices.resolve_index</c> API, read more about this API online:
743+
/// <para></para>
744+
/// <a href = "https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-resolve-index.html">https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-resolve-index.html</a>
745+
/// </summary>
746+
public ResolveIndexResponse Resolve(Names name, Func<ResolveIndexDescriptor, IResolveIndexRequest> selector = null) => Resolve(selector.InvokeOrDefault(new ResolveIndexDescriptor(name: name)));
747+
/// <summary>
748+
/// <c>GET</c> request to the <c>indices.resolve_index</c> API, read more about this API online:
749+
/// <para></para>
750+
/// <a href = "https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-resolve-index.html">https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-resolve-index.html</a>
751+
/// </summary>
752+
public Task<ResolveIndexResponse> ResolveAsync(Names name, Func<ResolveIndexDescriptor, IResolveIndexRequest> selector = null, CancellationToken ct = default) => ResolveAsync(selector.InvokeOrDefault(new ResolveIndexDescriptor(name: name)), ct);
753+
/// <summary>
754+
/// <c>GET</c> request to the <c>indices.resolve_index</c> API, read more about this API online:
755+
/// <para></para>
756+
/// <a href = "https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-resolve-index.html">https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-resolve-index.html</a>
757+
/// </summary>
758+
public ResolveIndexResponse Resolve(IResolveIndexRequest request) => DoRequest<IResolveIndexRequest, ResolveIndexResponse>(request, request.RequestParameters);
759+
/// <summary>
760+
/// <c>GET</c> request to the <c>indices.resolve_index</c> API, read more about this API online:
761+
/// <para></para>
762+
/// <a href = "https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-resolve-index.html">https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-resolve-index.html</a>
763+
/// </summary>
764+
public Task<ResolveIndexResponse> ResolveAsync(IResolveIndexRequest request, CancellationToken ct = default) => DoRequestAsync<IResolveIndexRequest, ResolveIndexResponse>(request, request.RequestParameters, ct);
765+
/// <summary>
742766
/// <c>POST</c> request to the <c>indices.rollover</c> API, read more about this API online:
743767
/// <para></para>
744768
/// <a href = "https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-rollover-index.html">https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-rollover-index.html</a>
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Licensed to Elasticsearch B.V under one or more agreements.
2+
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
3+
// See the LICENSE file in the project root for more information
4+
5+
namespace Nest
6+
{
7+
/// <summary>
8+
/// A request to the resolve index API
9+
/// </summary>
10+
[MapsApi("indices.resolve_index.json")]
11+
[ReadAs(typeof(ResolveIndexRequest))]
12+
public partial interface IResolveIndexRequest
13+
{
14+
}
15+
16+
/// <inheritdoc cref="IResolveIndexRequest" />
17+
public partial class ResolveIndexRequest
18+
{
19+
}
20+
21+
/// <inheritdoc cref="IResolveIndexRequest" />
22+
public partial class ResolveIndexDescriptor
23+
{
24+
}
25+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// Licensed to Elasticsearch B.V under one or more agreements.
2+
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
3+
// See the LICENSE file in the project root for more information
4+
5+
using System.Collections.Generic;
6+
using System.Runtime.Serialization;
7+
using Elasticsearch.Net;
8+
9+
namespace Nest
10+
{
11+
public class ResolveIndexResponse : ResponseBase
12+
{
13+
[DataMember(Name = "indices")]
14+
public IReadOnlyCollection<ResolvedIndex> Indices { get; internal set; } = EmptyReadOnly<ResolvedIndex>.Collection;
15+
16+
[DataMember(Name = "aliases")]
17+
public IReadOnlyCollection<ResolvedAlias> Aliases { get; internal set; } = EmptyReadOnly<ResolvedAlias>.Collection;
18+
19+
[DataMember(Name = "data_streams")]
20+
public IReadOnlyCollection<ResolvedDataStream> DataStreams { get; internal set; } = EmptyReadOnly<ResolvedDataStream>.Collection;
21+
}
22+
23+
public class ResolvedIndex
24+
{
25+
[DataMember(Name = "name")]
26+
public string Name { get; internal set; }
27+
28+
[DataMember(Name = "aliases")]
29+
public IReadOnlyCollection<string> Aliases { get; internal set; }
30+
31+
[DataMember(Name = "attributes")]
32+
public IReadOnlyCollection<string> Attributes { get; internal set; }
33+
34+
[DataMember(Name = "data_stream")]
35+
public string DataStream { get; internal set; }
36+
}
37+
38+
public class ResolvedAlias
39+
{
40+
[DataMember(Name = "name")]
41+
public string Name { get; internal set; }
42+
43+
[DataMember(Name = "indices")]
44+
public IReadOnlyCollection<string> Indices { get; internal set; }
45+
}
46+
47+
public class ResolvedDataStream
48+
{
49+
[DataMember(Name = "name")]
50+
public string Name { get; internal set; }
51+
52+
[DataMember(Name = "backing_indices")]
53+
public IReadOnlyCollection<string> BackingIndices { get; internal set; }
54+
55+
[DataMember(Name = "timestamp_field")]
56+
public string TimestampField { get; internal set; }
57+
}
58+
}

src/Nest/Requests.Indices.cs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2006,6 +2006,46 @@ public bool? IgnoreUnavailable
20062006
}
20072007
}
20082008

2009+
[InterfaceDataContract]
2010+
public partial interface IResolveIndexRequest : IRequest<ResolveIndexRequestParameters>
2011+
{
2012+
[IgnoreDataMember]
2013+
Names Name
2014+
{
2015+
get;
2016+
}
2017+
}
2018+
2019+
///<summary>Request for Resolve <para>https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-resolve-index.html</para></summary>
2020+
///<remarks>Note: Experimental within the Elasticsearch server, this functionality is experimental and may be changed or removed completely in a future release. Elastic will take a best effort approach to fix any issues, but experimental features are not subject to the support SLA of official GA features.</remarks>
2021+
public partial class ResolveIndexRequest : PlainRequestBase<ResolveIndexRequestParameters>, IResolveIndexRequest
2022+
{
2023+
protected IResolveIndexRequest Self => this;
2024+
internal override ApiUrls ApiUrls => ApiUrlsLookups.IndicesResolve;
2025+
///<summary>/_resolve/index/{name}</summary>
2026+
///<param name = "name">this parameter is required</param>
2027+
public ResolveIndexRequest(Names name): base(r => r.Required("name", name))
2028+
{
2029+
}
2030+
2031+
///<summary>Used for serialization purposes, making sure we have a parameterless constructor</summary>
2032+
[SerializationConstructor]
2033+
protected ResolveIndexRequest(): base()
2034+
{
2035+
}
2036+
2037+
// values part of the url path
2038+
[IgnoreDataMember]
2039+
Names IResolveIndexRequest.Name => Self.RouteValues.Get<Names>("name");
2040+
// Request parameters
2041+
///<summary>Whether wildcard expressions should get expanded to open or closed indices (default: open)</summary>
2042+
public ExpandWildcards? ExpandWildcards
2043+
{
2044+
get => Q<ExpandWildcards? >("expand_wildcards");
2045+
set => Q("expand_wildcards", value);
2046+
}
2047+
}
2048+
20092049
[InterfaceDataContract]
20102050
public partial interface IRolloverIndexRequest : IRequest<RolloverIndexRequestParameters>
20112051
{

src/Nest/_Generated/ApiUrlsLookup.generated.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ internal static class ApiUrlsLookups
134134
internal static ApiUrls IndicesRecoveryStatus = new ApiUrls(new[]{"_recovery", "{index}/_recovery"});
135135
internal static ApiUrls IndicesRefresh = new ApiUrls(new[]{"_refresh", "{index}/_refresh"});
136136
internal static ApiUrls IndicesReloadSearchAnalyzers = new ApiUrls(new[]{"{index}/_reload_search_analyzers"});
137+
internal static ApiUrls IndicesResolve = new ApiUrls(new[]{"_resolve/index/{name}"});
137138
internal static ApiUrls IndicesRollover = new ApiUrls(new[]{"{alias}/_rollover", "{alias}/_rollover/{new_index}"});
138139
internal static ApiUrls IndicesSegments = new ApiUrls(new[]{"_segments", "{index}/_segments"});
139140
internal static ApiUrls IndicesShardStores = new ApiUrls(new[]{"_shard_stores", "{index}/_shard_stores"});
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
// Licensed to Elasticsearch B.V under one or more agreements.
2+
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
3+
// See the LICENSE file in the project root for more information
4+
5+
using System;
6+
using System.Collections.Generic;
7+
using System.Linq;
8+
using Elastic.Elasticsearch.Xunit.XunitPlumbing;
9+
using Elasticsearch.Net;
10+
using FluentAssertions;
11+
using Nest;
12+
using Tests.Core.Extensions;
13+
using Tests.Core.ManagedElasticsearch.Clusters;
14+
using Tests.Framework.EndpointTests;
15+
using Tests.Framework.EndpointTests.TestState;
16+
17+
namespace Tests.Indices.IndexManagement.ResolveIndex
18+
{
19+
[SkipVersion("<7.9.0", "resolve index introduced in 7.9.0")]
20+
public class ResolveIndexApiTests
21+
: ApiIntegrationTestBase<WritableCluster, ResolveIndexResponse, IResolveIndexRequest, ResolveIndexDescriptor, ResolveIndexRequest>
22+
{
23+
public ResolveIndexApiTests(WritableCluster cluster, EndpointUsage usage) : base(cluster, usage) { }
24+
25+
protected override void IntegrationSetup(IElasticClient client, CallUniqueValues values)
26+
{
27+
foreach (var value in values)
28+
{
29+
var createIndexResponse = client.Indices.Create(value.Value, c => c
30+
.Settings(s => s
31+
.NumberOfShards(1)
32+
.NumberOfReplicas(0)
33+
)
34+
.Aliases(a => a
35+
.Alias(value.Value + "-alias")
36+
)
37+
);
38+
39+
if (!createIndexResponse.IsValid)
40+
throw new Exception($"exception whilst setting up integration test: {createIndexResponse.DebugInformation}");
41+
42+
var clusterResponse = client.Cluster.Health(value.Value, c => c.WaitForStatus(WaitForStatus.Green));
43+
44+
if (!clusterResponse.IsValid)
45+
throw new Exception($"exception whilst setting up integration test: {clusterResponse.DebugInformation}");
46+
}
47+
}
48+
49+
protected override bool ExpectIsValid => true;
50+
51+
protected override int ExpectStatusCode => 200;
52+
53+
protected override Func<ResolveIndexDescriptor, IResolveIndexRequest> Fluent => d => d;
54+
55+
protected override HttpMethod HttpMethod => HttpMethod.GET;
56+
57+
protected override ResolveIndexRequest Initializer => new ResolveIndexRequest($"{CallIsolatedValue}*");
58+
59+
protected override string UrlPath => $"/_resolve/index/{CallIsolatedValue}%2A";
60+
61+
protected override LazyResponses ClientUsage() => Calls(
62+
(client, f) => client.Indices.Resolve($"{CallIsolatedValue}*", f),
63+
(client, f) => client.Indices.ResolveAsync($"{CallIsolatedValue}*", f),
64+
(client, r) => client.Indices.Resolve(r),
65+
(client, r) => client.Indices.ResolveAsync(r)
66+
);
67+
68+
protected override ResolveIndexDescriptor NewDescriptor() => new ResolveIndexDescriptor($"{CallIsolatedValue}*");
69+
70+
protected override void ExpectResponse(ResolveIndexResponse response)
71+
{
72+
response.ShouldBeValid();
73+
response.Indices.Should().HaveCount(1);
74+
var resolvedIndex = response.Indices.First();
75+
resolvedIndex.Name.Should().Be(CallIsolatedValue);
76+
resolvedIndex.Aliases.Should().Contain(CallIsolatedValue + "-alias");
77+
resolvedIndex.Attributes.Should().Contain("open");
78+
var resolvedAlias = response.Aliases.First();
79+
resolvedAlias.Name.Should().Be(CallIsolatedValue + "-alias");
80+
resolvedAlias.Indices.Should().Contain(CallIsolatedValue);
81+
}
82+
}
83+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Licensed to Elasticsearch B.V under one or more agreements.
2+
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
3+
// See the LICENSE file in the project root for more information
4+
5+
using System.Threading.Tasks;
6+
using Elastic.Elasticsearch.Xunit.XunitPlumbing;
7+
using Nest;
8+
using Tests.Framework.EndpointTests;
9+
using static Tests.Framework.EndpointTests.UrlTester;
10+
11+
namespace Tests.Indices.IndexManagement.ResolveIndex
12+
{
13+
public class ResolveIndexUrlTests
14+
{
15+
[U] public async Task Urls()
16+
{
17+
var index = "index1";
18+
await GET($"/_resolve/index/{index}")
19+
.Fluent(c => c.Indices.Resolve(index))
20+
.Request(c => c.Indices.Resolve(new ResolveIndexRequest(index)))
21+
.FluentAsync(c => c.Indices.ResolveAsync(index))
22+
.RequestAsync(c => c.Indices.ResolveAsync(new ResolveIndexRequest(index)))
23+
;
24+
}
25+
}
26+
}

0 commit comments

Comments
 (0)