Skip to content

[Backport 8.2] Community backports for 8.1.3 #7803

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
Jul 11, 2023
Merged
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
19 changes: 14 additions & 5 deletions src/Elastic.Clients.Elasticsearch/Api/ResponseItem.cs
Original file line number Diff line number Diff line change
@@ -2,6 +2,8 @@
// 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;

namespace Elastic.Clients.Elasticsearch.Core.Bulk;

public abstract partial class ResponseItem
@@ -15,12 +17,19 @@ public bool IsValid
if (Error is not null)
return false;

return Operation.ToLowerInvariant() switch
var operation = Operation;

if (operation.Equals("delete", StringComparison.OrdinalIgnoreCase))
return Status is 200 or 404;

if (operation.Equals("create", StringComparison.OrdinalIgnoreCase) ||
operation.Equals("update", StringComparison.OrdinalIgnoreCase) ||
operation.Equals("index", StringComparison.OrdinalIgnoreCase))
{
"delete" => Status == 200 || Status == 404,
"update" or "index" or "create" => Status == 200 || Status == 201,
_ => false,
};
return Status is 200 or 201;
}

return false;
}
}
}
11 changes: 11 additions & 0 deletions src/Elastic.Clients.Elasticsearch/Core/IEnumStruct.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// 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.

namespace Elastic.Clients.Elasticsearch.Core;

internal interface IEnumStruct<TSelf> where TSelf : struct, IEnumStruct<TSelf>
{
// TODO: Can be made static when targeting .NET 7 and higher
TSelf Create(string value);
}
Original file line number Diff line number Diff line change
@@ -73,7 +73,6 @@ public Field(PropertyInfo property, double? boost = null, string format = null)
/// </remarks>
public string? Format { get; set; }

[JsonIgnore]
internal bool CachableExpression { get; }

/// <summary>
Original file line number Diff line number Diff line change
@@ -12,6 +12,9 @@ namespace Elastic.Clients.Elasticsearch;

internal sealed class FieldConverter : JsonConverter<Field>
{
private static readonly JsonEncodedText FieldProperty = JsonEncodedText.Encode("field");
private static readonly JsonEncodedText FormatProperty = JsonEncodedText.Encode("format");

private IElasticsearchClientSettings _settings;

public override void WriteAsPropertyName(Utf8JsonWriter writer, Field value, JsonSerializerOptions options)
@@ -48,19 +51,19 @@ private static Field ReadObjectField(ref Utf8JsonReader reader)
{
if (reader.TokenType == JsonTokenType.PropertyName)
{
var propertyName = reader.GetString();
reader.Read();

switch (propertyName)
if (reader.ValueTextEquals(FieldProperty.EncodedUtf8Bytes))
{
reader.Read();
field = reader.GetString();
}
else if (reader.ValueTextEquals(FormatProperty.EncodedUtf8Bytes))
{
reader.Read();
format = reader.GetString();
}
else
{
case "field":
field = reader.GetString();
break;
case "format":
format = reader.GetString();
break;
default:
throw new JsonException("Unexpected property while reading `Field`.");
throw new JsonException($"Unexpected property while reading `{nameof(Field)}`.");
}
}
}
@@ -70,19 +73,13 @@ private static Field ReadObjectField(ref Utf8JsonReader reader)
return new Field(field, format);
}

throw new JsonException("Unable to read `Field` from JSON.");
throw new JsonException($"Unable to read `{nameof(Field)}` from JSON.");
}

public override void Write(Utf8JsonWriter writer, Field value, JsonSerializerOptions options)
{
InitializeSettings(options);

if (value is null)
{
writer.WriteNullValue();
return;
}

var fieldName = _settings.Inferrer.Field(value);

if (string.IsNullOrEmpty(value.Format))
@@ -92,10 +89,8 @@ public override void Write(Utf8JsonWriter writer, Field value, JsonSerializerOpt
else
{
writer.WriteStartObject();
writer.WritePropertyName("field");
writer.WriteStringValue(fieldName);
writer.WritePropertyName("format");
writer.WriteStringValue(value.Format);
writer.WriteString(FieldProperty, fieldName);
writer.WriteString(FormatProperty, value.Format);
writer.WriteEndObject();
}
}
42 changes: 1 addition & 41 deletions src/Elastic.Clients.Elasticsearch/Core/Infer/Id/Ids.cs
Original file line number Diff line number Diff line change
@@ -6,7 +6,6 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text.Json;
using System.Text.Json.Serialization;
using Elastic.Transport;

@@ -22,7 +21,7 @@ public partial class Ids : IUrlParameter, IEquatable<Ids>

public Ids(IList<Id> ids) => _ids = ids;

public Ids(IEnumerable<string> ids) => _ids = ids?.Select(i => new Id(i)).ToList();
public Ids(IEnumerable<string> ids) => _ids = ids.Select(i => new Id(i)).ToList();

public Ids(string value)
{
@@ -84,42 +83,3 @@ public override int GetHashCode()

public static bool operator !=(Ids left, Ids right) => !Equals(left, right);
}

internal sealed class IdsConverter : JsonConverter<Ids>
{
public override Ids? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType != JsonTokenType.StartArray)
throw new JsonException($"Unexpected JSON token. Expected {JsonTokenType.StartArray} but read {reader.TokenType}");

var ids = new List<Id>();

while (reader.Read() && reader.TokenType != JsonTokenType.EndArray)
{
var id = JsonSerializer.Deserialize<Id>(ref reader, options);

if (id is not null)
ids.Add(id);
}

return new Ids(ids);
}

public override void Write(Utf8JsonWriter writer, Ids value, JsonSerializerOptions options)
{
if (value is null)
{
writer.WriteNullValue();
return;
}

writer.WriteStartArray();

foreach (var id in value.IdsToSerialize)
{
JsonSerializer.Serialize<Id>(writer, id, options);
}

writer.WriteEndArray();
}
}
49 changes: 49 additions & 0 deletions src/Elastic.Clients.Elasticsearch/Core/Infer/Id/IdsConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// 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;
using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace Elastic.Clients.Elasticsearch;

internal sealed class IdsConverter : JsonConverter<Ids>
{
public override Ids? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType != JsonTokenType.StartArray)
throw new JsonException($"Unexpected JSON token. Expected {JsonTokenType.StartArray} but read {reader.TokenType}");

var ids = new List<Id>();

while (reader.Read() && reader.TokenType != JsonTokenType.EndArray)
{
var id = JsonSerializer.Deserialize<Id>(ref reader, options);

if (id is not null)
ids.Add(id);
}

return new Ids(ids);
}

public override void Write(Utf8JsonWriter writer, Ids value, JsonSerializerOptions options)
{
if (value is null)
{
writer.WriteNullValue();
return;
}

writer.WriteStartArray();

foreach (var id in value.IdsToSerialize)
{
JsonSerializer.Serialize<Id>(writer, id, options);
}

writer.WriteEndArray();
}
}
16 changes: 12 additions & 4 deletions src/Elastic.Clients.Elasticsearch/Core/Infer/Metric/Metrics.cs
Original file line number Diff line number Diff line change
@@ -4,7 +4,6 @@

using System;
using System.Collections.Generic;
using System.Linq;
using Elastic.Transport;

namespace Elastic.Clients.Elasticsearch;
@@ -53,8 +52,8 @@ public bool Equals(Metrics other)
{
if (other is null) return false;

// Equality is true when the metrics names in both instances are equal, regardless of their order in the set.
return Values.OrderBy(t => t).SequenceEqual(other.Values.OrderBy(t => t));
// Equality is true when both instances have the same metric names.
return Values.SetEquals(other.Values);
}

string IUrlParameter.GetString(ITransportConfiguration settings) => GetString();
@@ -71,7 +70,16 @@ private string GetString()
}

/// <inheritdoc />
public override int GetHashCode() => Values != null ? Values.GetHashCode() : 0;
public override int GetHashCode()
{
// Lifting the minimal target framework to .NET Standard 2.1
// would be the best solution ever due to the HashCode type.
var hashCode = 0;
foreach (var metric in Values)
hashCode = (hashCode * 397) ^ metric.GetHashCode();

return hashCode;
}

public static bool operator ==(Metrics left, Metrics right) => Equals(left, right);
public static bool operator !=(Metrics left, Metrics right) => !Equals(left, right);
Original file line number Diff line number Diff line change
@@ -75,6 +75,7 @@ public override void Write(Utf8JsonWriter writer, double value, JsonSerializerOp
if (bytes.Length < utf8bytes.Length)
{
bytes.CopyTo(utf8bytes);
return;
}
}
catch
Original file line number Diff line number Diff line change
@@ -3,24 +3,18 @@
// See the LICENSE file in the project root for more information.

using System;
using System.Reflection;
using System.Text.Json;
using System.Text.Json.Serialization;
using Elastic.Clients.Elasticsearch.Core;

namespace Elastic.Clients.Elasticsearch.Serialization;

internal sealed class EnumStructConverter<T> : JsonConverter<T> where T : new()
internal sealed class EnumStructConverter<T> : JsonConverter<T> where T : struct, IEnumStruct<T>
{
public override T? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var value = reader.GetString();

var instance = (T)Activator.CreateInstance(
typeof(T),
BindingFlags.Instance | BindingFlags.NonPublic,
args: new object[] { value }, // TODO: Perf - Review use of ArrayPool
binder: null,
culture: null)!;
var instance = default(T).Create(value);

return instance;
}
@@ -30,7 +24,7 @@ public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions
var enumValue = value.ToString();

if (!string.IsNullOrEmpty(enumValue))
writer.WriteStringValue(value.ToString());
writer.WriteStringValue(enumValue);
else
writer.WriteNullValue();
}
Original file line number Diff line number Diff line change
@@ -75,6 +75,7 @@ public override void Write(Utf8JsonWriter writer, float value, JsonSerializerOpt
if (bytes.Length < utf8bytes.Length)
{
bytes.CopyTo(utf8bytes);
return;
}
}
catch
33 changes: 21 additions & 12 deletions src/Elastic.Clients.Elasticsearch/Serialization/UnionConverter.cs
Original file line number Diff line number Diff line change
@@ -122,12 +122,6 @@ private class DerivedUnionConverterInner<TType, TItem1, TItem2> : JsonConverter<
public override void Write(Utf8JsonWriter writer, TType value,
JsonSerializerOptions options)
{
if (value is null)
{
writer.WriteNullValue();
return;
}

if (value.Item1 is not null)
{
JsonSerializer.Serialize(writer, value.Item1, value.Item1.GetType(), options);
@@ -214,15 +208,30 @@ private class BucketsConverter<TBucket> : JsonConverter<Buckets<TBucket>>
{
public override Buckets<TBucket>? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
// TODO - Read ahead to establish the type - For now, hardcoded for lists
return reader.TokenType switch
{
JsonTokenType.Null => null,
JsonTokenType.StartArray => new(JsonSerializer.Deserialize<IReadOnlyCollection<TBucket>>(ref reader, options)),
JsonTokenType.StartObject => new(JsonSerializer.Deserialize<IReadOnlyDictionary<string, TBucket>>(ref reader, options)),
_ => throw new JsonException("Invalid bucket type")
};
}

var bucketType = typeToConvert.GetGenericArguments()[0];
public override void Write(Utf8JsonWriter writer, Buckets<TBucket> value, JsonSerializerOptions options)
{
if (value.Item1 is { } item1)
{
JsonSerializer.Serialize(writer, item1, options);
return;
}

var item = JsonSerializer.Deserialize(ref reader, typeof(IReadOnlyCollection<TBucket>), options);
if (value.Item2 is { } item2)
{
JsonSerializer.Serialize(writer, item2, options);
return;
}

return (Buckets<TBucket>)Activator.CreateInstance(typeof(Buckets<>).MakeGenericType(bucketType), item);
writer.WriteNullValue();
}

public override void Write(Utf8JsonWriter writer, Buckets<TBucket> value, JsonSerializerOptions options) => throw new NotImplementedException();
}
}
Original file line number Diff line number Diff line change
@@ -22,6 +22,7 @@
using System.Text.Json.Serialization;
using System.Runtime.Serialization;
using Elastic.Transport;
using Elastic.Clients.Elasticsearch.Core;
using Elastic.Clients.Elasticsearch.Serialization;

namespace Elastic.Clients.Elasticsearch.Aggregations;
Original file line number Diff line number Diff line change
@@ -22,6 +22,7 @@
using System.Text.Json.Serialization;
using System.Runtime.Serialization;
using Elastic.Transport;
using Elastic.Clients.Elasticsearch.Core;
using Elastic.Clients.Elasticsearch.Serialization;

namespace Elastic.Clients.Elasticsearch.Analysis;
Loading