@@ -153,16 +153,14 @@ private ValueTask<TResponse> DoRequestCoreAsync<TRequest, TResponse, TRequestPar
153
153
( int ) ProductCheckStatus . NotChecked
154
154
) ;
155
155
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
+ } ;
166
164
167
165
ValueTask < TResponse > SendRequest ( )
168
166
{
@@ -176,98 +174,85 @@ ValueTask<TResponse> SendRequest()
176
174
. Request < TResponse > ( new EndpointPath ( request . HttpMethod , resolvedUrl ) , postData , in openTelemetryData , request . RequestConfig ) ) ;
177
175
}
178
176
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
+ }
271
256
}
272
257
273
258
private static OpenTelemetryData PrepareOpenTelemetryData < TRequest , TRequestParameters > ( TRequest request , Dictionary < string , string > resolvedRouteValues )
0 commit comments