mirror of
https://github.com/spring-projects/spring-data-elasticsearch.git
synced 2025-06-25 05:22:10 +00:00
DATAES-435 - Report version mismatch if used with older ElasticSearch-version.
Original PR: #413
This commit is contained in:
parent
21406a5e7d
commit
2ec61ab4ff
17
pom.xml
17
pom.xml
@ -292,6 +292,23 @@
|
|||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
<resources>
|
||||||
|
<resource>
|
||||||
|
<directory>src/main/resources</directory>
|
||||||
|
<filtering>true</filtering>
|
||||||
|
<includes>
|
||||||
|
<include>**/versions.properties</include>
|
||||||
|
</includes>
|
||||||
|
</resource>
|
||||||
|
<resource>
|
||||||
|
<directory>src/main/resources</directory>
|
||||||
|
<filtering>false</filtering>
|
||||||
|
<excludes>
|
||||||
|
<exclude>**/versions.properties</exclude>
|
||||||
|
</excludes>
|
||||||
|
</resource>
|
||||||
|
</resources>
|
||||||
|
|
||||||
<plugins>
|
<plugins>
|
||||||
<!--
|
<!--
|
||||||
please do not remove this configuration for surefire - we need that to avoid issue with jar hell
|
please do not remove this configuration for surefire - we need that to avoid issue with jar hell
|
||||||
|
@ -33,6 +33,7 @@ import org.springframework.data.elasticsearch.core.query.IndexQueryBuilder;
|
|||||||
import org.springframework.data.elasticsearch.core.query.MoreLikeThisQuery;
|
import org.springframework.data.elasticsearch.core.query.MoreLikeThisQuery;
|
||||||
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
|
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
|
||||||
import org.springframework.data.elasticsearch.core.query.Query;
|
import org.springframework.data.elasticsearch.core.query.Query;
|
||||||
|
import org.springframework.data.elasticsearch.support.VersionInfo;
|
||||||
import org.springframework.data.mapping.callback.EntityCallbacks;
|
import org.springframework.data.mapping.callback.EntityCallbacks;
|
||||||
import org.springframework.data.util.CloseableIterator;
|
import org.springframework.data.util.CloseableIterator;
|
||||||
import org.springframework.data.util.Streamable;
|
import org.springframework.data.util.Streamable;
|
||||||
@ -59,6 +60,8 @@ public abstract class AbstractElasticsearchTemplate implements ElasticsearchOper
|
|||||||
|
|
||||||
this.elasticsearchConverter = elasticsearchConverter;
|
this.elasticsearchConverter = elasticsearchConverter;
|
||||||
requestFactory = new RequestFactory(elasticsearchConverter);
|
requestFactory = new RequestFactory(elasticsearchConverter);
|
||||||
|
|
||||||
|
VersionInfo.logVersions(getClusterVersion());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ElasticsearchConverter createElasticsearchConverter() {
|
protected ElasticsearchConverter createElasticsearchConverter() {
|
||||||
@ -288,14 +291,14 @@ public abstract class AbstractElasticsearchTemplate implements ElasticsearchOper
|
|||||||
/*
|
/*
|
||||||
* internal use only, not for public API
|
* internal use only, not for public API
|
||||||
*/
|
*/
|
||||||
abstract protected <T> SearchScrollHits<T> searchScrollStart(long scrollTimeInMillis, Query query,
|
abstract protected <T> SearchScrollHits<T> searchScrollStart(long scrollTimeInMillis, Query query, Class<T> clazz,
|
||||||
Class<T> clazz, IndexCoordinates index);
|
IndexCoordinates index);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* internal use only, not for public API
|
* internal use only, not for public API
|
||||||
*/
|
*/
|
||||||
abstract protected <T> SearchScrollHits<T> searchScrollContinue(@Nullable String scrollId,
|
abstract protected <T> SearchScrollHits<T> searchScrollContinue(@Nullable String scrollId, long scrollTimeInMillis,
|
||||||
long scrollTimeInMillis, Class<T> clazz);
|
Class<T> clazz);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* internal use only, not for public API
|
* internal use only, not for public API
|
||||||
@ -417,6 +420,15 @@ public abstract class AbstractElasticsearchTemplate implements ElasticsearchOper
|
|||||||
.withObject(entity) //
|
.withObject(entity) //
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tries to extract the version of the Elasticsearch cluster
|
||||||
|
*
|
||||||
|
* @return the version as string if it can be retrieved
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
abstract protected String getClusterVersion();
|
||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
// region callbacks
|
// region callbacks
|
||||||
|
@ -270,7 +270,8 @@ public class ElasticsearchRestTemplate extends AbstractElasticsearchTemplate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> SearchScrollHits<T> searchScrollContinue(@Nullable String scrollId, long scrollTimeInMillis, Class<T> clazz) {
|
public <T> SearchScrollHits<T> searchScrollContinue(@Nullable String scrollId, long scrollTimeInMillis,
|
||||||
|
Class<T> clazz) {
|
||||||
|
|
||||||
SearchScrollRequest request = new SearchScrollRequest(scrollId);
|
SearchScrollRequest request = new SearchScrollRequest(scrollId);
|
||||||
request.scroll(TimeValue.timeValueMillis(scrollTimeInMillis));
|
request.scroll(TimeValue.timeValueMillis(scrollTimeInMillis));
|
||||||
@ -355,4 +356,14 @@ public class ElasticsearchRestTemplate extends AbstractElasticsearchTemplate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
|
// region helper methods
|
||||||
|
@Override
|
||||||
|
protected String getClusterVersion() {
|
||||||
|
try {
|
||||||
|
return execute(client -> client.info(RequestOptions.DEFAULT)).getVersion().getNumber();
|
||||||
|
} catch (Exception ignored) {}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// endregion
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,11 @@ package org.springframework.data.elasticsearch.core;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.elasticsearch.Version;
|
||||||
import org.elasticsearch.action.ActionFuture;
|
import org.elasticsearch.action.ActionFuture;
|
||||||
|
import org.elasticsearch.action.admin.cluster.node.info.NodesInfoAction;
|
||||||
|
import org.elasticsearch.action.admin.cluster.node.info.NodesInfoRequestBuilder;
|
||||||
|
import org.elasticsearch.action.admin.cluster.node.info.NodesInfoResponse;
|
||||||
import org.elasticsearch.action.bulk.BulkRequestBuilder;
|
import org.elasticsearch.action.bulk.BulkRequestBuilder;
|
||||||
import org.elasticsearch.action.get.GetRequestBuilder;
|
import org.elasticsearch.action.get.GetRequestBuilder;
|
||||||
import org.elasticsearch.action.get.GetResponse;
|
import org.elasticsearch.action.get.GetResponse;
|
||||||
@ -320,4 +324,22 @@ public class ElasticsearchTemplate extends AbstractElasticsearchTemplate {
|
|||||||
return searchTimeout == null ? response.actionGet() : response.actionGet(searchTimeout);
|
return searchTimeout == null ? response.actionGet() : response.actionGet(searchTimeout);
|
||||||
}
|
}
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
|
|
||||||
|
//region helper methods
|
||||||
|
@Override
|
||||||
|
protected String getClusterVersion() {
|
||||||
|
|
||||||
|
try {
|
||||||
|
NodesInfoResponse nodesInfoResponse = client.admin().cluster().nodesInfo(
|
||||||
|
new NodesInfoRequestBuilder(client, NodesInfoAction.INSTANCE).request()
|
||||||
|
).actionGet();
|
||||||
|
if (!nodesInfoResponse.getNodes().isEmpty()) {
|
||||||
|
return nodesInfoResponse.getNodes().get(0).getVersion().toString();
|
||||||
|
}
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
//endregion
|
||||||
}
|
}
|
||||||
|
@ -82,6 +82,7 @@ import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
|
|||||||
import org.springframework.data.elasticsearch.core.query.Query;
|
import org.springframework.data.elasticsearch.core.query.Query;
|
||||||
import org.springframework.data.elasticsearch.core.query.StringQuery;
|
import org.springframework.data.elasticsearch.core.query.StringQuery;
|
||||||
import org.springframework.data.elasticsearch.core.query.UpdateQuery;
|
import org.springframework.data.elasticsearch.core.query.UpdateQuery;
|
||||||
|
import org.springframework.data.elasticsearch.support.VersionInfo;
|
||||||
import org.springframework.data.mapping.callback.ReactiveEntityCallbacks;
|
import org.springframework.data.mapping.callback.ReactiveEntityCallbacks;
|
||||||
import org.springframework.data.mapping.context.MappingContext;
|
import org.springframework.data.mapping.context.MappingContext;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
@ -131,6 +132,15 @@ public class ReactiveElasticsearchTemplate implements ReactiveElasticsearchOpera
|
|||||||
this.exceptionTranslator = new ElasticsearchExceptionTranslator();
|
this.exceptionTranslator = new ElasticsearchExceptionTranslator();
|
||||||
this.operations = new EntityOperations(this.mappingContext);
|
this.operations = new EntityOperations(this.mappingContext);
|
||||||
this.requestFactory = new RequestFactory(converter);
|
this.requestFactory = new RequestFactory(converter);
|
||||||
|
|
||||||
|
logVersions();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void logVersions() {
|
||||||
|
getClusterVersion() //
|
||||||
|
.doOnSuccess(VersionInfo::logVersions) //
|
||||||
|
.doOnError(e -> VersionInfo.logVersions(null)) //
|
||||||
|
.subscribe();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -157,6 +167,7 @@ public class ReactiveElasticsearchTemplate implements ReactiveElasticsearchOpera
|
|||||||
|
|
||||||
this.entityCallbacks = entityCallbacks;
|
this.entityCallbacks = entityCallbacks;
|
||||||
}
|
}
|
||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
// region DocumentOperations
|
// region DocumentOperations
|
||||||
@ -775,6 +786,15 @@ public class ReactiveElasticsearchTemplate implements ReactiveElasticsearchOpera
|
|||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
// region Helper methods
|
// region Helper methods
|
||||||
|
protected Mono<String> getClusterVersion() {
|
||||||
|
try {
|
||||||
|
return Mono.from(execute(client -> client.info())).map(mainResponse -> mainResponse.getVersion().toString());
|
||||||
|
} catch (Exception ignored) {}
|
||||||
|
return Mono.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
// endregion
|
||||||
|
|
||||||
// Property Setters / Getters
|
// Property Setters / Getters
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -0,0 +1,91 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 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.support;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.Properties;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
|
import org.elasticsearch.Version;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.lang.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is used to log the versions of Spring Data Elasticsearch, the Elasticsearch client libs used to built, the
|
||||||
|
* Elasticsearch client libs currently used and of the Elasticsearch cluster. If differences greater than a patchlevel
|
||||||
|
* are detected, these are logged as warnings.
|
||||||
|
*
|
||||||
|
* @author Peter-Josef Meisch
|
||||||
|
* @since 4.0
|
||||||
|
*/
|
||||||
|
public final class VersionInfo {
|
||||||
|
|
||||||
|
private static final Logger LOG = LoggerFactory.getLogger(VersionInfo.class);
|
||||||
|
private static final AtomicBoolean initialized = new AtomicBoolean(false);
|
||||||
|
private static String VERSION_PROPERTIES = "versions.properties";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* logs the relevant version info the first time it is called. Does nothing after the first call
|
||||||
|
*
|
||||||
|
* @param clusterVersion the version of the cluster
|
||||||
|
*/
|
||||||
|
public static void logVersions(@Nullable String clusterVersion) {
|
||||||
|
if (!initialized.getAndSet(true)) {
|
||||||
|
try {
|
||||||
|
InputStream resource = VersionInfo.class.getClassLoader().getResourceAsStream(VERSION_PROPERTIES);
|
||||||
|
if (resource != null) {
|
||||||
|
Properties properties = new Properties();
|
||||||
|
properties.load(resource);
|
||||||
|
|
||||||
|
String versionSpringDataElasticsearch = properties.getProperty("version.spring-data-elasticsearch");
|
||||||
|
Version versionESBuilt = Version.fromString(properties.getProperty("version.elasticsearch-client"));
|
||||||
|
Version versionESUsed = Version.CURRENT;
|
||||||
|
Version versionESCluster = clusterVersion != null ? Version.fromString(clusterVersion) : null;
|
||||||
|
|
||||||
|
LOG.info("Version Spring Data Elasticsearch: {}", versionSpringDataElasticsearch.toString());
|
||||||
|
LOG.info("Version Elasticsearch Client in build: {}", versionESBuilt.toString());
|
||||||
|
LOG.info("Version Elasticsearch Client used: {}", versionESUsed.toString());
|
||||||
|
|
||||||
|
if (differInMajorOrMinor(versionESBuilt, versionESUsed)) {
|
||||||
|
LOG.warn("Version mismatch in between Elasticsearch Clients build/use: {} - {}", versionESBuilt,
|
||||||
|
versionESUsed);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (versionESCluster != null) {
|
||||||
|
LOG.info("Version Elasticsearch cluster: {}", versionESCluster.toString());
|
||||||
|
|
||||||
|
if (differInMajorOrMinor(versionESUsed, versionESCluster)) {
|
||||||
|
LOG.warn("Version mismatch in between Elasticsearch Client and Cluster: {} - {}", versionESUsed,
|
||||||
|
versionESCluster);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LOG.warn("cannot load {}", VERSION_PROPERTIES);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOG.warn("Could not log version info: {} - {}", e.getClass().getSimpleName(), e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean differInMajorOrMinor(Version version1, Version version2) {
|
||||||
|
return version1.major != version2.major || version1.minor != version2.minor;
|
||||||
|
}
|
||||||
|
|
||||||
|
private VersionInfo() {}
|
||||||
|
}
|
2
src/main/resources/versions.properties
Normal file
2
src/main/resources/versions.properties
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
version.spring-data-elasticsearch=${project.version}
|
||||||
|
version.elasticsearch-client=${elasticsearch}
|
@ -7,6 +7,7 @@
|
|||||||
</encoder>
|
</encoder>
|
||||||
</appender>
|
</appender>
|
||||||
|
|
||||||
|
<logger name="org.springframework.data.elasticsearch.support.VersionInfo" level="info"/>
|
||||||
<logger name="org.springframework.data.elasticsearch.junit" level="debug"/>
|
<logger name="org.springframework.data.elasticsearch.junit" level="debug"/>
|
||||||
<logger name="org.springframework.data.elasticsearch.junit.junit4.ElasticsearchVersionRule" level="info"/>
|
<logger name="org.springframework.data.elasticsearch.junit.junit4.ElasticsearchVersionRule" level="info"/>
|
||||||
<logger name="org.springframework.data.elasticsearch.client.WIRE" level="info"/>
|
<logger name="org.springframework.data.elasticsearch.client.WIRE" level="info"/>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user