由于在 Elastic Stack 8.x 中天然地添加了安全性,我们在使用 Java 客户端进行连接的时候,我们可以通过不同的途径来完成。在我之前的文章中,我创建了一系列的文章来展示:
在上面,我们可以通过 Java HTTP 的集成来访问 Elasticsearch。这个是不依赖于 Elasticsearch 的版本来进行访问的。我们也可以通过 Elastic 公司所提供的 Elasticsearch Java client 8.x 来进行访问。在通常的情况下,Elasticsearch Java client 会更为高效。它提供了良好的 JSON 支持以及对连接的管理。这样也是被推荐的方法。
在今天的文章中,我将使用另外一种方式来进行展示。我将使用 Low Level client API 来进行连接及访问。
如果你还没有安装好自己的 Elasticsearch 及 Kibana。请参阅我之前的文章:
在默认的情况下,Elastic Stack 8.x 的安装已带有安全。如果你是自托管型的集群,那么你的证书应该是自签名的证书。
有两个官方的 Elasticsearch 客户端:低级客户端和 Elasticsearch 8.x (https://github.com/elastic/elasticsearch-java) 提供的新类型客户端。 低级用于与 Elasticsearch 通信,主要特点如下:
要创建 RestClient,我们将执行以下步骤:
1)我们需要添加用于执行 HTTP 调用的 Elasticsearch HTTP 客户端库。 该库位于 search.maven.org 的主 Maven 存储库中。 要在 Maven pom.xml 项目中启用编译,只需添加以下代码:
pom.xml
4.0.0
org.example
ELasticsearchJava-lowlevel
1.0-SNAPSHOT
8
8
org.elasticsearch.client
elasticsearch-rest-client
8.0.0
2)如果我们想实例化一个客户端并使用 get 方法获取一个文档,代码将如下所示:
ElasticsearchJavaLowLevel.java
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpStatus;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.TrustAllStrategy;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.nio.client.
HttpAsyncClientBuilder;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.util.EntityUtils;
import org.elasticsearch.client.*;
import java.io.IOException;
import java.security.*;
import javax.net.ssl.SSLContext;
public class ElasticsearchJavaLowLevel {
public static void main(String[] args) throws
KeyManagementException, NoSuchAlgorithmException,
KeyStoreException {
RestClientBuilder clientBuilder = RestClient.
builder(new HttpHost("localhost", 9200, "https"))
.setCompressionEnabled(true);
final CredentialsProvider credentialsProvider =
new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY,
new UsernamePasswordCredentials(System.
getenv("ES_USER"), System.getenv("ES_PASSWORD")));
final SSLContext sslContext = new
SSLContextBuilder().loadTrustMaterial(null,
TrustAllStrategy.INSTANCE).build();
clientBuilder.setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
public HttpAsyncClientBuilder
customizeHttpClient(HttpAsyncClientBuilder
httpClientBuilder) {
return httpClientBuilder
.setSSLContext(sslContext)
.setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
.setDefaultCredentialsProvider(credentialsProvider);
}
});
RestClient client = clientBuilder.build();
try {
Request request = new Request("GET", "/mybooks/_doc/1");
Response response = client.
performRequest(request);
if (response.getStatusLine().getStatusCode()
!= HttpStatus.SC_OK) {
System.err.println("Method failed: " +
response.getStatusLine());
} else {
HttpEntity entity = response.getEntity();
String responseBody = EntityUtils.
toString(entity);
System.out.println(responseBody);
}
} catch (IOException e) {
System.err.println("Fatal transport error: "
+ e.getMessage());
e.printStackTrace();
} finally {
// Release the connection.
try {
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
我们需要在环境变量中设置你访问 Elasticsearch 集群的用户名及密码。
上面的代码实现的功能相当于我们在 Kibana 下打入如下的命令:
GET mybooks/_doc/1
为了能够让上面的代码顺利执行,我们首先在 Kibana 中创建如下的一个索引:
PUT mybooks/_doc/1
{
"uuid": "1",
"title": "Great math"
}
在内部,Elasticsearch RestClient 客户端使用 Apache HttpComponents 库并用更方便的方法包装它。如果你想了解如何使用 Apache HttpComponents 来建立和 Elasticsearch 的连接,请参考我之前的文章 “ Elasticsearch:使用标准 Java HTTP 的集成 - Elastic Stack 8.x”。 我们执行了前面的步骤来创建和使用 RestClient。 让我们更详细地看一下它们:
1)第一步是初始化 RestClient 对象。 这是通过以下代码片段完成的:
RestClientBuilder clientBuilder = RestClient.builder(new HttpHost("localhost", 9200, "https"))
// some stuff to setup SSL and auth as seen in previous
example
…
RestClient client = clientBuilder.build();
builder 方法接受一个多值 HttpHost 主机(通过这种方式,你可以传递一个 HTTP 地址列表)并在后台返回 RestClientBuilder。
2)RestClientBuilder 对象允许通过多种方法自定义客户端通信,例如:
3)创建 RestClient 后,我们可以通过几种 performRequest 方法对它执行一些请求,用于同步调用和 performRequestAsync 方法用于异步调用。这些方法允许你设置参数,例如:
在前面的示例中,我们使用以下代码执行了 GET REST 调用:
Response response = client.performRequest(request);
响应对象是 org.elasticsearch.client.Response,它包装了 Apache HttpComponents 响应。
运行上面的代码,我们可以看到的结果为:
{"_index":"mybooks","_id":"1","_version":1,"_seq_no":0,"_primary_term":1,"found":true,"_source":{
"uuid": "1",
"title": "Great math"
}
}
我们可以看到它的结果和我们之前的是没有什么不同。