mirror of
https://github.com/spring-projects/spring-data-elasticsearch.git
synced 2024-10-23 08:34:16 +08:00
parent
34b0181014
commit
5b02364384
@ -8,7 +8,3 @@ Do not submit a Pull Request before having created an issue and having discussed
|
||||
== Running the test locally
|
||||
|
||||
In order to run the tests locally with `./mvnw test` you need to have docker running because Spring Data Elasticsearch uses https://www.testcontainers.org/[Testcontainers] to start a local running Elasticsearch instance.
|
||||
|
||||
== Class names of the test classes
|
||||
|
||||
Test classes that do depend on the client have either `ERHLC` (when using the deprecated Elasticsearch `RestHighLevelClient`) or `ELC` (the new `ElasticsearchClient`) in their name.
|
||||
|
49
README.adoc
49
README.adoc
@ -5,13 +5,13 @@ image:https://spring.io/badges/spring-data-elasticsearch/ga.svg[Spring Data Elas
|
||||
The primary goal of the https://projects.spring.io/spring-data[Spring Data] project is to make it easier to build Spring-powered applications that use new data access technologies such as non-relational databases, map-reduce frameworks, and cloud based data services.
|
||||
|
||||
The Spring Data Elasticsearch project provides integration with the https://www.elastic.co/[Elasticsearch] search engine.
|
||||
Key functional areas of Spring Data Elasticsearch are a POJO centric model for interacting with a Elasticsearch Documents and easily writing a Repository style data access layer.
|
||||
Key functional areas of Spring Data Elasticsearch are a POJO centric model for interacting with Elasticsearch Documents and easily writing a Repository style data access layer.
|
||||
|
||||
This project is lead and maintained by the community.
|
||||
|
||||
== Features
|
||||
|
||||
* Spring configuration support using Java based `@Configuration` classes or an XML namespace for a ES clients instances.
|
||||
* Spring configuration support using Java based `@Configuration` classes or an XML namespace for an ES client instances.
|
||||
* `ElasticsearchOperations` class and implementations that increases productivity performing common ES operations.
|
||||
Includes integrated object mapping between documents and POJOs.
|
||||
* Feature Rich Object Mapping integrated with Spring’s Conversion Service
|
||||
@ -19,28 +19,6 @@ Includes integrated object mapping between documents and POJOs.
|
||||
* Automatic implementation of `Repository` interfaces including support for custom search methods.
|
||||
* CDI support for repositories
|
||||
|
||||
== About Elasticsearch versions and clients
|
||||
|
||||
=== Elasticsearch 7.17 client libraries
|
||||
|
||||
At the end of 2021 Elasticsearch with version 7.17 released the new version of their Java client and deprecated the `RestHighLevelCLient` which was the default way to access Elasticsearch up to then.
|
||||
|
||||
Spring Data Elasticsearch will in version 4.4 offer the possibility to optionally use the new client as an alternative to the existing setup using the `RestHighLevelCLient`.
|
||||
The default client that is used still is the `RestHighLevelCLient`, first because the integration of the new client is not yet complete, the new client still has features missing and bugs which will hopefully be resolved soon.
|
||||
Second, and more important, the new Elasticsearch client forces users to switch from using `javax.json.spi.JsonProvider` to `jakarta.json.spi.JsonProvider`.
|
||||
Spring Data Elasticsearch cannot enforce this switch; Spring Boot will switch to `jakarta` with version 3 and then it's safe for Spring Data Elasticsearch to switch to the new client.
|
||||
|
||||
So for version 4.4 Spring Data Elasticsearch will keep using the `RestHighLevelCLient` in version 7.17.x (as long as this will be available).
|
||||
|
||||
=== Elasticsearch 8 client libraries
|
||||
|
||||
In Elasticsearch 8, the `RestHighLevelCLient` has been removed.
|
||||
This means that a switch to this client version can only be done with the next major upgrade which will be Spring Data Elasticsearch 5, based on Spring Data 3, used by Spring Boot 3, based on Spring 6 and Java 17.
|
||||
|
||||
=== Elasticsearch 8 cluster
|
||||
|
||||
It should be possible to use the Elasticsearch 7 client to access a cluster running version 8 by setting the appropriate compatibility headers (see the documentation at https://docs.spring.io/spring-data/elasticsearch/docs/current/reference/html/#elasticsearch.clients.configuration). but I encountered and heard of cases where the response from the server is not parseable by the client although the headers are set, so use with care.
|
||||
|
||||
== Code of Conduct
|
||||
|
||||
This project is governed by the https://github.com/spring-projects/.github/blob/e3cc2ff230d8f1dca06535aa6b5a4a23815861d4/CODE_OF_CONDUCT.md[Spring Code of Conduct].
|
||||
@ -86,25 +64,7 @@ public class MyService {
|
||||
|
||||
=== Using the RestClient
|
||||
|
||||
Provide a configuration like this:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@Configuration
|
||||
public class RestClientConfig extends AbstractElasticsearchConfiguration {
|
||||
|
||||
@Override
|
||||
@Bean
|
||||
public RestHighLevelClient elasticsearchClient() {
|
||||
|
||||
final ClientConfiguration clientConfiguration = ClientConfiguration.builder()
|
||||
.connectedTo("localhost:9200")
|
||||
.build();
|
||||
|
||||
return RestClients.create(clientConfiguration).rest();
|
||||
}
|
||||
}
|
||||
----
|
||||
Please check the [official documentation](https://docs.spring.io/spring-data/elasticsearch/docs/current/reference/html/#elasticsearch.clients.configuration).
|
||||
|
||||
=== Maven configuration
|
||||
|
||||
@ -119,9 +79,6 @@ Add the Maven dependency:
|
||||
</dependency>
|
||||
----
|
||||
|
||||
// NOTE: since Github does not support include directives, the content of
|
||||
// the src/main/asciidoc/reference/preface.adoc file is duplicated here
|
||||
// Always change both files!
|
||||
**Compatibility Matrix**
|
||||
|
||||
The compatibility between Spring Data Elasticsearch, Elasticsearch client drivers and Spring Boot versions can be found in the https://docs.spring.io/spring-data/elasticsearch/docs/current/reference/html/#preface.versions[reference documentation].
|
||||
|
@ -105,98 +105,6 @@ This is a reactive implementation based on the Elasticsearch client implementati
|
||||
Basically one should just use the `ReactiveElasticsearchOperations` to interact with the Elasticsearch cluster.
|
||||
When using repositories, this instance is used under the hood as well.
|
||||
|
||||
[[elasticsearch.clients.resthighlevelclient]]
|
||||
== High Level REST Client (deprecated)
|
||||
|
||||
[CAUTION]
|
||||
====
|
||||
The Elasticsearch Java RestHighLevelClient is deprecated, but still can be configured like shown (make sure to read
|
||||
<<elasticsearch-migration-guide-4.4-5.0.old-client>> as well).
|
||||
|
||||
It should only be used to access an Elasticsearch cluster running version 7, even with the compatibility headers set
|
||||
there are cases where the `RestHighLevelClient` cannot read the responses sent from a version 8 cluster.
|
||||
====
|
||||
|
||||
.RestHighLevelClient
|
||||
====
|
||||
[source,java]
|
||||
----
|
||||
import org.springframework.data.elasticsearch.client.erhlc.AbstractElasticsearchConfiguration;
|
||||
|
||||
@Configuration
|
||||
public class RestClientConfig extends AbstractElasticsearchConfiguration {
|
||||
|
||||
@Override
|
||||
@Bean
|
||||
public RestHighLevelClient elasticsearchClient() {
|
||||
|
||||
final ClientConfiguration clientConfiguration = ClientConfiguration.builder() <1>
|
||||
.connectedTo("localhost:9200")
|
||||
.build();
|
||||
|
||||
return RestClients.create(clientConfiguration).rest(); <2>
|
||||
}
|
||||
}
|
||||
|
||||
// ...
|
||||
|
||||
@Autowired
|
||||
RestHighLevelClient highLevelClient;
|
||||
|
||||
RestClient lowLevelClient = highLevelClient.lowLevelClient(); <3>
|
||||
----
|
||||
|
||||
<1> Use the builder to provide cluster addresses, set default `HttpHeaders` or enable SSL.
|
||||
<2> Create the RestHighLevelClient.
|
||||
<3> It is also possible to obtain the `lowLevelRest()` client.
|
||||
====
|
||||
|
||||
[[elasticsearch.clients.reactive]]
|
||||
== Reactive Client (deprecated)
|
||||
|
||||
The `org.springframework.data.elasticsearch.client.erhlc.ReactiveElasticsearchClient` is a non official driver based on `WebClient`.
|
||||
It uses the request/response objects provided by the Elasticsearch core project.
|
||||
Calls are directly operated on the reactive stack, **not** wrapping async (thread pool bound) responses into reactive types.
|
||||
|
||||
[CAUTION]
|
||||
====
|
||||
This was the first reactive implementation Spring Data Elasticsearch provided, but now is deprecated in favour
|
||||
of the `org.springframework.data.elasticsearch.client.elc.ReactiveElasticsearchClient`
|
||||
which uses the functionality offered by the new Elasticsearch client libraries.
|
||||
====
|
||||
|
||||
.Reactive REST Client (deprecated)
|
||||
====
|
||||
[source,java]
|
||||
----
|
||||
import org.springframework.data.elasticsearch.client.erhlc.AbstractReactiveElasticsearchConfiguration;
|
||||
|
||||
@Configuration
|
||||
public class ReactiveRestClientConfig extends AbstractReactiveElasticsearchConfiguration {
|
||||
|
||||
@Override
|
||||
@Bean
|
||||
public ReactiveElasticsearchClient reactiveElasticsearchClient() {
|
||||
final ClientConfiguration clientConfiguration = ClientConfiguration.builder() <.>
|
||||
.connectedTo("localhost:9200") //
|
||||
.build();
|
||||
return ReactiveRestClients.create(clientConfiguration);
|
||||
|
||||
}
|
||||
}
|
||||
// ...
|
||||
|
||||
Mono<IndexResponse> response = client.index(request ->
|
||||
|
||||
request.index("spring-data")
|
||||
.id(randomID())
|
||||
.source(singletonMap("feature", "reactive-client"));
|
||||
);
|
||||
----
|
||||
|
||||
<.> Use the builder to provide cluster addresses, set default `HttpHeaders` or enable SSL.
|
||||
====
|
||||
|
||||
[[elasticsearch.clients.configuration]]
|
||||
== Client Configuration
|
||||
|
||||
@ -298,38 +206,6 @@ ClientConfiguration.builder()
|
||||
----
|
||||
====
|
||||
|
||||
[[elasticsearch.clients.configuration.headers]]
|
||||
=== Elasticsearch 7 compatibility headers
|
||||
|
||||
When using the deprecated `RestHighLevelClient` and accessing an Elasticsearch cluster that is running on version 8, it is necessary to set the compatibility headers
|
||||
https://www.elastic.co/guide/en/elasticsearch/reference/8.0/rest-api-compatibility.html[see Elasticsearch
|
||||
documentation].
|
||||
|
||||
For the imperative client this must be done by setting the default headers, for the reactive code this must be done using a header supplier:
|
||||
|
||||
CAUTION: Even when these headers are set, there are cases where the response returned from the cluster cannot be
|
||||
parsed with the client. This is not an error in Spring Data Elasticsearch.
|
||||
|
||||
====
|
||||
[source,java]
|
||||
----
|
||||
|
||||
HttpHeaders compatibilityHeaders = new HttpHeaders();
|
||||
compatibilityHeaders.add("Accept", "application/vnd.elasticsearch+json;compatible-with=7");
|
||||
compatibilityHeaders.add("Content-Type", "application/vnd.elasticsearch+json;"
|
||||
+ "compatible-with=7");
|
||||
|
||||
ClientConfiguration clientConfiguration = ClientConfiguration.builder()
|
||||
.connectedTo("localhost:9200")
|
||||
.withProxy("localhost:8080")
|
||||
.withBasicAuth("elastic","hcraescitsale")
|
||||
.withDefaultHeaders(compatibilityHeaders) // this variant for imperative code
|
||||
.withHeaders(() -> compatibilityHeaders) // this variant for reactive code
|
||||
.build();
|
||||
|
||||
----
|
||||
====
|
||||
|
||||
[[elasticsearch.clients.logging]]
|
||||
== Client Logging
|
||||
|
||||
|
@ -6,6 +6,16 @@ This section describes breaking changes from version 5.1.x to 5.2.x and how remo
|
||||
[[elasticsearch-migration-guide-5.1-5.2.breaking-changes]]
|
||||
== Breaking Changes
|
||||
|
||||
|
||||
[[elasticsearch-migration-guide-5.1-5.2.deprecations]]
|
||||
== Deprecations
|
||||
|
||||
=== Removal of deprecated code
|
||||
|
||||
* All the code using the old deprecated `RestHighLevelClient` has been removed.
|
||||
The default Elasticsearch client used since version 5.0 is the (not so) new Elasticsearch Java client.
|
||||
* The `org.springframework.data.elasticsearch.client.ClientLogger` class has been removed.
|
||||
This logger was configured with the `org.springframework.data.elasticsearch.client.WIRE` setting, but was not working with all clients.
|
||||
From version 5 on, use the trace logger available in the Elasticsearch Java client, see <<elasticsearch.clients.logging>>.
|
||||
* The method `org.springframework.data.elasticsearch.core.ElasticsearchOperations.stringIdRepresentation(Object)` has been removed, use the `convertId(Object)` method defined in the same interface instead.
|
||||
* The class `org.springframework.data.elasticsearch.core.Range` has been removed, use `org.springframework.data.domain.Range` instead.
|
||||
* The methods `org.springframework.data.elasticsearch.core.query.IndexQuery.getParentId() and `setParentId(String)` have been removed, they werent used anymore and were no-ops. It has been removed from the `org.springframework.data.elasticsearch.core.query.IndexQuery` class as well.
|
||||
|
@ -59,7 +59,6 @@ class ClientConfigurationBuilder
|
||||
@Nullable private String pathPrefix;
|
||||
@Nullable private String proxy;
|
||||
private Supplier<HttpHeaders> headersSupplier = HttpHeaders::new;
|
||||
@Deprecated private final HttpClientConfigCallback httpClientConfigurer = httpClientBuilder -> httpClientBuilder;
|
||||
private final List<ClientConfiguration.ClientConfigurationCallback<?>> clientConfigurers = new ArrayList<>();
|
||||
|
||||
/*
|
||||
@ -242,7 +241,7 @@ class ClientConfigurationBuilder
|
||||
}
|
||||
|
||||
return new DefaultClientConfiguration(hosts, headers, useSsl, sslContext, caFingerprint, soTimeout, connectTimeout,
|
||||
pathPrefix, hostnameVerifier, proxy, httpClientConfigurer, clientConfigurers, headersSupplier);
|
||||
pathPrefix, hostnameVerifier, proxy, clientConfigurers, headersSupplier);
|
||||
}
|
||||
|
||||
private static InetSocketAddress parse(String hostAndPort) {
|
||||
|
@ -1,195 +0,0 @@
|
||||
/*
|
||||
* Copyright 2018-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.elasticsearch.client;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
* Logging Utility to log client requests and responses. Logs client requests and responses to Elasticsearch to a
|
||||
* dedicated logger: {@code org.springframework.data.elasticsearch.client.WIRE} on trace level.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @author Christoph Strobl
|
||||
* @author Peter-Josef Meisch
|
||||
* @author Oliver Drotbohm
|
||||
* @since 3.2
|
||||
* @deprecated since 5.0, Elasticsearch's RestClient has a trace level logging available.
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract class ClientLogger {
|
||||
|
||||
private static final Log WIRE_LOGGER = LogFactory.getLog("org.springframework.data.elasticsearch.client.WIRE");
|
||||
|
||||
private ClientLogger() {}
|
||||
|
||||
/**
|
||||
* Returns {@literal true} if the logger is enabled.
|
||||
*
|
||||
* @return {@literal true} if the logger is enabled.
|
||||
*/
|
||||
public static boolean isEnabled() {
|
||||
return WIRE_LOGGER.isTraceEnabled();
|
||||
}
|
||||
|
||||
/**
|
||||
* Log an outgoing HTTP request.
|
||||
*
|
||||
* @param logId the correlation id, see {@link #newLogId()}.
|
||||
* @param method HTTP method
|
||||
* @param endpoint URI
|
||||
* @param parameters optional parameters.
|
||||
*/
|
||||
public static void logRequest(String logId, String method, String endpoint, Object parameters) {
|
||||
|
||||
if (isEnabled()) {
|
||||
WIRE_LOGGER.trace(String.format("[%s] Sending request %s %s with parameters: %s", logId, method.toUpperCase(),
|
||||
endpoint, parameters));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Log an outgoing HTTP request.
|
||||
*
|
||||
* @param logId the correlation id, see {@link #newLogId()}.
|
||||
* @param method HTTP method
|
||||
* @param endpoint URI
|
||||
* @param parameters optional parameters.
|
||||
* @param headers a String containing the headers
|
||||
* @since 4.4
|
||||
*/
|
||||
public static void logRequest(String logId, String method, String endpoint, Object parameters, String headers) {
|
||||
|
||||
if (isEnabled()) {
|
||||
WIRE_LOGGER.trace(String.format("[%s] Sending request%n%s %s%nParameters: %s%nHeaders: %s", logId,
|
||||
method.toUpperCase(), endpoint, parameters, headers));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Log an outgoing HTTP request with a request body.
|
||||
*
|
||||
* @param logId the correlation id, see {@link #newLogId()}.
|
||||
* @param method HTTP method
|
||||
* @param endpoint URI
|
||||
* @param parameters optional parameters.
|
||||
* @param body body content supplier.
|
||||
*/
|
||||
public static void logRequest(String logId, String method, String endpoint, Object parameters,
|
||||
Supplier<Object> body) {
|
||||
|
||||
if (isEnabled()) {
|
||||
WIRE_LOGGER.trace(String.format("[%s] Sending request %s %s with parameters: %s%nRequest body: %s", logId,
|
||||
method.toUpperCase(), endpoint, parameters, body.get()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Log an outgoing HTTP request with a request body.
|
||||
*
|
||||
* @param logId the correlation id, see {@link #newLogId()}.
|
||||
* @param method HTTP method
|
||||
* @param endpoint URI
|
||||
* @param parameters optional parameters.
|
||||
* @param headers a String containing the headers
|
||||
* @param body body content supplier.
|
||||
* @since 4.4
|
||||
*/
|
||||
public static void logRequest(String logId, String method, String endpoint, Object parameters, String headers,
|
||||
Supplier<Object> body) {
|
||||
|
||||
if (isEnabled()) {
|
||||
WIRE_LOGGER.trace(String.format("[%s] Sending request%n%s %s%nParameters: %s%nHeaders: %s%nRequest body: %s",
|
||||
logId, method.toUpperCase(), endpoint, parameters, headers, body.get()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Log a raw HTTP response without logging the body.
|
||||
*
|
||||
* @param logId the correlation id, see {@link #newLogId()}.
|
||||
* @param statusCode the HTTP status code.
|
||||
*/
|
||||
public static void logRawResponse(String logId, @Nullable Integer statusCode) {
|
||||
|
||||
if (isEnabled()) {
|
||||
WIRE_LOGGER.trace(String.format("[%s] Received raw response: %d", logId, statusCode));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Log a raw HTTP response without logging the body.
|
||||
*
|
||||
* @param logId the correlation id, see {@link #newLogId()}.
|
||||
* @param statusCode the HTTP status code.
|
||||
* @param headers a String containing the headers
|
||||
*/
|
||||
public static void logRawResponse(String logId, @Nullable Integer statusCode, String headers) {
|
||||
|
||||
if (isEnabled()) {
|
||||
WIRE_LOGGER.trace(String.format("[%s] Received response: %d%n%s", logId, statusCode, headers));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Log a raw HTTP response along with the body.
|
||||
*
|
||||
* @param logId the correlation id, see {@link #newLogId()}.
|
||||
* @param statusCode the HTTP status code.
|
||||
* @param body body content.
|
||||
*/
|
||||
public static void logResponse(String logId, Integer statusCode, String body) {
|
||||
|
||||
if (isEnabled()) {
|
||||
WIRE_LOGGER.trace(String.format("[%s] Received response: %d%nResponse body: %s", logId, statusCode, body));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Log a raw HTTP response along with the body.
|
||||
*
|
||||
* @param logId the correlation id, see {@link #newLogId()}.
|
||||
* @param statusCode the HTTP status code.
|
||||
* @param headers a String containing the headers
|
||||
* @param body body content.
|
||||
* @since 4.4
|
||||
*/
|
||||
public static void logResponse(String logId, @Nullable Integer statusCode, String headers, String body) {
|
||||
|
||||
if (isEnabled()) {
|
||||
WIRE_LOGGER.trace(String.format("[%s] Received response: %d%nHeaders: %s%nResponse body: %s", logId, statusCode,
|
||||
headers, body));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new, unique correlation id to improve tracing across log events.
|
||||
*
|
||||
* @return a new, unique correlation id.
|
||||
*/
|
||||
public static String newLogId() {
|
||||
|
||||
if (!isEnabled()) {
|
||||
return "-";
|
||||
}
|
||||
|
||||
return ObjectUtils.getIdentityHexString(new Object());
|
||||
}
|
||||
}
|
@ -49,15 +49,13 @@ class DefaultClientConfiguration implements ClientConfiguration {
|
||||
@Nullable private final String pathPrefix;
|
||||
@Nullable private final HostnameVerifier hostnameVerifier;
|
||||
@Nullable private final String proxy;
|
||||
private final HttpClientConfigCallback httpClientConfigurer;
|
||||
private final Supplier<HttpHeaders> headersSupplier;
|
||||
private final List<ClientConfigurationCallback<?>> clientConfigurers;
|
||||
|
||||
DefaultClientConfiguration(List<InetSocketAddress> hosts, HttpHeaders headers, boolean useSsl,
|
||||
@Nullable SSLContext sslContext, @Nullable String caFingerprint, Duration soTimeout, Duration connectTimeout,
|
||||
@Nullable String pathPrefix, @Nullable HostnameVerifier hostnameVerifier, @Nullable String proxy,
|
||||
HttpClientConfigCallback httpClientConfigurer, List<ClientConfigurationCallback<?>> clientConfigurers,
|
||||
Supplier<HttpHeaders> headersSupplier) {
|
||||
List<ClientConfigurationCallback<?>> clientConfigurers, Supplier<HttpHeaders> headersSupplier) {
|
||||
|
||||
this.hosts = List.copyOf(hosts);
|
||||
this.headers = headers;
|
||||
@ -69,7 +67,6 @@ class DefaultClientConfiguration implements ClientConfiguration {
|
||||
this.pathPrefix = pathPrefix;
|
||||
this.hostnameVerifier = hostnameVerifier;
|
||||
this.proxy = proxy;
|
||||
this.httpClientConfigurer = httpClientConfigurer;
|
||||
this.clientConfigurers = clientConfigurers;
|
||||
this.headersSupplier = headersSupplier;
|
||||
}
|
||||
|
@ -37,7 +37,6 @@ import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.http.*;
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
import org.apache.http.entity.ByteArrayEntity;
|
||||
import org.apache.http.entity.ContentType;
|
||||
import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
|
||||
import org.apache.http.message.BasicHeader;
|
||||
@ -47,7 +46,6 @@ import org.elasticsearch.client.RequestOptions;
|
||||
import org.elasticsearch.client.RestClient;
|
||||
import org.elasticsearch.client.RestClientBuilder;
|
||||
import org.springframework.data.elasticsearch.client.ClientConfiguration;
|
||||
import org.springframework.data.elasticsearch.client.ClientLogger;
|
||||
import org.springframework.data.elasticsearch.support.HttpHeaders;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
@ -200,13 +198,6 @@ public final class ElasticsearchClients {
|
||||
clientConfiguration.getHostNameVerifier().ifPresent(clientBuilder::setSSLHostnameVerifier);
|
||||
clientBuilder.addInterceptorLast(new CustomHeaderInjector(clientConfiguration.getHeadersSupplier()));
|
||||
|
||||
if (ClientLogger.isEnabled()) {
|
||||
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
|
||||
|
||||
clientBuilder.addInterceptorLast((HttpRequestInterceptor) interceptor);
|
||||
clientBuilder.addInterceptorLast((HttpResponseInterceptor) interceptor);
|
||||
}
|
||||
|
||||
RequestConfig.Builder requestConfigBuilder = RequestConfig.custom();
|
||||
Duration connectTimeout = clientConfiguration.getConnectTimeout();
|
||||
|
||||
@ -284,66 +275,6 @@ public final class ElasticsearchClients {
|
||||
.toArray(org.apache.http.Header[]::new);
|
||||
}
|
||||
|
||||
/**
|
||||
* Logging interceptors for Elasticsearch client logging.
|
||||
*
|
||||
* @see ClientLogger
|
||||
* @since 4.4
|
||||
* @deprecated since 5.0
|
||||
*/
|
||||
@Deprecated
|
||||
private static class HttpLoggingInterceptor implements HttpResponseInterceptor, HttpRequestInterceptor {
|
||||
|
||||
@Override
|
||||
public void process(HttpRequest request, HttpContext context) throws IOException {
|
||||
|
||||
String logId = (String) context.getAttribute(LOG_ID_ATTRIBUTE);
|
||||
|
||||
if (logId == null) {
|
||||
logId = ClientLogger.newLogId();
|
||||
context.setAttribute(LOG_ID_ATTRIBUTE, logId);
|
||||
}
|
||||
|
||||
String headers = Arrays.stream(request.getAllHeaders())
|
||||
.map(header -> header.getName()
|
||||
+ ((header.getName().equals("Authorization")) ? ": *****" : ": " + header.getValue()))
|
||||
.collect(Collectors.joining(", ", "[", "]"));
|
||||
|
||||
if (request instanceof HttpEntityEnclosingRequest entityRequest
|
||||
&& ((HttpEntityEnclosingRequest) request).getEntity() != null) {
|
||||
|
||||
HttpEntity entity = ((HttpEntityEnclosingRequest) request).getEntity();
|
||||
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||
entity.writeTo(buffer);
|
||||
|
||||
if (!entity.isRepeatable()) {
|
||||
entityRequest.setEntity(new ByteArrayEntity(buffer.toByteArray()));
|
||||
}
|
||||
|
||||
ClientLogger.logRequest(logId, request.getRequestLine().getMethod(), request.getRequestLine().getUri(), "",
|
||||
headers, buffer::toString);
|
||||
} else {
|
||||
ClientLogger.logRequest(logId, request.getRequestLine().getMethod(), request.getRequestLine().getUri(), "",
|
||||
headers);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void process(HttpResponse response, HttpContext context) throws IOException {
|
||||
|
||||
String logId = (String) context.getAttribute(LOG_ID_ATTRIBUTE);
|
||||
|
||||
String headers = Arrays.stream(response.getAllHeaders())
|
||||
.map(header -> header.getName()
|
||||
+ ((header.getName().equals("Authorization")) ? ": *****" : ": " + header.getValue()))
|
||||
.collect(Collectors.joining(", ", "[", "]"));
|
||||
|
||||
// no way of logging the body, in this callback, it is not read yet, later there is no callback possibility in
|
||||
// RestClient or RestClientTransport
|
||||
ClientLogger.logRawResponse(logId, response.getStatusLine().getStatusCode(), headers);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Interceptor to inject custom supplied headers.
|
||||
*
|
||||
|
@ -65,9 +65,9 @@ import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* This class contains methods that are common to different implementations of the {@link ElasticsearchOperations}
|
||||
* interface that use different clients, like RestHighLevelClient and the next Java client from Elasticsearch or some
|
||||
* external implementation that might use a different client. This class must not contain imports or use classes that
|
||||
* are specific to one of these implementations.
|
||||
* interface that use different clients, like the different Java clients from Elasticsearch or some external
|
||||
* implementation that might use a different client. This class must not contain imports or use classes that are
|
||||
* specific to one of these implementations.
|
||||
* <p>
|
||||
* <strong>Note:</strong> Although this class is public, it is not considered to be part of the official Spring Data
|
||||
* Elasticsearch API and so might change at any time.
|
||||
@ -418,8 +418,7 @@ public abstract class AbstractElasticsearchTemplate implements ElasticsearchOper
|
||||
ElasticsearchPersistentProperty seqNoPrimaryTermProperty = persistentEntity.getSeqNoPrimaryTermProperty();
|
||||
// noinspection ConstantConditions
|
||||
propertyAccessor.setProperty(seqNoPrimaryTermProperty,
|
||||
new SeqNoPrimaryTerm(indexedObjectInformation.seqNo(),
|
||||
indexedObjectInformation.primaryTerm()));
|
||||
new SeqNoPrimaryTerm(indexedObjectInformation.seqNo(), indexedObjectInformation.primaryTerm()));
|
||||
}
|
||||
|
||||
if (indexedObjectInformation.version() != null && persistentEntity.hasVersionProperty()) {
|
||||
|
@ -77,20 +77,6 @@ public interface ElasticsearchOperations extends DocumentOperations, SearchOpera
|
||||
String getEntityRouting(Object entity);
|
||||
|
||||
// region helper
|
||||
/**
|
||||
* gets the String representation for an id.
|
||||
*
|
||||
* @param id
|
||||
* @return String representation
|
||||
* @since 4.0
|
||||
* @deprecated since 5.0, use {@link ElasticsearchOperations#convertId(Object)}.
|
||||
*/
|
||||
@Deprecated
|
||||
@Nullable
|
||||
default String stringIdRepresentation(@Nullable Object id) {
|
||||
return Objects.toString(id, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an idValue to a String representation. The default implementation calls
|
||||
* {@link ElasticsearchConverter#convertId(Object)}
|
||||
|
@ -1,439 +0,0 @@
|
||||
/*
|
||||
* Copyright 2021-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.elasticsearch.core;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
* Simple value object to work with ranges and boundaries.
|
||||
*
|
||||
* @author Sascha Woo
|
||||
* @since 4.3
|
||||
* @deprecated use {org.springframework.data.domain.Range} instead.
|
||||
*/
|
||||
@Deprecated(since = "5.0", forRemoval = true)
|
||||
public class Range<T> {
|
||||
|
||||
private final static Range<?> UNBOUNDED = Range.of(Bound.unbounded(), Bound.UNBOUNDED);
|
||||
|
||||
/**
|
||||
* The lower bound of the range.
|
||||
*/
|
||||
private final Bound<T> lowerBound;
|
||||
|
||||
/**
|
||||
* The upper bound of the range.
|
||||
*/
|
||||
private final Bound<T> upperBound;
|
||||
|
||||
/**
|
||||
* Creates a new {@link Range} with inclusive bounds for both values.
|
||||
*
|
||||
* @param <T>
|
||||
* @param from must not be {@literal null}.
|
||||
* @param to must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
public static <T> Range<T> closed(T from, T to) {
|
||||
return new Range<>(Bound.inclusive(from), Bound.inclusive(to));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Range with the given value as sole member.
|
||||
*
|
||||
* @param <T>
|
||||
* @param value must not be {@literal null}.
|
||||
* @return
|
||||
* @see Range#closed(Object, Object)
|
||||
*/
|
||||
public static <T> Range<T> just(T value) {
|
||||
return Range.closed(value, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new left-open {@link Range}, i.e. left exclusive, right inclusive.
|
||||
*
|
||||
* @param <T>
|
||||
* @param from must not be {@literal null}.
|
||||
* @param to must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
public static <T> Range<T> leftOpen(T from, T to) {
|
||||
return new Range<>(Bound.exclusive(from), Bound.inclusive(to));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a left-unbounded {@link Range} (the left bound set to {@link Bound#unbounded()}) with the given right
|
||||
* bound.
|
||||
*
|
||||
* @param <T>
|
||||
* @param to the right {@link Bound}, must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
public static <T> Range<T> leftUnbounded(Bound<T> to) {
|
||||
return new Range<>(Bound.unbounded(), to);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link Range} with the given lower and upper bound.
|
||||
*
|
||||
* @param lowerBound must not be {@literal null}.
|
||||
* @param upperBound must not be {@literal null}.
|
||||
*/
|
||||
public static <T> Range<T> of(Bound<T> lowerBound, Bound<T> upperBound) {
|
||||
return new Range<>(lowerBound, upperBound);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link Range} with exclusive bounds for both values.
|
||||
*
|
||||
* @param <T>
|
||||
* @param from must not be {@literal null}.
|
||||
* @param to must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
public static <T> Range<T> open(T from, T to) {
|
||||
return new Range<>(Bound.exclusive(from), Bound.exclusive(to));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new right-open {@link Range}, i.e. left inclusive, right exclusive.
|
||||
*
|
||||
* @param <T>
|
||||
* @param from must not be {@literal null}.
|
||||
* @param to must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
public static <T> Range<T> rightOpen(T from, T to) {
|
||||
return new Range<>(Bound.inclusive(from), Bound.exclusive(to));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a right-unbounded {@link Range} (the right bound set to {@link Bound#unbounded()}) with the given left
|
||||
* bound.
|
||||
*
|
||||
* @param <T>
|
||||
* @param from the left {@link Bound}, must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
public static <T> Range<T> rightUnbounded(Bound<T> from) {
|
||||
return new Range<>(from, Bound.unbounded());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an unbounded {@link Range}.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> Range<T> unbounded() {
|
||||
return (Range<T>) UNBOUNDED;
|
||||
}
|
||||
|
||||
private Range(Bound<T> lowerBound, Bound<T> upperBound) {
|
||||
|
||||
Assert.notNull(lowerBound, "Lower bound must not be null!");
|
||||
Assert.notNull(upperBound, "Upper bound must not be null!");
|
||||
|
||||
this.lowerBound = lowerBound;
|
||||
this.upperBound = upperBound;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the {@link Range} contains the given value.
|
||||
*
|
||||
* @param value must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public boolean contains(T value) {
|
||||
|
||||
Assert.notNull(value, "Reference value must not be null!");
|
||||
Assert.isInstanceOf(Comparable.class, value, "value must implements Comparable!");
|
||||
|
||||
boolean greaterThanLowerBound = lowerBound.getValue() //
|
||||
.map(it -> lowerBound.isInclusive() ? ((Comparable<? super T>) it).compareTo(value) <= 0
|
||||
: ((Comparable<? super T>) it).compareTo(value) < 0) //
|
||||
.orElse(true);
|
||||
|
||||
boolean lessThanUpperBound = upperBound.getValue() //
|
||||
.map(it -> upperBound.isInclusive() ? ((Comparable<? super T>) it).compareTo(value) >= 0
|
||||
: ((Comparable<? super T>) it).compareTo(value) > 0) //
|
||||
.orElse(true);
|
||||
|
||||
return greaterThanLowerBound && lessThanUpperBound;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(o instanceof Range<?> range)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ObjectUtils.nullSafeEquals(lowerBound, range.lowerBound)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return ObjectUtils.nullSafeEquals(upperBound, range.upperBound);
|
||||
}
|
||||
|
||||
public Range.Bound<T> getLowerBound() {
|
||||
return this.lowerBound;
|
||||
}
|
||||
|
||||
public Range.Bound<T> getUpperBound() {
|
||||
return this.upperBound;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = ObjectUtils.nullSafeHashCode(lowerBound);
|
||||
result = 31 * result + ObjectUtils.nullSafeHashCode(upperBound);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%s-%s", lowerBound.toPrefixString(), upperBound.toSuffixString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Value object representing a boundary. A boundary can either be {@link #unbounded() unbounded},
|
||||
* {@link #inclusive(Object)} including its value} or {@link #exclusive(Object)} its value}.
|
||||
*/
|
||||
public static final class Bound<T> {
|
||||
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" }) //
|
||||
private static final Bound<?> UNBOUNDED = new Bound(Optional.empty(), true);
|
||||
|
||||
@SuppressWarnings("OptionalUsedAsFieldOrParameterType") private final Optional<T> value;
|
||||
private final boolean inclusive;
|
||||
|
||||
/**
|
||||
* Creates a boundary excluding {@code value}.
|
||||
*
|
||||
* @param value must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
public static Bound<Double> exclusive(double value) {
|
||||
return exclusive((Double) value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a boundary excluding {@code value}.
|
||||
*
|
||||
* @param value must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
public static Bound<Float> exclusive(float value) {
|
||||
return exclusive((Float) value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a boundary excluding {@code value}.
|
||||
*
|
||||
* @param value must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
public static Bound<Integer> exclusive(int value) {
|
||||
return exclusive((Integer) value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a boundary excluding {@code value}.
|
||||
*
|
||||
* @param value must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
public static Bound<Long> exclusive(long value) {
|
||||
return exclusive((Long) value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a boundary excluding {@code value}.
|
||||
*
|
||||
* @param value must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
public static <T> Bound<T> exclusive(T value) {
|
||||
|
||||
Assert.notNull(value, "Value must not be null!");
|
||||
Assert.isInstanceOf(Comparable.class, value, "value must implements Comparable!");
|
||||
return new Bound<>(Optional.of(value), false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a boundary including {@code value}.
|
||||
*
|
||||
* @param value must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
public static Bound<Double> inclusive(double value) {
|
||||
return inclusive((Double) value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a boundary including {@code value}.
|
||||
*
|
||||
* @param value must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
public static Bound<Float> inclusive(float value) {
|
||||
return inclusive((Float) value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a boundary including {@code value}.
|
||||
*
|
||||
* @param value must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
public static Bound<Integer> inclusive(int value) {
|
||||
return inclusive((Integer) value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a boundary including {@code value}.
|
||||
*
|
||||
* @param value must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
public static Bound<Long> inclusive(long value) {
|
||||
return inclusive((Long) value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a boundary including {@code value}.
|
||||
*
|
||||
* @param value must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
public static <T> Bound<T> inclusive(T value) {
|
||||
|
||||
Assert.notNull(value, "Value must not be null!");
|
||||
Assert.isInstanceOf(Comparable.class, value, "value must implements Comparable!");
|
||||
return new Bound<>(Optional.of(value), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an unbounded {@link Bound}.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> Bound<T> unbounded() {
|
||||
return (Bound<T>) UNBOUNDED;
|
||||
}
|
||||
|
||||
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
|
||||
private Bound(Optional<T> value, boolean inclusive) {
|
||||
this.value = value;
|
||||
this.inclusive = inclusive;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(o instanceof Bound<?> bound)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (inclusive != bound.inclusive)
|
||||
return false;
|
||||
|
||||
return ObjectUtils.nullSafeEquals(value, bound.value);
|
||||
}
|
||||
|
||||
public Optional<T> getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = ObjectUtils.nullSafeHashCode(value);
|
||||
result = 31 * result + (inclusive ? 1 : 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this boundary is bounded.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isBounded() {
|
||||
return value.isPresent();
|
||||
}
|
||||
|
||||
public boolean isInclusive() {
|
||||
return this.inclusive;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return value.map(Object::toString).orElse("unbounded");
|
||||
}
|
||||
|
||||
String toPrefixString() {
|
||||
|
||||
return getValue() //
|
||||
.map(Object::toString) //
|
||||
.map(it -> isInclusive() ? "[".concat(it) : "(".concat(it)) //
|
||||
.orElse("unbounded");
|
||||
}
|
||||
|
||||
String toSuffixString() {
|
||||
|
||||
return getValue() //
|
||||
.map(Object::toString) //
|
||||
.map(it -> isInclusive() ? it.concat("]") : it.concat(")")) //
|
||||
.orElse("unbounded");
|
||||
}
|
||||
}
|
||||
}
|
@ -76,7 +76,6 @@ public class MappingBuilder {
|
||||
|
||||
private static final String FIELD_INDEX = "index";
|
||||
private static final String FIELD_PROPERTIES = "properties";
|
||||
@Deprecated private static final String FIELD_PARENT = "_parent";
|
||||
private static final String FIELD_CONTEXT_NAME = "name";
|
||||
private static final String FIELD_CONTEXT_TYPE = "type";
|
||||
private static final String FIELD_CONTEXT_PATH = "path";
|
||||
@ -279,7 +278,7 @@ public class MappingBuilder {
|
||||
if (property.isSeqNoPrimaryTermProperty()) {
|
||||
if (property.isAnnotationPresent(Field.class)) {
|
||||
LOGGER.warn(String.format("Property %s of %s is annotated for inclusion in mapping, but its type is " + //
|
||||
"SeqNoPrimaryTerm that is never mapped, so it is skipped", //
|
||||
"SeqNoPrimaryTerm that is never mapped, so it is skipped", //
|
||||
property.getFieldName(), entity.getType()));
|
||||
}
|
||||
return;
|
||||
|
@ -20,8 +20,7 @@ import java.util.Arrays;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Immutable Value object encapsulating index name(s) and index type(s). Type names are supported but deprecated as
|
||||
* Elasticsearch does not support types anymore.
|
||||
* Immutable Value object encapsulating index name(s) and index type(s).
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @author Christoph Strobl
|
||||
|
@ -32,8 +32,6 @@ public class IndexQuery {
|
||||
@Nullable private Object object;
|
||||
@Nullable private Long version;
|
||||
@Nullable private String source;
|
||||
@Deprecated
|
||||
@Nullable private String parentId;
|
||||
@Nullable private Long seqNo;
|
||||
@Nullable private Long primaryTerm;
|
||||
@Nullable private String routing;
|
||||
@ -43,13 +41,12 @@ public class IndexQuery {
|
||||
public IndexQuery() {}
|
||||
|
||||
public IndexQuery(@Nullable String id, @Nullable Object object, @Nullable Long version, @Nullable String source,
|
||||
@Nullable String parentId, @Nullable Long seqNo, @Nullable Long primaryTerm, @Nullable String routing,
|
||||
@Nullable OpType opType, @Nullable String indexName) {
|
||||
@Nullable Long seqNo, @Nullable Long primaryTerm, @Nullable String routing, @Nullable OpType opType,
|
||||
@Nullable String indexName) {
|
||||
this.id = id;
|
||||
this.object = object;
|
||||
this.version = version;
|
||||
this.source = source;
|
||||
this.parentId = parentId;
|
||||
this.seqNo = seqNo;
|
||||
this.primaryTerm = primaryTerm;
|
||||
this.routing = routing;
|
||||
@ -93,25 +90,6 @@ public class IndexQuery {
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated from 4.0. Elasticsearch 7 does not support the parent id in an index request. parent/child relations
|
||||
* must be modeled using the join datatype. Setting it here will have no effect.
|
||||
*/
|
||||
@Nullable
|
||||
@Deprecated
|
||||
public String getParentId() {
|
||||
return parentId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated from 4.0. Elasticsearch 7 does not support the parent id in an index request. parent/child relations
|
||||
* must be modeled using the join datatype. Setting it here will have no effect.
|
||||
*/
|
||||
@Deprecated
|
||||
public void setParentId(String parentId) {
|
||||
this.parentId = parentId;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Long getSeqNo() {
|
||||
return seqNo;
|
||||
|
@ -33,8 +33,6 @@ public class IndexQueryBuilder {
|
||||
@Nullable private Object object;
|
||||
@Nullable private Long version;
|
||||
@Nullable private String source;
|
||||
@Deprecated
|
||||
@Nullable private String parentId;
|
||||
@Nullable private Long seqNo;
|
||||
@Nullable private Long primaryTerm;
|
||||
@Nullable private String routing;
|
||||
@ -64,12 +62,6 @@ public class IndexQueryBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public IndexQueryBuilder withParentId(String parentId) {
|
||||
this.parentId = parentId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public IndexQueryBuilder withSeqNoPrimaryTerm(SeqNoPrimaryTerm seqNoPrimaryTerm) {
|
||||
this.seqNo = seqNoPrimaryTerm.sequenceNumber();
|
||||
this.primaryTerm = seqNoPrimaryTerm.primaryTerm();
|
||||
@ -90,7 +82,7 @@ public class IndexQueryBuilder {
|
||||
}
|
||||
|
||||
public IndexQuery build() {
|
||||
return new IndexQuery(id, object, version, source, parentId, seqNo, primaryTerm, routing, opType, indexName);
|
||||
return new IndexQuery(id, object, version, source, seqNo, primaryTerm, routing, opType, indexName);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2921,7 +2921,7 @@ public abstract class ElasticsearchIntegrationTests {
|
||||
List<Object> sortValues = searchHit.getSortValues();
|
||||
assertThat(sortValues).hasSize(2);
|
||||
assertThat(sortValues.get(0)).isInstanceOf(String.class).isEqualTo("thousands");
|
||||
// transport client returns Long, RestHighlevelClient Integer, new ElasticsearchClient String
|
||||
// different Java clients return this in different types
|
||||
java.lang.Object o = sortValues.get(1);
|
||||
if (o instanceof Integer i) {
|
||||
assertThat(o).isInstanceOf(Integer.class).isEqualTo(1000);
|
||||
|
@ -1,148 +0,0 @@
|
||||
/*
|
||||
* Copyright 2021-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.elasticsearch.core;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.Collections;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* @author Sascha Woo
|
||||
* @since 4.3
|
||||
*/
|
||||
@Deprecated(since = "5.0", forRemoval = true)
|
||||
public class RangeUnitTests {
|
||||
|
||||
@Test
|
||||
public void shouldContainsLocalDate() {
|
||||
|
||||
assertThat(Range.open(LocalDate.of(2021, 1, 1), LocalDate.of(2021, 2, 1)).contains(LocalDate.of(2021, 1, 10)))
|
||||
.isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldEqualToSameRange() {
|
||||
|
||||
Range<LocalDate> range1 = Range.open(LocalDate.of(2021, 1, 1), LocalDate.of(2021, 2, 1));
|
||||
Range<LocalDate> range2 = Range.open(LocalDate.of(2021, 1, 1), LocalDate.of(2021, 2, 1));
|
||||
|
||||
assertThat(range1).isEqualTo(range2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldHaveClosedBoundaries() {
|
||||
|
||||
Range<Integer> range = Range.closed(1, 3);
|
||||
|
||||
assertThat(range.contains(1)).isTrue();
|
||||
assertThat(range.contains(2)).isTrue();
|
||||
assertThat(range.contains(3)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldHaveJustOneValue() {
|
||||
|
||||
Range<Integer> range = Range.just(2);
|
||||
|
||||
assertThat(range.contains(1)).isFalse();
|
||||
assertThat(range.contains(2)).isTrue();
|
||||
assertThat(range.contains(3)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldHaveLeftOpenBoundary() {
|
||||
|
||||
Range<Integer> range = Range.leftOpen(1, 3);
|
||||
|
||||
assertThat(range.contains(1)).isFalse();
|
||||
assertThat(range.contains(2)).isTrue();
|
||||
assertThat(range.contains(3)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldHaveLeftUnboundedAndRightExclusive() {
|
||||
|
||||
Range<Integer> range = Range.leftUnbounded(Range.Bound.exclusive(3));
|
||||
|
||||
assertThat(range.contains(0)).isTrue();
|
||||
assertThat(range.contains(1)).isTrue();
|
||||
assertThat(range.contains(2)).isTrue();
|
||||
assertThat(range.contains(3)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldHaveLeftUnboundedAndRightInclusive() {
|
||||
|
||||
Range<Integer> range = Range.leftUnbounded(Range.Bound.inclusive(3));
|
||||
|
||||
assertThat(range.contains(0)).isTrue();
|
||||
assertThat(range.contains(1)).isTrue();
|
||||
assertThat(range.contains(2)).isTrue();
|
||||
assertThat(range.contains(3)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldHaveOpenBoundaries() {
|
||||
|
||||
Range<Integer> range = Range.open(1, 3);
|
||||
|
||||
assertThat(range.contains(1)).isFalse();
|
||||
assertThat(range.contains(2)).isTrue();
|
||||
assertThat(range.contains(3)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldHaveRightOpenBoundary() {
|
||||
|
||||
Range<Integer> range = Range.rightOpen(1, 3);
|
||||
|
||||
assertThat(range.contains(1)).isTrue();
|
||||
assertThat(range.contains(2)).isTrue();
|
||||
assertThat(range.contains(3)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldHaveRightUnboundedAndLeftExclusive() {
|
||||
|
||||
Range<Integer> range = Range.rightUnbounded(Range.Bound.exclusive(1));
|
||||
|
||||
assertThat(range.contains(1)).isFalse();
|
||||
assertThat(range.contains(2)).isTrue();
|
||||
assertThat(range.contains(3)).isTrue();
|
||||
assertThat(range.contains(4)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldHaveRightUnboundedAndLeftInclusive() {
|
||||
|
||||
Range<Integer> range = Range.rightUnbounded(Range.Bound.inclusive(1));
|
||||
|
||||
assertThat(range.contains(1)).isTrue();
|
||||
assertThat(range.contains(2)).isTrue();
|
||||
assertThat(range.contains(3)).isTrue();
|
||||
assertThat(range.contains(4)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldThrowExceptionIfNotComparable() {
|
||||
|
||||
assertThatThrownBy(() -> Range.just(Collections.singletonList("test"))).isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessageContaining("value must implements Comparable!");
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user