testcontainers_modules/elastic_search/
mod.rs

1use std::borrow::Cow;
2
3use testcontainers::{
4    core::{ContainerPort, WaitFor},
5    Image,
6};
7
8const NAME: &str = "docker.elastic.co/elasticsearch/elasticsearch";
9const TAG: &str = "7.16.1";
10/// Port that the [`Elasticsearch`] container has internally
11/// Used **for API calls over http**, including search, aggregation, monitoring, ...
12/// Client libraries have switched to using this to communicate to elastic.
13/// Can be rebound externally via [`testcontainers::core::ImageExt::with_mapped_port`]
14///
15/// [`Elasticsearch`]: https://elastic.co/
16pub const ELASTICSEARCH_API_PORT: ContainerPort = ContainerPort::Tcp(9200);
17/// Port that the [`Elasticsearch`] container has internally.
18/// Used **for nodes to communicate between each other** and handles cluster updates naster elections, nodes leaving/joining, ...
19/// Can be rebound externally via [`testcontainers::core::ImageExt::with_mapped_port`]
20///
21/// [`Elasticsearch`]: https://elastic.co/
22pub const ELASTICSEARCH_INTER_NODE_PORT: ContainerPort = ContainerPort::Tcp(9300);
23
24/// Module to work with [`Elasticsearch`] inside of tests.
25///
26/// Starts an instance of Elasticsearch based on the official [`Elasticsearch docker image`].
27///
28/// Elasticsearch is a distributed, RESTful search and analytics engine capable of addressing
29/// a growing number of use cases. This module provides a local Elasticsearch instance for testing purposes.
30/// The container exposes port `9200` for API calls ([`ELASTICSEARCH_API_PORT`]) and port `9300` for
31/// inter-node communication ([`ELASTICSEARCH_INTER_NODE_PORT`]) by default.
32///
33/// # Example
34/// ```
35/// use testcontainers_modules::{
36///     elastic_search::ElasticSearch, testcontainers::runners::SyncRunner,
37/// };
38///
39/// let elasticsearch_instance = ElasticSearch::default().start().unwrap();
40/// let host = elasticsearch_instance.get_host().unwrap();
41/// let port = elasticsearch_instance.get_host_port_ipv4(9200).unwrap();
42///
43/// // Use the Elasticsearch API at http://{host}:{port}
44/// ```
45///
46/// [`Elasticsearch`]: https://www.elastic.co/elasticsearch/
47/// [`Elasticsearch docker image`]: https://www.docker.elastic.co/r/elasticsearch/elasticsearch
48#[derive(Debug, Default, Clone)]
49pub struct ElasticSearch {
50    /// (remove if there is another variable)
51    /// Field is included to prevent this struct to be a unit struct.
52    /// This allows extending functionality (and thus further variables) without breaking changes
53    _priv: (),
54}
55
56impl Image for ElasticSearch {
57    fn name(&self) -> &str {
58        NAME
59    }
60
61    fn tag(&self) -> &str {
62        TAG
63    }
64
65    fn ready_conditions(&self) -> Vec<WaitFor> {
66        vec![WaitFor::message_on_stdout("[YELLOW] to [GREEN]")]
67    }
68
69    fn env_vars(
70        &self,
71    ) -> impl IntoIterator<Item = (impl Into<Cow<'_, str>>, impl Into<Cow<'_, str>>)> {
72        [("discovery.type", "single-node")]
73    }
74
75    fn expose_ports(&self) -> &[ContainerPort] {
76        &[ELASTICSEARCH_API_PORT, ELASTICSEARCH_INTER_NODE_PORT]
77    }
78}
79
80#[cfg(test)]
81mod tests {}