Skip to content

Commit

Permalink
feat: Add autoconfigure-adapter for spring-data-elasticsearch for hig…
Browse files Browse the repository at this point in the history
…h level rest client and reactive client

feat: Add Jafu Dsl for spring-data elasticsearch and reactive elasticsearch

feat: Add Kofu dsl for spring-data elasticsearch and reactive elasticsearch
  • Loading branch information
fteychene committed Nov 22, 2020
1 parent a3ef3a9 commit 7144636
Show file tree
Hide file tree
Showing 15 changed files with 427 additions and 0 deletions.
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));
}
}
2 changes: 2 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("com.fasterxml.jackson.module:jackson-module-kotlin")
testRuntimeOnly("de.flapdoodle.embed:de.flapdoodle.embed.mongo")
testRuntimeOnly("com.h2database:h2")
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", "high-level-rest-client"));
StepVerifier
.create(reactiveClient.index(request))
.assertNext(next -> assertEquals(RestStatus.CREATED, next.status()))
.verifyComplete();
es.stop();
}

}
2 changes: 2 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 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

0 comments on commit 7144636

Please sign in to comment.