Martin Čuka
Martin Čuka

Reputation: 18548

Spring Boot 2.0 can't connect to ElasticSearch 5.5.0 - NoNodeAvailableException

I was following a lot of examples / documentations but can't figure out how to connect from Spring Boot 2.0 to ElasticSearch 5.5.0 using spring data elastic and TransportClient. I always gets NoNodeAvailableException when trying to connect to elasticsearch.

My code is following:

pom.xml

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.1.BUILD-SNAPSHOT</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

config class

@Configuration
@EnableElasticsearchRepositories(basePackages = "com.example.demo")
public class EsConfig {

    @Value("${elasticsearch.host}")
    private String EsHost;

    @Value("${elasticsearch.port}")
    private int EsPort;

    @Value("${elasticsearch.clustername}")
    private String EsClusterName;

    @Bean
    public Client client() throws Exception {

        Settings esSettings = Settings.builder()
                .put("cluster.name", EsClusterName)
                .build();

        TransportClient client = new PreBuiltTransportClient(esSettings)
                .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName(EsHost), Integer.valueOf(EsPort)));
        return client;
    }

    @Bean
    public ElasticsearchOperations elasticsearchTemplate() throws Exception {
        return new ElasticsearchTemplate(client());
    }
}

application.properties

elasticsearch.clustername = elasticsearch
elasticsearch.host = localhost
elasticsearch.port = 9300

As i run the application I get an error:

failed to load elasticsearch nodes : org.elasticsearch.client.transport.NoNodeAvailableException: None of the configured nodes are available: [{#transport#-1}{ru3fMzoqTQygBpT5C6KXXw}{localhost}{127.0.0.1:9300}]

My elasticsearch is running in docker container

run -p 9200:9200 -p 9300:9300 --name elasticsearch -d --network mynetwork elasticsearch:5.5.0

Upvotes: 1

Views: 2837

Answers (2)

Martin Čuka
Martin Čuka

Reputation: 18548

The problem was in docker container itself. To connect to docker container from java you need to set http.host to 0 transport.host to 0 disable xpack security and disable sniffing If anyone else struggle here's solution:

docker network create mynetwork --driver=bridge
docker run -p 9200:9200 -p 9300:9300 -e "http.host=0.0.0.0" -e "transport.host=0.0.0.0" -e "xpack.security.enabled=false" -d --name thesiselasticsearch -d --network mynetwork docker.elastic.co/elasticsearch/elasticsearch:5.5.0
docker run -d --network mynetwork -e ELASTICSEARCH_URL=http://thesiselasticsearch:9200 --name thesiskibana -p 5601:5601 kibana:5.5.0

and configuration class:

@Configuration
@EnableElasticsearchRepositories(basePackages = "com.example.demo")
public class EsConfig {

    @Value("${elasticsearch.host}")
    private String EsHost;

    @Value("${elasticsearch.port}")
    private int EsPort;

    @Value("${elasticsearch.clustername}")
    private String EsClusterName;

    @Bean
    public Client client() throws Exception {

        Settings esSettings = Settings.builder()
                .put("cluster.name", "docker-cluster")
                .put("client.transport.sniff", false)
                .build();


        TransportClient client = new PreBuiltTransportClient(esSettings)
                .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
        return client;
    }

    @Bean
    public ElasticsearchOperations elasticsearchTemplate() throws Exception {
        return new ElasticsearchTemplate(client());
    }
}

Upvotes: 2

milo
milo

Reputation: 1

I had the same problem, this is what solved it for me:

This was my first issue:

debug log:

Parameter 0 of method elasticsearchTemplate in org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration required a single bean, but 2 were found:
    - buildClient: defined by method 'buildClient' in class path resource [nl/dummypackage/config/ElasticsearchConfig.class]
    - elasticsearchClient: defined by method 'elasticsearchClient' in class path resource [org/springframework/boot/autoconfigure/data/elasticsearch/ElasticsearchAutoConfiguration.class]

I removed my ElasticsearchConfig class and add this property to

application.properties

spring.data.elasticsearch.cluster-nodes=localhost:9300

Next issue: missing authentication token

debug log:

org.elasticsearch.transport.RemoteTransportException: [elasticsearch-docker-single-node][172.19.0.2:9300][cluster:monitor/nodes/liveness]
Caused by: org.elasticsearch.ElasticsearchSecurityException: missing authentication token for action [cluster:monitor/nodes/liveness]

For now, I solved it by disabling xpack.security:

elasticsearch.yml

xpack.security.enabled: false

Upvotes: 0

Related Questions