Skip to content

Commit 28a3433

Browse files
Fix MultiSearchTemplateRequest body (#7008) (#7015)
* Manually define the RequestItem for MultiSearchTemplateRequests - Manual type implements IStreamSerializable to support NDJSON. - Add serialization test * Update integration workflow stack version * Add release notes * Make headings discrete Co-authored-by: Steve Gordon <[email protected]>
1 parent c6b5bdc commit 28a3433

File tree

11 files changed

+180
-48
lines changed

11 files changed

+180
-48
lines changed

.github/workflows/integration-jobs.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ jobs:
2626
'8.2.3',
2727
'8.3.3',
2828
'8.4.3',
29-
"8.5.0",
29+
"8.5.2",
3030
'8.6.0-SNAPSHOT',
3131
'latest-8'
3232
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
[[release-notes-8.0.1]]
2+
== Release notes v8.0.1
3+
4+
[discrete]
5+
=== Bug fixes
6+
7+
- Fix MultiSearchTemplateRequest serialization (issue:
8+
https://github.com/elastic/elasticsearch-net/issues/7006[#7006])
9+
10+
[discrete]
11+
=== Breaking changes
12+
13+
This release includes the following breaking changes:
14+
15+
[discrete]
16+
==== MultiSearchTemplate type changes
17+
18+
The `Core.MSearchTemplate.RequestItem` type has been renamed to
19+
`Core.MSearchTemplate.SearchTemplateRequestItem`. It no longer derives from the
20+
`Union<T1, T2>` type. It has been manually designed to support serialisation to
21+
NDJSON, as required by the MSearchTemplate endpoint.
22+
23+
The `MultiSearchTemplateRequest.SearchTemplates` property has been updated to
24+
use this newly defined type.
25+
26+
This breaking change has been included in this patch release due to the
27+
original code-generated type not functioning correctly and therefore we have
28+
determined that this should ship ASAP.
29+
30+
[discrete]
31+
=== MultiSearch type changes
32+
33+
The `Core.MSearch.SearchRequestItem` type has been sealed for consistency with
34+
the design choices in the rest of the client. While technically breaking, we
35+
have decided that this should be included in this release before any potential
36+
derived types may exist in consuming applications.

docs/release-notes/release-notes.asciidoc

+7-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,13 @@
22
= Release notes
33

44
* <<breaking-changes-policy,Breaking changes policy>>
5-
* <<release-notes-8.0.0,Version 8.0.0>>
5+
6+
[discrete]
7+
== Version 8.x
8+
9+
* <<release-notes-8.0.0,Release notes v8.0.0>>
10+
* <<release-notes-8.0.1,Release notes v8.0.1>>
611

712
include::breaking-change-policy.asciidoc[]
813
include::release-notes-8.0.0.asciidoc[]
14+
include::release-notes-8.0.1.asciidoc[]

src/Elastic.Clients.Elasticsearch/Elastic.Clients.Elasticsearch.csproj

+3
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,7 @@
3333
<_Parameter1>true</_Parameter1>
3434
</AssemblyAttribute>
3535
</ItemGroup>
36+
<ItemGroup>
37+
<Folder Include="Types\Documents\" />
38+
</ItemGroup>
3639
</Project>

src/Elastic.Clients.Elasticsearch/Types/Documents/MultiSearch/SearchRequestItem.cs renamed to src/Elastic.Clients.Elasticsearch/Types/Core/MSearch/SearchRequestItem.cs

+1-3
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
namespace Elastic.Clients.Elasticsearch.Core.MSearch;
1212

1313
// POC - If we have more than one union doing this, can we autogenerate with correct ctors etc.
14-
public class SearchRequestItem : IStreamSerializable
14+
public sealed class SearchRequestItem : IStreamSerializable
1515
{
1616
public SearchRequestItem(MultisearchBody body) => Body = body;
1717

@@ -52,5 +52,3 @@ async Task IStreamSerializable.SerializeAsync(Stream stream, IElasticsearchClien
5252
}
5353
}
5454
}
55-
56-
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
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.IO;
6+
using System.Text.Json;
7+
using System.Threading.Tasks;
8+
using Elastic.Clients.Elasticsearch.Core.MSearch;
9+
using Elastic.Clients.Elasticsearch.Serialization;
10+
using Elastic.Transport;
11+
12+
namespace Elastic.Clients.Elasticsearch.Core.MSearchTemplate;
13+
14+
public sealed class SearchTemplateRequestItem : IStreamSerializable
15+
{
16+
public SearchTemplateRequestItem(TemplateConfig body) => Body = body;
17+
18+
public SearchTemplateRequestItem(MultisearchHeader header, TemplateConfig body)
19+
{
20+
Header = header;
21+
Body = body;
22+
}
23+
24+
public MultisearchHeader Header { get; init; }
25+
public TemplateConfig Body { get; init; }
26+
27+
void IStreamSerializable.Serialize(Stream stream, IElasticsearchClientSettings settings, SerializationFormatting formatting)
28+
{
29+
if (Body is null)
30+
return;
31+
32+
if (settings.RequestResponseSerializer.TryGetJsonSerializerOptions(out var options))
33+
{
34+
JsonSerializer.Serialize(stream, Header, options);
35+
stream.WriteByte((byte)'\n');
36+
JsonSerializer.Serialize(stream, Body, options);
37+
stream.WriteByte((byte)'\n');
38+
}
39+
}
40+
41+
async Task IStreamSerializable.SerializeAsync(Stream stream, IElasticsearchClientSettings settings, SerializationFormatting formatting)
42+
{
43+
if (Body is null)
44+
return;
45+
46+
if (settings.RequestResponseSerializer.TryGetJsonSerializerOptions(out var options))
47+
{
48+
await JsonSerializer.SerializeAsync(stream, Header, options).ConfigureAwait(false);
49+
stream.WriteByte((byte)'\n');
50+
await JsonSerializer.SerializeAsync(stream, Body, options).ConfigureAwait(false);
51+
stream.WriteByte((byte)'\n');
52+
}
53+
}
54+
}

src/Elastic.Clients.Elasticsearch/_Generated/Api/MultiSearchTemplateRequest.g.cs

+5-5
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ public MultiSearchTemplateRequest(Elastic.Clients.Elasticsearch.Indices? indices
7575
[JsonIgnore]
7676
public bool? TypedKeys { get => Q<bool?>("typed_keys"); set => Q("typed_keys", value); }
7777

78-
public List<Core.MSearchTemplate.RequestItem> SearchTemplates { get; set; }
78+
public List<Core.MSearchTemplate.SearchTemplateRequestItem> SearchTemplates { get; set; }
7979

8080
void IStreamSerializable.Serialize(Stream stream, IElasticsearchClientSettings settings, SerializationFormatting formatting)
8181
{
@@ -125,7 +125,7 @@ protected override void Serialize(Utf8JsonWriter writer, JsonSerializerOptions o
125125
{
126126
}
127127

128-
List<Core.MSearchTemplate.RequestItem> _items = new();
128+
List<Core.MSearchTemplate.SearchTemplateRequestItem> _items = new();
129129
void IStreamSerializable.Serialize(Stream stream, IElasticsearchClientSettings settings, SerializationFormatting formatting)
130130
{
131131
if (_items is null)
@@ -148,7 +148,7 @@ async Task IStreamSerializable.SerializeAsync(Stream stream, IElasticsearchClien
148148
}
149149
}
150150

151-
public MultiSearchTemplateRequestDescriptor<TDocument> Add(Core.MSearchTemplate.RequestItem item)
151+
public MultiSearchTemplateRequestDescriptor<TDocument> Add(Core.MSearchTemplate.SearchTemplateRequestItem item)
152152
{
153153
_items.Add(item);
154154
return this;
@@ -180,7 +180,7 @@ protected override void Serialize(Utf8JsonWriter writer, JsonSerializerOptions o
180180
{
181181
}
182182

183-
List<Core.MSearchTemplate.RequestItem> _items = new();
183+
List<Core.MSearchTemplate.SearchTemplateRequestItem> _items = new();
184184
void IStreamSerializable.Serialize(Stream stream, IElasticsearchClientSettings settings, SerializationFormatting formatting)
185185
{
186186
if (_items is null)
@@ -203,7 +203,7 @@ async Task IStreamSerializable.SerializeAsync(Stream stream, IElasticsearchClien
203203
}
204204
}
205205

206-
public MultiSearchTemplateRequestDescriptor Add(Core.MSearchTemplate.RequestItem item)
206+
public MultiSearchTemplateRequestDescriptor Add(Core.MSearchTemplate.SearchTemplateRequestItem item)
207207
{
208208
_items.Add(item);
209209
return this;

src/Elastic.Clients.Elasticsearch/_Generated/Types/Core/RequestItem.g.cs

-38
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
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.IO;
7+
using System.Threading.Tasks;
8+
using Elastic.Clients.Elasticsearch.Core.MSearch;
9+
using Elastic.Clients.Elasticsearch.Core.MSearchTemplate;
10+
using Elastic.Clients.Elasticsearch.Serialization;
11+
using Tests.Domain;
12+
using VerifyTests;
13+
using VerifyXunit;
14+
15+
namespace Tests.Core.MSearchTemplate;
16+
17+
[UsesVerify]
18+
public class MSearchTemplateSerialization
19+
{
20+
private readonly VerifySettings _verifySettings;
21+
22+
public MSearchTemplateSerialization()
23+
{
24+
_verifySettings = new VerifySettings();
25+
_verifySettings.DisableRequireUniquePrefix();
26+
}
27+
28+
[U]
29+
public async Task SerializesMultiSearchTemplateRequest()
30+
{
31+
var settings = new ElasticsearchClientSettings();
32+
settings.DefaultMappingFor<Project>(m => m.IndexName("projects"));
33+
34+
var ms = new MemoryStream();
35+
36+
var request = (IStreamSerializable)new MultiSearchTemplateRequest
37+
{
38+
SearchTemplates = new List<SearchTemplateRequestItem>
39+
{
40+
new SearchTemplateRequestItem(new MultisearchHeader { Index = Infer.Index<Project>() }, new TemplateConfig { Id = "my-search-template", Params = new Dictionary<string, object>
41+
{
42+
{ "query_string", "hello world" },
43+
{ "from", 0 }
44+
}}),
45+
new SearchTemplateRequestItem(new MultisearchHeader { Index = Infer.Index<Project>() }, new TemplateConfig { Id = "my-search-template", Params = new Dictionary<string, object>
46+
{
47+
{ "query_type", "match_all" }
48+
}}),
49+
}
50+
};
51+
52+
await request.SerializeAsync(ms, settings);
53+
54+
ms.Position = 0;
55+
var reader = new StreamReader(ms);
56+
var ndjson = reader.ReadToEnd();
57+
58+
await Verifier.Verify(ndjson, _verifySettings);
59+
60+
ms = new MemoryStream();
61+
request.Serialize(ms, settings);
62+
63+
ms.Position = 0;
64+
reader = new StreamReader(ms);
65+
ndjson = reader.ReadToEnd();
66+
67+
await Verifier.Verify(ndjson, _verifySettings);
68+
}
69+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{"index":"projects"}
2+
{"id":"my-search-template","params":{"query_string":"hello world","from":0}}
3+
{"index":"projects"}
4+
{"id":"my-search-template","params":{"query_type":"match_all"}}

0 commit comments

Comments
 (0)