Skip to content

Commit c32e3b3

Browse files
committed
Update Elastic.Transport to 0.5.2 (#8405)
1 parent 539c501 commit c32e3b3

16 files changed

+100
-198
lines changed

Diff for: src/Elastic.Clients.Elasticsearch.Serverless/Core/ElasticsearchClientProductRegistration.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,14 @@ public ElasticsearchClientProductRegistration(Type markerType) : base(markerType
2525

2626
public override string ServiceIdentifier => "esv";
2727

28-
public override string DefaultMimeType => null; // Prevent base 'ElasticsearchProductRegistration' from sending the compatibility header
28+
public override string? DefaultContentType => null; // Prevent base 'ElasticsearchProductRegistration' from sending the compatibility header
2929

3030
public override MetaHeaderProvider MetaHeaderProvider => _metaHeaderProvider;
3131

3232
/// <summary>
3333
/// Elastic.Clients.Elasticsearch handles 404 in its <see cref="ElasticsearchResponse.IsValidResponse" />, we do not want the low level client throwing
3434
/// exceptions
35-
/// when <see cref="ITransportConfiguration.ThrowExceptions" /> is enabled for 404's. The client is in charge of
35+
/// when <see cref="IRequestConfiguration.ThrowExceptions" /> is enabled for 404's. The client is in charge of
3636
/// composing paths
3737
/// so a 404 never signals a wrong URL but a missing entity.
3838
/// </summary>
@@ -77,7 +77,7 @@ public class ApiVersionMetaHeaderProducer : MetaHeaderProducer
7777

7878
public override string HeaderName => "Elastic-Api-Version";
7979

80-
public override string ProduceHeaderValue(RequestData requestData) => _apiVersion;
80+
public override string ProduceHeaderValue(RequestData requestData, bool isAsync) => _apiVersion;
8181

8282
public ApiVersionMetaHeaderProducer(VersionInfo version)
8383
{

Diff for: src/Elastic.Clients.Elasticsearch.Serverless/Elastic.Clients.Elasticsearch.Serverless.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
<Nullable>annotations</Nullable>
2222
</PropertyGroup>
2323
<ItemGroup>
24-
<PackageReference Include="Elastic.Transport" Version="0.4.26" />
24+
<PackageReference Include="Elastic.Transport" Version="0.5.2" />
2525
</ItemGroup>
2626
<ItemGroup>
2727
<InternalsVisibleTo Include="Tests" Key="$(ExposedPublicKey)" />

Diff for: src/Elastic.Clients.Elasticsearch/Core/ElasticsearchClientProductRegistration.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ public ElasticsearchClientProductRegistration(Type markerType) : base(markerType
1818
/// <summary>
1919
/// Elastic.Clients.Elasticsearch handles 404 in its <see cref="ElasticsearchResponse.IsValidResponse" />, we do not want the low level client throwing
2020
/// exceptions
21-
/// when <see cref="ITransportConfiguration.ThrowExceptions" /> is enabled for 404's. The client is in charge of
21+
/// when <see cref="IRequestConfiguration.ThrowExceptions" /> is enabled for 404's. The client is in charge of
2222
/// composing paths
2323
/// so a 404 never signals a wrong URL but a missing entity.
2424
/// </summary>

Diff for: src/Elastic.Clients.Elasticsearch/Elastic.Clients.Elasticsearch.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
<Nullable>annotations</Nullable>
2222
</PropertyGroup>
2323
<ItemGroup>
24-
<PackageReference Include="Elastic.Transport" Version="0.4.26" />
24+
<PackageReference Include="Elastic.Transport" Version="0.5.2" />
2525
</ItemGroup>
2626
<ItemGroup>
2727
<InternalsVisibleTo Include="Tests" Key="$(ExposedPublicKey)" />

Diff for: src/Elastic.Clients.Elasticsearch/_Shared/Api/BulkRequest.cs

+14-6
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,17 @@ namespace Elastic.Clients.Elasticsearch;
3232

3333
public partial class BulkRequest : IStreamSerializable
3434
{
35-
internal Request Self => this;
35+
private static readonly IRequestConfiguration RequestConfigSingleton = new RequestConfiguration
36+
{
37+
Accept = "application/json",
38+
ContentType = "application/x-ndjson"
39+
};
3640

37-
public BulkOperationsCollection Operations { get; set; }
41+
internal Request Self => this;
3842

39-
internal override string ContentType => "application/x-ndjson";
43+
protected internal override IRequestConfiguration RequestConfig => RequestConfigSingleton;
4044

41-
internal override string Accept => "application/json";
45+
public BulkOperationsCollection Operations { get; set; }
4246

4347
public void Serialize(Stream stream, IElasticsearchClientSettings settings, SerializationFormatting formatting = SerializationFormatting.None)
4448
{
@@ -87,9 +91,13 @@ public async Task SerializeAsync(Stream stream, IElasticsearchClientSettings set
8791

8892
public sealed partial class BulkRequestDescriptor : IStreamSerializable
8993
{
90-
internal override string ContentType => "application/x-ndjson";
94+
private static readonly IRequestConfiguration RequestConfigSingleton = new RequestConfiguration
95+
{
96+
Accept = "application/json",
97+
ContentType = "application/x-ndjson"
98+
};
9199

92-
internal override string Accept => "application/json";
100+
protected internal override IRequestConfiguration RequestConfig => RequestConfigSingleton;
93101

94102
private readonly BulkOperationsCollection _operations = new();
95103

Diff for: src/Elastic.Clients.Elasticsearch/_Shared/Api/Esql/EsqlQueryRequest.cs

+11-16
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,19 @@
1212
#if ELASTICSEARCH_SERVERLESS
1313
namespace Elastic.Clients.Elasticsearch.Serverless.Esql;
1414
#else
15-
1615
namespace Elastic.Clients.Elasticsearch.Esql;
1716
#endif
1817

19-
internal sealed class EsqlResponseBuilder : CustomResponseBuilder
18+
internal sealed class EsqlResponseBuilder : TypedResponseBuilder<EsqlQueryResponse>
2019
{
21-
public override object DeserializeResponse(Serializer serializer, ApiCallDetails response, Stream stream)
20+
protected override EsqlQueryResponse? Build(ApiCallDetails apiCallDetails, RequestData requestData,
21+
Stream responseStream,
22+
string contentType, long contentLength)
2223
{
23-
var bytes = stream switch
24+
var bytes = responseStream switch
2425
{
2526
MemoryStream ms => ms.ToArray(),
26-
_ => BytesFromStream(stream)
27+
_ => BytesFromStream(responseStream)
2728
};
2829

2930
return new EsqlQueryResponse { Data = bytes };
@@ -37,13 +38,14 @@ static byte[] BytesFromStream(Stream stream)
3738
}
3839
}
3940

40-
public override async Task<object> DeserializeResponseAsync(Serializer serializer, ApiCallDetails response, Stream stream,
41-
CancellationToken ctx = new CancellationToken())
41+
protected override async Task<EsqlQueryResponse?> BuildAsync(ApiCallDetails apiCallDetails, RequestData requestData,
42+
Stream responseStream,
43+
string contentType, long contentLength, CancellationToken cancellationToken = default)
4244
{
43-
var bytes = stream switch
45+
var bytes = responseStream switch
4446
{
4547
MemoryStream ms => ms.ToArray(),
46-
_ => await BytesFromStreamAsync(stream, ctx).ConfigureAwait(false)
48+
_ => await BytesFromStreamAsync(responseStream, cancellationToken).ConfigureAwait(false)
4749
};
4850

4951
return new EsqlQueryResponse { Data = bytes };
@@ -62,10 +64,3 @@ static async Task<byte[]> BytesFromStreamAsync(Stream stream, CancellationToken
6264
}
6365
}
6466
}
65-
66-
public sealed partial class EsqlQueryRequestParameters
67-
{
68-
private static readonly EsqlResponseBuilder ResponseBuilder = new();
69-
70-
public EsqlQueryRequestParameters() => CustomResponseBuilder = ResponseBuilder;
71-
}

Diff for: src/Elastic.Clients.Elasticsearch/_Shared/Client/ElasticsearchClient.cs

+34-99
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
#if ELASTICSEARCH_SERVERLESS
2222
namespace Elastic.Clients.Elasticsearch.Serverless;
2323
#else
24-
2524
namespace Elastic.Clients.Elasticsearch;
2625
#endif
2726

@@ -165,14 +164,12 @@ private ValueTask<TResponse> DoRequestCoreAsync<TRequest, TResponse, TRequestPar
165164

166165
ValueTask<TResponse> SendRequest()
167166
{
168-
var (resolvedUrl, _, resolvedRouteValues, postData) = PrepareRequest<TRequest, TRequestParameters>(request, forceConfiguration);
167+
var (endpointPath, resolvedRouteValues, postData) = PrepareRequest<TRequest, TRequestParameters>(request);
169168
var openTelemetryData = PrepareOpenTelemetryData<TRequest, TRequestParameters>(request, resolvedRouteValues);
170169

171170
return isAsync
172-
? new ValueTask<TResponse>(_transport
173-
.RequestAsync<TResponse>(request.HttpMethod, resolvedUrl, postData, request.RequestParameters, in openTelemetryData, cancellationToken))
174-
: new ValueTask<TResponse>(_transport
175-
.Request<TResponse>(request.HttpMethod, resolvedUrl, postData, request.RequestParameters, in openTelemetryData));
171+
? new ValueTask<TResponse>(_transport.RequestAsync<TResponse>(endpointPath, postData, in openTelemetryData, request.RequestConfig, cancellationToken))
172+
: new ValueTask<TResponse>(_transport.Request<TResponse>(endpointPath, postData, in openTelemetryData, request.RequestConfig));
176173
}
177174

178175
async ValueTask<TResponse> SendRequestWithProductCheck()
@@ -198,73 +195,59 @@ async ValueTask<TResponse> SendRequestWithProductCheckCore()
198195
{
199196
// Attach product check header
200197

201-
var hadRequestConfig = false;
202-
HeadersList? originalHeaders = null;
203-
204-
if (request.RequestParameters.RequestConfiguration is null)
205-
request.RequestParameters.RequestConfiguration = new RequestConfiguration();
206-
else
207-
{
208-
originalHeaders = request.RequestParameters.RequestConfiguration.ResponseHeadersToParse;
209-
hadRequestConfig = true;
210-
}
211-
212-
request.RequestParameters.RequestConfiguration.ResponseHeadersToParse = request.RequestParameters.RequestConfiguration.ResponseHeadersToParse.Count == 0
213-
? new HeadersList("x-elastic-product")
214-
: new HeadersList(request.RequestParameters.RequestConfiguration.ResponseHeadersToParse, "x-elastic-product");
198+
// TODO: The copy constructor should accept null values
199+
var requestConfig = (request.RequestConfig is null)
200+
? new RequestConfiguration()
201+
{
202+
ResponseHeadersToParse = new HeadersList("x-elastic-product")
203+
}
204+
: new RequestConfiguration(request.RequestConfig)
205+
{
206+
ResponseHeadersToParse = (request.RequestConfig.ResponseHeadersToParse is { Count: > 0 })
207+
? new HeadersList(request.RequestConfig.ResponseHeadersToParse, "x-elastic-product")
208+
: new HeadersList("x-elastic-product")
209+
};
215210

216211
// Send request
217212

218-
var (resolvedUrl, _, resolvedRouteValues, postData) = PrepareRequest<TRequest, TRequestParameters>(request, forceConfiguration);
213+
var (endpointPath, resolvedRouteValues, postData) = PrepareRequest<TRequest, TRequestParameters>(request);
219214
var openTelemetryData = PrepareOpenTelemetryData<TRequest, TRequestParameters>(request, resolvedRouteValues);
220215

221216
TResponse response;
222217

223218
if (isAsync)
224219
{
225220
response = await _transport
226-
.RequestAsync<TResponse>(request.HttpMethod, resolvedUrl, postData, request.RequestParameters, in openTelemetryData, cancellationToken)
221+
.RequestAsync<TResponse>(endpointPath, postData, in openTelemetryData, requestConfig, cancellationToken)
227222
.ConfigureAwait(false);
228223
}
229224
else
230225
{
231-
response = _transport
232-
.Request<TResponse>(request.HttpMethod, resolvedUrl, postData, request.RequestParameters, in openTelemetryData);
226+
response = _transport.Request<TResponse>(endpointPath, postData, in openTelemetryData, requestConfig);
233227
}
234228

235229
// Evaluate product check result
236230

237231
var hasSuccessStatusCode = response.ApiCallDetails.HttpStatusCode is >= 200 and <= 299;
238-
if (hasSuccessStatusCode)
239-
{
240-
var productCheckSucceeded = response.ApiCallDetails.TryGetHeader("x-elastic-product", out var values) &&
241-
values.FirstOrDefault(x => x.Equals("Elasticsearch", StringComparison.Ordinal)) is not null;
242-
243-
_productCheckStatus = productCheckSucceeded
244-
? (int)ProductCheckStatus.Succeeded
245-
: (int)ProductCheckStatus.Failed;
246-
247-
if (_productCheckStatus == (int)ProductCheckStatus.Failed)
248-
throw new UnsupportedProductException(UnsupportedProductException.InvalidProductError);
249-
}
250-
251-
if (request.RequestParameters.RequestConfiguration is null)
252-
return response;
253-
254-
// Reset request configuration
255-
256-
if (!hadRequestConfig)
257-
request.RequestParameters.RequestConfiguration = null;
258-
else if (originalHeaders is { Count: > 0 })
259-
request.RequestParameters.RequestConfiguration.ResponseHeadersToParse = originalHeaders.Value;
260-
261232
if (!hasSuccessStatusCode)
262233
{
263234
// The product check is unreliable for non success status codes.
264235
// We have to re-try on the next request.
265236
_productCheckStatus = (int)ProductCheckStatus.NotChecked;
237+
238+
return response;
266239
}
267240

241+
var productCheckSucceeded = response.ApiCallDetails.TryGetHeader("x-elastic-product", out var values) &&
242+
values.FirstOrDefault(x => x.Equals("Elasticsearch", StringComparison.Ordinal)) is not null;
243+
244+
_productCheckStatus = productCheckSucceeded
245+
? (int)ProductCheckStatus.Succeeded
246+
: (int)ProductCheckStatus.Failed;
247+
248+
if (_productCheckStatus == (int)ProductCheckStatus.Failed)
249+
throw new UnsupportedProductException(UnsupportedProductException.InvalidProductError);
250+
268251
return response;
269252
}
270253
}
@@ -304,69 +287,21 @@ private static OpenTelemetryData PrepareOpenTelemetryData<TRequest, TRequestPara
304287
return openTelemetryData;
305288
}
306289

307-
private (string resolvedUrl, string urlTemplate, Dictionary<string, string>? resolvedRouteValues, PostData data) PrepareRequest<TRequest, TRequestParameters>(TRequest request,
308-
Action<IRequestConfiguration>? forceConfiguration)
290+
private (EndpointPath endpointPath, Dictionary<string, string>? resolvedRouteValues, PostData data) PrepareRequest<TRequest, TRequestParameters>(TRequest request)
309291
where TRequest : Request<TRequestParameters>
310292
where TRequestParameters : RequestParameters, new()
311293
{
312294
request.ThrowIfNull(nameof(request), "A request is required.");
313295

314-
if (forceConfiguration is not null)
315-
ForceConfiguration(request, forceConfiguration);
316-
317-
if (request.ContentType is not null)
318-
ForceContentType<TRequest, TRequestParameters>(request, request.ContentType);
319-
320-
if (request.Accept is not null)
321-
ForceAccept<TRequest, TRequestParameters>(request, request.Accept);
322-
323-
var (resolvedUrl, urlTemplate, routeValues) = request.GetUrl(ElasticsearchClientSettings);
296+
var (resolvedUrl, _, routeValues) = request.GetUrl(ElasticsearchClientSettings);
297+
var pathAndQuery = request.RequestParameters.CreatePathWithQueryStrings(resolvedUrl, ElasticsearchClientSettings);
324298

325299
var postData =
326300
request.HttpMethod == HttpMethod.GET ||
327301
request.HttpMethod == HttpMethod.HEAD || !request.SupportsBody
328302
? null
329303
: PostData.Serializable(request);
330304

331-
return (resolvedUrl, urlTemplate, routeValues, postData);
332-
}
333-
334-
private static void ForceConfiguration<TRequestParameters>(Request<TRequestParameters> request, Action<IRequestConfiguration> forceConfiguration)
335-
where TRequestParameters : RequestParameters, new()
336-
{
337-
var configuration = request.RequestParameters.RequestConfiguration ?? new RequestConfiguration();
338-
forceConfiguration(configuration);
339-
request.RequestParameters.RequestConfiguration = configuration;
340-
}
341-
342-
private static void ForceContentType<TRequest, TRequestParameters>(TRequest request, string contentType)
343-
where TRequest : Request<TRequestParameters>
344-
where TRequestParameters : RequestParameters, new()
345-
{
346-
var configuration = request.RequestParameters.RequestConfiguration ?? new RequestConfiguration();
347-
configuration.Accept = contentType;
348-
configuration.ContentType = contentType;
349-
request.RequestParameters.RequestConfiguration = configuration;
350-
}
351-
352-
private static void ForceAccept<TRequest, TRequestParameters>(TRequest request, string acceptType)
353-
where TRequest : Request<TRequestParameters>
354-
where TRequestParameters : RequestParameters, new()
355-
{
356-
var configuration = request.RequestParameters.RequestConfiguration ?? new RequestConfiguration();
357-
configuration.Accept = acceptType;
358-
request.RequestParameters.RequestConfiguration = configuration;
359-
}
360-
361-
internal static void ForceJson(IRequestConfiguration requestConfiguration)
362-
{
363-
requestConfiguration.Accept = RequestData.DefaultMimeType;
364-
requestConfiguration.ContentType = RequestData.DefaultMimeType;
365-
}
366-
367-
internal static void ForceTextPlain(IRequestConfiguration requestConfiguration)
368-
{
369-
requestConfiguration.Accept = RequestData.MimeTypeTextPlain;
370-
requestConfiguration.ContentType = RequestData.MimeTypeTextPlain;
305+
return (new EndpointPath(request.HttpMethod, pathAndQuery), routeValues, postData);
371306
}
372307
}

Diff for: src/Elastic.Clients.Elasticsearch/_Shared/Core/Configuration/ElasticsearchClientSettings.cs

+13-9
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@
1010
using System.Reflection;
1111

1212
#if ELASTICSEARCH_SERVERLESS
13+
using Elastic.Clients.Elasticsearch.Serverless.Esql;
1314
using Elastic.Clients.Elasticsearch.Serverless.Fluent;
1415
#else
16+
using Elastic.Clients.Elasticsearch.Esql;
1517
using Elastic.Clients.Elasticsearch.Fluent;
1618
#endif
1719

@@ -104,9 +106,9 @@ public ElasticsearchClientSettings(
104106
/// <inheritdoc cref="IElasticsearchClientSettings" />
105107
[Browsable(false)]
106108
[EditorBrowsable(EditorBrowsableState.Never)]
107-
public abstract class
108-
ElasticsearchClientSettingsBase<TConnectionSettings> : ConnectionConfigurationBase<TConnectionSettings>,
109-
IElasticsearchClientSettings
109+
public abstract class ElasticsearchClientSettingsBase<TConnectionSettings> :
110+
ConnectionConfigurationBase<TConnectionSettings>,
111+
IElasticsearchClientSettings
110112
where TConnectionSettings : ElasticsearchClientSettingsBase<TConnectionSettings>, IElasticsearchClientSettings
111113
{
112114
private readonly FluentDictionary<Type, string> _defaultIndices;
@@ -381,19 +383,21 @@ public ConnectionConfiguration(NodePool nodePool, IRequestInvoker requestInvoker
381383
/// <inheritdoc cref="TransportClientConfigurationValues" />
382384
[Browsable(false)]
383385
[EditorBrowsable(EditorBrowsableState.Never)]
384-
public abstract class
385-
ConnectionConfigurationBase<TConnectionConfiguration> : TransportConfigurationBase<TConnectionConfiguration>,
386-
TransportClientConfigurationValues
387-
where TConnectionConfiguration : ConnectionConfigurationBase<TConnectionConfiguration>,
386+
public abstract class ConnectionConfigurationBase<TConnectionConfiguration> :
387+
TransportConfigurationDescriptorBase<TConnectionConfiguration>,
388388
TransportClientConfigurationValues
389+
where TConnectionConfiguration : ConnectionConfigurationBase<TConnectionConfiguration>, TransportClientConfigurationValues
389390
{
390391
private bool _includeServerStackTraceOnError;
391392

392393
protected ConnectionConfigurationBase(NodePool nodePool, IRequestInvoker requestInvoker,
393394
Serializer? serializer,
394395
ProductRegistration registration = null)
395-
: base(nodePool, requestInvoker, serializer, registration ?? new ElasticsearchProductRegistration(typeof(ElasticsearchClient))) =>
396-
UserAgent(ConnectionConfiguration.DefaultUserAgent);
396+
: base(nodePool, requestInvoker, serializer, registration ?? new ElasticsearchProductRegistration(typeof(ElasticsearchClient)))
397+
{
398+
UserAgent(ConnectionConfiguration.DefaultUserAgent);
399+
ResponseBuilder(new EsqlResponseBuilder());
400+
}
397401

398402
bool TransportClientConfigurationValues.IncludeServerStackTraceOnError => _includeServerStackTraceOnError;
399403

0 commit comments

Comments
 (0)