From 1274938d7573e9d0e4329904954a40fd859a27e4 Mon Sep 17 00:00:00 2001 From: Florian Bernd Date: Thu, 14 Nov 2024 12:49:06 +0100 Subject: [PATCH] Update `Elastic.Transport` --- .../ElasticsearchClientProductRegistration.cs | 6 +- ...ic.Clients.Elasticsearch.Serverless.csproj | 2 +- .../ElasticsearchClientProductRegistration.cs | 2 +- .../Elastic.Clients.Elasticsearch.csproj | 2 +- .../_Shared/Api/BulkRequest.cs | 20 +- .../_Shared/Api/Esql/EsqlQueryRequest.cs | 27 +- .../_Shared/Client/ElasticsearchClient.cs | 260 +++++++----------- .../ElasticsearchClientSettings.cs | 22 +- .../_Shared/Core/Request/PlainRequest.cs | 8 +- .../_Shared/Core/Request/Request.cs | 20 +- .../_Shared/Core/Request/RequestDescriptor.cs | 15 +- .../_Shared/Helpers/BulkAllObservable.cs | 2 +- .../Helpers/RequestParametersExtensions.cs | 29 -- src/Playground/Playground.csproj | 2 +- .../Tests.Core/Client/FixedResponseClient.cs | 6 +- tests/Tests/Tests.csproj | 2 +- 16 files changed, 172 insertions(+), 253 deletions(-) delete mode 100644 src/Elastic.Clients.Elasticsearch/_Shared/Helpers/RequestParametersExtensions.cs diff --git a/src/Elastic.Clients.Elasticsearch.Serverless/Core/ElasticsearchClientProductRegistration.cs b/src/Elastic.Clients.Elasticsearch.Serverless/Core/ElasticsearchClientProductRegistration.cs index 225f124c7c1..14278786060 100644 --- a/src/Elastic.Clients.Elasticsearch.Serverless/Core/ElasticsearchClientProductRegistration.cs +++ b/src/Elastic.Clients.Elasticsearch.Serverless/Core/ElasticsearchClientProductRegistration.cs @@ -25,14 +25,14 @@ public ElasticsearchClientProductRegistration(Type markerType) : base(markerType public override string ServiceIdentifier => "esv"; - public override string DefaultMimeType => null; // Prevent base 'ElasticsearchProductRegistration' from sending the compatibility header + public override string? DefaultContentType => null; // Prevent base 'ElasticsearchProductRegistration' from sending the compatibility header public override MetaHeaderProvider MetaHeaderProvider => _metaHeaderProvider; /// /// Elastic.Clients.Elasticsearch handles 404 in its , we do not want the low level client throwing /// exceptions - /// when is enabled for 404's. The client is in charge of + /// when is enabled for 404's. The client is in charge of /// composing paths /// so a 404 never signals a wrong URL but a missing entity. /// @@ -77,7 +77,7 @@ public class ApiVersionMetaHeaderProducer : MetaHeaderProducer public override string HeaderName => "Elastic-Api-Version"; - public override string ProduceHeaderValue(RequestData requestData) => _apiVersion; + public override string ProduceHeaderValue(RequestData requestData, bool isAsync) => _apiVersion; public ApiVersionMetaHeaderProducer(VersionInfo version) { diff --git a/src/Elastic.Clients.Elasticsearch.Serverless/Elastic.Clients.Elasticsearch.Serverless.csproj b/src/Elastic.Clients.Elasticsearch.Serverless/Elastic.Clients.Elasticsearch.Serverless.csproj index 4e00bb4e38c..9907978767d 100644 --- a/src/Elastic.Clients.Elasticsearch.Serverless/Elastic.Clients.Elasticsearch.Serverless.csproj +++ b/src/Elastic.Clients.Elasticsearch.Serverless/Elastic.Clients.Elasticsearch.Serverless.csproj @@ -21,7 +21,7 @@ annotations - + diff --git a/src/Elastic.Clients.Elasticsearch/Core/ElasticsearchClientProductRegistration.cs b/src/Elastic.Clients.Elasticsearch/Core/ElasticsearchClientProductRegistration.cs index 3f00d9bb255..6c5e75b814e 100644 --- a/src/Elastic.Clients.Elasticsearch/Core/ElasticsearchClientProductRegistration.cs +++ b/src/Elastic.Clients.Elasticsearch/Core/ElasticsearchClientProductRegistration.cs @@ -18,7 +18,7 @@ public ElasticsearchClientProductRegistration(Type markerType) : base(markerType /// /// Elastic.Clients.Elasticsearch handles 404 in its , we do not want the low level client throwing /// exceptions - /// when is enabled for 404's. The client is in charge of + /// when is enabled for 404's. The client is in charge of /// composing paths /// so a 404 never signals a wrong URL but a missing entity. /// diff --git a/src/Elastic.Clients.Elasticsearch/Elastic.Clients.Elasticsearch.csproj b/src/Elastic.Clients.Elasticsearch/Elastic.Clients.Elasticsearch.csproj index dcd3c9db9d8..c3409a69737 100644 --- a/src/Elastic.Clients.Elasticsearch/Elastic.Clients.Elasticsearch.csproj +++ b/src/Elastic.Clients.Elasticsearch/Elastic.Clients.Elasticsearch.csproj @@ -21,7 +21,7 @@ annotations - + diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Api/BulkRequest.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Api/BulkRequest.cs index b9a2bf5151e..853b13a8be5 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Api/BulkRequest.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Api/BulkRequest.cs @@ -32,13 +32,17 @@ namespace Elastic.Clients.Elasticsearch; public partial class BulkRequest : IStreamSerializable { - internal Request Self => this; + private static readonly IRequestConfiguration RequestConfigSingleton = new RequestConfiguration + { + Accept = "application/json", + ContentType = "application/x-ndjson" + }; - public BulkOperationsCollection Operations { get; set; } + internal Request Self => this; - internal override string ContentType => "application/x-ndjson"; + protected internal override IRequestConfiguration RequestConfig => RequestConfigSingleton; - internal override string Accept => "application/json"; + public BulkOperationsCollection Operations { get; set; } public void Serialize(Stream stream, IElasticsearchClientSettings settings, SerializationFormatting formatting = SerializationFormatting.None) { @@ -87,9 +91,13 @@ public async Task SerializeAsync(Stream stream, IElasticsearchClientSettings set public sealed partial class BulkRequestDescriptor : IStreamSerializable { - internal override string ContentType => "application/x-ndjson"; + private static readonly IRequestConfiguration RequestConfigSingleton = new RequestConfiguration + { + Accept = "application/json", + ContentType = "application/x-ndjson" + }; - internal override string Accept => "application/json"; + protected internal override IRequestConfiguration RequestConfig => RequestConfigSingleton; private readonly BulkOperationsCollection _operations = new(); diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Api/Esql/EsqlQueryRequest.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Api/Esql/EsqlQueryRequest.cs index 3f5821e2cb0..f4b002621f9 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Api/Esql/EsqlQueryRequest.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Api/Esql/EsqlQueryRequest.cs @@ -12,18 +12,19 @@ #if ELASTICSEARCH_SERVERLESS namespace Elastic.Clients.Elasticsearch.Serverless.Esql; #else - namespace Elastic.Clients.Elasticsearch.Esql; #endif -internal sealed class EsqlResponseBuilder : CustomResponseBuilder +internal sealed class EsqlResponseBuilder : TypedResponseBuilder { - public override object DeserializeResponse(Serializer serializer, ApiCallDetails response, Stream stream) + protected override EsqlQueryResponse? Build(ApiCallDetails apiCallDetails, RequestData requestData, + Stream responseStream, + string contentType, long contentLength) { - var bytes = stream switch + var bytes = responseStream switch { MemoryStream ms => ms.ToArray(), - _ => BytesFromStream(stream) + _ => BytesFromStream(responseStream) }; return new EsqlQueryResponse { Data = bytes }; @@ -37,13 +38,14 @@ static byte[] BytesFromStream(Stream stream) } } - public override async Task DeserializeResponseAsync(Serializer serializer, ApiCallDetails response, Stream stream, - CancellationToken ctx = new CancellationToken()) + protected override async Task BuildAsync(ApiCallDetails apiCallDetails, RequestData requestData, + Stream responseStream, + string contentType, long contentLength, CancellationToken cancellationToken = default) { - var bytes = stream switch + var bytes = responseStream switch { MemoryStream ms => ms.ToArray(), - _ => await BytesFromStreamAsync(stream, ctx).ConfigureAwait(false) + _ => await BytesFromStreamAsync(responseStream, cancellationToken).ConfigureAwait(false) }; return new EsqlQueryResponse { Data = bytes }; @@ -62,10 +64,3 @@ static async Task BytesFromStreamAsync(Stream stream, CancellationToken } } } - -public sealed partial class EsqlQueryRequestParameters -{ - private static readonly EsqlResponseBuilder ResponseBuilder = new(); - - public EsqlQueryRequestParameters() => CustomResponseBuilder = ResponseBuilder; -} diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Client/ElasticsearchClient.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Client/ElasticsearchClient.cs index c71b196dec4..aa863b60498 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Client/ElasticsearchClient.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Client/ElasticsearchClient.cs @@ -21,7 +21,6 @@ #if ELASTICSEARCH_SERVERLESS namespace Elastic.Clients.Elasticsearch.Serverless; #else - namespace Elastic.Clients.Elasticsearch; #endif @@ -154,119 +153,121 @@ private ValueTask DoRequestCoreAsync SendRequestWithProductCheck(), - (int)ProductCheckStatus.InProgress or - (int)ProductCheckStatus.Succeeded => SendRequest(), - (int)ProductCheckStatus.Failed => throw new UnsupportedProductException(UnsupportedProductException.InvalidProductError), - _ => throw new InvalidOperationException("unreachable") - }; + // TODO: Re-enable product check + //return productCheckStatus switch + //{ + // (int)ProductCheckStatus.NotChecked => SendRequestWithProductCheck(), + // (int)ProductCheckStatus.InProgress or + // (int)ProductCheckStatus.Succeeded => SendRequest(), + // (int)ProductCheckStatus.Failed => throw new UnsupportedProductException(UnsupportedProductException.InvalidProductError), + // _ => throw new InvalidOperationException("unreachable") + //}; + return SendRequest(); ValueTask SendRequest() { - var (resolvedUrl, _, resolvedRouteValues, postData) = PrepareRequest(request, forceConfiguration); + var (resolvedUrl, _, resolvedRouteValues, postData) = PrepareRequest(request); var openTelemetryData = PrepareOpenTelemetryData(request, resolvedRouteValues); return isAsync ? new ValueTask(_transport - .RequestAsync(request.HttpMethod, resolvedUrl, postData, request.RequestParameters, in openTelemetryData, cancellationToken)) + .RequestAsync(new EndpointPath(request.HttpMethod, resolvedUrl), postData, in openTelemetryData, request.RequestConfig, cancellationToken)) : new ValueTask(_transport - .Request(request.HttpMethod, resolvedUrl, postData, request.RequestParameters, in openTelemetryData)); + .Request(new EndpointPath(request.HttpMethod, resolvedUrl), postData, in openTelemetryData, request.RequestConfig)); } - async ValueTask SendRequestWithProductCheck() - { - try - { - return await SendRequestWithProductCheckCore().ConfigureAwait(false); - } - catch - { - // Re-try product check on next request. - - // 32-bit read/write operations are atomic and due to the initial memory barrier, we can be sure that - // no other thread executes the product check at the same time. Locked access is not required here. - if (_productCheckStatus is (int)ProductCheckStatus.InProgress) - _productCheckStatus = (int)ProductCheckStatus.NotChecked; - - throw; - } - } - - async ValueTask SendRequestWithProductCheckCore() - { - // Attach product check header - - var hadRequestConfig = false; - HeadersList? originalHeaders = null; - - if (request.RequestParameters.RequestConfiguration is null) - request.RequestParameters.RequestConfiguration = new RequestConfiguration(); - else - { - originalHeaders = request.RequestParameters.RequestConfiguration.ResponseHeadersToParse; - hadRequestConfig = true; - } - - request.RequestParameters.RequestConfiguration.ResponseHeadersToParse = request.RequestParameters.RequestConfiguration.ResponseHeadersToParse.Count == 0 - ? new HeadersList("x-elastic-product") - : new HeadersList(request.RequestParameters.RequestConfiguration.ResponseHeadersToParse, "x-elastic-product"); - - // Send request - - var (resolvedUrl, _, resolvedRouteValues, postData) = PrepareRequest(request, forceConfiguration); - var openTelemetryData = PrepareOpenTelemetryData(request, resolvedRouteValues); - - TResponse response; - - if (isAsync) - { - response = await _transport - .RequestAsync(request.HttpMethod, resolvedUrl, postData, request.RequestParameters, in openTelemetryData, cancellationToken) - .ConfigureAwait(false); - } - else - { - response = _transport - .Request(request.HttpMethod, resolvedUrl, postData, request.RequestParameters, in openTelemetryData); - } - - // Evaluate product check result - - var hasSuccessStatusCode = response.ApiCallDetails.HttpStatusCode is >= 200 and <= 299; - if (hasSuccessStatusCode) - { - var productCheckSucceeded = response.ApiCallDetails.TryGetHeader("x-elastic-product", out var values) && - values.FirstOrDefault(x => x.Equals("Elasticsearch", StringComparison.Ordinal)) is not null; - - _productCheckStatus = productCheckSucceeded - ? (int)ProductCheckStatus.Succeeded - : (int)ProductCheckStatus.Failed; - - if (_productCheckStatus == (int)ProductCheckStatus.Failed) - throw new UnsupportedProductException(UnsupportedProductException.InvalidProductError); - } - - if (request.RequestParameters.RequestConfiguration is null) - return response; - - // Reset request configuration - - if (!hadRequestConfig) - request.RequestParameters.RequestConfiguration = null; - else if (originalHeaders is { Count: > 0 }) - request.RequestParameters.RequestConfiguration.ResponseHeadersToParse = originalHeaders.Value; - - if (!hasSuccessStatusCode) - { - // The product check is unreliable for non success status codes. - // We have to re-try on the next request. - _productCheckStatus = (int)ProductCheckStatus.NotChecked; - } - - return response; - } + //async ValueTask SendRequestWithProductCheck() + //{ + // try + // { + // return await SendRequestWithProductCheckCore().ConfigureAwait(false); + // } + // catch + // { + // // Re-try product check on next request. + + // // 32-bit read/write operations are atomic and due to the initial memory barrier, we can be sure that + // // no other thread executes the product check at the same time. Locked access is not required here. + // if (_productCheckStatus is (int)ProductCheckStatus.InProgress) + // _productCheckStatus = (int)ProductCheckStatus.NotChecked; + + // throw; + // } + //} + + //async ValueTask SendRequestWithProductCheckCore() + //{ + // // Attach product check header + + // var hadRequestConfig = false; + // HeadersList? originalHeaders = null; + + // if (request.RequestConfiguration is null) + // request.RequestParameters.RequestConfiguration = new RequestConfiguration(); + // else + // { + // originalHeaders = request.RequestParameters.RequestConfiguration.ResponseHeadersToParse; + // hadRequestConfig = true; + // } + + // request.RequestParameters.RequestConfiguration.ResponseHeadersToParse = request.RequestParameters.RequestConfiguration.ResponseHeadersToParse.Count == 0 + // ? new HeadersList("x-elastic-product") + // : new HeadersList(request.RequestParameters.RequestConfiguration.ResponseHeadersToParse, "x-elastic-product"); + + // // Send request + + // var (resolvedUrl, _, resolvedRouteValues, postData) = PrepareRequest(request, forceConfiguration); + // var openTelemetryData = PrepareOpenTelemetryData(request, resolvedRouteValues); + + // TResponse response; + + // if (isAsync) + // { + // response = await _transport + // .RequestAsync(request.HttpMethod, resolvedUrl, postData, request.RequestParameters, in openTelemetryData, cancellationToken) + // .ConfigureAwait(false); + // } + // else + // { + // response = _transport + // .Request(request.HttpMethod, resolvedUrl, postData, request.RequestParameters, in openTelemetryData); + // } + + // // Evaluate product check result + + // var hasSuccessStatusCode = response.ApiCallDetails.HttpStatusCode is >= 200 and <= 299; + // if (hasSuccessStatusCode) + // { + // var productCheckSucceeded = response.ApiCallDetails.TryGetHeader("x-elastic-product", out var values) && + // values.FirstOrDefault(x => x.Equals("Elasticsearch", StringComparison.Ordinal)) is not null; + + // _productCheckStatus = productCheckSucceeded + // ? (int)ProductCheckStatus.Succeeded + // : (int)ProductCheckStatus.Failed; + + // if (_productCheckStatus == (int)ProductCheckStatus.Failed) + // throw new UnsupportedProductException(UnsupportedProductException.InvalidProductError); + // } + + // if (request.RequestParameters.RequestConfiguration is null) + // return response; + + // // Reset request configuration + + // if (!hadRequestConfig) + // request.RequestParameters.RequestConfiguration = null; + // else if (originalHeaders is { Count: > 0 }) + // request.RequestParameters.RequestConfiguration.ResponseHeadersToParse = originalHeaders.Value; + + // if (!hasSuccessStatusCode) + // { + // // The product check is unreliable for non success status codes. + // // We have to re-try on the next request. + // _productCheckStatus = (int)ProductCheckStatus.NotChecked; + // } + + // return response; + //} } private static OpenTelemetryData PrepareOpenTelemetryData(TRequest request, Dictionary resolvedRouteValues) @@ -304,22 +305,12 @@ private static OpenTelemetryData PrepareOpenTelemetryData? resolvedRouteValues, PostData data) PrepareRequest(TRequest request, - Action? forceConfiguration) + private (string resolvedUrl, string urlTemplate, Dictionary? resolvedRouteValues, PostData data) PrepareRequest(TRequest request) where TRequest : Request where TRequestParameters : RequestParameters, new() { request.ThrowIfNull(nameof(request), "A request is required."); - if (forceConfiguration is not null) - ForceConfiguration(request, forceConfiguration); - - if (request.ContentType is not null) - ForceContentType(request, request.ContentType); - - if (request.Accept is not null) - ForceAccept(request, request.Accept); - var (resolvedUrl, urlTemplate, routeValues) = request.GetUrl(ElasticsearchClientSettings); var postData = @@ -330,43 +321,4 @@ private static OpenTelemetryData PrepareOpenTelemetryData(Request request, Action forceConfiguration) - where TRequestParameters : RequestParameters, new() - { - var configuration = request.RequestParameters.RequestConfiguration ?? new RequestConfiguration(); - forceConfiguration(configuration); - request.RequestParameters.RequestConfiguration = configuration; - } - - private static void ForceContentType(TRequest request, string contentType) - where TRequest : Request - where TRequestParameters : RequestParameters, new() - { - var configuration = request.RequestParameters.RequestConfiguration ?? new RequestConfiguration(); - configuration.Accept = contentType; - configuration.ContentType = contentType; - request.RequestParameters.RequestConfiguration = configuration; - } - - private static void ForceAccept(TRequest request, string acceptType) - where TRequest : Request - where TRequestParameters : RequestParameters, new() - { - var configuration = request.RequestParameters.RequestConfiguration ?? new RequestConfiguration(); - configuration.Accept = acceptType; - request.RequestParameters.RequestConfiguration = configuration; - } - - internal static void ForceJson(IRequestConfiguration requestConfiguration) - { - requestConfiguration.Accept = RequestData.DefaultMimeType; - requestConfiguration.ContentType = RequestData.DefaultMimeType; - } - - internal static void ForceTextPlain(IRequestConfiguration requestConfiguration) - { - requestConfiguration.Accept = RequestData.MimeTypeTextPlain; - requestConfiguration.ContentType = RequestData.MimeTypeTextPlain; - } } diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Core/Configuration/ElasticsearchClientSettings.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Core/Configuration/ElasticsearchClientSettings.cs index 62c3e7ce566..b8381c7df40 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Core/Configuration/ElasticsearchClientSettings.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Core/Configuration/ElasticsearchClientSettings.cs @@ -10,8 +10,10 @@ using System.Reflection; #if ELASTICSEARCH_SERVERLESS +using Elastic.Clients.Elasticsearch.Serverless.Esql; using Elastic.Clients.Elasticsearch.Serverless.Fluent; #else +using Elastic.Clients.Elasticsearch.Esql; using Elastic.Clients.Elasticsearch.Fluent; #endif @@ -104,9 +106,9 @@ public ElasticsearchClientSettings( /// [Browsable(false)] [EditorBrowsable(EditorBrowsableState.Never)] -public abstract class - ElasticsearchClientSettingsBase : ConnectionConfigurationBase, - IElasticsearchClientSettings +public abstract class ElasticsearchClientSettingsBase : + ConnectionConfigurationBase, + IElasticsearchClientSettings where TConnectionSettings : ElasticsearchClientSettingsBase, IElasticsearchClientSettings { private readonly FluentDictionary _defaultIndices; @@ -381,19 +383,21 @@ public ConnectionConfiguration(NodePool nodePool, IRequestInvoker requestInvoker /// [Browsable(false)] [EditorBrowsable(EditorBrowsableState.Never)] -public abstract class - ConnectionConfigurationBase : TransportConfigurationBase, - TransportClientConfigurationValues - where TConnectionConfiguration : ConnectionConfigurationBase, +public abstract class ConnectionConfigurationBase : + TransportConfigurationDescriptorBase, TransportClientConfigurationValues + where TConnectionConfiguration : ConnectionConfigurationBase, TransportClientConfigurationValues { private bool _includeServerStackTraceOnError; protected ConnectionConfigurationBase(NodePool nodePool, IRequestInvoker requestInvoker, Serializer? serializer, ProductRegistration registration = null) - : base(nodePool, requestInvoker, serializer, registration ?? new ElasticsearchProductRegistration(typeof(ElasticsearchClient))) => - UserAgent(ConnectionConfiguration.DefaultUserAgent); + : base(nodePool, requestInvoker, serializer, registration ?? new ElasticsearchProductRegistration(typeof(ElasticsearchClient))) + { + UserAgent(ConnectionConfiguration.DefaultUserAgent); + ResponseBuilder(new EsqlResponseBuilder()); + } bool TransportClientConfigurationValues.IncludeServerStackTraceOnError => _includeServerStackTraceOnError; diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Core/Request/PlainRequest.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Core/Request/PlainRequest.cs index 912d1a46dbd..9e36e7f3894 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Core/Request/PlainRequest.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Core/Request/PlainRequest.cs @@ -15,6 +15,8 @@ namespace Elastic.Clients.Elasticsearch.Requests; public abstract class PlainRequest : Request where TParameters : RequestParameters, new() { + private IRequestConfiguration? _requestConfiguration; // TODO: Remove this from the request classes and add to the endpoint methods instead + // This internal ctor ensures that only types defined within the Elastic.Clients.Elasticsearch assembly can derive from this base class. // We don't expect consumers to derive from this public base class. internal PlainRequest() { } @@ -75,9 +77,9 @@ public string SourceQueryString /// Specify settings for this request alone, handy if you need a custom timeout or want to bypass sniffing, retries /// [JsonIgnore] - public IRequestConfiguration RequestConfiguration + public IRequestConfiguration? RequestConfiguration { - get => RequestParameters.RequestConfiguration; - set => RequestParameters.RequestConfiguration = value; + get => _requestConfiguration; + set => _requestConfiguration = value; } } diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Core/Request/Request.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Core/Request/Request.cs index 2b643379e60..9d3a2470874 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Core/Request/Request.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Core/Request/Request.cs @@ -6,7 +6,6 @@ using System.Collections.Generic; using System.Text.Json.Serialization; using Elastic.Transport; -using Elastic.Transport.Diagnostics; #if ELASTICSEARCH_SERVERLESS namespace Elastic.Clients.Elasticsearch.Serverless.Requests; @@ -23,9 +22,7 @@ public abstract class Request // We don't expect consumers to derive from this public base class. internal Request() { } - internal virtual string? Accept { get; } = null; - - internal virtual string? ContentType { get; } = null; + [JsonIgnore] protected internal virtual IRequestConfiguration? RequestConfig { get; set; } /// /// The default HTTP method for the request which is based on the Elasticsearch Specification endpoint definition. @@ -68,28 +65,19 @@ internal virtual void BeforeRequest() { } public abstract class Request : Request where TParameters : RequestParameters, new() { - private readonly TParameters _parameters; - - internal Request() => _parameters = new TParameters(); + internal Request() => RequestParameters = new TParameters(); protected Request(Func pathSelector) { pathSelector(RouteValues); - _parameters = new TParameters(); + RequestParameters = new TParameters(); } - [JsonIgnore] internal TParameters RequestParameters => _parameters; + [JsonIgnore] internal TParameters RequestParameters { get; } protected TOut? Q(string name) => RequestParameters.GetQueryStringValue(name); protected void Q(string name, object? value) => RequestParameters.SetQueryString(name, value); protected void Q(string name, IStringable value) => RequestParameters.SetQueryString(name, value.GetString()); - - protected void SetAcceptHeader(string format) - { - RequestParameters.RequestConfiguration ??= new RequestConfiguration(); - RequestParameters.RequestConfiguration.Accept = - RequestParameters.AcceptHeaderFromFormat(format); - } } diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Core/Request/RequestDescriptor.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Core/Request/RequestDescriptor.cs index 77ad327e1f5..05723aa7855 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Core/Request/RequestDescriptor.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Core/Request/RequestDescriptor.cs @@ -22,9 +22,10 @@ namespace Elastic.Clients.Elasticsearch.Requests; /// /// Base class for all request descriptor types. /// -public abstract partial class RequestDescriptor : Request, ISelfSerializable - where TDescriptor : RequestDescriptor - where TParameters : RequestParameters, new() +public abstract partial class RequestDescriptor : + Request, ISelfSerializable + where TDescriptor : RequestDescriptor + where TParameters : RequestParameters, new() { private readonly TDescriptor _descriptor; @@ -56,12 +57,10 @@ protected TDescriptor Qs(string name, IStringable value) /// /// Specify settings for this request alone, handy if you need a custom timeout or want to bypass sniffing, retries /// - public TDescriptor RequestConfiguration( - Func configurationSelector) + public TDescriptor RequestConfiguration(Func configurationSelector) { - var rc = RequestParameters.RequestConfiguration; - RequestParameters.RequestConfiguration = - configurationSelector?.Invoke(new RequestConfigurationDescriptor(rc)) ?? rc; + var rc = RequestConfig; + RequestConfig = configurationSelector?.Invoke(new RequestConfigurationDescriptor(rc)) ?? rc; return _descriptor; } diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Helpers/BulkAllObservable.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Helpers/BulkAllObservable.cs index e452e3465f1..e622b1436df 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Helpers/BulkAllObservable.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Helpers/BulkAllObservable.cs @@ -124,7 +124,7 @@ private async Task BulkAsync(IList buffer, long page, int ba var response = await _client.BulkAsync(s => { - s.RequestParameters.RequestConfiguration = new RequestConfiguration { DisableAuditTrail = false }; + s.RequestConfiguration(x => x.DisableAuditTrail(false)); s.Index(request.Index); s.Timeout(request.Timeout); diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Helpers/RequestParametersExtensions.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Helpers/RequestParametersExtensions.cs deleted file mode 100644 index 0640c806a70..00000000000 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Helpers/RequestParametersExtensions.cs +++ /dev/null @@ -1,29 +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 Elastic.Transport; - -#if ELASTICSEARCH_SERVERLESS -namespace Elastic.Clients.Elasticsearch.Serverless; -#else -namespace Elastic.Clients.Elasticsearch; -#endif - -internal static class RequestParametersExtensions -{ - internal static void SetRequestMetaData(this RequestParameters parameters, RequestMetaData requestMetaData) - { - if (parameters is null) - throw new ArgumentNullException(nameof(parameters)); - - if (requestMetaData is null) - throw new ArgumentNullException(nameof(requestMetaData)); - - parameters.RequestConfiguration ??= new RequestConfiguration(); - - parameters.RequestConfiguration.RequestMetaData = requestMetaData; - } -} diff --git a/src/Playground/Playground.csproj b/src/Playground/Playground.csproj index a2095681e91..455e7a6ebd9 100644 --- a/src/Playground/Playground.csproj +++ b/src/Playground/Playground.csproj @@ -10,7 +10,7 @@ - + diff --git a/tests/Tests.Core/Client/FixedResponseClient.cs b/tests/Tests.Core/Client/FixedResponseClient.cs index 8a33f59ed50..310a216f0f1 100644 --- a/tests/Tests.Core/Client/FixedResponseClient.cs +++ b/tests/Tests.Core/Client/FixedResponseClient.cs @@ -17,7 +17,7 @@ public static ElasticsearchClient Create( object response, int statusCode = 200, Func modifySettings = null, - string contentType = RequestData.DefaultMimeType, + string contentType = RequestData.DefaultContentType, Exception exception = null ) { @@ -29,7 +29,7 @@ public static ElasticsearchClientSettings CreateConnectionSettings( object response, int statusCode = 200, Func modifySettings = null, - string contentType = RequestData.DefaultMimeType, + string contentType = RequestData.DefaultContentType, Exception exception = null, Serializer serializer = null ) @@ -46,7 +46,7 @@ public static ElasticsearchClientSettings CreateConnectionSettings( break; default: { - responseBytes = contentType == RequestData.DefaultMimeType + responseBytes = contentType == RequestData.DefaultContentType ? serializer.SerializeToBytes(response, TestClient.Default.ElasticsearchClientSettings.MemoryStreamFactory) : Encoding.UTF8.GetBytes(response.ToString()); diff --git a/tests/Tests/Tests.csproj b/tests/Tests/Tests.csproj index e764cc6a729..7d2fab50684 100644 --- a/tests/Tests/Tests.csproj +++ b/tests/Tests/Tests.csproj @@ -10,7 +10,7 @@ - +