Skip to content

Refactor client overloads #7880

New issue

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

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

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Aug 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
251 changes: 11 additions & 240 deletions src/Elastic.Clients.Elasticsearch/Client/ElasticsearchClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,8 @@ internal ElasticsearchClient(HttpTransport<IElasticsearchClientSettings> transpo

public IElasticsearchClientSettings ElasticsearchClientSettings => _transport.Settings;
public Inferrer Infer => _transport.Settings.Inferrer;

public Serializer RequestResponseSerializer => _transport.Settings.RequestResponseSerializer;
public Serializer SourceSerializer => _transport.Settings.SourceSerializer;

public HttpTransport Transport => _transport;

private ProductCheckStatus _productCheckStatus;
Expand All @@ -93,83 +91,15 @@ private enum ProductCheckStatus

private partial void SetupNamespaces();

internal TResponse DoRequest<TRequest, TResponse, TRequestParameters>(
TRequest request,
TRequestParameters? parameters,
Action<IRequestConfiguration>? forceConfiguration = null)
internal TResponse DoRequest<TRequest, TResponse, TRequestParameters>(TRequest request)
where TRequest : Request<TRequestParameters>
where TResponse : ElasticsearchResponse, new()
where TRequestParameters : RequestParameters, new()
{
if (_productCheckStatus == ProductCheckStatus.Failed)
throw new UnsupportedProductException(UnsupportedProductException.InvalidProductError);

var requestModified = false;
var hadRequestConfig = false;
HeadersList? originalHeaders = null;

// If we have not yet checked the product name, add the product header to the list of headers to parse.
if (_productCheckStatus == ProductCheckStatus.NotChecked)
{
requestModified = true;
if (request.RequestParameters.RequestConfiguration is null)
{
request.RequestParameters.RequestConfiguration = new RequestConfiguration();
}
else
{
originalHeaders = request.RequestParameters.RequestConfiguration.ResponseHeadersToParse;
hadRequestConfig = true;
}

if (request.RequestParameters.RequestConfiguration.ResponseHeadersToParse.Count == 0)
{
request.RequestParameters.RequestConfiguration.ResponseHeadersToParse = new HeadersList("x-elastic-product");
}
else
{
request.RequestParameters.RequestConfiguration.ResponseHeadersToParse = new HeadersList(request.RequestParameters.RequestConfiguration.ResponseHeadersToParse, "x-elastic-product");
}
}

var (resolvedUrl, urlTemplate, postData) = PrepareRequest<TRequest, TRequestParameters>(request, forceConfiguration);

TResponse response;

using (var activity = _activitySource.StartActivity($"Elasticsearch: {request.HttpMethod} {urlTemplate}", ActivityKind.Client))
{
activity?.SetTag("db.system", "elasticsearch");
activity?.SetCustomProperty("elastic.transport.client", true);

response = _transport.Request<TResponse>(request.HttpMethod, resolvedUrl, postData, request.RequestParameters);

if (response.ApiCallDetails.RequestBodyInBytes is not null)
activity?.SetTag("db.statement", System.Text.Encoding.UTF8.GetString(response.ApiCallDetails.RequestBodyInBytes));
}

PostRequestProductCheck<TRequest, TResponse>(request, response);

if (_productCheckStatus == ProductCheckStatus.Failed)
throw new UnsupportedProductException(UnsupportedProductException.InvalidProductError);

if (requestModified)
{
if (!hadRequestConfig)
{
request.RequestParameters.RequestConfiguration = null;
}
else if (originalHeaders.HasValue && originalHeaders.Value.Count > 0)
{
request.RequestParameters.RequestConfiguration.ResponseHeadersToParse = originalHeaders.Value;
}
}

return response;
}
where TRequestParameters : RequestParameters, new() =>
DoRequest<TRequest, TResponse, TRequestParameters>(request, null);

internal TResponse DoRequest<TRequest, TResponse, TRequestParameters>(
TRequest request,
Action<IRequestConfiguration>? forceConfiguration = null)
Action<IRequestConfiguration>? forceConfiguration)
where TRequest : Request<TRequestParameters>
where TResponse : ElasticsearchResponse, new()
where TRequestParameters : RequestParameters, new()
Expand Down Expand Up @@ -240,175 +170,17 @@ internal TResponse DoRequest<TRequest, TResponse, TRequestParameters>(
return response;
}

internal Task<TResponse> DoRequestAsync<TRequest, TResponse, TRequestParameters>(
TRequest request,
RequestParameters? parameters,
CancellationToken cancellationToken = default)
where TRequest : Request<TRequestParameters>
where TResponse : ElasticsearchResponse, new()
where TRequestParameters : RequestParameters, new()
{
if (_productCheckStatus == ProductCheckStatus.Failed)
throw new UnsupportedProductException(UnsupportedProductException.InvalidProductError);

var requestModified = false;
var hadRequestConfig = false;
HeadersList? originalHeaders = null;

// If we have not yet checked the product name, add the product header to the list of headers to parse.
if (_productCheckStatus == ProductCheckStatus.NotChecked)
{
requestModified = true;

if (request.RequestParameters.RequestConfiguration is null)
{
request.RequestParameters.RequestConfiguration = new RequestConfiguration();
}
else
{
originalHeaders = request.RequestParameters.RequestConfiguration.ResponseHeadersToParse;
hadRequestConfig = true;
}

if (request.RequestParameters.RequestConfiguration.ResponseHeadersToParse.Count == 0)
{
request.RequestParameters.RequestConfiguration.ResponseHeadersToParse = new HeadersList("x-elastic-product");
}
else
{
request.RequestParameters.RequestConfiguration.ResponseHeadersToParse = new HeadersList(request.RequestParameters.RequestConfiguration.ResponseHeadersToParse, "x-elastic-product");
}
}

var (resolvedUrl, urlTemplate, postData) = PrepareRequest<TRequest, TRequestParameters>(request, null);

if (_productCheckStatus == ProductCheckStatus.Succeeded && !requestModified && !_activitySource.HasListeners())
return _transport.RequestAsync<TResponse>(request.HttpMethod, resolvedUrl, postData, parameters, cancellationToken);

return SendRequest(request, parameters, resolvedUrl, postData, hadRequestConfig, originalHeaders);

async Task<TResponse> SendRequest(TRequest request, RequestParameters? parameters, string url, PostData postData, bool hadRequestConfig, HeadersList? originalHeaders)
{
TResponse response;

using (var activity = _activitySource.StartActivity($"Elasticsearch: {request.HttpMethod} {urlTemplate}", ActivityKind.Client))
{
activity?.AddTag("db.system", "elasticsearch");
activity?.SetCustomProperty("elastic.transport.client", true);

response = await _transport.RequestAsync<TResponse>(request.HttpMethod, url, postData, parameters).ConfigureAwait(false);

if (response.ApiCallDetails.RequestBodyInBytes is not null)
activity?.AddTag("db.statement", System.Text.Encoding.UTF8.GetString(response.ApiCallDetails.RequestBodyInBytes));
}

PostRequestProductCheck<TRequest, TResponse>(request, response);

if (_productCheckStatus == ProductCheckStatus.Failed)
throw new UnsupportedProductException(UnsupportedProductException.InvalidProductError);

if (request.RequestParameters.RequestConfiguration is not null)
{
if (!hadRequestConfig)
{
request.RequestParameters.RequestConfiguration = null;
}
else if (originalHeaders.HasValue && originalHeaders.Value.Count > 0)
{
request.RequestParameters.RequestConfiguration.ResponseHeadersToParse = originalHeaders.Value;
}
}

return response;
}
}

internal Task<TResponse> DoRequestAsync<TRequest, TResponse, TRequestParameters>(
TRequest request,
CancellationToken cancellationToken = default)
where TRequest : Request<TRequestParameters>
where TResponse : ElasticsearchResponse, new()
where TRequestParameters : RequestParameters, new()
{
if (_productCheckStatus == ProductCheckStatus.Failed)
throw new UnsupportedProductException(UnsupportedProductException.InvalidProductError);

var requestModified = false;
var hadRequestConfig = false;
HeadersList? originalHeaders = null;

// If we have not yet checked the product name, add the product header to the list of headers to parse.
if (_productCheckStatus == ProductCheckStatus.NotChecked)
{
requestModified = true;

if (request.RequestParameters.RequestConfiguration is null)
{
request.RequestParameters.RequestConfiguration = new RequestConfiguration();
}
else
{
originalHeaders = request.RequestParameters.RequestConfiguration.ResponseHeadersToParse;
hadRequestConfig = true;
}

if (request.RequestParameters.RequestConfiguration.ResponseHeadersToParse.Count == 0)
{
request.RequestParameters.RequestConfiguration.ResponseHeadersToParse = new HeadersList("x-elastic-product");
}
else
{
request.RequestParameters.RequestConfiguration.ResponseHeadersToParse = new HeadersList(request.RequestParameters.RequestConfiguration.ResponseHeadersToParse, "x-elastic-product");
}
}

var (resolvedUrl, urlTemplate, postData) = PrepareRequest<TRequest, TRequestParameters>(request, null);

if (_productCheckStatus == ProductCheckStatus.Succeeded && !requestModified && !_activitySource.HasListeners())
return _transport.RequestAsync<TResponse>(request.HttpMethod, resolvedUrl, postData, request.RequestParameters, cancellationToken);

return SendRequest(request, request.RequestParameters, resolvedUrl, postData, hadRequestConfig, originalHeaders);

async Task<TResponse> SendRequest(TRequest request, RequestParameters? parameters, string url, PostData postData, bool hadRequestConfig, HeadersList? originalHeaders)
{
TResponse response;

using (var activity = _activitySource.StartActivity($"Elasticsearch: {request.HttpMethod} {urlTemplate}", ActivityKind.Client))
{
activity?.AddTag("db.system", "elasticsearch");
activity?.SetCustomProperty("elastic.transport.client", true);

response = await _transport.RequestAsync<TResponse>(request.HttpMethod, url, postData, parameters).ConfigureAwait(false);

if (response.ApiCallDetails.RequestBodyInBytes is not null)
activity?.AddTag("db.statement", System.Text.Encoding.UTF8.GetString(response.ApiCallDetails.RequestBodyInBytes));
}

PostRequestProductCheck<TRequest, TResponse>(request, response);

if (_productCheckStatus == ProductCheckStatus.Failed)
throw new UnsupportedProductException(UnsupportedProductException.InvalidProductError);

if (request.RequestParameters.RequestConfiguration is not null)
{
if (!hadRequestConfig)
{
request.RequestParameters.RequestConfiguration = null;
}
else if (originalHeaders.HasValue && originalHeaders.Value.Count > 0)
{
request.RequestParameters.RequestConfiguration.ResponseHeadersToParse = originalHeaders.Value;
}
}

return response;
}
}
=> DoRequestAsync<TRequest, TResponse, TRequestParameters>(request, null, cancellationToken);

internal Task<TResponse> DoRequestAsync<TRequest, TResponse, TRequestParameters>(
TRequest request,
RequestParameters? parameters,
Action<IRequestConfiguration>? forceConfiguration = null,
Action<IRequestConfiguration>? forceConfiguration,
CancellationToken cancellationToken = default)
where TRequest : Request<TRequestParameters>
where TResponse : ElasticsearchResponse, new()
Expand Down Expand Up @@ -446,12 +218,11 @@ internal Task<TResponse> DoRequestAsync<TRequest, TResponse, TRequestParameters>
}
}

var (resolvedUrl, urlTemplate, postData) = PrepareRequest<TRequest, TRequestParameters>(request, null);

if (_productCheckStatus == ProductCheckStatus.Succeeded && !requestModified && !_activitySource.HasListeners())
return _transport.RequestAsync<TResponse>(request.HttpMethod, resolvedUrl, postData, parameters, cancellationToken);
var (resolvedUrl, urlTemplate, postData) = PrepareRequest<TRequest, TRequestParameters>(request, forceConfiguration);

return SendRequest(request, parameters, resolvedUrl, postData, hadRequestConfig, originalHeaders);
return _productCheckStatus == ProductCheckStatus.Succeeded && !requestModified && !_activitySource.HasListeners()
? _transport.RequestAsync<TResponse>(request.HttpMethod, resolvedUrl, postData, request.RequestParameters, cancellationToken)
: SendRequest(request, request.RequestParameters, resolvedUrl, postData, hadRequestConfig, originalHeaders);

async Task<TResponse> SendRequest(TRequest request, RequestParameters? parameters, string url, PostData postData, bool hadRequestConfig, HeadersList? originalHeaders)
{
Expand All @@ -462,7 +233,7 @@ async Task<TResponse> SendRequest(TRequest request, RequestParameters? parameter
activity?.AddTag("db.system", "elasticsearch");
activity?.SetCustomProperty("elastic.transport.client", true);

response = await _transport.RequestAsync<TResponse>(request.HttpMethod, url, postData, parameters).ConfigureAwait(false);
response = await _transport.RequestAsync<TResponse>(request.HttpMethod, url, postData, parameters, cancellationToken).ConfigureAwait(false);

if (response.ApiCallDetails.RequestBodyInBytes is not null)
activity?.AddTag("db.statement", System.Text.Encoding.UTF8.GetString(response.ApiCallDetails.RequestBodyInBytes));
Expand Down
38 changes: 5 additions & 33 deletions src/Elastic.Clients.Elasticsearch/Client/NamespacedClientProxy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,23 +25,15 @@ protected NamespacedClientProxy() { }

internal NamespacedClientProxy(ElasticsearchClient client) => _client = client;

internal TResponse DoRequest<TRequest, TResponse, TRequestParameters>(
TRequest request,
TRequestParameters parameters,
Action<IRequestConfiguration>? forceConfiguration = null)
internal TResponse DoRequest<TRequest, TResponse, TRequestParameters>(TRequest request)
where TRequest : Request<TRequestParameters>
where TResponse : ElasticsearchResponse, new()
where TRequestParameters : RequestParameters, new()
{
if (_client is null)
ThrowHelper.ThrowInvalidOperationException(InvalidOperation);

return _client.DoRequest<TRequest, TResponse, TRequestParameters>(request, parameters, forceConfiguration);
}
=> DoRequest<TRequest, TResponse, TRequestParameters>(request, null);

internal TResponse DoRequest<TRequest, TResponse, TRequestParameters>(
TRequest request,
Action<IRequestConfiguration>? forceConfiguration = null)
Action<IRequestConfiguration>? forceConfiguration)
where TRequest : Request<TRequestParameters>
where TResponse : ElasticsearchResponse, new()
where TRequestParameters : RequestParameters, new()
Expand All @@ -58,30 +50,10 @@ internal Task<TResponse> DoRequestAsync<TRequest, TResponse, TRequestParameters>
where TRequest : Request<TRequestParameters>
where TResponse : ElasticsearchResponse, new()
where TRequestParameters : RequestParameters, new()
{
if (_client is null)
ThrowHelper.ThrowInvalidOperationException(InvalidOperation);

return _client.DoRequestAsync<TRequest, TResponse, TRequestParameters>(request, cancellationToken: cancellationToken);
}

internal Task<TResponse> DoRequestAsync<TRequest, TResponse, TRequestParameters>(
TRequest request,
TRequestParameters parameters,
CancellationToken cancellationToken = default)
where TRequest : Request<TRequestParameters>
where TResponse : ElasticsearchResponse, new()
where TRequestParameters : RequestParameters, new()
{
if (_client is null)
ThrowHelper.ThrowInvalidOperationException(InvalidOperation);

return _client.DoRequestAsync<TRequest, TResponse, TRequestParameters>(request, parameters, cancellationToken: cancellationToken);
}
=> DoRequestAsync<TRequest, TResponse, TRequestParameters>(request, null, cancellationToken);

internal Task<TResponse> DoRequestAsync<TRequest, TResponse, TRequestParameters>(
TRequest request,
TRequestParameters parameters,
Action<IRequestConfiguration>? forceConfiguration,
CancellationToken cancellationToken = default)
where TRequest : Request<TRequestParameters>
Expand All @@ -91,6 +63,6 @@ internal Task<TResponse> DoRequestAsync<TRequest, TResponse, TRequestParameters>
if (_client is null)
ThrowHelper.ThrowInvalidOperationException(InvalidOperation);

return _client.DoRequestAsync<TRequest, TResponse, TRequestParameters>(request, parameters, forceConfiguration, cancellationToken);
return _client.DoRequestAsync<TRequest, TResponse, TRequestParameters>(request, forceConfiguration, cancellationToken);
}
}