15
15
#if ELASTICSEARCH_SERVERLESS
16
16
using Elastic . Clients . Elasticsearch . Serverless . Requests ;
17
17
#else
18
+
18
19
using Elastic . Clients . Elasticsearch . Requests ;
20
+
19
21
#endif
20
22
21
23
#if ELASTICSEARCH_SERVERLESS
22
24
namespace Elastic . Clients . Elasticsearch . Serverless ;
23
25
#else
26
+
24
27
namespace Elastic . Clients . Elasticsearch ;
25
28
#endif
26
29
@@ -153,16 +156,14 @@ private ValueTask<TResponse> DoRequestCoreAsync<TRequest, TResponse, TRequestPar
153
156
( int ) ProductCheckStatus . NotChecked
154
157
) ;
155
158
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 ( ) ;
159
+ return productCheckStatus switch
160
+ {
161
+ ( int ) ProductCheckStatus . NotChecked => SendRequestWithProductCheck ( ) ,
162
+ ( int ) ProductCheckStatus . InProgress or
163
+ ( int ) ProductCheckStatus . Succeeded => SendRequest ( ) ,
164
+ ( int ) ProductCheckStatus . Failed => throw new UnsupportedProductException ( UnsupportedProductException . InvalidProductError ) ,
165
+ _ => throw new InvalidOperationException ( "unreachable" )
166
+ } ;
166
167
167
168
ValueTask < TResponse > SendRequest ( )
168
169
{
@@ -176,98 +177,85 @@ ValueTask<TResponse> SendRequest()
176
177
. Request < TResponse > ( new EndpointPath ( request . HttpMethod , resolvedUrl ) , postData , in openTelemetryData , request . RequestConfig ) ) ;
177
178
}
178
179
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
- //}
180
+ async ValueTask < TResponse > SendRequestWithProductCheck ( )
181
+ {
182
+ try
183
+ {
184
+ return await SendRequestWithProductCheckCore ( ) . ConfigureAwait ( false ) ;
185
+ }
186
+ catch
187
+ {
188
+ // Re-try product check on next request.
189
+
190
+ // 32-bit read/write operations are atomic and due to the initial memory barrier, we can be sure that
191
+ // no other thread executes the product check at the same time. Locked access is not required here.
192
+ if ( _productCheckStatus is ( int ) ProductCheckStatus . InProgress )
193
+ _productCheckStatus = ( int ) ProductCheckStatus . NotChecked ;
194
+
195
+ throw ;
196
+ }
197
+ }
198
+
199
+ async ValueTask < TResponse > SendRequestWithProductCheckCore ( )
200
+ {
201
+ // Attach product check header
202
+
203
+ // TODO: The copy constructor should accept null values
204
+ var requestConfig = ( request . RequestConfig is null )
205
+ ? new RequestConfiguration ( )
206
+ {
207
+ ResponseHeadersToParse = new HeadersList ( "x-elastic-product" )
208
+ }
209
+ : new RequestConfiguration ( request . RequestConfig )
210
+ {
211
+ ResponseHeadersToParse = ( request . RequestConfig . ResponseHeadersToParse is { Count : > 0 } )
212
+ ? new HeadersList ( request . RequestConfig . ResponseHeadersToParse , "x-elastic-product" )
213
+ : new HeadersList ( "x-elastic-product" )
214
+ } ;
215
+
216
+ // Send request
217
+
218
+ var ( resolvedUrl , _, resolvedRouteValues , postData ) = PrepareRequest < TRequest , TRequestParameters > ( request ) ;
219
+ var openTelemetryData = PrepareOpenTelemetryData < TRequest , TRequestParameters > ( request , resolvedRouteValues ) ;
220
+
221
+ TResponse response ;
222
+
223
+ if ( isAsync )
224
+ {
225
+ response = await _transport
226
+ . RequestAsync < TResponse > ( new EndpointPath ( request . HttpMethod , resolvedUrl ) , postData , in openTelemetryData , requestConfig , cancellationToken )
227
+ . ConfigureAwait ( false ) ;
228
+ }
229
+ else
230
+ {
231
+ response = _transport
232
+ . Request < TResponse > ( new EndpointPath ( request . HttpMethod , resolvedUrl ) , postData , in openTelemetryData , requestConfig ) ;
233
+ }
234
+
235
+ // Evaluate product check result
236
+
237
+ var hasSuccessStatusCode = response . ApiCallDetails . HttpStatusCode is >= 200 and <= 299 ;
238
+ if ( ! hasSuccessStatusCode )
239
+ {
240
+ // The product check is unreliable for non success status codes.
241
+ // We have to re-try on the next request.
242
+ _productCheckStatus = ( int ) ProductCheckStatus . NotChecked ;
243
+
244
+ return response ;
245
+ }
246
+
247
+ var productCheckSucceeded = response . ApiCallDetails . TryGetHeader ( "x-elastic-product" , out var values ) &&
248
+ values . FirstOrDefault ( x => x . Equals ( "Elasticsearch" , StringComparison . Ordinal ) ) is not null ;
249
+
250
+ _productCheckStatus = productCheckSucceeded
251
+ ? ( int ) ProductCheckStatus . Succeeded
252
+ : ( int ) ProductCheckStatus . Failed ;
253
+
254
+ if ( _productCheckStatus == ( int ) ProductCheckStatus . Failed )
255
+ throw new UnsupportedProductException ( UnsupportedProductException . InvalidProductError ) ;
256
+
257
+ return response ;
258
+ }
271
259
}
272
260
273
261
private static OpenTelemetryData PrepareOpenTelemetryData < TRequest , TRequestParameters > ( TRequest request , Dictionary < string , string > resolvedRouteValues )
0 commit comments