DATAES-709 - Add parameter to include defaults on get settings.

Original PR: #357
This commit is contained in:
Sascha Woo 2019-12-15 09:44:37 +01:00 committed by Peter-Josef Meisch
parent dec5231a05
commit 47d0104295
6 changed files with 122 additions and 53 deletions

View File

@ -20,7 +20,9 @@ import static org.springframework.util.StringUtils.*;
import java.util.HashMap;
import java.util.Map;
import org.elasticsearch.action.admin.indices.settings.get.GetSettingsResponse;
import org.elasticsearch.common.collect.MapBuilder;
import org.elasticsearch.common.settings.Settings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.elasticsearch.ElasticsearchException;
@ -36,6 +38,7 @@ import org.springframework.util.StringUtils;
* Base implementation of {@link IndexOperations} common to Transport and Rest based Implementations of IndexOperations.
*
* @author Peter-Josef Meisch
* @author Sascha Woo
* @since 4.0
*/
abstract class AbstractDefaultIndexOperations implements IndexOperations {
@ -112,8 +115,13 @@ abstract class AbstractDefaultIndexOperations implements IndexOperations {
}
@Override
public Map<String, Object> getSetting(Class<?> clazz) {
return getSetting(getRequiredPersistentEntity(clazz).getIndexCoordinates().getIndexName());
public Map<String, Object> getSettings(Class<?> clazz) {
return getSettings(clazz, false);
}
@Override
public Map<String, Object> getSettings(Class<?> clazz, boolean includeDefaults) {
return getSettings(getRequiredPersistentEntity(clazz).getIndexCoordinates().getIndexName(), includeDefaults);
}
@Override
@ -166,6 +174,27 @@ abstract class AbstractDefaultIndexOperations implements IndexOperations {
public IndexCoordinates getIndexCoordinatesFor(Class<?> clazz) {
return getRequiredPersistentEntity(clazz).getIndexCoordinates();
}
protected Map<String, Object> convertSettingsResponseToMap(GetSettingsResponse response, String indexName) {
Map<String, Object> settings = new HashMap<>();
if (!response.getIndexToDefaultSettings().isEmpty()) {
Settings defaultSettings = response.getIndexToDefaultSettings().get(indexName);
for (String key : defaultSettings.keySet()) {
settings.put(key, defaultSettings.get(key));
}
}
if (!response.getIndexToSettings().isEmpty()) {
Settings customSettings = response.getIndexToSettings().get(indexName);
for (String key : customSettings.keySet()) {
settings.put(key, customSettings.get(key));
}
}
return settings;
}
// endregion
}

View File

@ -23,13 +23,14 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.http.util.EntityUtils;
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest;
import org.elasticsearch.action.admin.indices.settings.get.GetSettingsRequest;
import org.elasticsearch.action.admin.indices.settings.get.GetSettingsResponse;
import org.elasticsearch.client.Request;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.Response;
@ -37,10 +38,6 @@ import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.cluster.metadata.AliasMetaData;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.DeprecationHandler;
import org.elasticsearch.common.xcontent.NamedXContentRegistry;
import org.elasticsearch.common.xcontent.XContentType;
import org.springframework.data.elasticsearch.ElasticsearchException;
import org.springframework.data.elasticsearch.core.client.support.AliasData;
import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
@ -56,6 +53,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
* {@link IndexOperations} implementation using the RestClient.
*
* @author Peter-Josef Meisch
* @author Sascha Woo
* @since 4.0
*/
class DefaultIndexOperations extends AbstractDefaultIndexOperations implements IndexOperations {
@ -176,21 +174,27 @@ class DefaultIndexOperations extends AbstractDefaultIndexOperations implements I
}
@Override
public Map getSetting(String indexName) {
public Map<String, Object> getSettings(String indexName) {
return getSettings(indexName, false);
}
@Override
public Map<String, Object> getSettings(String indexName, boolean includeDefaults) {
Assert.notNull(indexName, "No index defined for getSettings");
ObjectMapper objMapper = new ObjectMapper();
Map settings = null;
RestClient restClient = client.getLowLevelClient();
try {
Response response = restClient.performRequest(new Request("GET", "/" + indexName + "/_settings"));
settings = convertSettingResponse(EntityUtils.toString(response.getEntity()), indexName);
GetSettingsRequest request = new GetSettingsRequest() //
.indices(indexName) //
.includeDefaults(includeDefaults);
} catch (Exception e) {
throw new ElasticsearchException("Error while getting settings for indexName : " + indexName, e);
try {
GetSettingsResponse response = client.indices() //
.getSettings(request, RequestOptions.DEFAULT);
return convertSettingsResponseToMap(response, indexName);
} catch (IOException e) {
throw new ElasticsearchException("failed to get settings for index: " + indexName, e);
}
return settings;
}
@Override
@ -258,24 +262,5 @@ class DefaultIndexOperations extends AbstractDefaultIndexOperations implements I
}
}
private Map<String, String> convertSettingResponse(String settingResponse, String indexName) {
ObjectMapper mapper = new ObjectMapper();
try {
Settings settings = Settings.fromXContent(XContentType.JSON.xContent().createParser(NamedXContentRegistry.EMPTY,
DeprecationHandler.THROW_UNSUPPORTED_OPERATION, settingResponse));
String prefix = indexName + ".settings.";
// Backwards compatibility. TODO Change to return Settings object.
Map<String, String> result = new HashMap<String, String>();
Set<String> keySet = settings.keySet();
for (String key : keySet) {
result.put(key.substring(prefix.length()), settings.get(key));
}
return result;
} catch (IOException e) {
throw new ElasticsearchException("Could not map alias response : " + settingResponse, e);
}
}
// endregion
}

View File

@ -19,7 +19,6 @@ import static org.elasticsearch.client.Requests.*;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest;
import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest;
@ -28,9 +27,9 @@ import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequest;
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequestBuilder;
import org.elasticsearch.action.admin.indices.settings.get.GetSettingsRequest;
import org.elasticsearch.action.admin.indices.settings.get.GetSettingsResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.cluster.metadata.AliasMetaData;
import org.elasticsearch.common.settings.Settings;
import org.springframework.data.elasticsearch.ElasticsearchException;
import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
@ -41,6 +40,7 @@ import org.springframework.util.Assert;
* {@link IndexOperations} implementation using the TransportClient.
*
* @author Peter-Josef Meisch
* @author Sascha Woo
* @since 4.0
*/
class DefaultTransportIndexOperations extends AbstractDefaultIndexOperations implements IndexOperations {
@ -122,13 +122,25 @@ class DefaultTransportIndexOperations extends AbstractDefaultIndexOperations imp
}
@Override
public Map<String, Object> getSetting(String indexName) {
public Map<String, Object> getSettings(String indexName) {
return getSettings(indexName, false);
}
@Override
public Map<String, Object> getSettings(String indexName, boolean includeDefaults) {
Assert.notNull(indexName, "No index defined for getSettings");
Settings settings = client.admin().indices().getSettings(new GetSettingsRequest()).actionGet().getIndexToSettings()
.get(indexName);
return settings.keySet().stream().collect(Collectors.toMap((key) -> key, (key) -> settings.get(key)));
GetSettingsRequest request = new GetSettingsRequest() //
.indices(indexName) //
.includeDefaults(includeDefaults);
GetSettingsResponse response = client.admin() //
.indices() //
.getSettings(request) //
.actionGet();
return convertSettingsResponseToMap(response, indexName);
}
@Override
@ -138,4 +150,5 @@ class DefaultTransportIndexOperations extends AbstractDefaultIndexOperations imp
client.admin().indices().refresh(refreshRequest(index.getIndexNames())).actionGet();
}
}

View File

@ -269,11 +269,11 @@ public interface ElasticsearchOperations extends DocumentOperations, SearchOpera
*
* @param indexName the name of the index
* @return the settings
* @deprecated since 4.0, use {@link IndexOperations#getSetting(String)} )} instead}
* @deprecated since 4.0, use {@link IndexOperations#getSettings(String)} )} instead}
*/
@Deprecated
default Map<String, Object> getSetting(String indexName) {
return getIndexOperations().getSetting(indexName);
return getIndexOperations().getSettings(indexName);
}
/**
@ -282,11 +282,11 @@ public interface ElasticsearchOperations extends DocumentOperations, SearchOpera
* @param clazz The entity class, must be annotated with
* {@link org.springframework.data.elasticsearch.annotations.Document}
* @return the settings
* @deprecated since 4.0, use {@link IndexOperations#getSetting(Class)} instead}
* @deprecated since 4.0, use {@link IndexOperations#getSettings(Class)} instead}
*/
@Deprecated
default Map<String, Object> getSetting(Class<?> clazz) {
return getIndexOperations().getSetting(clazz);
return getIndexOperations().getSettings(clazz);
}
/**

View File

@ -27,6 +27,7 @@ import org.springframework.data.elasticsearch.core.query.AliasQuery;
* <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/indices.html">Elasticsearch Index APIs</a>.
*
* @author Peter-Josef Meisch
* @author Sascha Woo
* @since 4.0
*/
public interface IndexOperations {
@ -188,7 +189,16 @@ public interface IndexOperations {
* @param indexName the name of the index
* @return the settings
*/
Map<String, Object> getSetting(String indexName);
Map<String, Object> getSettings(String indexName);
/**
* Get settings for a given indexName.
*
* @param indexName the name of the index
* @param includeDefaults whether or not to include all the default settings
* @return the settings
*/
Map<String, Object> getSettings(String indexName, boolean includeDefaults);
/**
* Get settings for a given class.
@ -197,7 +207,17 @@ public interface IndexOperations {
* {@link org.springframework.data.elasticsearch.annotations.Document}
* @return the settings
*/
Map<String, Object> getSetting(Class<?> clazz);
Map<String, Object> getSettings(Class<?> clazz);
/**
* Get settings for a given class.
*
* @param clazz The entity class, must be annotated with
* {@link org.springframework.data.elasticsearch.annotations.Document}
* @param includeDefaults whether or not to include all the default settings
* @return the settings
*/
Map<String, Object> getSettings(Class<?> clazz, boolean includeDefaults);
/**
* Refresh the index(es).

View File

@ -887,7 +887,7 @@ public abstract class ElasticsearchTemplateTests {
// when
// creation is done in setup method
Map setting = indexOperations.getSetting(SampleEntity.class);
Map setting = indexOperations.getSettings(SampleEntity.class);
// then
assertThat(setting.get("index.number_of_shards")).isEqualTo("1");
@ -2166,7 +2166,7 @@ public abstract class ElasticsearchTemplateTests {
indexOperations.createIndex(INDEX_3_NAME, settings);
// then
Map map = indexOperations.getSetting(INDEX_3_NAME);
Map map = indexOperations.getSettings(INDEX_3_NAME);
assertThat(indexOperations.indexExists(INDEX_3_NAME)).isTrue();
assertThat(map.containsKey("index.analysis.analyzer.emailAnalyzer.tokenizer")).isTrue();
assertThat(map.get("index.analysis.analyzer.emailAnalyzer.tokenizer")).isEqualTo("uax_url_email");
@ -2179,7 +2179,7 @@ public abstract class ElasticsearchTemplateTests {
// delete , create and apply mapping in before method
// then
Map map = indexOperations.getSetting(SampleEntity.class);
Map map = indexOperations.getSettings(SampleEntity.class);
assertThat(indexOperations.indexExists(SampleEntity.class)).isTrue();
assertThat(map.containsKey("index.refresh_interval")).isTrue();
assertThat(map.containsKey("index.number_of_replicas")).isTrue();
@ -2209,7 +2209,7 @@ public abstract class ElasticsearchTemplateTests {
indexOperations.refresh(SampleEntity.class);
// then
Map map = indexOperations.getSetting(SampleEntity.class);
Map map = indexOperations.getSettings(SampleEntity.class);
assertThat(indexOperations.indexExists(INDEX_NAME_SAMPLE_ENTITY)).isTrue();
assertThat(map.containsKey("index.number_of_replicas")).isTrue();
assertThat(map.containsKey("index.number_of_shards")).isTrue();
@ -2284,7 +2284,7 @@ public abstract class ElasticsearchTemplateTests {
// then
assertThat(created).isTrue();
Map setting = indexOperations.getSetting(UseServerConfigurationEntity.class);
Map setting = indexOperations.getSettings(UseServerConfigurationEntity.class);
assertThat(setting.get("index.number_of_shards")).isEqualTo("1");
assertThat(setting.get("index.number_of_replicas")).isEqualTo("1");
}
@ -2811,6 +2811,28 @@ public abstract class ElasticsearchTemplateTests {
assertThat(searchRequest.source().from()).isEqualTo(30);
}
@Test // DATAES-709
public void shouldNotIncludeDefaultsGetIndexSettings() {
// given
// when
Map<String, Object> map = indexOperations.getSettings(SampleEntity.class);
// then
assertThat(map).doesNotContainKey("index.max_result_window");
}
@Test // DATAES-709
public void shouldIncludeDefaultsOnGetIndexSettings() {
// given
// when
Map<String, Object> map = indexOperations.getSettings(SampleEntity.class, true);
// then
assertThat(map).containsKey("index.max_result_window");
}
protected RequestFactory getRequestFactory() {
return ((AbstractElasticsearchTemplate) operations).getRequestFactory();
}