Skip to content

Commit f96a6f9

Browse files
authored
Add NEST support for EQL Search API (#5658)
* Add request and response classes * Code gen for EQL search * Add initial request properties * Initial response for testing * Un-skip EQL APIs from high-level code gen * Generate EQL code * Work on request and response types * Add event type for EQL * Update NEST code gen with license headers * Update request/response * Adding initial test * Support generic searches * Fixing URLs and adding URL tests * Add descriptor methods * Add sequence tests * Remove interfaces and update comments. * Remove redundant code in TimeSeriesCluster * Cleanup namespaces * Update license headers * Update headers * Remove UTF-8 BOM
1 parent 819182b commit f96a6f9

File tree

24 files changed

+1114
-23
lines changed

24 files changed

+1114
-23
lines changed

.github/check-license-headers.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ NLINES=$(wc -l .github/license-header.txt | awk '{print $1}')
1616
function check_license_header {
1717
local f
1818
f=$1
19-
if ! diff .github/license-header.txt <(head -$NLINES "$f") >/dev/null; then
19+
if ! diff -a --strip-trailing-cr .github/license-header.txt <(head -$NLINES "$f") >/dev/null; then
2020
echo "check-license-headers: error: '$f' does not have required license header, see 'diff -u .github/license-header.txt <(head -$NLINES $f)'"
2121
return 1
2222
else

src/ApiGenerator/Configuration/CodeConfiguration.cs

-4
Original file line numberDiff line numberDiff line change
@@ -99,10 +99,6 @@ public static class CodeConfiguration
9999
"cluster.get_component_template.json", // 7.8 experimental
100100
"cluster.put_component_template.json", // 7.8 experimental
101101
"cluster.exists_component_template.json", // 7.8 experimental
102-
103-
"eql.search.json", // 7.9 beta
104-
"eql.get.json", // 7.9 beta
105-
"eql.delete.json", // 7.9 beta
106102
};
107103

108104
/// <summary>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"eql.search": {
3+
"url": {
4+
"parts": {
5+
"index": {
6+
"type" : "list",
7+
"description" : "A comma-separated list of index names to search; use `_all` or empty string to perform the operation on all indices"
8+
}
9+
}
10+
}
11+
}
12+
}

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ public class GetStatusRequestParameters : RequestParameters<GetStatusRequestPara
7777
}
7878

7979
///<summary>Request options for Search <para>https://www.elastic.co/guide/en/elasticsearch/reference/current/eql-search-api.html</para></summary>
80-
public class SearchRequestParameters : RequestParameters<SearchRequestParameters>
80+
public class EqlSearchRequestParameters : RequestParameters<EqlSearchRequestParameters>
8181
{
8282
public override HttpMethod DefaultHttpMethod => HttpMethod.POST;
8383
public override bool SupportsBody => true;

src/Elasticsearch.Net/ElasticLowLevelClient.Eql.cs

+4-4
Original file line numberDiff line numberDiff line change
@@ -95,17 +95,17 @@ public TResponse GetStatus<TResponse>(string id, GetStatusRequestParameters requ
9595
public Task<TResponse> GetStatusAsync<TResponse>(string id, GetStatusRequestParameters requestParameters = null, CancellationToken ctx = default)
9696
where TResponse : class, IElasticsearchResponse, new() => DoRequestAsync<TResponse>(GET, Url($"_eql/search/status/{id:id}"), ctx, null, RequestParams(requestParameters));
9797
///<summary>POST on /{index}/_eql/search <para>https://www.elastic.co/guide/en/elasticsearch/reference/current/eql-search-api.html</para></summary>
98-
///<param name = "index">The name of the index to scope the operation</param>
98+
///<param name = "index">A comma-separated list of index names to search; use the special string `_all` or Indices.All to perform the operation on all indices</param>
9999
///<param name = "body">Eql request body. Use the `query` to limit the query scope.</param>
100100
///<param name = "requestParameters">Request specific configuration such as querystring parameters &amp; request specific connection settings.</param>
101-
public TResponse Search<TResponse>(string index, PostData body, SearchRequestParameters requestParameters = null)
101+
public TResponse Search<TResponse>(string index, PostData body, EqlSearchRequestParameters requestParameters = null)
102102
where TResponse : class, IElasticsearchResponse, new() => DoRequest<TResponse>(POST, Url($"{index:index}/_eql/search"), body, RequestParams(requestParameters));
103103
///<summary>POST on /{index}/_eql/search <para>https://www.elastic.co/guide/en/elasticsearch/reference/current/eql-search-api.html</para></summary>
104-
///<param name = "index">The name of the index to scope the operation</param>
104+
///<param name = "index">A comma-separated list of index names to search; use the special string `_all` or Indices.All to perform the operation on all indices</param>
105105
///<param name = "body">Eql request body. Use the `query` to limit the query scope.</param>
106106
///<param name = "requestParameters">Request specific configuration such as querystring parameters &amp; request specific connection settings.</param>
107107
[MapsApi("eql.search", "index, body")]
108-
public Task<TResponse> SearchAsync<TResponse>(string index, PostData body, SearchRequestParameters requestParameters = null, CancellationToken ctx = default)
108+
public Task<TResponse> SearchAsync<TResponse>(string index, PostData body, EqlSearchRequestParameters requestParameters = null, CancellationToken ctx = default)
109109
where TResponse : class, IElasticsearchResponse, new() => DoRequestAsync<TResponse>(POST, Url($"{index:index}/_eql/search"), ctx, body, RequestParams(requestParameters));
110110
}
111111
}

src/Nest/Descriptors.Eql.cs

+83
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/*
2+
* Licensed to Elasticsearch B.V. under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch B.V. licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
// ███╗ ██╗ ██████╗ ████████╗██╗ ██████╗███████╗
20+
// ████╗ ██║██╔═══██╗╚══██╔══╝██║██╔════╝██╔════╝
21+
// ██╔██╗ ██║██║ ██║ ██║ ██║██║ █████╗
22+
// ██║╚██╗██║██║ ██║ ██║ ██║██║ ██╔══╝
23+
// ██║ ╚████║╚██████╔╝ ██║ ██║╚██████╗███████╗
24+
// ╚═╝ ╚═══╝ ╚═════╝ ╚═╝ ╚═╝ ╚═════╝╚══════╝
25+
// -----------------------------------------------
26+
//
27+
// This file is automatically generated
28+
// Please do not edit these files manually
29+
// Run the following in the root of the repos:
30+
//
31+
// *NIX : ./build.sh codegen
32+
// Windows : build.bat codegen
33+
//
34+
// -----------------------------------------------
35+
// ReSharper disable RedundantUsingDirective
36+
using System;
37+
using System.Collections.Generic;
38+
using System.Linq;
39+
using System.Text;
40+
using System.Linq.Expressions;
41+
using Elasticsearch.Net;
42+
using Elasticsearch.Net.Utf8Json;
43+
using Elasticsearch.Net.Specification.EqlApi;
44+
45+
// ReSharper disable RedundantBaseConstructorCall
46+
// ReSharper disable UnusedTypeParameter
47+
// ReSharper disable PartialMethodWithSinglePart
48+
// ReSharper disable RedundantNameQualifier
49+
namespace Nest
50+
{
51+
///<summary>Descriptor for Search <para>https://www.elastic.co/guide/en/elasticsearch/reference/current/eql-search-api.html</para></summary>
52+
public partial class EqlSearchDescriptor<TInferDocument> : RequestDescriptorBase<EqlSearchDescriptor<TInferDocument>, EqlSearchRequestParameters, IEqlSearchRequest<TInferDocument>>, IEqlSearchRequest<TInferDocument>
53+
{
54+
internal override ApiUrls ApiUrls => ApiUrlsLookups.EqlSearch;
55+
///<summary>/{index}/_eql/search</summary>
56+
///<param name = "index">this parameter is required</param>
57+
public EqlSearchDescriptor(Indices index): base(r => r.Required("index", index))
58+
{
59+
}
60+
61+
///<summary>/{index}/_eql/search</summary>
62+
public EqlSearchDescriptor(): this(typeof(TInferDocument))
63+
{
64+
}
65+
66+
// values part of the url path
67+
Indices IEqlSearchRequest.Index => Self.RouteValues.Get<Indices>("index");
68+
///<summary>A comma-separated list of index names to search; use the special string `_all` or Indices.All to perform the operation on all indices</summary>
69+
public EqlSearchDescriptor<TInferDocument> Index(Indices index) => Assign(index, (a, v) => a.RouteValues.Required("index", v));
70+
///<summary>a shortcut into calling Index(typeof(TOther))</summary>
71+
public EqlSearchDescriptor<TInferDocument> Index<TOther>()
72+
where TOther : class => Assign(typeof(TOther), (a, v) => a.RouteValues.Required("index", (Indices)v));
73+
///<summary>A shortcut into calling Index(Indices.All)</summary>
74+
public EqlSearchDescriptor<TInferDocument> AllIndices() => Index(Indices.All);
75+
// Request parameters
76+
///<summary>Update the time interval in which the results (partial or final) for this search will be available</summary>
77+
public EqlSearchDescriptor<TInferDocument> KeepAlive(Time keepalive) => Qs("keep_alive", keepalive);
78+
///<summary>Control whether the response should be stored in the cluster if it completed within the provided [wait_for_completion] time (default: false)</summary>
79+
public EqlSearchDescriptor<TInferDocument> KeepOnCompletion(bool? keeponcompletion = true) => Qs("keep_on_completion", keeponcompletion);
80+
///<summary>Specify the time that the request should block waiting for the final response</summary>
81+
public EqlSearchDescriptor<TInferDocument> WaitForCompletionTimeout(Time waitforcompletiontimeout) => Qs("wait_for_completion_timeout", waitforcompletiontimeout);
82+
}
83+
}

src/Nest/ElasticClient.Eql.cs

+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
/*
2+
* Licensed to Elasticsearch B.V. under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch B.V. licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
// ███╗ ██╗ ██████╗ ████████╗██╗ ██████╗███████╗
20+
// ████╗ ██║██╔═══██╗╚══██╔══╝██║██╔════╝██╔════╝
21+
// ██╔██╗ ██║██║ ██║ ██║ ██║██║ █████╗
22+
// ██║╚██╗██║██║ ██║ ██║ ██║██║ ██╔══╝
23+
// ██║ ╚████║╚██████╔╝ ██║ ██║╚██████╗███████╗
24+
// ╚═╝ ╚═══╝ ╚═════╝ ╚═╝ ╚═╝ ╚═════╝╚══════╝
25+
// -----------------------------------------------
26+
//
27+
// This file is automatically generated
28+
// Please do not edit these files manually
29+
// Run the following in the root of the repos:
30+
//
31+
// *NIX : ./build.sh codegen
32+
// Windows : build.bat codegen
33+
//
34+
// -----------------------------------------------
35+
// ReSharper disable RedundantUsingDirective
36+
using System;
37+
using System.Threading;
38+
using System.Threading.Tasks;
39+
using Elasticsearch.Net.Specification.EqlApi;
40+
41+
// ReSharper disable once CheckNamespace
42+
// ReSharper disable RedundantTypeArgumentsOfMethod
43+
namespace Nest.Specification.EqlApi
44+
{
45+
///<summary>
46+
/// Eql APIs.
47+
/// <para>Not intended to be instantiated directly. Use the <see cref = "IElasticClient.Eql"/> property
48+
/// on <see cref = "IElasticClient"/>.
49+
///</para>
50+
///</summary>
51+
public class EqlNamespace : NamespacedClientProxy
52+
{
53+
internal EqlNamespace(ElasticClient client): base(client)
54+
{
55+
}
56+
57+
/// <summary>
58+
/// <c>POST</c> request to the <c>eql.search</c> API, read more about this API online:
59+
/// <para></para>
60+
/// <a href = "https://www.elastic.co/guide/en/elasticsearch/reference/current/eql-search-api.html">https://www.elastic.co/guide/en/elasticsearch/reference/current/eql-search-api.html</a>
61+
/// </summary>
62+
public EqlSearchResponse<TDocument> Search<TInferDocument, TDocument>(Func<EqlSearchDescriptor<TInferDocument>, IEqlSearchRequest> selector = null)
63+
where TInferDocument : class where TDocument : class => Search<TDocument>(selector.InvokeOrDefault(new EqlSearchDescriptor<TInferDocument>()));
64+
/// <summary>
65+
/// <c>POST</c> request to the <c>eql.search</c> API, read more about this API online:
66+
/// <para></para>
67+
/// <a href = "https://www.elastic.co/guide/en/elasticsearch/reference/current/eql-search-api.html">https://www.elastic.co/guide/en/elasticsearch/reference/current/eql-search-api.html</a>
68+
/// </summary>
69+
public Task<EqlSearchResponse<TDocument>> SearchAsync<TInferDocument, TDocument>(Func<EqlSearchDescriptor<TInferDocument>, IEqlSearchRequest> selector = null, CancellationToken ct = default)
70+
where TInferDocument : class where TDocument : class => SearchAsync<TDocument>(selector.InvokeOrDefault(new EqlSearchDescriptor<TInferDocument>()), ct);
71+
/// <summary>
72+
/// <c>POST</c> request to the <c>eql.search</c> API, read more about this API online:
73+
/// <para></para>
74+
/// <a href = "https://www.elastic.co/guide/en/elasticsearch/reference/current/eql-search-api.html">https://www.elastic.co/guide/en/elasticsearch/reference/current/eql-search-api.html</a>
75+
/// </summary>
76+
public EqlSearchResponse<TDocument> Search<TDocument>(Func<EqlSearchDescriptor<TDocument>, IEqlSearchRequest> selector = null)
77+
where TDocument : class => Search<TDocument>(selector.InvokeOrDefault(new EqlSearchDescriptor<TDocument>()));
78+
/// <summary>
79+
/// <c>POST</c> request to the <c>eql.search</c> API, read more about this API online:
80+
/// <para></para>
81+
/// <a href = "https://www.elastic.co/guide/en/elasticsearch/reference/current/eql-search-api.html">https://www.elastic.co/guide/en/elasticsearch/reference/current/eql-search-api.html</a>
82+
/// </summary>
83+
public Task<EqlSearchResponse<TDocument>> SearchAsync<TDocument>(Func<EqlSearchDescriptor<TDocument>, IEqlSearchRequest> selector = null, CancellationToken ct = default)
84+
where TDocument : class => SearchAsync<TDocument>(selector.InvokeOrDefault(new EqlSearchDescriptor<TDocument>()), ct);
85+
/// <summary>
86+
/// <c>POST</c> request to the <c>eql.search</c> API, read more about this API online:
87+
/// <para></para>
88+
/// <a href = "https://www.elastic.co/guide/en/elasticsearch/reference/current/eql-search-api.html">https://www.elastic.co/guide/en/elasticsearch/reference/current/eql-search-api.html</a>
89+
/// </summary>
90+
public EqlSearchResponse<TDocument> Search<TDocument>(IEqlSearchRequest request)
91+
where TDocument : class => DoRequest<IEqlSearchRequest, EqlSearchResponse<TDocument>>(request, request.RequestParameters);
92+
/// <summary>
93+
/// <c>POST</c> request to the <c>eql.search</c> API, read more about this API online:
94+
/// <para></para>
95+
/// <a href = "https://www.elastic.co/guide/en/elasticsearch/reference/current/eql-search-api.html">https://www.elastic.co/guide/en/elasticsearch/reference/current/eql-search-api.html</a>
96+
/// </summary>
97+
public Task<EqlSearchResponse<TDocument>> SearchAsync<TDocument>(IEqlSearchRequest request, CancellationToken ct = default)
98+
where TDocument : class => DoRequestAsync<IEqlSearchRequest, EqlSearchResponse<TDocument>>(request, request.RequestParameters, ct);
99+
}
100+
}

src/Nest/ElasticClient.NoNamespace.cs

+9
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
using Nest.Specification.CrossClusterReplicationApi;
4444
using Nest.Specification.DanglingIndicesApi;
4545
using Nest.Specification.EnrichApi;
46+
using Nest.Specification.EqlApi;
4647
using Nest.Specification.GraphApi;
4748
using Nest.Specification.IndexLifecycleManagementApi;
4849
using Nest.Specification.IndicesApi;
@@ -111,6 +112,13 @@ public EnrichNamespace Enrich
111112
private set;
112113
}
113114

115+
///<summary>Eql APIs</summary>
116+
public EqlNamespace Eql
117+
{
118+
get;
119+
private set;
120+
}
121+
114122
///<summary>Graph APIs</summary>
115123
public GraphNamespace Graph
116124
{
@@ -238,6 +246,7 @@ partial void SetupNamespaces()
238246
CrossClusterReplication = new CrossClusterReplicationNamespace(this);
239247
DanglingIndices = new DanglingIndicesNamespace(this);
240248
Enrich = new EnrichNamespace(this);
249+
Eql = new EqlNamespace(this);
241250
Graph = new GraphNamespace(this);
242251
IndexLifecycleManagement = new IndexLifecycleManagementNamespace(this);
243252
Indices = new IndicesNamespace(this);

src/Nest/IElasticClient.Generated.cs

+7
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
using Nest.Specification.CrossClusterReplicationApi;
4646
using Nest.Specification.DanglingIndicesApi;
4747
using Nest.Specification.EnrichApi;
48+
using Nest.Specification.EqlApi;
4849
using Nest.Specification.GraphApi;
4950
using Nest.Specification.IndexLifecycleManagementApi;
5051
using Nest.Specification.IndicesApi;
@@ -106,6 +107,12 @@ EnrichNamespace Enrich
106107
get;
107108
}
108109

110+
///<summary>Eql APIs</summary>
111+
EqlNamespace Eql
112+
{
113+
get;
114+
}
115+
109116
///<summary>Graph APIs</summary>
110117
GraphNamespace Graph
111118
{

0 commit comments

Comments
 (0)