Skip to content

Commit f432517

Browse files
committed
Re-enable product check
1 parent 1274938 commit f432517

File tree

1 file changed

+87
-102
lines changed

1 file changed

+87
-102
lines changed

src/Elastic.Clients.Elasticsearch/_Shared/Client/ElasticsearchClient.cs

Lines changed: 87 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -153,16 +153,14 @@ private ValueTask<TResponse> DoRequestCoreAsync<TRequest, TResponse, TRequestPar
153153
(int)ProductCheckStatus.NotChecked
154154
);
155155

156-
// TODO: Re-enable product check
157-
//return productCheckStatus switch
158-
//{
159-
// (int)ProductCheckStatus.NotChecked => SendRequestWithProductCheck(),
160-
// (int)ProductCheckStatus.InProgress or
161-
// (int)ProductCheckStatus.Succeeded => SendRequest(),
162-
// (int)ProductCheckStatus.Failed => throw new UnsupportedProductException(UnsupportedProductException.InvalidProductError),
163-
// _ => throw new InvalidOperationException("unreachable")
164-
//};
165-
return SendRequest();
156+
return productCheckStatus switch
157+
{
158+
(int)ProductCheckStatus.NotChecked => SendRequestWithProductCheck(),
159+
(int)ProductCheckStatus.InProgress or
160+
(int)ProductCheckStatus.Succeeded => SendRequest(),
161+
(int)ProductCheckStatus.Failed => throw new UnsupportedProductException(UnsupportedProductException.InvalidProductError),
162+
_ => throw new InvalidOperationException("unreachable")
163+
};
166164

167165
ValueTask<TResponse> SendRequest()
168166
{
@@ -176,98 +174,85 @@ ValueTask<TResponse> SendRequest()
176174
.Request<TResponse>(new EndpointPath(request.HttpMethod, resolvedUrl), postData, in openTelemetryData, request.RequestConfig));
177175
}
178176

179-
//async ValueTask<TResponse> SendRequestWithProductCheck()
180-
//{
181-
// try
182-
// {
183-
// return await SendRequestWithProductCheckCore().ConfigureAwait(false);
184-
// }
185-
// catch
186-
// {
187-
// // Re-try product check on next request.
188-
189-
// // 32-bit read/write operations are atomic and due to the initial memory barrier, we can be sure that
190-
// // no other thread executes the product check at the same time. Locked access is not required here.
191-
// if (_productCheckStatus is (int)ProductCheckStatus.InProgress)
192-
// _productCheckStatus = (int)ProductCheckStatus.NotChecked;
193-
194-
// throw;
195-
// }
196-
//}
197-
198-
//async ValueTask<TResponse> SendRequestWithProductCheckCore()
199-
//{
200-
// // Attach product check header
201-
202-
// var hadRequestConfig = false;
203-
// HeadersList? originalHeaders = null;
204-
205-
// if (request.RequestConfiguration is null)
206-
// request.RequestParameters.RequestConfiguration = new RequestConfiguration();
207-
// else
208-
// {
209-
// originalHeaders = request.RequestParameters.RequestConfiguration.ResponseHeadersToParse;
210-
// hadRequestConfig = true;
211-
// }
212-
213-
// request.RequestParameters.RequestConfiguration.ResponseHeadersToParse = request.RequestParameters.RequestConfiguration.ResponseHeadersToParse.Count == 0
214-
// ? new HeadersList("x-elastic-product")
215-
// : new HeadersList(request.RequestParameters.RequestConfiguration.ResponseHeadersToParse, "x-elastic-product");
216-
217-
// // Send request
218-
219-
// var (resolvedUrl, _, resolvedRouteValues, postData) = PrepareRequest<TRequest, TRequestParameters>(request, forceConfiguration);
220-
// var openTelemetryData = PrepareOpenTelemetryData<TRequest, TRequestParameters>(request, resolvedRouteValues);
221-
222-
// TResponse response;
223-
224-
// if (isAsync)
225-
// {
226-
// response = await _transport
227-
// .RequestAsync<TResponse>(request.HttpMethod, resolvedUrl, postData, request.RequestParameters, in openTelemetryData, cancellationToken)
228-
// .ConfigureAwait(false);
229-
// }
230-
// else
231-
// {
232-
// response = _transport
233-
// .Request<TResponse>(request.HttpMethod, resolvedUrl, postData, request.RequestParameters, in openTelemetryData);
234-
// }
235-
236-
// // Evaluate product check result
237-
238-
// var hasSuccessStatusCode = response.ApiCallDetails.HttpStatusCode is >= 200 and <= 299;
239-
// if (hasSuccessStatusCode)
240-
// {
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-
// }
251-
252-
// if (request.RequestParameters.RequestConfiguration is null)
253-
// return response;
254-
255-
// // Reset request configuration
256-
257-
// if (!hadRequestConfig)
258-
// request.RequestParameters.RequestConfiguration = null;
259-
// else if (originalHeaders is { Count: > 0 })
260-
// request.RequestParameters.RequestConfiguration.ResponseHeadersToParse = originalHeaders.Value;
261-
262-
// if (!hasSuccessStatusCode)
263-
// {
264-
// // The product check is unreliable for non success status codes.
265-
// // We have to re-try on the next request.
266-
// _productCheckStatus = (int)ProductCheckStatus.NotChecked;
267-
// }
268-
269-
// return response;
270-
//}
177+
async ValueTask<TResponse> SendRequestWithProductCheck()
178+
{
179+
try
180+
{
181+
return await SendRequestWithProductCheckCore().ConfigureAwait(false);
182+
}
183+
catch
184+
{
185+
// Re-try product check on next request.
186+
187+
// 32-bit read/write operations are atomic and due to the initial memory barrier, we can be sure that
188+
// no other thread executes the product check at the same time. Locked access is not required here.
189+
if (_productCheckStatus is (int)ProductCheckStatus.InProgress)
190+
_productCheckStatus = (int)ProductCheckStatus.NotChecked;
191+
192+
throw;
193+
}
194+
}
195+
196+
async ValueTask<TResponse> SendRequestWithProductCheckCore()
197+
{
198+
// Attach product check header
199+
200+
// TODO: The copy constructor should accept null values
201+
var requestConfig = (request.RequestConfig is null)
202+
? new RequestConfiguration()
203+
{
204+
ResponseHeadersToParse = new HeadersList("x-elastic-product")
205+
}
206+
: new RequestConfiguration(request.RequestConfig)
207+
{
208+
ResponseHeadersToParse = (request.RequestConfig.ResponseHeadersToParse is { Count: > 0 })
209+
? new HeadersList(request.RequestConfig.ResponseHeadersToParse, "x-elastic-product")
210+
: new HeadersList("x-elastic-product")
211+
};
212+
213+
// Send request
214+
215+
var (resolvedUrl, _, resolvedRouteValues, postData) = PrepareRequest<TRequest, TRequestParameters>(request);
216+
var openTelemetryData = PrepareOpenTelemetryData<TRequest, TRequestParameters>(request, resolvedRouteValues);
217+
218+
TResponse response;
219+
220+
if (isAsync)
221+
{
222+
response = await _transport
223+
.RequestAsync<TResponse>(new EndpointPath(request.HttpMethod, resolvedUrl), postData, in openTelemetryData, requestConfig, cancellationToken)
224+
.ConfigureAwait(false);
225+
}
226+
else
227+
{
228+
response = _transport
229+
.Request<TResponse>(new EndpointPath(request.HttpMethod, resolvedUrl), postData, in openTelemetryData, requestConfig);
230+
}
231+
232+
// Evaluate product check result
233+
234+
var hasSuccessStatusCode = response.ApiCallDetails.HttpStatusCode is >= 200 and <= 299;
235+
if (!hasSuccessStatusCode)
236+
{
237+
// The product check is unreliable for non success status codes.
238+
// We have to re-try on the next request.
239+
_productCheckStatus = (int)ProductCheckStatus.NotChecked;
240+
241+
return response;
242+
}
243+
244+
var productCheckSucceeded = response.ApiCallDetails.TryGetHeader("x-elastic-product", out var values) &&
245+
values.FirstOrDefault(x => x.Equals("Elasticsearch", StringComparison.Ordinal)) is not null;
246+
247+
_productCheckStatus = productCheckSucceeded
248+
? (int)ProductCheckStatus.Succeeded
249+
: (int)ProductCheckStatus.Failed;
250+
251+
if (_productCheckStatus == (int)ProductCheckStatus.Failed)
252+
throw new UnsupportedProductException(UnsupportedProductException.InvalidProductError);
253+
254+
return response;
255+
}
271256
}
272257

273258
private static OpenTelemetryData PrepareOpenTelemetryData<TRequest, TRequestParameters>(TRequest request, Dictionary<string, string> resolvedRouteValues)

0 commit comments

Comments
 (0)