Skip to content

[Backport 8.3] Fix MultiSearchTemplateRequest body #7012

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 24, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/integration-jobs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
'8.2.3',
'8.3.3',
'8.4.3',
"8.5.0",
"8.5.2",
'8.6.0-SNAPSHOT',
'latest-8'
]
Expand Down
36 changes: 36 additions & 0 deletions docs/release-notes/release-notes-8.0.1.asciidoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
[[release-notes-8.0.1]]
== Release notes v8.0.1

[discrete]
=== Bug fixes

- Fix MultiSearchTemplateRequest serialization (issue:
https://github.com/elastic/elasticsearch-net/issues/7006[#7006])

[discrete]
=== Breaking changes

This release includes the following breaking changes:

[discrete]
==== MultiSearchTemplate type changes

The `Core.MSearchTemplate.RequestItem` type has been renamed to
`Core.MSearchTemplate.SearchTemplateRequestItem`. It no longer derives from the
`Union<T1, T2>` type. It has been manually designed to support serialisation to
NDJSON, as required by the MSearchTemplate endpoint.

The `MultiSearchTemplateRequest.SearchTemplates` property has been updated to
use this newly defined type.

This breaking change has been included in this patch release due to the
original code-generated type not functioning correctly and therefore we have
determined that this should ship ASAP.

[discrete]
=== MultiSearch type changes

The `Core.MSearch.SearchRequestItem` type has been sealed for consistency with
the design choices in the rest of the client. While technically breaking, we
have decided that this should be included in this release before any potential
derived types may exist in consuming applications.
8 changes: 7 additions & 1 deletion docs/release-notes/release-notes.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@
= Release notes

* <<breaking-changes-policy,Breaking changes policy>>
* <<release-notes-8.0.0,Version 8.0.0>>

[discrete]
== Version 8.x

* <<release-notes-8.0.0,Release notes v8.0.0>>
* <<release-notes-8.0.1,Release notes v8.0.1>>

include::breaking-change-policy.asciidoc[]
include::release-notes-8.0.0.asciidoc[]
include::release-notes-8.0.1.asciidoc[]
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,7 @@
<_Parameter1>true</_Parameter1>
</AssemblyAttribute>
</ItemGroup>
<ItemGroup>
<Folder Include="Types\Documents\" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
namespace Elastic.Clients.Elasticsearch.Core.MSearch;

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

Expand Down Expand Up @@ -52,5 +52,3 @@ async Task IStreamSerializable.SerializeAsync(Stream stream, IElasticsearchClien
}
}
}


Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Licensed to Elasticsearch B.V under one or more agreements.
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information.

using System.IO;
using System.Text.Json;
using System.Threading.Tasks;
using Elastic.Clients.Elasticsearch.Core.MSearch;
using Elastic.Clients.Elasticsearch.Serialization;
using Elastic.Transport;

namespace Elastic.Clients.Elasticsearch.Core.MSearchTemplate;

public sealed class SearchTemplateRequestItem : IStreamSerializable
{
public SearchTemplateRequestItem(TemplateConfig body) => Body = body;

public SearchTemplateRequestItem(MultisearchHeader header, TemplateConfig body)
{
Header = header;
Body = body;
}

public MultisearchHeader Header { get; init; }
public TemplateConfig Body { get; init; }

void IStreamSerializable.Serialize(Stream stream, IElasticsearchClientSettings settings, SerializationFormatting formatting)
{
if (Body is null)
return;

if (settings.RequestResponseSerializer.TryGetJsonSerializerOptions(out var options))
{
JsonSerializer.Serialize(stream, Header, options);
stream.WriteByte((byte)'\n');
JsonSerializer.Serialize(stream, Body, options);
stream.WriteByte((byte)'\n');
}
}

async Task IStreamSerializable.SerializeAsync(Stream stream, IElasticsearchClientSettings settings, SerializationFormatting formatting)
{
if (Body is null)
return;

if (settings.RequestResponseSerializer.TryGetJsonSerializerOptions(out var options))
{
await JsonSerializer.SerializeAsync(stream, Header, options).ConfigureAwait(false);
stream.WriteByte((byte)'\n');
await JsonSerializer.SerializeAsync(stream, Body, options).ConfigureAwait(false);
stream.WriteByte((byte)'\n');
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ public MultiSearchTemplateRequest(Elastic.Clients.Elasticsearch.Indices? indices
[JsonIgnore]
public bool? TypedKeys { get => Q<bool?>("typed_keys"); set => Q("typed_keys", value); }

public List<Core.MSearchTemplate.RequestItem> SearchTemplates { get; set; }
public List<Core.MSearchTemplate.SearchTemplateRequestItem> SearchTemplates { get; set; }

void IStreamSerializable.Serialize(Stream stream, IElasticsearchClientSettings settings, SerializationFormatting formatting)
{
Expand Down Expand Up @@ -125,7 +125,7 @@ protected override void Serialize(Utf8JsonWriter writer, JsonSerializerOptions o
{
}

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

public MultiSearchTemplateRequestDescriptor<TDocument> Add(Core.MSearchTemplate.RequestItem item)
public MultiSearchTemplateRequestDescriptor<TDocument> Add(Core.MSearchTemplate.SearchTemplateRequestItem item)
{
_items.Add(item);
return this;
Expand Down Expand Up @@ -180,7 +180,7 @@ protected override void Serialize(Utf8JsonWriter writer, JsonSerializerOptions o
{
}

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

public MultiSearchTemplateRequestDescriptor Add(Core.MSearchTemplate.RequestItem item)
public MultiSearchTemplateRequestDescriptor Add(Core.MSearchTemplate.SearchTemplateRequestItem item)
{
_items.Add(item);
return this;
Expand Down

This file was deleted.

69 changes: 69 additions & 0 deletions tests/Tests/Core/MSearchTemplate/MSearchTemplateSerialization.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// Licensed to Elasticsearch B.V under one or more agreements.
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information.

using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using Elastic.Clients.Elasticsearch.Core.MSearch;
using Elastic.Clients.Elasticsearch.Core.MSearchTemplate;
using Elastic.Clients.Elasticsearch.Serialization;
using Tests.Domain;
using VerifyTests;
using VerifyXunit;

namespace Tests.Core.MSearchTemplate;

[UsesVerify]
public class MSearchTemplateSerialization
{
private readonly VerifySettings _verifySettings;

public MSearchTemplateSerialization()
{
_verifySettings = new VerifySettings();
_verifySettings.DisableRequireUniquePrefix();
}

[U]
public async Task SerializesMultiSearchTemplateRequest()
{
var settings = new ElasticsearchClientSettings();
settings.DefaultMappingFor<Project>(m => m.IndexName("projects"));

var ms = new MemoryStream();

var request = (IStreamSerializable)new MultiSearchTemplateRequest
{
SearchTemplates = new List<SearchTemplateRequestItem>
{
new SearchTemplateRequestItem(new MultisearchHeader { Index = Infer.Index<Project>() }, new TemplateConfig { Id = "my-search-template", Params = new Dictionary<string, object>
{
{ "query_string", "hello world" },
{ "from", 0 }
}}),
new SearchTemplateRequestItem(new MultisearchHeader { Index = Infer.Index<Project>() }, new TemplateConfig { Id = "my-search-template", Params = new Dictionary<string, object>
{
{ "query_type", "match_all" }
}}),
}
};

await request.SerializeAsync(ms, settings);

ms.Position = 0;
var reader = new StreamReader(ms);
var ndjson = reader.ReadToEnd();

await Verifier.Verify(ndjson, _verifySettings);

ms = new MemoryStream();
request.Serialize(ms, settings);

ms.Position = 0;
reader = new StreamReader(ms);
ndjson = reader.ReadToEnd();

await Verifier.Verify(ndjson, _verifySettings);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{"index":"projects"}
{"id":"my-search-template","params":{"query_string":"hello world","from":0}}
{"index":"projects"}
{"id":"my-search-template","params":{"query_type":"match_all"}}