java 用于测试的内存中的 ElasticSearch
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/31400491/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
ElasticSearch in-memory for testing
提问by MicTech
I would like to write some integration with ElasticSearch. For testing I would like to run in-memory ES.
我想写一些与 ElasticSearch 的集成。为了测试,我想运行内存中的 ES。
I found some information in documentation, but without example how to write those kind of test. Elasticsearch Reference [1.6] ? Testing ? Java Testing Framework ? integration tests ? unit tests
我在文档中找到了一些信息,但没有示例如何编写此类测试。Elasticsearch 参考 [1.6] ? 测试 ? Java 测试框架?集成测试 ? 单元测试
Also I found following article, but it's out of data. Easy JUnit testing with Elastic Search
我还发现了以下文章,但没有数据。使用 Elastic Search 轻松进行 JUnit 测试
I looking example how to start and run ES in-memory and access to it over REST API.
我查看了如何在内存中启动和运行 ES 并通过 REST API 访问它的示例。
回答by Tim Van Laer
Based on the second linkyou 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
.
在生产代码中,我配置了一个 Elasticsearch 客户端,如下所示。集成测试扩展了上面定义的抽象类并将属性配置elasticsearch.port
为 as9305
和elasticsearch.host
as 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);
}
}
That's it. The integration test will run the production code which is configured to connect to the node started in the AbstractElasticsearchTest.startElasticsearch()
.
而已。集成测试将运行生产代码,该代码被配置为连接到AbstractElasticsearchTest.startElasticsearch()
.
In case you want to use the elasticsearch REST api, use port 9205. E.g. with Apache HttpComponents:
如果您想使用 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);
回答by Raghu K Nair
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());
}
}
回答by andrii
You can start ES on your local machine using:
您可以使用以下命令在本地机器上启动 ES:
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:
当 ES 启动时,可以使用 curl 或其他工具通过 REST 免费访问它:
curl http://localhost:9200/_cat/health?v
回答by Jon Freedman
As of 2016 embedded elasticsearch is no-longer supported
截至 2016 年,不再支持嵌入式弹性搜索
As per a response from one of the devlopers in 2017you can use the following approaches:
根据2017 年其中一位开发人员的回复,您可以使用以下方法:
- Use the Gradle tools elasticsearch already has. You can read some information about this here: https://github.com/elastic/elasticsearch/issues/21119
- Use the Maven plugin: https://github.com/alexcojocaru/elasticsearch-maven-plugin
- Use Ant scripts like http://david.pilato.fr/blog/2016/10/18/elasticsearch-real-integration-tests-updated-for-ga
- Using Docker: https://www.testcontainers.org/modules/elasticsearch
- Using Docker from maven: https://github.com/dadoonet/fscrawler/blob/e15dddf72b1ed094dad279d492e4e0314f73683f/pom.xml#L241-L289
- 使用 elasticsearch 已有的 Gradle 工具。您可以在此处阅读有关此的一些信息:https: //github.com/elastic/elasticsearch/issues/21119
- 使用 Maven 插件:https: //github.com/alexcojocaru/elasticsearch-maven-plugin
- 使用 Ant 脚本,如http://david.pilato.fr/blog/2016/10/18/elasticsearch-real-integration-tests-updated-for-ga
- 使用 Docker:https: //www.testcontainers.org/modules/elasticsearch
- 从 maven 使用 Docker:https: //github.com/dadoonet/fscrawler/blob/e15dddf72b1ed094dad279d492e4e0314f73683f/pom.xml#L241-L289