How to connect Spring Boot to Elasticsearch 2.x.x

My Problem:

I have an application built using the Jhipter generator, which is based on Spring Boot. The latest version of Jhipster allows you to include Elasticsearch as an option, so I have an application which runs an embedded instance of Elasticsearch in development mode and connects to a server instance in production mode.

When the application is running in development mode it connects perfectly fine to the embedded instance, but if I try to connect to an external instance I get the following error:

ERROR 5256 — [ main] .d.e.r.s.AbstractElasticsearchRepository : failed to load Elasticsearch nodes :
org.elasticsearch.client.transport.NoNodeAvailableException: None of the configured nodes are available: []

I have an application which was using Spring boot version 1.3.6.RELEASE and in my server I was running an instance of Elasticsearch with version 2.3.1.

This error was due to two problems in my application:

– The client and the server version were different. I was using Spring Boot 1.3.6.RELEASE which includes Elasticsearch api version 1.5.2. while in my server I have an Elasticsearch version 2.3.1. so my client and server versions were not compatible. According to the documentation client and server major versions should be the same.
– Spring Boot makes use of ImmutableSettings class for auto configuration. This class has been removed from Elasticsearch 2.x.x and instead Settings.builder should be used.

Solution:

I solved the problem by:

1) Upgrading Spring Boot to the latest version, at the moment, 1.4.0.RC1. This Spring boot version includes Elasticsearch version 2.3.3 which is compatible with my server version (2.3.1).

[xml]
4.0.0

spring-boot-starter-parent
org.springframework.boot
1.4.0.RC1

xxxxxx

[/xml]

2) Adding cluster name and cluster node to my Spring properties. Please be aware that the cluster node is using the port 9300 instead of the 9200. This is because the java transport client talks to the cluster over port 9300, using the native Elasticsearch transport protocol.

[css]
spring:
data:
elasticsearch:
cluster-name: myClusterName
cluster-nodes: localhost:9300

[/css]

3) Instead of using Spring Boot auto configuration to configure ElasticsearchTemplate, I am getting the Elasticsearch properties from my spring profile and using Settings.builder to build the client, as in the following code:

[java]
@Configuration
public class ElasticSearchConfiguration {

@Value(“${spring.data.elasticsearch.cluster-name}”)
private String clusterName;

@Value(“${spring.data.elasticsearch.cluster-nodes}”)
private String clusterNodes;

@Bean
public ElasticsearchTemplate elasticsearchTemplate() throws UnknownHostException {

String server = clusterNodes.split(“:”)[0];
Integer port = Integer.parseInt(clusterNodes.split(“:”)[1]);

Settings settings = Settings.settingsBuilder()
.put(“cluster.name”, clusterName).build();

client = TransportClient.builder().settings(settings).build()
.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName(server), port));

return new ElasticsearchTemplate(client);

}

[/java]

You may also like...

3 Responses

  1. JInna Balu says:

    client is showing as undefined? Is this working. Have you overcome with this issue. Please let me know if this is working

  2. Maghesh says:

    I am also having the same issue. Please let me know if any body has resolved the problem.

  3. Maghesh says:

    I think, i have found a solution for this and it works for me fine.
    What i i did was that i copied the elastic search related settings from dev.yaml to prod.yaml.
    This way, it starts the embedded instance in AWS and all works fine.
    The portion that i copied from dev.yaml is shown below
    data:
    elasticsearch:
    cluster-name:
    cluster-nodes:
    properties:
    path:
    logs: target/elasticsearch/log
    data: target/elasticsearch/data

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.