Skip to content

Applied design & implementation level refactoring techniques to improve code readability & maintainability #2517

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
* @author Peter-Josef Meisch
* @author Huw Ayling-Miller
* @author Henrique Amaral
* @author Taranjot Singh
* @since 3.2
*/
public interface ClientConfiguration {
Expand Down Expand Up @@ -163,6 +164,11 @@ static ClientConfiguration create(InetSocketAddress socketAddress) {
*/
Optional<String> getProxy();

/**
* @return the function for configuring a WebClient.
*/
Function<WebClient, WebClient> getWebClientConfigurer();

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This reverts the change from #2513 reintroducing the since 4.3 unused method for configuring the WebClient. Why?

/**
* @return the client configuration callbacks
* @since 4.3
Expand Down Expand Up @@ -329,7 +335,7 @@ default TerminalClientConfigurationBuilder withSocketTimeout(long millis) {
* @param proxy a proxy formatted as String {@literal host:port}.
* @return the {@link TerminalClientConfigurationBuilder}.
*/
TerminalClientConfigurationBuilder withProxy(String proxy);
TerminalClientConfigurationBuilder setProxy(String proxy);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

all the methods on this builder class (and probably almost all builders in this project) use the with...() naming. Why should this be changed?


/**
* Register a {@link ClientConfigurationCallback} to configure the client.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
* @author Peter-Josef Meisch
* @author Huw Ayling-Miller
* @author Henrique Amaral
* @author Taranjot Singh
* @since 3.2
*/
class ClientConfigurationBuilder
Expand All @@ -59,6 +60,7 @@ class ClientConfigurationBuilder
private @Nullable String password;
private @Nullable String pathPrefix;
private @Nullable String proxy;
private final Function<WebClient, WebClient> webClientConfigurer = Function.identity();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reintroducing removed code

private Supplier<HttpHeaders> headersSupplier = HttpHeaders::new;
@Deprecated private final HttpClientConfigCallback httpClientConfigurer = httpClientBuilder -> httpClientBuilder;
private final List<ClientConfiguration.ClientConfigurationCallback<?>> clientConfigurers = new ArrayList<>();
Expand All @@ -71,7 +73,6 @@ class ClientConfigurationBuilder
public MaybeSecureClientConfigurationBuilder connectedTo(String... hostAndPorts) {

Assert.notEmpty(hostAndPorts, "At least one host is required");

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We separate the Assert.* blocks with a newline from the rest of the code. One leading and one trailing. There might be places where such a newline is missing, but here the formatting is alright.

this.hosts.addAll(Arrays.stream(hostAndPorts).map(ClientConfigurationBuilder::parse).toList());
return this;
}
Expand All @@ -91,7 +92,7 @@ public MaybeSecureClientConfigurationBuilder connectedTo(InetSocketAddress... en
}

@Override
public MaybeSecureClientConfigurationBuilder withProxy(String proxy) {
public MaybeSecureClientConfigurationBuilder setProxy(String proxy) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see my other comment in ClientConfiguration

Assert.hasLength(proxy, "proxy must not be null or empty");
this.proxy = proxy;
return this;
Expand Down Expand Up @@ -229,11 +230,10 @@ public ClientConfiguration build() {
}

return new DefaultClientConfiguration(hosts, headers, useSsl, sslContext, soTimeout, connectTimeout, pathPrefix,
hostnameVerifier, proxy, httpClientConfigurer, clientConfigurers, headersSupplier);
hostnameVerifier, proxy, webClientConfigurer, httpClientConfigurer, clientConfigurers, headersSupplier);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reintroducing removed code

}

private static InetSocketAddress parse(String hostAndPort) {
return InetSocketAddressParser.parse(hostAndPort, ElasticsearchHost.DEFAULT_PORT);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import java.time.Duration;
import java.util.List;
import java.util.Optional;
import java.util.function.Function;
import java.util.function.Supplier;

import javax.net.ssl.HostnameVerifier;
Expand All @@ -27,6 +28,7 @@
import org.elasticsearch.client.RestClientBuilder.HttpClientConfigCallback;
import org.springframework.data.elasticsearch.support.HttpHeaders;
import org.springframework.lang.Nullable;
import org.springframework.web.reactive.function.client.WebClient;

/**
* Default {@link ClientConfiguration} implementation.
Expand All @@ -35,6 +37,7 @@
* @author Christoph Strobl
* @author Huw Ayling-Miller
* @author Peter-Josef Meisch
* @author Taranjot Singh
* @since 3.2
*/
class DefaultClientConfiguration implements ClientConfiguration {
Expand All @@ -48,15 +51,16 @@ class DefaultClientConfiguration implements ClientConfiguration {
private final @Nullable String pathPrefix;
private final @Nullable HostnameVerifier hostnameVerifier;
private final @Nullable String proxy;
private final Function<WebClient, WebClient> webClientConfigurer;
private final HttpClientConfigCallback httpClientConfigurer;
private final Supplier<HttpHeaders> headersSupplier;
private final List<ClientConfigurationCallback<?>> clientConfigurers;

DefaultClientConfiguration(List<InetSocketAddress> hosts, HttpHeaders headers, boolean useSsl,
@Nullable SSLContext sslContext, Duration soTimeout, Duration connectTimeout, @Nullable String pathPrefix,
@Nullable HostnameVerifier hostnameVerifier, @Nullable String proxy,
HttpClientConfigCallback httpClientConfigurer, List<ClientConfigurationCallback<?>> clientConfigurers,
Supplier<HttpHeaders> headersSupplier) {
@Nullable SSLContext sslContext, Duration soTimeout, Duration connectTimeout, @Nullable String pathPrefix,
@Nullable HostnameVerifier hostnameVerifier, @Nullable String proxy,
Function<WebClient, WebClient> webClientConfigurer, HttpClientConfigCallback httpClientConfigurer,
List<ClientConfigurationCallback<?>> clientConfigurers, Supplier<HttpHeaders> headersSupplier) {
Comment on lines +60 to +63
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a formatting change not compatible with the code formatting guidelines (see the linked reference in the Pull Request template ():

You use the code formatters provided here and have them applied to your changes. Don’t submit any formatting related changes.


this.hosts = List.copyOf(hosts);
this.headers = headers;
Expand All @@ -67,6 +71,7 @@ class DefaultClientConfiguration implements ClientConfiguration {
this.pathPrefix = pathPrefix;
this.hostnameVerifier = hostnameVerifier;
this.proxy = proxy;
this.webClientConfigurer = webClientConfigurer;
this.httpClientConfigurer = httpClientConfigurer;
this.clientConfigurers = clientConfigurers;
this.headersSupplier = headersSupplier;
Expand Down Expand Up @@ -118,6 +123,11 @@ public Optional<String> getProxy() {
return Optional.ofNullable(proxy);
}

@Override
public Function<WebClient, WebClient> getWebClientConfigurer() {
return webClientConfigurer;
}

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reintroducing removed code

@Override
public <T> List<ClientConfigurationCallback<?>> getClientConfigurers() {
return clientConfigurers;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
* Utility to parse endpoints in {@code host:port} format into {@link java.net.InetSocketAddress}.
*
* @author Mark Paluch
* @author Taranjot Singh
* @since 3.2
*/
public class InetSocketAddressParser {
Expand All @@ -42,7 +43,10 @@ public static InetSocketAddress parse(String hostPortString, int defaultPort) {
String host;
String portString = null;

if (hostPortString.startsWith("[")) {
// Check if the host is surrounded by square brackets
boolean isBracketedHost = hostPortString.startsWith("[");

if (isBracketedHost) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extracting this to a boolean variable does not add anything of value, as this is the only place where this variable is used.

String[] hostAndPort = getHostAndPortFromBracketedHost(hostPortString);
host = hostAndPort[0];
portString = hostAndPort[1];
Expand All @@ -58,19 +62,8 @@ public static InetSocketAddress parse(String hostPortString, int defaultPort) {
}
}

int port = defaultPort;
if (StringUtils.hasText(portString)) {
// Try to parse the whole port string as a number.
Assert.isTrue(!portString.startsWith("+"), String.format("Cannot parse port number: %s", hostPortString));
try {
port = Integer.parseInt(portString);
} catch (NumberFormatException e) {
throw new IllegalArgumentException(String.format("Cannot parse port number: %s", hostPortString));
}

Assert.isTrue(isValidPort(port), String.format("Port number out of range: %s", hostPortString));
}

int port = parsePort(portString, defaultPort);
Assert.isTrue(isValidPort(port), String.format("Port number out of range: %s", hostPortString));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really see the need to extract this method, but if so, then the assert should be moved into the extracted method as well.

return InetSocketAddress.createUnresolved(host, port);
}

Expand Down Expand Up @@ -114,4 +107,24 @@ private static String[] getHostAndPortFromBracketedHost(String hostPortString) {
private static boolean isValidPort(int port) {
return port >= 0 && port <= 65535;
}

/**
* @param portString A string representing a port number.
* @param defaultPort default port to apply if {@code hostPostString} does not contain a port.
* @return {@literal true} for valid port numbers.
*/
private static int parsePort(String portString, int defaultPort) {
if (StringUtils.hasText(portString)) {
try {
return Integer.parseInt(portString);
} catch (NumberFormatException e) {
throw new IllegalArgumentException(String.format("Cannot parse port number: %s", portString));
}
} else {
return defaultPort;
}
}

}


Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.data.elasticsearch.client.ClientConfiguration;
import org.springframework.data.elasticsearch.client.ClientLogger;
import org.springframework.data.elasticsearch.support.HttpHeaders;
Expand All @@ -61,6 +62,7 @@
* Utility class to create the different Elasticsearch clients
*
* @author Peter-Josef Meisch
* @author Taranjot Singh
* @since 4.4
*/
public final class ElasticsearchClients {
Expand Down Expand Up @@ -93,7 +95,7 @@ public static ReactiveElasticsearchClient createReactive(ClientConfiguration cli
* @return the {@link ReactiveElasticsearchClient}
*/
public static ReactiveElasticsearchClient createReactive(ClientConfiguration clientConfiguration,
@Nullable TransportOptions transportOptions) {
@Nullable TransportOptions transportOptions) {

Assert.notNull(clientConfiguration, "ClientConfiguration must not be null!");

Expand All @@ -118,7 +120,7 @@ public static ReactiveElasticsearchClient createReactive(RestClient restClient)
* @return the {@link ReactiveElasticsearchClient}
*/
public static ReactiveElasticsearchClient createReactive(RestClient restClient,
@Nullable TransportOptions transportOptions) {
@Nullable TransportOptions transportOptions) {
return new ReactiveElasticsearchClient(getElasticsearchTransport(restClient, REACTIVE_CLIENT, transportOptions));
}

Expand All @@ -140,7 +142,7 @@ public static ElasticsearchClient createImperative(ClientConfiguration clientCon
* @return the {@link ElasticsearchClient}
*/
public static ElasticsearchClient createImperative(ClientConfiguration clientConfiguration,
TransportOptions transportOptions) {
TransportOptions transportOptions) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

formatting change not compatible with code formatting guidelines

return createImperative(getRestClient(clientConfiguration), transportOptions);
}

Expand All @@ -162,7 +164,7 @@ public static ElasticsearchClient createImperative(RestClient restClient) {
* @return the {@link ElasticsearchClient}
*/
public static ElasticsearchClient createImperative(RestClient restClient,
@Nullable TransportOptions transportOptions) {
@Nullable TransportOptions transportOptions) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

formatting change not compatible with code formatting guidelines

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

formatting change not compatible with code formatting guidelines


Assert.notNull(restClient, "restClient must not be null");

Expand Down Expand Up @@ -246,14 +248,14 @@ private static RestClientBuilder getRestClientBuilder(ClientConfiguration client
}

private static ElasticsearchTransport getElasticsearchTransport(RestClient restClient, String clientType,
@Nullable TransportOptions transportOptions) {
@Nullable TransportOptions transportOptions) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

formatting change not compatible with code formatting guidelines


TransportOptions.Builder transportOptionsBuilder = transportOptions != null ? transportOptions.toBuilder()
: new RestClientOptions(RequestOptions.DEFAULT).toBuilder();

ContentType jsonContentType = Version.VERSION == null ? ContentType.APPLICATION_JSON
: ContentType.create("application/vnd.elasticsearch+json",
new BasicNameValuePair("compatible-with", String.valueOf(Version.VERSION.major())));
new BasicNameValuePair("compatible-with", String.valueOf(Version.VERSION.major())));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

formatting change not compatible with code formatting guidelines


Consumer<String> setHeaderIfNotPresent = header -> {
if (transportOptionsBuilder.build().headers().stream() //
Expand Down Expand Up @@ -403,4 +405,23 @@ static ElasticsearchRestClientConfigurationCallback from(
return restClientBuilderCallback::apply;
}
}

/**
* Provides the {@link ElasticsearchClient} to be used.
*
* @param restClient the low level RestClient to use
* @return ElasticsearchClient instance
*/
@Bean
public static ElasticsearchClient elasticsearchClient(RestClient restClient) {

Assert.notNull(restClient, "restClient must not be null");

return ElasticsearchClients.createImperative(restClient, transportOptions());
}

public static TransportOptions transportOptions() {
return new RestClientOptions(RequestOptions.DEFAULT);
}

Comment on lines +408 to +426
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

putting a @Bean method here makes no sense, as this is a final utility class containing static methods and not a Spring configuration class that could provide beans. Bean setup of all relevant beans is done in the org.springframework.data.elasticsearch.client.elc.ElasticsearchConfiguration derived classes.

}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
* connection using the Elasticsearch Client.
*
* @author Peter-Josef Meisch
* @author Taranjot Singh
* @since 4.4
*/
public abstract class ElasticsearchConfiguration extends ElasticsearchConfigurationSupport {
Expand Down Expand Up @@ -67,10 +68,7 @@ public RestClient elasticsearchRestClient(ClientConfiguration clientConfiguratio
*/
@Bean
public ElasticsearchClient elasticsearchClient(RestClient restClient) {

Assert.notNull(restClient, "restClient must not be null");

return ElasticsearchClients.createImperative(restClient, transportOptions());
return ElasticsearchClients.elasticsearchClient(restClient);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see my comment in ElasticsearchClients about creation of beans. In addition to that, we cannot remove the transportOptions() method from this abstract class, as it might be overridden by the user in a derived implementation.

}

/**
Expand All @@ -81,7 +79,7 @@ public ElasticsearchClient elasticsearchClient(RestClient restClient) {
*/
@Bean(name = { "elasticsearchOperations", "elasticsearchTemplate" })
public ElasticsearchOperations elasticsearchOperations(ElasticsearchConverter elasticsearchConverter,
ElasticsearchClient elasticsearchClient) {
ElasticsearchClient elasticsearchClient) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

formatting change not compatible with code formatting guidelines


ElasticsearchTemplate template = new ElasticsearchTemplate(elasticsearchClient, elasticsearchConverter);
template.setRefreshPolicy(refreshPolicy());
Expand Down
Loading