Elasticsearch.Nest 教程系列 2-3 连接:Modifying the default connection | 修改默认连接

  • 本系列博文是“伪”官方文档翻译(更加本土化),并非完全将官方文档进行翻译,而是在查阅、测试原始文档并转换为自己真知灼见后的“准”翻译。有不同见解 / 说明不周的地方,还请海涵、不吝拍砖 :)

  • 官方文档见此:https://www.elastic.co/guide/en/elasticsearch/client/net-api/current/introduction.html

  • 本系列对应的版本环境:ElasticSearch@7.3.1,NEST@7.3.1,IDE 和开发平台默认为 VS2019,.NET CORE 2.1


NEST 客户端通过 IConnection 发送请求并创建响应,默认实现使用 System.Net.Http.HttpClient。

有的时候,你希望客制化连接,此时可以通过 InMemoryConnection,HttpConnection 来自定义。

使用 InMemoryConnection

InMemoryConnection 是一个内置的 IConnection,可以轻松地对其编写单元测试。通过配置,可以将调用时的默认响应字节、HTTP 状态代码和异常处理进行客制化。

事实上,InMemoryConnection 并不会发送任何请求或接收来自E lasticsearch 的任何响应:如果将 .DisableDirectStreaming 在全局或请求的时候设置为 true,则此请求仍会序列化,并且可以在响应上获取请求字节。

1
2
3
4
5
6
7
8
var connection = new InMemoryConnection();
var connectionPool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
/*
1.通过 IConnectionPool 和 IConnection 重载创建一个 ConnectionSettings
2.connection 使用的是 InMemoryConnection 的无参构造函数,表示为所有相应内容返回 200 状态码,并不真实执行任何 IO 操作。
*/
var settings = new ConnectionSettings(connectionPool, connection);
var client = new ElasticClient(settings);

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
var response = new
{
took = 1,
timed_out = false,
_shards = new
{
total = 2,
successful = 2,
failed = 0
},
hits = new
{
total = new { value = 25 },
max_score = 1.0,
hits = Enumerable.Range(1, 25).Select(i => (object)new
{
_index = "project",
_type = "project",
_id = $"Project {i}",
_score = 1.0,
_source = new { name = $"Project {i}" }
}).ToArray()
}
};

var responseBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(response));
// InMemoryConnection 配置为始终返回responseBytes 以及 HTTP状态代码为 200
var connection = new InMemoryConnection(responseBytes, 200);
var connectionPool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
var settings = new ConnectionSettings(connectionPool, connection).DefaultIndex("project");
var client = new ElasticClient(settings);

var searchResponse = client.Search<Project>(s => s.MatchAll());
  • 此时可以断言: searchResponse 是有效的,并且包含从固定的 InMemoryConnection 响应中反序列化的文档。

1
2
searchResponse.ShouldBeValid();
searchResponse.Documents.Count.Should().Be(25);

修改 HttpConnection

可能需要更改默认的 HttpConnection 的工作方式,例如,向请求中添加 X509 证书 以及 更改允许与端点连接的最大连接数等等。

通过继承自 HttpConnection,可以更改连接的行为。示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class MyCustomHttpConnection : HttpConnection
{
protected override HttpRequestMessage CreateRequestMessage(RequestData requestData)
{
var message = base.CreateRequestMessage(requestData);
var header = string.Empty;
message.Headers.Authorization = new AuthenticationHeaderValue("Negotiate", header);
return message;
}
}

public class KerberosConnection : HttpConnection
{
protected override HttpRequestMessage CreateRequestMessage(RequestData requestData)
{
var message = base.CreateRequestMessage(requestData);
var header = string.Empty;
message.Headers.Authorization = new AuthenticationHeaderValue("Negotiate", header);
return message;
}
}

更多凭证相关内容见此博文:NEST 教程系列 2-4 连接:Working with certificates | 使用凭证连接