mirror of
https://github.com/spring-projects/spring-data-elasticsearch.git
synced 2025-08-05 00:53:26 +00:00
Compare commits
8 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
e49bb63df4 | ||
|
006cda6de6 | ||
|
f51efa2cad | ||
|
6e30801a59 | ||
|
e64d0ada62 | ||
|
7f7cf3f52e | ||
|
55d470fc91 | ||
|
b7290b5d9c |
24
pom.xml
24
pom.xml
@ -5,12 +5,12 @@
|
||||
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-elasticsearch</artifactId>
|
||||
<version>6.0.0-M4</version>
|
||||
<version>6.0.0-SNAPSHOT</version>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.data.build</groupId>
|
||||
<artifactId>spring-data-parent</artifactId>
|
||||
<version>4.0.0-M4</version>
|
||||
<version>4.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<name>Spring Data Elasticsearch</name>
|
||||
@ -18,10 +18,10 @@
|
||||
<url>https://github.com/spring-projects/spring-data-elasticsearch</url>
|
||||
|
||||
<properties>
|
||||
<springdata.commons>4.0.0-M4</springdata.commons>
|
||||
<springdata.commons>4.0.0-SNAPSHOT</springdata.commons>
|
||||
|
||||
<!-- version of the ElasticsearchClient -->
|
||||
<elasticsearch-java>9.0.3</elasticsearch-java>
|
||||
<elasticsearch-java>9.0.4</elasticsearch-java>
|
||||
|
||||
<hoverfly>0.19.0</hoverfly>
|
||||
<log4j>2.23.1</log4j>
|
||||
@ -471,8 +471,20 @@
|
||||
</profiles>
|
||||
|
||||
<repositories>
|
||||
|
||||
|
||||
<repository>
|
||||
<id>spring-snapshot</id>
|
||||
<url>https://repo.spring.io/snapshot</url>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
</snapshots>
|
||||
<releases>
|
||||
<enabled>false</enabled>
|
||||
</releases>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>spring-milestone</id>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
</project>
|
||||
|
@ -389,6 +389,63 @@ ClientConfiguration.builder()
|
||||
----
|
||||
====
|
||||
|
||||
[[elasticsearch.clients.configurationcallbacks.connectionconfig]]
|
||||
==== Configuration of the ConnectionConfig used by the low level Elasticsearch `Rest5Client`:
|
||||
|
||||
This callback provides a `org.apache.hc.client5.http.config.ConnectionConfig` to configure the connection that is
|
||||
used by the `Rest5Client`.
|
||||
|
||||
====
|
||||
[source,java]
|
||||
----
|
||||
ClientConfiguration.builder()
|
||||
.connectedTo("localhost:9200", "localhost:9291")
|
||||
.withClientConfigurer(Rest5Clients.ElasticsearchConnectionConfigurationCallback.from(connectionConfigBuilder -> {
|
||||
// configure the connection
|
||||
return connectionConfigBuilder;
|
||||
}))
|
||||
.build();
|
||||
----
|
||||
====
|
||||
|
||||
[[elasticsearch.clients.configurationcallbacks.connectioncmanager]]
|
||||
==== Configuration of the ConnectionManager used by the low level Elasticsearch `Rest5Client`:
|
||||
|
||||
This callback provides a `org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManagerBuilder` to configure the connection manager that is
|
||||
used by the `Rest5Client`.
|
||||
|
||||
====
|
||||
[source,java]
|
||||
----
|
||||
ClientConfiguration.builder()
|
||||
.connectedTo("localhost:9200", "localhost:9291")
|
||||
.withClientConfigurer(Rest5Clients.ElasticsearchConnectionManagerCallback.from(connectionManagerBuilder -> {
|
||||
// configure the connection manager
|
||||
return connectionManagerBuilder;
|
||||
}))
|
||||
.build();
|
||||
----
|
||||
====
|
||||
|
||||
[[elasticsearch.clients.configurationcallbacks.requestconfig]]
|
||||
==== Configuration of the RequestConfig used by the low level Elasticsearch `Rest5Client`:
|
||||
|
||||
This callback provides a `org.apache.hc.client5.http.config.RequestConfig` to configure the RequestConfig that is
|
||||
used by the `Rest5Client`.
|
||||
|
||||
====
|
||||
[source,java]
|
||||
----
|
||||
ClientConfiguration.builder()
|
||||
.connectedTo("localhost:9200", "localhost:9291")
|
||||
.withClientConfigurer(Rest5Clients.ElasticsearchRequestConfigCallback.from(requestConfigBuilder -> {
|
||||
// configure the request config
|
||||
return requestConfigBuilder;
|
||||
}))
|
||||
.build();
|
||||
----
|
||||
====
|
||||
|
||||
[[elasticsearch.clients.logging]]
|
||||
== Client Logging
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
* Upgarde to Spring 7
|
||||
* Switch to jspecify nullability annotations
|
||||
* Upgrade to Elasticsearch 9.0.3
|
||||
* Upgrade to Elasticsearch 9.0.4
|
||||
* Use the new Elasticsearch Rest5Client as default
|
||||
|
||||
|
||||
|
@ -6,7 +6,7 @@ The following table shows the Elasticsearch and Spring versions that are used by
|
||||
[cols="^,^,^,^",options="header"]
|
||||
|===
|
||||
| Spring Data Release Train | Spring Data Elasticsearch | Elasticsearch | Spring Framework
|
||||
| 2025.1 (in development) | 6.0.x | 9.0.3 | 7.0.x
|
||||
| 2025.1 (in development) | 6.0.x | 9.0.4 | 7.0.x
|
||||
| 2025.0 | 5.5.x | 8.18.1 | 6.2.x
|
||||
| 2024.1 | 5.4.x | 8.15.5 | 6.1.x
|
||||
| 2024.0 | 5.3.xfootnote:oom[Out of maintenance] | 8.13.4 | 6.1.x
|
||||
|
@ -8,6 +8,8 @@ This section describes breaking changes from version 5.5.x to 6.0.x and how remo
|
||||
|
||||
From version 6.0 on, Spring Data Elasticsearch uses the Elasticsearch 9 libraries and as default the new `Rest5Client` provided by these libraries. It is still possible to use the old `RestClient`, check xref:elasticsearch/clients.adoc[Elasticsearch clients] for information. The configuration callbacks for this `RestClient` have been moved from `org.springframework.data.elasticsearch.client.elc.ElasticsearchClients` to the `org.springframework.data.elasticsearch.client.elc.rest_client.RestClients` class.
|
||||
|
||||
In the `org.springframework.data.elasticsearch.core.query.UpdateQuery` class the type of the two fields `ifSeqNo` and `ifPrimaryTerm` has changed from `Integer` to `Long` to align with the normal query and the underlying Elasticsearch client.
|
||||
|
||||
[[elasticsearch-migration-guide-5.5-6.0.deprecations]]
|
||||
== Deprecations
|
||||
|
||||
|
@ -24,6 +24,7 @@ import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.elasticsearch.client.ResponseException;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.DataAccessResourceFailureException;
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
@ -33,6 +34,7 @@ import org.springframework.data.elasticsearch.NoSuchIndexException;
|
||||
import org.springframework.data.elasticsearch.ResourceNotFoundException;
|
||||
import org.springframework.data.elasticsearch.UncategorizedElasticsearchException;
|
||||
import org.springframework.data.elasticsearch.VersionConflictException;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* Simple {@link PersistenceExceptionTranslator} for Elasticsearch. Convert the given runtime exception to an
|
||||
@ -45,6 +47,9 @@ import org.springframework.data.elasticsearch.VersionConflictException;
|
||||
*/
|
||||
public class ElasticsearchExceptionTranslator implements PersistenceExceptionTranslator {
|
||||
|
||||
public static final boolean LEGACY_RESTCLIENT_PRESENT = ClassUtils
|
||||
.isPresent("org.elasticsearch.client.ResponseException", ElasticsearchExceptionTranslator.class.getClassLoader());
|
||||
|
||||
private final JsonpMapper jsonpMapper;
|
||||
|
||||
public ElasticsearchExceptionTranslator(JsonpMapper jsonpMapper) {
|
||||
@ -68,7 +73,7 @@ public class ElasticsearchExceptionTranslator implements PersistenceExceptionTra
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataAccessException translateExceptionIfPossible(RuntimeException ex) {
|
||||
public @Nullable DataAccessException translateExceptionIfPossible(RuntimeException ex) {
|
||||
|
||||
checkForConflictException(ex);
|
||||
|
||||
@ -118,7 +123,7 @@ public class ElasticsearchExceptionTranslator implements PersistenceExceptionTra
|
||||
Integer status = null;
|
||||
String message = null;
|
||||
|
||||
if (exception instanceof ResponseException responseException) {
|
||||
if (LEGACY_RESTCLIENT_PRESENT && exception instanceof ResponseException responseException) {
|
||||
// this code is for the old RestClient
|
||||
status = responseException.getResponse().getStatusLine().getStatusCode();
|
||||
message = responseException.getMessage();
|
||||
|
@ -658,7 +658,7 @@ public class ElasticsearchTemplate extends AbstractElasticsearchTemplate {
|
||||
QueryResponse response = sqlClient.query(requestConverter.sqlQueryRequest(query));
|
||||
|
||||
return responseConverter.sqlResponse(response);
|
||||
} catch (IOException e) {
|
||||
} catch (Exception e) {
|
||||
throw exceptionTranslator.translateException(e);
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ import co.elastic.clients.elasticsearch.core.search.ResponseBody;
|
||||
import co.elastic.clients.json.JsonpMapper;
|
||||
import co.elastic.clients.transport.Version;
|
||||
import co.elastic.clients.transport.endpoints.BooleanResponse;
|
||||
import org.jspecify.annotations.NonNull;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.util.function.Tuple2;
|
||||
@ -162,7 +163,7 @@ public class ReactiveElasticsearchTemplate extends AbstractReactiveElasticsearch
|
||||
ExistsRequest existsRequest = requestConverter.documentExistsRequest(id, routingResolver.getRouting(), index);
|
||||
|
||||
return Mono.from(execute(
|
||||
((ClientCallback<Publisher<BooleanResponse>>) client -> client.exists(existsRequest))))
|
||||
((ClientCallback<@NonNull Publisher<BooleanResponse>>) client -> client.exists(existsRequest))))
|
||||
.map(BooleanResponse::value) //
|
||||
.onErrorReturn(NoSuchIndexException.class, false);
|
||||
}
|
||||
|
@ -723,12 +723,11 @@ class RequestConverter extends AbstractQueryProcessor {
|
||||
return a;
|
||||
});
|
||||
|
||||
uob //
|
||||
.routing(query.getRouting()) //
|
||||
.ifSeqNo(query.getIfSeqNo() != null ? Long.valueOf(query.getIfSeqNo()) : null) //
|
||||
.ifPrimaryTerm(query.getIfPrimaryTerm() != null ? Long.valueOf(query.getIfPrimaryTerm()) : null) //
|
||||
.retryOnConflict(query.getRetryOnConflict()) //
|
||||
;
|
||||
uob
|
||||
.routing(query.getRouting())
|
||||
.ifSeqNo(query.getIfSeqNo())
|
||||
.ifPrimaryTerm(query.getIfPrimaryTerm())
|
||||
.retryOnConflict(query.getRetryOnConflict());
|
||||
|
||||
// no refresh, timeout, waitForActiveShards on UpdateOperation or UpdateAction
|
||||
|
||||
@ -1095,17 +1094,16 @@ class RequestConverter extends AbstractQueryProcessor {
|
||||
});
|
||||
}
|
||||
|
||||
uqb //
|
||||
.doc(query.getDocument()) //
|
||||
.upsert(query.getUpsert()) //
|
||||
.routing(query.getRouting() != null ? query.getRouting() : routing) //
|
||||
.scriptedUpsert(query.getScriptedUpsert()) //
|
||||
.docAsUpsert(query.getDocAsUpsert()) //
|
||||
.ifSeqNo(query.getIfSeqNo() != null ? Long.valueOf(query.getIfSeqNo()) : null) //
|
||||
.ifPrimaryTerm(query.getIfPrimaryTerm() != null ? Long.valueOf(query.getIfPrimaryTerm()) : null) //
|
||||
.refresh(query.getRefreshPolicy() != null ? refresh(query.getRefreshPolicy()) : refresh(refreshPolicy)) //
|
||||
.retryOnConflict(query.getRetryOnConflict()) //
|
||||
;
|
||||
uqb
|
||||
.doc(query.getDocument())
|
||||
.upsert(query.getUpsert())
|
||||
.routing(query.getRouting() != null ? query.getRouting() : routing)
|
||||
.scriptedUpsert(query.getScriptedUpsert())
|
||||
.docAsUpsert(query.getDocAsUpsert())
|
||||
.ifSeqNo(query.getIfSeqNo())
|
||||
.ifPrimaryTerm(query.getIfPrimaryTerm())
|
||||
.refresh(query.getRefreshPolicy() != null ? refresh(query.getRefreshPolicy()) : refresh(refreshPolicy))
|
||||
.retryOnConflict(query.getRetryOnConflict());
|
||||
|
||||
if (query.getFetchSource() != null) {
|
||||
uqb.source(sc -> sc.fetch(query.getFetchSource()));
|
||||
@ -1293,7 +1291,7 @@ class RequestConverter extends AbstractQueryProcessor {
|
||||
.timeout(timeStringMs(query.getTimeout())) //
|
||||
;
|
||||
|
||||
bb.from((int) (query.getPageable().isPaged() ? query.getPageable().getOffset() : 0))
|
||||
bb.from((int) (query.getPageable().isPaged() ? query.getPageable().getOffset() : 0))
|
||||
.size(query.getRequestSize());
|
||||
|
||||
if (!isEmpty(query.getFields())) {
|
||||
@ -1466,7 +1464,7 @@ class RequestConverter extends AbstractQueryProcessor {
|
||||
builder.seqNoPrimaryTerm(true);
|
||||
}
|
||||
|
||||
builder.from((int) (query.getPageable().isPaged() ? query.getPageable().getOffset() : 0))
|
||||
builder.from((int) (query.getPageable().isPaged() ? query.getPageable().getOffset() : 0))
|
||||
.size(query.getRequestSize());
|
||||
|
||||
if (!isEmpty(query.getFields())) {
|
||||
|
@ -13,20 +13,14 @@ import java.net.URISyntaxException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.function.Function;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
|
||||
import org.apache.hc.client5.http.config.ConnectionConfig;
|
||||
import org.apache.hc.client5.http.config.RequestConfig;
|
||||
import org.apache.hc.client5.http.impl.DefaultAuthenticationStrategy;
|
||||
import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
|
||||
import org.apache.hc.client5.http.impl.async.HttpAsyncClientBuilder;
|
||||
import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManager;
|
||||
import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManagerBuilder;
|
||||
import org.apache.hc.client5.http.impl.routing.DefaultProxyRoutePlanner;
|
||||
import org.apache.hc.core5.http.Header;
|
||||
@ -38,7 +32,6 @@ import org.jspecify.annotations.NonNull;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.springframework.data.elasticsearch.client.ClientConfiguration;
|
||||
import org.springframework.data.elasticsearch.support.HttpHeaders;
|
||||
import org.springframework.data.elasticsearch.support.VersionInfo;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
@ -49,11 +42,8 @@ import org.springframework.util.Assert;
|
||||
public final class Rest5Clients {
|
||||
|
||||
// values copied from Rest5ClientBuilder
|
||||
public static final int DEFAULT_CONNECT_TIMEOUT_MILLIS = 1000;
|
||||
public static final int DEFAULT_SOCKET_TIMEOUT_MILLIS = 30000;
|
||||
public static final int DEFAULT_RESPONSE_TIMEOUT_MILLIS = 0; // meaning infinite
|
||||
public static final int DEFAULT_MAX_CONN_PER_ROUTE = 10;
|
||||
public static final int DEFAULT_MAX_CONN_TOTAL = 30;
|
||||
|
||||
private Rest5Clients() {}
|
||||
|
||||
@ -82,11 +72,7 @@ public final class Rest5Clients {
|
||||
builder.setDefaultHeaders(toHeaderArray(headers));
|
||||
}
|
||||
|
||||
// we need to provide our own HttpClient, as the Rest5ClientBuilder
|
||||
// does not provide a callback for configuration the http client as the old RestClientBuilder.
|
||||
var httpClient = createHttpClient(clientConfiguration);
|
||||
builder.setHttpClient(httpClient);
|
||||
|
||||
// RestClientBuilder configuration callbacks from the consumer
|
||||
for (ClientConfiguration.ClientConfigurationCallback<?> clientConfigurationCallback : clientConfiguration
|
||||
.getClientConfigurers()) {
|
||||
if (clientConfigurationCallback instanceof ElasticsearchRest5ClientConfigurationCallback configurationCallback) {
|
||||
@ -94,6 +80,104 @@ public final class Rest5Clients {
|
||||
}
|
||||
}
|
||||
|
||||
Duration connectTimeout = clientConfiguration.getConnectTimeout();
|
||||
Duration socketTimeout = clientConfiguration.getSocketTimeout();
|
||||
|
||||
builder.setHttpClientConfigCallback(httpAsyncClientBuilder -> {
|
||||
|
||||
if (clientConfiguration.getProxy().isPresent()) {
|
||||
var proxy = clientConfiguration.getProxy().get();
|
||||
try {
|
||||
var proxyRoutePlanner = new DefaultProxyRoutePlanner(HttpHost.create(proxy));
|
||||
httpAsyncClientBuilder.setRoutePlanner(proxyRoutePlanner);
|
||||
} catch (URISyntaxException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
httpAsyncClientBuilder.addRequestInterceptorFirst((request, entity, context) -> {
|
||||
clientConfiguration.getHeadersSupplier().get().forEach((header, values) -> {
|
||||
// The accept and content-type headers are already put on the request, despite this being the first
|
||||
// interceptor.
|
||||
if ("Accept".equalsIgnoreCase(header) || " Content-Type".equalsIgnoreCase(header)) {
|
||||
request.removeHeaders(header);
|
||||
}
|
||||
values.forEach(value -> request.addHeader(header, value));
|
||||
});
|
||||
});
|
||||
|
||||
// add httpclient configurator callbacks provided by the configuration
|
||||
for (ClientConfiguration.ClientConfigurationCallback<?> clientConfigurer : clientConfiguration
|
||||
.getClientConfigurers()) {
|
||||
if (clientConfigurer instanceof ElasticsearchHttpClientConfigurationCallback httpClientConfigurer) {
|
||||
httpAsyncClientBuilder = httpClientConfigurer.configure(httpAsyncClientBuilder);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
builder.setConnectionConfigCallback(connectionConfigBuilder -> {
|
||||
|
||||
if (!connectTimeout.isNegative()) {
|
||||
connectionConfigBuilder.setConnectTimeout(
|
||||
Timeout.of(Math.toIntExact(connectTimeout.toMillis()), TimeUnit.MILLISECONDS));
|
||||
}
|
||||
if (!socketTimeout.isNegative()) {
|
||||
var soTimeout = Timeout.of(Math.toIntExact(socketTimeout.toMillis()), TimeUnit.MILLISECONDS);
|
||||
connectionConfigBuilder.setSocketTimeout(soTimeout);
|
||||
} else {
|
||||
connectionConfigBuilder.setSocketTimeout(Timeout.of(DEFAULT_SOCKET_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS));
|
||||
}
|
||||
|
||||
// add connectionConfig configurator callbacks provided by the configuration
|
||||
for (ClientConfiguration.ClientConfigurationCallback<?> clientConfigurer : clientConfiguration
|
||||
.getClientConfigurers()) {
|
||||
if (clientConfigurer instanceof ElasticsearchConnectionConfigurationCallback connectionConfigurationCallback) {
|
||||
connectionConfigBuilder = connectionConfigurationCallback.configure(connectionConfigBuilder);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
builder.setConnectionManagerCallback(poolingAsyncClientConnectionManagerBuilder -> {
|
||||
|
||||
SSLContext sslContext = null;
|
||||
try {
|
||||
sslContext = clientConfiguration.getCaFingerprint().isPresent()
|
||||
? TransportUtils.sslContextFromCaFingerprint(clientConfiguration.getCaFingerprint().get())
|
||||
: (clientConfiguration.getSslContext().isPresent()
|
||||
? clientConfiguration.getSslContext().get()
|
||||
: SSLContext.getDefault());
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new IllegalStateException("could not create the default ssl context", e);
|
||||
}
|
||||
poolingAsyncClientConnectionManagerBuilder.setTlsStrategy(new BasicClientTlsStrategy(sslContext));
|
||||
|
||||
// add connectionManager configurator callbacks provided by the configuration
|
||||
for (ClientConfiguration.ClientConfigurationCallback<?> clientConfigurer : clientConfiguration
|
||||
.getClientConfigurers()) {
|
||||
if (clientConfigurer instanceof ElasticsearchConnectionManagerCallback connectionManagerCallback) {
|
||||
poolingAsyncClientConnectionManagerBuilder = connectionManagerCallback
|
||||
.configure(poolingAsyncClientConnectionManagerBuilder);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
builder.setRequestConfigCallback(requestConfigBuilder -> {
|
||||
|
||||
if (!socketTimeout.isNegative()) {
|
||||
var soTimeout = Timeout.of(Math.toIntExact(socketTimeout.toMillis()), TimeUnit.MILLISECONDS);
|
||||
requestConfigBuilder.setConnectionRequestTimeout(soTimeout);
|
||||
} else {
|
||||
requestConfigBuilder
|
||||
.setConnectionRequestTimeout(Timeout.of(DEFAULT_RESPONSE_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS));
|
||||
}
|
||||
// add connectionConfig configurator callbacks provided by the configuration
|
||||
for (ClientConfiguration.ClientConfigurationCallback<?> clientConfigurer : clientConfiguration
|
||||
.getClientConfigurers()) {
|
||||
if (clientConfigurer instanceof ElasticsearchRequestConfigCallback requestConfigCallback) {
|
||||
requestConfigBuilder = requestConfigCallback.configure(requestConfigBuilder);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
@ -114,109 +198,23 @@ public final class Rest5Clients {
|
||||
.toList().toArray(new Header[0]);
|
||||
}
|
||||
|
||||
// the basic logic to create the http client is copied from the Rest5ClientBuilder class, this is taken from the
|
||||
// Elasticsearch code, as there is no public usable instance in that
|
||||
private static CloseableHttpAsyncClient createHttpClient(ClientConfiguration clientConfiguration) {
|
||||
|
||||
var requestConfigBuilder = RequestConfig.custom();
|
||||
var connectionConfigBuilder = ConnectionConfig.custom();
|
||||
|
||||
Duration connectTimeout = clientConfiguration.getConnectTimeout();
|
||||
|
||||
if (!connectTimeout.isNegative()) {
|
||||
connectionConfigBuilder.setConnectTimeout(
|
||||
Timeout.of(Math.toIntExact(connectTimeout.toMillis()), TimeUnit.MILLISECONDS));
|
||||
}
|
||||
|
||||
Duration socketTimeout = clientConfiguration.getSocketTimeout();
|
||||
|
||||
if (!socketTimeout.isNegative()) {
|
||||
var soTimeout = Timeout.of(Math.toIntExact(socketTimeout.toMillis()), TimeUnit.MILLISECONDS);
|
||||
connectionConfigBuilder.setSocketTimeout(soTimeout);
|
||||
requestConfigBuilder.setConnectionRequestTimeout(soTimeout);
|
||||
} else {
|
||||
connectionConfigBuilder.setSocketTimeout(Timeout.of(DEFAULT_SOCKET_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS));
|
||||
requestConfigBuilder
|
||||
.setConnectionRequestTimeout(Timeout.of(DEFAULT_RESPONSE_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS));
|
||||
}
|
||||
|
||||
try {
|
||||
SSLContext sslContext = clientConfiguration.getCaFingerprint().isPresent()
|
||||
? TransportUtils.sslContextFromCaFingerprint(clientConfiguration.getCaFingerprint().get())
|
||||
: (clientConfiguration.getSslContext().isPresent()
|
||||
? clientConfiguration.getSslContext().get()
|
||||
: SSLContext.getDefault());
|
||||
|
||||
ConnectionConfig connectionConfig = connectionConfigBuilder.build();
|
||||
|
||||
PoolingAsyncClientConnectionManager defaultConnectionManager = PoolingAsyncClientConnectionManagerBuilder.create()
|
||||
.setDefaultConnectionConfig(connectionConfig)
|
||||
.setMaxConnPerRoute(DEFAULT_MAX_CONN_PER_ROUTE)
|
||||
.setMaxConnTotal(DEFAULT_MAX_CONN_TOTAL)
|
||||
.setTlsStrategy(new BasicClientTlsStrategy(sslContext))
|
||||
.build();
|
||||
|
||||
var requestConfig = requestConfigBuilder.build();
|
||||
|
||||
var immutableRefToHttpClientBuilder = new Object() {
|
||||
HttpAsyncClientBuilder httpClientBuilder = HttpAsyncClientBuilder.create()
|
||||
.setDefaultRequestConfig(requestConfig)
|
||||
.setConnectionManager(defaultConnectionManager)
|
||||
.setUserAgent(VersionInfo.clientVersions())
|
||||
.setTargetAuthenticationStrategy(new DefaultAuthenticationStrategy())
|
||||
.setThreadFactory(new RestClientThreadFactory());
|
||||
};
|
||||
|
||||
clientConfiguration.getProxy().ifPresent(proxy -> {
|
||||
try {
|
||||
var proxyRoutePlanner = new DefaultProxyRoutePlanner(HttpHost.create(proxy));
|
||||
immutableRefToHttpClientBuilder.httpClientBuilder.setRoutePlanner(proxyRoutePlanner);
|
||||
} catch (URISyntaxException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
|
||||
immutableRefToHttpClientBuilder.httpClientBuilder.addRequestInterceptorFirst((request, entity, context) -> {
|
||||
clientConfiguration.getHeadersSupplier().get().forEach((header, values) -> {
|
||||
// The accept and content-type headers are already put on the request, despite this being the first
|
||||
// interceptor.
|
||||
if ("Accept".equalsIgnoreCase(header) || " Content-Type".equalsIgnoreCase(header)) {
|
||||
request.removeHeaders(header);
|
||||
}
|
||||
values.forEach(value -> request.addHeader(header, value));
|
||||
});
|
||||
});
|
||||
|
||||
for (ClientConfiguration.ClientConfigurationCallback<?> clientConfigurer : clientConfiguration
|
||||
.getClientConfigurers()) {
|
||||
if (clientConfigurer instanceof ElasticsearchHttpClientConfigurationCallback httpClientConfigurer) {
|
||||
immutableRefToHttpClientBuilder.httpClientBuilder = httpClientConfigurer.configure(immutableRefToHttpClientBuilder.httpClientBuilder);
|
||||
}
|
||||
}
|
||||
|
||||
return immutableRefToHttpClientBuilder.httpClientBuilder.build();
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new IllegalStateException("could not create the default ssl context", e);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Copied from the Elasticsearch code as this class is not public there.
|
||||
/**
|
||||
* {@link ClientConfiguration.ClientConfigurationCallback} to configure the Rest5Client client with a
|
||||
* {@link Rest5ClientBuilder}
|
||||
*
|
||||
* @since 6.0
|
||||
*/
|
||||
private static class RestClientThreadFactory implements ThreadFactory {
|
||||
private static final AtomicLong CLIENT_THREAD_POOL_ID_GENERATOR = new AtomicLong();
|
||||
private final long clientThreadPoolId;
|
||||
private final AtomicLong clientThreadId;
|
||||
public interface ElasticsearchRest5ClientConfigurationCallback
|
||||
extends ClientConfiguration.ClientConfigurationCallback<Rest5ClientBuilder> {
|
||||
|
||||
private RestClientThreadFactory() {
|
||||
this.clientThreadPoolId = CLIENT_THREAD_POOL_ID_GENERATOR.getAndIncrement();
|
||||
this.clientThreadId = new AtomicLong();
|
||||
static ElasticsearchRest5ClientConfigurationCallback from(
|
||||
Function<Rest5ClientBuilder, Rest5ClientBuilder> rest5ClientBuilderCallback) {
|
||||
|
||||
Assert.notNull(rest5ClientBuilderCallback, "rest5ClientBuilderCallback must not be null");
|
||||
|
||||
return rest5ClientBuilderCallback::apply;
|
||||
}
|
||||
|
||||
public Thread newThread(Runnable runnable) {
|
||||
return new Thread(runnable, String.format(Locale.ROOT, "elasticsearch-rest-client-%d-thread-%d",
|
||||
this.clientThreadPoolId, this.clientThreadId.incrementAndGet()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -238,20 +236,56 @@ public final class Rest5Clients {
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link ClientConfiguration.ClientConfigurationCallback} to configure the Rest5Client client with a
|
||||
* {@link Rest5ClientBuilder}
|
||||
* {@link org.springframework.data.elasticsearch.client.ClientConfiguration.ClientConfigurationCallback} to configure
|
||||
* the Elasticsearch Rest5Client's connection with a {@link ConnectionConfig.Builder}
|
||||
*
|
||||
* @since 6.0
|
||||
*/
|
||||
public interface ElasticsearchRest5ClientConfigurationCallback
|
||||
extends ClientConfiguration.ClientConfigurationCallback<Rest5ClientBuilder> {
|
||||
public interface ElasticsearchConnectionConfigurationCallback
|
||||
extends ClientConfiguration.ClientConfigurationCallback<ConnectionConfig.Builder> {
|
||||
|
||||
static ElasticsearchRest5ClientConfigurationCallback from(
|
||||
Function<Rest5ClientBuilder, Rest5ClientBuilder> rest5ClientBuilderCallback) {
|
||||
static ElasticsearchConnectionConfigurationCallback from(
|
||||
Function<ConnectionConfig.Builder, ConnectionConfig.Builder> connectionConfigBuilderCallback) {
|
||||
|
||||
Assert.notNull(rest5ClientBuilderCallback, "rest5ClientBuilderCallback must not be null");
|
||||
Assert.notNull(connectionConfigBuilderCallback, "connectionConfigBuilderCallback must not be null");
|
||||
|
||||
return rest5ClientBuilderCallback::apply;
|
||||
return connectionConfigBuilderCallback::apply;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link org.springframework.data.elasticsearch.client.ClientConfiguration.ClientConfigurationCallback} to configure
|
||||
* the Elasticsearch Rest5Client's connection manager with a {@link PoolingAsyncClientConnectionManagerBuilder}
|
||||
*
|
||||
* @since 6.0
|
||||
*/
|
||||
public interface ElasticsearchConnectionManagerCallback
|
||||
extends ClientConfiguration.ClientConfigurationCallback<PoolingAsyncClientConnectionManagerBuilder> {
|
||||
|
||||
static ElasticsearchConnectionManagerCallback from(
|
||||
Function<PoolingAsyncClientConnectionManagerBuilder, PoolingAsyncClientConnectionManagerBuilder> connectionManagerBuilderCallback) {
|
||||
|
||||
Assert.notNull(connectionManagerBuilderCallback, "connectionManagerBuilderCallback must not be null");
|
||||
|
||||
return connectionManagerBuilderCallback::apply;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link org.springframework.data.elasticsearch.client.ClientConfiguration.ClientConfigurationCallback} to configure
|
||||
* the Elasticsearch Rest5Client's connection manager with a {@link RequestConfig.Builder}
|
||||
*
|
||||
* @since 6.0
|
||||
*/
|
||||
public interface ElasticsearchRequestConfigCallback
|
||||
extends ClientConfiguration.ClientConfigurationCallback<RequestConfig.Builder> {
|
||||
|
||||
static ElasticsearchRequestConfigCallback from(
|
||||
Function<RequestConfig.Builder, RequestConfig.Builder> requestConfigBuilderCallback) {
|
||||
|
||||
Assert.notNull(requestConfigBuilderCallback, "requestConfigBuilderCallback must not be null");
|
||||
|
||||
return requestConfigBuilderCallback::apply;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,7 @@ package org.springframework.data.elasticsearch.core;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.jspecify.annotations.NonNull;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
|
||||
@ -369,7 +370,7 @@ public class EntityOperations {
|
||||
* @see org.springframework.data.elasticsearch.core.EntityOperations.AdaptableEntity#initializeVersionProperty()
|
||||
*/
|
||||
@Override
|
||||
public T initializeVersionProperty() {
|
||||
public @NonNull T initializeVersionProperty() {
|
||||
return map;
|
||||
}
|
||||
|
||||
@ -389,7 +390,7 @@ public class EntityOperations {
|
||||
}
|
||||
|
||||
@Override
|
||||
public SeqNoPrimaryTerm getSeqNoPrimaryTerm() {
|
||||
public @Nullable SeqNoPrimaryTerm getSeqNoPrimaryTerm() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -398,7 +399,7 @@ public class EntityOperations {
|
||||
* @see org.springframework.data.elasticsearch.core.EntityOperations.AdaptableEntity#incrementVersion()
|
||||
*/
|
||||
@Override
|
||||
public T incrementVersion() {
|
||||
public @NonNull T incrementVersion() {
|
||||
return map;
|
||||
}
|
||||
|
||||
@ -407,7 +408,7 @@ public class EntityOperations {
|
||||
* @see org.springframework.data.elasticsearch.core.EntityOperations.Entity#getBean()
|
||||
*/
|
||||
@Override
|
||||
public T getBean() {
|
||||
public @NonNull T getBean() {
|
||||
return map;
|
||||
}
|
||||
|
||||
@ -425,12 +426,12 @@ public class EntityOperations {
|
||||
* @see org.springframework.data.elasticsearch.core.EntityOperations.Entity#getPersistentEntity()
|
||||
*/
|
||||
@Override
|
||||
public ElasticsearchPersistentEntity<?> getPersistentEntity() {
|
||||
public @Nullable ElasticsearchPersistentEntity<?> getPersistentEntity() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRouting() {
|
||||
public @Nullable String getRouting() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -650,7 +651,7 @@ public class EntityOperations {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRouting() {
|
||||
public @Nullable String getRouting() {
|
||||
|
||||
String routing = routingResolver.getRouting(propertyAccessor.getBean());
|
||||
|
||||
|
@ -714,7 +714,7 @@ public class MappingElasticsearchConverter
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T getPropertyValue(ElasticsearchPersistentProperty property) {
|
||||
public <T> @Nullable T getPropertyValue(ElasticsearchPersistentProperty property) {
|
||||
|
||||
String expression = property.getSpelExpression();
|
||||
Object value = expression != null ? evaluator.evaluate(expression) : accessor.get(property);
|
||||
|
@ -66,8 +66,7 @@ public class AliasActionParameters {
|
||||
return indices;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String[] getAliases() {
|
||||
public String@Nullable[] getAliases() {
|
||||
return aliases;
|
||||
}
|
||||
|
||||
@ -107,8 +106,8 @@ public class AliasActionParameters {
|
||||
}
|
||||
|
||||
public static final class Builder {
|
||||
@Nullable private String[] indices;
|
||||
@Nullable private String[] aliases;
|
||||
private String @Nullable [] indices;
|
||||
private String @Nullable [] aliases;
|
||||
@Nullable private Query filterQuery;
|
||||
@Nullable private Class<?> filterQueryClass;
|
||||
@Nullable private Boolean isHidden;
|
||||
|
@ -55,6 +55,7 @@ public class AliasActions {
|
||||
public AliasActions add(@Nullable AliasAction... actions) {
|
||||
|
||||
if (actions != null) {
|
||||
// noinspection NullableProblems
|
||||
this.actions.addAll(Arrays.asList(actions));
|
||||
}
|
||||
|
||||
|
@ -29,6 +29,7 @@ import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.jspecify.annotations.NonNull;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.data.annotation.Transient;
|
||||
@ -273,7 +274,7 @@ public class MappingBuilder {
|
||||
writeTypeHintMapping(propertiesNode);
|
||||
|
||||
if (entity != null) {
|
||||
entity.doWithProperties((PropertyHandler<ElasticsearchPersistentProperty>) property -> {
|
||||
entity.doWithProperties((PropertyHandler<@NonNull ElasticsearchPersistentProperty>) property -> {
|
||||
try {
|
||||
if (property.isAnnotationPresent(Transient.class) || isInIgnoreFields(property, parentFieldAnnotation)) {
|
||||
return;
|
||||
|
@ -35,7 +35,7 @@ public record PutIndexTemplateRequest(String name, String[] indexPatterns, @Null
|
||||
public static class Builder {
|
||||
|
||||
@Nullable private String name;
|
||||
@Nullable private String[] indexPatterns;
|
||||
private String @Nullable [] indexPatterns;
|
||||
@Nullable private Settings settings;
|
||||
@Nullable private Document mapping;
|
||||
@Nullable AliasActions aliasActions;
|
||||
|
@ -81,7 +81,7 @@ public class TemplateData {
|
||||
@Nullable Document mapping;
|
||||
int order;
|
||||
@Nullable Integer version;
|
||||
@Nullable private String[] indexPatterns;
|
||||
@Nullable private String@Nullable [] indexPatterns;
|
||||
@Nullable private Map<String, AliasData> aliases;
|
||||
|
||||
private TemplateDataBuilder() {}
|
||||
|
@ -65,7 +65,7 @@ public interface ElasticsearchPersistentEntity<T> extends PersistentEntity<T, El
|
||||
String getIndexStoreType();
|
||||
|
||||
@Override
|
||||
ElasticsearchPersistentProperty getVersionProperty();
|
||||
@Nullable ElasticsearchPersistentProperty getVersionProperty();
|
||||
|
||||
@Nullable
|
||||
String settingPath();
|
||||
|
@ -23,6 +23,7 @@ import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.jspecify.annotations.NonNull;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.springframework.core.annotation.AnnotatedElementUtils;
|
||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||
@ -298,7 +299,7 @@ public class SimpleElasticsearchPersistentEntity<T> extends BasicPersistentEntit
|
||||
|
||||
return fieldNamePropertyCache.computeIfAbsent(fieldName, key -> {
|
||||
AtomicReference<ElasticsearchPersistentProperty> propertyRef = new AtomicReference<>();
|
||||
doWithProperties((PropertyHandler<ElasticsearchPersistentProperty>) property -> {
|
||||
doWithProperties((PropertyHandler<@NonNull ElasticsearchPersistentProperty>) property -> {
|
||||
if (key.equals(property.getFieldName())) {
|
||||
propertyRef.set(property);
|
||||
}
|
||||
@ -552,10 +553,10 @@ public class SimpleElasticsearchPersistentEntity<T> extends BasicPersistentEntit
|
||||
short replicas;
|
||||
@Nullable String refreshIntervall;
|
||||
@Nullable String indexStoreType;
|
||||
@Nullable private String[] sortFields;
|
||||
private Setting.@Nullable SortOrder[] sortOrders;
|
||||
private Setting.@Nullable SortMode[] sortModes;
|
||||
private Setting.@Nullable SortMissing[] sortMissingValues;
|
||||
private String @Nullable [] sortFields;
|
||||
private Setting.@Nullable SortOrder @Nullable [] sortOrders;
|
||||
private Setting.@Nullable SortMode @Nullable [] sortModes;
|
||||
private Setting.@Nullable SortMissing @Nullable [] sortMissingValues;
|
||||
|
||||
Settings toSettings() {
|
||||
|
||||
|
@ -200,7 +200,7 @@ public abstract class BaseQueryBuilder<Q extends BaseQuery, SELF extends BaseQue
|
||||
/**
|
||||
* @since 5.1
|
||||
*/
|
||||
public Integer getReactiveBatchSize() {
|
||||
public @Nullable Integer getReactiveBatchSize() {
|
||||
return reactiveBatchSize;
|
||||
}
|
||||
|
||||
|
@ -344,8 +344,8 @@ public class ByQueryResponse {
|
||||
*
|
||||
* @return a new {@link SearchFailureBuilder} to build {@link SearchFailure}
|
||||
*/
|
||||
public static SearchFailureBuilder builder() {
|
||||
return new SearchFailureBuilder();
|
||||
public static SearchFailureBuilder builder(Throwable reason) {
|
||||
return new SearchFailureBuilder(reason);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -358,7 +358,9 @@ public class ByQueryResponse {
|
||||
@Nullable private Integer shardId;
|
||||
@Nullable private String nodeId;
|
||||
|
||||
private SearchFailureBuilder() {}
|
||||
private SearchFailureBuilder(Throwable reason) {
|
||||
this.reason = reason;
|
||||
}
|
||||
|
||||
public SearchFailureBuilder withReason(Throwable reason) {
|
||||
this.reason = reason;
|
||||
|
@ -63,12 +63,12 @@ public class FetchSourceFilter implements SourceFilter {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getIncludes() {
|
||||
public @Nullable String[] getIncludes() {
|
||||
return includes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getExcludes() {
|
||||
public @Nullable String[] getExcludes() {
|
||||
return excludes;
|
||||
}
|
||||
}
|
||||
|
@ -26,8 +26,8 @@ import org.jspecify.annotations.Nullable;
|
||||
public class FetchSourceFilterBuilder {
|
||||
|
||||
@Nullable private Boolean fetchSource;
|
||||
@Nullable private String[] includes;
|
||||
@Nullable private String[] excludes;
|
||||
private String @Nullable [] includes;
|
||||
private String @Nullable [] excludes;
|
||||
|
||||
public FetchSourceFilterBuilder withIncludes(String... includes) {
|
||||
this.includes = includes;
|
||||
|
@ -15,6 +15,7 @@
|
||||
*/
|
||||
package org.springframework.data.elasticsearch.core.query;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.elasticsearch.core.geo.GeoPoint;
|
||||
|
||||
@ -92,7 +93,7 @@ public class GeoDistanceOrder extends Order {
|
||||
getIgnoreUnmapped());
|
||||
}
|
||||
|
||||
public GeoDistanceOrder with(Mode mode) {
|
||||
public GeoDistanceOrder with(@Nullable Mode mode) {
|
||||
return new GeoDistanceOrder(getProperty(), getGeoPoint(), getDirection(), getDistanceType(), mode, getUnit(),
|
||||
getIgnoreUnmapped());
|
||||
}
|
||||
|
@ -121,7 +121,7 @@ public class HasChildQuery {
|
||||
|
||||
public static final class Builder {
|
||||
private final String type;
|
||||
private Query query;
|
||||
@Nullable private Query query;
|
||||
|
||||
@Nullable private Boolean ignoreUnmapped;
|
||||
|
||||
|
@ -92,7 +92,7 @@ public class HasParentQuery {
|
||||
|
||||
public static class Builder {
|
||||
private final String parentType;
|
||||
private Query query;
|
||||
@Nullable private Query query;
|
||||
|
||||
@Nullable private Boolean score;
|
||||
@Nullable private Boolean ignoreUnmapped;
|
||||
|
@ -32,14 +32,14 @@ public interface SourceFilter {
|
||||
/**
|
||||
* @return the name of the fields to include in a response.
|
||||
*/
|
||||
@Nullable
|
||||
String[] getIncludes();
|
||||
|
||||
String@Nullable[] getIncludes();
|
||||
|
||||
/**
|
||||
* @return the names of the fields to exclude from a response.
|
||||
*/
|
||||
@Nullable
|
||||
String[] getExcludes();
|
||||
|
||||
String@Nullable[] getExcludes();
|
||||
|
||||
/**
|
||||
* Flag to set the _source parameter in a query to true or false. If this is not null, the values returned from
|
||||
|
@ -42,8 +42,8 @@ public class UpdateQuery {
|
||||
@Nullable private final Boolean fetchSource;
|
||||
@Nullable private final List<String> fetchSourceIncludes;
|
||||
@Nullable private final List<String> fetchSourceExcludes;
|
||||
@Nullable private final Integer ifSeqNo;
|
||||
@Nullable private final Integer ifPrimaryTerm;
|
||||
@Nullable private final Long ifSeqNo;
|
||||
@Nullable private final Long ifPrimaryTerm;
|
||||
@Nullable private final RefreshPolicy refreshPolicy;
|
||||
@Nullable private final Integer retryOnConflict;
|
||||
@Nullable private final String timeout;
|
||||
@ -71,8 +71,8 @@ public class UpdateQuery {
|
||||
private UpdateQuery(String id, @Nullable String script, @Nullable Map<String, Object> params,
|
||||
@Nullable Document document, @Nullable Document upsert, @Nullable String lang, @Nullable String routing,
|
||||
@Nullable Boolean scriptedUpsert, @Nullable Boolean docAsUpsert, @Nullable Boolean fetchSource,
|
||||
@Nullable List<String> fetchSourceIncludes, @Nullable List<String> fetchSourceExcludes, @Nullable Integer ifSeqNo,
|
||||
@Nullable Integer ifPrimaryTerm, @Nullable RefreshPolicy refreshPolicy, @Nullable Integer retryOnConflict,
|
||||
@Nullable List<String> fetchSourceIncludes, @Nullable List<String> fetchSourceExcludes, @Nullable Long ifSeqNo,
|
||||
@Nullable Long ifPrimaryTerm, @Nullable RefreshPolicy refreshPolicy, @Nullable Integer retryOnConflict,
|
||||
@Nullable String timeout, @Nullable String waitForActiveShards, @Nullable Query query,
|
||||
@Nullable Boolean abortOnVersionConflict, @Nullable Integer batchSize, @Nullable Integer maxDocs,
|
||||
@Nullable Integer maxRetries, @Nullable String pipeline, @Nullable Float requestsPerSecond,
|
||||
@ -172,12 +172,12 @@ public class UpdateQuery {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Integer getIfSeqNo() {
|
||||
public Long getIfSeqNo() {
|
||||
return ifSeqNo;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Integer getIfPrimaryTerm() {
|
||||
public Long getIfPrimaryTerm() {
|
||||
return ifPrimaryTerm;
|
||||
}
|
||||
|
||||
@ -268,7 +268,7 @@ public class UpdateQuery {
|
||||
}
|
||||
|
||||
public static final class Builder {
|
||||
private String id;
|
||||
private String id = "";
|
||||
@Nullable private String script = null;
|
||||
@Nullable private Map<String, Object> params;
|
||||
@Nullable private Document document = null;
|
||||
@ -278,8 +278,8 @@ public class UpdateQuery {
|
||||
@Nullable private Boolean scriptedUpsert;
|
||||
@Nullable private Boolean docAsUpsert;
|
||||
@Nullable private Boolean fetchSource;
|
||||
@Nullable private Integer ifSeqNo;
|
||||
@Nullable private Integer ifPrimaryTerm;
|
||||
@Nullable private Long ifSeqNo;
|
||||
@Nullable private Long ifPrimaryTerm;
|
||||
@Nullable private RefreshPolicy refreshPolicy;
|
||||
@Nullable private Integer retryOnConflict;
|
||||
@Nullable private String timeout;
|
||||
@ -351,12 +351,12 @@ public class UpdateQuery {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withIfSeqNo(Integer ifSeqNo) {
|
||||
public Builder withIfSeqNo(Long ifSeqNo) {
|
||||
this.ifSeqNo = ifSeqNo;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withIfPrimaryTerm(Integer ifPrimaryTerm) {
|
||||
public Builder withIfPrimaryTerm(Long ifPrimaryTerm) {
|
||||
this.ifPrimaryTerm = ifPrimaryTerm;
|
||||
return this;
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ package org.springframework.data.elasticsearch.repository.query;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations;
|
||||
import org.springframework.data.elasticsearch.core.query.BaseQuery;
|
||||
import org.springframework.data.elasticsearch.core.query.SearchTemplateQuery;
|
||||
@ -33,7 +34,7 @@ import org.springframework.util.Assert;
|
||||
public class ReactiveRepositorySearchTemplateQuery extends AbstractReactiveElasticsearchRepositoryQuery {
|
||||
|
||||
private String id;
|
||||
private Map<String, Object> params;
|
||||
private Map<String, Object> params = Map.of();
|
||||
|
||||
public ReactiveRepositorySearchTemplateQuery(ReactiveElasticsearchQueryMethod queryMethod,
|
||||
ReactiveElasticsearchOperations elasticsearchOperations,
|
||||
|
@ -33,7 +33,7 @@ import org.springframework.util.Assert;
|
||||
public class RepositorySearchTemplateQuery extends AbstractElasticsearchRepositoryQuery {
|
||||
|
||||
private String id;
|
||||
private Map<String, Object> params;
|
||||
private Map<String, Object> params = Map.of();
|
||||
|
||||
public RepositorySearchTemplateQuery(ElasticsearchQueryMethod queryMethod,
|
||||
ElasticsearchOperations elasticsearchOperations, ValueExpressionDelegate valueExpressionDelegate,
|
||||
|
@ -82,7 +82,7 @@ class ExampleCriteriaMapper {
|
||||
|
||||
Object propertyValue = propertyAccessor.getProperty(property);
|
||||
if (property.isMap() && propertyValue != null) {
|
||||
for (Map.Entry<String, Object> entry : ((Map<String, Object>) propertyValue).entrySet()) {
|
||||
for (Map.Entry<String, @Nullable Object> entry : ((Map<String, @Nullable Object>) propertyValue).entrySet()) {
|
||||
String key = entry.getKey();
|
||||
Object value = entry.getValue();
|
||||
criteria = applyPropertySpec(propertyPath + "." + key, value, exampleSpecAccessor, property, matchMode,
|
||||
@ -96,7 +96,7 @@ class ExampleCriteriaMapper {
|
||||
return criteria;
|
||||
}
|
||||
|
||||
private Criteria applyPropertySpec(String path, Object propertyValue, ExampleMatcherAccessor exampleSpecAccessor,
|
||||
private Criteria applyPropertySpec(String path, @Nullable Object propertyValue, ExampleMatcherAccessor exampleSpecAccessor,
|
||||
ElasticsearchPersistentProperty property, ExampleMatcher.MatchMode matchMode, Criteria criteria) {
|
||||
|
||||
if (exampleSpecAccessor.isIgnoreCaseForPath(path)) {
|
||||
|
@ -47,13 +47,14 @@ public class QueryByExampleElasticsearchExecutor<T> implements QueryByExampleExe
|
||||
|
||||
@Override
|
||||
public <S extends T> Optional<S> findOne(Example<S> example) {
|
||||
CriteriaQuery criteriaQuery = CriteriaQuery.builder(exampleCriteriaMapper.criteria(example)).withMaxResults(2).build();
|
||||
CriteriaQuery criteriaQuery = CriteriaQuery.builder(exampleCriteriaMapper.criteria(example)).withMaxResults(2)
|
||||
.build();
|
||||
SearchHits<S> searchHits = operations.search(criteriaQuery, example.getProbeType(),
|
||||
operations.getIndexCoordinatesFor(example.getProbeType()));
|
||||
if (searchHits.getTotalHits() > 1) {
|
||||
throw new org.springframework.dao.IncorrectResultSizeDataAccessException(1);
|
||||
}
|
||||
return Optional.ofNullable(searchHits).filter(SearchHits::hasSearchHits)
|
||||
return Optional.of(searchHits).filter(SearchHits::hasSearchHits)
|
||||
.map(result -> (List<S>) SearchHitSupport.unwrapSearchHits(result)).map(s -> s.get(0));
|
||||
}
|
||||
|
||||
|
@ -39,11 +39,11 @@ import org.springframework.util.MultiValueMapAdapter;
|
||||
* @author Peter-Josef Meisch
|
||||
* @since 5.0
|
||||
*/
|
||||
public class HttpHeaders implements MultiValueMap<String, String> {
|
||||
public class HttpHeaders implements MultiValueMap<String, @Nullable String> {
|
||||
|
||||
public static final String AUTHORIZATION = "Authorization";
|
||||
|
||||
private final MultiValueMap<String, String> delegate;
|
||||
private final MultiValueMap<String, @Nullable String> delegate;
|
||||
|
||||
public HttpHeaders() {
|
||||
this.delegate = new MultiValueMapAdapter<>(new LinkedCaseInsensitiveMap<>(Locale.ENGLISH));
|
||||
@ -62,12 +62,12 @@ public class HttpHeaders implements MultiValueMap<String, String> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addAll(String key, List<? extends String> values) {
|
||||
public void addAll(String key, List<? extends @Nullable String> values) {
|
||||
delegate.addAll(key, values);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addAll(MultiValueMap<String, String> values) {
|
||||
public void addAll(MultiValueMap<String, @Nullable String> values) {
|
||||
delegate.addAll(values);
|
||||
}
|
||||
|
||||
@ -77,12 +77,12 @@ public class HttpHeaders implements MultiValueMap<String, String> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAll(Map<String, String> values) {
|
||||
public void setAll(Map<String, @Nullable String> values) {
|
||||
delegate.setAll(values);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> toSingleValueMap() {
|
||||
public Map<String, @Nullable String> toSingleValueMap() {
|
||||
return delegate.toSingleValueMap();
|
||||
}
|
||||
// endregion
|
||||
@ -110,18 +110,18 @@ public class HttpHeaders implements MultiValueMap<String, String> {
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public List<String> get(Object key) {
|
||||
public List<@Nullable String> get(Object key) {
|
||||
return delegate.get(key);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public List<String> put(String key, List<String> value) {
|
||||
public List<@Nullable String> put(String key, List<@Nullable String> value) {
|
||||
return delegate.put(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> remove(Object key) {
|
||||
public List<@Nullable String> remove(Object key) {
|
||||
return delegate.remove(key);
|
||||
}
|
||||
|
||||
|
@ -47,7 +47,6 @@ import org.springframework.data.elasticsearch.support.HttpHeaders;
|
||||
|
||||
import com.github.tomakehurst.wiremock.WireMockServer;
|
||||
import com.github.tomakehurst.wiremock.client.WireMock;
|
||||
import com.github.tomakehurst.wiremock.common.ConsoleNotifier;
|
||||
import com.github.tomakehurst.wiremock.matching.AnythingPattern;
|
||||
import com.github.tomakehurst.wiremock.matching.EqualToPattern;
|
||||
import com.github.tomakehurst.wiremock.stubbing.StubMapping;
|
||||
@ -104,8 +103,11 @@ public class RestClientsTest {
|
||||
defaultHeaders.add("def2", "def2-1");
|
||||
|
||||
AtomicInteger supplierCount = new AtomicInteger(1);
|
||||
AtomicInteger httpClientConfigurerCount = new AtomicInteger(0);
|
||||
AtomicInteger restClientConfigurerCount = new AtomicInteger(0);
|
||||
AtomicInteger httpClientConfigurerCount = new AtomicInteger(0);
|
||||
AtomicInteger connectionConfigurerCount = new AtomicInteger(0);
|
||||
AtomicInteger connectionManagerConfigurerCount = new AtomicInteger(0);
|
||||
AtomicInteger requestConfigurerCount = new AtomicInteger(0);
|
||||
|
||||
ClientConfigurationBuilder configurationBuilder = new ClientConfigurationBuilder();
|
||||
configurationBuilder //
|
||||
@ -120,17 +122,31 @@ public class RestClientsTest {
|
||||
});
|
||||
|
||||
if (clientUnderTestFactory instanceof ELCRest5ClientUnderTestFactory) {
|
||||
configurationBuilder.withClientConfigurer(
|
||||
Rest5Clients.ElasticsearchRest5ClientConfigurationCallback.from(rest5ClientBuilder -> {
|
||||
restClientConfigurerCount.incrementAndGet();
|
||||
return rest5ClientBuilder;
|
||||
}));
|
||||
configurationBuilder.withClientConfigurer(
|
||||
Rest5Clients.ElasticsearchHttpClientConfigurationCallback.from(httpClientBuilder -> {
|
||||
httpClientConfigurerCount.incrementAndGet();
|
||||
return httpClientBuilder;
|
||||
}));
|
||||
configurationBuilder.withClientConfigurer(
|
||||
Rest5Clients.ElasticsearchRest5ClientConfigurationCallback.from(rest5ClientBuilder -> {
|
||||
restClientConfigurerCount.incrementAndGet();
|
||||
return rest5ClientBuilder;
|
||||
Rest5Clients.ElasticsearchConnectionConfigurationCallback.from(connectionConfigBuilder -> {
|
||||
connectionConfigurerCount.incrementAndGet();
|
||||
return connectionConfigBuilder;
|
||||
}));
|
||||
configurationBuilder.withClientConfigurer(
|
||||
Rest5Clients.ElasticsearchConnectionManagerCallback.from(connectionManagerBuilder -> {
|
||||
connectionManagerConfigurerCount.incrementAndGet();
|
||||
return connectionManagerBuilder;
|
||||
}));
|
||||
configurationBuilder.withClientConfigurer(
|
||||
Rest5Clients.ElasticsearchRequestConfigCallback.from(requestConfigBuilder -> {
|
||||
requestConfigurerCount.incrementAndGet();
|
||||
return requestConfigBuilder;
|
||||
}));
|
||||
|
||||
} else if (clientUnderTestFactory instanceof ELCRestClientUnderTestFactory) {
|
||||
configurationBuilder.withClientConfigurer(
|
||||
RestClients.ElasticsearchHttpClientConfigurationCallback.from(httpClientBuilder -> {
|
||||
@ -177,8 +193,12 @@ public class RestClientsTest {
|
||||
;
|
||||
}
|
||||
|
||||
assertThat(restClientConfigurerCount).hasValue(clientUnderTestFactory.getExpectedRestClientConfigurerCalls());
|
||||
assertThat(httpClientConfigurerCount).hasValue(1);
|
||||
assertThat(restClientConfigurerCount).hasValue(clientUnderTestFactory.getExpectedRestClientConfigCalls());
|
||||
assertThat(connectionConfigurerCount).hasValue(clientUnderTestFactory.getExpectedConnectionConfigurerCalls());
|
||||
assertThat(connectionManagerConfigurerCount)
|
||||
.hasValue(clientUnderTestFactory.getExpectedConnectionManagerConfigurerCalls());
|
||||
assertThat(requestConfigurerCount).hasValue(clientUnderTestFactory.getExpectedRequestConfigurerCalls());
|
||||
});
|
||||
}
|
||||
|
||||
@ -404,11 +424,23 @@ public class RestClientsTest {
|
||||
|
||||
protected abstract String getDisplayName();
|
||||
|
||||
protected Integer getExpectedRestClientConfigCalls() {
|
||||
protected Integer getExpectedRestClientConfigurerCalls() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
protected abstract int getElasticsearchMajorVersion();
|
||||
|
||||
public Integer getExpectedConnectionConfigurerCalls() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public Integer getExpectedConnectionManagerConfigurerCalls() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public Integer getExpectedRequestConfigurerCalls() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -423,7 +455,22 @@ public class RestClientsTest {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Integer getExpectedRestClientConfigCalls() {
|
||||
protected Integer getExpectedRestClientConfigurerCalls() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getExpectedConnectionConfigurerCalls() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getExpectedConnectionManagerConfigurerCalls() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getExpectedRequestConfigurerCalls() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -467,7 +514,7 @@ public class RestClientsTest {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Integer getExpectedRestClientConfigCalls() {
|
||||
protected Integer getExpectedRestClientConfigurerCalls() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -511,7 +558,7 @@ public class RestClientsTest {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Integer getExpectedRestClientConfigCalls() {
|
||||
protected Integer getExpectedRestClientConfigurerCalls() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,7 @@ package org.springframework.data.elasticsearch.config.configuration;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
import org.jspecify.annotations.NonNull;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
@ -49,7 +50,7 @@ public class ReactiveElasticsearchConfigurationELCTests {
|
||||
static class Config extends ReactiveElasticsearchConfiguration {
|
||||
|
||||
@Override
|
||||
public ClientConfiguration clientConfiguration() {
|
||||
public @NonNull ClientConfiguration clientConfiguration() {
|
||||
return ClientConfiguration.builder() //
|
||||
.connectedTo("localhost:9200") //
|
||||
.build();
|
||||
|
@ -71,10 +71,10 @@ public abstract class EnableNestedRepositoriesIntegrationTests {
|
||||
@Field(type = Text, store = true, fielddata = true) private String type;
|
||||
@Nullable
|
||||
@Field(type = Text, store = true, fielddata = true) private String message;
|
||||
@Nullable private int rate;
|
||||
private int rate;
|
||||
@Nullable
|
||||
@ScriptedField private Double scriptedRate;
|
||||
@Nullable private boolean available;
|
||||
private boolean available;
|
||||
@Nullable private String highlightedMessage;
|
||||
@Nullable private GeoPoint location;
|
||||
@Nullable
|
||||
|
@ -114,10 +114,10 @@ public abstract class EnableRepositoriesIntegrationTests implements ApplicationC
|
||||
@Field(type = Text, store = true, fielddata = true) private String type;
|
||||
@Nullable
|
||||
@Field(type = Text, store = true, fielddata = true) private String message;
|
||||
@Nullable private int rate;
|
||||
private int rate;
|
||||
@Nullable
|
||||
@ScriptedField private Double scriptedRate;
|
||||
@Nullable private boolean available;
|
||||
private boolean available;
|
||||
@Nullable private String highlightedMessage;
|
||||
@Nullable private GeoPoint location;
|
||||
@Nullable
|
||||
@ -208,10 +208,10 @@ public abstract class EnableRepositoriesIntegrationTests implements ApplicationC
|
||||
@Nullable private String type;
|
||||
@Nullable
|
||||
@Field(type = FieldType.Text, fielddata = true) private String message;
|
||||
@Nullable private int rate;
|
||||
private int rate;
|
||||
@Nullable
|
||||
@ScriptedField private Long scriptedRate;
|
||||
@Nullable private boolean available;
|
||||
private boolean available;
|
||||
@Nullable private String highlightedMessage;
|
||||
@Nullable private GeoPoint location;
|
||||
@Nullable
|
||||
|
@ -3900,10 +3900,10 @@ public abstract class ElasticsearchIntegrationTests {
|
||||
@Field(type = Text, store = true, fielddata = true) private String type;
|
||||
@Nullable
|
||||
@Field(type = Text, store = true, fielddata = true) private String message;
|
||||
@Nullable private int rate;
|
||||
private int rate;
|
||||
@Nullable
|
||||
@ScriptedField private Double scriptedRate;
|
||||
@Nullable private boolean available;
|
||||
private boolean available;
|
||||
@Nullable private GeoPoint location;
|
||||
@Nullable
|
||||
@Version private Long version;
|
||||
@ -3918,7 +3918,7 @@ public abstract class ElasticsearchIntegrationTests {
|
||||
@Nullable private String type;
|
||||
@Nullable private String message;
|
||||
@Nullable private Long version;
|
||||
@Nullable private int rate;
|
||||
private int rate;
|
||||
@Nullable private GeoPoint location;
|
||||
|
||||
public Builder id(String id) {
|
||||
@ -4115,10 +4115,10 @@ public abstract class ElasticsearchIntegrationTests {
|
||||
@Nullable private String type;
|
||||
@Nullable
|
||||
@Field(type = FieldType.Text, fielddata = true) private String message;
|
||||
@Nullable private int rate;
|
||||
private int rate;
|
||||
@Nullable
|
||||
@ScriptedField private Long scriptedRate;
|
||||
@Nullable private boolean available;
|
||||
private boolean available;
|
||||
@Nullable private GeoPoint location;
|
||||
@Nullable
|
||||
@Version private Long version;
|
||||
@ -4806,8 +4806,7 @@ public abstract class ElasticsearchIntegrationTests {
|
||||
@Document(indexName = "#{@indexNameProvider.indexName()}-immutable-scripted")
|
||||
public static final class ImmutableWithScriptedEntity {
|
||||
@Id private final String id;
|
||||
@Field(type = Integer)
|
||||
@Nullable private final int rate;
|
||||
@Field(type = Integer) private final int rate;
|
||||
@Nullable
|
||||
@ScriptedField private final Double scriptedRate;
|
||||
|
||||
@ -4863,9 +4862,11 @@ public abstract class ElasticsearchIntegrationTests {
|
||||
|
||||
@Document(indexName = "#{@indexNameProvider.indexName()}-readonly-id")
|
||||
static class ReadonlyIdEntity {
|
||||
@Field(type = FieldType.Keyword) private String part1;
|
||||
@Field(type = FieldType.Keyword)
|
||||
@Nullable private String part1;
|
||||
|
||||
@Field(type = FieldType.Keyword) private String part2;
|
||||
@Field(type = FieldType.Keyword)
|
||||
@Nullable private String part2;
|
||||
|
||||
@Id
|
||||
@WriteOnlyProperty
|
||||
@ -4874,7 +4875,7 @@ public abstract class ElasticsearchIntegrationTests {
|
||||
return part1 + '-' + part2;
|
||||
}
|
||||
|
||||
public String getPart1() {
|
||||
public @Nullable String getPart1() {
|
||||
return part1;
|
||||
}
|
||||
|
||||
@ -4882,7 +4883,7 @@ public abstract class ElasticsearchIntegrationTests {
|
||||
this.part1 = part1;
|
||||
}
|
||||
|
||||
public String getPart2() {
|
||||
public @Nullable String getPart2() {
|
||||
return part2;
|
||||
}
|
||||
|
||||
@ -5006,9 +5007,11 @@ public abstract class ElasticsearchIntegrationTests {
|
||||
private static class RootEntity {
|
||||
@Id private String id;
|
||||
|
||||
@Field(type = FieldType.Object) private Child child;
|
||||
@Field(type = FieldType.Object)
|
||||
@Nullable private Child child;
|
||||
|
||||
@Field(type = FieldType.Object) private Parent parent;
|
||||
@Field(type = FieldType.Object)
|
||||
@Nullable private Parent parent;
|
||||
|
||||
@JoinTypeRelations(relations = {
|
||||
@JoinTypeRelation(parent = "parent", children = { "child" })
|
||||
@ -5030,7 +5033,7 @@ public abstract class ElasticsearchIntegrationTests {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Child getChild() {
|
||||
public @Nullable Child getChild() {
|
||||
return child;
|
||||
}
|
||||
|
||||
@ -5038,7 +5041,7 @@ public abstract class ElasticsearchIntegrationTests {
|
||||
this.child = child;
|
||||
}
|
||||
|
||||
public Parent getParent() {
|
||||
public @Nullable Parent getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
|
@ -245,7 +245,7 @@ class EntityOperationsUnitTests {
|
||||
@IndexedIndexName
|
||||
@Nullable private String indexName;
|
||||
|
||||
public String getId() {
|
||||
public @Nullable String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
|
@ -134,7 +134,7 @@ public abstract class LogEntityIntegrationTests {
|
||||
@Nullable
|
||||
@Id private String id;
|
||||
@Nullable private String action;
|
||||
@Nullable private long sequenceCode;
|
||||
private long sequenceCode;
|
||||
@Nullable
|
||||
@Field(type = Ip) private String ip;
|
||||
@Field(type = Date, format = DateFormat.date_time) private java.util.@Nullable Date date;
|
||||
@ -149,7 +149,7 @@ public abstract class LogEntityIntegrationTests {
|
||||
return format;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
public @Nullable String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@ -157,7 +157,7 @@ public abstract class LogEntityIntegrationTests {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getAction() {
|
||||
public @Nullable String getAction() {
|
||||
return action;
|
||||
}
|
||||
|
||||
@ -173,7 +173,7 @@ public abstract class LogEntityIntegrationTests {
|
||||
this.sequenceCode = sequenceCode;
|
||||
}
|
||||
|
||||
public String getIp() {
|
||||
public @Nullable String getIp() {
|
||||
return ip;
|
||||
}
|
||||
|
||||
@ -181,7 +181,7 @@ public abstract class LogEntityIntegrationTests {
|
||||
this.ip = ip;
|
||||
}
|
||||
|
||||
public java.util.Date getDate() {
|
||||
public java.util.@Nullable Date getDate() {
|
||||
return date;
|
||||
}
|
||||
|
||||
|
@ -1298,7 +1298,7 @@ public abstract class ReactiveElasticsearchIntegrationTests {
|
||||
@Id private String id;
|
||||
@Nullable
|
||||
@Field(type = Text, store = true, fielddata = true) private String message;
|
||||
@Nullable private int rate;
|
||||
private int rate;
|
||||
@Nullable
|
||||
@Version private Long version;
|
||||
|
||||
@ -1568,9 +1568,9 @@ public abstract class ReactiveElasticsearchIntegrationTests {
|
||||
|
||||
@Document(indexName = "#{@indexNameProvider.indexName()}-readonly-id")
|
||||
static class ReadonlyIdEntity {
|
||||
@Field(type = FieldType.Keyword) private String part1;
|
||||
@Field(type = FieldType.Keyword) private @Nullable String part1;
|
||||
|
||||
@Field(type = FieldType.Keyword) private String part2;
|
||||
@Field(type = FieldType.Keyword) private @Nullable String part2;
|
||||
|
||||
@Id
|
||||
@WriteOnlyProperty
|
||||
@ -1579,7 +1579,7 @@ public abstract class ReactiveElasticsearchIntegrationTests {
|
||||
return part1 + '-' + part2;
|
||||
}
|
||||
|
||||
public String getPart1() {
|
||||
public @Nullable String getPart1() {
|
||||
return part1;
|
||||
}
|
||||
|
||||
@ -1587,7 +1587,7 @@ public abstract class ReactiveElasticsearchIntegrationTests {
|
||||
this.part1 = part1;
|
||||
}
|
||||
|
||||
public String getPart2() {
|
||||
public @Nullable String getPart2() {
|
||||
return part2;
|
||||
}
|
||||
|
||||
|
@ -164,7 +164,7 @@ public abstract class AggregationIntegrationTests {
|
||||
@Nullable
|
||||
@Field(type = Integer, store = true) private List<Integer> publishedYears = new ArrayList<>();
|
||||
|
||||
@Nullable private int score;
|
||||
private int score;
|
||||
|
||||
public ArticleEntity(@Nullable String id) {
|
||||
this.id = id;
|
||||
|
@ -25,7 +25,15 @@ import java.time.LocalTime;
|
||||
import java.time.OffsetTime;
|
||||
import java.time.ZoneOffset;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.intellij.lang.annotations.Language;
|
||||
@ -128,7 +136,7 @@ public class MappingElasticsearchConverterUnitTests {
|
||||
public void init() {
|
||||
|
||||
SimpleElasticsearchMappingContext mappingContext = new SimpleElasticsearchMappingContext();
|
||||
mappingContext.setInitialEntitySet(Collections.singleton(Rifle.class));
|
||||
mappingContext.setInitialEntitySet(singleton(Rifle.class));
|
||||
mappingContext.afterPropertiesSet();
|
||||
|
||||
mappingElasticsearchConverter = new MappingElasticsearchConverter(mappingContext, new GenericConversionService());
|
||||
@ -389,7 +397,7 @@ public class MappingElasticsearchConverterUnitTests {
|
||||
@Test // DATAES-530
|
||||
public void readListOfConcreteTypesCorrectly() {
|
||||
|
||||
sarahAsMap.put("coWorkers", Collections.singletonList(kyleAsMap));
|
||||
sarahAsMap.put("coWorkers", singletonList(kyleAsMap));
|
||||
|
||||
Person target = mappingElasticsearchConverter.read(Person.class, sarahAsMap);
|
||||
|
||||
@ -414,7 +422,7 @@ public class MappingElasticsearchConverterUnitTests {
|
||||
|
||||
Map<String, Object> target = writeToMap(sarahConnor);
|
||||
assertThat(target.get("shippingAddresses")).isInstanceOf(Map.class);
|
||||
assertThat(target.get("shippingAddresses")).isEqualTo(Collections.singletonMap("home", gratiotAveAsMap));
|
||||
assertThat(target.get("shippingAddresses")).isEqualTo(singletonMap("home", gratiotAveAsMap));
|
||||
}
|
||||
|
||||
@Test // DATAES-530
|
||||
@ -433,7 +441,7 @@ public class MappingElasticsearchConverterUnitTests {
|
||||
@Test // DATAES-530
|
||||
public void readConcreteMapCorrectly() {
|
||||
|
||||
sarahAsMap.put("shippingAddresses", Collections.singletonMap("home", gratiotAveAsMap));
|
||||
sarahAsMap.put("shippingAddresses", singletonMap("home", gratiotAveAsMap));
|
||||
|
||||
Person target = mappingElasticsearchConverter.read(Person.class, sarahAsMap);
|
||||
|
||||
@ -443,7 +451,7 @@ public class MappingElasticsearchConverterUnitTests {
|
||||
@Test // DATAES-530
|
||||
public void readInterfaceMapCorrectly() {
|
||||
|
||||
sarahAsMap.put("inventoryMap", Collections.singletonMap("glock19", gunAsMap));
|
||||
sarahAsMap.put("inventoryMap", singletonMap("glock19", gunAsMap));
|
||||
|
||||
Person target = mappingElasticsearchConverter.read(Person.class, sarahAsMap);
|
||||
|
||||
@ -490,7 +498,7 @@ public class MappingElasticsearchConverterUnitTests {
|
||||
public void readGenericListList() {
|
||||
|
||||
Document source = Document.create();
|
||||
source.put("objectList", Collections.singletonList(Arrays.asList(t800AsMap, gunAsMap)));
|
||||
source.put("objectList", singletonList(Arrays.asList(t800AsMap, gunAsMap)));
|
||||
|
||||
Skynet target = mappingElasticsearchConverter.read(Skynet.class, source);
|
||||
|
||||
@ -515,7 +523,7 @@ public class MappingElasticsearchConverterUnitTests {
|
||||
public void readGenericMap() {
|
||||
|
||||
Document source = Document.create();
|
||||
source.put("objectMap", Collections.singletonMap("glock19", gunAsMap));
|
||||
source.put("objectMap", singletonMap("glock19", gunAsMap));
|
||||
|
||||
Skynet target = mappingElasticsearchConverter.read(Skynet.class, source);
|
||||
|
||||
@ -527,23 +535,23 @@ public class MappingElasticsearchConverterUnitTests {
|
||||
|
||||
Skynet skynet = new Skynet();
|
||||
skynet.objectMap = new LinkedHashMap<>();
|
||||
skynet.objectMap.put("inventory", Collections.singletonMap("glock19", gun));
|
||||
skynet.objectMap.put("inventory", singletonMap("glock19", gun));
|
||||
|
||||
Map<String, Object> target = writeToMap(skynet);
|
||||
|
||||
assertThat((Map<String, Object>) target.get("objectMap")).containsEntry("inventory",
|
||||
Collections.singletonMap("glock19", gunAsMap));
|
||||
singletonMap("glock19", gunAsMap));
|
||||
}
|
||||
|
||||
@Test // DATAES-530
|
||||
public void readGenericMapMap() {
|
||||
|
||||
Document source = Document.create();
|
||||
source.put("objectMap", Collections.singletonMap("inventory", Collections.singletonMap("glock19", gunAsMap)));
|
||||
source.put("objectMap", singletonMap("inventory", singletonMap("glock19", gunAsMap)));
|
||||
|
||||
Skynet target = mappingElasticsearchConverter.read(Skynet.class, source);
|
||||
|
||||
assertThat(target.getObjectMap()).containsEntry("inventory", Collections.singletonMap("glock19", gun));
|
||||
assertThat(target.getObjectMap()).containsEntry("inventory", singletonMap("glock19", gun));
|
||||
}
|
||||
|
||||
@Test // DATAES-530
|
||||
@ -575,7 +583,7 @@ public class MappingElasticsearchConverterUnitTests {
|
||||
@Test // DATAES-530
|
||||
public void writesNestedAliased() {
|
||||
|
||||
t800.inventoryList = Collections.singletonList(rifle);
|
||||
t800.inventoryList = singletonList(rifle);
|
||||
Map<String, Object> target = writeToMap(t800);
|
||||
|
||||
assertThat((List<Document>) target.get("inventoryList")).contains(rifleAsMap);
|
||||
@ -589,7 +597,7 @@ public class MappingElasticsearchConverterUnitTests {
|
||||
@Test // DATAES-530
|
||||
public void readsNestedAliased() {
|
||||
|
||||
t800AsMap.put("inventoryList", Collections.singletonList(rifleAsMap));
|
||||
t800AsMap.put("inventoryList", singletonList(rifleAsMap));
|
||||
|
||||
assertThat(mappingElasticsearchConverter.read(Person.class, t800AsMap).getInventoryList()).containsExactly(rifle);
|
||||
}
|
||||
@ -911,12 +919,12 @@ public class MappingElasticsearchConverterUnitTests {
|
||||
void shouldWriteMapContainingCollectionContainingMap() throws JSONException {
|
||||
|
||||
class EntityWithMapCollectionMap {
|
||||
Map<String, Object> map;
|
||||
Map<String, Object> map = Map.of();
|
||||
}
|
||||
class InnerEntity {
|
||||
String prop1;
|
||||
@Nullable String prop1;
|
||||
|
||||
String prop2;
|
||||
@Nullable String prop2;
|
||||
|
||||
public InnerEntity() {}
|
||||
|
||||
@ -928,8 +936,8 @@ public class MappingElasticsearchConverterUnitTests {
|
||||
}
|
||||
|
||||
var entity = new EntityWithMapCollectionMap();
|
||||
entity.map = Collections.singletonMap("collection",
|
||||
Collections.singletonList(Collections.singletonMap("destination", new InnerEntity("prop1", "prop2"))));
|
||||
entity.map = singletonMap("collection",
|
||||
singletonList(singletonMap("destination", new InnerEntity("prop1", "prop2"))));
|
||||
|
||||
var expected = """
|
||||
{
|
||||
@ -1069,67 +1077,79 @@ public class MappingElasticsearchConverterUnitTests {
|
||||
class RangeEntity {
|
||||
|
||||
@Id private String id;
|
||||
@Field(type = FieldType.Integer_Range) private Range<Integer> integerRange;
|
||||
@Field(type = FieldType.Float_Range) private Range<Float> floatRange;
|
||||
@Field(type = FieldType.Long_Range) private Range<Long> longRange;
|
||||
@Field(type = FieldType.Double_Range) private Range<Double> doubleRange;
|
||||
@Field(type = FieldType.Date_Range) private Range<Date> dateRange;
|
||||
@Field(type = FieldType.Date_Range, format = DateFormat.year_month_day) private Range<LocalDate> localDateRange;
|
||||
@Field(type = FieldType.Integer_Range)
|
||||
@Nullable private Range<Integer> integerRange;
|
||||
@Field(type = FieldType.Float_Range)
|
||||
@Nullable private Range<Float> floatRange;
|
||||
@Field(type = FieldType.Long_Range)
|
||||
@Nullable private Range<Long> longRange;
|
||||
@Field(type = FieldType.Double_Range)
|
||||
@Nullable private Range<Double> doubleRange;
|
||||
@Field(type = FieldType.Date_Range)
|
||||
@Nullable private Range<Date> dateRange;
|
||||
@Field(type = FieldType.Date_Range, format = DateFormat.year_month_day)
|
||||
@Nullable private Range<LocalDate> localDateRange;
|
||||
@Field(type = FieldType.Date_Range,
|
||||
format = DateFormat.hour_minute_second_millis) private Range<LocalTime> localTimeRange;
|
||||
format = DateFormat.hour_minute_second_millis)
|
||||
@Nullable private Range<LocalTime> localTimeRange;
|
||||
@Field(type = FieldType.Date_Range,
|
||||
format = DateFormat.date_hour_minute_second_millis) private Range<LocalDateTime> localDateTimeRange;
|
||||
@Field(type = FieldType.Date_Range, format = DateFormat.time) private Range<OffsetTime> offsetTimeRange;
|
||||
@Field(type = FieldType.Date_Range) private Range<ZonedDateTime> zonedDateTimeRange;
|
||||
@Field(type = FieldType.Date_Range, storeNullValue = true) private Range<ZonedDateTime> nullRange;
|
||||
format = DateFormat.date_hour_minute_second_millis)
|
||||
@Nullable private Range<LocalDateTime> localDateTimeRange;
|
||||
@Field(type = FieldType.Date_Range, format = DateFormat.time)
|
||||
@Nullable private Range<OffsetTime> offsetTimeRange;
|
||||
@Field(type = FieldType.Date_Range)
|
||||
@Nullable private Range<ZonedDateTime> zonedDateTimeRange;
|
||||
@Field(type = FieldType.Date_Range, storeNullValue = true)
|
||||
@Nullable private Range<ZonedDateTime> nullRange;
|
||||
|
||||
@Field(type = FieldType.Integer_Range) private List<Range<Integer>> integerRangeList;
|
||||
@Field(type = FieldType.Integer_Range)
|
||||
@Nullable private List<Range<Integer>> integerRangeList;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public Range<Integer> getIntegerRange() {
|
||||
public @Nullable Range<Integer> getIntegerRange() {
|
||||
return integerRange;
|
||||
}
|
||||
|
||||
public Range<Float> getFloatRange() {
|
||||
public @Nullable Range<Float> getFloatRange() {
|
||||
return floatRange;
|
||||
}
|
||||
|
||||
public Range<Long> getLongRange() {
|
||||
public @Nullable Range<Long> getLongRange() {
|
||||
return longRange;
|
||||
}
|
||||
|
||||
public Range<Double> getDoubleRange() {
|
||||
public @Nullable Range<Double> getDoubleRange() {
|
||||
return doubleRange;
|
||||
}
|
||||
|
||||
public Range<Date> getDateRange() {
|
||||
public @Nullable Range<Date> getDateRange() {
|
||||
return dateRange;
|
||||
}
|
||||
|
||||
public Range<LocalDate> getLocalDateRange() {
|
||||
public @Nullable Range<LocalDate> getLocalDateRange() {
|
||||
return localDateRange;
|
||||
}
|
||||
|
||||
public Range<LocalTime> getLocalTimeRange() {
|
||||
public @Nullable Range<LocalTime> getLocalTimeRange() {
|
||||
return localTimeRange;
|
||||
}
|
||||
|
||||
public Range<LocalDateTime> getLocalDateTimeRange() {
|
||||
public @Nullable Range<LocalDateTime> getLocalDateTimeRange() {
|
||||
return localDateTimeRange;
|
||||
}
|
||||
|
||||
public Range<OffsetTime> getOffsetTimeRange() {
|
||||
public @Nullable Range<OffsetTime> getOffsetTimeRange() {
|
||||
return offsetTimeRange;
|
||||
}
|
||||
|
||||
public Range<ZonedDateTime> getZonedDateTimeRange() {
|
||||
public @Nullable Range<ZonedDateTime> getZonedDateTimeRange() {
|
||||
return zonedDateTimeRange;
|
||||
}
|
||||
|
||||
public Range<ZonedDateTime> getNullRange() {
|
||||
public @Nullable Range<ZonedDateTime> getNullRange() {
|
||||
return nullRange;
|
||||
}
|
||||
|
||||
@ -1181,7 +1201,7 @@ public class MappingElasticsearchConverterUnitTests {
|
||||
this.nullRange = nullRange;
|
||||
}
|
||||
|
||||
public List<Range<Integer>> getIntegerRangeList() {
|
||||
public @Nullable List<Range<Integer>> getIntegerRangeList() {
|
||||
return integerRangeList;
|
||||
}
|
||||
|
||||
@ -2639,8 +2659,7 @@ public class MappingElasticsearchConverterUnitTests {
|
||||
@Nullable private GeoPoint pointB;
|
||||
@Nullable
|
||||
@GeoPointField private String pointC;
|
||||
@Nullable
|
||||
@GeoPointField private double[] pointD;
|
||||
@GeoPointField private double @Nullable [] pointD;
|
||||
|
||||
@Nullable
|
||||
public String getId() {
|
||||
@ -2705,12 +2724,11 @@ public class MappingElasticsearchConverterUnitTests {
|
||||
this.pointC = pointC;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public double[] getPointD() {
|
||||
public double @Nullable [] getPointD() {
|
||||
return pointD;
|
||||
}
|
||||
|
||||
public void setPointD(@Nullable double[] pointD) {
|
||||
public void setPointD(double @Nullable [] pointD) {
|
||||
this.pointD = pointD;
|
||||
}
|
||||
}
|
||||
@ -3259,7 +3277,8 @@ public class MappingElasticsearchConverterUnitTests {
|
||||
@Id
|
||||
@Nullable private String id;
|
||||
|
||||
@Field(type = FieldType.Nested, name = "level-one") private List<Level1> level1Entries;
|
||||
@Field(type = FieldType.Nested, name = "level-one")
|
||||
@Nullable private List<Level1> level1Entries;
|
||||
|
||||
@Nullable
|
||||
public String getId() {
|
||||
@ -3270,7 +3289,7 @@ public class MappingElasticsearchConverterUnitTests {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public List<Level1> getLevel1Entries() {
|
||||
public @Nullable List<Level1> getLevel1Entries() {
|
||||
return level1Entries;
|
||||
}
|
||||
|
||||
@ -3279,9 +3298,10 @@ public class MappingElasticsearchConverterUnitTests {
|
||||
}
|
||||
|
||||
static class Level1 {
|
||||
@Field(type = FieldType.Nested, name = "level-two") private List<Level2> level2Entries;
|
||||
@Field(type = FieldType.Nested, name = "level-two")
|
||||
@Nullable private List<Level2> level2Entries;
|
||||
|
||||
public List<Level2> getLevel2Entries() {
|
||||
public @Nullable List<Level2> getLevel2Entries() {
|
||||
return level2Entries;
|
||||
}
|
||||
|
||||
@ -3291,9 +3311,10 @@ public class MappingElasticsearchConverterUnitTests {
|
||||
}
|
||||
|
||||
static class Level2 {
|
||||
@Field(type = FieldType.Keyword, name = "key-word") private String keyWord;
|
||||
@Field(type = FieldType.Keyword, name = "key-word")
|
||||
@Nullable private String keyWord;
|
||||
|
||||
public String getKeyWord() {
|
||||
public @Nullable String getKeyWord() {
|
||||
return keyWord;
|
||||
}
|
||||
|
||||
|
@ -424,12 +424,11 @@ public abstract class GeoIntegrationTests {
|
||||
@Nullable private String name;
|
||||
@Nullable
|
||||
@GeoPointField private String locationAsString;
|
||||
@Nullable
|
||||
@GeoPointField private double[] locationAsArray;
|
||||
@GeoPointField private double @Nullable [] locationAsArray;
|
||||
@Nullable
|
||||
@GeoPointField private String locationAsGeoHash;
|
||||
|
||||
public String getId() {
|
||||
public @Nullable String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@ -437,7 +436,7 @@ public abstract class GeoIntegrationTests {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
public @Nullable String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@ -445,7 +444,7 @@ public abstract class GeoIntegrationTests {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getLocationAsString() {
|
||||
public @Nullable String getLocationAsString() {
|
||||
return locationAsString;
|
||||
}
|
||||
|
||||
@ -461,7 +460,7 @@ public abstract class GeoIntegrationTests {
|
||||
this.locationAsArray = locationAsArray;
|
||||
}
|
||||
|
||||
public String getLocationAsGeoHash() {
|
||||
public @Nullable String getLocationAsGeoHash() {
|
||||
return locationAsGeoHash;
|
||||
}
|
||||
|
||||
|
@ -724,8 +724,7 @@ public abstract class MappingBuilderIntegrationTests extends MappingContextBaseT
|
||||
static class DenseVectorEntity {
|
||||
@Nullable
|
||||
@Id private String id;
|
||||
@Nullable
|
||||
@Field(type = Dense_Vector, dims = 3) private float[] dense_vector;
|
||||
@Field(type = Dense_Vector, dims = 3) private float @Nullable [] dense_vector;
|
||||
|
||||
@Nullable
|
||||
public String getId() {
|
||||
@ -736,12 +735,11 @@ public abstract class MappingBuilderIntegrationTests extends MappingContextBaseT
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public float[] getDense_vector() {
|
||||
public float @Nullable [] getDense_vector() {
|
||||
return dense_vector;
|
||||
}
|
||||
|
||||
public void setDense_vector(@Nullable float[] dense_vector) {
|
||||
public void setDense_vector(float @Nullable [] dense_vector) {
|
||||
this.dense_vector = dense_vector;
|
||||
}
|
||||
}
|
||||
@ -915,7 +913,8 @@ public abstract class MappingBuilderIntegrationTests extends MappingContextBaseT
|
||||
@Nullable
|
||||
@Id private String id;
|
||||
|
||||
@Field(type = FieldType.Dense_Vector, dims = 42, knnSimilarity = KnnSimilarity.COSINE) private double[] denseVector;
|
||||
@Field(type = FieldType.Dense_Vector, dims = 42,
|
||||
knnSimilarity = KnnSimilarity.COSINE) private double @Nullable [] denseVector;
|
||||
}
|
||||
|
||||
@Mapping(aliases = {
|
||||
|
@ -1398,7 +1398,7 @@ public class MappingBuilderUnitTests extends MappingContextBaseTests {
|
||||
|
||||
@Field("mapping-property")
|
||||
@Mapping(mappingPath = "/mappings/test-field-analyzed-mappings.json") //
|
||||
@Nullable private byte[] mappingProperty;
|
||||
private byte @Nullable [] mappingProperty;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@ -1820,8 +1820,7 @@ public class MappingBuilderUnitTests extends MappingContextBaseTests {
|
||||
@Nullable private GeoPoint pointB;
|
||||
@Nullable
|
||||
@GeoPointField private String pointC;
|
||||
@Nullable
|
||||
@GeoPointField private double[] pointD;
|
||||
@GeoPointField private double @Nullable [] pointD;
|
||||
|
||||
@Nullable
|
||||
@GeoShapeField private String shape1;
|
||||
@ -1892,12 +1891,11 @@ public class MappingBuilderUnitTests extends MappingContextBaseTests {
|
||||
this.pointC = pointC;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public double[] getPointD() {
|
||||
public double @Nullable [] getPointD() {
|
||||
return pointD;
|
||||
}
|
||||
|
||||
public void setPointD(@Nullable double[] pointD) {
|
||||
public void setPointD(double @Nullable [] pointD) {
|
||||
this.pointD = pointD;
|
||||
}
|
||||
|
||||
@ -2171,8 +2169,7 @@ public class MappingBuilderUnitTests extends MappingContextBaseTests {
|
||||
static class DenseVectorEntity {
|
||||
@Nullable
|
||||
@Id private String id;
|
||||
@Nullable
|
||||
@Field(type = FieldType.Dense_Vector, dims = 16) private float[] my_vector;
|
||||
@Field(type = FieldType.Dense_Vector, dims = 16) private float @Nullable [] my_vector;
|
||||
|
||||
@Nullable
|
||||
public String getId() {
|
||||
@ -2183,12 +2180,11 @@ public class MappingBuilderUnitTests extends MappingContextBaseTests {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public float[] getMy_vector() {
|
||||
public float @Nullable [] getMy_vector() {
|
||||
return my_vector;
|
||||
}
|
||||
|
||||
public void setMy_vector(@Nullable float[] my_vector) {
|
||||
public void setMy_vector(float @Nullable [] my_vector) {
|
||||
this.my_vector = my_vector;
|
||||
}
|
||||
}
|
||||
@ -2198,10 +2194,9 @@ public class MappingBuilderUnitTests extends MappingContextBaseTests {
|
||||
@Nullable
|
||||
@Id private String id;
|
||||
|
||||
@Nullable
|
||||
@Field(type = FieldType.Dense_Vector, dims = 16, elementType = FieldElementType.FLOAT,
|
||||
knnIndexOptions = @KnnIndexOptions(type = KnnAlgorithmType.HNSW, m = 16, efConstruction = 100),
|
||||
knnSimilarity = KnnSimilarity.DOT_PRODUCT) private float[] my_vector;
|
||||
knnSimilarity = KnnSimilarity.DOT_PRODUCT) private float @Nullable [] my_vector;
|
||||
|
||||
@Nullable
|
||||
public String getId() {
|
||||
@ -2212,12 +2207,11 @@ public class MappingBuilderUnitTests extends MappingContextBaseTests {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public float[] getMy_vector() {
|
||||
public float @Nullable [] getMy_vector() {
|
||||
return my_vector;
|
||||
}
|
||||
|
||||
public void setMy_vector(@Nullable float[] my_vector) {
|
||||
public void setMy_vector(float @Nullable [] my_vector) {
|
||||
this.my_vector = my_vector;
|
||||
}
|
||||
}
|
||||
@ -2277,7 +2271,7 @@ public class MappingBuilderUnitTests extends MappingContextBaseTests {
|
||||
static class DenseVectorMisMatchConfidenceIntervalClass {
|
||||
@Field(type = Dense_Vector, dims = 16, elementType = FieldElementType.FLOAT,
|
||||
knnIndexOptions = @KnnIndexOptions(type = KnnAlgorithmType.HNSW, m = 16, confidenceInterval = 0.95F),
|
||||
knnSimilarity = KnnSimilarity.DOT_PRODUCT) private float[] dense_vector;
|
||||
knnSimilarity = KnnSimilarity.DOT_PRODUCT) private float @Nullable [] dense_vector;
|
||||
}
|
||||
|
||||
static class DisabledMappingProperty {
|
||||
|
@ -110,10 +110,10 @@ public class MappingParametersTest extends MappingContextBaseTests {
|
||||
}
|
||||
|
||||
static class DenseVectorInvalidDimsClass {
|
||||
@Field(type = Dense_Vector, dims = 4097) private float[] dense_vector;
|
||||
@Field(type = Dense_Vector, dims = 4097) private float @Nullable [] dense_vector;
|
||||
}
|
||||
|
||||
static class DenseVectorMissingDimsClass {
|
||||
@Field(type = Dense_Vector) private float[] dense_vector;
|
||||
@Field(type = Dense_Vector) private float @Nullable [] dense_vector;
|
||||
}
|
||||
}
|
||||
|
@ -444,7 +444,8 @@ public abstract class ReactiveIndexOperationsIntegrationTests {
|
||||
})
|
||||
private static class EntityWithAliases {
|
||||
@Nullable private @Id String id;
|
||||
@Field(type = Text) private String type;
|
||||
@Field(type = Text)
|
||||
@Nullable private String type;
|
||||
|
||||
@Nullable
|
||||
public String getId() {
|
||||
@ -455,7 +456,7 @@ public abstract class ReactiveIndexOperationsIntegrationTests {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
public @Nullable String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
|
@ -325,7 +325,7 @@ public class SimpleElasticsearchPersistentPropertyUnitTests {
|
||||
|
||||
static class FieldNamingStrategyEntity {
|
||||
@Nullable private String withoutCustomFieldName;
|
||||
@Field(name = "CUStomFIEldnAME") private String withCustomFieldName;
|
||||
@Field(name = "CUStomFIEldnAME") @Nullable private String withCustomFieldName;
|
||||
|
||||
@Nullable
|
||||
public String getWithoutCustomFieldName() {
|
||||
@ -336,7 +336,7 @@ public class SimpleElasticsearchPersistentPropertyUnitTests {
|
||||
this.withoutCustomFieldName = withoutCustomFieldName;
|
||||
}
|
||||
|
||||
public String getWithCustomFieldName() {
|
||||
public @Nullable String getWithCustomFieldName() {
|
||||
return withCustomFieldName;
|
||||
}
|
||||
|
||||
|
@ -715,7 +715,7 @@ public abstract class CriteriaQueryIntegrationTests {
|
||||
@Field(type = Text, store = true, fielddata = true) private String type;
|
||||
@Nullable
|
||||
@Field(type = Text, store = true, fielddata = true) private String message;
|
||||
@Nullable private int rate;
|
||||
private int rate;
|
||||
@Nullable
|
||||
@Version private Long version;
|
||||
|
||||
|
@ -27,7 +27,6 @@ import java.util.Properties;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.testcontainers.elasticsearch.ElasticsearchContainer;
|
||||
@ -41,7 +40,7 @@ import org.testcontainers.utility.DockerImageName;
|
||||
*
|
||||
* @author Peter-Josef Meisch
|
||||
*/
|
||||
public class ClusterConnection implements ExtensionContext.Store.CloseableResource {
|
||||
public class ClusterConnection implements AutoCloseable {
|
||||
|
||||
private static final Log LOGGER = LogFactory.getLog(ClusterConnection.class);
|
||||
|
||||
@ -106,7 +105,7 @@ public class ClusterConnection implements ExtensionContext.Store.CloseableResour
|
||||
LOGGER.warn("DATAES_ELASTICSEARCH_PORT does not contain a number");
|
||||
}
|
||||
|
||||
return ClusterConnectionInfo.builder().withIntegrationtestEnvironment(IntegrationtestEnvironment.get())
|
||||
return ClusterConnectionInfo.builder(IntegrationtestEnvironment.get())
|
||||
.withHostAndPort(host, port).build();
|
||||
}
|
||||
|
||||
@ -138,11 +137,10 @@ public class ClusterConnection implements ExtensionContext.Store.CloseableResour
|
||||
.withEnv(testcontainersProperties).withStartupTimeout(Duration.ofMinutes(2)).withReuse(true);
|
||||
elasticsearchContainer.start();
|
||||
|
||||
return ClusterConnectionInfo.builder() //
|
||||
.withIntegrationtestEnvironment(integrationtestEnvironment)
|
||||
return ClusterConnectionInfo.builder(integrationtestEnvironment)
|
||||
.withHostAndPort(elasticsearchContainer.getHost(),
|
||||
elasticsearchContainer.getMappedPort(ELASTICSEARCH_DEFAULT_PORT)) //
|
||||
.withElasticsearchContainer(elasticsearchContainer) //
|
||||
elasticsearchContainer.getMappedPort(ELASTICSEARCH_DEFAULT_PORT))
|
||||
.withElasticsearchContainer(elasticsearchContainer)
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Could not start Elasticsearch container", e);
|
||||
|
@ -24,7 +24,7 @@ import org.testcontainers.elasticsearch.ElasticsearchContainer;
|
||||
* The {@link #host}, {@link #httpPort} and {@link #useSsl} values specify the values needed to connect to the cluster
|
||||
* with a rest client for both a local started cluster and for one defined by the cluster URL when creating the
|
||||
* {@link ClusterConnection}.<br/>
|
||||
* The object must be created by using a {@link ClusterConnectionInfo.Builder}.
|
||||
* The object must be created by using a {@link Builder}.
|
||||
*
|
||||
* @author Peter-Josef Meisch
|
||||
*/
|
||||
@ -36,8 +36,8 @@ public final class ClusterConnectionInfo {
|
||||
private final String clusterName;
|
||||
@Nullable private final ElasticsearchContainer elasticsearchContainer;
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
public static Builder builder(IntegrationtestEnvironment integrationtestEnvironment) {
|
||||
return new Builder(integrationtestEnvironment);
|
||||
}
|
||||
|
||||
private ClusterConnectionInfo(IntegrationtestEnvironment integrationtestEnvironment, String host, int httpPort,
|
||||
@ -84,13 +84,12 @@ public final class ClusterConnectionInfo {
|
||||
public static class Builder {
|
||||
private IntegrationtestEnvironment integrationtestEnvironment;
|
||||
private boolean useSsl = false;
|
||||
private String host;
|
||||
private String host = "";
|
||||
private int httpPort;
|
||||
@Nullable private ElasticsearchContainer elasticsearchContainer;
|
||||
|
||||
public Builder withIntegrationtestEnvironment(IntegrationtestEnvironment integrationtestEnvironment) {
|
||||
public Builder(IntegrationtestEnvironment integrationtestEnvironment) {
|
||||
this.integrationtestEnvironment = integrationtestEnvironment;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withHostAndPort(String host, int httpPort) {
|
||||
|
@ -176,7 +176,7 @@ public class CdiRepositoryTests {
|
||||
@Nullable
|
||||
@Field(type = FieldType.Float) private Float price;
|
||||
@Nullable private Integer popularity;
|
||||
@Nullable private boolean available;
|
||||
private boolean available;
|
||||
@Nullable private String location;
|
||||
@Nullable private Date lastModified;
|
||||
|
||||
@ -293,11 +293,12 @@ public class CdiRepositoryTests {
|
||||
|
||||
@Id private String id;
|
||||
|
||||
private String name;
|
||||
@Nullable private String name;
|
||||
|
||||
@Field(type = FieldType.Nested) private List<Car> car;
|
||||
@Field(type = FieldType.Nested)
|
||||
@Nullable private List<Car> car;
|
||||
|
||||
@Field(type = FieldType.Nested, includeInParent = true) private List<Book> books;
|
||||
@Field(type = FieldType.Nested, includeInParent = true) private @Nullable List<Book> books;
|
||||
|
||||
}
|
||||
|
||||
|
@ -2443,8 +2443,8 @@ public abstract class CustomMethodRepositoryIntegrationTests {
|
||||
@Field(type = Text, store = true, fielddata = true) private String message;
|
||||
@Nullable
|
||||
@Field(type = Keyword) private String keyword;
|
||||
@Nullable private int rate;
|
||||
@Nullable private boolean available;
|
||||
private int rate;
|
||||
private boolean available;
|
||||
@Nullable private GeoPoint location;
|
||||
@Nullable
|
||||
@Version private Long version;
|
||||
|
@ -116,8 +116,7 @@ public abstract class GeoRepositoryIntegrationTests {
|
||||
@Nullable private GeoPoint pointB;
|
||||
@Nullable
|
||||
@GeoPointField private String pointC;
|
||||
@Nullable
|
||||
@GeoPointField private double[] pointD;
|
||||
@GeoPointField private double @Nullable [] pointD;
|
||||
|
||||
@Nullable
|
||||
public String getId() {
|
||||
@ -182,12 +181,11 @@ public abstract class GeoRepositoryIntegrationTests {
|
||||
this.pointC = pointC;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public double[] getPointD() {
|
||||
public double @Nullable [] getPointD() {
|
||||
return pointD;
|
||||
}
|
||||
|
||||
public void setPointD(@Nullable double[] pointD) {
|
||||
public void setPointD(double @Nullable [] pointD) {
|
||||
this.pointD = pointD;
|
||||
}
|
||||
}
|
||||
|
@ -165,12 +165,11 @@ public abstract class KnnSearchIntegrationTests {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public float[] getVector() {
|
||||
public float @Nullable [] getVector() {
|
||||
return vector;
|
||||
}
|
||||
|
||||
public void setVector(@Nullable float[] vector) {
|
||||
public void setVector(float @Nullable [] vector) {
|
||||
this.vector = vector;
|
||||
}
|
||||
}
|
||||
|
@ -510,7 +510,7 @@ public class RepositoryStringQueryUnitTests extends RepositoryStringQueryUnitTes
|
||||
@Document(indexName = "test-index-person-query-unittest")
|
||||
static class Person {
|
||||
|
||||
@Nullable public int age;
|
||||
public int age;
|
||||
@Nullable
|
||||
@Id private String id;
|
||||
@Nullable private String name;
|
||||
@ -519,7 +519,6 @@ public class RepositoryStringQueryUnitTests extends RepositoryStringQueryUnitTes
|
||||
@Nullable
|
||||
@Field(type = FieldType.Nested, includeInParent = true) private List<Book> books;
|
||||
|
||||
@Nullable
|
||||
public int getAge() {
|
||||
return age;
|
||||
}
|
||||
|
@ -296,7 +296,7 @@ abstract class QueryKeywordsIntegrationTests {
|
||||
@Field(type = FieldType.Keyword) private String text;
|
||||
@Nullable
|
||||
@Field(type = FieldType.Float) private Float price;
|
||||
@Nullable private boolean available;
|
||||
private boolean available;
|
||||
@Nullable
|
||||
@Field(name = "sort-name", type = FieldType.Keyword) private String sortName;
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
*/
|
||||
package org.springframework.data.elasticsearch.repository.query.valueconverter;
|
||||
|
||||
import org.jspecify.annotations.NonNull;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
@ -125,12 +126,12 @@ public abstract class ReactiveValueConverterIntegrationTests {
|
||||
public static final String PREFIX = "text-";
|
||||
|
||||
@Override
|
||||
public Object write(Object value) {
|
||||
public @NonNull Object write(@NonNull Object value) {
|
||||
return PREFIX + value.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object read(Object value) {
|
||||
public @NonNull Object read(@NonNull Object value) {
|
||||
|
||||
String valueString = value.toString();
|
||||
|
||||
|
@ -17,6 +17,7 @@ package org.springframework.data.elasticsearch.repository.query.valueconverter;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
import org.jspecify.annotations.NonNull;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
@ -121,12 +122,12 @@ abstract class ValueConverterIntegrationTests {
|
||||
public static final String PREFIX = "text-";
|
||||
|
||||
@Override
|
||||
public Object write(Object value) {
|
||||
public Object write(@NonNull Object value) {
|
||||
return PREFIX + value.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object read(Object value) {
|
||||
public Object read(@NonNull Object value) {
|
||||
|
||||
String valueString = value.toString();
|
||||
|
||||
|
@ -664,8 +664,8 @@ abstract class ElasticsearchRepositoryIntegrationTests {
|
||||
@Field(type = FieldType.Text, store = true, fielddata = true) private String type;
|
||||
@Nullable
|
||||
@Field(type = FieldType.Text, store = true, fielddata = true) private String message;
|
||||
@Nullable private int rate;
|
||||
@Nullable private boolean available;
|
||||
private int rate;
|
||||
private boolean available;
|
||||
@Nullable
|
||||
@Version private Long version;
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
||||
#
|
||||
#
|
||||
sde.testcontainers.image-name=docker.elastic.co/elasticsearch/elasticsearch
|
||||
sde.testcontainers.image-version=9.0.3
|
||||
sde.testcontainers.image-version=9.0.4
|
||||
#
|
||||
#
|
||||
# needed as we do a DELETE /* at the end of the tests, will be required from 8.0 on, produces a warning since 7.13
|
||||
|
Loading…
x
Reference in New Issue
Block a user