How to start elasticsearch 5.1 embedded in my java application?

With elasticsearch 2.x I used the following code to launch an embedded Node for testing:

@Bean
public Node elasticSearchTestNode() {
    return NodeBuilder.nodeBuilder()
            .settings(Settings.settingsBuilder()
                    .put("http.enabled", "true")
                    .put("path.home", "elasticsearch-data")
                    .build())
            .node();
}

This does not compile any more. How can I start an embedded node in 5.x ?


Embedding elasticsearch is no longer officially supported, and it's a bit more complicated than in 2.x, but it works.

You need to add some dependencies:

    <dependency>
        <groupId>org.elasticsearch</groupId>
        <artifactId>elasticsearch</artifactId>
        <version>5.1.1</version>
        <scope>test</scope>
    </dependency>
    <dependency><!-- required by elasticsearch -->
        <groupId>org.elasticsearch.plugin</groupId>
        <artifactId>transport-netty4-client</artifactId>
        <version>5.1.1</version>
        <scope>test</scope>
    </dependency>
    <dependency><!-- required by elasticsearch -->
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-api</artifactId>
        <version>2.7</version>
    </dependency>

And then launch a node like this:

@Bean
public Node elasticSearchTestNode() throws NodeValidationException {
    Node node = new MyNode(
            Settings.builder()
                    .put("transport.type", "netty4")
                    .put("http.type", "netty4")
                    .put("http.enabled", "true")
                    .put("path.home", "elasticsearch-data")
                    .build(),
            asList(Netty4Plugin.class));
    node.start();
    return node;
}

private static class MyNode extends Node {
    public MyNode(Settings preparedSettings, Collection<Class<? extends Plugin>> classpathPlugins) {
        super(InternalSettingsPreparer.prepareEnvironment(preparedSettings, null), classpathPlugins);
    }
}

The simplest way to make ES5 working is to use Allegro embedded-elasticsearch library (more info in article here). After day of struggling with embedding ES5 on jar level I found it pretty easy. Include into your pom:

<dependency>
    <groupId>pl.allegro.tech</groupId>
    <artifactId>embedded-elasticsearch</artifactId>
    <version>2.5.0</version>
    <scope>test</scope>
</dependency>

and use following code in your unit test

EmbeddedElastic embeddedElastic = EmbeddedElastic.builder()
        .withElasticVersion("5.5.2")
        .withSetting(PopularProperties.HTTP_PORT, 21121)
        .build();
embeddedElastic.start();

Test will automatically download Elastic and run it in isolated environment driven from your test at OS process level. http://localhost:21121 proves it works.

Our application has to interact with different versions of ESs. So this was another reason why this solution was also useful for our case, since we wouldn't otherwise be able to test multiple versions of ESs by adding multiple elasticsearch.jars into classpath.

Note: if this approach resembles "poor-man's Docker" to you, you can also have a look at TestContainers project. I didn't try it myself though I suppose it would be possible, assuming your testing infrastructure have the use of Docker.


It's not supported.

You should read this blog post.

EDIT:

This is how I solved the integration tests with maven problem.