Remove support for Elasticsearch transport client

The Elasticsearch transport client has been deprecated since Spring Boot
2.2.0 and is about to be removed from Spring Data Elasticsearch and
Elasticsearch itself in their next major releases.

The available REST client support variants are now the preferred way of
using Elasticsearch features.

Closes gh-19668
This commit is contained in:
Brian Clozel
2020-01-13 15:36:47 +01:00
parent 648e468c86
commit b780e5247c
21 changed files with 37 additions and 543 deletions

View File

@@ -1,70 +0,0 @@
/*
* 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.Properties;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.transport.TransportClient;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.elasticsearch.client.TransportClientFactoryBean;
/**
* {@link org.springframework.boot.autoconfigure.EnableAutoConfiguration
* Auto-configuration} for Elasticsearch.
*
* @author Artur Konczak
* @author Mohsin Husen
* @author Andy Wilkinson
* @since 1.1.0
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ Client.class, TransportClientFactoryBean.class })
@ConditionalOnProperty(prefix = "spring.data.elasticsearch", name = "cluster-nodes", matchIfMissing = false)
@EnableConfigurationProperties(ElasticsearchProperties.class)
public class ElasticsearchAutoConfiguration {
private final ElasticsearchProperties properties;
public ElasticsearchAutoConfiguration(ElasticsearchProperties properties) {
this.properties = properties;
}
@Bean
@ConditionalOnMissingBean
public TransportClient elasticsearchClient() throws Exception {
TransportClientFactoryBean factory = new TransportClientFactoryBean();
factory.setClusterNodes(this.properties.getClusterNodes());
factory.setProperties(createProperties());
factory.afterPropertiesSet();
return factory.getObject();
}
private Properties createProperties() {
Properties properties = new Properties();
properties.put("cluster.name", this.properties.getClusterName());
properties.putAll(this.properties.getProperties());
return properties;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-2020 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.
@@ -29,9 +29,6 @@ import org.springframework.data.elasticsearch.repository.config.EnableReactiveEl
/**
* {@link EnableAutoConfiguration Auto-configuration} for Spring Data's Elasticsearch
* support.
* <p>
* 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
@@ -42,10 +39,8 @@ import org.springframework.data.elasticsearch.repository.config.EnableReactiveEl
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ ElasticsearchTemplate.class })
@AutoConfigureAfter({ ElasticsearchAutoConfiguration.class, RestClientAutoConfiguration.class,
ReactiveRestClientAutoConfiguration.class })
@AutoConfigureAfter({ RestClientAutoConfiguration.class, ReactiveRestClientAutoConfiguration.class })
@Import({ ElasticsearchDataConfiguration.BaseConfiguration.class,
ElasticsearchDataConfiguration.TransportClientConfiguration.class,
ElasticsearchDataConfiguration.RestClientConfiguration.class,
ElasticsearchDataConfiguration.ReactiveRestClientConfiguration.class })
public class ElasticsearchDataAutoConfiguration {

View File

@@ -18,7 +18,6 @@ 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;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
@@ -29,7 +28,6 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient;
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.ReactiveElasticsearchOperations;
import org.springframework.data.elasticsearch.core.ReactiveElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
@@ -78,25 +76,6 @@ abstract class ElasticsearchDataConfiguration {
}
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(Client.class)
static class TransportClientConfiguration {
@Bean
@ConditionalOnMissingBean(value = ElasticsearchOperations.class, name = "elasticsearchTemplate")
@ConditionalOnBean(Client.class)
@Deprecated
ElasticsearchTemplate elasticsearchTemplate(Client client, ElasticsearchConverter converter) {
try {
return new ElasticsearchTemplate(client, converter);
}
catch (Exception ex) {
throw new IllegalStateException(ex);
}
}
}
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ WebClient.class, ReactiveElasticsearchOperations.class })
static class ReactiveRestClientConfiguration {

View File

@@ -1,73 +0,0 @@
/*
* 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.springframework.boot.context.properties.ConfigurationProperties;
/**
* Configuration properties for Elasticsearch.
*
* @author Artur Konczak
* @author Mohsin Husen
* @since 1.1.0
*/
@ConfigurationProperties(prefix = "spring.data.elasticsearch")
public class ElasticsearchProperties {
/**
* Elasticsearch cluster name.
*/
private String clusterName = "elasticsearch";
/**
* Comma-separated list of cluster node addresses.
*/
private String clusterNodes;
/**
* Additional properties used to configure the client.
*/
private Map<String, String> properties = new HashMap<>();
public String getClusterName() {
return this.clusterName;
}
public void setClusterName(String clusterName) {
this.clusterName = clusterName;
}
public String getClusterNodes() {
return this.clusterNodes;
}
public void setClusterNodes(String clusterNodes) {
this.clusterNodes = clusterNodes;
}
public Map<String, String> getProperties() {
return this.properties;
}
public void setProperties(Map<String, String> properties) {
this.properties = properties;
}
}

View File

@@ -348,30 +348,6 @@
"level": "error"
}
},
{
"name": "spring.data.elasticsearch.cluster-name",
"type": "java.lang.String",
"description": "Elasticsearch cluster name.",
"deprecation": {
"reason": "The transport client support is deprecated. Use other supported clients instead."
}
},
{
"name": "spring.data.elasticsearch.cluster-nodes",
"type": "java.lang.String",
"description": "Comma-separated list of cluster node addresses.",
"deprecation": {
"reason": "The transport client support is deprecated. Use other supported clients instead."
}
},
{
"name": "spring.data.elasticsearch.properties",
"type": "java.util.Map<java.lang.String,java.lang.String>",
"description": "Additional properties used to configure the client.",
"deprecation": {
"reason": "The transport client support is deprecated. Use other supported clients instead."
}
},
{
"name": "spring.data.elasticsearch.repositories.enabled",
"type": "java.lang.Boolean",

View File

@@ -39,7 +39,6 @@ org.springframework.boot.autoconfigure.data.couchbase.CouchbaseDataAutoConfigura
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseRepositoriesAutoConfiguration,\
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,\

View File

@@ -1,102 +0,0 @@
/*
* Copyright 2012-2020 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.List;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.cluster.node.DiscoveryNode;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.testcontainers.elasticsearch.ElasticsearchContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.test.util.TestPropertyValues;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
/**
* Tests for {@link ElasticsearchAutoConfiguration}.
*
* @author Phillip Webb
* @author Andy Wilkinson
*/
@Testcontainers(disabledWithoutDocker = true)
class ElasticsearchAutoConfigurationTests {
@Container
public static ElasticsearchContainer elasticsearch = new VersionOverridingElasticsearchContainer()
.withStartupAttempts(5).withStartupTimeout(Duration.ofMinutes(10));
private AnnotationConfigApplicationContext context;
@BeforeEach
void setUp() {
System.setProperty("es.set.netty.runtime.available.processors", "false");
}
@AfterEach
void close() {
if (this.context != null) {
this.context.close();
}
System.clearProperty("es.set.netty.runtime.available.processors");
}
@Test
void useExistingClient() {
this.context = new AnnotationConfigApplicationContext();
this.context.register(CustomConfiguration.class, PropertyPlaceholderAutoConfiguration.class,
ElasticsearchAutoConfiguration.class);
this.context.refresh();
assertThat(this.context.getBeanNamesForType(Client.class)).hasSize(1);
assertThat(this.context.getBean("myClient")).isSameAs(this.context.getBean(Client.class));
}
@Test
@SuppressWarnings("deprecation")
void createTransportClient() {
this.context = new AnnotationConfigApplicationContext();
TestPropertyValues
.of("spring.data.elasticsearch.cluster-nodes:" + elasticsearch.getTcpHost().getHostString() + ":"
+ elasticsearch.getTcpHost().getPort(), "spring.data.elasticsearch.cluster-name:docker-cluster")
.applyTo(this.context);
this.context.register(PropertyPlaceholderAutoConfiguration.class, ElasticsearchAutoConfiguration.class);
this.context.refresh();
List<DiscoveryNode> connectedNodes = this.context.getBean(TransportClient.class).connectedNodes();
assertThat(connectedNodes).hasSize(1);
}
@Configuration(proxyBeanMethods = false)
static class CustomConfiguration {
@Bean
Client myClient() {
return mock(Client.class);
}
}
}

View File

@@ -16,14 +16,9 @@
package org.springframework.boot.autoconfigure.data.elasticsearch;
import java.time.Duration;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.testcontainers.elasticsearch.ElasticsearchContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.autoconfigure.elasticsearch.rest.RestClientAutoConfiguration;
@@ -31,10 +26,8 @@ import org.springframework.boot.test.context.runner.ApplicationContextRunner;
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.ReactiveElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
@@ -48,15 +41,10 @@ import static org.mockito.Mockito.mock;
* @author Peter-Josef Meisch
* @author Scott Frederick
*/
@Testcontainers(disabledWithoutDocker = true)
class ElasticsearchDataAutoConfigurationTests {
@Container
static ElasticsearchContainer elasticsearch = new VersionOverridingElasticsearchContainer().withStartupAttempts(5)
.withStartupTimeout(Duration.ofMinutes(10));
private ApplicationContextRunner contextRunner = new ApplicationContextRunner().withConfiguration(
AutoConfigurations.of(ElasticsearchAutoConfiguration.class, RestClientAutoConfiguration.class,
private ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(RestClientAutoConfiguration.class,
ReactiveRestClientAutoConfiguration.class, ElasticsearchDataAutoConfiguration.class));
@BeforeEach
@@ -69,25 +57,6 @@ class ElasticsearchDataAutoConfigurationTests {
System.clearProperty("es.set.netty.runtime.available.processors");
}
@Test
@SuppressWarnings("deprecation")
void defaultTransportBeansAreRegistered() {
this.contextRunner
.withPropertyValues(
"spring.data.elasticsearch.cluster-nodes:" + elasticsearch.getTcpHost().getHostString() + ":"
+ elasticsearch.getTcpHost().getPort(),
"spring.data.elasticsearch.cluster-name:docker-cluster")
.run((context) -> assertThat(context).hasSingleBean(ElasticsearchTemplate.class)
.hasSingleBean(SimpleElasticsearchMappingContext.class)
.hasSingleBean(ElasticsearchConverter.class));
}
@Test
@SuppressWarnings("deprecation")
void defaultTransportBeansNotRegisteredIfNoTransportClient() {
this.contextRunner.run((context) -> assertThat(context).doesNotHaveBean(ElasticsearchTemplate.class));
}
@Test
void defaultRestBeansRegistered() {
this.contextRunner.run((context) -> assertThat(context).hasSingleBean(ElasticsearchRestTemplate.class)
@@ -95,13 +64,6 @@ class ElasticsearchDataAutoConfigurationTests {
.hasSingleBean(ElasticsearchConverter.class));
}
@Test
@SuppressWarnings("deprecation")
void customTransportTemplateShouldBeUsed() {
this.contextRunner.withUserConfiguration(CustomTransportTemplate.class).run((context) -> assertThat(context)
.getBeanNames(ElasticsearchTemplate.class).hasSize(1).contains("elasticsearchTemplate"));
}
@Test
void customRestTemplateShouldBeUsed() {
this.contextRunner.withUserConfiguration(CustomRestTemplate.class).run((context) -> assertThat(context)
@@ -115,17 +77,6 @@ class ElasticsearchDataAutoConfigurationTests {
.contains("reactiveElasticsearchTemplate"));
}
@Configuration(proxyBeanMethods = false)
static class CustomTransportTemplate {
@Bean
@SuppressWarnings("deprecation")
ElasticsearchTemplate elasticsearchTemplate() {
return mock(ElasticsearchTemplate.class);
}
}
@Configuration(proxyBeanMethods = false)
static class CustomRestTemplate {

View File

@@ -52,9 +52,8 @@ class ElasticsearchRepositoriesAutoConfigurationTests {
.withStartupAttempts(5).withStartupTimeout(Duration.ofMinutes(10));
private ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withConfiguration(
AutoConfigurations.of(ElasticsearchAutoConfiguration.class, RestClientAutoConfiguration.class,
ElasticsearchRepositoriesAutoConfiguration.class, ElasticsearchDataAutoConfiguration.class))
.withConfiguration(AutoConfigurations.of(RestClientAutoConfiguration.class,
ElasticsearchRepositoriesAutoConfiguration.class, ElasticsearchDataAutoConfiguration.class))
.withPropertyValues("spring.elasticsearch.rest.uris=" + elasticsearch.getHttpHostAddress());
@Test