mirror of
https://github.com/spring-projects/spring-data-elasticsearch.git
synced 2025-10-13 13:58:57 +00:00
DATAES-767 - Fix ReactiveElasticsearch handling of 4xx HTTP responses.
Original PR: #445
This commit is contained in:
parent
07ee01f435
commit
e605cad688
@ -49,6 +49,7 @@ import java.util.function.Supplier;
|
|||||||
import javax.net.ssl.SSLContext;
|
import javax.net.ssl.SSLContext;
|
||||||
|
|
||||||
import org.apache.http.util.EntityUtils;
|
import org.apache.http.util.EntityUtils;
|
||||||
|
import org.elasticsearch.ElasticsearchException;
|
||||||
import org.elasticsearch.ElasticsearchStatusException;
|
import org.elasticsearch.ElasticsearchStatusException;
|
||||||
import org.elasticsearch.action.ActionRequest;
|
import org.elasticsearch.action.ActionRequest;
|
||||||
import org.elasticsearch.action.admin.indices.close.CloseIndexRequest;
|
import org.elasticsearch.action.admin.indices.close.CloseIndexRequest;
|
||||||
@ -115,6 +116,7 @@ import org.springframework.util.Assert;
|
|||||||
import org.springframework.util.ObjectUtils;
|
import org.springframework.util.ObjectUtils;
|
||||||
import org.springframework.util.ReflectionUtils;
|
import org.springframework.util.ReflectionUtils;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
import org.springframework.web.client.HttpClientErrorException;
|
||||||
import org.springframework.web.client.HttpServerErrorException;
|
import org.springframework.web.client.HttpServerErrorException;
|
||||||
import org.springframework.web.reactive.function.BodyExtractors;
|
import org.springframework.web.reactive.function.BodyExtractors;
|
||||||
import org.springframework.web.reactive.function.client.ClientRequest;
|
import org.springframework.web.reactive.function.client.ClientRequest;
|
||||||
@ -764,6 +766,12 @@ public class DefaultReactiveElasticsearchClient implements ReactiveElasticsearch
|
|||||||
return handleServerError(request, response);
|
return handleServerError(request, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (response.statusCode().is4xxClientError()) {
|
||||||
|
|
||||||
|
ClientLogger.logRawResponse(logId, response.statusCode());
|
||||||
|
return handleClientError(logId, request, response, responseType);
|
||||||
|
}
|
||||||
|
|
||||||
return response.body(BodyExtractors.toMono(byte[].class)) //
|
return response.body(BodyExtractors.toMono(byte[].class)) //
|
||||||
.map(it -> new String(it, StandardCharsets.UTF_8)) //
|
.map(it -> new String(it, StandardCharsets.UTF_8)) //
|
||||||
.doOnNext(it -> ClientLogger.logResponse(logId, response.statusCode(), it)) //
|
.doOnNext(it -> ClientLogger.logResponse(logId, response.statusCode(), it)) //
|
||||||
@ -800,13 +808,68 @@ public class DefaultReactiveElasticsearchClient implements ReactiveElasticsearch
|
|||||||
DeprecationHandler.THROW_UNSUPPORTED_OPERATION, content);
|
DeprecationHandler.THROW_UNSUPPORTED_OPERATION, content);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static <T> Publisher<? extends T> handleServerError(Request request, ClientResponse response) {
|
private <T> Publisher<? extends T> handleServerError(Request request, ClientResponse response) {
|
||||||
|
|
||||||
return Mono.error(
|
return Mono.error(
|
||||||
new HttpServerErrorException(response.statusCode(), String.format("%s request to %s returned error code %s.",
|
new HttpServerErrorException(response.statusCode(), String.format("%s request to %s returned error code %s.",
|
||||||
request.getMethod(), request.getEndpoint(), response.statusCode().value())));
|
request.getMethod(), request.getEndpoint(), response.statusCode().value())));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private <T> Publisher<? extends T> handleClientError(String logId, Request request, ClientResponse response,
|
||||||
|
Class<T> responseType) {
|
||||||
|
|
||||||
|
return response.body(BodyExtractors.toMono(byte[].class)) //
|
||||||
|
.map(bytes -> new String(bytes, StandardCharsets.UTF_8)) //
|
||||||
|
.flatMap(content -> {
|
||||||
|
String mediaType = response.headers().contentType().map(MediaType::toString)
|
||||||
|
.orElse(XContentType.JSON.mediaType());
|
||||||
|
try {
|
||||||
|
ElasticsearchException exception = getElasticsearchException(response, content, mediaType);
|
||||||
|
if (exception != null) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
buildExceptionMessages(sb, exception);
|
||||||
|
return Mono.error(new HttpClientErrorException(response.statusCode(), sb.toString()));
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
return Mono
|
||||||
|
.error(new ElasticsearchStatusException(content, RestStatus.fromCode(response.statusCode().value())));
|
||||||
|
}
|
||||||
|
return Mono.just(content);
|
||||||
|
})
|
||||||
|
.doOnNext(it -> ClientLogger.logResponse(logId, response.statusCode(), it)) //
|
||||||
|
.flatMap(content -> doDecode(response, responseType, content));
|
||||||
|
}
|
||||||
|
|
||||||
|
// region ElasticsearchException helper
|
||||||
|
@Nullable
|
||||||
|
private ElasticsearchException getElasticsearchException(ClientResponse response, String content, String mediaType)
|
||||||
|
throws IOException {
|
||||||
|
|
||||||
|
XContentParser parser = createParser(mediaType, content);
|
||||||
|
// we have a JSON object with an error and a status field
|
||||||
|
XContentParser.Token token = parser.nextToken(); // Skip START_OBJECT
|
||||||
|
|
||||||
|
do {
|
||||||
|
token = parser.nextToken();
|
||||||
|
|
||||||
|
if (parser.currentName().equals("error")) {
|
||||||
|
return ElasticsearchException.failureFromXContent(parser);
|
||||||
|
}
|
||||||
|
} while (token == XContentParser.Token.FIELD_NAME);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void buildExceptionMessages(StringBuilder sb, Throwable t) {
|
||||||
|
|
||||||
|
sb.append(t.getMessage());
|
||||||
|
for (Throwable throwable : t.getSuppressed()) {
|
||||||
|
sb.append(", ");
|
||||||
|
buildExceptionMessages(sb, throwable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// endregion
|
||||||
|
|
||||||
|
// region internal classes
|
||||||
/**
|
/**
|
||||||
* Reactive client {@link ReactiveElasticsearchClient.Status} implementation.
|
* Reactive client {@link ReactiveElasticsearchClient.Status} implementation.
|
||||||
*
|
*
|
||||||
@ -867,4 +930,5 @@ public class DefaultReactiveElasticsearchClient implements ReactiveElasticsearch
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// endregion
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,7 @@ import org.springframework.data.elasticsearch.UncategorizedElasticsearchExceptio
|
|||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
import org.springframework.util.ObjectUtils;
|
import org.springframework.util.ObjectUtils;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
import org.springframework.web.client.HttpClientErrorException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Christoph Strobl
|
* @author Christoph Strobl
|
||||||
@ -63,6 +64,15 @@ public class ElasticsearchExceptionTranslator implements PersistenceExceptionTra
|
|||||||
return new UncategorizedElasticsearchException(ex.getMessage(), ex);
|
return new UncategorizedElasticsearchException(ex.getMessage(), ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ex instanceof HttpClientErrorException) {
|
||||||
|
HttpClientErrorException httpClientErrorException = (HttpClientErrorException) ex;
|
||||||
|
|
||||||
|
if (isSeqNoConflict(httpClientErrorException)) {
|
||||||
|
return new OptimisticLockingFailureException("Cannot index a document due to seq_no+primary_term conflict",
|
||||||
|
httpClientErrorException);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (ex instanceof ValidationException) {
|
if (ex instanceof ValidationException) {
|
||||||
return new DataIntegrityViolationException(ex.getMessage(), ex);
|
return new DataIntegrityViolationException(ex.getMessage(), ex);
|
||||||
}
|
}
|
||||||
@ -75,7 +85,7 @@ public class ElasticsearchExceptionTranslator implements PersistenceExceptionTra
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isSeqNoConflict(ElasticsearchException exception) {
|
private boolean isSeqNoConflict(Exception exception) {
|
||||||
|
|
||||||
if (exception instanceof ElasticsearchStatusException) {
|
if (exception instanceof ElasticsearchStatusException) {
|
||||||
ElasticsearchStatusException statusException = (ElasticsearchStatusException) exception;
|
ElasticsearchStatusException statusException = (ElasticsearchStatusException) exception;
|
||||||
@ -90,6 +100,13 @@ public class ElasticsearchExceptionTranslator implements PersistenceExceptionTra
|
|||||||
&& versionConflictEngineException.getMessage().contains("version conflict, required seqNo");
|
&& versionConflictEngineException.getMessage().contains("version conflict, required seqNo");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (exception instanceof HttpClientErrorException) {
|
||||||
|
HttpClientErrorException httpClientErrorException = (HttpClientErrorException) exception;
|
||||||
|
|
||||||
|
return httpClientErrorException.getMessage() != null
|
||||||
|
&& httpClientErrorException.getMessage().contains("version conflict, required seqNo");
|
||||||
|
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@ package org.springframework.data.elasticsearch.client.reactive;
|
|||||||
import static org.assertj.core.api.Assertions.*;
|
import static org.assertj.core.api.Assertions.*;
|
||||||
|
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
|
import org.springframework.web.client.HttpClientErrorException;
|
||||||
import reactor.test.StepVerifier;
|
import reactor.test.StepVerifier;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -147,7 +148,7 @@ public class ReactiveElasticsearchClientTests {
|
|||||||
|
|
||||||
client.get(new GetRequest(INDEX_I, "nonono")) //
|
client.get(new GetRequest(INDEX_I, "nonono")) //
|
||||||
.as(StepVerifier::create) //
|
.as(StepVerifier::create) //
|
||||||
.expectError(ElasticsearchStatusException.class) //
|
.expectError(HttpClientErrorException.class) //
|
||||||
.verify();
|
.verify();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -304,7 +305,7 @@ public class ReactiveElasticsearchClientTests {
|
|||||||
|
|
||||||
client.index(request) //
|
client.index(request) //
|
||||||
.as(StepVerifier::create) //
|
.as(StepVerifier::create) //
|
||||||
.verifyError(ElasticsearchStatusException.class);
|
.verifyError(HttpClientErrorException.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test // DATAES-488
|
@Test // DATAES-488
|
||||||
@ -353,7 +354,7 @@ public class ReactiveElasticsearchClientTests {
|
|||||||
|
|
||||||
client.update(request) //
|
client.update(request) //
|
||||||
.as(StepVerifier::create) //
|
.as(StepVerifier::create) //
|
||||||
.verifyError(ElasticsearchStatusException.class);
|
.verifyError(HttpClientErrorException.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test // DATAES-488
|
@Test // DATAES-488
|
||||||
@ -514,7 +515,7 @@ public class ReactiveElasticsearchClientTests {
|
|||||||
|
|
||||||
client.indices().createIndex(request -> request.index(INDEX_I)) //
|
client.indices().createIndex(request -> request.index(INDEX_I)) //
|
||||||
.as(StepVerifier::create) //
|
.as(StepVerifier::create) //
|
||||||
.verifyError(ElasticsearchStatusException.class);
|
.verifyError(HttpClientErrorException.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test // DATAES-569
|
@Test // DATAES-569
|
||||||
@ -529,12 +530,12 @@ public class ReactiveElasticsearchClientTests {
|
|||||||
assertThat(syncClient.indices().exists(new GetIndexRequest(INDEX_I), RequestOptions.DEFAULT)).isFalse();
|
assertThat(syncClient.indices().exists(new GetIndexRequest(INDEX_I), RequestOptions.DEFAULT)).isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test // DATAES-569
|
@Test // DATAES-569, DATAES-767
|
||||||
public void deleteNonExistingIndexErrors() {
|
public void deleteNonExistingIndexErrors() {
|
||||||
|
|
||||||
client.indices().deleteIndex(request -> request.indices(INDEX_I)) //
|
client.indices().deleteIndex(request -> request.indices(INDEX_I)) //
|
||||||
.as(StepVerifier::create) //
|
.as(StepVerifier::create) //
|
||||||
.verifyError(ElasticsearchStatusException.class);
|
.verifyError(HttpClientErrorException.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test // DATAES-569
|
@Test // DATAES-569
|
||||||
@ -547,12 +548,12 @@ public class ReactiveElasticsearchClientTests {
|
|||||||
.verifyComplete();
|
.verifyComplete();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test // DATAES-569
|
@Test // DATAES-569, DATAES-767
|
||||||
public void openNonExistingIndex() {
|
public void openNonExistingIndex() {
|
||||||
|
|
||||||
client.indices().openIndex(request -> request.indices(INDEX_I)) //
|
client.indices().openIndex(request -> request.indices(INDEX_I)) //
|
||||||
.as(StepVerifier::create) //
|
.as(StepVerifier::create) //
|
||||||
.verifyError(ElasticsearchStatusException.class);
|
.verifyError(HttpClientErrorException.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test // DATAES-569
|
@Test // DATAES-569
|
||||||
@ -565,12 +566,12 @@ public class ReactiveElasticsearchClientTests {
|
|||||||
.verifyComplete();
|
.verifyComplete();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test // DATAES-569
|
@Test // DATAES-569, DATAES-767
|
||||||
public void closeNonExistingIndex() {
|
public void closeNonExistingIndex() {
|
||||||
|
|
||||||
client.indices().closeIndex(request -> request.indices(INDEX_I)) //
|
client.indices().closeIndex(request -> request.indices(INDEX_I)) //
|
||||||
.as(StepVerifier::create) //
|
.as(StepVerifier::create) //
|
||||||
.verifyError(ElasticsearchStatusException.class);
|
.verifyError(HttpClientErrorException.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test // DATAES-569
|
@Test // DATAES-569
|
||||||
@ -583,12 +584,12 @@ public class ReactiveElasticsearchClientTests {
|
|||||||
.verifyComplete();
|
.verifyComplete();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test // DATAES-569
|
@Test // DATAES-569, DATAES-767
|
||||||
public void refreshNonExistingIndex() {
|
public void refreshNonExistingIndex() {
|
||||||
|
|
||||||
client.indices().refreshIndex(request -> request.indices(INDEX_I)) //
|
client.indices().refreshIndex(request -> request.indices(INDEX_I)) //
|
||||||
.as(StepVerifier::create) //
|
.as(StepVerifier::create) //
|
||||||
.verifyError(ElasticsearchStatusException.class);
|
.verifyError(HttpClientErrorException.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test // DATAES-569
|
@Test // DATAES-569
|
||||||
@ -604,7 +605,7 @@ public class ReactiveElasticsearchClientTests {
|
|||||||
.verifyComplete();
|
.verifyComplete();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test // DATAES-569
|
@Test // DATAES-569, DATAES-767
|
||||||
public void updateMappingNonExistingIndex() {
|
public void updateMappingNonExistingIndex() {
|
||||||
|
|
||||||
Map<String, Object> jsonMap = Collections.singletonMap("properties",
|
Map<String, Object> jsonMap = Collections.singletonMap("properties",
|
||||||
@ -612,7 +613,7 @@ public class ReactiveElasticsearchClientTests {
|
|||||||
|
|
||||||
client.indices().updateMapping(request -> request.indices(INDEX_I).type(TYPE_I).source(jsonMap)) //
|
client.indices().updateMapping(request -> request.indices(INDEX_I).type(TYPE_I).source(jsonMap)) //
|
||||||
.as(StepVerifier::create) //
|
.as(StepVerifier::create) //
|
||||||
.verifyError(ElasticsearchStatusException.class);
|
.verifyError(HttpClientErrorException.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test // DATAES-569
|
@Test // DATAES-569
|
||||||
@ -625,12 +626,12 @@ public class ReactiveElasticsearchClientTests {
|
|||||||
.verifyComplete();
|
.verifyComplete();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test // DATAES-569
|
@Test // DATAES-569, DATAES-767
|
||||||
public void flushNonExistingIndex() {
|
public void flushNonExistingIndex() {
|
||||||
|
|
||||||
client.indices().flushIndex(request -> request.indices(INDEX_I)) //
|
client.indices().flushIndex(request -> request.indices(INDEX_I)) //
|
||||||
.as(StepVerifier::create) //
|
.as(StepVerifier::create) //
|
||||||
.verifyError(ElasticsearchStatusException.class);
|
.verifyError(HttpClientErrorException.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test // DATAES-684
|
@Test // DATAES-684
|
||||||
|
@ -19,6 +19,7 @@ import static org.assertj.core.api.Assertions.*;
|
|||||||
import static org.mockito.Mockito.*;
|
import static org.mockito.Mockito.*;
|
||||||
import static org.springframework.data.elasticsearch.client.reactive.ReactiveMockClientTestsUtils.MockWebClientProvider.Receive.*;
|
import static org.springframework.data.elasticsearch.client.reactive.ReactiveMockClientTestsUtils.MockWebClientProvider.Receive.*;
|
||||||
|
|
||||||
|
import org.springframework.web.client.HttpClientErrorException;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
import reactor.test.StepVerifier;
|
import reactor.test.StepVerifier;
|
||||||
|
|
||||||
@ -459,7 +460,7 @@ public class ReactiveElasticsearchClientUnitTests {
|
|||||||
.verifyComplete();
|
.verifyComplete();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test // DATAES-488
|
@Test // DATAES-488, DATAES-767
|
||||||
public void updateShouldEmitErrorWhenNotFound() {
|
public void updateShouldEmitErrorWhenNotFound() {
|
||||||
|
|
||||||
hostProvider.when(HOST) //
|
hostProvider.when(HOST) //
|
||||||
@ -467,7 +468,7 @@ public class ReactiveElasticsearchClientUnitTests {
|
|||||||
|
|
||||||
client.update(new UpdateRequest("twitter", "doc", "1").doc(Collections.singletonMap("user", "cstrobl")))
|
client.update(new UpdateRequest("twitter", "doc", "1").doc(Collections.singletonMap("user", "cstrobl")))
|
||||||
.as(StepVerifier::create) //
|
.as(StepVerifier::create) //
|
||||||
.expectError(ElasticsearchStatusException.class) //
|
.expectError(HttpClientErrorException.class) //
|
||||||
.verify();
|
.verify();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,9 +24,12 @@ import org.elasticsearch.rest.RestStatus;
|
|||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.dao.DataAccessException;
|
import org.springframework.dao.DataAccessException;
|
||||||
import org.springframework.dao.OptimisticLockingFailureException;
|
import org.springframework.dao.OptimisticLockingFailureException;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.web.client.HttpClientErrorException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Roman Puchkovskiy
|
* @author Roman Puchkovskiy
|
||||||
|
* @author Peter-Josef Meisch
|
||||||
*/
|
*/
|
||||||
class ElasticsearchExceptionTranslatorTests {
|
class ElasticsearchExceptionTranslatorTests {
|
||||||
private final ElasticsearchExceptionTranslator translator = new ElasticsearchExceptionTranslator();
|
private final ElasticsearchExceptionTranslator translator = new ElasticsearchExceptionTranslator();
|
||||||
@ -56,4 +59,16 @@ class ElasticsearchExceptionTranslatorTests {
|
|||||||
assertThat(translated.getMessage()).startsWith("Cannot index a document due to seq_no+primary_term conflict");
|
assertThat(translated.getMessage()).startsWith("Cannot index a document due to seq_no+primary_term conflict");
|
||||||
assertThat(translated.getCause()).isSameAs(ex);
|
assertThat(translated.getCause()).isSameAs(ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test // DATAES-767
|
||||||
|
void shouldConvertHttpClientErrorExceptionWithSeqNoConflictToOptimisticLockingFailureException() {
|
||||||
|
HttpClientErrorException ex = new HttpClientErrorException(HttpStatus.BAD_REQUEST,
|
||||||
|
"Elasticsearch exception [type=version_conflict_engine_exception, reason=[WPUUsXEB6uuA6j8_A7AB]: version conflict, required seqNo [34], primary term [16]. current document has seqNo [35] and primary term [16]]");
|
||||||
|
|
||||||
|
DataAccessException translated = translator.translateExceptionIfPossible(ex);
|
||||||
|
|
||||||
|
assertThat(translated).isInstanceOf(OptimisticLockingFailureException.class);
|
||||||
|
assertThat(translated.getMessage()).startsWith("Cannot index a document due to seq_no+primary_term conflict");
|
||||||
|
assertThat(translated.getCause()).isSameAs(ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@ import lombok.Builder;
|
|||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
|
import org.springframework.web.client.HttpClientErrorException;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
import reactor.test.StepVerifier;
|
import reactor.test.StepVerifier;
|
||||||
|
|
||||||
@ -213,12 +214,12 @@ public class ReactiveElasticsearchTemplateTests {
|
|||||||
}).isInstanceOf(IllegalArgumentException.class);
|
}).isInstanceOf(IllegalArgumentException.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test // DATAES-519
|
@Test // DATAES-519, DATAES-767
|
||||||
public void getByIdShouldCompleteWhenIndexDoesNotExist() {
|
public void getByIdShouldErrorWhenIndexDoesNotExist() {
|
||||||
|
|
||||||
template.get("foo", SampleEntity.class, IndexCoordinates.of("no-such-index").withTypes("test-type")) //
|
template.get("foo", SampleEntity.class, IndexCoordinates.of("no-such-index").withTypes("test-type")) //
|
||||||
.as(StepVerifier::create) //
|
.as(StepVerifier::create) //
|
||||||
.verifyComplete();
|
.expectError(HttpClientErrorException.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test // DATAES-504
|
@Test // DATAES-504
|
||||||
@ -326,14 +327,14 @@ public class ReactiveElasticsearchTemplateTests {
|
|||||||
.verifyComplete();
|
.verifyComplete();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test // DATAES-519
|
@Test // DATAES-519, DATAES-767
|
||||||
public void searchShouldCompleteWhenIndexDoesNotExist() {
|
public void searchShouldCompleteWhenIndexDoesNotExist() {
|
||||||
|
|
||||||
template
|
template
|
||||||
.search(new CriteriaQuery(Criteria.where("message").is("some message")), SampleEntity.class,
|
.search(new CriteriaQuery(Criteria.where("message").is("some message")), SampleEntity.class,
|
||||||
IndexCoordinates.of("no-such-index")) //
|
IndexCoordinates.of("no-such-index")) //
|
||||||
.as(StepVerifier::create) //
|
.as(StepVerifier::create) //
|
||||||
.verifyComplete();
|
.expectError(HttpClientErrorException.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test // DATAES-504
|
@Test // DATAES-504
|
||||||
@ -430,7 +431,7 @@ public class ReactiveElasticsearchTemplateTests {
|
|||||||
.verifyComplete();
|
.verifyComplete();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test // DATAES-595
|
@Test // DATAES-595, DATAES-767
|
||||||
public void shouldThrowElasticsearchStatusExceptionWhenInvalidPreferenceForGivenCriteria() {
|
public void shouldThrowElasticsearchStatusExceptionWhenInvalidPreferenceForGivenCriteria() {
|
||||||
|
|
||||||
SampleEntity sampleEntity1 = randomEntity("test message");
|
SampleEntity sampleEntity1 = randomEntity("test message");
|
||||||
@ -445,7 +446,7 @@ public class ReactiveElasticsearchTemplateTests {
|
|||||||
|
|
||||||
template.search(queryWithInvalidPreference, SampleEntity.class) //
|
template.search(queryWithInvalidPreference, SampleEntity.class) //
|
||||||
.as(StepVerifier::create) //
|
.as(StepVerifier::create) //
|
||||||
.expectError(UncategorizedElasticsearchException.class).verify();
|
.expectError(HttpClientErrorException.class).verify();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test // DATAES-504
|
@Test // DATAES-504
|
||||||
@ -520,22 +521,20 @@ public class ReactiveElasticsearchTemplateTests {
|
|||||||
}).verifyComplete();
|
}).verifyComplete();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test // DATAES-567
|
@Test // DATAES-567, DATAES-767
|
||||||
public void aggregateShouldReturnEmptyWhenIndexDoesNotExist() {
|
public void aggregateShouldErrorWhenIndexDoesNotExist() {
|
||||||
template
|
template.aggregate(new CriteriaQuery(Criteria.where("message").is("some message")), SampleEntity.class,
|
||||||
.aggregate(new CriteriaQuery(Criteria.where("message").is("some message")), SampleEntity.class,
|
|
||||||
IndexCoordinates.of("no-such-index")) //
|
IndexCoordinates.of("no-such-index")) //
|
||||||
.as(StepVerifier::create) //
|
.as(StepVerifier::create) //
|
||||||
.verifyComplete();
|
.expectError(HttpClientErrorException.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test // DATAES-519
|
@Test // DATAES-519, DATAES-767
|
||||||
public void countShouldReturnZeroWhenIndexDoesNotExist() {
|
public void countShouldReturnZeroWhenIndexDoesNotExist() {
|
||||||
|
|
||||||
template.count(SampleEntity.class) //
|
template.count(SampleEntity.class) //
|
||||||
.as(StepVerifier::create) //
|
.as(StepVerifier::create) //
|
||||||
.expectNext(0L) //
|
.expectError(HttpClientErrorException.class);
|
||||||
.verifyComplete();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test // DATAES-504
|
@Test // DATAES-504
|
||||||
@ -562,12 +561,12 @@ public class ReactiveElasticsearchTemplateTests {
|
|||||||
.verifyComplete();
|
.verifyComplete();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test // DATAES-519
|
@Test // DATAES-519, DATAES-767
|
||||||
public void deleteShouldCompleteWhenIndexDoesNotExist() {
|
public void deleteShouldErrorWhenIndexDoesNotExist() {
|
||||||
|
|
||||||
template.delete("does-not-exists", IndexCoordinates.of("no-such-index")) //
|
template.delete("does-not-exists", IndexCoordinates.of("no-such-index")) //
|
||||||
.as(StepVerifier::create)//
|
.as(StepVerifier::create)//
|
||||||
.verifyComplete();
|
.expectError(HttpClientErrorException.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test // DATAES-504
|
@Test // DATAES-504
|
||||||
@ -926,7 +925,10 @@ public class ReactiveElasticsearchTemplateTests {
|
|||||||
template.save(forEdit1).block();
|
template.save(forEdit1).block();
|
||||||
|
|
||||||
forEdit2.setMessage("It'll be great");
|
forEdit2.setMessage("It'll be great");
|
||||||
template.save(forEdit2).as(StepVerifier::create).expectError(OptimisticLockingFailureException.class).verify();
|
template.save(forEdit2) //
|
||||||
|
.as(StepVerifier::create) //
|
||||||
|
.expectError(OptimisticLockingFailureException.class) //
|
||||||
|
.verify();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test // DATAES-799
|
@Test // DATAES-799
|
||||||
|
@ -72,6 +72,7 @@ import org.springframework.data.elasticsearch.repository.config.EnableReactiveEl
|
|||||||
import org.springframework.data.repository.reactive.ReactiveCrudRepository;
|
import org.springframework.data.repository.reactive.ReactiveCrudRepository;
|
||||||
import org.springframework.test.context.ContextConfiguration;
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
import org.springframework.web.client.HttpClientErrorException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Christoph Strobl
|
* @author Christoph Strobl
|
||||||
@ -129,9 +130,11 @@ public class SimpleReactiveElasticsearchRepositoryTests {
|
|||||||
.verifyComplete();
|
.verifyComplete();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test // DATAES-519
|
@Test // DATAES-519, DATAES-767
|
||||||
public void findByIdShouldCompleteIfIndexDoesNotExist() {
|
public void findByIdShouldErrorIfIndexDoesNotExist() {
|
||||||
repository.findById("id-two").as(StepVerifier::create).verifyComplete();
|
repository.findById("id-two") //
|
||||||
|
.as(StepVerifier::create) //
|
||||||
|
.expectError(HttpClientErrorException.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test // DATAES-519
|
@Test // DATAES-519
|
||||||
@ -264,9 +267,11 @@ public class SimpleReactiveElasticsearchRepositoryTests {
|
|||||||
.verifyComplete();
|
.verifyComplete();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test // DATAES-519
|
@Test // DATAES-519, DATAES-767
|
||||||
public void countShouldReturnZeroWhenIndexDoesNotExist() {
|
public void countShouldErrorWhenIndexDoesNotExist() {
|
||||||
repository.count().as(StepVerifier::create).expectNext(0L).verifyComplete();
|
repository.count() //
|
||||||
|
.as(StepVerifier::create) //
|
||||||
|
.expectError(HttpClientErrorException.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test // DATAES-519
|
@Test // DATAES-519
|
||||||
@ -352,9 +357,12 @@ public class SimpleReactiveElasticsearchRepositoryTests {
|
|||||||
repository.deleteById("does-not-exist").as(StepVerifier::create).verifyComplete();
|
repository.deleteById("does-not-exist").as(StepVerifier::create).verifyComplete();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test // DATAES-519
|
@Test // DATAES-519, DATAES-767
|
||||||
public void deleteByIdShouldCompleteWhenIndexDoesNotExist() {
|
public void deleteByIdShouldErrorWhenIndexDoesNotExist() {
|
||||||
repository.deleteById("does-not-exist").as(StepVerifier::create).verifyComplete();
|
repository.deleteById("does-not-exist") //
|
||||||
|
.as(StepVerifier::create) //
|
||||||
|
.verifyError(HttpClientErrorException.class);
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test // DATAES-519
|
@Test // DATAES-519
|
||||||
|
Loading…
x
Reference in New Issue
Block a user