Search code examples
elasticsearchquarkushibernate-search

How to start quarkus native app with elasticsearch?


I have already deployed a first Quarkus app with hibernate-orm-panache, resteasy-reactive, postgresql etc as a Docker container. The Quarkus app as a container connects to the PostgreSQL on the local machine and it works quite well. In the second version I wanted to additionally implement ElasticSearch with it, which worked quite well in dev mode.

Now I am facing the difficulty of deploying quarkus-app and elasticsearch as a container. I tried to run it normally in dev mode on the server and it works fine. After creating the native package, creating the Docker image and finally running that image as a container. I get an error message that Elasticsearch request failed:Connection refused.

properties file looks like this:

quarkus.datasource.db-kind=postgresql
quarkus.datasource.username=postgres
quarkus.datasource.password=postgrespw
quarkus.datasource.jdbc.url=jdbc:postgresql://192.168.5.45:5432/b2data

#quarkus.hibernate-orm.log.sql=true

quarkus.hibernate-search-orm.elasticsearch.version=7
quarkus.hibernate-search-orm.automatic-indexing.synchronization.strategy=sync

quarkus.elasticsearch.hosts = localhost:9200
#quarkus.elasticsearch.port = 9200
#quarkus.elasticsearch.devservices.enabled = false

I also tried to start elasticsearch-cluster first as localhost:9200 and then connect quarkus, but unfortunately without success. I am new to quarkus and especially elasticsearch. I know I am missing something so can someone please help me figure this out.

<dependencies>
  <dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-resteasy-reactive-jackson</artifactId>
  </dependency>
  <dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-hibernate-orm-panache</artifactId>
  </dependency>
  <dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-hibernate-search-orm-elasticsearch</artifactId>
  </dependency>
  <dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-jdbc-postgresql</artifactId>
  </dependency>
  <dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-arc</artifactId>
  </dependency>
  <dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-resteasy-reactive</artifactId>
  </dependency>
  <dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-junit5</artifactId>
    <scope>test</scope>
  </dependency>
  <dependency>
    <groupId>io.rest-assured</groupId>
    <artifactId>rest-assured</artifactId>
    <scope>test</scope>
  </dependency>
</dependencies>

and error log

2022-11-03 15:10:05,879 ERROR [org.hib.sea.eng.rep.spi.RootFailureCollector] (JPA Startup Thread: <default>) HSEARCH000521: Hibernate Search encountered a failure during bootstrap; continuing for now to list all problems, but the process will ultimately be aborted.
Context: default backend
Failure:: org.hibernate.search.util.common.SearchException: HSEARCH400080: Unable to detect the Elasticsearch version running on the cluster: HSEARCH400007: Elasticsearch request failed: Connection refused
Request: GET  with parameters {}
Response: (no response)
        at org.hibernate.search.backend.elasticsearch.client.impl.ElasticsearchClientUtils.getElasticsearchVersion(ElasticsearchClientUtils.java:59)
        at org.hibernate.search.backend.elasticsearch.impl.ElasticsearchLinkImpl.initVersion(ElasticsearchLinkImpl.java:200)
        at org.hibernate.search.backend.elasticsearch.impl.ElasticsearchLinkImpl.onStart(ElasticsearchLinkImpl.java:142)
        at org.hibernate.search.backend.elasticsearch.impl.ElasticsearchBackendImpl.start(ElasticsearchBackendImpl.java:148)
        at org.hibernate.search.engine.common.impl.BackendNonStartedState.start(BackendNonStartedState.java:48)
        at org.hibernate.search.engine.common.impl.SearchIntegrationPartialBuildStateImpl$SearchIntegrationFinalizerImpl.finalizeIntegration(SearchIntegrationPartialBuildStateImpl.java:174)
        at org.hibernate.search.mapper.orm.bootstrap.impl.HibernateOrmIntegrationPartialBuildState.doBootSecondPhase(HibernateOrmIntegrationPartialBuildState.java:75)
        at org.hibernate.search.mapper.orm.bootstrap.impl.HibernateOrmIntegrationBooterImpl.bootNow(HibernateOrmIntegrationBooterImpl.java:176)
        at java.util.concurrent.CompletableFuture$UniApply.tryFire(CompletableFuture.java:646)
        at java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:510)
        at java.util.concurrent.CompletableFuture.complete(CompletableFuture.java:2147)
        at org.hibernate.search.mapper.orm.bootstrap.impl.HibernateSearchSessionFactoryObserver.sessionFactoryCreated(HibernateSearchSessionFactoryObserver.java:41)
        at org.hibernate.internal.SessionFactoryObserverChain.sessionFactoryCreated(SessionFactoryObserverChain.java:35)
        at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:402)
        at io.quarkus.hibernate.orm.runtime.boot.FastBootEntityManagerFactoryBuilder.build(FastBootEntityManagerFactoryBuilder.java:74)
        at io.quarkus.hibernate.orm.runtime.FastBootHibernatePersistenceProvider.createEntityManagerFactory(FastBootHibernatePersistenceProvider.java:72)
        at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:80)
        at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:55)
        at io.quarkus.hibernate.orm.runtime.JPAConfig$LazyPersistenceUnit.get(JPAConfig.java:165)
        at io.quarkus.hibernate.orm.runtime.JPAConfig$1.run(JPAConfig.java:66)
        at java.lang.Thread.run(Thread.java:833)
        at com.oracle.svm.core.thread.PlatformThreads.threadStartRoutine(PlatformThreads.java:705)
        at com.oracle.svm.core.posix.thread.PosixPlatformThreads.pthreadStartRoutine(PosixPlatformThreads.java:202)
Caused by: org.hibernate.search.util.common.SearchException: HSEARCH400007: Elasticsearch request failed: Connection refused
Request: GET  with parameters {}
Response: (no response)
        at org.hibernate.search.backend.elasticsearch.client.impl.ElasticsearchClientUtils.tryGetElasticsearchVersion(ElasticsearchClientUtils.java:83)
        at org.hibernate.search.backend.elasticsearch.client.impl.ElasticsearchClientUtils.getElasticsearchVersion(ElasticsearchClientUtils.java:56)
        ... 22 more
Caused by: org.hibernate.search.util.common.SearchException: Connection refused
        at org.hibernate.search.util.common.impl.Throwables.toRuntimeException(Throwables.java:33)
        at org.hibernate.search.util.common.impl.Futures.unwrappedExceptionJoin(Futures.java:196)
        at org.hibernate.search.backend.elasticsearch.client.impl.ElasticsearchClientUtils.tryGetElasticsearchVersion(ElasticsearchClientUtils.java:67)
        ... 23 more
Caused by: java.net.ConnectException: Connection refused
        at com.oracle.svm.jni.JNIJavaCallWrappers.jniInvoke_VA_LIST_ConnectException_constructor_026ed3e065cc052585fca43de83265b2d1381f28(JNIJavaCallWrappers.java:0)
        at sun.nio.ch.Net.pollConnect(Net.java)
        at sun.nio.ch.Net.pollConnectNow(Net.java:672)
        at sun.nio.ch.SocketChannelImpl.finishConnect(SocketChannelImpl.java:946)
        at org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor.processEvent(DefaultConnectingIOReactor.java:174)
        at org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor.processEvents(DefaultConnectingIOReactor.java:148)
        at org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor.execute(AbstractMultiworkerIOReactor.java:351)
        at org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager.execute(PoolingNHttpClientConnectionManager.java:221)
        at org.apache.http.impl.nio.client.CloseableHttpAsyncClientBase$1.run(CloseableHttpAsyncClientBase.java:64)
        ... 3 more

2022-11-03 15:10:05,882 ERROR [io.qua.run.Application] (main) Failed to start application (with profile prod): org.hibernate.search.util.common.SearchException: HSEARCH000520: Hibernate Search encountered failures during bootstrap. Failures:

    default backend:
        failures:
          - HSEARCH400080: Unable to detect the Elasticsearch version running on the cluster: HSEARCH400007: Elasticsearch request failed: Connection refused
            Request: GET  with parameters {}
            Response: (no response)
        at org.hibernate.search.engine.reporting.spi.RootFailureCollector.checkNoFailure(RootFailureCollector.java:53)
        at org.hibernate.search.engine.common.impl.SearchIntegrationPartialBuildStateImpl$SearchIntegrationFinalizerImpl.finalizeIntegration(SearchIntegrationPartialBuildStateImpl.java:177)
        at org.hibernate.search.mapper.orm.bootstrap.impl.HibernateOrmIntegrationPartialBuildState.doBootSecondPhase(HibernateOrmIntegrationPartialBuildState.java:75)
        at org.hibernate.search.mapper.orm.bootstrap.impl.HibernateOrmIntegrationBooterImpl.bootNow(HibernateOrmIntegrationBooterImpl.java:176)
        at java.util.concurrent.CompletableFuture$UniApply.tryFire(CompletableFuture.java:646)
        at java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:510)
        at java.util.concurrent.CompletableFuture.complete(CompletableFuture.java:2147)
        at org.hibernate.search.mapper.orm.bootstrap.impl.HibernateSearchSessionFactoryObserver.sessionFactoryCreated(HibernateSearchSessionFactoryObserver.java:41)
        at org.hibernate.internal.SessionFactoryObserverChain.sessionFactoryCreated(SessionFactoryObserverChain.java:35)
        at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:402)
        at io.quarkus.hibernate.orm.runtime.boot.FastBootEntityManagerFactoryBuilder.build(FastBootEntityManagerFactoryBuilder.java:74)
        at io.quarkus.hibernate.orm.runtime.FastBootHibernatePersistenceProvider.createEntityManagerFactory(FastBootHibernatePersistenceProvider.java:72)
        at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:80)
        at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:55)
        at io.quarkus.hibernate.orm.runtime.JPAConfig$LazyPersistenceUnit.get(JPAConfig.java:165)
        at io.quarkus.hibernate.orm.runtime.JPAConfig$1.run(JPAConfig.java:66)
        at java.lang.Thread.run(Thread.java:833)
        at com.oracle.svm.core.thread.PlatformThreads.threadStartRoutine(PlatformThreads.java:705)
        at com.oracle.svm.core.posix.thread.PosixPlatformThreads.pthreadStartRoutine(PosixPlatformThreads.java:202)

Solution

  • We're missing the most important information here: how did you start your application container and the Elasticsearch container?

    A container will not "see" another container as running on localhost by default; you need to configure networking and use the proper hostname to refer to the other container.

    If you're new to docker, I'd recommend reading the documentation (starting with the overview of networking).

    But in short, the easier solution is to just create a custom bridge network and run everything within that network:

    docker network create my-net
    
    # Run postgres
    # WARNING: in a real-world scenario you should configure named volumes or mounts,
    # to properly persist data.
    # See https://docs.docker.com/storage/
    docker run --name mypostgres --network my-net \
      -e POSTGRES_USER=admin \                                                                    
      -e POSTGRES_PASSWORD=admin \        
      -e POSTGRES_DB=my-db \              
      postgres:14.5
    
    # Run elasticsearch
    # WARNING: in a real-world scenario you should configure named volumes or mounts,
    # to properly persist data.
    # See https://docs.docker.com/storage/
    docker run --name myelasticsearch --network my-net \
      --ulimit memlock=-1:-1 --memory-swappiness=0 \                                                                               
      -e "xpack.security.enabled=false" \
      -e "discovery.type=single-node" \
      elastic/elasticsearch:7.17.7
    
    # Run the application,
    # passing the connection info as environment variables
    docker run --name myapp --network my-net -p 8080:8080 \
      -e QUARKUS_DATASOURCE_JDBC_URL=jdbc:postgresql://mypostgres/my-db \
      -e QUARKUS_DATASOURCE_USERNAME=admin \
      -e QUARKUS_DATASOURCE_PASSWORD=admin \
      -e QUARKUS_HIBERNATE_SEARCH_ORM_ELASTICSEARCH_HOSTS=myelasticsearch:9200 \
      my-app-container-image
    

    You might want to use docker-compose, to neatly store all that configuration in a single file: https://docs.docker.com/compose/gettingstarted/