DATAES-488 - Polishing.
Convert spaces to tabs for pom.xml. Switch reactive dependencies to optional. Remove unused commonscollections property. Use managed versions for reactor and Spring dependencies. Introduce WebClientProvider to avoid reinstantiation of WebClient instances. Introduce ClientConfiguration to encapsulate common Elasticsearch client configuration properties. Split ElasticsearchClients into RestClients and ReactiveRestClients to avoid mandatory dependency on WebFlux/Project Reactor. Adapt tests and code referring to WebClient creation. Extract response body as byte array instead of Flux of DataBuffer to avoid chunking and to parse an entire response. Encapsulate hostAndPort string used across configuration/HostProvider with InetSocketAddress. Add parser for InetSocketAddress. Original Pull Request: #226
This commit is contained in:
committed by
Christoph Strobl
parent
691a8c57bc
commit
390d7e8273
@@ -13,7 +13,6 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.elasticsearch;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
@@ -22,12 +21,15 @@ import org.elasticsearch.ElasticsearchStatusException;
|
||||
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
|
||||
import org.elasticsearch.client.RequestOptions;
|
||||
import org.elasticsearch.client.RestHighLevelClient;
|
||||
import org.springframework.data.elasticsearch.client.ElasticsearchClients;
|
||||
import org.springframework.data.elasticsearch.client.ClientConfiguration;
|
||||
import org.springframework.data.elasticsearch.client.RestClients;
|
||||
import org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient;
|
||||
import org.springframework.data.elasticsearch.client.reactive.ReactiveRestClients;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
* @author Christoph Strobl
|
||||
* @author Mark Paluch
|
||||
* @currentRead Fool's Fate - Robin Hobb
|
||||
*/
|
||||
public final class TestUtils {
|
||||
@@ -35,11 +37,11 @@ public final class TestUtils {
|
||||
private TestUtils() {}
|
||||
|
||||
public static RestHighLevelClient restHighLevelClient() {
|
||||
return ElasticsearchClients.createClient().connectedToLocalhost().rest();
|
||||
return RestClients.create(ClientConfiguration.create("localhost:9200")).rest();
|
||||
}
|
||||
|
||||
public static ReactiveElasticsearchClient reactiveClient() {
|
||||
return ElasticsearchClients.createClient().connectedToLocalhost().reactive();
|
||||
return ReactiveRestClients.create(ClientConfiguration.create("localhost:9200"));
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright 2018 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
|
||||
*
|
||||
* http://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.data.elasticsearch.client;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link ClientConfiguration}.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
public class ClientConfigurationUnitTests {
|
||||
|
||||
@Test // DATAES-488
|
||||
public void shouldCreateSimpleConfiguration() {
|
||||
|
||||
ClientConfiguration clientConfiguration = ClientConfiguration.create("localhost:9200");
|
||||
|
||||
assertThat(clientConfiguration.getEndpoints()).containsOnly(InetSocketAddress.createUnresolved("localhost", 9200));
|
||||
}
|
||||
|
||||
@Test // DATAES-488
|
||||
public void shouldCreateCustomizedConfiguration() {
|
||||
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.set("foo", "bar");
|
||||
|
||||
ClientConfiguration clientConfiguration = ClientConfiguration.builder() //
|
||||
.connectedTo("foo", "bar") //
|
||||
.usingSsl() //
|
||||
.withDefaultHeaders(headers) //
|
||||
.build();
|
||||
|
||||
assertThat(clientConfiguration.getEndpoints()).containsOnly(InetSocketAddress.createUnresolved("foo", 9200),
|
||||
InetSocketAddress.createUnresolved("bar", 9200));
|
||||
assertThat(clientConfiguration.useSsl()).isTrue();
|
||||
assertThat(clientConfiguration.getDefaultHeaders().get("foo")).containsOnly("bar");
|
||||
}
|
||||
|
||||
@Test // DATAES-488
|
||||
public void shouldCreateSslConfiguration() {
|
||||
|
||||
SSLContext sslContext = mock(SSLContext.class);
|
||||
|
||||
ClientConfiguration clientConfiguration = ClientConfiguration.builder() //
|
||||
.connectedTo("foo", "bar") //
|
||||
.usingSsl(sslContext) //
|
||||
.build();
|
||||
|
||||
assertThat(clientConfiguration.getEndpoints()).containsOnly(InetSocketAddress.createUnresolved("foo", 9200),
|
||||
InetSocketAddress.createUnresolved("bar", 9200));
|
||||
assertThat(clientConfiguration.useSsl()).isTrue();
|
||||
assertThat(clientConfiguration.getSslContext()).contains(sslContext);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Copyright 2018 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
|
||||
*
|
||||
* http://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.data.elasticsearch.client;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link InetSocketAddressParser}.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
public class InetSocketAddressParserUnitTests {
|
||||
|
||||
@Test
|
||||
public void testFromStringWellFormed() {
|
||||
// Well-formed inputs.
|
||||
checkFromStringCase("pivotal.io", 80, "pivotal.io", 80, false);
|
||||
checkFromStringCase("pivotal.io", 80, "pivotal.io", 80, false);
|
||||
checkFromStringCase("192.0.2.1", 82, "192.0.2.1", 82, false);
|
||||
checkFromStringCase("[2001::1]", 84, "2001::1", 84, false);
|
||||
checkFromStringCase("2001::3", 86, "2001::3", 86, false);
|
||||
checkFromStringCase("host:", 80, "host", 80, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFromStringBadDefaultPort() {
|
||||
// Well-formed strings with bad default ports.
|
||||
checkFromStringCase("gmail.com:81", -1, "gmail.com", 81, true);
|
||||
checkFromStringCase("192.0.2.2:83", -1, "192.0.2.2", 83, true);
|
||||
checkFromStringCase("[2001::2]:85", -1, "2001::2", 85, true);
|
||||
checkFromStringCase("goo.gl:65535", 65536, "goo.gl", 65535, true);
|
||||
// No port, bad default.
|
||||
checkFromStringCase("pivotal.io", -1, null, -1, false);
|
||||
checkFromStringCase("192.0.2.1", 65536, null, -1, false);
|
||||
checkFromStringCase("[2001::1]", -1, null, -1, false);
|
||||
checkFromStringCase("2001::3", 65536, null, -1, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFromStringUnusedDefaultPort() {
|
||||
// Default port, but unused.
|
||||
checkFromStringCase("gmail.com:81", 77, "gmail.com", 81, true);
|
||||
checkFromStringCase("192.0.2.2:83", 77, "192.0.2.2", 83, true);
|
||||
checkFromStringCase("[2001::2]:85", 77, "2001::2", 85, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFromStringBadPort() {
|
||||
// Out-of-range ports.
|
||||
checkFromStringCase("pivotal.io:65536", 1, null, 99, false);
|
||||
checkFromStringCase("pivotal.io:9999999999", 1, null, 99, false);
|
||||
// Invalid port parts.
|
||||
checkFromStringCase("pivotal.io:port", 1, null, 99, false);
|
||||
checkFromStringCase("pivotal.io:-25", 1, null, 99, false);
|
||||
checkFromStringCase("pivotal.io:+25", 1, null, 99, false);
|
||||
checkFromStringCase("pivotal.io:25 ", 1, null, 99, false);
|
||||
checkFromStringCase("pivotal.io:25\t", 1, null, 99, false);
|
||||
checkFromStringCase("pivotal.io:0x25 ", 1, null, 99, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFromStringUnparseableNonsense() {
|
||||
// Some nonsense that causes parse failures.
|
||||
checkFromStringCase("[goo.gl]", 1, null, 99, false);
|
||||
checkFromStringCase("[goo.gl]:80", 1, null, 99, false);
|
||||
checkFromStringCase("[", 1, null, 99, false);
|
||||
checkFromStringCase("[]:", 1, null, 99, false);
|
||||
checkFromStringCase("[]:80", 1, null, 99, false);
|
||||
checkFromStringCase("[]bad", 1, null, 99, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFromStringParseableNonsense() {
|
||||
// Examples of nonsense that gets through.
|
||||
checkFromStringCase("[[:]]", 86, "[:]", 86, false);
|
||||
checkFromStringCase("x:y:z", 87, "x:y:z", 87, false);
|
||||
checkFromStringCase("", 88, "", 88, false);
|
||||
checkFromStringCase(":", 99, "", 99, false);
|
||||
checkFromStringCase(":123", -1, "", 123, true);
|
||||
checkFromStringCase("\nOMG\t", 89, "\nOMG\t", 89, false);
|
||||
}
|
||||
|
||||
private static void checkFromStringCase(String hpString, int defaultPort, String expectHost, int expectPort,
|
||||
boolean expectHasExplicitPort) {
|
||||
InetSocketAddress hp;
|
||||
|
||||
try {
|
||||
hp = InetSocketAddressParser.parse(hpString, defaultPort);
|
||||
} catch (IllegalArgumentException e) {
|
||||
// Make sure we expected this.
|
||||
assertThat(expectHost).isNull();
|
||||
return;
|
||||
}
|
||||
|
||||
assertThat(expectHost).isNotNull();
|
||||
|
||||
if (expectHasExplicitPort) {
|
||||
assertThat(hp.getPort()).isEqualTo(expectPort);
|
||||
} else {
|
||||
assertThat(hp.getPort()).isEqualTo(defaultPort);
|
||||
}
|
||||
|
||||
assertThat(hp.getHostString()).isEqualTo(expectHost);
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,6 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.elasticsearch.client.reactive;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
@@ -24,11 +23,11 @@ import reactor.test.StepVerifier;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.elasticsearch.client.reactive.HostProvider.VerificationMode;
|
||||
import org.springframework.data.elasticsearch.client.ElasticsearchHost;
|
||||
import org.springframework.data.elasticsearch.client.ElasticsearchHost.State;
|
||||
import org.springframework.data.elasticsearch.client.reactive.HostProvider.VerificationMode;
|
||||
import org.springframework.data.elasticsearch.client.reactive.ReactiveMockClientTestsUtils.MockDelegatingElasticsearchHostProvider;
|
||||
import org.springframework.data.elasticsearch.client.reactive.ReactiveMockClientTestsUtils.WebClientProvider.Receive;
|
||||
import org.springframework.data.elasticsearch.client.reactive.ReactiveMockClientTestsUtils.MockWebClientProvider.Receive;
|
||||
import org.springframework.web.reactive.function.client.ClientResponse;
|
||||
|
||||
/**
|
||||
@@ -107,7 +106,7 @@ public class MultiNodeHostProviderUnitTests {
|
||||
|
||||
provider.clusterInfo().as(StepVerifier::create).expectNextCount(1).verifyComplete();
|
||||
|
||||
provider.getActive(VerificationMode.FORCE).as(StepVerifier::create).expectNext(mock.client(HOST_2))
|
||||
provider.getActive(VerificationMode.ACTIVE).as(StepVerifier::create).expectNext(mock.client(HOST_2))
|
||||
.verifyComplete();
|
||||
|
||||
verify(mock.client(HOST_2), times(2)).head();
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.elasticsearch.client.reactive;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
@@ -43,14 +42,20 @@ import org.elasticsearch.search.builder.SearchSourceBuilder;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.data.elasticsearch.TestUtils;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
/**
|
||||
* @author Christoph Strobl
|
||||
* @author Mark Paluch
|
||||
* @currentRead Fool's Fate - Robin Hobb
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@ContextConfiguration("classpath:infrastructure.xml")
|
||||
public class ReactiveElasticsearchClientTests {
|
||||
|
||||
static final String INDEX_I = "idx-1-reactive-client-tests";
|
||||
|
||||
@@ -13,14 +13,12 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.elasticsearch.client.reactive;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.ArgumentMatchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.springframework.data.elasticsearch.client.reactive.ReactiveMockClientTestsUtils.WebClientProvider.Receive.*;
|
||||
import static org.springframework.data.elasticsearch.client.reactive.ReactiveMockClientTestsUtils.MockWebClientProvider.Receive.*;
|
||||
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
@@ -40,7 +38,7 @@ import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.reactivestreams.Publisher;
|
||||
import org.springframework.data.elasticsearch.client.reactive.ReactiveMockClientTestsUtils.MockDelegatingElasticsearchHostProvider;
|
||||
import org.springframework.data.elasticsearch.client.reactive.ReactiveMockClientTestsUtils.WebClientProvider.Receive;
|
||||
import org.springframework.data.elasticsearch.client.reactive.ReactiveMockClientTestsUtils.MockWebClientProvider.Receive;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
|
||||
@@ -13,21 +13,22 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.elasticsearch.client.reactive;
|
||||
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
@@ -35,10 +36,8 @@ import java.util.function.Supplier;
|
||||
import org.mockito.Mockito;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.buffer.DataBuffer;
|
||||
import org.springframework.core.io.buffer.DefaultDataBufferFactory;
|
||||
import org.springframework.data.elasticsearch.client.ElasticsearchHost;
|
||||
import org.springframework.data.elasticsearch.client.reactive.ReactiveMockClientTestsUtils.WebClientProvider.Send;
|
||||
import org.springframework.data.elasticsearch.client.reactive.ReactiveMockClientTestsUtils.MockWebClientProvider.Send;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
@@ -52,10 +51,11 @@ import org.springframework.web.reactive.function.client.WebClient.RequestHeaders
|
||||
|
||||
/**
|
||||
* @author Christoph Strobl
|
||||
* @since 2018/10
|
||||
*/
|
||||
public class ReactiveMockClientTestsUtils {
|
||||
|
||||
private final static Map<String, InetSocketAddress> ADDRESS_CACHE = new ConcurrentHashMap<>();
|
||||
|
||||
public static MockDelegatingElasticsearchHostProvider<SingleNodeHostProvider> single(String host) {
|
||||
return provider(host);
|
||||
}
|
||||
@@ -66,26 +66,17 @@ public class ReactiveMockClientTestsUtils {
|
||||
|
||||
public static <T extends HostProvider> MockDelegatingElasticsearchHostProvider<T> provider(String... hosts) {
|
||||
|
||||
WebClientProvider clientProvider = new WebClientProvider();
|
||||
ErrorCollector errorCollector = new ErrorCollector();
|
||||
MockWebClientProvider clientProvider = new MockWebClientProvider(errorCollector);
|
||||
HostProvider delegate = null;
|
||||
|
||||
if (hosts.length == 1) {
|
||||
|
||||
delegate = new SingleNodeHostProvider(HttpHeaders.EMPTY, errorCollector, hosts[0]) {
|
||||
@Override // hook in there to modify result
|
||||
public WebClient createWebClient(String host, HttpHeaders headers) {
|
||||
return clientProvider.get(host);
|
||||
}
|
||||
};
|
||||
delegate = new SingleNodeHostProvider(clientProvider, getInetSocketAddress(hosts[0])) {};
|
||||
} else {
|
||||
|
||||
delegate = new MultiNodeHostProvider(HttpHeaders.EMPTY, errorCollector, hosts) {
|
||||
@Override // hook in there to modify result
|
||||
public WebClient createWebClient(String host, HttpHeaders headers) {
|
||||
return clientProvider.get(host);
|
||||
}
|
||||
};
|
||||
delegate = new MultiNodeHostProvider(clientProvider, Arrays.stream(hosts)
|
||||
.map(ReactiveMockClientTestsUtils::getInetSocketAddress).toArray(InetSocketAddress[]::new)) {};
|
||||
}
|
||||
|
||||
return new MockDelegatingElasticsearchHostProvider(HttpHeaders.EMPTY, clientProvider, errorCollector, delegate,
|
||||
@@ -93,6 +84,10 @@ public class ReactiveMockClientTestsUtils {
|
||||
|
||||
}
|
||||
|
||||
private static InetSocketAddress getInetSocketAddress(String hostAndPort) {
|
||||
return ADDRESS_CACHE.computeIfAbsent(hostAndPort, ElasticsearchHost::parse);
|
||||
}
|
||||
|
||||
public static class ErrorCollector implements Consumer<Throwable> {
|
||||
|
||||
List<Throwable> errors = new CopyOnWriteArrayList<>();
|
||||
@@ -110,11 +105,11 @@ public class ReactiveMockClientTestsUtils {
|
||||
public static class MockDelegatingElasticsearchHostProvider<T extends HostProvider> implements HostProvider {
|
||||
|
||||
private final T delegate;
|
||||
private final WebClientProvider clientProvider;
|
||||
private final MockWebClientProvider clientProvider;
|
||||
private final ErrorCollector errorCollector;
|
||||
private @Nullable String activeDefaultHost;
|
||||
|
||||
public MockDelegatingElasticsearchHostProvider(HttpHeaders httpHeaders, WebClientProvider clientProvider,
|
||||
public MockDelegatingElasticsearchHostProvider(HttpHeaders httpHeaders, MockWebClientProvider clientProvider,
|
||||
ErrorCollector errorCollector, T delegate, String activeDefaultHost) {
|
||||
|
||||
this.errorCollector = errorCollector;
|
||||
@@ -123,14 +118,14 @@ public class ReactiveMockClientTestsUtils {
|
||||
this.activeDefaultHost = activeDefaultHost;
|
||||
}
|
||||
|
||||
public Mono<String> lookupActiveHost() {
|
||||
public Mono<InetSocketAddress> lookupActiveHost() {
|
||||
return delegate.lookupActiveHost();
|
||||
}
|
||||
|
||||
public Mono<String> lookupActiveHost(VerificationMode verificationMode) {
|
||||
public Mono<InetSocketAddress> lookupActiveHost(VerificationMode verificationMode) {
|
||||
|
||||
if (StringUtils.hasText(activeDefaultHost)) {
|
||||
return Mono.just(activeDefaultHost);
|
||||
return Mono.just(getInetSocketAddress(activeDefaultHost));
|
||||
}
|
||||
|
||||
return delegate.lookupActiveHost(verificationMode);
|
||||
@@ -144,34 +139,21 @@ public class ReactiveMockClientTestsUtils {
|
||||
return delegate.getActive(verificationMode);
|
||||
}
|
||||
|
||||
public Mono<WebClient> getActive(VerificationMode verificationMode, HttpHeaders headers) {
|
||||
return delegate.getActive(verificationMode, headers);
|
||||
}
|
||||
|
||||
public WebClient createWebClient(String host, HttpHeaders headers) {
|
||||
return delegate.createWebClient(host, headers);
|
||||
public WebClient createWebClient(InetSocketAddress endpoint) {
|
||||
return delegate.createWebClient(endpoint);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<ClusterInformation> clusterInfo() {
|
||||
|
||||
if (StringUtils.hasText(activeDefaultHost)) {
|
||||
return Mono.just(new ClusterInformation(Collections.singleton(ElasticsearchHost.online(activeDefaultHost))));
|
||||
return Mono.just(new ClusterInformation(
|
||||
Collections.singleton(ElasticsearchHost.online(getInetSocketAddress(activeDefaultHost)))));
|
||||
}
|
||||
|
||||
return delegate.clusterInfo();
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpHeaders getDefaultHeaders() {
|
||||
return delegate.getDefaultHeaders();
|
||||
}
|
||||
|
||||
@Override
|
||||
public HostProvider withDefaultHeaders(HttpHeaders headers) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public Send when(String host) {
|
||||
return clientProvider.when(host);
|
||||
}
|
||||
@@ -188,28 +170,25 @@ public class ReactiveMockClientTestsUtils {
|
||||
return delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HostProvider withErrorListener(Consumer<Throwable> errorListener) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public MockDelegatingElasticsearchHostProvider<T> withActiveDefaultHost(String host) {
|
||||
return new MockDelegatingElasticsearchHostProvider(HttpHeaders.EMPTY, clientProvider, errorCollector, delegate,
|
||||
host);
|
||||
}
|
||||
}
|
||||
|
||||
public static class WebClientProvider {
|
||||
public static class MockWebClientProvider implements WebClientProvider {
|
||||
|
||||
private final Object lock = new Object();
|
||||
private final Consumer<Throwable> errorListener;
|
||||
|
||||
private Map<String, WebClient> clientMap;
|
||||
private Map<String, RequestHeadersUriSpec> headersUriSpecMap;
|
||||
private Map<String, RequestBodyUriSpec> bodyUriSpecMap;
|
||||
private Map<String, ClientResponse> responseMap;
|
||||
private Map<InetSocketAddress, WebClient> clientMap;
|
||||
private Map<InetSocketAddress, RequestHeadersUriSpec> headersUriSpecMap;
|
||||
private Map<InetSocketAddress, RequestBodyUriSpec> bodyUriSpecMap;
|
||||
private Map<InetSocketAddress, ClientResponse> responseMap;
|
||||
|
||||
public WebClientProvider() {
|
||||
public MockWebClientProvider(Consumer<Throwable> errorListener) {
|
||||
|
||||
this.errorListener = errorListener;
|
||||
this.clientMap = new LinkedHashMap<>();
|
||||
this.headersUriSpecMap = new LinkedHashMap<>();
|
||||
this.bodyUriSpecMap = new LinkedHashMap<>();
|
||||
@@ -217,10 +196,14 @@ public class ReactiveMockClientTestsUtils {
|
||||
}
|
||||
|
||||
public WebClient get(String host) {
|
||||
return get(getInetSocketAddress(host));
|
||||
}
|
||||
|
||||
public WebClient get(InetSocketAddress endpoint) {
|
||||
|
||||
synchronized (lock) {
|
||||
|
||||
return clientMap.computeIfAbsent(host, key -> {
|
||||
return clientMap.computeIfAbsent(endpoint, key -> {
|
||||
|
||||
WebClient webClient = mock(WebClient.class);
|
||||
|
||||
@@ -243,17 +226,39 @@ public class ReactiveMockClientTestsUtils {
|
||||
Mockito.when(bodyUriSpec.exchange()).thenReturn(Mono.just(response));
|
||||
Mockito.when(response.statusCode()).thenReturn(HttpStatus.ACCEPTED);
|
||||
|
||||
headersUriSpecMap.putIfAbsent(host, headersUriSpec);
|
||||
bodyUriSpecMap.putIfAbsent(host, bodyUriSpec);
|
||||
responseMap.putIfAbsent(host, response);
|
||||
headersUriSpecMap.putIfAbsent(key, headersUriSpec);
|
||||
bodyUriSpecMap.putIfAbsent(key, bodyUriSpec);
|
||||
responseMap.putIfAbsent(key, response);
|
||||
|
||||
return webClient;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpHeaders getDefaultHeaders() {
|
||||
return HttpHeaders.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebClientProvider withDefaultHeaders(HttpHeaders headers) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Consumer<Throwable> getErrorListener() {
|
||||
return errorListener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebClientProvider withErrorListener(Consumer<Throwable> errorListener) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public Send when(String host) {
|
||||
return new CallbackImpl(get(host), headersUriSpecMap.get(host), bodyUriSpecMap.get(host), responseMap.get(host));
|
||||
InetSocketAddress inetSocketAddress = getInetSocketAddress(host);
|
||||
return new CallbackImpl(get(host), headersUriSpecMap.get(inetSocketAddress),
|
||||
bodyUriSpecMap.get(inetSocketAddress), responseMap.get(inetSocketAddress));
|
||||
}
|
||||
|
||||
public interface Client {
|
||||
@@ -342,7 +347,7 @@ public class ReactiveMockClientTestsUtils {
|
||||
}
|
||||
|
||||
default Receive body(Supplier<byte[]> json) {
|
||||
return body(new DefaultDataBufferFactory().wrap(json.get()));
|
||||
return body(json.get());
|
||||
}
|
||||
|
||||
default Receive body(Resource resource) {
|
||||
@@ -356,8 +361,8 @@ public class ReactiveMockClientTestsUtils {
|
||||
});
|
||||
}
|
||||
|
||||
default Receive body(DataBuffer dataBuffer) {
|
||||
return receive(response -> Mockito.when(response.body(any())).thenReturn(Flux.just(dataBuffer)));
|
||||
default Receive body(byte[] bytes) {
|
||||
return receive(response -> Mockito.when(response.body(any())).thenReturn(Mono.just(bytes)));
|
||||
}
|
||||
|
||||
static void ok(ClientResponse response) {
|
||||
|
||||
@@ -16,17 +16,17 @@
|
||||
|
||||
package org.springframework.data.elasticsearch.client.reactive;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
import org.springframework.data.elasticsearch.client.NoReachableHostException;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.elasticsearch.client.ElasticsearchHost;
|
||||
import org.springframework.data.elasticsearch.client.ElasticsearchHost.State;
|
||||
import org.springframework.data.elasticsearch.client.NoReachableHostException;
|
||||
import org.springframework.data.elasticsearch.client.reactive.ReactiveMockClientTestsUtils.MockDelegatingElasticsearchHostProvider;
|
||||
import org.springframework.data.elasticsearch.client.reactive.ReactiveMockClientTestsUtils.WebClientProvider.Receive;
|
||||
import org.springframework.data.elasticsearch.client.reactive.ReactiveMockClientTestsUtils.MockWebClientProvider.Receive;
|
||||
|
||||
/**
|
||||
* @author Christoph Strobl
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.elasticsearch.core;
|
||||
|
||||
import static org.apache.commons.lang.RandomStringUtils.*;
|
||||
@@ -25,17 +24,22 @@ import java.util.List;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.data.elasticsearch.TestUtils;
|
||||
import org.springframework.data.elasticsearch.core.query.Criteria;
|
||||
import org.springframework.data.elasticsearch.core.query.CriteriaQuery;
|
||||
import org.springframework.data.elasticsearch.core.query.IndexQuery;
|
||||
import org.springframework.data.elasticsearch.core.query.IndexQueryBuilder;
|
||||
import org.springframework.data.elasticsearch.entities.SampleEntity;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
/**
|
||||
* @author Christoph Strobl
|
||||
* @currentRead Golden Fool - Robin Hobb
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@ContextConfiguration("classpath:infrastructure.xml")
|
||||
public class ReactiveElasticsearchTemplateTests {
|
||||
|
||||
private ElasticsearchRestTemplate restTemplate;
|
||||
|
||||
Reference in New Issue
Block a user