web-dev-qa-db-fra.com

ElasticSearch en mémoire pour les tests

J'aimerais écrire une intégration avec ElasticSearch. Pour les tests, j'aimerais utiliser ES en mémoire.

J'ai trouvé des informations dans la documentation, mais sans exemple, comment écrire ce type de test. Elasticsearch Reference [1.6] »Tests» Tests d'intégration de Java Testing Framework «Tests unitaires

J'ai aussi trouvé l'article suivant, mais c'est à court de données. Test facile de JUnit avec Elastic Search

Je cherche par exemple à démarrer et à exécuter ES en mémoire et à y accéder via l’API REST.

14
MicTech

Sur la base de le deuxième lien vous avez fourni, j'ai créé cette classe de test abstraite:

@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);
        }
    }    
}

Dans le code de production, j'ai configuré un client Elasticsearch comme suit. Le test d'intégration étend la classe abstraite définie ci-dessus et configure la propriété elasticsearch.port en tant que 9305 et elasticsearch.Host en tant que localhost.

@Configuration
public 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);
    }
}

C'est tout. Le test d'intégration exécutera le code de production configuré pour se connecter au nœud démarré dans AbstractElasticsearchTest.startElasticsearch().

Si vous souhaitez utiliser l’application elasticsearch REST, utilisez le port 9205. E.g. avec 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);
7
Tim Van Laer

Voici ma mise en place 

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());        
    }
}
2
Raghu K Nair

Vous pouvez démarrer ES sur votre ordinateur local en utilisant:

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

Lorsque ES a démarré, remplissez-le librement pour y accéder via REST à l'aide de curl ou d'autres outils:

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