簡體   English   中英

用於測試的內存中的 ElasticSearch

[英]ElasticSearch in-memory for testing

我想寫一些與 ElasticSearch 的集成。 為了測試,我想運行內存中的 ES。

我在文檔中找到了一些信息,但沒有示例如何編寫此類測試。 Elasticsearch 參考 [1.6] » 測試 » Java 測試框架 » 集成測試 « 單元測試

我還發現了以下文章,但沒有數據。 使用 Elastic Search 輕松進行 JUnit 測試

我查看了如何在內存中啟動和運行 ES 並通過 REST API 訪問它的示例。

根據您提供的第二個鏈接,我創建了這個抽象測試類:

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

在生產代碼中,我配置了一個 Elasticsearch 客戶端,如下所示。 集成測試擴展了上面定義的抽象類,並將屬性elasticsearch.port配置為9305並將elasticsearch.host配置為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);
    }
}

就是這樣。 集成測試將運行生產代碼,該代碼被配置為連接到在AbstractElasticsearchTest.startElasticsearch()啟動的節點。

如果您想使用 elasticsearch REST api,請使用端口 9205。例如,使用 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);

這是我的實現

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

您可以使用以下命令在本地機器上啟動 ES:

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

當 ES 啟動時,可以使用 curl 或其他工具通過 REST 免費訪問它:

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

截至 2016 年,不再支持嵌入式彈性搜索

根據2017 年其中一位開發人員的回復,您可以使用以下方法:

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM