Skip to content

Commit 4ac05d2

Browse files
ngChrisChristoph Schmid
andauthored
Add Elasticsearch support (#17)
Co-authored-by: Christoph Schmid <christoph.schmid@cloudflight.io>
1 parent 03b6241 commit 4ac05d2

File tree

9 files changed

+160
-1
lines changed

9 files changed

+160
-1
lines changed

README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,3 +366,18 @@ dependencies {
366366
* `spring.mail.host`
367367
* `spring.mail.port`
368368
* `test-resources.mailhog.api-url`
369+
370+
## Elasticsearch
371+
372+
* **Module-ID**: elasticsearch
373+
* **Default-Image**: docker.elastic.co/elasticsearch/elasticsearch
374+
375+
````kotlin
376+
dependencies {
377+
testResourcesImplementation ("io.cloudflight.testresources.springboot:springboot-testresources-elasticsearch:0.1.2")
378+
}
379+
````
380+
381+
* **Provided properties**:
382+
* `spring.elasticsearch.uris`
383+
* `spring.elasticsearch.password`

gradle/libs.versions.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,5 @@ jupiter-api = { module = "org.junit.jupiter:junit-jupiter-api", version.ref = "j
1414
jupiter-engine = { module = "org.junit.jupiter:junit-jupiter-engine", version.ref = "junit" }
1515

1616
assertj = { module = "org.assertj:assertj-core", version = "3.23.1" }
17-
17+
testcontainers-elasticsearch = { module = "org.testcontainers:elasticsearch", version = "" }
1818
testcontainers-junit4-mock = { module = "io.quarkus:quarkus-junit4-mock", version = "2.9.2.Final" }

settings.gradle.kts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ include("springboot-testresources-jdbc:springboot-testresources-jdbc-postgres")
1414
include("springboot-testresources-rabbitmq")
1515
include("springboot-testresources-redis")
1616
include("springboot-testresources-mailhog")
17+
include("springboot-testresources-elasticsearch")
1718

1819
include("testprojects:jdbc:mariadb")
1920
include("testprojects:jdbc:mssql")
@@ -23,3 +24,4 @@ include("testprojects:minio")
2324
include("testprojects:rabbitmq")
2425
include("testprojects:redis")
2526
include("testprojects:mailhog")
27+
include("testprojects:elasticsearch")
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
2+
description = "Spring Boot TestResourceProvider for Elasticsearc"
3+
4+
dependencies {
5+
implementation("org.testcontainers:elasticsearch")
6+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package io.cloudflight.testresources.springboot.elasticsearch;
2+
3+
import io.micronaut.testresources.testcontainers.AbstractTestContainersProvider;
4+
import org.testcontainers.elasticsearch.ElasticsearchContainer;
5+
import org.testcontainers.utility.DockerImageName;
6+
7+
import java.util.*;
8+
import java.util.stream.Collectors;
9+
10+
public class ElasticSearchTestResourceProvider extends AbstractTestContainersProvider<ElasticsearchContainer> {
11+
12+
private static final String SIMPLE_NAME = "elasticsearch";
13+
private static final String DEFAULT_IMAGE = "docker.elastic.co/elasticsearch/elasticsearch";
14+
private static final String DEFAULT_TAG = "8.4.3";
15+
private static final String PREFIX = "spring.elasticsearch";
16+
private static final String URIS = "uris";
17+
private static final String PASSWORD = "password";
18+
private static final String ENV_PASSWORD = "ELASTIC_PASSWORD";
19+
private static final List<String> SUPPORTED_LIST = Collections.unmodifiableList(
20+
Arrays.asList(URIS, PASSWORD)
21+
);
22+
23+
@Override
24+
protected String getSimpleName() {
25+
return SIMPLE_NAME;
26+
}
27+
28+
@Override
29+
protected String getDefaultImageName() {
30+
return DEFAULT_IMAGE;
31+
}
32+
33+
@Override
34+
protected ElasticsearchContainer createContainer(DockerImageName imageName, Map<String, Object> requestedProperties, Map<String, Object> testResourcesConfiguration) {
35+
if ("latest".equals(imageName.getVersionPart())) {
36+
// ElasticSearch does't provide a latest tag, so we use a hardcoded version
37+
imageName = imageName.withTag(DEFAULT_TAG);
38+
}
39+
ElasticsearchContainer container = new ElasticsearchContainer(imageName);
40+
container.withEnv("xpack.security.enabled", "false");
41+
return container;
42+
}
43+
44+
@Override
45+
protected Optional<String> resolveProperty(String propertyName, ElasticsearchContainer container) {
46+
String value = switch (configurationPropertyFrom(propertyName)) {
47+
case URIS -> container.getHttpHostAddress();
48+
case PASSWORD -> container.getEnvMap().get(ENV_PASSWORD);
49+
default -> null;
50+
};
51+
return Optional.ofNullable(value);
52+
}
53+
54+
private String configurationPropertyFrom(String expression) {
55+
String[] propertyParts = expression.split("\\.");
56+
return propertyParts[propertyParts.length - 1];
57+
}
58+
59+
@Override
60+
public boolean shouldAnswer(String propertyName, Map<String, Object> requestedProperties, Map<String, Object> testResourcesConfiguration) {
61+
return propertyName.startsWith(PREFIX);
62+
}
63+
64+
@Override
65+
public List<String> getResolvableProperties(Map<String, Collection<String>> propertyEntries, Map<String, Object> testResourcesConfig) {
66+
return SUPPORTED_LIST.stream().map(p -> PREFIX + "." + p).collect(Collectors.toList());
67+
}
68+
69+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
io.cloudflight.testresources.springboot.elasticsearch.ElasticSearchTestResourceProvider
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
plugins {
2+
id("io.micronaut.test-resources")
3+
}
4+
5+
dependencies {
6+
implementation("org.springframework.boot:spring-boot-starter-data-elasticsearch")
7+
8+
runtimeOnly("org.jetbrains.kotlin:kotlin-reflect")
9+
10+
testImplementation("org.springframework.boot:spring-boot-starter-test")
11+
12+
testRuntimeOnly(project(":springboot-testresources-client"))
13+
testResourcesImplementation(project(":springboot-testresources-elasticsearch"))
14+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package io.cloudflight.testresources.springboot.elasticsearch
2+
3+
import org.springframework.boot.autoconfigure.SpringBootApplication
4+
import org.springframework.data.annotation.Id
5+
import org.springframework.data.elasticsearch.annotations.Document
6+
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository
7+
import org.springframework.stereotype.Repository
8+
9+
10+
@SpringBootApplication
11+
class Application
12+
13+
@Document(indexName = "test_index")
14+
class TestDocument( @Id var key: String? = null, var title: String? = null) {
15+
}
16+
17+
@Repository
18+
interface TestDocumentRepository : ElasticsearchRepository<TestDocument?, String?> {
19+
fun findByTitle(title: String?): List<TestDocument?>?
20+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package io.cloudflight.testresources.springboot.elasticsearch
2+
3+
import org.assertj.core.api.Assertions.assertThat
4+
import org.junit.jupiter.api.Test
5+
import org.springframework.beans.factory.annotation.Autowired
6+
import org.springframework.beans.factory.annotation.Value
7+
import org.springframework.boot.test.context.SpringBootTest
8+
9+
@SpringBootTest
10+
class ApplicationTest(
11+
@Value("\${spring.elasticsearch.uris}") private val uris: String,
12+
@Autowired private val testDocumentRepository: TestDocumentRepository
13+
) {
14+
15+
@Test
16+
fun urisPropertyIsBound() {
17+
assertThat(uris).matches("^localhost:[1-9][0-9]{3,4}\$")
18+
}
19+
20+
@Test
21+
fun springDataShouldWork() {
22+
val key = "test::1"
23+
val title = "myvalue"
24+
assertThat(testDocumentRepository).isNotNull()
25+
assertThat(testDocumentRepository.findById(key).isPresent()).isFalse()
26+
val testDocument = TestDocument(key, title)
27+
testDocumentRepository.save(testDocument)
28+
val foundDocument = testDocumentRepository.findById(key).get()
29+
assertThat(foundDocument.key).isEqualTo(key)
30+
assertThat(foundDocument.title).isEqualTo(title)
31+
}
32+
}

0 commit comments

Comments
 (0)