ElasticSearch in-memory for testing ElasticSearch in-memory for testing elasticsearch elasticsearch

ElasticSearch in-memory for testing


Based on the second link you provided, I created this abstract test class:

@RunWith(SpringJUnit4ClassRunner.class)public abstract class AbstractElasticsearchTest {    private static final String HTTP_PORT = "9205";    private static final String HTTP_TRANSPORT_PORT = "9305";    private static final String ES_WORKING_DIR = "target/es";    private static Node node;    @BeforeClass    public static void startElasticsearch() throws Exception {            removeOldDataDir(ES_WORKING_DIR + "/" + clusterName);        Settings settings = Settings.builder()                .put("path.home", ES_WORKING_DIR)                .put("path.conf", ES_WORKING_DIR)                .put("path.data", ES_WORKING_DIR)                .put("path.work", ES_WORKING_DIR)                .put("path.logs", ES_WORKING_DIR)                .put("http.port", HTTP_PORT)                .put("transport.tcp.port", HTTP_TRANSPORT_PORT)                .put("index.number_of_shards", "1")                .put("index.number_of_replicas", "0")                .put("discovery.zen.ping.multicast.enabled", "false")                .build();        node = nodeBuilder().settings(settings).clusterName("monkeys.elasticsearch").client(false).node();        node.start();    }    @AfterClass    public static void stopElasticsearch() {        node.close();    }    private static void removeOldDataDir(String datadir) throws Exception {        File dataDir = new File(datadir);        if (dataDir.exists()) {            FileSystemUtils.deleteRecursively(dataDir);        }    }    }

In the production code, I configured an Elasticsearch client as follows. The integration test extends the above defined abstract class and configures property elasticsearch.port as 9305 and elasticsearch.host as localhost.

@Configurationpublic class ElasticsearchConfiguration {        @Bean(destroyMethod = "close")    public Client elasticsearchClient(@Value("${elasticsearch.clusterName}") String clusterName,                                      @Value("${elasticsearch.host}") String elasticsearchClusterHost,                                      @Value("${elasticsearch.port}") Integer elasticsearchClusterPort) throws UnknownHostException {        Settings settings = Settings.settingsBuilder().put("cluster.name", clusterName).build();        InetSocketTransportAddress transportAddress = new InetSocketTransportAddress(InetAddress.getByName(elasticsearchClusterHost), elasticsearchClusterPort);        return TransportClient.builder().settings(settings).build().addTransportAddress(transportAddress);    }}

That's it. The integration test will run the production code which is configured to connect to the node started in the AbstractElasticsearchTest.startElasticsearch().

In case you want to use the elasticsearch REST api, use port 9205. E.g. with Apache HttpComponents:

HttpClient httpClient = HttpClients.createDefault();HttpPut httpPut = new HttpPut("http://localhost:9205/_template/" + templateName);httpPut.setEntity(new FileEntity(new File("template.json")));httpClient.execute(httpPut);


Here is my implementation

import java.io.File;import java.io.IOException;import java.nio.file.Files;import java.util.UUID;import org.elasticsearch.client.Client;import org.elasticsearch.common.settings.ImmutableSettings;import org.elasticsearch.node.Node;import org.elasticsearch.node.NodeBuilder;/** * * @author Raghu Nair */public final class ElasticSearchInMemory {    private static Client client = null;    private static File tempDir = null;    private static Node elasticSearchNode = null;    public static Client getClient() {        return client;    }    public static void setUp() throws Exception {        tempDir = File.createTempFile("elasticsearch-temp", Long.toString(System.nanoTime()));        tempDir.delete();        tempDir.mkdir();        System.out.println("writing to: " + tempDir);        String clusterName = UUID.randomUUID().toString();        elasticSearchNode = NodeBuilder                .nodeBuilder()                .local(false)                .clusterName(clusterName)                .settings(                        ImmutableSettings.settingsBuilder()                        .put("script.disable_dynamic", "false")                        .put("gateway.type", "local")                        .put("index.number_of_shards", "1")                        .put("index.number_of_replicas", "0")                        .put("path.data", new File(tempDir, "data").getAbsolutePath())                        .put("path.logs", new File(tempDir, "logs").getAbsolutePath())                        .put("path.work", new File(tempDir, "work").getAbsolutePath())                ).node();        elasticSearchNode.start();        client = elasticSearchNode.client();    }    public static void tearDown() throws Exception {        if (client != null) {            client.close();        }        if (elasticSearchNode != null) {            elasticSearchNode.stop();            elasticSearchNode.close();        }        if (tempDir != null) {            removeDirectory(tempDir);        }    }    public static void removeDirectory(File dir) throws IOException {        if (dir.isDirectory()) {            File[] files = dir.listFiles();            if (files != null && files.length > 0) {                for (File aFile : files) {                    removeDirectory(aFile);                }            }        }         Files.delete(dir.toPath());            }}


You can start ES on your local machine using:

Settings settings = Settings.settingsBuilder()        .put("path.home", ".")        .build();NodeBuilder.nodeBuilder().settings(settings).node();

When ES started, fill free to access to it over REST using curl or other tools:

curl http://localhost:9200/_cat/health?v