Skip to content

Commit bdcecd0

Browse files
authored
DATAES-612 - Add support for index templates.
Original PR: spring-projects#495
1 parent 0944d16 commit bdcecd0

28 files changed

+1834
-114
lines changed

src/main/asciidoc/reference/elasticsearch-new.adoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
* Upgrade to Elasticsearch 7.8.0
88
* Improved API for alias management
99
* Introduction of `ReactiveIndexOperations` for index management
10+
* Index templates support
1011

1112
[[new-features.4-0-0]]
1213
== New in Spring Data Elasticsearch 4.0

src/main/java/org/springframework/data/elasticsearch/ElasticsearchException.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
* @author Rizwan Idrees
2626
* @author Mohsin Husen
2727
* @author Peter-Josef Meisch
28-
* @deprecated since 4.0, use {@link org.springframework.dao.UncategorizedDataAccessException}
28+
* @deprecated since 4.0, use {@link UncategorizedElasticsearchException}
2929
*/
3030
@Deprecated
3131
public class ElasticsearchException extends RuntimeException {

src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java

Lines changed: 42 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@
6464
import org.elasticsearch.action.admin.indices.refresh.RefreshResponse;
6565
import org.elasticsearch.action.admin.indices.settings.get.GetSettingsRequest;
6666
import org.elasticsearch.action.admin.indices.settings.get.GetSettingsResponse;
67+
import org.elasticsearch.action.admin.indices.template.delete.DeleteIndexTemplateRequest;
6768
import org.elasticsearch.action.bulk.BulkRequest;
6869
import org.elasticsearch.action.bulk.BulkResponse;
6970
import org.elasticsearch.action.delete.DeleteRequest;
@@ -86,6 +87,10 @@
8687
import org.elasticsearch.action.update.UpdateResponse;
8788
import org.elasticsearch.client.GetAliasesResponse;
8889
import org.elasticsearch.client.Request;
90+
import org.elasticsearch.client.indices.GetIndexTemplatesRequest;
91+
import org.elasticsearch.client.indices.GetIndexTemplatesResponse;
92+
import org.elasticsearch.client.indices.IndexTemplatesExistRequest;
93+
import org.elasticsearch.client.indices.PutIndexTemplateRequest;
8994
import org.elasticsearch.common.unit.TimeValue;
9095
import org.elasticsearch.common.xcontent.DeprecationHandler;
9196
import org.elasticsearch.common.xcontent.NamedXContentRegistry;
@@ -266,10 +271,9 @@ private static WebClientProvider getWebClientProvider(ClientConfiguration client
266271
Optional<SSLContext> sslContext = clientConfiguration.getSslContext();
267272

268273
if (sslContext.isPresent()) {
269-
httpClient = httpClient.secure(sslContextSpec -> {
270-
sslContextSpec.sslContext(new JdkSslContext(sslContext.get(), true, null, IdentityCipherSuiteFilter.INSTANCE,
271-
ApplicationProtocolConfig.DISABLED, ClientAuth.NONE, null, false));
272-
});
274+
httpClient = httpClient
275+
.secure(sslContextSpec -> sslContextSpec.sslContext(new JdkSslContext(sslContext.get(), true, null,
276+
IdentityCipherSuiteFilter.INSTANCE, ApplicationProtocolConfig.DISABLED, ClientAuth.NONE, null, false)));
273277
} else {
274278
httpClient = httpClient.secure();
275279
}
@@ -589,8 +593,8 @@ private static GetResult getResponseToGetResult(GetResponse response) {
589593

590594
// -->
591595

592-
private <Req extends ActionRequest, Resp> Flux<Resp> sendRequest(Req request, Function<Req, Request> converter,
593-
Class<Resp> responseType, HttpHeaders headers) {
596+
private <REQ, RESP> Flux<RESP> sendRequest(REQ request, Function<REQ, Request> converter, Class<RESP> responseType,
597+
HttpHeaders headers) {
594598
return sendRequest(converter.apply(request), responseType, headers);
595599
}
596600

@@ -737,6 +741,32 @@ public Mono<GetAliasesResponse> getAliases(HttpHeaders headers, GetAliasesReques
737741
return sendRequest(getAliasesRequest, requestCreator.getAlias(), GetAliasesResponse.class, headers).publishNext();
738742
}
739743

744+
@Override
745+
public Mono<Boolean> putTemplate(HttpHeaders headers, PutIndexTemplateRequest putIndexTemplateRequest) {
746+
return sendRequest(putIndexTemplateRequest, requestCreator.putTemplate(), AcknowledgedResponse.class, headers)
747+
.map(AcknowledgedResponse::isAcknowledged).next();
748+
}
749+
750+
@Override
751+
public Mono<GetIndexTemplatesResponse> getTemplate(HttpHeaders headers,
752+
GetIndexTemplatesRequest getIndexTemplatesRequest) {
753+
return (sendRequest(getIndexTemplatesRequest, requestCreator.getTemplates(), GetIndexTemplatesResponse.class,
754+
headers)).next();
755+
}
756+
757+
@Override
758+
public Mono<Boolean> existsTemplate(HttpHeaders headers, IndexTemplatesExistRequest indexTemplatesExistRequest) {
759+
return sendRequest(indexTemplatesExistRequest, requestCreator.templatesExist(), RawActionResponse.class, headers) //
760+
.flatMap(response -> response.releaseBody().thenReturn(response.statusCode().is2xxSuccessful())) //
761+
.next();
762+
}
763+
764+
@Override
765+
public Mono<Boolean> deleteTemplate(HttpHeaders headers, DeleteIndexTemplateRequest deleteIndexTemplateRequest) {
766+
return sendRequest(deleteIndexTemplateRequest, requestCreator.deleteTemplate(), AcknowledgedResponse.class, headers)
767+
.map(AcknowledgedResponse::isAcknowledged).next();
768+
}
769+
740770
// endregion
741771

742772
// region helper functions
@@ -758,7 +788,7 @@ private <T> Publisher<? extends T> readResponseBody(String logId, Request reques
758788
if (response.statusCode().is4xxClientError()) {
759789

760790
ClientLogger.logRawResponse(logId, response.statusCode());
761-
return handleClientError(logId, request, response, responseType);
791+
return handleClientError(logId, response, responseType);
762792
}
763793

764794
return response.body(BodyExtractors.toMono(byte[].class)) //
@@ -825,8 +855,7 @@ private <T> Publisher<? extends T> handleServerError(Request request, ClientResp
825855
request.getMethod(), request.getEndpoint(), statusCode), status)));
826856
}
827857

828-
private <T> Publisher<? extends T> handleClientError(String logId, Request request, ClientResponse response,
829-
Class<T> responseType) {
858+
private <T> Publisher<? extends T> handleClientError(String logId, ClientResponse response, Class<T> responseType) {
830859

831860
int statusCode = response.statusCode().value();
832861
RestStatus status = RestStatus.fromCode(statusCode);
@@ -874,12 +903,13 @@ private static ElasticsearchException getElasticsearchException(String content,
874903
try {
875904
XContentParser parser = createParser(mediaType, content);
876905
// we have a JSON object with an error and a status field
877-
XContentParser.Token token = parser.nextToken(); // Skip START_OBJECT
906+
parser.nextToken(); // Skip START_OBJECT
878907

908+
XContentParser.Token token;
879909
do {
880910
token = parser.nextToken();
881911

882-
if (parser.currentName().equals("error")) {
912+
if ("error".equals(parser.currentName())) {
883913
return ElasticsearchException.failureFromXContent(parser);
884914
}
885915
} while (token == XContentParser.Token.FIELD_NAME);
@@ -906,7 +936,7 @@ private static void buildExceptionMessages(StringBuilder sb, Throwable t) {
906936
*
907937
* @author Christoph Strobl
908938
*/
909-
class ClientStatus implements Status {
939+
static class ClientStatus implements Status {
910940

911941
private final Collection<ElasticsearchHost> connectedHosts;
912942

src/main/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClient.java

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import org.elasticsearch.action.admin.indices.refresh.RefreshRequest;
3737
import org.elasticsearch.action.admin.indices.settings.get.GetSettingsRequest;
3838
import org.elasticsearch.action.admin.indices.settings.get.GetSettingsResponse;
39+
import org.elasticsearch.action.admin.indices.template.delete.DeleteIndexTemplateRequest;
3940
import org.elasticsearch.action.bulk.BulkRequest;
4041
import org.elasticsearch.action.bulk.BulkResponse;
4142
import org.elasticsearch.action.delete.DeleteRequest;
@@ -50,6 +51,10 @@
5051
import org.elasticsearch.action.update.UpdateRequest;
5152
import org.elasticsearch.action.update.UpdateResponse;
5253
import org.elasticsearch.client.GetAliasesResponse;
54+
import org.elasticsearch.client.indices.GetIndexTemplatesRequest;
55+
import org.elasticsearch.client.indices.GetIndexTemplatesResponse;
56+
import org.elasticsearch.client.indices.IndexTemplatesExistRequest;
57+
import org.elasticsearch.client.indices.PutIndexTemplateRequest;
5358
import org.elasticsearch.index.get.GetResult;
5459
import org.elasticsearch.index.reindex.BulkByScrollResponse;
5560
import org.elasticsearch.index.reindex.DeleteByQueryRequest;
@@ -610,6 +615,7 @@ default Mono<BulkResponse> bulk(BulkRequest bulkRequest) {
610615
* @param callback the {@link ReactiveElasticsearchClientCallback callback} wielding the actual command to run.
611616
* @return the {@link Mono} emitting the {@link ClientResponse} once subscribed.
612617
*/
618+
@SuppressWarnings("JavaDoc")
613619
Mono<ClientResponse> execute(ReactiveElasticsearchClientCallback callback);
614620

615621
/**
@@ -1196,5 +1202,144 @@ default Mono<GetAliasesResponse> getAliases(GetAliasesRequest getAliasesRequest)
11961202
* @since 4.1
11971203
*/
11981204
Mono<GetAliasesResponse> getAliases(HttpHeaders headers, GetAliasesRequest getAliasesRequest);
1205+
1206+
/**
1207+
* Execute the given {@link PutIndexTemplateRequest} against the {@literal indices} API.
1208+
*
1209+
* @param consumer never {@literal null}.
1210+
* @return a {@link Mono} signalling operation completion.
1211+
* @since 4.1
1212+
*/
1213+
default Mono<Boolean> putTemplate(Consumer<PutIndexTemplateRequest> consumer, String templateName) {
1214+
PutIndexTemplateRequest putIndexTemplateRequest = new PutIndexTemplateRequest(templateName);
1215+
consumer.accept(putIndexTemplateRequest);
1216+
return putTemplate(putIndexTemplateRequest);
1217+
}
1218+
1219+
/**
1220+
* Execute the given {@link PutIndexTemplateRequest} against the {@literal indices} API.
1221+
*
1222+
* @param putIndexTemplateRequest must not be {@literal null}
1223+
* @return a {@link Mono} signalling operation completion.
1224+
* @since 4.1
1225+
*/
1226+
default Mono<Boolean> putTemplate(PutIndexTemplateRequest putIndexTemplateRequest) {
1227+
return putTemplate(HttpHeaders.EMPTY, putIndexTemplateRequest);
1228+
}
1229+
1230+
/**
1231+
* Execute the given {@link PutIndexTemplateRequest} against the {@literal indices} API.
1232+
*
1233+
* @param headers Use {@link HttpHeaders} to provide eg. authentication data. Must not be {@literal null}.
1234+
* @param putIndexTemplateRequest must not be {@literal null}
1235+
* @return a {@link Mono} signalling operation completion.
1236+
* @since 4.1
1237+
*/
1238+
Mono<Boolean> putTemplate(HttpHeaders headers, PutIndexTemplateRequest putIndexTemplateRequest);
1239+
1240+
/**
1241+
* Execute the given {@link GetIndexTemplatesRequest} against the {@literal indices} API.
1242+
*
1243+
* @param consumer never {@literal null}.
1244+
* @return a {@link Mono} with the GetIndexTemplatesResponse.
1245+
* @since 4.1
1246+
*/
1247+
default Mono<GetIndexTemplatesResponse> getTemplate(Consumer<GetIndexTemplatesRequest> consumer) {
1248+
1249+
GetIndexTemplatesRequest getIndexTemplatesRequest = new GetIndexTemplatesRequest();
1250+
consumer.accept(getIndexTemplatesRequest);
1251+
return getTemplate(getIndexTemplatesRequest);
1252+
}
1253+
1254+
/**
1255+
* Execute the given {@link GetIndexTemplatesRequest} against the {@literal indices} API.
1256+
*
1257+
* @param getIndexTemplatesRequest must not be {@literal null}
1258+
* @return a {@link Mono} with the GetIndexTemplatesResponse.
1259+
* @since 4.1
1260+
*/
1261+
default Mono<GetIndexTemplatesResponse> getTemplate(GetIndexTemplatesRequest getIndexTemplatesRequest) {
1262+
return getTemplate(HttpHeaders.EMPTY, getIndexTemplatesRequest);
1263+
}
1264+
1265+
/**
1266+
* Execute the given {@link GetIndexTemplatesRequest} against the {@literal indices} API.
1267+
*
1268+
* @param headers Use {@link HttpHeaders} to provide eg. authentication data. Must not be {@literal null}.
1269+
* @param getIndexTemplatesRequest must not be {@literal null}
1270+
* @return a {@link Mono} with the GetIndexTemplatesResponse.
1271+
* @since 4.1
1272+
*/
1273+
Mono<GetIndexTemplatesResponse> getTemplate(HttpHeaders headers, GetIndexTemplatesRequest getIndexTemplatesRequest);
1274+
1275+
/**
1276+
* Execute the given {@link IndexTemplatesExistRequest} against the {@literal indices} API.
1277+
*
1278+
* @param consumer never {@literal null}.
1279+
* @return the {@link Mono} emitting {@literal true} if the template exists, {@literal false} otherwise.
1280+
* @since 4.1
1281+
*/
1282+
default Mono<Boolean> existsTemplate(Consumer<IndexTemplatesExistRequest> consumer) {
1283+
1284+
IndexTemplatesExistRequest indexTemplatesExistRequest = new IndexTemplatesExistRequest();
1285+
consumer.accept(indexTemplatesExistRequest);
1286+
return existsTemplate(indexTemplatesExistRequest);
1287+
}
1288+
1289+
/**
1290+
* Execute the given {@link IndexTemplatesExistRequest} against the {@literal indices} API.
1291+
*
1292+
* @param indexTemplatesExistRequest must not be {@literal null}
1293+
* @return the {@link Mono} emitting {@literal true} if the template exists, {@literal false} otherwise.
1294+
* @since 4.1
1295+
*/
1296+
default Mono<Boolean> existsTemplate(IndexTemplatesExistRequest indexTemplatesExistRequest) {
1297+
return existsTemplate(HttpHeaders.EMPTY, indexTemplatesExistRequest);
1298+
}
1299+
1300+
/**
1301+
* Execute the given {@link IndexTemplatesExistRequest} against the {@literal indices} API.
1302+
*
1303+
* @param headers Use {@link HttpHeaders} to provide eg. authentication data. Must not be {@literal null}.
1304+
* @param indexTemplatesExistRequest must not be {@literal null}
1305+
* @return the {@link Mono} emitting {@literal true} if the template exists, {@literal false} otherwise.
1306+
* @since 4.1
1307+
*/
1308+
Mono<Boolean> existsTemplate(HttpHeaders headers, IndexTemplatesExistRequest indexTemplatesExistRequest);
1309+
1310+
/**
1311+
* Execute the given {@link DeleteIndexTemplateRequest} against the {@literal indices} API.
1312+
*
1313+
* @param consumer never {@literal null}.
1314+
* @return the {@link Mono} emitting {@literal true} if the template exists, {@literal false} otherwise.
1315+
* @since 4.1
1316+
*/
1317+
default Mono<Boolean> deleteTemplate(Consumer<DeleteIndexTemplateRequest> consumer) {
1318+
1319+
DeleteIndexTemplateRequest deleteIndexTemplateRequest = new DeleteIndexTemplateRequest();
1320+
consumer.accept(deleteIndexTemplateRequest);
1321+
return deleteTemplate(deleteIndexTemplateRequest);
1322+
}
1323+
1324+
/**
1325+
* Execute the given {@link DeleteIndexTemplateRequest} against the {@literal indices} API.
1326+
*
1327+
* @param deleteIndexTemplateRequest must not be {@literal null}
1328+
* @return the {@link Mono} emitting {@literal true} if the template exists, {@literal false} otherwise.
1329+
* @since 4.1
1330+
*/
1331+
default Mono<Boolean> deleteTemplate(DeleteIndexTemplateRequest deleteIndexTemplateRequest) {
1332+
return deleteTemplate(HttpHeaders.EMPTY, deleteIndexTemplateRequest);
1333+
}
1334+
1335+
/**
1336+
* Execute the given {@link DeleteIndexTemplateRequest} against the {@literal indices} API.
1337+
*
1338+
* @param headers Use {@link HttpHeaders} to provide eg. authentication data. Must not be {@literal null}.
1339+
* @param deleteIndexTemplateRequest must not be {@literal null}
1340+
* @return the {@link Mono} emitting {@literal true} if the template exists, {@literal false} otherwise.
1341+
* @since 4.1
1342+
*/
1343+
Mono<Boolean> deleteTemplate(HttpHeaders headers, DeleteIndexTemplateRequest deleteIndexTemplateRequest);
11991344
}
12001345
}

src/main/java/org/springframework/data/elasticsearch/client/reactive/RequestCreator.java

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import org.elasticsearch.action.admin.indices.open.OpenIndexRequest;
1616
import org.elasticsearch.action.admin.indices.refresh.RefreshRequest;
1717
import org.elasticsearch.action.admin.indices.settings.get.GetSettingsRequest;
18+
import org.elasticsearch.action.admin.indices.template.delete.DeleteIndexTemplateRequest;
1819
import org.elasticsearch.action.bulk.BulkRequest;
1920
import org.elasticsearch.action.delete.DeleteRequest;
2021
import org.elasticsearch.action.get.GetRequest;
@@ -27,6 +28,9 @@
2728
import org.elasticsearch.action.update.UpdateRequest;
2829
import org.elasticsearch.client.Request;
2930
import org.elasticsearch.client.core.CountRequest;
31+
import org.elasticsearch.client.indices.GetIndexTemplatesRequest;
32+
import org.elasticsearch.client.indices.IndexTemplatesExistRequest;
33+
import org.elasticsearch.client.indices.PutIndexTemplateRequest;
3034
import org.elasticsearch.index.reindex.DeleteByQueryRequest;
3135
import org.springframework.data.elasticsearch.UncategorizedElasticsearchException;
3236
import org.springframework.data.elasticsearch.client.util.RequestConverters;
@@ -156,7 +160,38 @@ default Function<IndicesAliasesRequest, Request> updateAlias() {
156160
return RequestConverters::updateAliases;
157161
}
158162

163+
/**
164+
* @since 4.1
165+
*/
159166
default Function<GetAliasesRequest, Request> getAlias() {
160167
return RequestConverters::getAlias;
161168
}
169+
170+
/**
171+
* @since 4.1
172+
*/
173+
default Function<PutIndexTemplateRequest, Request> putTemplate() {
174+
return RequestConverters::putTemplate;
175+
}
176+
177+
/**
178+
* @since 4.1
179+
*/
180+
default Function<GetIndexTemplatesRequest, Request> getTemplates() {
181+
return RequestConverters::getTemplates;
182+
}
183+
184+
/**
185+
* @since 4.1
186+
*/
187+
default Function<IndexTemplatesExistRequest, Request> templatesExist() {
188+
return RequestConverters::templatesExist;
189+
}
190+
191+
/**
192+
* @since 4.1
193+
*/
194+
default Function<DeleteIndexTemplateRequest, Request> deleteTemplate() {
195+
return RequestConverters::deleteTemplate;
196+
}
162197
}

0 commit comments

Comments
 (0)