Remove support for deprecated Elasticsearch Jest client

Closes #19676
pull/19711/head
Scott Frederick 5 years ago committed by Brian Clozel
parent b34a311d02
commit c789592e26

@ -62,7 +62,6 @@ dependencies {
optional 'io.micrometer:micrometer-registry-statsd'
optional 'io.micrometer:micrometer-registry-wavefront'
optional 'io.projectreactor.netty:reactor-netty'
optional 'io.searchbox:jest'
optional 'jakarta.jms:jakarta.jms-api'
optional 'jakarta.servlet:jakarta.servlet-api'
optional 'javax.cache:cache-api'

@ -1,59 +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.actuate.autoconfigure.elasticsearch;
import java.util.Map;
import io.searchbox.client.JestClient;
import org.springframework.boot.actuate.autoconfigure.health.CompositeHealthContributorConfiguration;
import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator;
import org.springframework.boot.actuate.elasticsearch.ElasticsearchHealthIndicator;
import org.springframework.boot.actuate.elasticsearch.ElasticsearchJestHealthIndicator;
import org.springframework.boot.actuate.health.HealthContributor;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.elasticsearch.jest.JestAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* {@link EnableAutoConfiguration Auto-configuration} for
* {@link ElasticsearchHealthIndicator} using the {@link JestClient}.
*
* @author Stephane Nicoll
* @since 2.1.0
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(JestClient.class)
@ConditionalOnBean(JestClient.class)
@ConditionalOnEnabledHealthIndicator("elasticsearch")
@AutoConfigureAfter(JestAutoConfiguration.class)
@Deprecated
public class ElasticSearchJestHealthContributorAutoConfiguration
extends CompositeHealthContributorConfiguration<ElasticsearchJestHealthIndicator, JestClient> {
@Bean
@ConditionalOnMissingBean(name = { "elasticsearchHealthIndicator", "elasticsearchHealthContributor" })
public HealthContributor elasticsearchHealthContributor(Map<String, JestClient> clients) {
return createContributor(clients);
}
}

@ -13,7 +13,6 @@ org.springframework.boot.actuate.autoconfigure.context.properties.ConfigurationP
org.springframework.boot.actuate.autoconfigure.context.ShutdownEndpointAutoConfiguration,\
org.springframework.boot.actuate.autoconfigure.couchbase.CouchbaseHealthContributorAutoConfiguration,\
org.springframework.boot.actuate.autoconfigure.couchbase.CouchbaseReactiveHealthContributorAutoConfiguration,\
org.springframework.boot.actuate.autoconfigure.elasticsearch.ElasticSearchJestHealthContributorAutoConfiguration,\
org.springframework.boot.actuate.autoconfigure.elasticsearch.ElasticSearchRestHealthContributorAutoConfiguration,\
org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration,\
org.springframework.boot.actuate.autoconfigure.endpoint.jmx.JmxEndpointAutoConfiguration,\

@ -1,57 +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.actuate.autoconfigure.elasticsearch;
import io.searchbox.client.JestClient;
import org.junit.jupiter.api.Test;
import org.springframework.boot.actuate.autoconfigure.health.HealthContributorAutoConfiguration;
import org.springframework.boot.actuate.elasticsearch.ElasticsearchHealthIndicator;
import org.springframework.boot.actuate.elasticsearch.ElasticsearchJestHealthIndicator;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
/**
* Tests for {@link ElasticSearchJestHealthContributorAutoConfiguration}.
*
* @author Phillip Webb
*/
@Deprecated
class ElasticsearchHealthContributorAutoConfigurationTests {
private ApplicationContextRunner contextRunner = new ApplicationContextRunner().withConfiguration(AutoConfigurations
.of(ElasticSearchJestHealthContributorAutoConfiguration.class, HealthContributorAutoConfiguration.class));
@Test
void runWhenUsingJestClientShouldCreateIndicator() {
this.contextRunner.withBean(JestClient.class, () -> mock(JestClient.class))
.withSystemProperties("es.set.netty.runtime.available.processors=false")
.run((context) -> assertThat(context).hasSingleBean(ElasticsearchJestHealthIndicator.class)
.doesNotHaveBean(ElasticsearchHealthIndicator.class));
}
@Test
void runWhenDisabledShouldNotCreateIndicator() {
this.contextRunner.withPropertyValues("management.health.elasticsearch.enabled:false")
.run((context) -> assertThat(context).doesNotHaveBean(ElasticsearchHealthIndicator.class)
.doesNotHaveBean(ElasticsearchJestHealthIndicator.class));
}
}

@ -80,12 +80,10 @@ class WebEndpointsAutoConfigurationIntegrationTests {
Neo4jRepositoriesAutoConfiguration.class, MongoAutoConfiguration.class, MongoDataAutoConfiguration.class,
MongoReactiveAutoConfiguration.class, MongoReactiveDataAutoConfiguration.class,
RepositoryRestMvcAutoConfiguration.class, HazelcastAutoConfiguration.class,
ElasticsearchDataAutoConfiguration.class,
org.springframework.boot.autoconfigure.elasticsearch.jest.JestAutoConfiguration.class,
SolrRepositoriesAutoConfiguration.class, SolrAutoConfiguration.class, RedisAutoConfiguration.class,
RedisRepositoriesAutoConfiguration.class, MetricsAutoConfiguration.class })
ElasticsearchDataAutoConfiguration.class, SolrRepositoriesAutoConfiguration.class,
SolrAutoConfiguration.class, RedisAutoConfiguration.class, RedisRepositoriesAutoConfiguration.class,
MetricsAutoConfiguration.class })
@SpringBootConfiguration
@SuppressWarnings("deprecation")
static class WebEndpointTestApplication {
}

@ -24,7 +24,6 @@ dependencies {
optional 'io.micrometer:micrometer-registry-prometheus'
optional 'io.prometheus:simpleclient_pushgateway'
optional 'io.reactivex:rxjava-reactive-streams'
optional 'io.searchbox:jest'
optional 'org.elasticsearch.client:elasticsearch-rest-client'
optional ('io.undertow:undertow-servlet') {
exclude group: 'org.jboss.spec.javax.annotation', module: 'jboss-annotations-api_1.2_spec'

@ -1,69 +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.actuate.elasticsearch;
import java.util.Map;
import io.searchbox.client.JestClient;
import io.searchbox.client.JestResult;
import org.springframework.boot.actuate.health.AbstractHealthIndicator;
import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.boot.json.JsonParser;
import org.springframework.boot.json.JsonParserFactory;
/**
* {@link HealthIndicator} for Elasticsearch using a {@link JestClient}.
*
* @author Stephane Nicoll
* @author Julian Devia Serna
* @author Brian Clozel
* @since 2.0.0
*/
public class ElasticsearchJestHealthIndicator extends AbstractHealthIndicator {
private final JestClient jestClient;
private final JsonParser jsonParser = JsonParserFactory.getJsonParser();
public ElasticsearchJestHealthIndicator(JestClient jestClient) {
super("Elasticsearch health check failed");
this.jestClient = jestClient;
}
@Override
protected void doHealthCheck(Health.Builder builder) throws Exception {
JestResult healthResult = this.jestClient.execute(new io.searchbox.cluster.Health.Builder().build());
if (healthResult.getResponseCode() != 200 || !healthResult.isSucceeded()) {
builder.down();
builder.withDetail("statusCode", healthResult.getResponseCode());
}
else {
Map<String, Object> response = this.jsonParser.parseMap(healthResult.getJsonString());
String status = (String) response.get("status");
if (status.equals(io.searchbox.cluster.Health.Status.RED.getKey())) {
builder.outOfService();
}
else {
builder.up();
}
builder.withDetails(response);
}
}
}

@ -1,141 +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.actuate.elasticsearch;
import java.io.IOException;
import java.util.Map;
import com.google.gson.Gson;
import com.google.gson.JsonParser;
import io.searchbox.action.Action;
import io.searchbox.client.JestClient;
import io.searchbox.client.JestResult;
import io.searchbox.client.config.exception.CouldNotConnectException;
import io.searchbox.core.SearchResult;
import org.junit.jupiter.api.Test;
import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.Status;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.entry;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
/**
* Tests for {@link ElasticsearchJestHealthIndicator}.
*
* @author Stephane Nicoll
* @author Julian Devia Serna
* @author Brian Clozel
*/
class ElasticsearchJestHealthIndicatorTests {
private final JestClient jestClient = mock(JestClient.class);
private final ElasticsearchJestHealthIndicator healthIndicator = new ElasticsearchJestHealthIndicator(
this.jestClient);
@SuppressWarnings("unchecked")
@Test
void elasticsearchIsUp() throws IOException {
given(this.jestClient.execute(any(Action.class))).willReturn(createJestResult(200, true, "green"));
Health health = this.healthIndicator.health();
assertThat(health.getStatus()).isEqualTo(Status.UP);
assertHealthDetailsWithStatus(health.getDetails(), "green");
}
@Test
@SuppressWarnings("unchecked")
void elasticsearchWithYellowStatusIsUp() throws IOException {
given(this.jestClient.execute(any(Action.class))).willReturn(createJestResult(200, true, "yellow"));
Health health = this.healthIndicator.health();
assertThat(health.getStatus()).isEqualTo(Status.UP);
assertHealthDetailsWithStatus(health.getDetails(), "yellow");
}
@SuppressWarnings("unchecked")
@Test
void elasticsearchIsDown() throws IOException {
given(this.jestClient.execute(any(Action.class)))
.willThrow(new CouldNotConnectException("http://localhost:9200", new IOException()));
Health health = this.healthIndicator.health();
assertThat(health.getStatus()).isEqualTo(Status.DOWN);
}
@SuppressWarnings("unchecked")
@Test
void elasticsearchIsDownWhenQueryDidNotSucceed() throws IOException {
given(this.jestClient.execute(any(Action.class))).willReturn(createJestResult(200, false, ""));
Health health = this.healthIndicator.health();
assertThat(health.getStatus()).isEqualTo(Status.DOWN);
}
@SuppressWarnings("unchecked")
@Test
void elasticsearchIsDownByResponseCode() throws IOException {
given(this.jestClient.execute(any(Action.class))).willReturn(createJestResult(500, false, ""));
Health health = this.healthIndicator.health();
assertThat(health.getStatus()).isEqualTo(Status.DOWN);
assertThat(health.getDetails()).contains(entry("statusCode", 500));
}
@SuppressWarnings("unchecked")
@Test
void elasticsearchIsOutOfServiceByStatus() throws IOException {
given(this.jestClient.execute(any(Action.class))).willReturn(createJestResult(200, true, "red"));
Health health = this.healthIndicator.health();
assertThat(health.getStatus()).isEqualTo(Status.OUT_OF_SERVICE);
assertHealthDetailsWithStatus(health.getDetails(), "red");
}
private void assertHealthDetailsWithStatus(Map<String, Object> details, String status) {
assertThat(details).contains(entry("cluster_name", "elasticsearch"), entry("status", status),
entry("timed_out", false), entry("number_of_nodes", 1), entry("number_of_data_nodes", 1),
entry("active_primary_shards", 0), entry("active_shards", 0), entry("relocating_shards", 0),
entry("initializing_shards", 0), entry("unassigned_shards", 0), entry("delayed_unassigned_shards", 0),
entry("number_of_pending_tasks", 0), entry("number_of_in_flight_fetch", 0),
entry("task_max_waiting_in_queue_millis", 0), entry("active_shards_percent_as_number", 100.0));
}
private static JestResult createJestResult(int responseCode, boolean succeeded, String status) {
SearchResult searchResult = new SearchResult(new Gson());
String json;
if (responseCode == 200) {
json = String.format(
"{\"cluster_name\":\"elasticsearch\","
+ "\"status\":\"%s\",\"timed_out\":false,\"number_of_nodes\":1,"
+ "\"number_of_data_nodes\":1,\"active_primary_shards\":0,"
+ "\"active_shards\":0,\"relocating_shards\":0,\"initializing_shards\":0,"
+ "\"unassigned_shards\":0,\"delayed_unassigned_shards\":0,"
+ "\"number_of_pending_tasks\":0,\"number_of_in_flight_fetch\":0,"
+ "\"task_max_waiting_in_queue_millis\":0,\"active_shards_percent_as_number\":100.0}",
status);
}
else {
json = "{\n \"error\": \"Server Error\",\n \"status\": \"" + status + "\"\n}";
}
searchResult.setJsonString(json);
searchResult.setJsonObject(JsonParser.parseString(json).getAsJsonObject());
searchResult.setResponseCode(responseCode);
searchResult.setSucceeded(succeeded);
return searchResult;
}
}

@ -34,7 +34,6 @@ dependencies {
optional 'de.flapdoodle.embed:de.flapdoodle.embed.mongo'
optional 'io.lettuce:lettuce-core'
optional 'io.projectreactor.netty:reactor-netty'
optional 'io.searchbox:jest'
optional 'io.rsocket:rsocket-core'
optional 'io.rsocket:rsocket-transport-netty'
optional ('io.undertow:undertow-servlet') {

@ -1,39 +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.elasticsearch.jest;
import io.searchbox.client.config.HttpClientConfig;
import io.searchbox.client.config.HttpClientConfig.Builder;
/**
* Callback interface that can be implemented by beans wishing to further customize the
* {@link HttpClientConfig} via a {@link Builder HttpClientConfig.Builder} whilst
* retaining default auto-configuration.
*
* @author Stephane Nicoll
* @since 1.5.0
*/
@FunctionalInterface
public interface HttpClientConfigBuilderCustomizer {
/**
* Customize the {@link Builder}.
* @param builder the builder to customize
*/
void customize(Builder builder);
}

@ -1,82 +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.elasticsearch.jest;
import java.time.Duration;
import com.google.gson.Gson;
import io.searchbox.client.JestClient;
import io.searchbox.client.JestClientFactory;
import io.searchbox.client.config.HttpClientConfig;
import org.apache.http.HttpHost;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
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.elasticsearch.jest.JestProperties.Proxy;
import org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration;
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.util.Assert;
/**
* {@link EnableAutoConfiguration Auto-configuration} for Jest.
*
* @author Stephane Nicoll
* @since 1.4.0
* @deprecated since 2.2.0 in favor of other auto-configured Elasticsearch clients
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(JestClient.class)
@EnableConfigurationProperties(JestProperties.class)
@AutoConfigureAfter(GsonAutoConfiguration.class)
@Deprecated
public class JestAutoConfiguration {
@Bean(destroyMethod = "shutdownClient")
@ConditionalOnMissingBean
public JestClient jestClient(JestProperties properties, ObjectProvider<Gson> gson,
ObjectProvider<HttpClientConfigBuilderCustomizer> builderCustomizers) {
JestClientFactory factory = new JestClientFactory();
factory.setHttpClientConfig(createHttpClientConfig(properties, gson, builderCustomizers));
return factory.getObject();
}
protected HttpClientConfig createHttpClientConfig(JestProperties properties, ObjectProvider<Gson> gson,
ObjectProvider<HttpClientConfigBuilderCustomizer> builderCustomizers) {
HttpClientConfig.Builder builder = new HttpClientConfig.Builder(properties.getUris());
PropertyMapper map = PropertyMapper.get();
map.from(properties::getUsername).whenHasText()
.to((username) -> builder.defaultCredentials(username, properties.getPassword()));
Proxy proxy = properties.getProxy();
map.from(proxy::getHost).whenHasText().to((host) -> {
Assert.notNull(proxy.getPort(), "Proxy port must not be null");
builder.proxy(new HttpHost(host, proxy.getPort()));
});
map.from(gson::getIfUnique).whenNonNull().to(builder::gson);
map.from(properties::isMultiThreaded).to(builder::multiThreaded);
map.from(properties::getConnectionTimeout).whenNonNull().asInt(Duration::toMillis).to(builder::connTimeout);
map.from(properties::getReadTimeout).whenNonNull().asInt(Duration::toMillis).to(builder::readTimeout);
builderCustomizers.orderedStream().forEach((customizer) -> customizer.customize(builder));
return builder.build();
}
}

@ -1,152 +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.elasticsearch.jest;
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 Jest.
*
* @author Stephane Nicoll
* @since 1.4.0
*/
@ConfigurationProperties(prefix = "spring.elasticsearch.jest")
public class JestProperties {
/**
* Comma-separated list of the Elasticsearch instances to use.
*/
private List<String> uris = new ArrayList<>(Collections.singletonList("http://localhost:9200"));
/**
* Login username.
*/
private String username;
/**
* Login password.
*/
private String password;
/**
* Whether to enable connection requests from multiple execution threads.
*/
private boolean multiThreaded = true;
/**
* Connection timeout.
*/
private Duration connectionTimeout = Duration.ofSeconds(3);
/**
* Read timeout.
*/
private Duration readTimeout = Duration.ofSeconds(3);
/**
* Proxy settings.
*/
private final Proxy proxy = new Proxy();
public List<String> getUris() {
return this.uris;
}
public void setUris(List<String> uris) {
this.uris = uris;
}
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 boolean isMultiThreaded() {
return this.multiThreaded;
}
public void setMultiThreaded(boolean multiThreaded) {
this.multiThreaded = multiThreaded;
}
public Duration getConnectionTimeout() {
return this.connectionTimeout;
}
public void setConnectionTimeout(Duration connectionTimeout) {
this.connectionTimeout = connectionTimeout;
}
public Duration getReadTimeout() {
return this.readTimeout;
}
public void setReadTimeout(Duration readTimeout) {
this.readTimeout = readTimeout;
}
public Proxy getProxy() {
return this.proxy;
}
public static class Proxy {
/**
* Proxy host the HTTP client should use.
*/
private String host;
/**
* Proxy port the HTTP client should use.
*/
private Integer port;
public String getHost() {
return this.host;
}
public void setHost(String host) {
this.host = host;
}
public Integer getPort() {
return this.port;
}
public void setPort(Integer port) {
this.port = port;
}
}
}

@ -1,20 +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.
*/
/**
* Auto-configuration for Jest.
*/
package org.springframework.boot.autoconfigure.elasticsearch.jest;

@ -428,15 +428,6 @@
"description": "Whether to enable Solr repositories.",
"defaultValue": true
},
{
"name": "spring.elasticsearch.jest.uris",
"defaultValue": [
"http://localhost:9200"
],
"deprecation": {
"reason": "The Jest client support is deprecated. Use other supported clients instead."
}
},
{
"name": "spring.elasticsearch.rest.uris",
"defaultValue": [

@ -58,7 +58,6 @@ org.springframework.boot.autoconfigure.data.redis.RedisReactiveAutoConfiguration
org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.rest.RepositoryRestMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration,\
org.springframework.boot.autoconfigure.elasticsearch.jest.JestAutoConfiguration,\
org.springframework.boot.autoconfigure.elasticsearch.rest.RestClientAutoConfiguration,\
org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,\
org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration,\

@ -1,173 +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.elasticsearch.jest;
import java.io.IOException;
import java.time.Duration;
import java.util.HashMap;
import java.util.Map;
import com.google.gson.Gson;
import io.searchbox.action.Action;
import io.searchbox.client.JestClient;
import io.searchbox.client.JestResult;
import io.searchbox.client.http.JestHttpClient;
import io.searchbox.core.Get;
import io.searchbox.core.Index;
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.beans.factory.BeanCreationException;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
/**
* Tests for {@link JestAutoConfiguration}.
*
* @author Stephane Nicoll
* @author Andy Wilkinson
*/
@Deprecated
@Testcontainers(disabledWithoutDocker = true)
class JestAutoConfigurationTests {
@Container
static final ElasticsearchContainer elasticsearch = new ElasticsearchContainer().withStartupAttempts(5)
.withStartupTimeout(Duration.ofMinutes(10));
private ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(GsonAutoConfiguration.class, JestAutoConfiguration.class));
@Test
void jestClientOnLocalhostByDefault() {
this.contextRunner.run((context) -> assertThat(context).hasSingleBean(JestClient.class));
}
@Test
void customJestClient() {
this.contextRunner.withUserConfiguration(CustomJestClient.class)
.withPropertyValues("spring.elasticsearch.jest.uris[0]=http://localhost:9200")
.run((context) -> assertThat(context).hasSingleBean(JestClient.class));
}
@Test
void customGson() {
this.contextRunner.withUserConfiguration(CustomGson.class)
.withPropertyValues("spring.elasticsearch.jest.uris=http://localhost:9200").run((context) -> {
JestHttpClient client = (JestHttpClient) context.getBean(JestClient.class);
assertThat(client.getGson()).isSameAs(context.getBean("customGson"));
});
}
@Test
void customizerOverridesAutoConfig() {
this.contextRunner.withUserConfiguration(BuilderCustomizer.class)
.withPropertyValues("spring.elasticsearch.jest.uris=http://localhost:9200").run((context) -> {
JestHttpClient client = (JestHttpClient) context.getBean(JestClient.class);
assertThat(client.getGson()).isSameAs(context.getBean(BuilderCustomizer.class).getGson());
});
}
@Test
void proxyHostWithoutPort() {
this.contextRunner
.withPropertyValues("spring.elasticsearch.jest.uris=http://localhost:9200",
"spring.elasticsearch.jest.proxy.host=proxy.example.com")
.run((context) -> assertThat(context.getStartupFailure()).isInstanceOf(BeanCreationException.class)
.hasMessageContaining("Proxy port must not be null"));
}
@Test
void jestCanCommunicateWithElasticsearchInstance() {
this.contextRunner
.withPropertyValues("spring.elasticsearch.jest.uris=http://" + elasticsearch.getHttpHostAddress())
.run((context) -> {
JestClient client = context.getBean(JestClient.class);
Map<String, String> source = new HashMap<>();
source.put("a", "alpha");
source.put("b", "bravo");
Index index = new Index.Builder(source).index("foo").type("bar").id("1").build();
execute(client, index);
Get getRequest = new Get.Builder("foo", "1").build();
assertThat(execute(client, getRequest).getResponseCode()).isEqualTo(200);
});
}
private JestResult execute(JestClient client, Action<? extends JestResult> action) {
for (int i = 0; i < 2; i++) {
try {
return client.execute(action);
}
catch (IOException ex) {
// Continue
}
}
try {
return client.execute(action);
}
catch (IOException ex) {
throw new RuntimeException(ex);
}
}
@Configuration(proxyBeanMethods = false)
static class CustomJestClient {
@Bean
JestClient customJestClient() {
return mock(JestClient.class);
}
}
@Configuration(proxyBeanMethods = false)
static class CustomGson {
@Bean
Gson customGson() {
return new Gson();
}
}
@Configuration(proxyBeanMethods = false)
@Import(CustomGson.class)
static class BuilderCustomizer {
private final Gson gson = new Gson();
@Bean
HttpClientConfigBuilderCustomizer customizer() {
return (builder) -> builder.gson(BuilderCustomizer.this.gson);
}
Gson getGson() {
return this.gson;
}
}
}

@ -868,13 +868,6 @@ bom {
]
}
}
library('Jest', '6.3.1') {
group('io.searchbox') {
modules = [
'jest'
]
}
}
library('Jetty EL', '8.5.40') {
group('org.mortbay.jasper') {
modules = [

@ -4146,9 +4146,6 @@ Spring Boot supports several clients:
Spring Boot provides a dedicated "`Starter`", `spring-boot-starter-data-elasticsearch`.
The https://github.com/searchbox-io/Jest[Jest] client has been deprecated, 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
@ -4192,33 +4189,6 @@ You can further tune how it is configured, as shown in the following example:
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
Now that Spring Boot supports the official `RestHighLevelClient`, Jest support is deprecated.
If you have `Jest` on the classpath, you can inject an auto-configured `JestClient` that by default targets `http://localhost:9200`.
You can further tune how the client is configured, as shown in the following example:
[source,properties,indent=0,configprops]
----
spring.elasticsearch.jest.uris=https://search.example.com:9200
spring.elasticsearch.jest.read-timeout=10000
spring.elasticsearch.jest.username=user
spring.elasticsearch.jest.password=secret
----
You can also register an arbitrary number of beans that implement `HttpClientConfigBuilderCustomizer` for more advanced customizations.
The following example tunes additional HTTP settings:
[source,java,indent=0]
----
include::{code-examples}/elasticsearch/jest/JestClientCustomizationExample.java[tag=customizer]
----
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, a `RestHighLevelClient` bean must be defined,

@ -1,46 +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.docs.elasticsearch.jest;
import io.searchbox.client.config.HttpClientConfig;
import org.springframework.boot.autoconfigure.elasticsearch.jest.HttpClientConfigBuilderCustomizer;
/**
* Example configuration for using a {@link HttpClientConfigBuilderCustomizer} to
* configure additional HTTP settings.
*
* @author Stephane Nicoll
*/
public class JestClientCustomizationExample {
/**
* A {@link HttpClientConfigBuilderCustomizer} that applies additional HTTP settings
* to the auto-configured jest client.
*/
// tag::customizer[]
static class HttpSettingsCustomizer implements HttpClientConfigBuilderCustomizer {
@Override
public void customize(HttpClientConfig.Builder builder) {
builder.maxTotalConnection(100).defaultMaxTotalConnectionPerRoute(5);
}
}
// end::customizer[]
}
Loading…
Cancel
Save