Skip to content

Commit 2578769

Browse files
codebrainStuart Cam
authored andcommitted
Implement CCR Follow Info API (#3927)
Implement CCR Follow Info API
1 parent 66671e1 commit 2578769

File tree

12 files changed

+224
-3
lines changed

12 files changed

+224
-3
lines changed

src/CodeGeneration/ApiGenerator/Configuration/CodeConfiguration.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,7 @@ public static class CodeConfiguration
2121
// these APIs are new and need to be mapped
2222
"ml.set_upgrade_mode.json",
2323
"ml.find_file_structure.json",
24-
"monitoring.bulk.json",
25-
26-
"ccr.follow_info.json",
24+
"monitoring.bulk.json"
2725
};
2826

2927

src/Elasticsearch.Net/Api/RequestParameters/RequestParameters.CrossClusterReplication.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,12 @@ public string WaitForActiveShards
4545
}
4646
}
4747

48+
///<summary>Request options for FollowInfo <para>https://www.elastic.co/guide/en/elasticsearch/reference/current/ccr-get-follow-info.html</para></summary>
49+
public class FollowInfoRequestParameters : RequestParameters<FollowInfoRequestParameters>
50+
{
51+
public override HttpMethod DefaultHttpMethod => HttpMethod.GET;
52+
}
53+
4854
///<summary>Request options for FollowIndexStats <para>https://www.elastic.co/guide/en/elasticsearch/reference/current/ccr-get-follow-stats.html</para></summary>
4955
public class FollowIndexStatsRequestParameters : RequestParameters<FollowIndexStatsRequestParameters>
5056
{

src/Elasticsearch.Net/ElasticLowLevelClient.CrossClusterReplication.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,16 @@ public TResponse CreateFollowIndex<TResponse>(string index, PostData body, Creat
6565
///<param name = "requestParameters">Request specific configuration such as querystring parameters &amp; request specific connection settings.</param>
6666
public Task<TResponse> CreateFollowIndexAsync<TResponse>(string index, PostData body, CreateFollowIndexRequestParameters requestParameters = null, CancellationToken ctx = default)
6767
where TResponse : class, IElasticsearchResponse, new() => DoRequestAsync<TResponse>(PUT, Url($"{index:index}/_ccr/follow"), ctx, body, RequestParams(requestParameters));
68+
///<summary>GET on /{index}/_ccr/info <para>https://www.elastic.co/guide/en/elasticsearch/reference/current/ccr-get-follow-info.html</para></summary>
69+
///<param name = "index">A comma-separated list of index patterns; use `_all` to perform the operation on all indices</param>
70+
///<param name = "requestParameters">Request specific configuration such as querystring parameters &amp; request specific connection settings.</param>
71+
public TResponse FollowInfo<TResponse>(string index, FollowInfoRequestParameters requestParameters = null)
72+
where TResponse : class, IElasticsearchResponse, new() => DoRequest<TResponse>(GET, Url($"{index:index}/_ccr/info"), null, RequestParams(requestParameters));
73+
///<summary>GET on /{index}/_ccr/info <para>https://www.elastic.co/guide/en/elasticsearch/reference/current/ccr-get-follow-info.html</para></summary>
74+
///<param name = "index">A comma-separated list of index patterns; use `_all` to perform the operation on all indices</param>
75+
///<param name = "requestParameters">Request specific configuration such as querystring parameters &amp; request specific connection settings.</param>
76+
public Task<TResponse> FollowInfoAsync<TResponse>(string index, FollowInfoRequestParameters requestParameters = null, CancellationToken ctx = default)
77+
where TResponse : class, IElasticsearchResponse, new() => DoRequestAsync<TResponse>(GET, Url($"{index:index}/_ccr/info"), ctx, null, RequestParams(requestParameters));
6878
///<summary>GET on /{index}/_ccr/stats <para>https://www.elastic.co/guide/en/elasticsearch/reference/current/ccr-get-follow-stats.html</para></summary>
6979
///<param name = "index">A comma-separated list of index patterns; use `_all` to perform the operation on all indices</param>
7080
///<param name = "requestParameters">Request specific configuration such as querystring parameters &amp; request specific connection settings.</param>

src/Nest/Descriptors.CrossClusterReplication.cs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,34 @@ public CreateFollowIndexDescriptor Index<TOther>()
7979
public CreateFollowIndexDescriptor WaitForActiveShards(string waitforactiveshards) => Qs("wait_for_active_shards", waitforactiveshards);
8080
}
8181

82+
///<summary>descriptor for FollowInfo <para>https://www.elastic.co/guide/en/elasticsearch/reference/current/ccr-get-follow-info.html</para></summary>
83+
public partial class FollowInfoDescriptor : RequestDescriptorBase<FollowInfoDescriptor, FollowInfoRequestParameters, IFollowInfoRequest>, IFollowInfoRequest
84+
{
85+
internal override ApiUrls ApiUrls => ApiUrlsLookups.CrossClusterReplicationFollowInfo;
86+
///<summary>/{index}/_ccr/info</summary>
87+
///<param name = "index">this parameter is required</param>
88+
public FollowInfoDescriptor(Indices index): base(r => r.Required("index", index))
89+
{
90+
}
91+
92+
///<summary>Used for serialization purposes, making sure we have a parameterless constructor</summary>
93+
[SerializationConstructor]
94+
protected FollowInfoDescriptor(): base()
95+
{
96+
}
97+
98+
// values part of the url path
99+
Indices IFollowInfoRequest.Index => Self.RouteValues.Get<Indices>("index");
100+
///<summary>A comma-separated list of index patterns; use `_all` to perform the operation on all indices</summary>
101+
public FollowInfoDescriptor Index(Indices index) => Assign(index, (a, v) => a.RouteValues.Required("index", v));
102+
///<summary>a shortcut into calling Index(typeof(TOther))</summary>
103+
public FollowInfoDescriptor Index<TOther>()
104+
where TOther : class => Assign(typeof(TOther), (a, v) => a.RouteValues.Required("index", (Indices)v));
105+
///<summary>A shortcut into calling Index(Indices.All)</summary>
106+
public FollowInfoDescriptor AllIndices() => Index(Indices.All);
107+
// Request parameters
108+
}
109+
82110
///<summary>descriptor for FollowIndexStats <para>https://www.elastic.co/guide/en/elasticsearch/reference/current/ccr-get-follow-stats.html</para></summary>
83111
public partial class FollowIndexStatsDescriptor : RequestDescriptorBase<FollowIndexStatsDescriptor, FollowIndexStatsRequestParameters, IFollowIndexStatsRequest>, IFollowIndexStatsRequest
84112
{

src/Nest/ElasticClient.CrossClusterReplication.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,30 @@ internal CrossClusterReplicationNamespace(ElasticClient client): base(client)
8585
/// </summary>
8686
public Task<CreateFollowIndexResponse> CreateFollowIndexAsync(ICreateFollowIndexRequest request, CancellationToken ct = default) => DoRequestAsync<ICreateFollowIndexRequest, CreateFollowIndexResponse>(request, request.RequestParameters, ct);
8787
/// <summary>
88+
/// <c>GET</c> request to the <c>ccr.follow_info</c> API, read more about this API online:
89+
/// <para></para>
90+
/// <a href = "https://www.elastic.co/guide/en/elasticsearch/reference/current/ccr-get-follow-info.html">https://www.elastic.co/guide/en/elasticsearch/reference/current/ccr-get-follow-info.html</a>
91+
/// </summary>
92+
public FollowInfoResponse FollowInfo(Indices index, Func<FollowInfoDescriptor, IFollowInfoRequest> selector = null) => FollowInfo(selector.InvokeOrDefault(new FollowInfoDescriptor(index: index)));
93+
/// <summary>
94+
/// <c>GET</c> request to the <c>ccr.follow_info</c> API, read more about this API online:
95+
/// <para></para>
96+
/// <a href = "https://www.elastic.co/guide/en/elasticsearch/reference/current/ccr-get-follow-info.html">https://www.elastic.co/guide/en/elasticsearch/reference/current/ccr-get-follow-info.html</a>
97+
/// </summary>
98+
public Task<FollowInfoResponse> FollowInfoAsync(Indices index, Func<FollowInfoDescriptor, IFollowInfoRequest> selector = null, CancellationToken ct = default) => FollowInfoAsync(selector.InvokeOrDefault(new FollowInfoDescriptor(index: index)), ct);
99+
/// <summary>
100+
/// <c>GET</c> request to the <c>ccr.follow_info</c> API, read more about this API online:
101+
/// <para></para>
102+
/// <a href = "https://www.elastic.co/guide/en/elasticsearch/reference/current/ccr-get-follow-info.html">https://www.elastic.co/guide/en/elasticsearch/reference/current/ccr-get-follow-info.html</a>
103+
/// </summary>
104+
public FollowInfoResponse FollowInfo(IFollowInfoRequest request) => DoRequest<IFollowInfoRequest, FollowInfoResponse>(request, request.RequestParameters);
105+
/// <summary>
106+
/// <c>GET</c> request to the <c>ccr.follow_info</c> API, read more about this API online:
107+
/// <para></para>
108+
/// <a href = "https://www.elastic.co/guide/en/elasticsearch/reference/current/ccr-get-follow-info.html">https://www.elastic.co/guide/en/elasticsearch/reference/current/ccr-get-follow-info.html</a>
109+
/// </summary>
110+
public Task<FollowInfoResponse> FollowInfoAsync(IFollowInfoRequest request, CancellationToken ct = default) => DoRequestAsync<IFollowInfoRequest, FollowInfoResponse>(request, request.RequestParameters, ct);
111+
/// <summary>
88112
/// <c>GET</c> request to the <c>ccr.follow_stats</c> API, read more about this API online:
89113
/// <para></para>
90114
/// <a href = "https://www.elastic.co/guide/en/elasticsearch/reference/current/ccr-get-follow-stats.html">https://www.elastic.co/guide/en/elasticsearch/reference/current/ccr-get-follow-stats.html</a>

src/Nest/Requests.CrossClusterReplication.cs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,39 @@ public string WaitForActiveShards
106106
}
107107
}
108108

109+
[InterfaceDataContract]
110+
public partial interface IFollowInfoRequest : IRequest<FollowInfoRequestParameters>
111+
{
112+
[IgnoreDataMember]
113+
Indices Index
114+
{
115+
get;
116+
}
117+
}
118+
119+
///<summary>Request for FollowInfo <para>https://www.elastic.co/guide/en/elasticsearch/reference/current/ccr-get-follow-info.html</para></summary>
120+
public partial class FollowInfoRequest : PlainRequestBase<FollowInfoRequestParameters>, IFollowInfoRequest
121+
{
122+
protected IFollowInfoRequest Self => this;
123+
internal override ApiUrls ApiUrls => ApiUrlsLookups.CrossClusterReplicationFollowInfo;
124+
///<summary>/{index}/_ccr/info</summary>
125+
///<param name = "index">this parameter is required</param>
126+
public FollowInfoRequest(Indices index): base(r => r.Required("index", index))
127+
{
128+
}
129+
130+
///<summary>Used for serialization purposes, making sure we have a parameterless constructor</summary>
131+
[SerializationConstructor]
132+
protected FollowInfoRequest(): base()
133+
{
134+
}
135+
136+
// values part of the url path
137+
[IgnoreDataMember]
138+
Indices IFollowInfoRequest.Index => Self.RouteValues.Get<Indices>("index");
139+
// Request parameters
140+
}
141+
109142
[InterfaceDataContract]
110143
public partial interface IFollowIndexStatsRequest : IRequest<FollowIndexStatsRequestParameters>
111144
{
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
using System;
2+
using System.Runtime.Serialization;
3+
4+
namespace Nest
5+
{
6+
public class FollowConfig
7+
{
8+
[DataMember(Name = "max_read_request_operation_count")]
9+
public int MaximumReadRequestOperationCount { get; internal set; }
10+
11+
[DataMember(Name = "max_read_request_size")]
12+
public string MaximumReadRequestSize { get; internal set; }
13+
14+
[DataMember(Name = "max_outstanding_read_requests")]
15+
public int MaximumOutstandingReadRequests { get; internal set; }
16+
17+
[DataMember(Name = "max_write_request_operation_count")]
18+
public int MaximumWriteRequestOperationCount { get; internal set; }
19+
20+
[DataMember(Name = "max_write_request_size")]
21+
public string MaximumWriteRequestSize { get; internal set; }
22+
23+
[DataMember(Name = "max_outstanding_write_requests")]
24+
public int MaximumOutstandingWriteRequests { get; internal set; }
25+
26+
[DataMember(Name = "max_write_buffer_count")]
27+
public int MaximumWriteBufferCount { get; internal set; }
28+
29+
[DataMember(Name = "max_write_buffer_size")]
30+
public string MaximumWriteBufferSize { get; internal set; }
31+
32+
[DataMember(Name = "max_retry_delay")]
33+
public Time MaximumRetryDelay { get; internal set; }
34+
35+
[DataMember(Name = "read_poll_timeout")]
36+
public Time ReadPollTimeout { get; internal set; }
37+
}
38+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
namespace Nest
2+
{
3+
/// <summary>
4+
/// Retrieves information about all follower indices.
5+
/// </summary>
6+
[MapsApi("ccr.follow_info.json")]
7+
public partial interface IFollowInfoRequest { }
8+
9+
/// <inheritdoc cref="IFollowInfoRequest" />
10+
public partial class FollowInfoRequest { }
11+
12+
/// <inheritdoc cref="IFollowInfoRequest" />
13+
public partial class FollowInfoDescriptor { }
14+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
using System.Collections.Generic;
2+
using System.Runtime.Serialization;
3+
using Elasticsearch.Net;
4+
5+
namespace Nest
6+
{
7+
public class FollowInfoResponse : ResponseBase
8+
{
9+
[DataMember(Name = "follower_indices")]
10+
public IReadOnlyCollection<FollowerInfo> FollowerIndices { get; internal set; } = EmptyReadOnly<FollowerInfo>.Collection;
11+
}
12+
13+
public class FollowerInfo
14+
{
15+
[DataMember(Name = "follower_index")]
16+
public string FollowerIndex { get; internal set; }
17+
18+
[DataMember(Name = "remote_cluster")]
19+
public string RemoteCluster { get; internal set; }
20+
21+
[DataMember(Name = "leader_index")]
22+
public string LeaderIndex { get; internal set; }
23+
24+
[DataMember(Name = "status")]
25+
public FollowerIndexStatus Status { get; internal set; }
26+
27+
[DataMember(Name = "parameters")]
28+
public FollowConfig Parameters { get; internal set; }
29+
}
30+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
using System.Runtime.Serialization;
2+
using Elasticsearch.Net;
3+
4+
namespace Nest
5+
{
6+
[StringEnum]
7+
public enum FollowerIndexStatus
8+
{
9+
[EnumMember(Value = "active")]
10+
Active,
11+
12+
[EnumMember(Value = "paused")]
13+
Paused
14+
}
15+
}

src/Nest/_Generated/ApiUrlsLookup.generated.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ internal static class ApiUrlsLookups
4141
internal static ApiUrls CatThreadPool = new ApiUrls(new[]{"_cat/thread_pool", "_cat/thread_pool/{thread_pool_patterns}"});
4242
internal static ApiUrls CrossClusterReplicationDeleteAutoFollowPattern = new ApiUrls(new[]{"_ccr/auto_follow/{name}"});
4343
internal static ApiUrls CrossClusterReplicationCreateFollowIndex = new ApiUrls(new[]{"{index}/_ccr/follow"});
44+
internal static ApiUrls CrossClusterReplicationFollowInfo = new ApiUrls(new[]{"{index}/_ccr/info"});
4445
internal static ApiUrls CrossClusterReplicationFollowIndexStats = new ApiUrls(new[]{"{index}/_ccr/stats"});
4546
internal static ApiUrls CrossClusterReplicationForgetFollowerIndex = new ApiUrls(new[]{"{index}/_ccr/forget_follower"});
4647
internal static ApiUrls CrossClusterReplicationGetAutoFollowPattern = new ApiUrls(new[]{"_ccr/auto_follow", "_ccr/auto_follow/{name}"});

src/Tests/Tests/XPack/CrossClusterReplication/CrossClusterReplicationFollowTests.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ public class CrossClusterReplicationFollowTests : CoordinatedIntegrationTestBase
2929
private const string FollowIndexStep = nameof(FollowIndexStep);
3030
private const string FollowStatsAgainStep = nameof(FollowStatsAgainStep);
3131
private const string FollowStatsStep = nameof(FollowStatsStep);
32+
private const string FollowInfoStep = nameof(FollowInfoStep);
3233
private const string IndexDataStep = nameof(IndexDataStep);
3334
private const string PauseFollowStep = nameof(PauseFollowStep);
3435
private const string PauseForCloseStep = nameof(PauseForCloseStep);
@@ -158,6 +159,17 @@ public CrossClusterReplicationFollowTests(XPackCluster cluster, EndpointUsage us
158159
(v, c, r) => c.CrossClusterReplication.FollowIndexStatsAsync(r)
159160
)
160161
},
162+
{
163+
FollowInfoStep, u =>
164+
u.Calls<FollowInfoDescriptor, FollowInfoRequest, IFollowInfoRequest, FollowInfoResponse>(
165+
v => new FollowInfoRequest(CopyIndex(v)),
166+
(v, d) => d,
167+
(v, c, f) => c.CrossClusterReplication.FollowInfo(CopyIndex(v), f),
168+
(v, c, f) => c.CrossClusterReplication.FollowInfoAsync(CopyIndex(v), f),
169+
(v, c, r) => c.CrossClusterReplication.FollowInfo(r),
170+
(v, c, r) => c.CrossClusterReplication.FollowInfoAsync(r)
171+
)
172+
},
161173
{
162174
DeleteOriginalIndicesStep, u => u.Calls<DeleteIndexDescriptor, DeleteIndexRequest, IDeleteIndexRequest, DeleteIndexResponse>
163175
(
@@ -271,6 +283,18 @@ [I] public async Task FollowStatsResponse() => await Assert<FollowIndexStatsResp
271283
}
272284
});
273285

286+
[I] public async Task FollowInfoResponse() => await Assert<FollowInfoResponse>(FollowInfoStep, r =>
287+
{
288+
r.IsValid.Should().BeTrue();
289+
r.FollowerIndices.Should().NotBeNull();
290+
r.FollowerIndices.Should().NotBeEmpty();
291+
var first = r.FollowerIndices.First();
292+
first.FollowerIndex.Should().NotBeNullOrWhiteSpace();
293+
first.RemoteCluster.Should().NotBeNullOrWhiteSpace();
294+
first.LeaderIndex.Should().NotBeNullOrWhiteSpace();
295+
first.Parameters.Should().NotBeNull();
296+
});
297+
274298
[I] public async Task GlobalStatsResponse() => await Assert<CcrStatsResponse>(GlobalStatsStep, r =>
275299
{
276300
r.IsValid.Should().BeTrue();

0 commit comments

Comments
 (0)