mirror of
https://github.com/spring-projects/spring-boot.git
synced 2024-08-29 03:06:45 +08:00
Auto-configure reactive Elasticsearch components
As of Spring Data Moore, a new reactive template and the corresponding repositories support have been added. This commit auto-configures a `ReactiveElasticsearchTemplate` with the configuration properties under the `spring.data.elasticsearch.client.reactive` namespace. To enable this feature, applications require both Spring Data Elasticsearch dependencies (typically `spring-boot-starter-data-elasticsearch`) and dependencies for a `WebClient` (often `spring-boot-starter-webflux`). The support for the reactive Elasticsearch repositories is also provided. Closes gh-16214
This commit is contained in:
parent
05ad95548b
commit
16c521a9e6
@ -24,27 +24,30 @@ import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
|
||||
import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories;
|
||||
import org.springframework.data.elasticsearch.repository.config.EnableReactiveElasticsearchRepositories;
|
||||
|
||||
/**
|
||||
* {@link EnableAutoConfiguration Auto-configuration} for Spring Data's Elasticsearch
|
||||
* support.
|
||||
* <p>
|
||||
* Registers an {@link ElasticsearchTemplate} if no other bean of the same type is
|
||||
* configured.
|
||||
* Registers an {@link ElasticsearchTemplate} if no other bean of the same type and the
|
||||
* same name {@code "elasticsearchTemplate"} is configured.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
* @author Artur Konczak
|
||||
* @author Mohsin Husen
|
||||
* @see EnableElasticsearchRepositories
|
||||
* @see EnableReactiveElasticsearchRepositories
|
||||
* @since 1.1.0
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass({ ElasticsearchTemplate.class })
|
||||
@AutoConfigureAfter({ ElasticsearchAutoConfiguration.class,
|
||||
RestClientAutoConfiguration.class })
|
||||
RestClientAutoConfiguration.class, ReactiveRestClientAutoConfiguration.class })
|
||||
@Import({ ElasticsearchDataConfiguration.BaseConfiguration.class,
|
||||
ElasticsearchDataConfiguration.TransportClientConfiguration.class,
|
||||
ElasticsearchDataConfiguration.RestHighLevelClientConfiguration.class })
|
||||
ElasticsearchDataConfiguration.RestClientConfiguration.class,
|
||||
ElasticsearchDataConfiguration.ReactiveRestClientConfiguration.class })
|
||||
public class ElasticsearchDataAutoConfiguration {
|
||||
|
||||
}
|
||||
|
@ -16,6 +16,8 @@
|
||||
|
||||
package org.springframework.boot.autoconfigure.data.elasticsearch;
|
||||
|
||||
import org.elasticsearch.action.support.IndicesOptions;
|
||||
import org.elasticsearch.action.support.WriteRequest;
|
||||
import org.elasticsearch.client.Client;
|
||||
import org.elasticsearch.client.RestHighLevelClient;
|
||||
|
||||
@ -24,12 +26,20 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient;
|
||||
import org.springframework.data.elasticsearch.core.DefaultEntityMapper;
|
||||
import org.springframework.data.elasticsearch.core.DefaultResultMapper;
|
||||
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
|
||||
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
|
||||
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
|
||||
import org.springframework.data.elasticsearch.core.EntityMapper;
|
||||
import org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations;
|
||||
import org.springframework.data.elasticsearch.core.ReactiveElasticsearchTemplate;
|
||||
import org.springframework.data.elasticsearch.core.ResultsMapper;
|
||||
import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
|
||||
import org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter;
|
||||
import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
|
||||
/**
|
||||
* Configuration classes for Spring Data for Elasticsearch
|
||||
@ -57,19 +67,33 @@ abstract class ElasticsearchDataConfiguration {
|
||||
return new SimpleElasticsearchMappingContext();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public EntityMapper entityMapper(
|
||||
SimpleElasticsearchMappingContext mappingContext) {
|
||||
return new DefaultEntityMapper(mappingContext);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public ResultsMapper resultsMapper(
|
||||
SimpleElasticsearchMappingContext mappingContext,
|
||||
EntityMapper entityMapper) {
|
||||
return new DefaultResultMapper(mappingContext, entityMapper);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass(RestHighLevelClient.class)
|
||||
static class RestHighLevelClientConfiguration {
|
||||
static class RestClientConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(value = ElasticsearchOperations.class,
|
||||
name = "elasticsearchTemplate")
|
||||
@ConditionalOnBean(RestHighLevelClient.class)
|
||||
public ElasticsearchRestTemplate elasticsearchTemplate(RestHighLevelClient client,
|
||||
ElasticsearchConverter converter) {
|
||||
return new ElasticsearchRestTemplate(client, converter);
|
||||
ElasticsearchConverter converter, ResultsMapper resultsMapper) {
|
||||
return new ElasticsearchRestTemplate(client, converter, resultsMapper);
|
||||
}
|
||||
|
||||
}
|
||||
@ -83,9 +107,9 @@ abstract class ElasticsearchDataConfiguration {
|
||||
name = "elasticsearchTemplate")
|
||||
@ConditionalOnBean(Client.class)
|
||||
public ElasticsearchTemplate elasticsearchTemplate(Client client,
|
||||
ElasticsearchConverter converter) {
|
||||
ElasticsearchConverter converter, ResultsMapper resultsMapper) {
|
||||
try {
|
||||
return new ElasticsearchTemplate(client, converter);
|
||||
return new ElasticsearchTemplate(client, converter, resultsMapper);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new IllegalStateException(ex);
|
||||
@ -94,4 +118,24 @@ abstract class ElasticsearchDataConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass({ WebClient.class, ReactiveElasticsearchOperations.class })
|
||||
static class ReactiveRestClientConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(value = ReactiveElasticsearchOperations.class,
|
||||
name = "reactiveElasticsearchTemplate")
|
||||
@ConditionalOnBean(ReactiveElasticsearchClient.class)
|
||||
public ReactiveElasticsearchTemplate reactiveElasticsearchTemplate(
|
||||
ReactiveElasticsearchClient client, ElasticsearchConverter converter,
|
||||
ResultsMapper resultsMapper) {
|
||||
ReactiveElasticsearchTemplate template = new ReactiveElasticsearchTemplate(
|
||||
client, converter, resultsMapper);
|
||||
template.setIndicesOptions(IndicesOptions.strictExpandOpenAndForbidClosed());
|
||||
template.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);
|
||||
return template;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.data.elasticsearch;
|
||||
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient;
|
||||
import org.springframework.data.elasticsearch.repository.ReactiveElasticsearchRepository;
|
||||
import org.springframework.data.elasticsearch.repository.config.EnableReactiveElasticsearchRepositories;
|
||||
import org.springframework.data.elasticsearch.repository.support.ReactiveElasticsearchRepositoryFactoryBean;
|
||||
|
||||
/**
|
||||
* {@link EnableAutoConfiguration Auto-configuration} for Spring Data's Elasticsearch
|
||||
* Reactive Repositories.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
* @see EnableReactiveElasticsearchRepositories
|
||||
* @since 2.2.0
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass({ ReactiveElasticsearchClient.class,
|
||||
ReactiveElasticsearchRepository.class })
|
||||
@ConditionalOnProperty(prefix = "spring.data.elasticsearch.repositories",
|
||||
name = "enabled", havingValue = "true", matchIfMissing = true)
|
||||
@ConditionalOnMissingBean(ReactiveElasticsearchRepositoryFactoryBean.class)
|
||||
@Import(ReactiveElasticsearchRepositoriesRegistrar.class)
|
||||
public class ReactiveElasticsearchRepositoriesAutoConfiguration {
|
||||
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.data.elasticsearch;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
|
||||
import org.springframework.boot.autoconfigure.data.AbstractRepositoryConfigurationSourceSupport;
|
||||
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
|
||||
import org.springframework.data.elasticsearch.repository.config.EnableReactiveElasticsearchRepositories;
|
||||
import org.springframework.data.elasticsearch.repository.config.ReactiveElasticsearchRepositoryConfigurationExtension;
|
||||
import org.springframework.data.repository.config.RepositoryConfigurationExtension;
|
||||
|
||||
/**
|
||||
* {@link ImportBeanDefinitionRegistrar} used to auto-configure Spring Data Elasticsearch
|
||||
* Reactive Repositories.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
* @since 2.2.0
|
||||
*/
|
||||
class ReactiveElasticsearchRepositoriesRegistrar
|
||||
extends AbstractRepositoryConfigurationSourceSupport {
|
||||
|
||||
@Override
|
||||
protected Class<? extends Annotation> getAnnotation() {
|
||||
return EnableReactiveElasticsearchRepositories.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<?> getConfiguration() {
|
||||
return EnableElasticsearchRepositoriesConfiguration.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected RepositoryConfigurationExtension getRepositoryConfigurationExtension() {
|
||||
return new ReactiveElasticsearchRepositoryConfigurationExtension();
|
||||
}
|
||||
|
||||
@EnableReactiveElasticsearchRepositories
|
||||
private static class EnableElasticsearchRepositoriesConfiguration {
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.data.elasticsearch;
|
||||
|
||||
import reactor.netty.http.client.HttpClient;
|
||||
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.boot.context.properties.PropertyMapper;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.elasticsearch.client.ClientConfiguration;
|
||||
import org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient;
|
||||
import org.springframework.data.elasticsearch.client.reactive.ReactiveRestClients;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
|
||||
/**
|
||||
* {@link EnableAutoConfiguration Auto-configuration} for Elasticsearch Reactive REST
|
||||
* clients.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
* @since 2.2.0
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass({ ReactiveRestClients.class, WebClient.class, HttpClient.class })
|
||||
@EnableConfigurationProperties(ReactiveRestClientProperties.class)
|
||||
public class ReactiveRestClientAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public ClientConfiguration clientConfiguration(
|
||||
ReactiveRestClientProperties properties) {
|
||||
ClientConfiguration.MaybeSecureClientConfigurationBuilder builder = ClientConfiguration
|
||||
.builder().connectedTo(properties.getEndpoints().toArray(new String[0]));
|
||||
if (properties.isUseSsl()) {
|
||||
builder.usingSsl();
|
||||
}
|
||||
configureTimeouts(builder, properties);
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private void configureTimeouts(
|
||||
ClientConfiguration.TerminalClientConfigurationBuilder builder,
|
||||
ReactiveRestClientProperties properties) {
|
||||
PropertyMapper map = PropertyMapper.get();
|
||||
map.from(properties.getConnectionTimeout()).whenNonNull()
|
||||
.to(builder::withConnectTimeout);
|
||||
map.from(properties.getSocketTimeout()).whenNonNull()
|
||||
.to(builder::withSocketTimeout);
|
||||
map.from(properties.getUsername()).whenHasText().to((username) -> {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setBasicAuth(username, properties.getPassword());
|
||||
builder.withDefaultHeaders(headers);
|
||||
});
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public ReactiveElasticsearchClient reactiveElasticsearchClient(
|
||||
ClientConfiguration clientConfiguration) {
|
||||
return ReactiveRestClients.create(clientConfiguration);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.data.elasticsearch;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
/**
|
||||
* Configuration properties for Elasticsearch Reactive REST clients.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
* @since 2.2.0
|
||||
*/
|
||||
@ConfigurationProperties(prefix = "spring.data.elasticsearch.client.reactive")
|
||||
public class ReactiveRestClientProperties {
|
||||
|
||||
/**
|
||||
* Comma-separated list of the Elasticsearch endpoints to connect to.
|
||||
*/
|
||||
private List<String> endpoints = new ArrayList<>(
|
||||
Collections.singletonList("localhost:9200"));
|
||||
|
||||
/**
|
||||
* Whether the client should use SSL to connect to the endpoints.
|
||||
*/
|
||||
private boolean useSsl = false;
|
||||
|
||||
/**
|
||||
* Credentials username.
|
||||
*/
|
||||
private String username;
|
||||
|
||||
/**
|
||||
* Credentials password.
|
||||
*/
|
||||
private String password;
|
||||
|
||||
/**
|
||||
* Connection timeout.
|
||||
*/
|
||||
private Duration connectionTimeout;
|
||||
|
||||
/**
|
||||
* Read and Write Socket timeout.
|
||||
*/
|
||||
private Duration socketTimeout;
|
||||
|
||||
public List<String> getEndpoints() {
|
||||
return this.endpoints;
|
||||
}
|
||||
|
||||
public void setEndpoints(List<String> endpoints) {
|
||||
this.endpoints = endpoints;
|
||||
}
|
||||
|
||||
public boolean isUseSsl() {
|
||||
return this.useSsl;
|
||||
}
|
||||
|
||||
public void setUseSsl(boolean useSsl) {
|
||||
this.useSsl = useSsl;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return this.username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return this.password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public Duration getConnectionTimeout() {
|
||||
return this.connectionTimeout;
|
||||
}
|
||||
|
||||
public void setConnectionTimeout(Duration connectionTimeout) {
|
||||
this.connectionTimeout = connectionTimeout;
|
||||
}
|
||||
|
||||
public Duration getSocketTimeout() {
|
||||
return this.socketTimeout;
|
||||
}
|
||||
|
||||
public void setSocketTimeout(Duration socketTimeout) {
|
||||
this.socketTimeout = socketTimeout;
|
||||
}
|
||||
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2017 the original author or authors.
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -42,6 +42,8 @@ org.springframework.boot.autoconfigure.data.couchbase.CouchbaseRepositoriesAutoC
|
||||
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveElasticsearchRepositoriesAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveRestClientAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.data.jdbc.JdbcRepositoriesAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.data.ldap.LdapRepositoriesAutoConfiguration,\
|
||||
|
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.data.alt.elasticsearch;
|
||||
|
||||
import org.springframework.boot.autoconfigure.data.elasticsearch.city.City;
|
||||
import org.springframework.data.elasticsearch.repository.ReactiveElasticsearchRepository;
|
||||
|
||||
public interface CityReactiveElasticsearchDbRepository
|
||||
extends ReactiveElasticsearchRepository<City, Long> {
|
||||
|
||||
}
|
@ -41,7 +41,6 @@ import static org.mockito.Mockito.mock;
|
||||
* @author Phillip Webb
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
@Deprecated
|
||||
@Testcontainers
|
||||
public class ElasticsearchAutoConfigurationTests {
|
||||
|
||||
|
@ -28,6 +28,8 @@ import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
|
||||
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
|
||||
import org.springframework.data.elasticsearch.core.EntityMapper;
|
||||
import org.springframework.data.elasticsearch.core.ReactiveElasticsearchTemplate;
|
||||
import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
|
||||
import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext;
|
||||
|
||||
@ -50,6 +52,7 @@ public class ElasticsearchDataAutoConfigurationTests {
|
||||
private ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withConfiguration(AutoConfigurations.of(ElasticsearchAutoConfiguration.class,
|
||||
RestClientAutoConfiguration.class,
|
||||
ReactiveRestClientAutoConfiguration.class,
|
||||
ElasticsearchDataAutoConfiguration.class));
|
||||
|
||||
@Test
|
||||
@ -75,6 +78,10 @@ public class ElasticsearchDataAutoConfigurationTests {
|
||||
public void defaultRestBeansRegistered() {
|
||||
this.contextRunner.run((context) -> assertThat(context)
|
||||
.hasSingleBean(ElasticsearchRestTemplate.class)
|
||||
.hasSingleBean(ReactiveElasticsearchTemplate.class)
|
||||
.hasSingleBean(ElasticsearchConverter.class)
|
||||
.hasSingleBean(SimpleElasticsearchMappingContext.class)
|
||||
.hasSingleBean(EntityMapper.class)
|
||||
.hasSingleBean(ElasticsearchConverter.class));
|
||||
}
|
||||
|
||||
@ -94,6 +101,14 @@ public class ElasticsearchDataAutoConfigurationTests {
|
||||
.contains("elasticsearchTemplate"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customReactiveRestTemplateShouldBeUsed() {
|
||||
this.contextRunner.withUserConfiguration(CustomReactiveRestTemplate.class)
|
||||
.run((context) -> assertThat(context)
|
||||
.getBeanNames(ReactiveElasticsearchTemplate.class).hasSize(1)
|
||||
.contains("reactiveElasticsearchTemplate"));
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class CustomTransportTemplate {
|
||||
|
||||
@ -114,4 +129,14 @@ public class ElasticsearchDataAutoConfigurationTests {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class CustomReactiveRestTemplate {
|
||||
|
||||
@Bean
|
||||
ReactiveElasticsearchTemplate reactiveElasticsearchTemplate() {
|
||||
return mock(ReactiveElasticsearchTemplate.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.data.elasticsearch;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.testcontainers.junit.jupiter.Container;
|
||||
import org.testcontainers.junit.jupiter.Testcontainers;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage;
|
||||
import org.springframework.boot.autoconfigure.data.alt.elasticsearch.CityReactiveElasticsearchDbRepository;
|
||||
import org.springframework.boot.autoconfigure.data.elasticsearch.city.City;
|
||||
import org.springframework.boot.autoconfigure.data.elasticsearch.city.ReactiveCityRepository;
|
||||
import org.springframework.boot.autoconfigure.data.empty.EmptyDataPackage;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.boot.testsupport.testcontainers.ElasticsearchContainer;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.elasticsearch.core.ReactiveElasticsearchTemplate;
|
||||
import org.springframework.data.elasticsearch.repository.config.EnableReactiveElasticsearchRepositories;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link ReactiveElasticsearchRepositoriesAutoConfiguration}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @author Andy Wilkinson
|
||||
* @author Brian Clozel
|
||||
*/
|
||||
@Testcontainers
|
||||
public class ReactiveElasticsearchRepositoriesAutoConfigurationTests {
|
||||
|
||||
@Container
|
||||
public static ElasticsearchContainer elasticsearch = new ElasticsearchContainer();
|
||||
|
||||
private ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withConfiguration(
|
||||
AutoConfigurations.of(ReactiveRestClientAutoConfiguration.class,
|
||||
ReactiveElasticsearchRepositoriesAutoConfiguration.class,
|
||||
ElasticsearchDataAutoConfiguration.class))
|
||||
.withPropertyValues(
|
||||
"spring.data.elasticsearch.client.reactive.endpoints=localhost:"
|
||||
+ elasticsearch.getMappedHttpPort());
|
||||
|
||||
@Test
|
||||
public void testDefaultRepositoryConfiguration() {
|
||||
this.contextRunner.withUserConfiguration(TestConfiguration.class)
|
||||
.run((context) -> assertThat(context)
|
||||
.hasSingleBean(ReactiveCityRepository.class)
|
||||
.hasSingleBean(ReactiveElasticsearchTemplate.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoRepositoryConfiguration() {
|
||||
this.contextRunner.withUserConfiguration(EmptyConfiguration.class)
|
||||
.run((context) -> assertThat(context)
|
||||
.hasSingleBean(ReactiveElasticsearchTemplate.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doesNotTriggerDefaultRepositoryDetectionIfCustomized() {
|
||||
this.contextRunner.withUserConfiguration(CustomizedConfiguration.class)
|
||||
.run((context) -> assertThat(context)
|
||||
.hasSingleBean(CityReactiveElasticsearchDbRepository.class));
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@TestAutoConfigurationPackage(City.class)
|
||||
static class TestConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@TestAutoConfigurationPackage(EmptyDataPackage.class)
|
||||
static class EmptyConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@TestAutoConfigurationPackage(ReactiveElasticsearchRepositoriesAutoConfigurationTests.class)
|
||||
@EnableReactiveElasticsearchRepositories(
|
||||
basePackageClasses = CityReactiveElasticsearchDbRepository.class)
|
||||
static class CustomizedConfiguration {
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.data.elasticsearch;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.elasticsearch.action.get.GetRequest;
|
||||
import org.elasticsearch.action.index.IndexRequest;
|
||||
import org.elasticsearch.index.get.GetResult;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.testcontainers.junit.jupiter.Container;
|
||||
import org.testcontainers.junit.jupiter.Testcontainers;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.boot.testsupport.testcontainers.ElasticsearchContainer;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.elasticsearch.client.ClientConfiguration;
|
||||
import org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests for {@link ReactiveRestClientAutoConfiguration}
|
||||
*
|
||||
* @author Brian Clozel
|
||||
*/
|
||||
@Testcontainers
|
||||
public class ReactiveRestClientAutoConfigurationTests {
|
||||
|
||||
@Container
|
||||
public static ElasticsearchContainer elasticsearch = new ElasticsearchContainer();
|
||||
|
||||
private ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withConfiguration(
|
||||
AutoConfigurations.of(ReactiveRestClientAutoConfiguration.class));
|
||||
|
||||
@Test
|
||||
public void configureShouldCreateDefaultBeans() {
|
||||
this.contextRunner.run(
|
||||
(context) -> assertThat(context).hasSingleBean(ClientConfiguration.class)
|
||||
.hasSingleBean(ReactiveElasticsearchClient.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void configureWhenCustomClientShouldBackOff() {
|
||||
this.contextRunner.withUserConfiguration(CustomClientConfiguration.class)
|
||||
.run((context) -> assertThat(context)
|
||||
.hasSingleBean(ReactiveElasticsearchClient.class)
|
||||
.hasBean("customClient"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void configureWhenCustomClientConfig() {
|
||||
this.contextRunner.withUserConfiguration(CustomClientConfigConfiguration.class)
|
||||
.run((context) -> assertThat(context)
|
||||
.hasSingleBean(ReactiveElasticsearchClient.class)
|
||||
.hasSingleBean(ClientConfiguration.class)
|
||||
.hasBean("customClientConfiguration"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void restClientCanQueryElasticsearchNode() {
|
||||
this.contextRunner.withPropertyValues(
|
||||
"spring.data.elasticsearch.client.reactive.endpoints=localhost:"
|
||||
+ elasticsearch.getMappedPort())
|
||||
.run((context) -> {
|
||||
ReactiveElasticsearchClient client = context
|
||||
.getBean(ReactiveElasticsearchClient.class);
|
||||
Map<String, String> source = new HashMap<>();
|
||||
source.put("a", "alpha");
|
||||
source.put("b", "bravo");
|
||||
IndexRequest index = new IndexRequest("foo", "bar", "1")
|
||||
.source(source);
|
||||
GetRequest getRequest = new GetRequest("foo", "bar", "1");
|
||||
GetResult getResult = client.index(index).then(client.get(getRequest))
|
||||
.block();
|
||||
assertThat(getResult.isExists()).isTrue();
|
||||
});
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class CustomClientConfiguration {
|
||||
|
||||
@Bean
|
||||
public ReactiveElasticsearchClient customClient() {
|
||||
return mock(ReactiveElasticsearchClient.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class CustomClientConfigConfiguration {
|
||||
|
||||
@Bean
|
||||
public ClientConfiguration customClientConfiguration() {
|
||||
return ClientConfiguration.localhost();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.data.elasticsearch.city;
|
||||
|
||||
import org.springframework.data.repository.reactive.ReactiveCrudRepository;
|
||||
|
||||
/**
|
||||
* @author Brian Clozel
|
||||
*/
|
||||
public interface ReactiveCityRepository extends ReactiveCrudRepository<City, String> {
|
||||
|
||||
}
|
@ -52,6 +52,8 @@
|
||||
:spring-session: https://projects.spring.io/spring-session/
|
||||
:spring-framework: https://projects.spring.io/spring-framework/
|
||||
:spring-security: https://projects.spring.io/spring-security/
|
||||
:spring-data-elasticsearch: https://spring.io/projects/spring-data-elasticsearch
|
||||
:spring-data-elasticsearch-reference: https://docs.spring.io/spring-data/elasticsearch/docs/current/reference/html/
|
||||
:spring-data-jpa: https://projects.spring.io/spring-data-jpa/
|
||||
:spring-security-reference: https://docs.spring.io/spring-security/site/docs/{spring-security-docs-version}/reference/htmlsingle
|
||||
:spring-security-oauth2-reference: https://projects.spring.io/spring-security-oauth/docs/oauth2.html
|
||||
|
@ -4865,12 +4865,15 @@ auto-configuration for Elasticsearch.
|
||||
Spring Boot supports several clients:
|
||||
|
||||
* The official Java "Low Level" and "High Level" REST clients
|
||||
* https://github.com/searchbox-io/Jest[Jest]
|
||||
* The `ReactiveElasticsearchClient` provided by Spring Data Elasticsearch
|
||||
|
||||
The transport client is still available but its support has been deprecated in
|
||||
https://github.com/spring-projects/spring-data-elasticsearch[Spring Data Elasticsearch]
|
||||
and will be removed in a future release. Spring Boot provides a dedicated "`Starter`",
|
||||
`spring-boot-starter-data-elasticsearch`.
|
||||
and Elasticsearch itself. It will be removed in a future release.
|
||||
Spring Boot provides a dedicated "`Starter`", `spring-boot-starter-data-elasticsearch`.
|
||||
|
||||
The https://github.com/searchbox-io/Jest[Jest] client has been deprecated as well, since
|
||||
both Elasticsearch and Spring Data Elasticsearch provide official support for REST clients.
|
||||
|
||||
[[boot-features-connecting-to-elasticsearch-rest]]
|
||||
==== Connecting to Elasticsearch using REST clients
|
||||
@ -4899,6 +4902,28 @@ If you have the `org.elasticsearch.client:elasticsearch-rest-high-level-client`
|
||||
on the classpath, Spring Boot will auto-configure a `RestHighLevelClient`, which wraps
|
||||
any existing `RestClient` bean, reusing its HTTP configuration.
|
||||
|
||||
[[boot-features-connecting-to-elasticsearch-reactive-rest]]
|
||||
==== Connecting to Elasticsearch using Reactive REST clients
|
||||
{spring-data-elasticsearch}[Spring Data Elasticsearch] ships `ReactiveElasticsearchClient`
|
||||
for querying Elasticsearch instances in a reactive fashion. It is built on top of WebFlux's
|
||||
`WebClient`, so both `spring-boot-starter-elasticsearch` and `spring-boot-starter-webflux`
|
||||
dependencies are useful to enable this support.
|
||||
|
||||
By default, Spring Boot will auto-configure and register a `ReactiveElasticsearchClient`
|
||||
bean that targets `http://localhost:9200`.
|
||||
You can further tune how it is configured, as shown in the following example:
|
||||
|
||||
[source,properties,indent=0]
|
||||
----
|
||||
spring.elasticsearch.reactive.endpoints=search.example.com:9200
|
||||
spring.elasticsearch.reactive.use-ssl=true
|
||||
spring.elasticsearch.reactive.socket-timeout=10s
|
||||
spring.elasticsearch.reactive.username=user
|
||||
spring.elasticsearch.reactive.password=secret
|
||||
----
|
||||
|
||||
If the configuration properties are not enough and you'd like to fully control the client
|
||||
configuration, you can register a custom `ClientConfiguration` bean.
|
||||
|
||||
[[boot-features-connecting-to-elasticsearch-jest]]
|
||||
==== Connecting to Elasticsearch using Jest
|
||||
@ -4933,17 +4958,12 @@ To take full control over the registration, define a `JestClient` bean.
|
||||
[[boot-features-connecting-to-elasticsearch-spring-data]]
|
||||
==== Connecting to Elasticsearch by Using Spring Data
|
||||
|
||||
To connect to Elasticsearch, you must provide the address of one or more Elasticsearch
|
||||
instances. The address can be specified by setting the `spring.elasticsearch.rest.uris`
|
||||
property to a comma-separated `host:port` list. With this configuration in place, an
|
||||
`ElasticsearchRestTemplate` or `RestHighLevelClient` can be injected like any other Spring bean,
|
||||
To connect to Elasticsearch, a `RestHighLevelClient` bean must be defined,
|
||||
auto-configured by Spring Boot or manually provided by the application (see previous sections).
|
||||
With this configuration in place, an
|
||||
`ElasticsearchRestTemplate` can be injected like any other Spring bean,
|
||||
as shown in the following example:
|
||||
|
||||
[source,properties,indent=0]
|
||||
----
|
||||
spring.elasticsearch.rest.uris=localhost:9200
|
||||
----
|
||||
|
||||
[source,java,indent=0]
|
||||
----
|
||||
@Component
|
||||
@ -4960,9 +4980,12 @@ as shown in the following example:
|
||||
}
|
||||
----
|
||||
|
||||
If you add your own `ElasticsearchRestTemplate` or `ElasticsearchOperations` `@Bean`,
|
||||
it replaces the default given it is named `"elasticsearchTemplate""`.
|
||||
|
||||
In the presence of `spring-data-elasticsearch` and the required dependencies
|
||||
for using a `WebClient` (typically `spring-boot-starter-webflux`), Spring Boot can also
|
||||
auto-configure a
|
||||
<<boot-features-connecting-to-elasticsearch-reactive-rest,ReactiveElasticsearchClient>>
|
||||
and a `ReactiveElasticsearchTemplate` as beans. They are the reactive equivalent of the
|
||||
other REST clients.
|
||||
|
||||
|
||||
[[boot-features-spring-data-elasticsearch-repositories]]
|
||||
@ -4977,8 +5000,24 @@ now an Elasticsearch `@Document` class rather than a JPA `@Entity`, it works in
|
||||
way.
|
||||
|
||||
TIP: For complete details of Spring Data Elasticsearch, refer to the
|
||||
https://docs.spring.io/spring-data/elasticsearch/docs/[reference documentation].
|
||||
{spring-data-elasticsearch-reference}[reference documentation].
|
||||
|
||||
Spring Boot supports both classic and reactive Elasticsearch repositories, using the
|
||||
`ElasticsearchRestTemplate` or `ReactiveElasticsearchTemplate` beans. Most likely those
|
||||
beans are auto-configured by Spring Boot given the required dependencies are present.
|
||||
|
||||
If you wish to use your own template for backing the Elasticsearch repositories, you can
|
||||
add your own `ElasticsearchRestTemplate` or `ElasticsearchOperations` `@Bean`,
|
||||
as long as it is named `"elasticsearchTemplate"`. Same applies to
|
||||
`ReactiveElasticsearchTemplate` and `ReactiveElasticsearchOperations`, with the bean
|
||||
name `"reactiveElasticsearchTemplate"`.
|
||||
|
||||
You can choose to disable the repositories support with the following property:
|
||||
|
||||
[source,properties,indent=0]
|
||||
----
|
||||
spring.data.elasticsearch.repositories.enabled=false
|
||||
----
|
||||
|
||||
|
||||
[[boot-features-cassandra]]
|
||||
|
Loading…
Reference in New Issue
Block a user