ES NuGet升级用InMemoryRequestInvoker遇UnsupportedProductException
解决Elasticsearch 8.15.10版本中InMemoryRequestInvoker抛出UnsupportedProductException的问题
问题原因
升级到8.15.10版本后,Elasticsearch客户端新增了产品验证机制,默认的InMemoryRequestInvoker没有返回服务器版本信息,导致客户端判定连接的不是合法的ES服务,抛出UnsupportedProductException。
解决方案
方案一:禁用产品检查(快速解决测试场景)
如果你的需求只是捕获请求体,不需要模拟完整的ES服务响应,可以直接在客户端配置中禁用产品验证:
var clientSettings = new ElasticsearchClientSettings(new InMemoryRequestInvoker()) .DisableProductCheck(); // 关闭产品验证逻辑 var client = new ElasticsearchClient(clientSettings);
使用此配置后,客户端不再验证服务器产品信息,即可正常调用Indices.CreateAsync并捕获请求体。
方案二:自定义RequestInvoker模拟ES版本响应
如果需要更真实的模拟ES服务行为,可以自定义InMemoryRequestInvoker,处理版本检查请求并返回合法的版本信息:
using Elastic.Clients.Elasticsearch; using Elastic.Clients.Elasticsearch.Transport; using System.Net; using System.Text.Json; public class CustomInMemoryRequestInvoker : InMemoryRequestInvoker { public override async Task<TransportResponse> InvokeAsync<TResponse>(RequestData requestData, CancellationToken cancellationToken = default) { // 处理ES版本检查请求(GET /) if (requestData.HttpMethod == HttpMethod.Get && requestData.Uri.AbsolutePath == "/") { var versionJson = JsonSerializer.Serialize(new { version = new { number = "8.15.10", build_flavor = "default", build_type = "docker", build_hash = "f27399d", build_date = "2024-05-23T14:04:37.555259655Z", build_snapshot = false, lucene_version = "9.10.0", minimum_wire_compatibility_version = "7.17.0", minimum_index_compatibility_version = "7.0.0" }, tagline = "You Know, for Search" }); return new TransportResponse { StatusCode = HttpStatusCode.OK, BodyBytes = Encoding.UTF8.GetBytes(versionJson), Headers = new Dictionary<string, IEnumerable<string>>() }; } // 处理创建索引请求,返回成功响应 if (requestData.HttpMethod == HttpMethod.Put && requestData.Uri.AbsolutePath.Equals("/dummy", StringComparison.OrdinalIgnoreCase)) { var createIndexResponse = JsonSerializer.Serialize(new { acknowledged = true, shards_acknowledged = true, index = "dummy" }); return new TransportResponse { StatusCode = HttpStatusCode.OK, BodyBytes = Encoding.UTF8.GetBytes(createIndexResponse), Headers = new Dictionary<string, IEnumerable<string>>() }; } return await base.InvokeAsync<TResponse>(requestData, cancellationToken); } }
使用自定义Invoker初始化客户端:
var clientSettings = new ElasticsearchClientSettings(new CustomInMemoryRequestInvoker()); var client = new ElasticsearchClient(clientSettings);
此方案会模拟ES服务器的版本检查和索引创建响应,更贴近真实环境,适合需要完整模拟ES行为的测试场景。
内容的提问来源于stack exchange,提问作者ProgrammingLlama
相关产品推荐
相关产品推荐

