[英]Spring boot, ElasticSearch and TestContainers integration tests. Connection refused
I create an integration test for retrieving data from elasticsearch.我创建了一个用于从 elasticsearch 检索数据的集成测试。
I am using default values for the testContainer so my RestHighLevelClient should have access to the test container but all the time I am getting the same exception ( java.net.ConnecteException: Connection refused
) when I am trying to index data, but when I run my locally the docker image by command我正在使用 testContainer 的默认值,因此我的 RestHighLevelClient 应该可以访问测试容器,但是当我尝试索引数据时,我总是得到相同的异常(
java.net.ConnecteException: Connection refused
denied ),但是当我运行时我通过命令在本地获取 docker 映像
docker run -d --rm -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e "transport.host=127.0.0.1" --name elastic docker.elastic.co/elasticsearch/elasticsearch:6.5.4
my test works correctly.我的测试工作正常。
Where is the problem, because the port mapping is the same?问题出在哪里,因为端口映射是一样的? What is the reason of this exception?
这个异常的原因是什么?
My test:我的测试:
@ExtendWith(SpringExtension.class)
@Testcontainers
@WebMvcTest
class FlowerResourceTest {
@Container
private ElasticsearchContainer esContainer = new ElasticsearchContainer("docker.elastic.co/elasticsearch/elasticsearch:6.5.4");
@Autowired
private ElasticsearchConfiguration esConfig;
@Autowired
private FlowerService flowerService;
private RestHighLevelClient client;
@Test
void test() throws IOException, InterruptedException {
client = esConfig.client();
var jsonFlower = "{\n" +
" \"name\": \"XXX\",\n" +
" \"color\" : \"red\"\n" +
"}";
IndexRequest indexRequest = new IndexRequest("flowers", "doc", "1")
.source(jsonFlower, XContentType.JSON);
assertTrue(esContainer.isRunning());
client.index(indexRequest, RequestOptions.DEFAULT);
var flowers = flowerService.findAll();
assertTrue(flowers.size() > 0);
DeleteRequest deleteRequest = new DeleteRequest("flowers", "doc", "1");
client.delete(deleteRequest, RequestOptions.DEFAULT);
}
}
If I remember well, you can ask for the exposed port using the following command:如果我没记错的话,你可以使用以下命令请求暴露的端口:
esContainer.getMappedPort(ELASTICSEARCH_PORT);
The Docker container exposes a random available port, so check the port as with the mentioned command. Docker 容器公开了一个随机可用端口,因此请使用上述命令检查该端口。 Use that port for the client.
将该端口用于客户端。 A colleague of mine wrote a blog post about this with some sample code if you are interested: https://www.luminis.eu/blog/search-en/elasticsearch-instances-for-integration-testing/
如果您有兴趣,我的一位同事用一些示例代码写了一篇关于此的博客文章: https ://www.luminis.eu/blog/search-en/elasticsearch-instances-for-integration-testing/
I would guess that Elasticsearch hasn't had enough time to start up.我猜想 Elasticsearch 没有足够的时间启动。 It's a Java process and might need some time — on my machine around 20s.
这是一个 Java 进程,可能需要一些时间——在我的机器上大约 20 多岁。 You'll probably want to set a wait strategy;
您可能需要设置等待策略; something like this:
像这样的东西:
esContainer.setWaitStrategy( Wait.forHttp("/") .forPort(9200) .forStatusCode(200) .withStartupTimeout(Duration.ofSeconds(60)));
Try using it this way尝试以这种方式使用它
@Container
private static ElasticsearchContainer elasticsearchContainer = new ElasticTestContainer();
private RestHighLevelClient client;
@BeforeClass
public static void init(){
elasticsearchContainer.start();
}
@Test
void test() throws IOException, InterruptedException {
RestClientBuilder restClientBuilder = RestClient.builder(new HttpHost(elasticsearchContainer.getHost(), 9200, "http"));
client = new RestHighLevelClient(restClientBuilder);
var jsonFlower = "{\n" +
" \"name\": \"XXX\",\n" +
" \"color\" : \"red\"\n" +
"}";
IndexRequest indexRequest = new IndexRequest("flowers", "doc", "1")
.source(jsonFlower, XContentType.JSON);
assertTrue(elasticsearchContainer.isRunning());
client.index(indexRequest, RequestOptions.DEFAULT);
var flowers = flowerService.findAll();
assertTrue(flowers.size() > 0);
DeleteRequest deleteRequest = new DeleteRequest("flowers", "doc", "1");
client.delete(deleteRequest, RequestOptions.DEFAULT);
}
ElasticTestContainer class ElasticTestContainer 类
public class ElasticTestContainer extends ElasticsearchContainer {
private static final String DOCKER_ELASTIC = "docker.elastic.co/elasticsearch/elasticsearch:6.5.4";
private static final String CLUSTER_NAME = "sample-cluster";
private static final String ELASTIC_SEARCH = "elasticsearch";
public ElasticTestContainer() {
super(DOCKER_ELASTIC);
this.addFixedExposedPort(9200, 9200);
this.addFixedExposedPort(9300, 9300);
this.addEnv(CLUSTER_NAME, ELASTIC_SEARCH);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.