Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add basic Dsl and configuration for spring-data elasticsearch #345

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions autoconfigure-adapter/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ dependencies {
compileOnly("org.mongodb:mongodb-driver-legacy")
compileOnly("org.mongodb:mongodb-driver-reactivestreams")
compileOnly("org.springframework.data:spring-data-cassandra")
compileOnly("org.springframework.data:spring-data-elasticsearch")
compileOnly("org.springframework.data:spring-data-redis")
compileOnly("redis.clients:jedis")
compileOnly("io.lettuce:lettuce-core")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package org.springframework.boot.autoconfigure.data.elasticsearch;

import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.data.elasticsearch.client.ClientConfiguration;
import org.springframework.data.elasticsearch.client.RestClients;

public class ElasticSearchDataInitializer implements ApplicationContextInitializer<GenericApplicationContext> {

private final ClientConfiguration clientConfiguration;

public ElasticSearchDataInitializer(ClientConfiguration clientConfiguration) {
this.clientConfiguration = clientConfiguration;
}

@Override
public void initialize(GenericApplicationContext context) {
context.registerBean(RestHighLevelClient.class, () -> RestClients.create(clientConfiguration).rest());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package org.springframework.boot.autoconfigure.data.elasticsearch;

import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.data.elasticsearch.client.ClientConfiguration;
import org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient;
import org.springframework.data.elasticsearch.client.reactive.ReactiveRestClients;

public class ReactiveElasticSearchDataInitializer implements ApplicationContextInitializer<GenericApplicationContext> {

private final ClientConfiguration clientConfiguration;

public ReactiveElasticSearchDataInitializer(ClientConfiguration clientConfiguration) {
this.clientConfiguration = clientConfiguration;
}

@Override
public void initialize(GenericApplicationContext context) {
context.registerBean(ReactiveElasticsearchClient.class, () -> ReactiveRestClients.create(clientConfiguration));
}
}
4 changes: 4 additions & 0 deletions jafu/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ dependencies {
compileOnly("org.springframework:spring-webmvc")
compileOnly("com.fasterxml.jackson.core:jackson-databind")
compileOnly("org.springframework.data:spring-data-mongodb")
compileOnly("org.springframework.data:spring-data-elasticsearch")
compileOnly("de.flapdoodle.embed:de.flapdoodle.embed.mongo")
compileOnly("org.springframework.data:spring-data-r2dbc")
compileOnly("com.datastax.oss:java-driver-core")
Expand All @@ -47,6 +48,7 @@ dependencies {
testImplementation("org.springframework.boot:spring-boot-starter-data-mongodb-reactive")
testImplementation("org.springframework.boot:spring-boot-starter-jdbc")
testImplementation("org.springframework.boot:spring-boot-starter-data-redis-reactive")
testImplementation("org.springframework.data:spring-data-elasticsearch")
testImplementation("org.springframework.boot:spring-boot-starter-data-r2dbc")
testImplementation("org.springframework.boot:spring-boot-starter-jdbc")
testImplementation("com.fasterxml.jackson.module:jackson-module-kotlin")
Expand All @@ -62,6 +64,8 @@ dependencies {

tasks.withType<Test> {
if (project.hasProperty("isCI")) {
exclude("org/springframework/fu/jafu/elasticsearch/ElasticSearchDslTest.class")
exclude("org/springframework/fu/jafu/elasticsearch/ReactiveElasticSearchDslTest.class")
exclude("org/springframework/fu/jafu/r2dbc/DataR2dbcDslTest.class")
exclude("org/springframework/fu/jafu/r2dbc/R2dbcDslTest.class")
exclude("org/springframework/fu/jafu/redis/ReactiveRedisDslTests.class")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package org.springframework.fu.jafu.elasticsearch;

import org.springframework.context.support.GenericApplicationContext;
import org.springframework.data.elasticsearch.client.ClientConfiguration;
import org.springframework.fu.jafu.AbstractDsl;

import java.util.Optional;
import java.util.function.Consumer;

public abstract class AbstractElasticSearchDsl<SELF extends AbstractElasticSearchDsl<SELF>> extends AbstractDsl {

private final SELF self;
private final Consumer<SELF> dsl;
private Optional<String> hostAndPort = Optional.empty();
private Boolean useSsl = false;

protected abstract SELF getSelf();

protected AbstractElasticSearchDsl(Consumer<SELF> dsl) {
this.dsl = dsl;
this.self = getSelf();
}

public SELF hostAndPort(String hostAndPort) {
this.hostAndPort = Optional.ofNullable(hostAndPort);
return self;
}

public SELF useSsl(Boolean useSsl) {
this.useSsl = useSsl;
return self;
}

protected ClientConfiguration createClientConfiguration() {
ClientConfiguration.ClientConfigurationBuilderWithRequiredEndpoint baseBuilder = ClientConfiguration.builder();
ClientConfiguration.MaybeSecureClientConfigurationBuilder maybeSecureBuilder =
hostAndPort.map(baseBuilder::connectedTo).orElseGet(baseBuilder::connectedToLocalhost);
ClientConfiguration.TerminalClientConfigurationBuilder terminalBuilder = maybeSecureBuilder;
if (useSsl) {
terminalBuilder = maybeSecureBuilder.usingSsl();
}
return terminalBuilder.build();
}

@Override
public void initialize(GenericApplicationContext context) {
super.initialize(context);
dsl.accept(self);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package org.springframework.fu.jafu.elasticsearch;

import org.springframework.boot.autoconfigure.data.elasticsearch.ElasticSearchDataInitializer;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.data.elasticsearch.client.ClientConfiguration;
import org.springframework.fu.jafu.AbstractDsl;

import java.util.Optional;
import java.util.function.Consumer;

public class ElasticSearchDsl extends AbstractElasticSearchDsl<ElasticSearchDsl> {

public ElasticSearchDsl(Consumer<ElasticSearchDsl> dsl) {
super(dsl);
}

/**
* Configure Spring-data ElasticSearch support with default properties.
* @see org.springframework.fu.jafu.ConfigurationDsl#enable(ApplicationContextInitializer)
* @see org.springframework.fu.jafu.elasticsearch.ElasticSearchDsl
*/
public static ApplicationContextInitializer<GenericApplicationContext> elasticSearch() {
return new ElasticSearchDsl(mongoDsl -> {});
}

/**
* Configure Spring-data ElasticSearch with customized properties.
* @see org.springframework.fu.jafu.ConfigurationDsl#enable(ApplicationContextInitializer)
* @see org.springframework.fu.jafu.elasticsearch.ElasticSearchDsl
*/
public static ApplicationContextInitializer<GenericApplicationContext> elasticSearch(Consumer<ElasticSearchDsl> dsl) {
return new ElasticSearchDsl(dsl);
}

@Override
protected ElasticSearchDsl getSelf() {
return this;
}

@Override
public void initialize(GenericApplicationContext context) {
super.initialize(context);
new ElasticSearchDataInitializer(createClientConfiguration()).initialize(context);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package org.springframework.fu.jafu.elasticsearch;

import org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveElasticSearchDataInitializer;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.support.GenericApplicationContext;

import java.util.function.Consumer;

public class ReactiveElasticSearchDsl extends AbstractElasticSearchDsl<ReactiveElasticSearchDsl> {

public ReactiveElasticSearchDsl(Consumer<ReactiveElasticSearchDsl> dsl) {
super(dsl);
}

/**
* Configure Spring-data ElasticSearch support with default properties.
* @see org.springframework.fu.jafu.ConfigurationDsl#enable(ApplicationContextInitializer)
* @see org.springframework.fu.jafu.elasticsearch.ReactiveElasticSearchDsl
*/
public static ApplicationContextInitializer<GenericApplicationContext> reactiveElasticSearch() {
return new ReactiveElasticSearchDsl(mongoDsl -> {});
}

/**
* Configure Spring-data ElasticSearch with customized properties.
* @see org.springframework.fu.jafu.ConfigurationDsl#enable(ApplicationContextInitializer)
* @see org.springframework.fu.jafu.elasticsearch.ReactiveElasticSearchDsl
*/
public static ApplicationContextInitializer<GenericApplicationContext> reactiveElasticSearch(Consumer<ReactiveElasticSearchDsl> dsl) {
return new ReactiveElasticSearchDsl(dsl);
}

@Override
protected ReactiveElasticSearchDsl getSelf() {
return this;
}

@Override
public void initialize(GenericApplicationContext context) {
super.initialize(context);
new ReactiveElasticSearchDataInitializer(createClientConfiguration()).initialize(context);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package org.springframework.fu.jafu.elasticsearch;

import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.junit.jupiter.api.Test;
import org.springframework.fu.jafu.Jafu;
import org.testcontainers.containers.GenericContainer;

import java.io.IOException;
import java.util.Collections;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.springframework.fu.jafu.elasticsearch.ElasticSearchDsl.elasticSearch;

class ElasticSearchDslTest {

@Test
public void enableElasticSearch() throws IOException {
var es = new GenericContainer("elasticsearch:7.9.3")
.withExposedPorts(9200)
.withEnv("discovery.type", "single-node");

es.start();
var app = Jafu.application(a ->
a.enable(elasticSearch(esDsl ->
esDsl.hostAndPort("localhost:" + es.getFirstMappedPort()))));

var context = app.run();
var client = context.getBean(RestHighLevelClient.class);
assertNotNull(client);

var request = new IndexRequest("spring-data")
.source(Collections.singletonMap("feature", "high-level-rest-client"));
var response = client.index(request, RequestOptions.DEFAULT);
assertEquals(201, response.status().getStatus());

es.stop();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package org.springframework.fu.jafu.elasticsearch;

import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.rest.RestStatus;
import org.junit.jupiter.api.Test;
import org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient;
import org.springframework.fu.jafu.Jafu;
import org.testcontainers.containers.GenericContainer;
import reactor.test.StepVerifier;

import java.io.IOException;
import java.util.Collections;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.springframework.fu.jafu.elasticsearch.ReactiveElasticSearchDsl.reactiveElasticSearch;

class ReactiveElasticSearchDslTest {

@Test
public void enableReactiveElasticSearch() throws IOException {
var es = new GenericContainer("elasticsearch:7.9.3")
.withExposedPorts(9200)
.withEnv("discovery.type", "single-node");

es.start();
var app = Jafu.application(a ->
a.enable(reactiveElasticSearch(esDsl ->
esDsl.hostAndPort("localhost:" + es.getFirstMappedPort()))));

var context = app.run();
var reactiveClient = context.getBean(ReactiveElasticsearchClient.class);
assertNotNull(reactiveClient);

var request = new IndexRequest("spring-data")
.source(Collections.singletonMap("feature", "reactive-client"));
StepVerifier
.create(reactiveClient.index(request))
.assertNext(next -> assertEquals(RestStatus.CREATED, next.status()))
.verifyComplete();
es.stop();
}

}
4 changes: 4 additions & 0 deletions kofu/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ dependencies {
compileOnly("org.mongodb:mongodb-driver-reactivestreams")
compileOnly("org.springframework.data:spring-data-cassandra")
compileOnly("org.springframework.data:spring-data-redis")
compileOnly("org.springframework.data:spring-data-elasticsearch")
compileOnly("com.fasterxml.jackson.core:jackson-databind")
compileOnly("com.samskivert:jmustache")
compileOnly("io.projectreactor.kotlin:reactor-kotlin-extensions")
Expand Down Expand Up @@ -58,6 +59,7 @@ dependencies {
testImplementation("redis.clients:jedis")
testImplementation("io.lettuce:lettuce-core")
testImplementation("org.springframework:spring-r2dbc")
testImplementation("org.springframework.data:spring-data-elasticsearch")
testRuntimeOnly("io.r2dbc:r2dbc-h2")
testRuntimeOnly("io.r2dbc:r2dbc-postgresql:0.8.4.RELEASE")
testRuntimeOnly("org.postgresql:postgresql:42.2.18")
Expand All @@ -68,6 +70,8 @@ dependencies {

tasks.withType<Test> {
if (project.hasProperty("isCI")) {
exclude("org/springframework/fu/kofu/elasticsearch/ElasticSearchDslTest.class")
exclude("org/springframework/fu/kofu/elasticsearch/ReactiveElasticSearchDslTest.class")
exclude("org/springframework/fu/kofu/redis/ReactiveRedisDslTests.class")
exclude("org/springframework/fu/kofu/redis/RedisDslTests.class")
exclude("org/springframework/fu/kofu/r2dbc/DataR2dbcDslTest.class")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package org.springframework.fu.kofu.elasticsearch

import org.springframework.data.elasticsearch.client.ClientConfiguration
import org.springframework.fu.kofu.AbstractDsl

abstract class AbstractElasticSearchDsl: AbstractDsl() {

var hostAndPort: String? = null
var usingSsl: Boolean = false

protected fun createClientConfiguration() =
ClientConfiguration.builder()
.let {
if (hostAndPort != null) it.connectedTo(hostAndPort)
else it.connectedToLocalhost()
}
.let {
if (usingSsl) it.usingSsl()
else it
}.build()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package org.springframework.fu.kofu.elasticsearch

import org.springframework.boot.autoconfigure.data.elasticsearch.ElasticSearchDataInitializer
import org.springframework.context.support.GenericApplicationContext
import org.springframework.data.elasticsearch.client.ClientConfiguration
import org.springframework.fu.kofu.AbstractDsl
import org.springframework.fu.kofu.ConfigurationDsl

class ElasticSearchDsl(private val dsl: ElasticSearchDsl.() -> Unit): AbstractElasticSearchDsl() {

override fun initialize(context: GenericApplicationContext) {
super.initialize(context)
apply(dsl)
ElasticSearchDataInitializer(createClientConfiguration()).initialize(context)
}
}

fun ConfigurationDsl.elasticSearch(dsl: ElasticSearchDsl.() -> Unit) {
ElasticSearchDsl(dsl).initialize(context)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package org.springframework.fu.kofu.elasticsearch

import org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveElasticSearchDataInitializer
import org.springframework.context.support.GenericApplicationContext
import org.springframework.fu.kofu.ConfigurationDsl

class ReactiveElasticSearchDsl(private val dsl: ReactiveElasticSearchDsl.() -> Unit): AbstractElasticSearchDsl() {
override fun initialize(context: GenericApplicationContext) {
super.initialize(context)
apply(dsl)
ReactiveElasticSearchDataInitializer(createClientConfiguration()).initialize(context)
}
}

fun ConfigurationDsl.reactiveElasticSearch(dsl: ReactiveElasticSearchDsl.() -> Unit) {
ReactiveElasticSearchDsl(dsl).initialize(context)
}
Loading