Spring管理Elasticsearch客户端

遇到2个问题:

1.我的Elasticsearch安装了X-pack插件,现有的Spring-data-elasticsearch不支持x-pack。

2.我的Elasticsearch开启了SSL验证,在连接时需要设置。

 

ElasticsearchTemplate是Spring-data-elasticsearch包封装好的Elasticsearch客户端对象,里面包含了Elasticsearch的各种基本操作,在集成到我的项目过程中发现Spring-data-elasticsearch并不支持安装了X-pack插件的Elasticsearch,主要是x-pack需要用户名密码认证。查看源码发现org.springframework.data.elasticsearch.core.ElasticsearchTemplate的构造函数需要一个org.elasticsearch.client.Client,于是就想我自己实现一个Client,用它来构造ElasticsearchTemplate不就行了嘛。

<!-- 自己实例化一个client -->
<bean id="elasticSearchClient" class="com.xxx.xxx.elastic.TransportClientFactoryBean">
		<property name="clusterName" value="${esserver.cluster.name}"></property>
		<property name="nodes" value="${esserver.cluster.nodes}"></property>
		<property name="port" value="${esserver.cluster.port}"></property>
		<property name="user" value="${esserver.cluster.user}"></property>
		<property name="pass" value="${esserver.cluster.pass}"></property>
		<property name="clientSslEnabled" value="${esserver.cluster.clientSslEnabled}"></property>
</bean>
<!-- 实例化的client作为ElasticsearchTemplate构造方法的入参 -->
<bean name="elasticsearchTemplate"
       class="org.springframework.data.elasticsearch.core.ElasticsearchTemplate">
   <constructor-arg ref="elasticSearchClient" />
</bean>

实例化client:

package com.xxx.xxx.elastic;

import java.net.InetAddress;
import java.util.List;

import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.cluster.node.DiscoveryNode;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.xpack.client.PreBuiltXPackTransportClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;

public class TransportClientFactoryBean implements FactoryBean<TransportClient>, InitializingBean, DisposableBean{

	private static final Logger logger = LoggerFactory.getLogger(TransportClientFactoryBean.class);
	private String clusterName = "elasticsearch";//集群名称
	private Boolean clientTransportSniff = true;//自动选举
	private Boolean clientSslEnabled = false;//Elasticsearch是否开启了ssl
	private TransportClient client;//客户端
	private String user = "elastic";//用户名
	private String pass = "changeme";//密码
	private String port = "9300";//端口
	private String nodes = "127.0.0.1";//ip
	
	@Override
	public void destroy() throws Exception {
		try {
			logger.info("Closing elasticSearch  client");
			if (client != null) {
				client.close();
			}
		} catch (final Exception e) {
			logger.error("Error closing ElasticSearch client: ", e);
		}
	}

	@Override
	public void afterPropertiesSet() throws Exception {
		buildClient();
	}

	@Override
	public TransportClient getObject() throws Exception {
		return client;
	}

	@Override
	public Class<?> getObjectType() {
		return TransportClient.class;
	}

	@Override
	public boolean isSingleton() {
		return false;
	}
	
	protected void buildClient() throws Exception {
		//创建Elasticsearch客户端
		String path = Thread.currentThread().getContextClassLoader().getResource("/elastic-certificates.p12").getPath();
		try {
			System.setProperty("es.set.netty.runtime.available.processors", "false");
			String os = System.getProperty("os.name");  
			if(os.toLowerCase().startsWith("win")){  
				path = path.substring(1);
			}
			Settings settings = Settings.builder().put("cluster.name", clusterName)
					.put("xpack.security.transport.ssl.enabled", clientSslEnabled)
					.put("xpack.security.user", user+":"+pass)
					.put("xpack.security.transport.ssl.verification_mode", "certificate")
			        .put("xpack.security.transport.ssl.keystore.path", path)
			        .put("xpack.security.transport.ssl.truststore.path", path)
					.put("client.transport.sniff", clientTransportSniff).build();
			client = new PreBuiltXPackTransportClient(settings);
			for (String node : nodes.split(",")) {
				client.addTransportAddress(new TransportAddress(InetAddress.getByName(node),
						Integer.valueOf(Integer.valueOf(port))));
			}
			//判断是否连接成功
			List<DiscoveryNode> list = client.connectedNodes();
			if(list!=null&&list.size()>0){
				String nodeStr = "";
				for(DiscoveryNode node:list){
					nodeStr += ";"+node.getHostAddress();
				}
				logger.info("init elasticSearch client successed,connected nodes:{}", nodeStr);
			}else{
				logger.info("init elasticSearch client failed:connected nodes ware empty");
			}
			
		} catch (Exception e) {
			logger.error("init elasticSearch client failed:", e);
		}
	}

	public String getClusterName() {
		return clusterName;
	}

	public void setClusterName(String clusterName) {
		this.clusterName = clusterName;
	}

	public Boolean getClientTransportSniff() {
		return clientTransportSniff;
	}

	public void setClientTransportSniff(Boolean clientTransportSniff) {
		this.clientTransportSniff = clientTransportSniff;
	}

	public Boolean getClientSslEnabled() {
		return clientSslEnabled;
	}

	public void setClientSslEnabled(Boolean clientSslEnabled) {
		this.clientSslEnabled = clientSslEnabled;
	}

	public TransportClient getClient() {
		return client;
	}

	public void setClient(TransportClient client) {
		this.client = client;
	}

	public String getUser() {
		return user;
	}

	public void setUser(String user) {
		this.user = user;
	}

	public String getPass() {
		return pass;
	}

	public void setPass(String pass) {
		this.pass = pass;
	}

	public String getPort() {
		return port;
	}

	public void setPort(String port) {
		this.port = port;
	}

	public String getNodes() {
		return nodes;
	}

	public void setNodes(String nodes) {
		this.nodes = nodes;
	}

}

 这步特别要注意的是设置SSL,我自己是用certificate方法创建的SSL链接,并设置了证书路径。其他方式是类似的,也是设置一个证书路径和认证方式。

接下来设置自己的Elasticsearch信息到properties文件就可以了:

esserver.cluster.name = tracklog
esserver.cluster.nodes = 172.0.0.1
esserver.cluster.port = 9300
esserver.cluster.user = elastic
esserver.cluster.pass = changeme
esserver.cluster.clientSslEnabled = true

启动项目,日志显示连接成功:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值