diff --git a/src/Elastic.Clients.Elasticsearch.JsonNetSerializer/ConnectionSettingsAwareContractResolver.cs b/src/Elastic.Clients.Elasticsearch.JsonNetSerializer/ConnectionSettingsAwareContractResolver.cs index 0c304b17109..930bb411e86 100644 --- a/src/Elastic.Clients.Elasticsearch.JsonNetSerializer/ConnectionSettingsAwareContractResolver.cs +++ b/src/Elastic.Clients.Elasticsearch.JsonNetSerializer/ConnectionSettingsAwareContractResolver.cs @@ -8,82 +8,87 @@ using System.Reflection; using Elastic.Clients.Elasticsearch; using Elastic.Clients.Elasticsearch.QueryDsl; +using Elastic.Clients.Elasticsearch.Serialization; using Newtonsoft.Json; using Newtonsoft.Json.Converters; using Newtonsoft.Json.Serialization; using JsonProperty = Newtonsoft.Json.Serialization.JsonProperty; -namespace Elastic.Clients.JsonNetSerializer +namespace Elastic.Clients.Elasticsearch.JsonNetSerializer; + +public class ConnectionSettingsAwareContractResolver : DefaultContractResolver { - public class ConnectionSettingsAwareContractResolver : DefaultContractResolver + public ConnectionSettingsAwareContractResolver(IElasticsearchClientSettings connectionSettings) => + ConnectionSettings = connectionSettings ?? throw new ArgumentNullException(nameof(connectionSettings)); + + protected IElasticsearchClientSettings ConnectionSettings { get; } + + protected override string ResolvePropertyName(string fieldName) => + ConnectionSettings.DefaultFieldNameInferrer != null + ? ConnectionSettings.DefaultFieldNameInferrer(fieldName) + : base.ResolvePropertyName(fieldName); + + protected override JsonContract CreateContract(Type objectType) + { + var contract = base.CreateContract(objectType); + if (objectType.IsEnum && objectType.GetCustomAttribute() != null) + contract.Converter = new StringEnumConverter(); + + return contract; + } + + protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) + { + var property = base.CreateProperty(member, memberSerialization); + ApplyShouldSerializer(property); + ApplyPropertyOverrides(member, property); + return property; + } + + /// Renames/Ignores a property based on the connection settings mapping or custom attributes for the property + private void ApplyPropertyOverrides(MemberInfo member, JsonProperty property) + { + //if (!ConnectionSettings.PropertyMappings.TryGetValue(member, out var propertyMapping)) + // propertyMapping = ElasticsearchPropertyAttributeBase.From(member); + + var serializerMapping = ConnectionSettings.PropertyMappingProvider?.CreatePropertyMapping(member); + + var nameOverride = /*propertyMapping?.Name ??*/ serializerMapping?.Name; + if (!string.IsNullOrWhiteSpace(nameOverride)) + property.PropertyName = nameOverride; + + var overrideIgnore = /*propertyMapping?.Ignore ??*/ serializerMapping?.Ignore; + if (overrideIgnore.HasValue) + property.Ignored = overrideIgnore.Value; + } + + private static void ApplyShouldSerializer(JsonProperty property) + { + if (property.PropertyType == typeof(QueryContainer)) + property.ShouldSerialize = o => ShouldSerializeQueryContainer(o, property); + else if (property.PropertyType == typeof(IEnumerable)) + property.ShouldSerialize = o => ShouldSerializeQueryContainers(o, property); + } + + private static bool ShouldSerializeQueryContainer(object o, JsonProperty prop) + { + if (o == null) + return false; + if (prop.ValueProvider.GetValue(o) is not QueryContainer q) + return false; + //return q.IsWritable; + return true; + } + + private static bool ShouldSerializeQueryContainers(object o, JsonProperty prop) { - public ConnectionSettingsAwareContractResolver(IElasticsearchClientSettings connectionSettings) => - ConnectionSettings = connectionSettings ?? throw new ArgumentNullException(nameof(connectionSettings)); - - protected IElasticsearchClientSettings ConnectionSettings { get; } - - protected override string ResolvePropertyName(string fieldName) => - ConnectionSettings.DefaultFieldNameInferrer != null - ? ConnectionSettings.DefaultFieldNameInferrer(fieldName) - : base.ResolvePropertyName(fieldName); - - protected override JsonContract CreateContract(Type objectType) - { - var contract = base.CreateContract(objectType); - if (objectType.IsEnum && objectType.GetCustomAttribute() != null) - contract.Converter = new StringEnumConverter(); - - return contract; - } - - protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) - { - var property = base.CreateProperty(member, memberSerialization); - ApplyShouldSerializer(property); - ApplyPropertyOverrides(member, property); - return property; - } - - /// Renames/Ignores a property based on the connection settings mapping or custom attributes for the property - private void ApplyPropertyOverrides(MemberInfo member, JsonProperty property) - { - //if (!ConnectionSettings.PropertyMappings.TryGetValue(member, out var propertyMapping)) - // propertyMapping = ElasticsearchPropertyAttributeBase.From(member); - - var serializerMapping = ConnectionSettings.PropertyMappingProvider?.CreatePropertyMapping(member); - - var nameOverride = /*propertyMapping?.Name ??*/ serializerMapping?.Name; - if (!string.IsNullOrWhiteSpace(nameOverride)) property.PropertyName = nameOverride; - - var overrideIgnore = /*propertyMapping?.Ignore ??*/ serializerMapping?.Ignore; - if (overrideIgnore.HasValue) - property.Ignored = overrideIgnore.Value; - } - - private static void ApplyShouldSerializer(JsonProperty property) - { - if (property.PropertyType == typeof(QueryContainer)) - property.ShouldSerialize = o => ShouldSerializeQueryContainer(o, property); - else if (property.PropertyType == typeof(IEnumerable)) - property.ShouldSerialize = o => ShouldSerializeQueryContainers(o, property); - } - - private static bool ShouldSerializeQueryContainer(object o, JsonProperty prop) - { - if (o == null) return false; - if (prop.ValueProvider.GetValue(o) is not QueryContainer q) return false; - //return q.IsWritable; - return true; - } - - private static bool ShouldSerializeQueryContainers(object o, JsonProperty prop) - { - if (o == null) return false; - if (prop.ValueProvider.GetValue(o) is not IEnumerable q) return false; - - var queryContainers = q as QueryContainer[] ?? q.ToArray(); - //return queryContainers.Any(qq => qq != null && ((QueryContainer)qq).IsWritable); - return queryContainers.Any(qq => qq != null); - } + if (o == null) + return false; + if (prop.ValueProvider.GetValue(o) is not IEnumerable q) + return false; + + var queryContainers = q as QueryContainer[] ?? q.ToArray(); + //return queryContainers.Any(qq => qq != null && ((QueryContainer)qq).IsWritable); + return queryContainers.Any(qq => qq != null); } } diff --git a/src/Elastic.Clients.Elasticsearch.JsonNetSerializer/ConnectionSettingsAwareSerializerBase.Customization.cs b/src/Elastic.Clients.Elasticsearch.JsonNetSerializer/ConnectionSettingsAwareSerializerBase.Customization.cs index 7e51e2cbe7c..d36406c52fc 100644 --- a/src/Elastic.Clients.Elasticsearch.JsonNetSerializer/ConnectionSettingsAwareSerializerBase.Customization.cs +++ b/src/Elastic.Clients.Elasticsearch.JsonNetSerializer/ConnectionSettingsAwareSerializerBase.Customization.cs @@ -11,7 +11,7 @@ using Elastic.Transport; using Newtonsoft.Json; -namespace Elastic.Clients.JsonNetSerializer +namespace Elastic.Clients.Elasticsearch.JsonNetSerializer { public abstract partial class ConnectionSettingsAwareSerializer : Serializer { diff --git a/src/Elastic.Clients.Elasticsearch.JsonNetSerializer/ConnectionSettingsAwareSerializerBase.PropertyMappingProvider.cs b/src/Elastic.Clients.Elasticsearch.JsonNetSerializer/ConnectionSettingsAwareSerializerBase.PropertyMappingProvider.cs index be37426d58b..f38cfdbabeb 100644 --- a/src/Elastic.Clients.Elasticsearch.JsonNetSerializer/ConnectionSettingsAwareSerializerBase.PropertyMappingProvider.cs +++ b/src/Elastic.Clients.Elasticsearch.JsonNetSerializer/ConnectionSettingsAwareSerializerBase.PropertyMappingProvider.cs @@ -8,7 +8,7 @@ using Elastic.Clients.Elasticsearch; using Newtonsoft.Json; -namespace Elastic.Clients.JsonNetSerializer +namespace Elastic.Clients.Elasticsearch.JsonNetSerializer { public abstract partial class ConnectionSettingsAwareSerializer : IPropertyMappingProvider { diff --git a/src/Elastic.Clients.Elasticsearch.JsonNetSerializer/ConnectionSettingsAwareSerializerBase.Serializer.cs b/src/Elastic.Clients.Elasticsearch.JsonNetSerializer/ConnectionSettingsAwareSerializerBase.Serializer.cs index 825f1cce184..856969b09bb 100644 --- a/src/Elastic.Clients.Elasticsearch.JsonNetSerializer/ConnectionSettingsAwareSerializerBase.Serializer.cs +++ b/src/Elastic.Clients.Elasticsearch.JsonNetSerializer/ConnectionSettingsAwareSerializerBase.Serializer.cs @@ -5,77 +5,75 @@ using System; using System.Collections.Generic; using System.Linq; -using Elastic.Clients.JsonNetSerializer.Converters; using Newtonsoft.Json; using Elastic.Transport; -using Elastic.Clients.Elasticsearch; using Newtonsoft.Json.Converters; +using Elastic.Clients.Elasticsearch.JsonNetSerializer.Converters; -namespace Elastic.Clients.JsonNetSerializer +namespace Elastic.Clients.Elasticsearch.JsonNetSerializer; + +public abstract partial class ConnectionSettingsAwareSerializer { - public abstract partial class ConnectionSettingsAwareSerializer + protected ConnectionSettingsAwareSerializer(Serializer builtinSerializer, IElasticsearchClientSettings connectionSettings) + : this(builtinSerializer, connectionSettings, null, null, null) { } + + internal ConnectionSettingsAwareSerializer( + Serializer builtinSerializer, + IElasticsearchClientSettings connectionSettings, + Func jsonSerializerSettingsFactory, + Action modifyContractResolver, + IEnumerable contractJsonConverters + ) { - protected ConnectionSettingsAwareSerializer(Serializer builtinSerializer, IElasticsearchClientSettings connectionSettings) - : this(builtinSerializer, connectionSettings, null, null, null) { } + JsonSerializerSettingsFactory = jsonSerializerSettingsFactory; + ModifyContractResolverCallback = modifyContractResolver; + ContractJsonConverters = contractJsonConverters ?? Enumerable.Empty(); - internal ConnectionSettingsAwareSerializer( - Serializer builtinSerializer, - IElasticsearchClientSettings connectionSettings, - Func jsonSerializerSettingsFactory, - Action modifyContractResolver, - IEnumerable contractJsonConverters - ) + ConnectionSettings = connectionSettings; + BuiltinSerializer = builtinSerializer; + Converters = new List { - JsonSerializerSettingsFactory = jsonSerializerSettingsFactory; - ModifyContractResolverCallback = modifyContractResolver; - ContractJsonConverters = contractJsonConverters ?? Enumerable.Empty(); - - ConnectionSettings = connectionSettings; - BuiltinSerializer = builtinSerializer; - Converters = new List - { - new HandleNestTypesOnSourceJsonConverter(BuiltinSerializer, connectionSettings.MemoryStreamFactory), - new TimeSpanToStringConverter(), - new StringEnumConverter() - }; - _serializer = CreateSerializer(SerializationFormatting.Indented); - _collapsedSerializer = CreateSerializer(SerializationFormatting.None); - } + new HandleNestTypesOnSourceJsonConverter(BuiltinSerializer, connectionSettings.MemoryStreamFactory), + new TimeSpanToStringConverter(), + new StringEnumConverter() + }; + _serializer = CreateSerializer(SerializationFormatting.Indented); + _collapsedSerializer = CreateSerializer(SerializationFormatting.None); + } - protected Serializer BuiltinSerializer { get; } + protected Serializer BuiltinSerializer { get; } - protected IElasticsearchClientSettings ConnectionSettings { get; } - protected IEnumerable ContractJsonConverters { get; } - protected Func JsonSerializerSettingsFactory { get; } - protected Action ModifyContractResolverCallback { get; } + protected IElasticsearchClientSettings ConnectionSettings { get; } + protected IEnumerable ContractJsonConverters { get; } + protected Func JsonSerializerSettingsFactory { get; } + protected Action ModifyContractResolverCallback { get; } - private List Converters { get; } + private List Converters { get; } - private JsonSerializer CreateSerializer(SerializationFormatting formatting) - { - var s = CreateJsonSerializerSettings() ?? new JsonSerializerSettings(); - var converters = CreateJsonConverters() ?? Enumerable.Empty(); - var contract = CreateContractResolver(); - s.Formatting = formatting == SerializationFormatting.Indented ? Formatting.Indented : Formatting.None; - s.ContractResolver = contract; - foreach (var converter in converters.Concat(Converters)) - s.Converters.Add(converter); + private JsonSerializer CreateSerializer(SerializationFormatting formatting) + { + var s = CreateJsonSerializerSettings() ?? new JsonSerializerSettings(); + var converters = CreateJsonConverters() ?? Enumerable.Empty(); + var contract = CreateContractResolver(); + s.Formatting = formatting == SerializationFormatting.Indented ? Formatting.Indented : Formatting.None; + s.ContractResolver = contract; + foreach (var converter in converters.Concat(Converters)) + s.Converters.Add(converter); - return JsonSerializer.Create(s); - } + return JsonSerializer.Create(s); + } - protected virtual ConnectionSettingsAwareContractResolver CreateContractResolver() - { - var contract = new ConnectionSettingsAwareContractResolver(ConnectionSettings); - ModifyContractResolver(contract); - return contract; - } + protected virtual ConnectionSettingsAwareContractResolver CreateContractResolver() + { + var contract = new ConnectionSettingsAwareContractResolver(ConnectionSettings); + ModifyContractResolver(contract); + return contract; + } - protected virtual JsonSerializerSettings CreateJsonSerializerSettings() => JsonSerializerSettingsFactory?.Invoke(); + protected virtual JsonSerializerSettings CreateJsonSerializerSettings() => JsonSerializerSettingsFactory?.Invoke(); - protected virtual IEnumerable CreateJsonConverters() => ContractJsonConverters; + protected virtual IEnumerable CreateJsonConverters() => ContractJsonConverters; - protected virtual void ModifyContractResolver(ConnectionSettingsAwareContractResolver resolver) => - ModifyContractResolverCallback?.Invoke(resolver); - } + protected virtual void ModifyContractResolver(ConnectionSettingsAwareContractResolver resolver) => + ModifyContractResolverCallback?.Invoke(resolver); } diff --git a/src/Elastic.Clients.Elasticsearch.JsonNetSerializer/Converters/HandleNestTypesOnSourceJsonConverter.cs b/src/Elastic.Clients.Elasticsearch.JsonNetSerializer/Converters/HandleNestTypesOnSourceJsonConverter.cs index 71e67a863f8..b887ecd1c44 100644 --- a/src/Elastic.Clients.Elasticsearch.JsonNetSerializer/Converters/HandleNestTypesOnSourceJsonConverter.cs +++ b/src/Elastic.Clients.Elasticsearch.JsonNetSerializer/Converters/HandleNestTypesOnSourceJsonConverter.cs @@ -11,7 +11,7 @@ using Newtonsoft.Json; using Newtonsoft.Json.Linq; -namespace Elastic.Clients.JsonNetSerializer.Converters +namespace Elastic.Clients.Elasticsearch.JsonNetSerializer.Converters { public class HandleNestTypesOnSourceJsonConverter : JsonConverter { diff --git a/src/Elastic.Clients.Elasticsearch.JsonNetSerializer/Converters/TimeSpanToStringConverter.cs b/src/Elastic.Clients.Elasticsearch.JsonNetSerializer/Converters/TimeSpanToStringConverter.cs index fb5e839d0b8..5d48ccd7af4 100644 --- a/src/Elastic.Clients.Elasticsearch.JsonNetSerializer/Converters/TimeSpanToStringConverter.cs +++ b/src/Elastic.Clients.Elasticsearch.JsonNetSerializer/Converters/TimeSpanToStringConverter.cs @@ -5,7 +5,7 @@ using System; using Newtonsoft.Json; -namespace Elastic.Clients.JsonNetSerializer.Converters +namespace Elastic.Clients.Elasticsearch.JsonNetSerializer.Converters { /// /// Included for compatibility reasons diff --git a/src/Elastic.Clients.Elasticsearch.JsonNetSerializer/JTokenExtensions.cs b/src/Elastic.Clients.Elasticsearch.JsonNetSerializer/JTokenExtensions.cs index 2c779821e38..58b6e23a928 100644 --- a/src/Elastic.Clients.Elasticsearch.JsonNetSerializer/JTokenExtensions.cs +++ b/src/Elastic.Clients.Elasticsearch.JsonNetSerializer/JTokenExtensions.cs @@ -7,7 +7,7 @@ using Newtonsoft.Json; using Newtonsoft.Json.Linq; -namespace Elastic.Clients.JsonNetSerializer +namespace Elastic.Clients.Elasticsearch.JsonNetSerializer { internal static class JTokenExtensions { diff --git a/src/Elastic.Clients.Elasticsearch.JsonNetSerializer/JsonNetSerializer.cs b/src/Elastic.Clients.Elasticsearch.JsonNetSerializer/JsonNetSerializer.cs index 9702ee5c6d6..db8361aa6fa 100644 --- a/src/Elastic.Clients.Elasticsearch.JsonNetSerializer/JsonNetSerializer.cs +++ b/src/Elastic.Clients.Elasticsearch.JsonNetSerializer/JsonNetSerializer.cs @@ -7,8 +7,9 @@ using Elastic.Transport; using Elastic.Clients.Elasticsearch; using Newtonsoft.Json; +using Elastic.Clients.Elasticsearch.JsonNetSerializer; -namespace Elastic.Clients.JsonNetSerializer +namespace Elastic.Clients.Elasticsearch.JsonNetSerializer { public class JsonNetSerializer : ConnectionSettingsAwareSerializer { diff --git a/src/Elastic.Clients.Elasticsearch.JsonNetSerializer/JsonReaderExtensions.cs b/src/Elastic.Clients.Elasticsearch.JsonNetSerializer/JsonReaderExtensions.cs index 75bb9833bf7..c2a45bc962c 100644 --- a/src/Elastic.Clients.Elasticsearch.JsonNetSerializer/JsonReaderExtensions.cs +++ b/src/Elastic.Clients.Elasticsearch.JsonNetSerializer/JsonReaderExtensions.cs @@ -7,7 +7,7 @@ using Newtonsoft.Json; using Newtonsoft.Json.Linq; -namespace Elastic.Clients.JsonNetSerializer +namespace Elastic.Clients.Elasticsearch.JsonNetSerializer { internal static class JsonReaderExtensions { diff --git a/src/Elastic.Clients.Elasticsearch/Api/BulkRequest.cs b/src/Elastic.Clients.Elasticsearch/Api/BulkRequest.cs index be6647b7fd4..02bc0bd8c51 100644 --- a/src/Elastic.Clients.Elasticsearch/Api/BulkRequest.cs +++ b/src/Elastic.Clients.Elasticsearch/Api/BulkRequest.cs @@ -9,6 +9,8 @@ using System.Collections.Generic; using System.Linq; using Elastic.Clients.Elasticsearch.Core.Bulk; +using Elastic.Clients.Elasticsearch.Serialization; +using Elastic.Clients.Elasticsearch.Requests; namespace Elastic.Clients.Elasticsearch { @@ -107,7 +109,7 @@ public BulkRequestDescriptor Index(TSource document, IndexName index, A return this; } - public BulkRequestDescriptor Update(BulkUpdateOperationBase update) + public BulkRequestDescriptor Update(BulkUpdateOperation update) { _operations.Add(update); return this; diff --git a/src/Elastic.Clients.Elasticsearch/Api/BulkResponse.cs b/src/Elastic.Clients.Elasticsearch/Api/BulkResponse.cs index f5924aa3f74..d81b6f3a104 100644 --- a/src/Elastic.Clients.Elasticsearch/Api/BulkResponse.cs +++ b/src/Elastic.Clients.Elasticsearch/Api/BulkResponse.cs @@ -13,11 +13,11 @@ namespace Elastic.Clients.Elasticsearch public partial class BulkResponse { [JsonConverter(typeof(BulkResponseItemConverter)), JsonPropertyName("items")] - public IReadOnlyList Items { get; init; } + public IReadOnlyList Items { get; init; } [JsonIgnore] - public IEnumerable ItemsWithErrors => !Items.HasAny() - ? Enumerable.Empty() + public IEnumerable ItemsWithErrors => !Items.HasAny() + ? Enumerable.Empty() : Items.Where(i => !i.IsValid); public override bool IsValid => base.IsValid && !Errors && !ItemsWithErrors.HasAny(); diff --git a/src/Elastic.Clients.Elasticsearch/Api/CreateRequest.cs b/src/Elastic.Clients.Elasticsearch/Api/CreateRequest.cs index 27fc2f5a550..54ac0d80058 100644 --- a/src/Elastic.Clients.Elasticsearch/Api/CreateRequest.cs +++ b/src/Elastic.Clients.Elasticsearch/Api/CreateRequest.cs @@ -2,6 +2,7 @@ // 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 Elastic.Clients.Elasticsearch.Serialization; using Elastic.Transport; using System.Text.Json; diff --git a/src/Elastic.Clients.Elasticsearch/Api/IndexRequest.cs b/src/Elastic.Clients.Elasticsearch/Api/IndexRequest.cs index fe56e30856f..09e6e4d527f 100644 --- a/src/Elastic.Clients.Elasticsearch/Api/IndexRequest.cs +++ b/src/Elastic.Clients.Elasticsearch/Api/IndexRequest.cs @@ -4,6 +4,8 @@ using System.Text.Json; using System.Text.Json.Serialization; +using Elastic.Clients.Elasticsearch.Requests; +using Elastic.Clients.Elasticsearch.Serialization; using Elastic.Transport; namespace Elastic.Clients.Elasticsearch diff --git a/src/Elastic.Clients.Elasticsearch/Api/BulkResponseItemBase.cs b/src/Elastic.Clients.Elasticsearch/Api/ResponseItem.cs similarity index 92% rename from src/Elastic.Clients.Elasticsearch/Api/BulkResponseItemBase.cs rename to src/Elastic.Clients.Elasticsearch/Api/ResponseItem.cs index 4a885d8e3b4..79729ad31c6 100644 --- a/src/Elastic.Clients.Elasticsearch/Api/BulkResponseItemBase.cs +++ b/src/Elastic.Clients.Elasticsearch/Api/ResponseItem.cs @@ -4,7 +4,7 @@ namespace Elastic.Clients.Elasticsearch.Core.Bulk { - public abstract partial class BulkResponseItemBase + public abstract partial class ResponseItem { public abstract string Operation { get; } diff --git a/src/Elastic.Clients.Elasticsearch/Api/SearchRequest.cs b/src/Elastic.Clients.Elasticsearch/Api/SearchRequest.cs index f3f35222db0..ddf31f555f2 100644 --- a/src/Elastic.Clients.Elasticsearch/Api/SearchRequest.cs +++ b/src/Elastic.Clients.Elasticsearch/Api/SearchRequest.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System; +using Elastic.Clients.Elasticsearch.Requests; namespace Elastic.Clients.Elasticsearch { diff --git a/src/Elastic.Clients.Elasticsearch/Api/SourceResponse.cs b/src/Elastic.Clients.Elasticsearch/Api/SourceResponse.cs index 09b6d82f5a1..1e2cb42467e 100644 --- a/src/Elastic.Clients.Elasticsearch/Api/SourceResponse.cs +++ b/src/Elastic.Clients.Elasticsearch/Api/SourceResponse.cs @@ -4,6 +4,7 @@ using System.Text.Json; using System.IO; +using Elastic.Clients.Elasticsearch.Serialization; namespace Elastic.Clients.Elasticsearch { diff --git a/src/Elastic.Clients.Elasticsearch/Client/ElasticsearchClient.cs b/src/Elastic.Clients.Elasticsearch/Client/ElasticsearchClient.cs index 2542b8a8265..0ddb77861f4 100644 --- a/src/Elastic.Clients.Elasticsearch/Client/ElasticsearchClient.cs +++ b/src/Elastic.Clients.Elasticsearch/Client/ElasticsearchClient.cs @@ -8,6 +8,7 @@ using System.Text.Json; using System.Threading; using System.Threading.Tasks; +using Elastic.Clients.Elasticsearch.Requests; using Elastic.Transport; namespace Elastic.Clients.Elasticsearch; diff --git a/src/Elastic.Clients.Elasticsearch/Client/NamespacedClientProxy.cs b/src/Elastic.Clients.Elasticsearch/Client/NamespacedClientProxy.cs index 1753755ad58..3a5c1dc0424 100644 --- a/src/Elastic.Clients.Elasticsearch/Client/NamespacedClientProxy.cs +++ b/src/Elastic.Clients.Elasticsearch/Client/NamespacedClientProxy.cs @@ -5,6 +5,7 @@ using System; using System.Threading; using System.Threading.Tasks; +using Elastic.Clients.Elasticsearch.Requests; using Elastic.Transport; namespace Elastic.Clients.Elasticsearch diff --git a/src/Elastic.Clients.Elasticsearch/Common/Aggregations/Aggregation.cs b/src/Elastic.Clients.Elasticsearch/Common/Aggregations/Aggregation.cs index 9494b5bc07b..e24c9eb2803 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/Aggregations/Aggregation.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/Aggregations/Aggregation.cs @@ -15,6 +15,8 @@ internal interface IAggregation /// public abstract class Aggregation : IAggregation { + internal Aggregation() { } + public abstract string? Name { get; internal set; } //always evaluate to false so that each side of && equation is evaluated diff --git a/src/Elastic.Clients.Elasticsearch/Common/Aggregations/AggregationDictionary.cs b/src/Elastic.Clients.Elasticsearch/Common/Aggregations/AggregationDictionary.cs index 73b47ccbd59..10745b2d613 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/Aggregations/AggregationDictionary.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/Aggregations/AggregationDictionary.cs @@ -11,7 +11,7 @@ namespace Elastic.Clients.Elasticsearch.Aggregations; /// /// Describes aggregations to execute as part of a search. /// -public sealed class AggregationDictionary : IsADictionaryBase +public sealed class AggregationDictionary : IsADictionary { public AggregationDictionary() { } diff --git a/src/Elastic.Clients.Elasticsearch/Common/Configuration/ClrTypeDefaults.cs b/src/Elastic.Clients.Elasticsearch/Common/Configuration/ClrTypeDefaults.cs index 7b23e8b4af2..8cfd369bc8c 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/Configuration/ClrTypeDefaults.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/Configuration/ClrTypeDefaults.cs @@ -4,6 +4,7 @@ using System; using System.Linq.Expressions; +using Elastic.Clients.Elasticsearch.Fluent; namespace Elastic.Clients.Elasticsearch { @@ -57,7 +58,7 @@ public ClrTypeMapping() : base(typeof(TDocument)) { } public Expression> RoutingProperty { get; set; } } - public sealed class ClrTypeMappingDescriptor : DescriptorBase + public sealed class ClrTypeMappingDescriptor : Descriptor { internal Type _clrType; internal string _indexName; @@ -84,7 +85,7 @@ public sealed class ClrTypeMappingDescriptor : DescriptorBase Assign(disable, (a, v) => a._disableIdInference = v); } - public sealed class ClrTypeMappingDescriptor : DescriptorBase> + public sealed class ClrTypeMappingDescriptor : Descriptor> { internal Type _clrType = typeof(TDocument); internal string _indexName; diff --git a/src/Elastic.Clients.Elasticsearch/Common/Configuration/ElasticsearchClientSettings.cs b/src/Elastic.Clients.Elasticsearch/Common/Configuration/ElasticsearchClientSettings.cs index 672b4a8d169..81ad2a90790 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/Configuration/ElasticsearchClientSettings.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/Configuration/ElasticsearchClientSettings.cs @@ -8,6 +8,8 @@ using System.Linq; using System.Linq.Expressions; using System.Reflection; +using Elastic.Clients.Elasticsearch.Fluent; +using Elastic.Clients.Elasticsearch.Serialization; using Elastic.Transport; using Elastic.Transport.Products; using Elastic.Transport.Products.Elasticsearch; diff --git a/src/Elastic.Clients.Elasticsearch/Common/Configuration/IElasticsearchClientSettings.cs b/src/Elastic.Clients.Elasticsearch/Common/Configuration/IElasticsearchClientSettings.cs index 6f2795dc255..d12da6ba668 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/Configuration/IElasticsearchClientSettings.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/Configuration/IElasticsearchClientSettings.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Reflection; +using Elastic.Clients.Elasticsearch.Fluent; using Elastic.Transport; namespace Elastic.Clients.Elasticsearch diff --git a/src/Elastic.Clients.Elasticsearch/Common/DateTime/DateMath/DateMathOperation.cs b/src/Elastic.Clients.Elasticsearch/Common/DateTime/DateMath/DateMathOperation.cs index eb542b0115c..97b6443ae32 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/DateTime/DateMath/DateMathOperation.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/DateTime/DateMath/DateMathOperation.cs @@ -6,6 +6,7 @@ using System.Runtime.Serialization; using System.Text.Json; using System.Text.Json.Serialization; +using Elastic.Clients.Elasticsearch.Serialization; namespace Elastic.Clients.Elasticsearch; diff --git a/src/Elastic.Clients.Elasticsearch/Common/DateTime/DateMath/DateMathTimeUnit.cs b/src/Elastic.Clients.Elasticsearch/Common/DateTime/DateMath/DateMathTimeUnit.cs index 1e0b13040e5..424df43497b 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/DateTime/DateMath/DateMathTimeUnit.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/DateTime/DateMath/DateMathTimeUnit.cs @@ -6,6 +6,7 @@ using System.Runtime.Serialization; using System.Text.Json; using System.Text.Json.Serialization; +using Elastic.Clients.Elasticsearch.Serialization; namespace Elastic.Clients.Elasticsearch; diff --git a/src/Elastic.Clients.Elasticsearch/Common/EmptyReadOnly.cs b/src/Elastic.Clients.Elasticsearch/Common/EmptyReadOnly.cs new file mode 100644 index 00000000000..4c315cc8ec8 --- /dev/null +++ b/src/Elastic.Clients.Elasticsearch/Common/EmptyReadOnly.cs @@ -0,0 +1,19 @@ +// 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.Collections.ObjectModel; + +namespace Elastic.Clients.Elasticsearch; + +internal static class EmptyReadOnly +{ + public static readonly IReadOnlyCollection Collection = new ReadOnlyCollection(new TElement[0]); + public static readonly IReadOnlyList List = new List(); +} + +internal static class EmptyReadOnly +{ + public static readonly IReadOnlyDictionary Dictionary = new ReadOnlyDictionary(new Dictionary(0)); +} diff --git a/src/Elastic.Clients.Elasticsearch/Common/EmptyReadOnlyExtensions.cs b/src/Elastic.Clients.Elasticsearch/Common/EmptyReadOnlyExtensions.cs new file mode 100644 index 00000000000..516e97be6c3 --- /dev/null +++ b/src/Elastic.Clients.Elasticsearch/Common/EmptyReadOnlyExtensions.cs @@ -0,0 +1,18 @@ +// 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.Collections.ObjectModel; +using System.Linq; + +namespace Elastic.Clients.Elasticsearch; + +internal static class EmptyReadOnlyExtensions +{ + public static IReadOnlyCollection ToReadOnlyCollection(this IEnumerable enumerable) => + enumerable == null ? EmptyReadOnly.Collection : new ReadOnlyCollection(enumerable.ToList()); + + public static IReadOnlyCollection ToReadOnlyCollection(this IList enumerable) => + enumerable == null || enumerable.Count == 0 ? EmptyReadOnly.Collection : new ReadOnlyCollection(enumerable); +} diff --git a/src/Elastic.Clients.Elasticsearch/Common/Fields/FieldValue.cs b/src/Elastic.Clients.Elasticsearch/Common/Fields/FieldValue.cs index 692836ec624..532a27e1018 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/Fields/FieldValue.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/Fields/FieldValue.cs @@ -7,6 +7,7 @@ using System; using System.Diagnostics.CodeAnalysis; using System.Collections.Generic; +using Elastic.Clients.Elasticsearch.Serialization; namespace Elastic.Clients.Elasticsearch { diff --git a/src/Elastic.Clients.Elasticsearch/Common/Fields/FieldValues.cs b/src/Elastic.Clients.Elasticsearch/Common/Fields/FieldValues.cs index 72f7151df8e..c7ecb779b1d 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/Fields/FieldValues.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/Fields/FieldValues.cs @@ -12,7 +12,7 @@ namespace Elastic.Clients.Elasticsearch { [JsonConverter(typeof(FieldValuesConverter))] - public sealed class FieldValues : IsADictionaryBase + public sealed class FieldValues : IsADictionary { public static readonly FieldValues Empty = new(); diff --git a/src/Elastic.Clients.Elasticsearch/Common/Fluent/DescriptorBase.cs b/src/Elastic.Clients.Elasticsearch/Common/Fluent/Descriptor.cs similarity index 68% rename from src/Elastic.Clients.Elasticsearch/Common/Fluent/DescriptorBase.cs rename to src/Elastic.Clients.Elasticsearch/Common/Fluent/Descriptor.cs index 809187b492d..6b7c3250e2a 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/Fluent/DescriptorBase.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/Fluent/Descriptor.cs @@ -8,8 +8,9 @@ using System.Runtime.Serialization; using System.Text.Json; using System.Text.Json.Serialization; +using Elastic.Clients.Elasticsearch.Serialization; -namespace Elastic.Clients.Elasticsearch; +namespace Elastic.Clients.Elasticsearch.Fluent; public abstract class Descriptor { @@ -43,25 +44,29 @@ internal Descriptor() { } public override string ToString() => base.ToString(); } -public abstract class DescriptorBase : Descriptor - where TDescriptor : DescriptorBase +public abstract class Descriptor : Descriptor + where TDescriptor : Descriptor { private readonly TDescriptor _self; - internal DescriptorBase() : base() => _self = (TDescriptor)this; + // This internal ctor ensures that only types defined within the client assembly can derive from this base class. + // We don't expect consumers to derive from this public base class. + internal Descriptor() : base() => _self = (TDescriptor)this; [JsonIgnore] [IgnoreDataMember] protected TDescriptor Self => _self; [MethodImpl(MethodImplOptions.AggressiveInlining)] - protected TDescriptor Assign(TValue value, Action assign) => Fluent.Assign(_self, value, assign); + protected TDescriptor Assign(TValue value, Action assign) => FluentAssign.Assign(_self, value, assign); } -public abstract class SerializableDescriptorBase : DescriptorBase, ISelfSerializable - where TDescriptor : SerializableDescriptorBase +public abstract class SerializableDescriptor : Descriptor, ISelfSerializable + where TDescriptor : SerializableDescriptor { - internal SerializableDescriptorBase(): base() { } + // This internal ctor ensures that only types defined within the client assembly can derive from this base class. + // We don't expect consumers to derive from this public base class. + internal SerializableDescriptor(): base() { } void ISelfSerializable.Serialize(Utf8JsonWriter writer, JsonSerializerOptions options, IElasticsearchClientSettings settings) => Serialize(writer, options, settings); diff --git a/src/Elastic.Clients.Elasticsearch/Common/Fluent/Fluent.cs b/src/Elastic.Clients.Elasticsearch/Common/Fluent/Fluent.cs index 55471a2b751..c3d9572a920 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/Fluent/Fluent.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/Fluent/Fluent.cs @@ -5,13 +5,13 @@ using System; using System.Runtime.CompilerServices; -namespace Elastic.Clients.Elasticsearch; +namespace Elastic.Clients.Elasticsearch.Fluent; -internal static class Fluent +internal static class FluentAssign { [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static TDescriptor Assign(TDescriptor self, TValue value, Action assign) - where TDescriptor : DescriptorBase + where TDescriptor : Descriptor { assign(self, value); return self; diff --git a/src/Elastic.Clients.Elasticsearch/Common/Fluent/FluentDictionary.cs b/src/Elastic.Clients.Elasticsearch/Common/Fluent/FluentDictionary.cs index 230c646ce2e..7258083d1f4 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/Fluent/FluentDictionary.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/Fluent/FluentDictionary.cs @@ -4,7 +4,7 @@ using System.Collections.Generic; -namespace Elastic.Clients.Elasticsearch; +namespace Elastic.Clients.Elasticsearch.Fluent; /// /// Used in the "fluent" syntax to support chained configuration of dictionary entries. diff --git a/src/Elastic.Clients.Elasticsearch/Common/Fluent/IBuildableDescriptor.cs b/src/Elastic.Clients.Elasticsearch/Common/Fluent/IBuildableDescriptor.cs index 85cf6559bf5..697f243ae5a 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/Fluent/IBuildableDescriptor.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/Fluent/IBuildableDescriptor.cs @@ -2,7 +2,7 @@ // 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; +namespace Elastic.Clients.Elasticsearch.Fluent; /// /// Used to mark descriptors which can be used to build the object they describe. diff --git a/src/Elastic.Clients.Elasticsearch/Common/Fluent/Promise/IPromise.cs b/src/Elastic.Clients.Elasticsearch/Common/Fluent/Promise/IPromise.cs index 84a8aa76c53..2f467d0347a 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/Fluent/Promise/IPromise.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/Fluent/Promise/IPromise.cs @@ -2,9 +2,9 @@ // 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; +namespace Elastic.Clients.Elasticsearch.Fluent; -public interface IPromise where TValue : class +internal interface IPromise where TValue : class { TValue Value { get; } } diff --git a/src/Elastic.Clients.Elasticsearch/Common/Fluent/Promise/IsADictionaryDescriptor.cs b/src/Elastic.Clients.Elasticsearch/Common/Fluent/Promise/IsADictionaryDescriptor.cs index 6145bcaab42..b2721114005 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/Fluent/Promise/IsADictionaryDescriptor.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/Fluent/Promise/IsADictionaryDescriptor.cs @@ -4,7 +4,7 @@ using System; -namespace Elastic.Clients.Elasticsearch; +namespace Elastic.Clients.Elasticsearch.Fluent; public abstract class IsADictionaryDescriptor : PromiseDescriptor diff --git a/src/Elastic.Clients.Elasticsearch/Common/Fluent/Promise/PromiseDescriptor.cs b/src/Elastic.Clients.Elasticsearch/Common/Fluent/Promise/PromiseDescriptor.cs index 58e525205d0..5bf764e064d 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/Fluent/Promise/PromiseDescriptor.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/Fluent/Promise/PromiseDescriptor.cs @@ -4,7 +4,7 @@ using System; -namespace Elastic.Clients.Elasticsearch; +namespace Elastic.Clients.Elasticsearch.Fluent; public abstract class PromiseDescriptor : Descriptor, IPromise where TDescriptor : PromiseDescriptor diff --git a/src/Elastic.Clients.Elasticsearch/Common/Fluent/SelectorBase.cs b/src/Elastic.Clients.Elasticsearch/Common/Fluent/SelectorBase.cs deleted file mode 100644 index 907ca7bc8ac..00000000000 --- a/src/Elastic.Clients.Elasticsearch/Common/Fluent/SelectorBase.cs +++ /dev/null @@ -1,38 +0,0 @@ -// 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.ComponentModel; - -namespace Elastic.Clients.Elasticsearch -{ - public interface ISelector { } - - public abstract class SelectorBase : ISelector - { - /// - /// Hides the method. - /// - [Browsable(false)] - [EditorBrowsable(EditorBrowsableState.Never)] - // ReSharper disable once BaseObjectEqualsIsObjectEquals - //only used to hide by default - public override bool Equals(object obj) => base.Equals(obj); - - /// - /// Hides the method. - /// - [Browsable(false)] - [EditorBrowsable(EditorBrowsableState.Never)] - // ReSharper disable once BaseObjectGetHashCodeCallInGetHashCode - //only used to hide by default - public override int GetHashCode() => base.GetHashCode(); - - /// - /// Hides the method. - /// - [Browsable(false)] - [EditorBrowsable(EditorBrowsableState.Never)] - public override string ToString() => base.ToString(); - } -} diff --git a/src/Elastic.Clients.Elasticsearch/Common/Infer/PropertyMapping.cs b/src/Elastic.Clients.Elasticsearch/Common/Infer/PropertyMapping.cs index e165d6aaac2..45d548510ed 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/Infer/PropertyMapping.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/Infer/PropertyMapping.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System; +using Elastic.Clients.Elasticsearch.Serialization; namespace Elastic.Clients.Elasticsearch { diff --git a/src/Elastic.Clients.Elasticsearch/Common/Infer/PropertyName/PropertyName.cs b/src/Elastic.Clients.Elasticsearch/Common/Infer/PropertyName/PropertyName.cs index 6e85ba3124a..ece36b82d7d 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/Infer/PropertyName/PropertyName.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/Infer/PropertyName/PropertyName.cs @@ -7,6 +7,7 @@ using System.Linq.Expressions; using System.Reflection; using System.Text.Json.Serialization; +using Elastic.Clients.Elasticsearch.Serialization; using Elastic.Transport; namespace Elastic.Clients.Elasticsearch diff --git a/src/Elastic.Clients.Elasticsearch/Common/IsADictionaryBase.cs b/src/Elastic.Clients.Elasticsearch/Common/IsADictionaryBase.cs index 756b94f65f3..3afb7a0a598 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/IsADictionaryBase.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/IsADictionaryBase.cs @@ -20,11 +20,11 @@ public interface IIsADictionary : IDictionary, IIsAD /// /// -public abstract class IsADictionaryBase : IIsADictionary +public abstract class IsADictionary : IIsADictionary { - internal IsADictionaryBase() => BackingDictionary = new Dictionary(); + internal IsADictionary() => BackingDictionary = new Dictionary(); - internal IsADictionaryBase(IDictionary backingDictionary) + internal IsADictionary(IDictionary backingDictionary) { if (backingDictionary != null) foreach (var key in backingDictionary.Keys) @@ -87,66 +87,3 @@ void ICollection>.Add(KeyValuePair item protected virtual TKey Sanitize(TKey key) => key; } - -public interface IIsAReadOnlyDictionary { } - -public interface IIsAReadOnlyDictionary : IReadOnlyDictionary, IIsAReadOnlyDictionary { } - -public abstract class IsAReadOnlyDictionaryBase : IIsAReadOnlyDictionary -{ - internal IsAReadOnlyDictionaryBase(IReadOnlyDictionary backingDictionary) - { - if (backingDictionary == null) - return; - - var dictionary = new Dictionary(backingDictionary.Count); - foreach (var key in backingDictionary.Keys) - // ReSharper disable once VirtualMemberCallInConstructor - // expect all implementations of Sanitize to be pure - dictionary[Sanitize(key)] = backingDictionary[key]; - - BackingDictionary = dictionary; - } - - public int Count => BackingDictionary.Count; - - public TValue this[TKey key] => BackingDictionary[key]; - - public IEnumerable Keys => BackingDictionary.Keys; - - public IEnumerable Values => BackingDictionary.Values; - protected internal IReadOnlyDictionary BackingDictionary { get; } = EmptyReadOnly.Dictionary; - - IEnumerator IEnumerable.GetEnumerator() => BackingDictionary.GetEnumerator(); - - IEnumerator> IEnumerable>.GetEnumerator() => - BackingDictionary.GetEnumerator(); - - public bool ContainsKey(TKey key) => BackingDictionary.ContainsKey(key); - - public bool TryGetValue(TKey key, out TValue value) => - BackingDictionary.TryGetValue(key, out value); - - protected virtual TKey Sanitize(TKey key) => key; -} - -internal static class EmptyReadOnlyExtensions -{ - public static IReadOnlyCollection ToReadOnlyCollection(this IEnumerable enumerable) => - enumerable == null ? EmptyReadOnly.Collection : new ReadOnlyCollection(enumerable.ToList()); - - public static IReadOnlyCollection ToReadOnlyCollection(this IList enumerable) => - enumerable == null || enumerable.Count == 0 ? EmptyReadOnly.Collection : new ReadOnlyCollection(enumerable); -} - - -internal static class EmptyReadOnly -{ - public static readonly IReadOnlyCollection Collection = new ReadOnlyCollection(new TElement[0]); - public static readonly IReadOnlyList List = new List(); -} - -internal static class EmptyReadOnly -{ - public static readonly IReadOnlyDictionary Dictionary = new ReadOnlyDictionary(new Dictionary(0)); -} diff --git a/src/Elastic.Clients.Elasticsearch/Common/IsAReadOnlyDictionary.cs b/src/Elastic.Clients.Elasticsearch/Common/IsAReadOnlyDictionary.cs new file mode 100644 index 00000000000..95c1f183a60 --- /dev/null +++ b/src/Elastic.Clients.Elasticsearch/Common/IsAReadOnlyDictionary.cs @@ -0,0 +1,50 @@ +// 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; +using System.Collections.Generic; + +namespace Elastic.Clients.Elasticsearch; + +public interface IIsAReadOnlyDictionary { } + +public interface IIsAReadOnlyDictionary : IReadOnlyDictionary, IIsAReadOnlyDictionary { } + +public abstract class IsAReadOnlyDictionary : IIsAReadOnlyDictionary +{ + internal IsAReadOnlyDictionary(IReadOnlyDictionary backingDictionary) + { + if (backingDictionary == null) + return; + + var dictionary = new Dictionary(backingDictionary.Count); + foreach (var key in backingDictionary.Keys) + // ReSharper disable once VirtualMemberCallInConstructor + // expect all implementations of Sanitize to be pure + dictionary[Sanitize(key)] = backingDictionary[key]; + + BackingDictionary = dictionary; + } + + public int Count => BackingDictionary.Count; + + public TValue this[TKey key] => BackingDictionary[key]; + + public IEnumerable Keys => BackingDictionary.Keys; + + public IEnumerable Values => BackingDictionary.Values; + protected internal IReadOnlyDictionary BackingDictionary { get; } = EmptyReadOnly.Dictionary; + + IEnumerator IEnumerable.GetEnumerator() => BackingDictionary.GetEnumerator(); + + IEnumerator> IEnumerable>.GetEnumerator() => + BackingDictionary.GetEnumerator(); + + public bool ContainsKey(TKey key) => BackingDictionary.ContainsKey(key); + + public bool TryGetValue(TKey key, out TValue value) => + BackingDictionary.TryGetValue(key, out value); + + protected virtual TKey Sanitize(TKey key) => key; +} diff --git a/src/Elastic.Clients.Elasticsearch/Common/RawJsonString.cs b/src/Elastic.Clients.Elasticsearch/Common/RawJsonString.cs new file mode 100644 index 00000000000..e8b1a6d5aac --- /dev/null +++ b/src/Elastic.Clients.Elasticsearch/Common/RawJsonString.cs @@ -0,0 +1,24 @@ +// 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.Text.Json; +using System.Text.Json.Serialization; + +namespace Elastic.Clients.Elasticsearch; + +#if NET6_0_OR_GREATER +public struct RawJsonString +{ +public RawJsonString(string rawJson) => Json = rawJson; + +public string Json { get; init; } +} + +internal class RawJsonConverter : JsonConverter +{ +public override RawJsonString Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => throw new NotImplementedException(); +public override void Write(Utf8JsonWriter writer, RawJsonString value, JsonSerializerOptions options) => writer.WriteRawValue(value.Json); +} +#endif diff --git a/src/Elastic.Clients.Elasticsearch/Common/Request/ApiUrls.cs b/src/Elastic.Clients.Elasticsearch/Common/Request/ApiUrls.cs index a3b0aa9bb31..1df2582145e 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/Request/ApiUrls.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/Request/ApiUrls.cs @@ -6,78 +6,77 @@ using System.Collections.Generic; using System.Linq; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch.Requests; + +/// +/// Each Request type holds a static instance of this class which creates cached builders for each +/// of the defined urls in the json spec. +/// +internal class ApiUrls { + private static readonly RouteValues EmptyRouteValues = new(); + private readonly string _errorMessageSuffix; + /// - /// Each Request type holds a static instance of this class which creates cached builders for each - /// of the defined urls in the json spec. + /// If the spec only defines a single non parameterizable route this allows us to shortcircuit and avoid hitting + /// the cached string builders. /// - internal class ApiUrls - { - private static readonly RouteValues EmptyRouteValues = new(); - private readonly string _errorMessageSuffix; + private readonly string _fixedUrl; - /// - /// If the spec only defines a single non parameterizable route this allows us to shortcircuit and avoid hitting - /// the cached string builders. - /// - private readonly string _fixedUrl; - - /// Only intended to be created once per request and stored in a static - internal ApiUrls(string[] routes) + /// Only intended to be created once per request and stored in a static + internal ApiUrls(string[] routes) + { + if (routes == null || routes.Length == 0) + throw new ArgumentException("urls is null or empty", nameof(routes)); + if (routes.Length == 1 && !routes[0].Contains("{")) + _fixedUrl = routes[0]; + else { - if (routes == null || routes.Length == 0) - throw new ArgumentException("urls is null or empty", nameof(routes)); - if (routes.Length == 1 && !routes[0].Contains("{")) - _fixedUrl = routes[0]; - else + foreach (var route in routes) { - foreach (var route in routes) - { - var bracketsCount = route.Count(c => c.Equals('{')); - if (Routes == null) - Routes = new Dictionary>(); - if (Routes.ContainsKey(bracketsCount)) - Routes[bracketsCount].Add(new UrlLookup(route)); - else - Routes.Add(bracketsCount, new List {new(route)}); - } + var bracketsCount = route.Count(c => c.Equals('{')); + if (Routes == null) + Routes = new Dictionary>(); + if (Routes.ContainsKey(bracketsCount)) + Routes[bracketsCount].Add(new UrlLookup(route)); + else + Routes.Add(bracketsCount, new List {new(route)}); } - - _errorMessageSuffix = string.Join(",", routes); - - // received multiple urls without brackets we resolve to first - if (Routes == null) - _fixedUrl = routes[0]; } - /// - /// Creates a lookup for number of parts <=> list of routes with that number of parts. - /// allows us to quickly find the right url to use in the list. - /// - public Dictionary> Routes { get; } + _errorMessageSuffix = string.Join(",", routes); - public string Resolve(RouteValues routeValues, IElasticsearchClientSettings settings) - { - if (_fixedUrl != null) - return _fixedUrl; + // received multiple urls without brackets we resolve to first + if (Routes == null) + _fixedUrl = routes[0]; + } - var resolved = routeValues.Resolve(settings); + /// + /// Creates a lookup for number of parts <=> list of routes with that number of parts. + /// allows us to quickly find the right url to use in the list. + /// + public Dictionary> Routes { get; } - if (!Routes.TryGetValue(resolved.Count, out var routes)) - throw new Exception($"No route taking {resolved.Count} parameters{_errorMessageSuffix}"); + public string Resolve(RouteValues routeValues, IElasticsearchClientSettings settings) + { + if (_fixedUrl != null) + return _fixedUrl; - if (routes.Count == 1) - return routes[0].ToUrl(resolved); + var resolved = routeValues.Resolve(settings); - //find the first url with N parts that has all provided named parts - foreach (var u in routes) - { - if (u.Matches(resolved)) - return u.ToUrl(resolved); - } + if (!Routes.TryGetValue(resolved.Count, out var routes)) + throw new Exception($"No route taking {resolved.Count} parameters{_errorMessageSuffix}"); + + if (routes.Count == 1) + return routes[0].ToUrl(resolved); - throw new Exception($"No route taking {routeValues.Count} parameters{_errorMessageSuffix}"); + //find the first url with N parts that has all provided named parts + foreach (var u in routes) + { + if (u.Matches(resolved)) + return u.ToUrl(resolved); } + + throw new Exception($"No route taking {routeValues.Count} parameters{_errorMessageSuffix}"); } } diff --git a/src/Elastic.Clients.Elasticsearch/Common/Request/IProxyRequest.cs b/src/Elastic.Clients.Elasticsearch/Common/Request/IProxyRequest.cs deleted file mode 100644 index e410f702cba..00000000000 --- a/src/Elastic.Clients.Elasticsearch/Common/Request/IProxyRequest.cs +++ /dev/null @@ -1,23 +0,0 @@ -// 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.Text.Json; -using Elastic.Transport; - -namespace Elastic.Clients.Elasticsearch -{ - internal interface ICustomJsonWriter - { - // TODO: Temp - //void WriteJson(Stream stream, ITransportSerializer sourceSerializer, SerializationFormatting formatting); - - void WriteJson(Utf8JsonWriter writer, Serializer sourceSerializer); - } - - - ///// - ///// Describes a request that serializes the document passed to when calling the fluent API. - ///// - //public interface IDocumentRequest { } -} diff --git a/src/Elastic.Clients.Elasticsearch/Common/Request/IRequest.cs b/src/Elastic.Clients.Elasticsearch/Common/Request/IRequest.cs new file mode 100644 index 00000000000..3fe54a38331 --- /dev/null +++ b/src/Elastic.Clients.Elasticsearch/Common/Request/IRequest.cs @@ -0,0 +1,40 @@ +// 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.Text.Json.Serialization; +using Elastic.Transport; + +namespace Elastic.Clients.Elasticsearch.Requests; + +public interface IRequest +{ + [JsonIgnore] string? Accept { get; } + + [JsonIgnore] string? ContentType { get; } + + [JsonIgnore] HttpMethod HttpMethod { get; } + + [JsonIgnore] bool SupportsBody { get; } + + [JsonIgnore] RouteValues RouteValues { get; } + + [JsonIgnore] IRequestParameters RequestParameters { get; } + + //[JsonIgnore] bool CanBeEmpty { get; } + + //[JsonIgnore] bool IsEmpty { get; } + + string GetUrl(IElasticsearchClientSettings settings); +} + +public interface IRequest : IRequest + where TParameters : class, IRequestParameters, new() +{ + /// + /// Used to describe request parameters that are not part of the body. e.g. query string, connection configuration + /// overrides, etc. + /// + [JsonIgnore] + new TParameters RequestParameters { get; } +} diff --git a/src/Elastic.Clients.Elasticsearch/Common/Request/PlainRequest.cs b/src/Elastic.Clients.Elasticsearch/Common/Request/PlainRequest.cs new file mode 100644 index 00000000000..485328faaa8 --- /dev/null +++ b/src/Elastic.Clients.Elasticsearch/Common/Request/PlainRequest.cs @@ -0,0 +1,82 @@ +// 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.Text.Json.Serialization; +using Elastic.Transport; + +namespace Elastic.Clients.Elasticsearch.Requests; + +public abstract partial class PlainRequest +{ + ///Include the stack trace of returned errors. + [JsonIgnore] + public bool? ErrorTrace + { + get => Q("error_trace"); + set => Q("error_trace", value); + } + + /// + /// A comma-separated list of filters used to reduce the response. + /// + /// Use of response filtering can result in a response from Elasticsearch + /// that cannot be correctly deserialized to the respective response type for the request. + /// In such situations, use the low level client to issue the request and handle response deserialization. + /// + /// + [JsonIgnore] + public string[] FilterPath + { + get => Q("filter_path"); + set => Q("filter_path", value); + } + + ///Return human readable values for statistics. + [JsonIgnore] + public bool? Human + { + get => Q("human"); + set => Q("human", value); + } + + ///Pretty format the returned JSON response. + [JsonIgnore] + public bool? Pretty + { + get => Q("pretty"); + set => Q("pretty", value); + } + + /// + /// The URL-encoded request definition. Useful for libraries that do not accept a request body for non-POST + /// requests. + /// + [JsonIgnore] + public string SourceQueryString + { + get => Q("source"); + set => Q("source", value); + } +} + +public abstract partial class PlainRequest : Request + where TParameters : class, IRequestParameters, new() +{ + // This internal ctor ensures that only types defined within the client assembly can derive from this base class. + // We don't expect consumers to derive from this public base class. + internal PlainRequest() { } + + protected PlainRequest(Func pathSelector) : base(pathSelector) { } + + /// + /// Specify settings for this request alone, handy if you need a custom timeout or want to bypass sniffing, retries + /// + [JsonIgnore] + public IRequestConfiguration RequestConfiguration + { + get => RequestState.RequestParameters.RequestConfiguration; + set => RequestState.RequestParameters.RequestConfiguration = value; + } +} diff --git a/src/Elastic.Clients.Elasticsearch/Common/Request/PlainRequestBase.cs b/src/Elastic.Clients.Elasticsearch/Common/Request/PlainRequestBase.cs deleted file mode 100644 index e977690f3bc..00000000000 --- a/src/Elastic.Clients.Elasticsearch/Common/Request/PlainRequestBase.cs +++ /dev/null @@ -1,62 +0,0 @@ -// 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.Text.Json.Serialization; - - -namespace Elastic.Clients.Elasticsearch -{ - public abstract partial class PlainRequestBase - { - ///Include the stack trace of returned errors. - [JsonIgnore] - public bool? ErrorTrace - { - get => Q("error_trace"); - set => Q("error_trace", value); - } - - /// - /// A comma-separated list of filters used to reduce the response. - /// - /// Use of response filtering can result in a response from Elasticsearch - /// that cannot be correctly deserialized to the respective response type for the request. - /// In such situations, use the low level client to issue the request and handle response deserialization. - /// - /// - [JsonIgnore] - public string[] FilterPath - { - get => Q("filter_path"); - set => Q("filter_path", value); - } - - ///Return human readable values for statistics. - [JsonIgnore] - public bool? Human - { - get => Q("human"); - set => Q("human", value); - } - - ///Pretty format the returned JSON response. - [JsonIgnore] - public bool? Pretty - { - get => Q("pretty"); - set => Q("pretty", value); - } - - /// - /// The URL-encoded request definition. Useful for libraries that do not accept a request body for non-POST - /// requests. - /// - [JsonIgnore] - public string SourceQueryString - { - get => Q("source"); - set => Q("source", value); - } - } -} diff --git a/src/Elastic.Clients.Elasticsearch/Common/Request/Request.cs b/src/Elastic.Clients.Elasticsearch/Common/Request/Request.cs new file mode 100644 index 00000000000..ded708999c2 --- /dev/null +++ b/src/Elastic.Clients.Elasticsearch/Common/Request/Request.cs @@ -0,0 +1,92 @@ +// 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.Text.Json.Serialization; +using Elastic.Transport; + +namespace Elastic.Clients.Elasticsearch.Requests; + +public abstract class Request : IRequest + where TParameters : class, IRequestParameters, new() +{ + private readonly TParameters _parameters; + + // ReSharper disable once VirtualMemberCallInConstructor + internal Request() + { + _parameters = new TParameters(); + // ReSharper disable once VirtualMemberCallInConstructor + RequestDefaults(_parameters); + } + + protected Request(Func pathSelector) + { + pathSelector(RequestState.RouteValues); + _parameters = new TParameters(); + // ReSharper disable once VirtualMemberCallInConstructor + RequestDefaults(_parameters); + } + + protected virtual HttpMethod? DynamicHttpMethod { get; } + + protected abstract HttpMethod HttpMethod { get; } + + protected abstract bool SupportsBody { get; } + + internal virtual void BeforeRequest() { } + + //protected virtual bool CanBeEmpty => false; + + //protected virtual bool IsEmpty => false; + + [JsonIgnore] protected IRequest RequestState => this; + + protected virtual string? Accept { get; } = null; + + protected virtual string? ContentType { get; } = null; + + internal abstract ApiUrls ApiUrls { get; } + + [JsonIgnore] HttpMethod IRequest.HttpMethod => DynamicHttpMethod ?? HttpMethod; + + [JsonIgnore] bool IRequest.SupportsBody => SupportsBody; + + //[JsonIgnore] bool IRequest.CanBeEmpty => CanBeEmpty; + + //[JsonIgnore] bool IRequest.IsEmpty => IsEmpty; + + [JsonIgnore] string? IRequest.Accept => Accept; + + [JsonIgnore] string? IRequest.ContentType => ContentType; + + [JsonIgnore] TParameters IRequest.RequestParameters => _parameters; + + IRequestParameters IRequest.RequestParameters => _parameters; + + [JsonIgnore] RouteValues IRequest.RouteValues { get; } = new(); + + string IRequest.GetUrl(IElasticsearchClientSettings settings) => ResolveUrl(RequestState.RouteValues, settings); + + protected virtual string ResolveUrl(RouteValues routeValues, IElasticsearchClientSettings settings) => + ApiUrls.Resolve(routeValues, settings); + + /// + /// Allows a request implementation to set certain request parameter defaults, use sparingly! + /// + protected virtual void RequestDefaults(TParameters parameters) { } + + protected TOut Q(string name) => RequestState.RequestParameters.GetQueryStringValue(name); + + protected void Q(string name, object value) => RequestState.RequestParameters.SetQueryString(name, value); + + protected void Q(string name, IStringable value) => RequestState.RequestParameters.SetQueryString(name, value.GetString()); + + protected void SetAcceptHeader(string format) + { + RequestState.RequestParameters.RequestConfiguration ??= new RequestConfiguration(); + RequestState.RequestParameters.RequestConfiguration.Accept = + RequestState.RequestParameters.AcceptHeaderFromFormat(format); + } +} diff --git a/src/Elastic.Clients.Elasticsearch/Common/Request/RequestBase.cs b/src/Elastic.Clients.Elasticsearch/Common/Request/RequestBase.cs deleted file mode 100644 index 4c58434a979..00000000000 --- a/src/Elastic.Clients.Elasticsearch/Common/Request/RequestBase.cs +++ /dev/null @@ -1,217 +0,0 @@ -// 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.ComponentModel; -using System.Text.Json; -using System.Text.Json.Serialization; -using Elastic.Transport; - -namespace Elastic.Clients.Elasticsearch -{ - public interface IRequest - { - [JsonIgnore] string? Accept { get; } - - [JsonIgnore] string? ContentType { get; } - - [JsonIgnore] HttpMethod HttpMethod { get; } - - [JsonIgnore] bool SupportsBody { get; } - - [JsonIgnore] RouteValues RouteValues { get; } - - [JsonIgnore] IRequestParameters RequestParameters { get; } - - //[JsonIgnore] bool CanBeEmpty { get; } - - //[JsonIgnore] bool IsEmpty { get; } - - string GetUrl(IElasticsearchClientSettings settings); - } - - public interface IRequest : IRequest - where TParameters : class, IRequestParameters, new() - { - /// - /// Used to describe request parameters that are not part of the body. e.g. query string, connection configuration - /// overrides, etc. - /// - [JsonIgnore] - new TParameters RequestParameters { get; } - } - - public abstract class RequestBase : IRequest - where TParameters : class, IRequestParameters, new() - { - private readonly TParameters _parameters; - - // ReSharper disable once VirtualMemberCallInConstructor - protected RequestBase() - { - _parameters = new TParameters(); - // ReSharper disable once VirtualMemberCallInConstructor - RequestDefaults(_parameters); - } - - protected RequestBase(Func pathSelector) - { - pathSelector(RequestState.RouteValues); - _parameters = new TParameters(); - // ReSharper disable once VirtualMemberCallInConstructor - RequestDefaults(_parameters); - } - - protected virtual HttpMethod? DynamicHttpMethod { get; } - - protected abstract HttpMethod HttpMethod { get; } - - protected abstract bool SupportsBody { get; } - - internal virtual void BeforeRequest() { } - - //protected virtual bool CanBeEmpty => false; - - //protected virtual bool IsEmpty => false; - - [JsonIgnore] protected IRequest RequestState => this; - - protected virtual string? Accept { get; } = null; - - protected virtual string? ContentType { get; } = null; - - internal abstract ApiUrls ApiUrls { get; } - - [JsonIgnore] HttpMethod IRequest.HttpMethod => DynamicHttpMethod ?? HttpMethod; - - [JsonIgnore] bool IRequest.SupportsBody => SupportsBody; - - //[JsonIgnore] bool IRequest.CanBeEmpty => CanBeEmpty; - - //[JsonIgnore] bool IRequest.IsEmpty => IsEmpty; - - [JsonIgnore] string? IRequest.Accept => Accept; - - [JsonIgnore] string? IRequest.ContentType => ContentType; - - [JsonIgnore] TParameters IRequest.RequestParameters => _parameters; - - IRequestParameters IRequest.RequestParameters => _parameters; - - [JsonIgnore] RouteValues IRequest.RouteValues { get; } = new(); - - string IRequest.GetUrl(IElasticsearchClientSettings settings) => ResolveUrl(RequestState.RouteValues, settings); - - protected virtual string ResolveUrl(RouteValues routeValues, IElasticsearchClientSettings settings) => - ApiUrls.Resolve(routeValues, settings); - - /// - /// Allows a request implementation to set certain request parameter defaults, use sparingly! - /// - protected virtual void RequestDefaults(TParameters parameters) { } - - protected TOut Q(string name) => RequestState.RequestParameters.GetQueryStringValue(name); - - protected void Q(string name, object value) => RequestState.RequestParameters.SetQueryString(name, value); - - protected void Q(string name, IStringable value) => RequestState.RequestParameters.SetQueryString(name, value.GetString()); - - protected void SetAcceptHeader(string format) - { - RequestState.RequestParameters.RequestConfiguration ??= new RequestConfiguration(); - RequestState.RequestParameters.RequestConfiguration.Accept = - RequestState.RequestParameters.AcceptHeaderFromFormat(format); - } - } - - public abstract partial class PlainRequestBase : RequestBase - where TParameters : class, IRequestParameters, new() - { - protected PlainRequestBase() { } - - protected PlainRequestBase(Func pathSelector) : base(pathSelector) { } - - /// - /// Specify settings for this request alone, handy if you need a custom timeout or want to bypass sniffing, retries - /// - [JsonIgnore] - public IRequestConfiguration RequestConfiguration - { - get => RequestState.RequestParameters.RequestConfiguration; - set => RequestState.RequestParameters.RequestConfiguration = value; - } - } - - /// - /// Base class for all Request descriptor types - /// - public abstract partial class - RequestDescriptorBase : RequestBase, ISelfSerializable - where TDescriptor : RequestDescriptorBase, IRequest - where TParameters : RequestParameters, new() - { - private readonly TDescriptor _descriptor; - - void ISelfSerializable.Serialize(Utf8JsonWriter writer, JsonSerializerOptions options, IElasticsearchClientSettings settings) => Serialize(writer, options, settings); - - internal RequestDescriptorBase() => _descriptor = (TDescriptor)this; - - protected abstract void Serialize(Utf8JsonWriter writer, JsonSerializerOptions options, IElasticsearchClientSettings settings); - - internal RequestDescriptorBase(Func pathSelector) : base(pathSelector) => - _descriptor = (TDescriptor)this; - - protected TDescriptor Self => _descriptor; - - protected RouteValues RouteValues => ((IRequest)this).RouteValues; - - protected TDescriptor Qs(string name, object value) - { - Q(name, value); - return _descriptor; - } - - protected TDescriptor Qs(string name, IStringable value) - { - Q(name, value.GetString()); - return _descriptor; - } - - /// - /// Specify settings for this request alone, handy if you need a custom timeout or want to bypass sniffing, retries - /// - public TDescriptor RequestConfiguration( - Func configurationSelector) - { - var rc = RequestState.RequestParameters.RequestConfiguration; - RequestState.RequestParameters.RequestConfiguration = - configurationSelector?.Invoke(new RequestConfigurationDescriptor(rc)) ?? rc; - return _descriptor; - } - - /// - /// Hides the method. - /// - [Browsable(false)] - [EditorBrowsable(EditorBrowsableState.Never)] - public override string ToString() => base.ToString(); - - /// - /// Hides the method. - /// - [Browsable(false)] - [EditorBrowsable(EditorBrowsableState.Never)] - // ReSharper disable BaseObjectEqualsIsObjectEquals - public override bool Equals(object obj) => base.Equals(obj); - - /// - /// Hides the method. - /// - [Browsable(false)] - [EditorBrowsable(EditorBrowsableState.Never)] - // ReSharper disable once BaseObjectGetHashCodeCallInGetHashCode - public override int GetHashCode() => base.GetHashCode(); - // ReSharper restore BaseObjectEqualsIsObjectEquals - } -} diff --git a/src/Elastic.Clients.Elasticsearch/Common/Request/RequestDescriptor.cs b/src/Elastic.Clients.Elasticsearch/Common/Request/RequestDescriptor.cs new file mode 100644 index 00000000000..7a79cbdf2b8 --- /dev/null +++ b/src/Elastic.Clients.Elasticsearch/Common/Request/RequestDescriptor.cs @@ -0,0 +1,84 @@ +// 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.ComponentModel; +using System.Text.Json; +using Elastic.Clients.Elasticsearch.Serialization; +using Elastic.Transport; + +namespace Elastic.Clients.Elasticsearch.Requests; + +/// +/// Base class for all request descriptor types. +/// +public abstract partial class RequestDescriptor : Request, ISelfSerializable + where TDescriptor : RequestDescriptor, IRequest + where TParameters : RequestParameters, new() +{ + private readonly TDescriptor _descriptor; + + void ISelfSerializable.Serialize(Utf8JsonWriter writer, JsonSerializerOptions options, IElasticsearchClientSettings settings) => Serialize(writer, options, settings); + + // This internal ctor ensures that only types defined within the client assembly can derive from this base class. + // We don't expect consumers to derive from this public base class. + internal RequestDescriptor() => _descriptor = (TDescriptor)this; + + protected abstract void Serialize(Utf8JsonWriter writer, JsonSerializerOptions options, IElasticsearchClientSettings settings); + + internal RequestDescriptor(Func pathSelector) : base(pathSelector) => + _descriptor = (TDescriptor)this; + + protected TDescriptor Self => _descriptor; + + protected RouteValues RouteValues => ((IRequest)this).RouteValues; + + protected TDescriptor Qs(string name, object value) + { + Q(name, value); + return _descriptor; + } + + protected TDescriptor Qs(string name, IStringable value) + { + Q(name, value.GetString()); + return _descriptor; + } + + /// + /// Specify settings for this request alone, handy if you need a custom timeout or want to bypass sniffing, retries + /// + public TDescriptor RequestConfiguration( + Func configurationSelector) + { + var rc = RequestState.RequestParameters.RequestConfiguration; + RequestState.RequestParameters.RequestConfiguration = + configurationSelector?.Invoke(new RequestConfigurationDescriptor(rc)) ?? rc; + return _descriptor; + } + + /// + /// Hides the method. + /// + [Browsable(false)] + [EditorBrowsable(EditorBrowsableState.Never)] + public override string ToString() => base.ToString(); + + /// + /// Hides the method. + /// + [Browsable(false)] + [EditorBrowsable(EditorBrowsableState.Never)] + // ReSharper disable BaseObjectEqualsIsObjectEquals + public override bool Equals(object obj) => base.Equals(obj); + + /// + /// Hides the method. + /// + [Browsable(false)] + [EditorBrowsable(EditorBrowsableState.Never)] + // ReSharper disable once BaseObjectGetHashCodeCallInGetHashCode + public override int GetHashCode() => base.GetHashCode(); + // ReSharper restore BaseObjectEqualsIsObjectEquals +} diff --git a/src/Elastic.Clients.Elasticsearch/Common/Request/RouteValues.cs b/src/Elastic.Clients.Elasticsearch/Common/Request/RouteValues.cs index 7d88ea4b01b..34693a23ea5 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/Request/RouteValues.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/Request/RouteValues.cs @@ -6,78 +6,77 @@ using System.Collections.Generic; using Elastic.Transport; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch.Requests; + +internal class ResolvedRouteValues : Dictionary { - internal class ResolvedRouteValues : Dictionary - { - internal static ResolvedRouteValues Empty = new(0); + internal static ResolvedRouteValues Empty = new(0); - public ResolvedRouteValues(int size) : base(size) { } - } + public ResolvedRouteValues(int size) : base(size) { } +} - public sealed class RouteValues : Dictionary +public sealed class RouteValues : Dictionary +{ + /// + /// Used specifically by index requests to determine whether to use PUT or POST. + /// + internal bool ContainsId { get; private set; } + + internal ResolvedRouteValues Resolve(IElasticsearchClientSettings configuration) { - /// - /// Used specifically by index requests to determine whether to use PUT or POST. - /// - internal bool ContainsId { get; private set; } + if (Count == 0) + return ResolvedRouteValues.Empty; - internal ResolvedRouteValues Resolve(IElasticsearchClientSettings configuration) + var resolved = new ResolvedRouteValues(Count); + foreach (var kv in this) { - if (Count == 0) - return ResolvedRouteValues.Empty; - - var resolved = new ResolvedRouteValues(Count); - foreach (var kv in this) - { - var value = this[kv.Key].GetString(configuration); - if (value.IsNullOrEmpty()) - continue; - resolved[kv.Key] = value; - if (IsId(kv.Key)) - ContainsId = true; - } - - return resolved; + var value = this[kv.Key].GetString(configuration); + if (value.IsNullOrEmpty()) + continue; + resolved[kv.Key] = value; + if (IsId(kv.Key)) + ContainsId = true; } - private RouteValues Route(string name, IUrlParameter? routeValue, bool required = true) + return resolved; + } + + private RouteValues Route(string name, IUrlParameter? routeValue, bool required = true) + { + switch (routeValue) { - switch (routeValue) - { - case null when !required: - { - if (!ContainsKey(name)) - return this; - Remove(name); - if (IsId(name)) - ContainsId = false; // invalidate cache + case null when !required: + { + if (!ContainsKey(name)) return this; - } - - case null: - throw new ArgumentNullException(name, $"{name} is required to build a URL to this API."); - - default: - this[name] = routeValue; + Remove(name); if (IsId(name)) ContainsId = false; // invalidate cache return this; - } + } + + case null: + throw new ArgumentNullException(name, $"{name} is required to build a URL to this API."); + + default: + this[name] = routeValue; + if (IsId(name)) + ContainsId = false; // invalidate cache + return this; } + } - private static bool IsId(string key) => key.Equals("id", StringComparison.OrdinalIgnoreCase); + private static bool IsId(string key) => key.Equals("id", StringComparison.OrdinalIgnoreCase); - internal RouteValues Required(string route, IUrlParameter? value) => Route(route, value); + internal RouteValues Required(string route, IUrlParameter? value) => Route(route, value); - internal RouteValues Optional(string route, IUrlParameter? value) => Route(route, value, false); + internal RouteValues Optional(string route, IUrlParameter? value) => Route(route, value, false); - internal TActual Get(string route) - { - if (TryGetValue(route, out var actual) && actual != null) - return (TActual)actual; + internal TActual Get(string route) + { + if (TryGetValue(route, out var actual) && actual != null) + return (TActual)actual; - return default; - } + return default; } } diff --git a/src/Elastic.Clients.Elasticsearch/Common/Request/UrlLookup.cs b/src/Elastic.Clients.Elasticsearch/Common/Request/UrlLookup.cs index 97bb135474b..aa026729436 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/Request/UrlLookup.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/Request/UrlLookup.cs @@ -6,67 +6,66 @@ using System.Linq; using System.Text; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch.Requests; + +internal class UrlLookup { - internal class UrlLookup - { - private readonly string[] _parts; - private readonly string _route; - private readonly string[] _tokenized; - private readonly int _length; + private readonly string[] _parts; + private readonly string _route; + private readonly string[] _tokenized; + private readonly int _length; - public UrlLookup(string route) - { - _route = route; - _tokenized = route.Replace("{", "{@") - .Split(new[] { '{', '}' }, StringSplitOptions.RemoveEmptyEntries); + public UrlLookup(string route) + { + _route = route; + _tokenized = route.Replace("{", "{@") + .Split(new[] { '{', '}' }, StringSplitOptions.RemoveEmptyEntries); - _parts = _tokenized - .Where(p => p.StartsWith("@")) - .Select(p => p.Remove(0, 1)) - .ToArray(); + _parts = _tokenized + .Where(p => p.StartsWith("@")) + .Select(p => p.Remove(0, 1)) + .ToArray(); - _length = _route.Length + (_parts.Length * 4); - } + _length = _route.Length + (_parts.Length * 4); + } - public bool Matches(ResolvedRouteValues values) + public bool Matches(ResolvedRouteValues values) + { + for (var i = 0; i < _parts.Length; i++) { - for (var i = 0; i < _parts.Length; i++) - { - if (!values.ContainsKey(_parts[i])) - return false; - } - return true; + if (!values.ContainsKey(_parts[i])) + return false; } + return true; + } - public string ToUrl(ResolvedRouteValues values) - { - if (values.Count == 0 && _tokenized.Length == 1 && _tokenized[0][0] != '@') - return _tokenized[0]; + public string ToUrl(ResolvedRouteValues values) + { + if (values.Count == 0 && _tokenized.Length == 1 && _tokenized[0][0] != '@') + return _tokenized[0]; - var sb = new StringBuilder(_length); - var i = 0; - for (var index = 0; index < _tokenized.Length; index++) + var sb = new StringBuilder(_length); + var i = 0; + for (var index = 0; index < _tokenized.Length; index++) + { + var t = _tokenized[index]; + if (t[0] == '@') { - var t = _tokenized[index]; - if (t[0] == '@') + if (values.TryGetValue(_parts[i], out var v)) { - if (values.TryGetValue(_parts[i], out var v)) - { - if (string.IsNullOrEmpty(v)) - throw new Exception($"'{_parts[i]}' defined but is empty on url: {_route}"); - - sb.Append(Uri.EscapeDataString(v)); - } - else - throw new Exception($"No value provided for '{_parts[i]}' on url: {_route}"); + if (string.IsNullOrEmpty(v)) + throw new Exception($"'{_parts[i]}' defined but is empty on url: {_route}"); - i++; + sb.Append(Uri.EscapeDataString(v)); } else - sb.Append(t); + throw new Exception($"No value provided for '{_parts[i]}' on url: {_route}"); + + i++; } - return sb.ToString(); + else + sb.Append(t); } + return sb.ToString(); } } diff --git a/src/Elastic.Clients.Elasticsearch/Common/Response/ExistsResponseBase.cs b/src/Elastic.Clients.Elasticsearch/Common/Response/ExistsResponseBase.cs index 5a6a505c9d0..b4cf0b07d5a 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/Response/ExistsResponseBase.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/Response/ExistsResponseBase.cs @@ -4,10 +4,9 @@ using Elastic.Transport.Products.Elasticsearch; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch; + +public abstract class ExistsResponseBase : ElasticsearchResponseBase { - public abstract class ExistsResponseBase : ElasticsearchResponseBase - { - public bool Exists => ApiCall is {Success: true, HttpStatusCode: 200}; - } + public bool Exists => ApiCall is {Success: true, HttpStatusCode: 200}; } diff --git a/src/Elastic.Clients.Elasticsearch/Common/UrlParameters/Name/Name.cs b/src/Elastic.Clients.Elasticsearch/Common/UrlParameters/Name/Name.cs index f596fdee0f4..5c0cc9279c9 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/UrlParameters/Name/Name.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/UrlParameters/Name/Name.cs @@ -5,6 +5,7 @@ using System; using System.Diagnostics; using System.Text.Json.Serialization; +using Elastic.Clients.Elasticsearch.Serialization; using Elastic.Transport; namespace Elastic.Clients.Elasticsearch; diff --git a/src/Elastic.Clients.Elasticsearch/Common/UrlParameters/TaskId/TaskId.cs b/src/Elastic.Clients.Elasticsearch/Common/UrlParameters/TaskId/TaskId.cs index e0b6df13186..57689f40f8d 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/UrlParameters/TaskId/TaskId.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/UrlParameters/TaskId/TaskId.cs @@ -8,6 +8,7 @@ using System.Runtime; using System.Text.Json; using System.Text.Json.Serialization; +using Elastic.Clients.Elasticsearch.Serialization; using Elastic.Transport; namespace Elastic.Clients.Elasticsearch; diff --git a/src/Elastic.Clients.Elasticsearch/Common/UrlParameters/Username/Username.cs b/src/Elastic.Clients.Elasticsearch/Common/UrlParameters/Username/Username.cs index 55de23a81df..65f8b734471 100644 --- a/src/Elastic.Clients.Elasticsearch/Common/UrlParameters/Username/Username.cs +++ b/src/Elastic.Clients.Elasticsearch/Common/UrlParameters/Username/Username.cs @@ -5,6 +5,7 @@ using System; using System.Diagnostics; using System.Text.Json.Serialization; +using Elastic.Clients.Elasticsearch.Serialization; using Elastic.Transport; namespace Elastic.Clients.Elasticsearch; diff --git a/src/Elastic.Clients.Elasticsearch/Helpers/BulkAllObservable.cs b/src/Elastic.Clients.Elasticsearch/Helpers/BulkAllObservable.cs index d3beb293db6..5a0528a3b83 100644 --- a/src/Elastic.Clients.Elasticsearch/Helpers/BulkAllObservable.cs +++ b/src/Elastic.Clients.Elasticsearch/Helpers/BulkAllObservable.cs @@ -13,6 +13,7 @@ using Elastic.Transport.Extensions; using Elastic.Transport.Products.Elasticsearch; using Elastic.Clients.Elasticsearch.Core.Bulk; +using Elastic.Clients.Elasticsearch.Requests; namespace Elastic.Clients.Elasticsearch; @@ -27,10 +28,10 @@ public sealed class BulkAllObservable : IDisposable, IObservable _droppedDocumentCallBack; + private readonly Action _droppedDocumentCallBack; private readonly int _maxDegreeOfParallelism; private readonly IBulkAllRequest _partitionedBulkRequest; - private readonly Func _retryPredicate; + private readonly Func _retryPredicate; private readonly Action _incrementFailed = () => { }; private readonly Action _incrementRetries = () => { }; @@ -158,7 +159,7 @@ private async Task BulkAsync(IList buffer, long page, int ba return await HandleBulkRequestAsync(buffer, page, backOffRetries, response).ConfigureAwait(false); var retryableDocuments = new List(); - var droppedDocuments = new List>(); + var droppedDocuments = new List>(); foreach (var documentWithResponse in response.Items.Zip(buffer, Tuple.Create)) { @@ -184,7 +185,7 @@ private async Task BulkAsync(IList buffer, long page, int ba return new BulkAllResponse { Retries = backOffRetries, Page = page, Items = response.Items }; } - private void HandleDroppedDocuments(List> droppedDocuments, BulkResponse response) + private void HandleDroppedDocuments(List> droppedDocuments, BulkResponse response) { if (droppedDocuments.Count <= 0) return; @@ -248,9 +249,9 @@ private Exception ThrowOnBadBulk(IElasticsearchResponse response, string message return Throw(message, response.ApiCall); } - private static bool RetryBulkActionPredicate(BulkResponseItemBase bulkResponseItem, T d) => bulkResponseItem.Status == 429; + private static bool RetryBulkActionPredicate(ResponseItem bulkResponseItem, T d) => bulkResponseItem.Status == 429; - private static void DroppedDocumentCallbackDefault(BulkResponseItemBase bulkResponseItem, T d) { } + private static void DroppedDocumentCallbackDefault(ResponseItem bulkResponseItem, T d) { } public void Dispose() { diff --git a/src/Elastic.Clients.Elasticsearch/Helpers/BulkAllRequest.cs b/src/Elastic.Clients.Elasticsearch/Helpers/BulkAllRequest.cs index b6369d6f1a2..131b127a268 100644 --- a/src/Elastic.Clients.Elasticsearch/Helpers/BulkAllRequest.cs +++ b/src/Elastic.Clients.Elasticsearch/Helpers/BulkAllRequest.cs @@ -7,6 +7,7 @@ using System.Text.Json; using Elastic.Transport; using Elastic.Clients.Elasticsearch.Core.Bulk; +using Elastic.Clients.Elasticsearch.Fluent; namespace Elastic.Clients.Elasticsearch; @@ -34,9 +35,9 @@ public BulkAllRequest(IEnumerable documents) public int? Size { get; set; } - public Action? DroppedDocumentCallback { get; set; } + public Action? DroppedDocumentCallback { get; set; } - public Func? RetryDocumentPredicate { get; set; } + public Func? RetryDocumentPredicate { get; set; } public Action? BulkResponseCallback { get; set; } @@ -58,7 +59,7 @@ public BulkAllRequest(IEnumerable documents) RequestMetaData IHelperCallable.ParentMetaData { get => ParentMetaData; set => ParentMetaData = value; } } -public sealed class BulkAllRequestDescriptor : SerializableDescriptorBase>, IBulkAllRequest, IHelperCallable +public sealed class BulkAllRequestDescriptor : SerializableDescriptor>, IBulkAllRequest, IHelperCallable { private readonly IEnumerable _documents; @@ -71,8 +72,8 @@ public sealed class BulkAllRequestDescriptor : SerializableDescriptorBase> _bufferToBulk; - private Func _retryDocumentPredicate; - private Action _droppedDocumentCallback; + private Func _retryDocumentPredicate; + private Action _droppedDocumentCallback; private Routing _routing; private bool _continueAfterDroppedDocuments; private string _pipeline; @@ -94,13 +95,13 @@ public BulkAllRequestDescriptor(IEnumerable documents) Action? IBulkAllRequest.BulkResponseCallback => _bulkResponseCallback; bool IBulkAllRequest.ContinueAfterDroppedDocuments => _continueAfterDroppedDocuments; IEnumerable IBulkAllRequest.Documents => _documents; - Action? IBulkAllRequest.DroppedDocumentCallback => _droppedDocumentCallback; + Action? IBulkAllRequest.DroppedDocumentCallback => _droppedDocumentCallback; IndexName IBulkAllRequest.Index => _index; int? IBulkAllRequest.MaxDegreeOfParallelism => _maxDegreeOfParallism; string? IBulkAllRequest.Pipeline => _pipeline; Indices? IBulkAllRequest.RefreshIndices => _refreshIndices; bool IBulkAllRequest.RefreshOnCompleted => _refreshOnCompleted; - Func? IBulkAllRequest.RetryDocumentPredicate => _retryDocumentPredicate; + Func? IBulkAllRequest.RetryDocumentPredicate => _retryDocumentPredicate; Routing? IBulkAllRequest.Routing => _routing; int? IBulkAllRequest.Size => _size; Duration? IBulkAllRequest.Timeout => _timeout; @@ -121,7 +122,7 @@ public BulkAllRequestDescriptor BulkResponseCallback(Action cal public BulkAllRequestDescriptor ContinueAfterDroppedDocuments(bool proceed = true) => Assign(proceed, (a, v) => a._continueAfterDroppedDocuments = v); - public BulkAllRequestDescriptor DroppedDocumentCallback(Action callback) => + public BulkAllRequestDescriptor DroppedDocumentCallback(Action callback) => Assign(callback, (a, v) => a._droppedDocumentCallback = v); public BulkAllRequestDescriptor Index(IndexName index) => Assign(index, (a, v) => a._index = v); @@ -136,7 +137,7 @@ public BulkAllRequestDescriptor DroppedDocumentCallback(Action RefreshOnCompleted(bool refreshOnCompleted = true) => Assign(refreshOnCompleted, (a, v) => a._refreshOnCompleted = v); - public BulkAllRequestDescriptor RetryDocumentPredicate(Func predicate) => + public BulkAllRequestDescriptor RetryDocumentPredicate(Func predicate) => Assign(predicate, (a, v) => a._retryDocumentPredicate = v); public BulkAllRequestDescriptor Routing(Routing routing) => Assign(routing, (a, v) => a._routing = v); diff --git a/src/Elastic.Clients.Elasticsearch/Helpers/BulkAllResponse.cs b/src/Elastic.Clients.Elasticsearch/Helpers/BulkAllResponse.cs index e3ffade304a..396c4e8bfc3 100644 --- a/src/Elastic.Clients.Elasticsearch/Helpers/BulkAllResponse.cs +++ b/src/Elastic.Clients.Elasticsearch/Helpers/BulkAllResponse.cs @@ -16,5 +16,5 @@ public sealed class BulkAllResponse public int Retries { get; internal set; } /// The items returned from the bulk response - public IReadOnlyCollection Items { get; internal set; } = EmptyReadOnly.Collection; + public IReadOnlyCollection Items { get; internal set; } = EmptyReadOnly.Collection; } diff --git a/src/Elastic.Clients.Elasticsearch/Helpers/IBulkAllRequest.cs b/src/Elastic.Clients.Elasticsearch/Helpers/IBulkAllRequest.cs index 51de060e65d..702915eafd6 100644 --- a/src/Elastic.Clients.Elasticsearch/Helpers/IBulkAllRequest.cs +++ b/src/Elastic.Clients.Elasticsearch/Helpers/IBulkAllRequest.cs @@ -17,13 +17,13 @@ public interface IBulkAllRequest Action? BulkResponseCallback { get; } bool ContinueAfterDroppedDocuments { get; } IEnumerable Documents { get; } - Action? DroppedDocumentCallback { get; } + Action? DroppedDocumentCallback { get; } IndexName Index { get; } int? MaxDegreeOfParallelism { get; } string? Pipeline { get; } Indices? RefreshIndices { get; } bool RefreshOnCompleted { get; } - Func? RetryDocumentPredicate { get; } + Func? RetryDocumentPredicate { get; } Routing? Routing { get; } int? Size { get; } Duration? Timeout { get; } diff --git a/src/Elastic.Clients.Elasticsearch/Serialization/AggregationContainerSerializationHelper.cs b/src/Elastic.Clients.Elasticsearch/Serialization/AggregationContainerSerializationHelper.cs index 089f022c3f1..9c7d6209aa8 100644 --- a/src/Elastic.Clients.Elasticsearch/Serialization/AggregationContainerSerializationHelper.cs +++ b/src/Elastic.Clients.Elasticsearch/Serialization/AggregationContainerSerializationHelper.cs @@ -5,29 +5,28 @@ using System.Text.Json; using Elastic.Clients.Elasticsearch.Aggregations; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch.Serialization; + +internal static class AggregationContainerSerializationHelper { - internal static class AggregationContainerSerializationHelper + public static AggregationContainer ReadContainer(ref Utf8JsonReader reader, JsonSerializerOptions options) where T : Aggregation { - public static AggregationContainer ReadContainer(ref Utf8JsonReader reader, JsonSerializerOptions options) where T : Aggregation - { - var variant = JsonSerializer.Deserialize(ref reader, options); + var variant = JsonSerializer.Deserialize(ref reader, options); - var container = new AggregationContainer(variant); + var container = new AggregationContainer(variant); - return container; - } + return container; + } - public static AggregationContainer ReadContainer(string variantName, ref Utf8JsonReader reader, JsonSerializerOptions options) where T : Aggregation - { - var variant = JsonSerializer.Deserialize(ref reader, options); + public static AggregationContainer ReadContainer(string variantName, ref Utf8JsonReader reader, JsonSerializerOptions options) where T : Aggregation + { + var variant = JsonSerializer.Deserialize(ref reader, options); - var container = new AggregationContainer(variant); + var container = new AggregationContainer(variant); - if (container.Variant is Aggregation agg) - agg.Name = variantName; + if (container.Variant is Aggregation agg) + agg.Name = variantName; - return container; - } + return container; } } diff --git a/src/Elastic.Clients.Elasticsearch/Serialization/CustomizedNamingPolicy.cs b/src/Elastic.Clients.Elasticsearch/Serialization/CustomizedNamingPolicy.cs index e3f283364ac..ae9ff4b20e4 100644 --- a/src/Elastic.Clients.Elasticsearch/Serialization/CustomizedNamingPolicy.cs +++ b/src/Elastic.Clients.Elasticsearch/Serialization/CustomizedNamingPolicy.cs @@ -5,7 +5,7 @@ using System; using System.Text.Json; -namespace Elastic.Clients.Elasticsearch; +namespace Elastic.Clients.Elasticsearch.Serialization; internal class CustomizedNamingPolicy : JsonNamingPolicy { diff --git a/src/Elastic.Clients.Elasticsearch/Serialization/DefaultRequestResponseSerializer.cs b/src/Elastic.Clients.Elasticsearch/Serialization/DefaultRequestResponseSerializer.cs index 5e70955a26d..ece54bcfb7f 100644 --- a/src/Elastic.Clients.Elasticsearch/Serialization/DefaultRequestResponseSerializer.cs +++ b/src/Elastic.Clients.Elasticsearch/Serialization/DefaultRequestResponseSerializer.cs @@ -11,7 +11,7 @@ using Elastic.Clients.Elasticsearch.Aggregations; using Elastic.Transport; -namespace Elastic.Clients.Elasticsearch; +namespace Elastic.Clients.Elasticsearch.Serialization; /// /// The built in internal serializer that the high level client Elastic.Clients.Elasticsearch uses. diff --git a/src/Elastic.Clients.Elasticsearch/Serialization/DefaultSourceSerializer.cs b/src/Elastic.Clients.Elasticsearch/Serialization/DefaultSourceSerializer.cs index 3b59a3975a5..6421507e8b4 100644 --- a/src/Elastic.Clients.Elasticsearch/Serialization/DefaultSourceSerializer.cs +++ b/src/Elastic.Clients.Elasticsearch/Serialization/DefaultSourceSerializer.cs @@ -5,7 +5,7 @@ using System.Text.Json; using System.Text.Json.Serialization; -namespace Elastic.Clients.Elasticsearch; +namespace Elastic.Clients.Elasticsearch.Serialization; internal class DefaultSourceSerializer : SystemTextJsonSerializer { diff --git a/src/Elastic.Clients.Elasticsearch/Serialization/ExtraSerializationData.cs b/src/Elastic.Clients.Elasticsearch/Serialization/ExtraSerializationData.cs index 9677dc6263e..44259e2e77a 100644 --- a/src/Elastic.Clients.Elasticsearch/Serialization/ExtraSerializationData.cs +++ b/src/Elastic.Clients.Elasticsearch/Serialization/ExtraSerializationData.cs @@ -6,7 +6,7 @@ using System.Text.Json; using System.Text.Json.Serialization; -namespace Elastic.Clients.Elasticsearch; +namespace Elastic.Clients.Elasticsearch.Serialization; /// /// This actually does not ever get used as a converter. It's just an ugly hack to provide a way to diff --git a/src/Elastic.Clients.Elasticsearch/Serialization/FieldNameQueryAttribute.cs b/src/Elastic.Clients.Elasticsearch/Serialization/FieldNameQueryAttribute.cs index 6b30d411272..2955bc6ebb6 100644 --- a/src/Elastic.Clients.Elasticsearch/Serialization/FieldNameQueryAttribute.cs +++ b/src/Elastic.Clients.Elasticsearch/Serialization/FieldNameQueryAttribute.cs @@ -4,13 +4,12 @@ using System; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch.Serialization; + +[AttributeUsage(AttributeTargets.Interface)] +internal class FieldNameQueryAttribute : Attribute { - [AttributeUsage(AttributeTargets.Interface)] - internal class FieldNameQueryAttribute : Attribute - { - public FieldNameQueryAttribute(Type convertType) => ConvertType = convertType; + public FieldNameQueryAttribute(Type convertType) => ConvertType = convertType; - public Type ConvertType { get; } - } + public Type ConvertType { get; } } diff --git a/src/Elastic.Clients.Elasticsearch/Serialization/ICustomJsonWriter.cs b/src/Elastic.Clients.Elasticsearch/Serialization/ICustomJsonWriter.cs new file mode 100644 index 00000000000..ba1d7f315b7 --- /dev/null +++ b/src/Elastic.Clients.Elasticsearch/Serialization/ICustomJsonWriter.cs @@ -0,0 +1,13 @@ +// 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.Text.Json; +using Elastic.Transport; + +namespace Elastic.Clients.Elasticsearch.Serialization; + +internal interface ICustomJsonWriter +{ + void WriteJson(Utf8JsonWriter writer, Serializer sourceSerializer); +} diff --git a/src/Elastic.Clients.Elasticsearch/Serialization/IEnumerableSingleOrManyConverter.cs b/src/Elastic.Clients.Elasticsearch/Serialization/IEnumerableSingleOrManyConverter.cs index 2a1f25870aa..113b00b47a4 100644 --- a/src/Elastic.Clients.Elasticsearch/Serialization/IEnumerableSingleOrManyConverter.cs +++ b/src/Elastic.Clients.Elasticsearch/Serialization/IEnumerableSingleOrManyConverter.cs @@ -7,14 +7,13 @@ using System.Text.Json; using System.Text.Json.Serialization; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch.Serialization; + +internal abstract class IEnumerableSingleOrManyConverter : JsonConverter> { - internal abstract class IEnumerableSingleOrManyConverter : JsonConverter> - { - public override IEnumerable? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => - SingleOrManySerializationHelper.Deserialize(ref reader, options); + public override IEnumerable? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => + SingleOrManySerializationHelper.Deserialize(ref reader, options); - public override void Write(Utf8JsonWriter writer, IEnumerable value, JsonSerializerOptions options) => - SingleOrManySerializationHelper.Serialize(value, writer, options); - } + public override void Write(Utf8JsonWriter writer, IEnumerable value, JsonSerializerOptions options) => + SingleOrManySerializationHelper.Serialize(value, writer, options); } diff --git a/src/Elastic.Clients.Elasticsearch/Serialization/ISourceMarker.cs b/src/Elastic.Clients.Elasticsearch/Serialization/ISourceMarker.cs index cbb77121280..70308dd7f03 100644 --- a/src/Elastic.Clients.Elasticsearch/Serialization/ISourceMarker.cs +++ b/src/Elastic.Clients.Elasticsearch/Serialization/ISourceMarker.cs @@ -2,7 +2,6 @@ // 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 -{ - internal interface ISourceMarker { } -} +namespace Elastic.Clients.Elasticsearch.Serialization; + +internal interface ISourceMarker { } diff --git a/src/Elastic.Clients.Elasticsearch/Serialization/IStreamSerializable.cs b/src/Elastic.Clients.Elasticsearch/Serialization/IStreamSerializable.cs index bf2085c9a32..048e6506041 100644 --- a/src/Elastic.Clients.Elasticsearch/Serialization/IStreamSerializable.cs +++ b/src/Elastic.Clients.Elasticsearch/Serialization/IStreamSerializable.cs @@ -6,28 +6,27 @@ using Elastic.Transport; using System.IO; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch.Serialization; + +/// +/// Used to mark types which expect to directly serialise into a stream. This supports non-json compliant output such as NDJSON. +/// +internal interface IStreamSerializable { /// - /// Used to mark types which expect to directly serialise into a stream. This supports non-json compliant output such as NDJSON. + /// Serialize the object into the supplied . /// - internal interface IStreamSerializable - { - /// - /// Serialize the object into the supplied . - /// - /// - /// - /// - void Serialize(Stream stream, IElasticsearchClientSettings settings, SerializationFormatting formatting = SerializationFormatting.None); + /// + /// + /// + void Serialize(Stream stream, IElasticsearchClientSettings settings, SerializationFormatting formatting = SerializationFormatting.None); - /// - /// Asynchronously serialize the object into the supplied . - /// - /// - /// - /// - /// - Task SerializeAsync(Stream stream, IElasticsearchClientSettings settings, SerializationFormatting formatting = SerializationFormatting.None); - } + /// + /// Asynchronously serialize the object into the supplied . + /// + /// + /// + /// + /// + Task SerializeAsync(Stream stream, IElasticsearchClientSettings settings, SerializationFormatting formatting = SerializationFormatting.None); } diff --git a/src/Elastic.Clients.Elasticsearch/Serialization/InterfaceConverter.cs b/src/Elastic.Clients.Elasticsearch/Serialization/InterfaceConverter.cs index 1327ce2c9bf..dd48123d8f9 100644 --- a/src/Elastic.Clients.Elasticsearch/Serialization/InterfaceConverter.cs +++ b/src/Elastic.Clients.Elasticsearch/Serialization/InterfaceConverter.cs @@ -6,7 +6,7 @@ using System.Text.Json; using System.Text.Json.Serialization; -namespace Elastic.Clients.Elasticsearch; +namespace Elastic.Clients.Elasticsearch.Serialization; internal sealed class InterfaceConverter : JsonConverter where TConcrete : class, TInterface diff --git a/src/Elastic.Clients.Elasticsearch/Serialization/InterfaceConverterAttribute.cs b/src/Elastic.Clients.Elasticsearch/Serialization/InterfaceConverterAttribute.cs index f72980139ef..b53215f504a 100644 --- a/src/Elastic.Clients.Elasticsearch/Serialization/InterfaceConverterAttribute.cs +++ b/src/Elastic.Clients.Elasticsearch/Serialization/InterfaceConverterAttribute.cs @@ -4,14 +4,12 @@ using System; -namespace Elastic.Clients.Elasticsearch -{ +namespace Elastic.Clients.Elasticsearch.Serialization; - [AttributeUsage(AttributeTargets.Interface)] - internal class InterfaceConverterAttribute : Attribute - { - public InterfaceConverterAttribute(Type converterType) => ConverterType = converterType; +[AttributeUsage(AttributeTargets.Interface)] +internal class InterfaceConverterAttribute : Attribute +{ + public InterfaceConverterAttribute(Type converterType) => ConverterType = converterType; - public Type ConverterType { get; } - } + public Type ConverterType { get; } } diff --git a/src/Elastic.Clients.Elasticsearch/Serialization/InterfaceConverterFactory.cs b/src/Elastic.Clients.Elasticsearch/Serialization/InterfaceConverterFactory.cs index 82e45c16ff3..8bf38d79d30 100644 --- a/src/Elastic.Clients.Elasticsearch/Serialization/InterfaceConverterFactory.cs +++ b/src/Elastic.Clients.Elasticsearch/Serialization/InterfaceConverterFactory.cs @@ -7,35 +7,34 @@ using System.Text.Json; using System.Text.Json.Serialization; -namespace Elastic.Clients.Elasticsearch -{ - internal sealed class InterfaceConverterFactory : JsonConverterFactory - { - private readonly IElasticsearchClientSettings _settings; +namespace Elastic.Clients.Elasticsearch.Serialization; - public InterfaceConverterFactory(IElasticsearchClientSettings settings) => _settings = settings; +internal sealed class InterfaceConverterFactory : JsonConverterFactory +{ + private readonly IElasticsearchClientSettings _settings; - public override bool CanConvert(Type typeToConvert) - { - var customAttributes = typeToConvert.GetCustomAttributes(); + public InterfaceConverterFactory(IElasticsearchClientSettings settings) => _settings = settings; - var canConvert = false; + public override bool CanConvert(Type typeToConvert) + { + var customAttributes = typeToConvert.GetCustomAttributes(); - foreach (var item in customAttributes) - { - var type = item.GetType(); - if (type == typeof(InterfaceConverterAttribute)) - canConvert = true; - } + var canConvert = false; - return canConvert; + foreach (var item in customAttributes) + { + var type = item.GetType(); + if (type == typeof(InterfaceConverterAttribute)) + canConvert = true; } - public override JsonConverter? CreateConverter(Type typeToConvert, JsonSerializerOptions options) - { - var att = typeToConvert.GetCustomAttribute(); + return canConvert; + } - return (JsonConverter)Activator.CreateInstance(att.ConverterType)!; - } + public override JsonConverter? CreateConverter(Type typeToConvert, JsonSerializerOptions options) + { + var att = typeToConvert.GetCustomAttribute(); + + return (JsonConverter)Activator.CreateInstance(att.ConverterType)!; } } diff --git a/src/Elastic.Clients.Elasticsearch/Serialization/IntermediateConverter.cs b/src/Elastic.Clients.Elasticsearch/Serialization/IntermediateConverter.cs index 93df64a8fe6..47431f2aab9 100644 --- a/src/Elastic.Clients.Elasticsearch/Serialization/IntermediateConverter.cs +++ b/src/Elastic.Clients.Elasticsearch/Serialization/IntermediateConverter.cs @@ -7,22 +7,21 @@ using System.Text.Json; using System.Text.Json.Serialization; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch.Serialization; + +internal sealed class IntermediateConverter : JsonConverter> { - internal sealed class IntermediateConverter : JsonConverter> + public override IReadOnlyDictionary? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { - public override IReadOnlyDictionary? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - var converter = options.GetConverter(typeof(ReadOnlyIndexNameDictionary<>).MakeGenericType(typeof(TValue))); - - if (converter is ReadOnlyIndexNameDictionaryConverter specialisedConverter) - { - return specialisedConverter.Read(ref reader, typeToConvert, options); - } + var converter = options.GetConverter(typeof(ReadOnlyIndexNameDictionary<>).MakeGenericType(typeof(TValue))); - return null; + if (converter is ReadOnlyIndexNameDictionaryConverter specialisedConverter) + { + return specialisedConverter.Read(ref reader, typeToConvert, options); } - public override void Write(Utf8JsonWriter writer, IReadOnlyDictionary value, JsonSerializerOptions options) => throw new NotImplementedException(); + return null; } + + public override void Write(Utf8JsonWriter writer, IReadOnlyDictionary value, JsonSerializerOptions options) => throw new NotImplementedException(); } diff --git a/src/Elastic.Clients.Elasticsearch/Serialization/IntermediateSourceConverter.cs b/src/Elastic.Clients.Elasticsearch/Serialization/IntermediateSourceConverter.cs index ed08093646a..abc4703b5f8 100644 --- a/src/Elastic.Clients.Elasticsearch/Serialization/IntermediateSourceConverter.cs +++ b/src/Elastic.Clients.Elasticsearch/Serialization/IntermediateSourceConverter.cs @@ -6,31 +6,30 @@ using System.Text.Json; using System.Text.Json.Serialization; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch.Serialization; + +internal sealed class IntermediateSourceConverter : JsonConverter { - internal sealed class IntermediateSourceConverter : JsonConverter + public override T? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { - public override T? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + var converter = options.GetConverter(typeof(SourceMarker<>).MakeGenericType(typeToConvert)); + + if (converter is SourceConverter sourceConverter) { - var converter = options.GetConverter(typeof(SourceMarker<>).MakeGenericType(typeToConvert)); + var source = sourceConverter.Read(ref reader, typeToConvert, options); + return source.Source; + } - if (converter is SourceConverter sourceConverter) - { - var source = sourceConverter.Read(ref reader, typeToConvert, options); - return source.Source; - } + return default; + } - return default; - } + public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options) + { + var converter = options.GetConverter(typeof(SourceMarker<>).MakeGenericType(typeof(T))); - public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options) + if (converter is SourceConverter sourceConverter) { - var converter = options.GetConverter(typeof(SourceMarker<>).MakeGenericType(typeof(T))); - - if (converter is SourceConverter sourceConverter) - { - sourceConverter.Write(writer, new SourceMarker { Source = value }, options); - } + sourceConverter.Write(writer, new SourceMarker { Source = value }, options); } } } diff --git a/src/Elastic.Clients.Elasticsearch/Serialization/IsADictionaryConverter.cs b/src/Elastic.Clients.Elasticsearch/Serialization/IsADictionaryConverter.cs index 777747fc8d4..8dd84dadc13 100644 --- a/src/Elastic.Clients.Elasticsearch/Serialization/IsADictionaryConverter.cs +++ b/src/Elastic.Clients.Elasticsearch/Serialization/IsADictionaryConverter.cs @@ -7,7 +7,7 @@ using System.Text.Json; using System.Text.Json.Serialization; -namespace Elastic.Clients.Elasticsearch; +namespace Elastic.Clients.Elasticsearch.Serialization; // TODO : We need to handle these cases https://github.com/elastic/elasticsearch-specification/pull/1589 @@ -16,7 +16,7 @@ internal sealed class IsADictionaryConverter : JsonConverterFactory public override bool CanConvert(Type typeToConvert) => typeToConvert.BaseType is not null && typeToConvert.BaseType.IsGenericType && - typeToConvert.BaseType.GetGenericTypeDefinition() == typeof(IsADictionaryBase<,>); + typeToConvert.BaseType.GetGenericTypeDefinition() == typeof(IsADictionary<,>); public override JsonConverter? CreateConverter(Type typeToConvert, JsonSerializerOptions options) { @@ -36,7 +36,7 @@ typeToConvert.BaseType is not null && private class IsADictionaryConverterInner : JsonConverter where TKey : class - where TType : IsADictionaryBase, new() + where TType : IsADictionary, new() { public override TType? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { diff --git a/src/Elastic.Clients.Elasticsearch/Serialization/JsonSerializerOptionsExtensions.cs b/src/Elastic.Clients.Elasticsearch/Serialization/JsonSerializerOptionsExtensions.cs index 5d5b267d0dc..7314769f00d 100644 --- a/src/Elastic.Clients.Elasticsearch/Serialization/JsonSerializerOptionsExtensions.cs +++ b/src/Elastic.Clients.Elasticsearch/Serialization/JsonSerializerOptionsExtensions.cs @@ -4,7 +4,7 @@ using System.Text.Json; -namespace Elastic.Clients.Elasticsearch; +namespace Elastic.Clients.Elasticsearch.Serialization; internal static class JsonSerializerOptionsExtensions { diff --git a/src/Elastic.Clients.Elasticsearch/Serialization/KeyValuePairConverter.cs b/src/Elastic.Clients.Elasticsearch/Serialization/KeyValuePairConverter.cs index 59b4a6e4890..5100d38c850 100644 --- a/src/Elastic.Clients.Elasticsearch/Serialization/KeyValuePairConverter.cs +++ b/src/Elastic.Clients.Elasticsearch/Serialization/KeyValuePairConverter.cs @@ -9,59 +9,58 @@ using System.Text.Json.Serialization; using Elastic.Transport; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch.Serialization; + +internal sealed class KeyValuePairConverterFactory : JsonConverterFactory { - internal sealed class KeyValuePairConverterFactory : JsonConverterFactory - { - private readonly IElasticsearchClientSettings _settings; + private readonly IElasticsearchClientSettings _settings; - public KeyValuePairConverterFactory(IElasticsearchClientSettings settings) => _settings = settings; + public KeyValuePairConverterFactory(IElasticsearchClientSettings settings) => _settings = settings; - public override bool CanConvert(Type typeToConvert) => typeToConvert.IsGenericType - && typeToConvert.Name == typeof(KeyValuePair<,>).Name - && typeof(IUrlParameter).IsAssignableFrom(typeToConvert.GetGenericArguments()[0]); + public override bool CanConvert(Type typeToConvert) => typeToConvert.IsGenericType + && typeToConvert.Name == typeof(KeyValuePair<,>).Name + && typeof(IUrlParameter).IsAssignableFrom(typeToConvert.GetGenericArguments()[0]); - public override JsonConverter CreateConverter( - Type type, - JsonSerializerOptions options) - { - var itemOneType = type.GetGenericArguments()[0]; - var itemTwoType = type.GetGenericArguments()[1]; + public override JsonConverter CreateConverter( + Type type, + JsonSerializerOptions options) + { + var itemOneType = type.GetGenericArguments()[0]; + var itemTwoType = type.GetGenericArguments()[1]; - return (JsonConverter)Activator.CreateInstance(typeof(KeyValuePairConverter<,>).MakeGenericType(itemOneType, itemTwoType), _settings); - } + return (JsonConverter)Activator.CreateInstance(typeof(KeyValuePairConverter<,>).MakeGenericType(itemOneType, itemTwoType), _settings); + } - private class KeyValuePairConverter : JsonConverter> where TItem1 : class, IUrlParameter - { - private readonly IElasticsearchClientSettings _settings; + private class KeyValuePairConverter : JsonConverter> where TItem1 : class, IUrlParameter + { + private readonly IElasticsearchClientSettings _settings; - public KeyValuePairConverter(IElasticsearchClientSettings settings) => _settings = settings; + public KeyValuePairConverter(IElasticsearchClientSettings settings) => _settings = settings; - public override KeyValuePair Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - if (reader.TokenType != JsonTokenType.StartObject) - throw new JsonException("Unexpected token for KeyValuePair"); + public override KeyValuePair Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if (reader.TokenType != JsonTokenType.StartObject) + throw new JsonException("Unexpected token for KeyValuePair"); - reader.Read(); // property name (key) - var keyString = reader.GetString(); + reader.Read(); // property name (key) + var keyString = reader.GetString(); - reader.Read(); // value - var value = JsonSerializer.Deserialize(ref reader, options); + reader.Read(); // value + var value = JsonSerializer.Deserialize(ref reader, options); - reader.Read(); // end object + reader.Read(); // end object - var key = (TItem1)Activator.CreateInstance(typeof(TItem1), keyString); - return new KeyValuePair(key, value); - } + var key = (TItem1)Activator.CreateInstance(typeof(TItem1), keyString); + return new KeyValuePair(key, value); + } - public override void Write(Utf8JsonWriter writer, KeyValuePair value, - JsonSerializerOptions options) - { - writer.WriteStartObject(); - writer.WritePropertyName(value.Key.GetString(_settings)); - JsonSerializer.Serialize(writer, value.Value, options); - writer.WriteEndObject(); - } + public override void Write(Utf8JsonWriter writer, KeyValuePair value, + JsonSerializerOptions options) + { + writer.WriteStartObject(); + writer.WritePropertyName(value.Key.GetString(_settings)); + JsonSerializer.Serialize(writer, value.Value, options); + writer.WriteEndObject(); } } } diff --git a/src/Elastic.Clients.Elasticsearch/Serialization/NumericAliasConverter.cs b/src/Elastic.Clients.Elasticsearch/Serialization/NumericAliasConverter.cs index a4135a4a8e2..99d59a64379 100644 --- a/src/Elastic.Clients.Elasticsearch/Serialization/NumericAliasConverter.cs +++ b/src/Elastic.Clients.Elasticsearch/Serialization/NumericAliasConverter.cs @@ -7,25 +7,24 @@ using System.Text.Json; using System.Text.Json.Serialization; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch.Serialization; + +internal sealed class NumericAliasConverter : JsonConverter { - internal sealed class NumericAliasConverter : JsonConverter + 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.GetInt64(); - - var instance = (T)Activator.CreateInstance( - typeof(T), - BindingFlags.Instance | BindingFlags.Public, - args: new object[] {value}, - binder: null, - culture: null)!; + var value = reader.GetInt64(); - return instance; - } + var instance = (T)Activator.CreateInstance( + typeof(T), + BindingFlags.Instance | BindingFlags.Public, + args: new object[] {value}, + binder: null, + culture: null)!; - public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options) => - throw new NotImplementedException(); + return instance; } + + public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options) => + throw new NotImplementedException(); } diff --git a/src/Elastic.Clients.Elasticsearch/Serialization/ObjectToInferredTypesConverter.cs b/src/Elastic.Clients.Elasticsearch/Serialization/ObjectToInferredTypesConverter.cs index 455f0c21af2..23a7cff7220 100644 --- a/src/Elastic.Clients.Elasticsearch/Serialization/ObjectToInferredTypesConverter.cs +++ b/src/Elastic.Clients.Elasticsearch/Serialization/ObjectToInferredTypesConverter.cs @@ -6,28 +6,27 @@ using System.Text.Json; using System.Text.Json.Serialization; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch.Serialization; + +internal sealed class ObjectToInferredTypesConverter : JsonConverter { - internal sealed class ObjectToInferredTypesConverter : JsonConverter - { - public override object Read( - ref Utf8JsonReader reader, - Type typeToConvert, - JsonSerializerOptions options) => reader.TokenType switch - { - JsonTokenType.True => true, - JsonTokenType.False => false, - JsonTokenType.Number when reader.TryGetInt64(out var l) => l, - JsonTokenType.Number => reader.GetDouble(), - JsonTokenType.String when reader.TryGetDateTime(out var datetime) => datetime, - JsonTokenType.String => reader.GetString(), - _ => JsonDocument.ParseValue(ref reader).RootElement.Clone() - }; + public override object Read( + ref Utf8JsonReader reader, + Type typeToConvert, + JsonSerializerOptions options) => reader.TokenType switch + { + JsonTokenType.True => true, + JsonTokenType.False => false, + JsonTokenType.Number when reader.TryGetInt64(out var l) => l, + JsonTokenType.Number => reader.GetDouble(), + JsonTokenType.String when reader.TryGetDateTime(out var datetime) => datetime, + JsonTokenType.String => reader.GetString(), + _ => JsonDocument.ParseValue(ref reader).RootElement.Clone() + }; - public override void Write( - Utf8JsonWriter writer, - object objectToWrite, - JsonSerializerOptions options) => - JsonSerializer.Serialize(writer, objectToWrite, objectToWrite.GetType(), options); - } + public override void Write( + Utf8JsonWriter writer, + object objectToWrite, + JsonSerializerOptions options) => + JsonSerializer.Serialize(writer, objectToWrite, objectToWrite.GetType(), options); } diff --git a/src/Elastic.Clients.Elasticsearch/Serialization/PercentageConverter.cs b/src/Elastic.Clients.Elasticsearch/Serialization/PercentageConverter.cs deleted file mode 100644 index 1652771bd36..00000000000 --- a/src/Elastic.Clients.Elasticsearch/Serialization/PercentageConverter.cs +++ /dev/null @@ -1,40 +0,0 @@ -// 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.Runtime.Serialization; -using System.Text.Json; -using System.Text.Json.Serialization; - -namespace Elastic.Clients.Elasticsearch -{ - //internal sealed class PercentageConverter : JsonConverter - //{ - // public override Percentage Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - // { - // var token = reader.TokenType; - - // switch (token) - // { - // case JsonTokenType.String: - // { - // var value = reader.GetString(); - // var result = (Percentage)Activator.CreateInstance(typeof(Percentage), value); - // return result; - // } - // case JsonTokenType.Number: - // { - // var value = reader.GetSingle(); - // var result = (Percentage)Activator.CreateInstance(typeof(Percentage), value); - // return result; - // } - // } - - // throw new SerializationException(); - // } - - // public override void Write(Utf8JsonWriter writer, Percentage value, JsonSerializerOptions options) => - // throw new NotImplementedException(); - //} -} diff --git a/src/Elastic.Clients.Elasticsearch/Serialization/PropertyNameConverter.cs b/src/Elastic.Clients.Elasticsearch/Serialization/PropertyNameConverter.cs index 2436f62a04c..8ed87f2be87 100644 --- a/src/Elastic.Clients.Elasticsearch/Serialization/PropertyNameConverter.cs +++ b/src/Elastic.Clients.Elasticsearch/Serialization/PropertyNameConverter.cs @@ -7,37 +7,36 @@ using System.Text.Json.Serialization; using Elastic.Transport; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch.Serialization; + +internal sealed class PropertyNameConverter : SettingsJsonConverter { - internal sealed class PropertyNameConverter : SettingsJsonConverter - { - public override void WriteAsPropertyName(Utf8JsonWriter writer, PropertyName value, JsonSerializerOptions options) => - writer.WritePropertyName(((IUrlParameter)value).GetString(GetSettings(options))); + public override void WriteAsPropertyName(Utf8JsonWriter writer, PropertyName value, JsonSerializerOptions options) => + writer.WritePropertyName(((IUrlParameter)value).GetString(GetSettings(options))); - public override PropertyName ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => - reader.GetString(); + public override PropertyName ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => + reader.GetString(); - public override PropertyName? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + public override PropertyName? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if (reader.TokenType == JsonTokenType.String) { - if (reader.TokenType == JsonTokenType.String) - { - PropertyName propertyName = reader.GetString(); - return propertyName; - } - - return null; + PropertyName propertyName = reader.GetString(); + return propertyName; } - public override void Write(Utf8JsonWriter writer, PropertyName? value, JsonSerializerOptions options) + return null; + } + + public override void Write(Utf8JsonWriter writer, PropertyName? value, JsonSerializerOptions options) + { + if (value is null) { - if (value is null) - { - writer.WriteNullValue(); - return; - } - - var propertyName = GetSettings(options).Inferrer.PropertyName(value); - writer.WriteStringValue(propertyName); + writer.WriteNullValue(); + return; } + + var propertyName = GetSettings(options).Inferrer.PropertyName(value); + writer.WriteStringValue(propertyName); } } diff --git a/src/Elastic.Clients.Elasticsearch/Serialization/ProxyRequestConverter.cs b/src/Elastic.Clients.Elasticsearch/Serialization/ProxyRequestConverter.cs index d291ff065be..1ff99774725 100644 --- a/src/Elastic.Clients.Elasticsearch/Serialization/ProxyRequestConverter.cs +++ b/src/Elastic.Clients.Elasticsearch/Serialization/ProxyRequestConverter.cs @@ -6,20 +6,19 @@ using System.Text.Json; using System.Text.Json.Serialization; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch.Serialization; + +internal sealed class CustomJsonWriterConverter : JsonConverter { - internal sealed class CustomJsonWriterConverter : JsonConverter - { - private readonly IElasticsearchClientSettings _settings; + private readonly IElasticsearchClientSettings _settings; - public CustomJsonWriterConverter(IElasticsearchClientSettings settings) => _settings = settings; + public CustomJsonWriterConverter(IElasticsearchClientSettings settings) => _settings = settings; - public override TDocument? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => - throw new NotImplementedException(); + public override TDocument? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => + throw new NotImplementedException(); - public override void Write(Utf8JsonWriter writer, TDocument value, JsonSerializerOptions options) - { - if (value is ICustomJsonWriter proxyRequest) proxyRequest.WriteJson(writer, _settings.SourceSerializer); - } + public override void Write(Utf8JsonWriter writer, TDocument value, JsonSerializerOptions options) + { + if (value is ICustomJsonWriter proxyRequest) proxyRequest.WriteJson(writer, _settings.SourceSerializer); } } diff --git a/src/Elastic.Clients.Elasticsearch/Serialization/ProxyRequestConverterFactory.cs b/src/Elastic.Clients.Elasticsearch/Serialization/ProxyRequestConverterFactory.cs index 5bf27da924a..434331acc38 100644 --- a/src/Elastic.Clients.Elasticsearch/Serialization/ProxyRequestConverterFactory.cs +++ b/src/Elastic.Clients.Elasticsearch/Serialization/ProxyRequestConverterFactory.cs @@ -7,7 +7,7 @@ using System.Text.Json; using System.Text.Json.Serialization; -namespace Elastic.Clients.Elasticsearch; +namespace Elastic.Clients.Elasticsearch.Serialization; internal sealed class CustomJsonWriterConverterFactory : JsonConverterFactory { diff --git a/src/Elastic.Clients.Elasticsearch/Serialization/ReadOnlyIndexNameDictionaryConverter.cs b/src/Elastic.Clients.Elasticsearch/Serialization/ReadOnlyIndexNameDictionaryConverter.cs index 146e54f31c5..b226e5c8fad 100644 --- a/src/Elastic.Clients.Elasticsearch/Serialization/ReadOnlyIndexNameDictionaryConverter.cs +++ b/src/Elastic.Clients.Elasticsearch/Serialization/ReadOnlyIndexNameDictionaryConverter.cs @@ -7,32 +7,31 @@ using System.Text.Json; using System.Text.Json.Serialization; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch.Serialization; + +internal sealed class ReadOnlyIndexNameDictionaryConverter : JsonConverterAttribute { - internal sealed class ReadOnlyIndexNameDictionaryConverter : JsonConverterAttribute - { - public ReadOnlyIndexNameDictionaryConverter(Type valueType) => ValueType = valueType; + public ReadOnlyIndexNameDictionaryConverter(Type valueType) => ValueType = valueType; - public Type ValueType { get; } + public Type ValueType { get; } - public override JsonConverter? CreateConverter(Type typeToConvert) => (JsonConverter)Activator.CreateInstance(typeof(IntermediateConverter<>).MakeGenericType(ValueType)); - } - - internal sealed class ReadOnlyIndexNameDictionaryConverter : JsonConverter> - { - private readonly IElasticsearchClientSettings _settings; + public override JsonConverter? CreateConverter(Type typeToConvert) => (JsonConverter)Activator.CreateInstance(typeof(IntermediateConverter<>).MakeGenericType(ValueType)); +} - public ReadOnlyIndexNameDictionaryConverter(IElasticsearchClientSettings settings) => _settings = settings; +internal sealed class ReadOnlyIndexNameDictionaryConverter : JsonConverter> +{ + private readonly IElasticsearchClientSettings _settings; - public override IReadOnlyDictionary? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - var initialDictionary = JsonSerializer.Deserialize>(ref reader, options); + public ReadOnlyIndexNameDictionaryConverter(IElasticsearchClientSettings settings) => _settings = settings; - var readOnlyDictionary = new ReadOnlyIndexNameDictionary(initialDictionary, _settings); + public override IReadOnlyDictionary? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + var initialDictionary = JsonSerializer.Deserialize>(ref reader, options); - return readOnlyDictionary; - } + var readOnlyDictionary = new ReadOnlyIndexNameDictionary(initialDictionary, _settings); - public override void Write(Utf8JsonWriter writer, IReadOnlyDictionary value, JsonSerializerOptions options) => throw new NotImplementedException(); + return readOnlyDictionary; } + + public override void Write(Utf8JsonWriter writer, IReadOnlyDictionary value, JsonSerializerOptions options) => throw new NotImplementedException(); } diff --git a/src/Elastic.Clients.Elasticsearch/Serialization/ReadOnlyIndexNameDictionaryConverterFactory.cs b/src/Elastic.Clients.Elasticsearch/Serialization/ReadOnlyIndexNameDictionaryConverterFactory.cs index f9ae245e69e..f0768962d1e 100644 --- a/src/Elastic.Clients.Elasticsearch/Serialization/ReadOnlyIndexNameDictionaryConverterFactory.cs +++ b/src/Elastic.Clients.Elasticsearch/Serialization/ReadOnlyIndexNameDictionaryConverterFactory.cs @@ -6,27 +6,26 @@ using System.Text.Json; using System.Text.Json.Serialization; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch.Serialization; + +internal sealed class ReadOnlyIndexNameDictionaryConverterFactory : JsonConverterFactory { - internal sealed class ReadOnlyIndexNameDictionaryConverterFactory : JsonConverterFactory - { - private readonly IElasticsearchClientSettings _settings; + private readonly IElasticsearchClientSettings _settings; - public ReadOnlyIndexNameDictionaryConverterFactory(IElasticsearchClientSettings settings) => _settings = settings; - - public override bool CanConvert(Type typeToConvert) - { - if (!typeToConvert.IsGenericType) - return false; + public ReadOnlyIndexNameDictionaryConverterFactory(IElasticsearchClientSettings settings) => _settings = settings; + + public override bool CanConvert(Type typeToConvert) + { + if (!typeToConvert.IsGenericType) + return false; - var canConvert = typeof(ReadOnlyIndexNameDictionary<>) == typeToConvert.GetGenericTypeDefinition(); - return canConvert; - } + var canConvert = typeof(ReadOnlyIndexNameDictionary<>) == typeToConvert.GetGenericTypeDefinition(); + return canConvert; + } - public override JsonConverter CreateConverter(Type type, JsonSerializerOptions options) - { - var valueType = type.GetGenericArguments()[0]; - return (JsonConverter)Activator.CreateInstance(typeof(ReadOnlyIndexNameDictionaryConverter<>).MakeGenericType(valueType), _settings); - } + public override JsonConverter CreateConverter(Type type, JsonSerializerOptions options) + { + var valueType = type.GetGenericArguments()[0]; + return (JsonConverter)Activator.CreateInstance(typeof(ReadOnlyIndexNameDictionaryConverter<>).MakeGenericType(valueType), _settings); } } diff --git a/src/Elastic.Clients.Elasticsearch/Serialization/ResponseItemConverterFactory.cs b/src/Elastic.Clients.Elasticsearch/Serialization/ResponseItemConverterFactory.cs index 0da3418eb03..201e09af4ab 100644 --- a/src/Elastic.Clients.Elasticsearch/Serialization/ResponseItemConverterFactory.cs +++ b/src/Elastic.Clients.Elasticsearch/Serialization/ResponseItemConverterFactory.cs @@ -8,92 +8,91 @@ using Elastic.Clients.Elasticsearch.Core.Get; using Elastic.Clients.Elasticsearch.Core.MGet; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch.Serialization; + +/// +/// A converter factory able to provide a converter to handle (de)serializing . +/// +internal sealed class ResponseItemConverterFactory : JsonConverterFactory { - /// - /// A converter factory able to provide a converter to handle (de)serializing . - /// - internal sealed class ResponseItemConverterFactory : JsonConverterFactory - { - public override bool CanConvert(Type typeToConvert) => typeToConvert.IsGenericType && typeToConvert.GetGenericTypeDefinition() == typeof(ResponseItem<>); + public override bool CanConvert(Type typeToConvert) => typeToConvert.IsGenericType && typeToConvert.GetGenericTypeDefinition() == typeof(ResponseItem<>); - public override JsonConverter? CreateConverter(Type typeToConvert, JsonSerializerOptions options) - { - var documentType = typeToConvert.GetGenericArguments()[0]; + public override JsonConverter? CreateConverter(Type typeToConvert, JsonSerializerOptions options) + { + var documentType = typeToConvert.GetGenericArguments()[0]; - return (JsonConverter)Activator.CreateInstance( - typeof(ResponseItemConverter<>).MakeGenericType(documentType)); - } + return (JsonConverter)Activator.CreateInstance( + typeof(ResponseItemConverter<>).MakeGenericType(documentType)); + } - private sealed class ResponseItemConverter : JsonConverter> + private sealed class ResponseItemConverter : JsonConverter> + { + public override ResponseItem? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { - public override ResponseItem? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - const string exceptionMessage = "Unable to deserialize union."; - var readerCopy = reader; + const string exceptionMessage = "Unable to deserialize union."; + var readerCopy = reader; - Exception getResultException = null; - Exception errorException = null; + Exception getResultException = null; + Exception errorException = null; - // TODO - Review and optimise performance, possibly read-ahead to check for the error property and then deserialise - // accordingly is better? + // TODO - Review and optimise performance, possibly read-ahead to check for the error property and then deserialise + // accordingly is better? - try - { - var result = JsonSerializer.Deserialize>(ref readerCopy, options); - - // If we have a version number, we can be sure this isn't an error - if (result is not null && result.Version is not null) - { - reader = readerCopy; // Ensure we swap the reader to reflect the data we have consumed. - return new ResponseItem(result); - } - } - catch (Exception ex) - { - getResultException = ex; - } + try + { + var result = JsonSerializer.Deserialize>(ref readerCopy, options); - try + // If we have a version number, we can be sure this isn't an error + if (result is not null && result.Version is not null) { - var result = JsonSerializer.Deserialize(ref reader, options); - - if (result is not null && result.Error is not null) - { - return new ResponseItem(result); - } - } - catch (Exception ex) - { - errorException = ex; + reader = readerCopy; // Ensure we swap the reader to reflect the data we have consumed. + return new ResponseItem(result); } + } + catch (Exception ex) + { + getResultException = ex; + } - Exception innerException = null; + try + { + var result = JsonSerializer.Deserialize(ref reader, options); - if (errorException is not null && getResultException is not null) - { - innerException = new AggregateException(errorException, getResultException); - } - else if (errorException is not null) - { - innerException = errorException; - } - else if (getResultException is not null) + if (result is not null && result.Error is not null) { - innerException = getResultException; + return new ResponseItem(result); } + } + catch (Exception ex) + { + errorException = ex; + } - if (innerException is not null) - { - throw new JsonException(exceptionMessage, innerException); - } + Exception innerException = null; - throw new JsonException(exceptionMessage); + if (errorException is not null && getResultException is not null) + { + innerException = new AggregateException(errorException, getResultException); + } + else if (errorException is not null) + { + innerException = errorException; + } + else if (getResultException is not null) + { + innerException = getResultException; } - // Not implemented as this type is read-only on responses. - public override void Write(Utf8JsonWriter writer, ResponseItem value, JsonSerializerOptions options) => - throw new NotImplementedException("We never expect to serialize an instance of ResponseItem as its a read-only response type."); + if (innerException is not null) + { + throw new JsonException(exceptionMessage, innerException); + } + + throw new JsonException(exceptionMessage); } + + // Not implemented as this type is read-only on responses. + public override void Write(Utf8JsonWriter writer, ResponseItem value, JsonSerializerOptions options) => + throw new NotImplementedException("We never expect to serialize an instance of ResponseItem as its a read-only response type."); } } diff --git a/src/Elastic.Clients.Elasticsearch/Serialization/SelfSerializable.cs b/src/Elastic.Clients.Elasticsearch/Serialization/SelfSerializable.cs index dec1671bfbe..1f40c872ca9 100644 --- a/src/Elastic.Clients.Elasticsearch/Serialization/SelfSerializable.cs +++ b/src/Elastic.Clients.Elasticsearch/Serialization/SelfSerializable.cs @@ -4,7 +4,7 @@ using System.Text.Json; -namespace Elastic.Clients.Elasticsearch; +namespace Elastic.Clients.Elasticsearch.Serialization; /// /// Marks a type to provide it's own serialization code. diff --git a/src/Elastic.Clients.Elasticsearch/Serialization/SelfSerializableConverterFactory.cs b/src/Elastic.Clients.Elasticsearch/Serialization/SelfSerializableConverterFactory.cs index da4d59b5e0d..b1095fdc9d8 100644 --- a/src/Elastic.Clients.Elasticsearch/Serialization/SelfSerializableConverterFactory.cs +++ b/src/Elastic.Clients.Elasticsearch/Serialization/SelfSerializableConverterFactory.cs @@ -6,97 +6,95 @@ using System.Text.Json; using System.Text.Json.Serialization; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch.Serialization; + +internal sealed class SelfSerializableConverterFactory : JsonConverterFactory { + private readonly SelfSerializableJsonConverter _converter; + + public SelfSerializableConverterFactory(IElasticsearchClientSettings settings) => _converter = new SelfSerializableJsonConverter(settings); - internal sealed class SelfSerializableConverterFactory : JsonConverterFactory + public override bool CanConvert(Type typeToConvert) { - private readonly SelfSerializableJsonConverter _converter; + var canSerialize = typeof(ISelfSerializable).IsAssignableFrom(typeToConvert); + return canSerialize; + } - public SelfSerializableConverterFactory(IElasticsearchClientSettings settings) => _converter = new SelfSerializableJsonConverter(settings); + public override JsonConverter? CreateConverter(Type typeToConvert, JsonSerializerOptions options) => + _converter; - public override bool CanConvert(Type typeToConvert) - { - var canSerialize = typeof(ISelfSerializable).IsAssignableFrom(typeToConvert); - return canSerialize; - } + private class SelfSerializableJsonConverter : JsonConverter + { + private readonly IElasticsearchClientSettings _settings; - public override JsonConverter? CreateConverter(Type typeToConvert, JsonSerializerOptions options) => - _converter; + public SelfSerializableJsonConverter(IElasticsearchClientSettings settings) => _settings = settings; - private class SelfSerializableJsonConverter : JsonConverter - { - private readonly IElasticsearchClientSettings _settings; + public override ISelfSerializable? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => default; - public SelfSerializableJsonConverter(IElasticsearchClientSettings settings) => _settings = settings; + public override void Write(Utf8JsonWriter writer, ISelfSerializable value, JsonSerializerOptions options) => value.Serialize(writer, options, _settings); + } +} - public override ISelfSerializable? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => default; +internal sealed class SelfTwoWaySerializableConverterFactory : JsonConverterFactory +{ + private readonly SelfSerializableJsonConverter _converter; - public override void Write(Utf8JsonWriter writer, ISelfSerializable value, JsonSerializerOptions options) => value.Serialize(writer, options, _settings); - } + public SelfTwoWaySerializableConverterFactory(IElasticsearchClientSettings settings) => _converter = new SelfSerializableJsonConverter(settings); + + public override bool CanConvert(Type typeToConvert) + { + var canSerialize = typeof(ISelfTwoWaySerializable).IsAssignableFrom(typeToConvert); + return canSerialize; } - internal sealed class SelfTwoWaySerializableConverterFactory : JsonConverterFactory + public override JsonConverter? CreateConverter(Type typeToConvert, JsonSerializerOptions options) => + _converter; + + private class SelfSerializableJsonConverter : JsonConverter { - private readonly SelfSerializableJsonConverter _converter; + private readonly IElasticsearchClientSettings _settings; - public SelfTwoWaySerializableConverterFactory(IElasticsearchClientSettings settings) => _converter = new SelfSerializableJsonConverter(settings); + public SelfSerializableJsonConverter(IElasticsearchClientSettings settings) => _settings = settings; - public override bool CanConvert(Type typeToConvert) + public override ISelfTwoWaySerializable? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { - var canSerialize = typeof(ISelfTwoWaySerializable).IsAssignableFrom(typeToConvert); - return canSerialize; + var instance = (ISelfTwoWaySerializable)Activator.CreateInstance(typeToConvert, true); + instance.Deserialize(ref reader, options, _settings); + return instance; } - public override JsonConverter? CreateConverter(Type typeToConvert, JsonSerializerOptions options) => - _converter; - - private class SelfSerializableJsonConverter : JsonConverter - { - private readonly IElasticsearchClientSettings _settings; + public override void Write(Utf8JsonWriter writer, ISelfTwoWaySerializable value, JsonSerializerOptions options) => value.Serialize(writer, options, _settings); + } +} - public SelfSerializableJsonConverter(IElasticsearchClientSettings settings) => _settings = settings; +internal sealed class SelfDeserializableConverterFactory : JsonConverterFactory +{ + private readonly IElasticsearchClientSettings _settings; - public override ISelfTwoWaySerializable? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - var instance = (ISelfTwoWaySerializable)Activator.CreateInstance(typeToConvert, true); - instance.Deserialize(ref reader, options, _settings); - return instance; - } + public SelfDeserializableConverterFactory(IElasticsearchClientSettings settings) => _settings = settings; - public override void Write(Utf8JsonWriter writer, ISelfTwoWaySerializable value, JsonSerializerOptions options) => value.Serialize(writer, options, _settings); - } + public override bool CanConvert(Type typeToConvert) + { + var canSerialize = typeof(ISelfDeserializable).IsAssignableFrom(typeToConvert); + return canSerialize; } - internal sealed class SelfDeserializableConverterFactory : JsonConverterFactory + public override JsonConverter? CreateConverter(Type typeToConvert, JsonSerializerOptions options) => + (JsonConverter)Activator.CreateInstance(typeof(SelfDeserializableJsonConverter), _settings); + + private class SelfDeserializableJsonConverter : JsonConverter { private readonly IElasticsearchClientSettings _settings; - public SelfDeserializableConverterFactory(IElasticsearchClientSettings settings) => _settings = settings; + public SelfDeserializableJsonConverter(IElasticsearchClientSettings settings) => _settings = settings; - public override bool CanConvert(Type typeToConvert) + public override ISelfDeserializable? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { - var canSerialize = typeof(ISelfDeserializable).IsAssignableFrom(typeToConvert); - return canSerialize; + var instance = (ISelfDeserializable)Activator.CreateInstance(typeToConvert); + instance.Deserialize(ref reader, options, _settings); + return instance; } - public override JsonConverter? CreateConverter(Type typeToConvert, JsonSerializerOptions options) => - (JsonConverter)Activator.CreateInstance(typeof(SelfDeserializableJsonConverter), _settings); - - private class SelfDeserializableJsonConverter : JsonConverter - { - private readonly IElasticsearchClientSettings _settings; - - public SelfDeserializableJsonConverter(IElasticsearchClientSettings settings) => _settings = settings; - - public override ISelfDeserializable? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - var instance = (ISelfDeserializable)Activator.CreateInstance(typeToConvert); - instance.Deserialize(ref reader, options, _settings); - return instance; - } - - public override void Write(Utf8JsonWriter writer, ISelfDeserializable value, JsonSerializerOptions options) => throw new NotImplementedException(); - } + public override void Write(Utf8JsonWriter writer, ISelfDeserializable value, JsonSerializerOptions options) => throw new NotImplementedException(); } } diff --git a/src/Elastic.Clients.Elasticsearch/Serialization/SerializationConstants.cs b/src/Elastic.Clients.Elasticsearch/Serialization/SerializationConstants.cs index b0a69566965..006daf3a91c 100644 --- a/src/Elastic.Clients.Elasticsearch/Serialization/SerializationConstants.cs +++ b/src/Elastic.Clients.Elasticsearch/Serialization/SerializationConstants.cs @@ -2,10 +2,9 @@ // 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 +namespace Elastic.Clients.Elasticsearch.Serialization; + +internal static class SerializationConstants { - internal static class SerializationConstants - { - public const byte Newline = (byte)'\n'; - } + public const byte Newline = (byte)'\n'; } diff --git a/src/Elastic.Clients.Elasticsearch/Serialization/SerializerExtensions.cs b/src/Elastic.Clients.Elasticsearch/Serialization/SerializerExtensions.cs index 2e34aca9c6a..3101c7b6b94 100644 --- a/src/Elastic.Clients.Elasticsearch/Serialization/SerializerExtensions.cs +++ b/src/Elastic.Clients.Elasticsearch/Serialization/SerializerExtensions.cs @@ -5,17 +5,12 @@ using System.Text.Json; using Elastic.Transport; -namespace Elastic.Clients.Elasticsearch; +namespace Elastic.Clients.Elasticsearch.Serialization; internal static class SerializerExtensions { public static bool TryGetJsonSerializerOptions(this Serializer serializer, out JsonSerializerOptions? options) { - //if (serializer is DiagnosticsSerializerProxy diagnosticsSerializerProxy) - //{ - // return diagnosticsSerializerProxy.InnerSerializer.TryGetJsonSerializerOptions(out options); - //} - if (serializer is DefaultRequestResponseSerializer defaultSerializer) { options = defaultSerializer.Options; diff --git a/src/Elastic.Clients.Elasticsearch/Serialization/SettingsJsonConverter.cs b/src/Elastic.Clients.Elasticsearch/Serialization/SettingsJsonConverter.cs index 2d8b1c1dadd..486bac3ae13 100644 --- a/src/Elastic.Clients.Elasticsearch/Serialization/SettingsJsonConverter.cs +++ b/src/Elastic.Clients.Elasticsearch/Serialization/SettingsJsonConverter.cs @@ -5,36 +5,35 @@ using System.Text.Json; using System.Text.Json.Serialization; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch.Serialization; + +/// +/// Used for derived converters which need access to in order to serialize. +/// +/// The type of object or value handled by the converter. +internal abstract class SettingsJsonConverter : JsonConverter { + private IElasticsearchClientSettings _settings; + /// - /// Used for derived converters which need access to in order to serialize. + /// Access the for a given instance. /// - /// The type of object or value handled by the converter. - internal abstract class SettingsJsonConverter : JsonConverter + /// The for which the should be retrieved. + /// An instance related to the provided . + /// Thrown if a corresponding instance cannot be found for the . + protected IElasticsearchClientSettings GetSettings(JsonSerializerOptions options) { - private IElasticsearchClientSettings _settings; - - /// - /// Access the for a given instance. - /// - /// The for which the should be retrieved. - /// An instance related to the provided . - /// Thrown if a corresponding instance cannot be found for the . - protected IElasticsearchClientSettings GetSettings(JsonSerializerOptions options) - { - if (_settings is not null) - return _settings; + if (_settings is not null) + return _settings; - // We avoid locking here as the result of accessing the settings should be idemopotent and low cost. + // We avoid locking here as the result of accessing the settings should be idemopotent and low cost. - if (options.TryGetClientSettings(out var settings)) - { - _settings = settings; - return _settings; - } - - throw new JsonException("Unable to retrieve ElasticsearchClientSettings settings from JsonSerializerOptions."); + if (options.TryGetClientSettings(out var settings)) + { + _settings = settings; + return _settings; } + + throw new JsonException("Unable to retrieve ElasticsearchClientSettings settings from JsonSerializerOptions."); } } diff --git a/src/Elastic.Clients.Elasticsearch/Serialization/SimpleInterfaceConverter.cs b/src/Elastic.Clients.Elasticsearch/Serialization/SimpleInterfaceConverter.cs index f9dc6038f8e..65a1a75c86a 100644 --- a/src/Elastic.Clients.Elasticsearch/Serialization/SimpleInterfaceConverter.cs +++ b/src/Elastic.Clients.Elasticsearch/Serialization/SimpleInterfaceConverter.cs @@ -6,14 +6,13 @@ using System.Text.Json; using System.Text.Json.Serialization; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch.Serialization; + +internal sealed class SimpleInterfaceConverter : JsonConverter where TConcrete : class, TInterface { - internal sealed class SimpleInterfaceConverter : JsonConverter where TConcrete : class, TInterface - { - public override TInterface Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => - JsonSerializer.Deserialize(ref reader, options); + public override TInterface Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => + JsonSerializer.Deserialize(ref reader, options); - public override void Write(Utf8JsonWriter writer, TInterface value, JsonSerializerOptions options) - => JsonSerializer.Serialize(writer, value, typeof(TConcrete), options); - } + public override void Write(Utf8JsonWriter writer, TInterface value, JsonSerializerOptions options) + => JsonSerializer.Serialize(writer, value, typeof(TConcrete), options); } diff --git a/src/Elastic.Clients.Elasticsearch/Serialization/SingleOrManySerializationHelper.cs b/src/Elastic.Clients.Elasticsearch/Serialization/SingleOrManySerializationHelper.cs index 1598f5824ee..c88b001f205 100644 --- a/src/Elastic.Clients.Elasticsearch/Serialization/SingleOrManySerializationHelper.cs +++ b/src/Elastic.Clients.Elasticsearch/Serialization/SingleOrManySerializationHelper.cs @@ -7,74 +7,50 @@ using System.Text.Json; using System; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch.Serialization; + +internal static class SingleOrManySerializationHelper { - internal static class SingleOrManySerializationHelper + public static IEnumerable Deserialize(ref Utf8JsonReader reader, JsonSerializerOptions options) { - public static IEnumerable Deserialize(ref Utf8JsonReader reader, JsonSerializerOptions options) + if (reader.TokenType == JsonTokenType.StartObject) { - if (reader.TokenType == JsonTokenType.StartObject) - { - var singleItem = JsonSerializer.Deserialize(ref reader, options); - return new TItem[] { singleItem }; - } - - if (reader.TokenType == JsonTokenType.StartArray) - { - var list = new List(); - while (reader.Read() && reader.TokenType != JsonTokenType.EndArray) - { - var item = JsonSerializer.Deserialize(ref reader, options); - list.Add(item); - } - return list; - } - - // Handles situations such as a single sort value which can be a string - // e.g. GET nuget-stats/_search - // { - // "sort": "version" - // } - if (reader.TokenType == JsonTokenType.String) - { - var value = reader.GetString(); - var item = (TItem)Activator.CreateInstance(typeof(TItem), value); - return new TItem[] { item }; - } - - throw new JsonException("Unexpected token."); + var singleItem = JsonSerializer.Deserialize(ref reader, options); + return new TItem[] { singleItem }; } - public static void Serialize(IEnumerable value, Utf8JsonWriter writer, JsonSerializerOptions options) + if (reader.TokenType == JsonTokenType.StartArray) { - if (value is not ICollection collection) + var list = new List(); + while (reader.Read() && reader.TokenType != JsonTokenType.EndArray) { - // Avoid a double enumeration of counting then iterating. - // Instead, produce an array, even if it's an array of one. - - writer.WriteStartArray(); - foreach (var item in value) - { - JsonSerializer.Serialize(writer, item, options); - } - writer.WriteEndArray(); - return; + var item = JsonSerializer.Deserialize(ref reader, options); + list.Add(item); } + return list; + } - var count = collection.Count; + // Handles situations such as a single sort value which can be a string + // e.g. GET nuget-stats/_search + // { + // "sort": "version" + // } + if (reader.TokenType == JsonTokenType.String) + { + var value = reader.GetString(); + var item = (TItem)Activator.CreateInstance(typeof(TItem), value); + return new TItem[] { item }; + } - if (count == 0) - { - writer.WriteStartObject(); - writer.WriteEndObject(); - return; - } + throw new JsonException("Unexpected token."); + } - if (count == 1) - { - JsonSerializer.Serialize(writer, value.Single(), options); - return; - } + public static void Serialize(IEnumerable value, Utf8JsonWriter writer, JsonSerializerOptions options) + { + if (value is not ICollection collection) + { + // Avoid a double enumeration of counting then iterating. + // Instead, produce an array, even if it's an array of one. writer.WriteStartArray(); foreach (var item in value) @@ -82,6 +58,29 @@ public static void Serialize(IEnumerable value, Utf8JsonWriter wri JsonSerializer.Serialize(writer, item, options); } writer.WriteEndArray(); + return; + } + + var count = collection.Count; + + if (count == 0) + { + writer.WriteStartObject(); + writer.WriteEndObject(); + return; + } + + if (count == 1) + { + JsonSerializer.Serialize(writer, value.Single(), options); + return; + } + + writer.WriteStartArray(); + foreach (var item in value) + { + JsonSerializer.Serialize(writer, item, options); } + writer.WriteEndArray(); } } diff --git a/src/Elastic.Clients.Elasticsearch/Serialization/SourceConverter.cs b/src/Elastic.Clients.Elasticsearch/Serialization/SourceConverter.cs index 51e5eeaaaf7..dc4172d270b 100644 --- a/src/Elastic.Clients.Elasticsearch/Serialization/SourceConverter.cs +++ b/src/Elastic.Clients.Elasticsearch/Serialization/SourceConverter.cs @@ -6,19 +6,18 @@ using System.Text.Json; using System.Text.Json.Serialization; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch.Serialization; + +internal sealed class SourceConverter : JsonConverter> { - internal sealed class SourceConverter : JsonConverter> - { - private readonly IElasticsearchClientSettings _settings; + private readonly IElasticsearchClientSettings _settings; - public SourceConverter(IElasticsearchClientSettings settings) => _settings = settings; + public SourceConverter(IElasticsearchClientSettings settings) => _settings = settings; - public override SourceMarker? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => new() - { - Source = SourceSerialisation.Deserialize(ref reader, _settings) - }; + public override SourceMarker? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => new() + { + Source = SourceSerialisation.Deserialize(ref reader, _settings) + }; - public override void Write(Utf8JsonWriter writer, SourceMarker value, JsonSerializerOptions options) => SourceSerialisation.Serialize(value.Source, writer, _settings); - } + public override void Write(Utf8JsonWriter writer, SourceMarker value, JsonSerializerOptions options) => SourceSerialisation.Serialize(value.Source, writer, _settings); } diff --git a/src/Elastic.Clients.Elasticsearch/Serialization/SourceConverterAttribute.cs b/src/Elastic.Clients.Elasticsearch/Serialization/SourceConverterAttribute.cs index 1330b6237d9..d7d3e06fb02 100644 --- a/src/Elastic.Clients.Elasticsearch/Serialization/SourceConverterAttribute.cs +++ b/src/Elastic.Clients.Elasticsearch/Serialization/SourceConverterAttribute.cs @@ -5,10 +5,9 @@ using System; using System.Text.Json.Serialization; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch.Serialization; + +internal sealed class SourceConverterAttribute : JsonConverterAttribute { - internal sealed class SourceConverterAttribute : JsonConverterAttribute - { - public override JsonConverter? CreateConverter(Type typeToConvert) => (JsonConverter)Activator.CreateInstance(typeof(IntermediateSourceConverter<>).MakeGenericType(typeToConvert)); - } + public override JsonConverter? CreateConverter(Type typeToConvert) => (JsonConverter)Activator.CreateInstance(typeof(IntermediateSourceConverter<>).MakeGenericType(typeToConvert)); } diff --git a/src/Elastic.Clients.Elasticsearch/Serialization/SourceConverterFactory.cs b/src/Elastic.Clients.Elasticsearch/Serialization/SourceConverterFactory.cs index 976b3a01b21..d576c964a4b 100644 --- a/src/Elastic.Clients.Elasticsearch/Serialization/SourceConverterFactory.cs +++ b/src/Elastic.Clients.Elasticsearch/Serialization/SourceConverterFactory.cs @@ -6,27 +6,26 @@ using System.Text.Json; using System.Text.Json.Serialization; -namespace Elastic.Clients.Elasticsearch +namespace Elastic.Clients.Elasticsearch.Serialization; + +internal sealed class SourceConverterFactory : JsonConverterFactory { - internal sealed class SourceConverterFactory : JsonConverterFactory - { - private readonly IElasticsearchClientSettings _settings; + private readonly IElasticsearchClientSettings _settings; - public SourceConverterFactory(IElasticsearchClientSettings settings) => _settings = settings; + public SourceConverterFactory(IElasticsearchClientSettings settings) => _settings = settings; - public override bool CanConvert(Type typeToConvert) - { - if (!typeToConvert.IsGenericType) - return false; + public override bool CanConvert(Type typeToConvert) + { + if (!typeToConvert.IsGenericType) + return false; - var canConvert = typeof(SourceMarker<>) == typeToConvert.GetGenericTypeDefinition(); - return canConvert; - } + var canConvert = typeof(SourceMarker<>) == typeToConvert.GetGenericTypeDefinition(); + return canConvert; + } - public override JsonConverter CreateConverter(Type type, JsonSerializerOptions options) - { - var valueType = type.GetGenericArguments()[0]; - return (JsonConverter)Activator.CreateInstance(typeof(SourceConverter<>).MakeGenericType(valueType), _settings); - } + public override JsonConverter CreateConverter(Type type, JsonSerializerOptions options) + { + var valueType = type.GetGenericArguments()[0]; + return (JsonConverter)Activator.CreateInstance(typeof(SourceConverter<>).MakeGenericType(valueType), _settings); } } diff --git a/src/Elastic.Clients.Elasticsearch/Serialization/SourceMarker.cs b/src/Elastic.Clients.Elasticsearch/Serialization/SourceMarker.cs index 8dbd03d3d49..7cb89ef1d84 100644 --- a/src/Elastic.Clients.Elasticsearch/Serialization/SourceMarker.cs +++ b/src/Elastic.Clients.Elasticsearch/Serialization/SourceMarker.cs @@ -2,10 +2,9 @@ // 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 +namespace Elastic.Clients.Elasticsearch.Serialization; + +internal sealed class SourceMarker { - internal sealed class SourceMarker - { - public T Source { get; set; } - } + public T Source { get; set; } } diff --git a/src/Elastic.Clients.Elasticsearch/Serialization/SourceSerialisation.cs b/src/Elastic.Clients.Elasticsearch/Serialization/SourceSerialisation.cs index 6af0684d17c..d5045dca5bf 100644 --- a/src/Elastic.Clients.Elasticsearch/Serialization/SourceSerialisation.cs +++ b/src/Elastic.Clients.Elasticsearch/Serialization/SourceSerialisation.cs @@ -8,22 +8,7 @@ using System.Text.Json.Serialization; using Elastic.Transport; -namespace Elastic.Clients.Elasticsearch; - -#if NET6_0_OR_GREATER -public struct RawJsonString -{ - public RawJsonString(string rawJson) => Json = rawJson; - - public string Json { get; init; } -} - -internal class RawJsonConverter : JsonConverter -{ - public override RawJsonString Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => throw new NotImplementedException(); - public override void Write(Utf8JsonWriter writer, RawJsonString value, JsonSerializerOptions options) => writer.WriteRawValue(value.Json); -} -#endif +namespace Elastic.Clients.Elasticsearch.Serialization; /// /// May be used by requests that need to serialise only part of their source rather than the request object itself. diff --git a/src/Elastic.Clients.Elasticsearch/Serialization/StringAliasConverter.cs b/src/Elastic.Clients.Elasticsearch/Serialization/StringAliasConverter.cs index c74bf7af716..ce1c71a5b5f 100644 --- a/src/Elastic.Clients.Elasticsearch/Serialization/StringAliasConverter.cs +++ b/src/Elastic.Clients.Elasticsearch/Serialization/StringAliasConverter.cs @@ -7,7 +7,7 @@ using System.Text.Json; using System.Text.Json.Serialization; -namespace Elastic.Clients.Elasticsearch; +namespace Elastic.Clients.Elasticsearch.Serialization; internal sealed class StringAliasConverter : JsonConverter { diff --git a/src/Elastic.Clients.Elasticsearch/Serialization/StringEnumAttribute.cs b/src/Elastic.Clients.Elasticsearch/Serialization/StringEnumAttribute.cs index 12738095423..2bdf4c83d18 100644 --- a/src/Elastic.Clients.Elasticsearch/Serialization/StringEnumAttribute.cs +++ b/src/Elastic.Clients.Elasticsearch/Serialization/StringEnumAttribute.cs @@ -4,8 +4,7 @@ using System; -namespace Elastic.Clients.Elasticsearch -{ - [AttributeUsage(AttributeTargets.Property | AttributeTargets.Enum)] - public class StringEnumAttribute : Attribute { } -} +namespace Elastic.Clients.Elasticsearch.Serialization; + +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Enum)] +public class StringEnumAttribute : Attribute { } diff --git a/src/Elastic.Clients.Elasticsearch/Serialization/Stringified.cs b/src/Elastic.Clients.Elasticsearch/Serialization/Stringified.cs index 5591f7e0cab..fce710611fe 100644 --- a/src/Elastic.Clients.Elasticsearch/Serialization/Stringified.cs +++ b/src/Elastic.Clients.Elasticsearch/Serialization/Stringified.cs @@ -6,7 +6,7 @@ using System.Text.Json; using System.Text.Json.Serialization; -namespace Elastic.Clients.Elasticsearch; +namespace Elastic.Clients.Elasticsearch.Serialization; internal sealed class StringifiedLongConverter : JsonConverter { diff --git a/src/Elastic.Clients.Elasticsearch/Serialization/SystemTextJsonSerializer.cs b/src/Elastic.Clients.Elasticsearch/Serialization/SystemTextJsonSerializer.cs index 341ecb3eb27..35f5e94f0db 100644 --- a/src/Elastic.Clients.Elasticsearch/Serialization/SystemTextJsonSerializer.cs +++ b/src/Elastic.Clients.Elasticsearch/Serialization/SystemTextJsonSerializer.cs @@ -9,7 +9,7 @@ using System.Threading.Tasks; using Elastic.Transport; -namespace Elastic.Clients.Elasticsearch; +namespace Elastic.Clients.Elasticsearch.Serialization; public abstract class SystemTextJsonSerializer : Serializer { diff --git a/src/Elastic.Clients.Elasticsearch/Serialization/TermsAggregateSerializationHelper.cs b/src/Elastic.Clients.Elasticsearch/Serialization/TermsAggregateSerializationHelper.cs index d1ba447f9ac..c4d25f17f66 100644 --- a/src/Elastic.Clients.Elasticsearch/Serialization/TermsAggregateSerializationHelper.cs +++ b/src/Elastic.Clients.Elasticsearch/Serialization/TermsAggregateSerializationHelper.cs @@ -5,107 +5,106 @@ using System; using System.Text.Json; using System.Text; -using Elastic.Clients.Elasticsearch.Serialization; +using Elastic.Clients.Elasticsearch.Aggregations; -namespace Elastic.Clients.Elasticsearch.Aggregations +namespace Elastic.Clients.Elasticsearch.Serialization; + +internal static class TermsAggregateSerializationHelper { - internal static class TermsAggregateSerializationHelper + private static readonly byte[] s_buckets = Encoding.UTF8.GetBytes("buckets"); + private static readonly byte[] s_key = Encoding.UTF8.GetBytes("key"); + private static readonly byte s_period = (byte)'.'; + + public static bool TryDeserialiseTermsAggregate(string aggregateName, ref Utf8JsonReader reader, JsonSerializerOptions options, out IAggregate? aggregate) { - private static readonly byte[] s_buckets = Encoding.UTF8.GetBytes("buckets"); - private static readonly byte[] s_key = Encoding.UTF8.GetBytes("key"); - private static readonly byte s_period = (byte)'.'; + aggregate = null; + + // We take a copy here so we can read forward to establish the term key type before we resume with final deserialisation. + var readerCopy = reader; - public static bool TryDeserialiseTermsAggregate(string aggregateName, ref Utf8JsonReader reader, JsonSerializerOptions options, out IAggregate? aggregate) + if (JsonHelper.TryReadUntilStringPropertyValue(ref readerCopy, s_buckets)) { - aggregate = null; + if (readerCopy.TokenType != JsonTokenType.StartArray) + throw new Exception("TODO"); - // We take a copy here so we can read forward to establish the term key type before we resume with final deserialisation. - var readerCopy = reader; + readerCopy.Read(); - if (JsonHelper.TryReadUntilStringPropertyValue(ref readerCopy, s_buckets)) + if (readerCopy.TokenType == JsonTokenType.EndArray) // We have no buckets { - if (readerCopy.TokenType != JsonTokenType.StartArray) - throw new Exception("TODO"); + if (aggregateName.Equals("sterms", StringComparison.Ordinal)) + { + var agg = JsonSerializer.Deserialize(ref reader, options); + aggregate = agg; + return true; + } - readerCopy.Read(); + if (aggregateName.Equals("lterms", StringComparison.Ordinal)) + { + var agg = JsonSerializer.Deserialize(ref reader, options); + aggregate = agg; + return true; + } - if (readerCopy.TokenType == JsonTokenType.EndArray) // We have no buckets + if (aggregateName.Equals("dterms", StringComparison.Ordinal)) { - if (aggregateName.Equals("sterms", StringComparison.Ordinal)) - { - var agg = JsonSerializer.Deserialize(ref reader, options); - aggregate = agg; - return true; - } + var agg = JsonSerializer.Deserialize(ref reader, options); + aggregate = agg; + return true; + } - if (aggregateName.Equals("lterms", StringComparison.Ordinal)) - { - var agg = JsonSerializer.Deserialize(ref reader, options); - aggregate = agg; - return true; - } + if (aggregateName.Equals("multi_terms", StringComparison.Ordinal)) + { + var agg = JsonSerializer.Deserialize(ref reader, options); + aggregate = agg; + return true; + } - if (aggregateName.Equals("dterms", StringComparison.Ordinal)) - { - var agg = JsonSerializer.Deserialize(ref reader, options); - aggregate = agg; - return true; - } + throw new JsonException($"Unable to deserialize empty terms aggregate for '{aggregateName}'."); + } + else + { + if (readerCopy.TokenType != JsonTokenType.StartObject) + throw new Exception("TODO"); // TODO! - if (aggregateName.Equals("multi_terms", StringComparison.Ordinal)) + if (JsonHelper.TryReadUntilStringPropertyValue(ref readerCopy, s_key)) + { + if (readerCopy.TokenType == JsonTokenType.String) { - var agg = JsonSerializer.Deserialize(ref reader, options); + var agg = JsonSerializer.Deserialize(ref reader, options); aggregate = agg; return true; } - - throw new JsonException($"Unable to deserialize empty terms aggregate for '{aggregateName}'."); - } - else - { - if (readerCopy.TokenType != JsonTokenType.StartObject) - throw new Exception("TODO"); // TODO! - - if (JsonHelper.TryReadUntilStringPropertyValue(ref readerCopy, s_key)) + else if (readerCopy.TokenType == JsonTokenType.Number) { - if (readerCopy.TokenType == JsonTokenType.String) + var value = readerCopy.ValueSpan; // TODO - May need to check for sequence + + if (value.IndexOf(s_period) > -1 && readerCopy.TryGetDouble(out _)) { - var agg = JsonSerializer.Deserialize(ref reader, options); + var agg = JsonSerializer.Deserialize(ref reader, options); aggregate = agg; return true; } - else if (readerCopy.TokenType == JsonTokenType.Number) - { - var value = readerCopy.ValueSpan; // TODO - May need to check for sequence - - if (value.IndexOf(s_period) > -1 && readerCopy.TryGetDouble(out _)) - { - var agg = JsonSerializer.Deserialize(ref reader, options); - aggregate = agg; - return true; - } - else if (readerCopy.TryGetInt64(out _)) - { - var agg = JsonSerializer.Deserialize(ref reader, options); - aggregate = agg; - return true; - } - } - else if (readerCopy.TokenType == JsonTokenType.StartArray) + else if (readerCopy.TryGetInt64(out _)) { - var agg = JsonSerializer.Deserialize(ref reader, options); + var agg = JsonSerializer.Deserialize(ref reader, options); aggregate = agg; return true; } - else - { - throw new JsonException("Unhandled token type when parsing the terms aggregate response"); - } + } + else if (readerCopy.TokenType == JsonTokenType.StartArray) + { + var agg = JsonSerializer.Deserialize(ref reader, options); + aggregate = agg; + return true; + } + else + { + throw new JsonException("Unhandled token type when parsing the terms aggregate response"); } } } - - return false; } + + return false; } } diff --git a/src/Elastic.Clients.Elasticsearch/Serialization/ThrowHelper.cs b/src/Elastic.Clients.Elasticsearch/Serialization/ThrowHelper.cs index 571f113a3aa..b8fa30111fb 100644 --- a/src/Elastic.Clients.Elasticsearch/Serialization/ThrowHelper.cs +++ b/src/Elastic.Clients.Elasticsearch/Serialization/ThrowHelper.cs @@ -5,7 +5,7 @@ using System.Runtime.CompilerServices; using System.Text.Json; -namespace Elastic.Clients.Elasticsearch; +namespace Elastic.Clients.Elasticsearch.Serialization; internal class ThrowHelper { diff --git a/src/Elastic.Clients.Elasticsearch/Serialization/UnionConverter.cs b/src/Elastic.Clients.Elasticsearch/Serialization/UnionConverter.cs index f1000616f0d..7a340b9f947 100644 --- a/src/Elastic.Clients.Elasticsearch/Serialization/UnionConverter.cs +++ b/src/Elastic.Clients.Elasticsearch/Serialization/UnionConverter.cs @@ -8,7 +8,7 @@ using System.Text.Json.Serialization; using Elastic.Clients.Elasticsearch.Aggregations; -namespace Elastic.Clients.Elasticsearch; +namespace Elastic.Clients.Elasticsearch.Serialization; internal sealed class UnionConverter : JsonConverterFactory { diff --git a/src/Elastic.Clients.Elasticsearch/Types/Aggregations/AggregateDictionaryConverter.cs b/src/Elastic.Clients.Elasticsearch/Types/Aggregations/AggregateDictionaryConverter.cs index 47890fa2bce..0f8a3a3008e 100644 --- a/src/Elastic.Clients.Elasticsearch/Types/Aggregations/AggregateDictionaryConverter.cs +++ b/src/Elastic.Clients.Elasticsearch/Types/Aggregations/AggregateDictionaryConverter.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Text.Json.Serialization; using System.Text.Json; +using Elastic.Clients.Elasticsearch.Serialization; namespace Elastic.Clients.Elasticsearch.Aggregations; diff --git a/src/Elastic.Clients.Elasticsearch/Types/Aggregations/EmptyTermsAggregate.cs b/src/Elastic.Clients.Elasticsearch/Types/Aggregations/EmptyTermsAggregate.cs deleted file mode 100644 index 4380d1febf2..00000000000 --- a/src/Elastic.Clients.Elasticsearch/Types/Aggregations/EmptyTermsAggregate.cs +++ /dev/null @@ -1,28 +0,0 @@ -// 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.Text.Json.Serialization; - -namespace Elastic.Clients.Elasticsearch.Aggregations -{ - //public sealed class EmptyTermsAggregate : IAggregate - //{ - // [JsonInclude] - // [JsonPropertyName("doc_count_error_upper_bound")] - // public long? DocCountErrorUpperBound { get; init; } - - // [JsonInclude] - // [JsonPropertyName("sum_other_doc_count")] - // public long SumOtherDocCount { get; init; } - - // [JsonInclude] - // [JsonPropertyName("buckets")] - // public Buckets> Buckets { get; init; } - - // [JsonInclude] - // [JsonPropertyName("meta")] - // public Dictionary? Meta { get; init; } - //} -} diff --git a/src/Elastic.Clients.Elasticsearch/Types/Aggregations/EmptyTermsBucket.cs b/src/Elastic.Clients.Elasticsearch/Types/Aggregations/EmptyTermsBucket.cs deleted file mode 100644 index 979fbf3949d..00000000000 --- a/src/Elastic.Clients.Elasticsearch/Types/Aggregations/EmptyTermsBucket.cs +++ /dev/null @@ -1,8 +0,0 @@ -// 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.Aggregations -{ - public sealed class EmptyTermsBucket { } -} diff --git a/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkCreateOperation.cs b/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkCreateOperation.cs index 7282d0da7ca..eddd9f24caa 100644 --- a/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkCreateOperation.cs +++ b/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkCreateOperation.cs @@ -8,6 +8,7 @@ using System.Text.Json; using System.Text.Json.Serialization; using System.Threading.Tasks; +using Elastic.Clients.Elasticsearch.Serialization; namespace Elastic.Clients.Elasticsearch.Core.Bulk; @@ -15,7 +16,7 @@ namespace Elastic.Clients.Elasticsearch.Core.Bulk; /// Represents a bulk operation to create a document. /// /// The type representing the document being created. -public sealed class BulkCreateOperation : BulkOperationBase +public sealed class BulkCreateOperation : BulkOperation { /// /// Creates an instance of with the provided document serialized diff --git a/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkCreateOperationDescriptor.cs b/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkCreateOperationDescriptor.cs index 5c3ff974c29..1e71ed21dd6 100644 --- a/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkCreateOperationDescriptor.cs +++ b/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkCreateOperationDescriptor.cs @@ -8,11 +8,13 @@ using System.Text.Json; using System.Threading; using System.Threading.Tasks; +using Elastic.Clients.Elasticsearch.Fluent; +using Elastic.Clients.Elasticsearch.Serialization; using Elastic.Transport; namespace Elastic.Clients.Elasticsearch.Core.Bulk; -public sealed class BulkCreateOperationDescriptor : BulkOperationDescriptorBase> +public sealed class BulkCreateOperationDescriptor : BulkOperationDescriptor> { private string _pipeline; private Dictionary _dynamicTemplates; diff --git a/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkDeleteOperation.cs b/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkDeleteOperation.cs index f4dc31b3f5c..b89726fc1b2 100644 --- a/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkDeleteOperation.cs +++ b/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkDeleteOperation.cs @@ -7,10 +7,11 @@ using System.Text.Json; using System.Text.Json.Serialization; using System.Threading.Tasks; +using Elastic.Clients.Elasticsearch.Serialization; namespace Elastic.Clients.Elasticsearch.Core.Bulk; -public class BulkDeleteOperation : BulkOperationBase +public class BulkDeleteOperation : BulkOperation { public BulkDeleteOperation(Id id) => Id = id; diff --git a/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkDeleteOperationDescriptor.cs b/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkDeleteOperationDescriptor.cs index 070cc3414b6..9fe9dc6024c 100644 --- a/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkDeleteOperationDescriptor.cs +++ b/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkDeleteOperationDescriptor.cs @@ -7,11 +7,12 @@ using System.Text.Json; using System.Threading; using System.Threading.Tasks; +using Elastic.Clients.Elasticsearch.Serialization; using Elastic.Transport; namespace Elastic.Clients.Elasticsearch.Core.Bulk; -public class BulkDeleteOperationDescriptor : BulkOperationDescriptorBase +public class BulkDeleteOperationDescriptor : BulkOperationDescriptor { public BulkDeleteOperationDescriptor() { } diff --git a/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkIndexOperation.cs b/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkIndexOperation.cs index 8b77ae2241c..92e10f12151 100644 --- a/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkIndexOperation.cs +++ b/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkIndexOperation.cs @@ -8,10 +8,11 @@ using System.Text.Json; using System.Text.Json.Serialization; using System.Threading.Tasks; +using Elastic.Clients.Elasticsearch.Serialization; namespace Elastic.Clients.Elasticsearch.Core.Bulk; -public sealed class BulkIndexOperation : BulkOperationBase +public sealed class BulkIndexOperation : BulkOperation { /// /// Creates an instance of with the provided document serialized diff --git a/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkIndexOperationDescriptor.cs b/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkIndexOperationDescriptor.cs index ba191710ee9..ee7d2b1f3c5 100644 --- a/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkIndexOperationDescriptor.cs +++ b/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkIndexOperationDescriptor.cs @@ -8,11 +8,13 @@ using System.Text.Json; using System.Threading; using System.Threading.Tasks; +using Elastic.Clients.Elasticsearch.Fluent; +using Elastic.Clients.Elasticsearch.Serialization; using Elastic.Transport; namespace Elastic.Clients.Elasticsearch.Core.Bulk; -public sealed class BulkIndexOperationDescriptor : BulkOperationDescriptorBase> +public sealed class BulkIndexOperationDescriptor : BulkOperationDescriptor> { private string _pipeline; diff --git a/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkOperationBase.cs b/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkOperation.cs similarity index 96% rename from src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkOperationBase.cs rename to src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkOperation.cs index 175c2b516e2..c76f0f6fea3 100644 --- a/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkOperationBase.cs +++ b/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkOperation.cs @@ -6,6 +6,7 @@ using System.IO; using System.Text.Json.Serialization; using System.Threading.Tasks; +using Elastic.Clients.Elasticsearch.Serialization; using Elastic.Transport; namespace Elastic.Clients.Elasticsearch.Core.Bulk; @@ -16,9 +17,9 @@ namespace Elastic.Clients.Elasticsearch.Core.Bulk; /// /// This is an abstract class. /// -public abstract class BulkOperationBase : IBulkOperation, IStreamSerializable +public abstract class BulkOperation : IBulkOperation, IStreamSerializable { - internal BulkOperationBase() { } + internal BulkOperation() { } /// /// The document ID. diff --git a/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkOperationDescriptorBase.cs b/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkOperationDescriptor.cs similarity index 93% rename from src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkOperationDescriptorBase.cs rename to src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkOperationDescriptor.cs index 803043bbbef..0451a0ba7c8 100644 --- a/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkOperationDescriptorBase.cs +++ b/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkOperationDescriptor.cs @@ -7,16 +7,20 @@ using System.Text.Json; using System.Threading; using System.Threading.Tasks; +using Elastic.Clients.Elasticsearch.Fluent; +using Elastic.Clients.Elasticsearch.Serialization; using Elastic.Transport; namespace Elastic.Clients.Elasticsearch.Core.Bulk; -public abstract class BulkOperationDescriptorBase : SerializableDescriptorBase, IBulkOperation, IStreamSerializable where TDescriptor : BulkOperationDescriptorBase +public abstract class BulkOperationDescriptor : SerializableDescriptor, IBulkOperation, IStreamSerializable where TDescriptor : BulkOperationDescriptor { private long? _version; private VersionType? _versionType; private bool? _requireAlias; + internal BulkOperationDescriptor() { } + protected IndexName IndexNameValue { get; set; } protected Id IdValue { get; set; } protected Routing RoutingValue { get; set; } diff --git a/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkOperationsCollection.cs b/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkOperationsCollection.cs index f77c8ee8af4..8a9314e6190 100644 --- a/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkOperationsCollection.cs +++ b/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkOperationsCollection.cs @@ -7,6 +7,7 @@ using System.Collections.Generic; using System.IO; using System.Threading.Tasks; +using Elastic.Clients.Elasticsearch.Serialization; using Elastic.Transport; namespace Elastic.Clients.Elasticsearch.Core.Bulk; diff --git a/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkResponseItemConverter.cs b/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkResponseItemConverter.cs index eb58f505f30..992bcd61e8d 100644 --- a/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkResponseItemConverter.cs +++ b/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkResponseItemConverter.cs @@ -9,14 +9,14 @@ namespace Elastic.Clients.Elasticsearch.Core.Bulk; -internal sealed class BulkResponseItemConverter : JsonConverter> +internal sealed class BulkResponseItemConverter : JsonConverter> { - public override IReadOnlyList? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + public override IReadOnlyList? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { if (reader.TokenType != JsonTokenType.StartArray) throw new JsonException($"Unexpected token in bulk response items. Read {reader.TokenType} but was expecting {JsonTokenType.StartArray}."); - var responseItems = new List(); + var responseItems = new List(); while (reader.Read() && reader.TokenType != JsonTokenType.EndArray) { @@ -28,7 +28,7 @@ internal sealed class BulkResponseItemConverter : JsonConverter value, JsonSerializerOptions options) => throw new NotImplementedException(); + public override void Write(Utf8JsonWriter writer, IReadOnlyList value, JsonSerializerOptions options) => throw new NotImplementedException(); } diff --git a/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkUpdateBody.cs b/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkUpdateBody.cs index dcf51939355..72cabc973d8 100644 --- a/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkUpdateBody.cs +++ b/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkUpdateBody.cs @@ -4,13 +4,44 @@ using System.Text.Json; using Elastic.Clients.Elasticsearch.Core.Search; +using Elastic.Clients.Elasticsearch.Serialization; namespace Elastic.Clients.Elasticsearch.Core.Bulk; -internal class BulkUpdateBody : BulkUpdateBodyBase +internal abstract class BulkUpdateBody : ISelfSerializable +{ + public long? IfSequenceNumber { get; set; } + + public long? IfPrimaryTerm { get; set; } + + protected abstract void SerializeProperties(Utf8JsonWriter writer, JsonSerializerOptions options, IElasticsearchClientSettings settings); + + void ISelfSerializable.Serialize(Utf8JsonWriter writer, JsonSerializerOptions options, IElasticsearchClientSettings settings) + { + writer.WriteStartObject(); + + if (IfSequenceNumber.HasValue) + { + writer.WritePropertyName("if_seq_no"); + writer.WriteNumberValue(IfSequenceNumber.Value); + } + + if (IfPrimaryTerm.HasValue) + { + writer.WritePropertyName("if_primary_term"); + writer.WriteNumberValue(IfPrimaryTerm.Value); + } + + SerializeProperties(writer, options, settings); + + writer.WriteEndObject(); + } +} + +internal class BulkUpdateBody : BulkUpdateBody { public bool? DocAsUpsert { get; set; } - + public TPartialUpdate PartialUpdate { get; set; } public Script Script { get; set; } @@ -60,3 +91,4 @@ protected override void SerializeProperties(Utf8JsonWriter writer, JsonSerialize } } } + diff --git a/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkUpdateBodyBase.cs b/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkUpdateBodyBase.cs deleted file mode 100644 index 76f1ed2267f..00000000000 --- a/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkUpdateBodyBase.cs +++ /dev/null @@ -1,37 +0,0 @@ -// 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.Text.Json; - -namespace Elastic.Clients.Elasticsearch.Core.Bulk; - -internal abstract class BulkUpdateBodyBase : ISelfSerializable -{ - public long? IfSequenceNumber { get; set; } - - public long? IfPrimaryTerm { get; set; } - - protected abstract void SerializeProperties(Utf8JsonWriter writer, JsonSerializerOptions options, IElasticsearchClientSettings settings); - - void ISelfSerializable.Serialize(Utf8JsonWriter writer, JsonSerializerOptions options, IElasticsearchClientSettings settings) - { - writer.WriteStartObject(); - - if (IfSequenceNumber.HasValue) - { - writer.WritePropertyName("if_seq_no"); - writer.WriteNumberValue(IfSequenceNumber.Value); - } - - if (IfPrimaryTerm.HasValue) - { - writer.WritePropertyName("if_primary_term"); - writer.WriteNumberValue(IfPrimaryTerm.Value); - } - - SerializeProperties(writer, options, settings); - - writer.WriteEndObject(); - } -} diff --git a/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkUpdateOperation.cs b/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkUpdateOperation.cs index 02c66ba5340..20cbc3b02bb 100644 --- a/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkUpdateOperation.cs +++ b/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkUpdateOperation.cs @@ -2,106 +2,137 @@ // 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.Linq; +using System.IO; using System.Text.Json; using System.Text.Json.Serialization; -using Elastic.Clients.Elasticsearch.Core.Search; +using System.Threading; +using System.Threading.Tasks; +using Elastic.Clients.Elasticsearch.Serialization; +using Elastic.Transport; namespace Elastic.Clients.Elasticsearch.Core.Bulk; -public sealed class BulkUpdateOperation : BulkUpdateOperationBase +public abstract class BulkUpdateOperation : BulkOperation { - public BulkUpdateOperation(Id id) => Id = id; + protected internal BulkUpdateOperation() : base() { } - public BulkUpdateOperation(TDocument idFrom, bool useIdFromAsUpsert = false) - { - IdFrom = idFrom; - if (useIdFromAsUpsert) - Upsert = idFrom; - } + private static byte _newline => (byte)'\n'; + + [JsonPropertyName("retry_on_conflict")] + public bool? RetryOnConflict { get; set; } + + protected override string Operation => "update"; + + protected abstract void BeforeSerialize(IElasticsearchClientSettings settings); + + /// + /// Serialise the operation action line for the NDJSON stream. + /// + /// + /// + protected abstract void WriteOperation(Utf8JsonWriter writer, JsonSerializerOptions options = null); - public BulkUpdateOperation(TDocument idFrom, TPartialDocument update, bool useIdFromAsUpsert = false) + protected override void Serialize(Stream stream, IElasticsearchClientSettings settings) { - IdFrom = idFrom; - if (useIdFromAsUpsert) - Upsert = idFrom; - Doc = update; - } + BeforeSerialize(settings); + + var requestResponseSerializer = settings.RequestResponseSerializer; + + var internalWriter = new Utf8JsonWriter(stream); - protected override Type ClrType => typeof(TDocument); + internalWriter.WriteStartObject(); + internalWriter.WritePropertyName(Operation); + requestResponseSerializer.TryGetJsonSerializerOptions(out var options); + WriteOperation(internalWriter, options); + internalWriter.WriteEndObject(); + internalWriter.Flush(); - [JsonPropertyName("pipeline")] - public string? Pipeline { get; set; } + stream.WriteByte(_newline); - [JsonPropertyName("dynamic_templates")] - public Dictionary? DynamicTemplates { get; set; } + var body = GetBody(); + settings.RequestResponseSerializer.Serialize(body, stream); + stream.Flush(); + } - [JsonIgnore] - public TPartialDocument Doc { get; set; } + protected override async Task SerializeAsync(Stream stream, IElasticsearchClientSettings settings) + { + BeforeSerialize(settings); - [JsonIgnore] - public TDocument IdFrom { get; set; } + var internalWriter = new Utf8JsonWriter(stream); + SerializeOperationAction(settings, internalWriter); + internalWriter.Flush(); - [JsonIgnore] - public Script Script { get; set; } + stream.WriteByte(_newline); - [JsonIgnore] - public bool? ScriptedUpsert { get; set; } + var body = GetBody(); + await settings.RequestResponseSerializer.SerializeAsync(body, stream).ConfigureAwait(false); + await stream.FlushAsync().ConfigureAwait(false); + } - [JsonIgnore] - public bool? DocAsUpsert { get; set; } + private void SerializeOperationAction(IElasticsearchClientSettings settings, Utf8JsonWriter writer) + { + var requestResponseSerializer = settings.RequestResponseSerializer; + writer.WriteStartObject(); + writer.WritePropertyName(Operation); + requestResponseSerializer.TryGetJsonSerializerOptions(out var options); + WriteOperation(writer, options); + writer.WriteEndObject(); + } - [JsonIgnore] - public TDocument Upsert { get; set; } + protected abstract object GetBody(); +} - [JsonIgnore] - public Union Source { get; set; } +public abstract class BulkUpdateOperationDescriptorBase : BulkOperationDescriptor> +{ + private static byte _newline => (byte)'\n'; protected override string Operation => "update"; - protected override void BeforeSerialize(IElasticsearchClientSettings settings) + protected abstract void BeforeSerialize(IElasticsearchClientSettings settings); + + protected abstract void WriteOperation(Utf8JsonWriter writer, JsonSerializerOptions options = null); + + protected override void Serialize(Stream stream, IElasticsearchClientSettings settings, SerializationFormatting formatting = SerializationFormatting.None) { - Id ??= new Id(new[] { IdFrom, Upsert }.FirstOrDefault(o => o != null)); + BeforeSerialize(settings); + + var requestResponseSerializer = settings.RequestResponseSerializer; - if (Routing is null) - { - if (IdFrom != null) - Routing ??= new Routing(IdFrom); + var internalWriter = new Utf8JsonWriter(stream); - if (Upsert != null) - Routing ??= new Routing(Upsert); - } + internalWriter.WriteStartObject(); + internalWriter.WritePropertyName(Operation); + requestResponseSerializer.TryGetJsonSerializerOptions(out var options); + WriteOperation(internalWriter, options); + internalWriter.WriteEndObject(); + internalWriter.Flush(); + + stream.WriteByte(_newline); + var body = GetBody(); + settings.RequestResponseSerializer.Serialize(body, stream, formatting); } - protected override void WriteOperation(Utf8JsonWriter writer, JsonSerializerOptions options = null) => JsonSerializer.Serialize(writer, this, options); - - protected override object GetBody() => new BulkUpdateBody { - PartialUpdate = Doc, - Script = Script, - Upsert = Upsert, - DocAsUpsert = DocAsUpsert, - ScriptedUpsert = ScriptedUpsert, - IfPrimaryTerm = IfPrimaryTerm, - IfSequenceNumber = IfSequenceNumber, - Source = Source - }; -} + protected override async Task SerializeAsync(Stream stream, IElasticsearchClientSettings settings, SerializationFormatting formatting, CancellationToken cancellationToken = default) + { + BeforeSerialize(settings); -public static class BulkUpdateOperationFactory -{ - public static BulkUpdateOperationWithPartial WithPartial(Id id, TPartial partialDocument) => new(id, partialDocument); + var requestResponseSerializer = settings.RequestResponseSerializer; + + var internalWriter = new Utf8JsonWriter(stream); - public static BulkUpdateOperationWithPartial WithPartial(Id id, IndexName index, TPartial partialDocument) => new(id, index, partialDocument); + internalWriter.WriteStartObject(); + internalWriter.WritePropertyName(Operation); - public static BulkUpdateOperationWithScript WithScript(Id id, IndexName index, Script script) => new(id, index, script); + requestResponseSerializer.TryGetJsonSerializerOptions(out var options); + WriteOperation(internalWriter, options); - public static BulkUpdateOperationWithScript WithScript(Id id, IndexName index, Script script, TDocument upsert) => new(upsert, id, index, script); + internalWriter.WriteEndObject(); + internalWriter.Flush(); - public static BulkUpdateOperationWithScript WithScript(Id id, Script script, TDocument upsert) => new(upsert, id, script); + stream.WriteByte(_newline); - public static BulkUpdateOperationWithScript WithScript(Script script, TDocument upsert) => new(upsert, new Id(upsert), script); + var body = GetBody(); - public static BulkUpdateOperationWithScript WithScript(Id id, Script script) => new(id, script); + await settings.SourceSerializer.SerializeAsync(body, stream, formatting).ConfigureAwait(false); + } } diff --git a/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkUpdateOperationBase.cs b/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkUpdateOperationBase.cs deleted file mode 100644 index d46ab245c80..00000000000 --- a/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkUpdateOperationBase.cs +++ /dev/null @@ -1,137 +0,0 @@ -// 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.Text.Json.Serialization; -using System.Threading; -using System.Threading.Tasks; -using Elastic.Transport; - -namespace Elastic.Clients.Elasticsearch.Core.Bulk; - -public abstract class BulkUpdateOperationBase : BulkOperationBase -{ - protected internal BulkUpdateOperationBase() : base() { } - - private static byte _newline => (byte)'\n'; - - [JsonPropertyName("retry_on_conflict")] - public bool? RetryOnConflict { get; set; } - - protected override string Operation => "update"; - - protected abstract void BeforeSerialize(IElasticsearchClientSettings settings); - - /// - /// Serialise the operation action line for the NDJSON stream. - /// - /// - /// - protected abstract void WriteOperation(Utf8JsonWriter writer, JsonSerializerOptions options = null); - - protected override void Serialize(Stream stream, IElasticsearchClientSettings settings) - { - BeforeSerialize(settings); - - var requestResponseSerializer = settings.RequestResponseSerializer; - - var internalWriter = new Utf8JsonWriter(stream); - - internalWriter.WriteStartObject(); - internalWriter.WritePropertyName(Operation); - requestResponseSerializer.TryGetJsonSerializerOptions(out var options); - WriteOperation(internalWriter, options); - internalWriter.WriteEndObject(); - internalWriter.Flush(); - - stream.WriteByte(_newline); - - var body = GetBody(); - settings.RequestResponseSerializer.Serialize(body, stream); - stream.Flush(); - } - - protected override async Task SerializeAsync(Stream stream, IElasticsearchClientSettings settings) - { - BeforeSerialize(settings); - - var internalWriter = new Utf8JsonWriter(stream); - SerializeOperationAction(settings, internalWriter); - internalWriter.Flush(); - - stream.WriteByte(_newline); - - var body = GetBody(); - await settings.RequestResponseSerializer.SerializeAsync(body, stream).ConfigureAwait(false); - await stream.FlushAsync().ConfigureAwait(false); - } - - private void SerializeOperationAction(IElasticsearchClientSettings settings, Utf8JsonWriter writer) - { - var requestResponseSerializer = settings.RequestResponseSerializer; - writer.WriteStartObject(); - writer.WritePropertyName(Operation); - requestResponseSerializer.TryGetJsonSerializerOptions(out var options); - WriteOperation(writer, options); - writer.WriteEndObject(); - } - - protected abstract object GetBody(); -} - -public abstract class BulkUpdateOperationDescriptorBase : BulkOperationDescriptorBase> -{ - private static byte _newline => (byte)'\n'; - - protected override string Operation => "update"; - - protected abstract void BeforeSerialize(IElasticsearchClientSettings settings); - - protected abstract void WriteOperation(Utf8JsonWriter writer, JsonSerializerOptions options = null); - - protected override void Serialize(Stream stream, IElasticsearchClientSettings settings, SerializationFormatting formatting = SerializationFormatting.None) - { - BeforeSerialize(settings); - - var requestResponseSerializer = settings.RequestResponseSerializer; - - var internalWriter = new Utf8JsonWriter(stream); - - internalWriter.WriteStartObject(); - internalWriter.WritePropertyName(Operation); - requestResponseSerializer.TryGetJsonSerializerOptions(out var options); - WriteOperation(internalWriter, options); - internalWriter.WriteEndObject(); - internalWriter.Flush(); - - stream.WriteByte(_newline); - var body = GetBody(); - settings.RequestResponseSerializer.Serialize(body, stream, formatting); - } - - protected override async Task SerializeAsync(Stream stream, IElasticsearchClientSettings settings, SerializationFormatting formatting, CancellationToken cancellationToken = default) - { - BeforeSerialize(settings); - - var requestResponseSerializer = settings.RequestResponseSerializer; - - var internalWriter = new Utf8JsonWriter(stream); - - internalWriter.WriteStartObject(); - internalWriter.WritePropertyName(Operation); - - requestResponseSerializer.TryGetJsonSerializerOptions(out var options); - WriteOperation(internalWriter, options); - - internalWriter.WriteEndObject(); - internalWriter.Flush(); - - stream.WriteByte(_newline); - - var body = GetBody(); - - await settings.SourceSerializer.SerializeAsync(body, stream, formatting).ConfigureAwait(false); - } -} diff --git a/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkUpdateOperationDescriptor.cs b/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkUpdateOperationDescriptor.cs index cf34b9389c1..d4cb1721287 100644 --- a/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkUpdateOperationDescriptor.cs +++ b/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkUpdateOperationDescriptor.cs @@ -10,10 +10,11 @@ using System.Threading.Tasks; using Elastic.Transport; using Elastic.Clients.Elasticsearch.Core.Search; +using Elastic.Clients.Elasticsearch.Serialization; namespace Elastic.Clients.Elasticsearch.Core.Bulk; -public sealed class BulkUpdateOperationDescriptor : BulkOperationDescriptorBase> +public sealed class BulkUpdateOperationDescriptor : BulkOperationDescriptor> { private static byte _newline => (byte)'\n'; diff --git a/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkUpdateOperationT.cs b/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkUpdateOperationT.cs new file mode 100644 index 00000000000..0272e5f9ae0 --- /dev/null +++ b/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkUpdateOperationT.cs @@ -0,0 +1,107 @@ +// 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.Linq; +using System.Text.Json; +using System.Text.Json.Serialization; +using Elastic.Clients.Elasticsearch.Core.Search; + +namespace Elastic.Clients.Elasticsearch.Core.Bulk; + +public sealed class BulkUpdateOperation : BulkUpdateOperation +{ + public BulkUpdateOperation(Id id) => Id = id; + + public BulkUpdateOperation(TDocument idFrom, bool useIdFromAsUpsert = false) + { + IdFrom = idFrom; + if (useIdFromAsUpsert) + Upsert = idFrom; + } + + public BulkUpdateOperation(TDocument idFrom, TPartialDocument update, bool useIdFromAsUpsert = false) + { + IdFrom = idFrom; + if (useIdFromAsUpsert) + Upsert = idFrom; + Doc = update; + } + + protected override Type ClrType => typeof(TDocument); + + [JsonPropertyName("pipeline")] + public string? Pipeline { get; set; } + + [JsonPropertyName("dynamic_templates")] + public Dictionary? DynamicTemplates { get; set; } + + [JsonIgnore] + public TPartialDocument Doc { get; set; } + + [JsonIgnore] + public TDocument IdFrom { get; set; } + + [JsonIgnore] + public Script Script { get; set; } + + [JsonIgnore] + public bool? ScriptedUpsert { get; set; } + + [JsonIgnore] + public bool? DocAsUpsert { get; set; } + + [JsonIgnore] + public TDocument Upsert { get; set; } + + [JsonIgnore] + public Union Source { get; set; } + + protected override string Operation => "update"; + + protected override void BeforeSerialize(IElasticsearchClientSettings settings) + { + Id ??= new Id(new[] { IdFrom, Upsert }.FirstOrDefault(o => o != null)); + + if (Routing is null) + { + if (IdFrom != null) + Routing ??= new Routing(IdFrom); + + if (Upsert != null) + Routing ??= new Routing(Upsert); + } + } + + protected override void WriteOperation(Utf8JsonWriter writer, JsonSerializerOptions options = null) => JsonSerializer.Serialize(writer, this, options); + + protected override object GetBody() => new BulkUpdateBody { + PartialUpdate = Doc, + Script = Script, + Upsert = Upsert, + DocAsUpsert = DocAsUpsert, + ScriptedUpsert = ScriptedUpsert, + IfPrimaryTerm = IfPrimaryTerm, + IfSequenceNumber = IfSequenceNumber, + Source = Source + }; +} + +public static class BulkUpdateOperationFactory +{ + public static BulkUpdateOperationWithPartial WithPartial(Id id, TPartial partialDocument) => new(id, partialDocument); + + public static BulkUpdateOperationWithPartial WithPartial(Id id, IndexName index, TPartial partialDocument) => new(id, index, partialDocument); + + public static BulkUpdateOperationWithScript WithScript(Id id, IndexName index, Script script) => new(id, index, script); + + public static BulkUpdateOperationWithScript WithScript(Id id, IndexName index, Script script, TDocument upsert) => new(upsert, id, index, script); + + public static BulkUpdateOperationWithScript WithScript(Id id, Script script, TDocument upsert) => new(upsert, id, script); + + public static BulkUpdateOperationWithScript WithScript(Script script, TDocument upsert) => new(upsert, new Id(upsert), script); + + public static BulkUpdateOperationWithScript WithScript(Id id, Script script) => new(id, script); +} diff --git a/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkUpdateOperationWithPartial.cs b/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkUpdateOperationWithPartial.cs index b36d558ed08..8ad17bb279a 100644 --- a/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkUpdateOperationWithPartial.cs +++ b/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkUpdateOperationWithPartial.cs @@ -8,7 +8,7 @@ namespace Elastic.Clients.Elasticsearch.Core.Bulk; -public sealed class BulkUpdateOperationWithPartial : BulkUpdateOperationBase +public sealed class BulkUpdateOperationWithPartial : BulkUpdateOperation { public BulkUpdateOperationWithPartial(Id id, TPartialDocument partialDocument) { diff --git a/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkUpdateOperationWithScript.cs b/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkUpdateOperationWithScript.cs index 12eac78e9e9..d3feccab61d 100644 --- a/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkUpdateOperationWithScript.cs +++ b/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/BulkUpdateOperationWithScript.cs @@ -8,7 +8,7 @@ namespace Elastic.Clients.Elasticsearch.Core.Bulk; -public class BulkUpdateOperationWithScript : BulkUpdateOperationBase +public class BulkUpdateOperationWithScript : BulkUpdateOperation { public BulkUpdateOperationWithScript(Id id, Script script) { diff --git a/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/PartialBulkUpdateBody.cs b/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/PartialBulkUpdateBody.cs index 8e317df6e58..2d8b41ab60f 100644 --- a/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/PartialBulkUpdateBody.cs +++ b/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/PartialBulkUpdateBody.cs @@ -3,10 +3,11 @@ // See the LICENSE file in the project root for more information. using System.Text.Json; +using Elastic.Clients.Elasticsearch.Serialization; namespace Elastic.Clients.Elasticsearch.Core.Bulk; -internal class PartialBulkUpdateBody : BulkUpdateBodyBase +internal class PartialBulkUpdateBody : BulkUpdateBody { public bool? DocAsUpsert { get; set; } diff --git a/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/Response/BulkCreateResponseItem.cs b/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/Response/BulkCreateResponseItem.cs index f52006b0ff8..6e183cbb35c 100644 --- a/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/Response/BulkCreateResponseItem.cs +++ b/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/Response/BulkCreateResponseItem.cs @@ -4,7 +4,7 @@ namespace Elastic.Clients.Elasticsearch.Core.Bulk; -public sealed class CreateResponseItem : BulkResponseItemBase +public sealed class CreateResponseItem : ResponseItem { public override string Operation => "create"; } diff --git a/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/Response/BulkDeleteResponseItem.cs b/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/Response/BulkDeleteResponseItem.cs index bd5aa12751c..d7462faf2d5 100644 --- a/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/Response/BulkDeleteResponseItem.cs +++ b/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/Response/BulkDeleteResponseItem.cs @@ -4,7 +4,7 @@ namespace Elastic.Clients.Elasticsearch.Core.Bulk; -public sealed class BulkDeleteResponseItem : BulkResponseItemBase +public sealed class BulkDeleteResponseItem : ResponseItem { public override string Operation => "delete"; } diff --git a/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/Response/BulkIndexResponseItem.cs b/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/Response/BulkIndexResponseItem.cs index 4c949cb257f..4b6c0219107 100644 --- a/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/Response/BulkIndexResponseItem.cs +++ b/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/Response/BulkIndexResponseItem.cs @@ -4,7 +4,7 @@ namespace Elastic.Clients.Elasticsearch.Core.Bulk; -public sealed class BulkIndexResponseItem : BulkResponseItemBase +public sealed class BulkIndexResponseItem : ResponseItem { public override string Operation => "index"; } diff --git a/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/Response/BulkUpdateResponseItem.cs b/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/Response/BulkUpdateResponseItem.cs index 7e6b22a5b8c..ac2530b6e5d 100644 --- a/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/Response/BulkUpdateResponseItem.cs +++ b/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/Response/BulkUpdateResponseItem.cs @@ -4,7 +4,7 @@ namespace Elastic.Clients.Elasticsearch.Core.Bulk; -public sealed class BulkUpdateResponseItem : BulkResponseItemBase +public sealed class BulkUpdateResponseItem : ResponseItem { public override string Operation => "update"; } diff --git a/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/ScriptedBulkUpdateBody.cs b/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/ScriptedBulkUpdateBody.cs index 18801c1401d..2233aa69d07 100644 --- a/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/ScriptedBulkUpdateBody.cs +++ b/src/Elastic.Clients.Elasticsearch/Types/Core/Bulk/ScriptedBulkUpdateBody.cs @@ -3,10 +3,11 @@ // See the LICENSE file in the project root for more information. using System.Text.Json; +using Elastic.Clients.Elasticsearch.Serialization; namespace Elastic.Clients.Elasticsearch.Core.Bulk; -internal class ScriptedBulkUpdateBody : BulkUpdateBodyBase +internal class ScriptedBulkUpdateBody : BulkUpdateBody { public Script Script { get; set; } diff --git a/src/Elastic.Clients.Elasticsearch/Types/Documents/MultiSearch/SearchRequestItem.cs b/src/Elastic.Clients.Elasticsearch/Types/Documents/MultiSearch/SearchRequestItem.cs index b6c1cc2e58a..e6d7d0dd032 100644 --- a/src/Elastic.Clients.Elasticsearch/Types/Documents/MultiSearch/SearchRequestItem.cs +++ b/src/Elastic.Clients.Elasticsearch/Types/Documents/MultiSearch/SearchRequestItem.cs @@ -5,6 +5,7 @@ using System.IO; using System.Text.Json; using System.Threading.Tasks; +using Elastic.Clients.Elasticsearch.Serialization; using Elastic.Transport; namespace Elastic.Clients.Elasticsearch.Core.MSearch diff --git a/src/Elastic.Clients.Elasticsearch/Types/Mapping/PropertiesDescriptor.cs b/src/Elastic.Clients.Elasticsearch/Types/Mapping/PropertiesDescriptor.cs index cdeba437b0c..9bfb6107178 100644 --- a/src/Elastic.Clients.Elasticsearch/Types/Mapping/PropertiesDescriptor.cs +++ b/src/Elastic.Clients.Elasticsearch/Types/Mapping/PropertiesDescriptor.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Linq.Expressions; +using Elastic.Clients.Elasticsearch.Fluent; namespace Elastic.Clients.Elasticsearch.Mapping; diff --git a/src/Elastic.Clients.Elasticsearch/Types/ScriptBase.cs b/src/Elastic.Clients.Elasticsearch/Types/ScriptBase.cs deleted file mode 100644 index 4360134fe50..00000000000 --- a/src/Elastic.Clients.Elasticsearch/Types/ScriptBase.cs +++ /dev/null @@ -1,64 +0,0 @@ -// 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.Text.Json; -using System.Text.Json.Serialization; - -namespace Elastic.Clients.Elasticsearch; - -//public interface IScript { } - -///// -///// Base class for scripts -///// -//[JsonConverter(typeof(ScriptBaseConverter))] -//public abstract class Script : IScript -//{ -//} - -//internal sealed class ScriptBaseConverter : JsonConverter