diff --git a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java new file mode 100644 index 000000000..b983548f5 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java @@ -0,0 +1,52 @@ +package org.springframework.data.elasticsearch.core; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.data.elasticsearch.ElasticsearchException; +import org.springframework.data.elasticsearch.annotations.Mapping; +import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; +import org.springframework.util.Assert; +import org.springframework.util.StringUtils; + +/** + * AbstractElasticsearchTemplate + * + * @author Sascha Woo + */ +public abstract class AbstractElasticsearchTemplate { + + private static final Logger LOGGER = LoggerFactory.getLogger(AbstractElasticsearchTemplate.class); + + protected ElasticsearchConverter elasticsearchConverter; + + public AbstractElasticsearchTemplate(ElasticsearchConverter elasticsearchConverter) { + + Assert.notNull(elasticsearchConverter, "elasticsearchConverter must not be null."); + this.elasticsearchConverter = elasticsearchConverter; + } + + protected String buildMapping(Class clazz) { + + // load mapping specified in Mapping annotation if present + if (clazz.isAnnotationPresent(Mapping.class)) { + String mappingPath = clazz.getAnnotation(Mapping.class).mappingPath(); + if (!StringUtils.isEmpty(mappingPath)) { + String mappings = ResourceUtil.readFileFromClasspath(mappingPath); + if (!StringUtils.isEmpty(mappings)) { + return mappings; + } + } else { + LOGGER.info("mappingPath in @Mapping has to be defined. Building mappings using @Field"); + } + } + + // build mapping from field annotations + try { + MappingBuilder mappingBuilder = new MappingBuilder(elasticsearchConverter); + return mappingBuilder.buildPropertyMapping(clazz); + } catch (Exception e) { + throw new ElasticsearchException("Failed to build mapping for " + clazz.getSimpleName(), e); + } + } + +} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java index e14d14453..02c83ebe3 100755 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java @@ -104,6 +104,16 @@ public interface ElasticsearchOperations { */ boolean putMapping(Class clazz); + /** + * Create mapping for the given class and put the mapping to the given indexName and type. + * + * @param indexName + * @param type + * @param mappings + * @since 3.2 + */ + boolean putMapping(String indexName, String type, Class clazz); + /** * Create mapping for a given indexName and type * diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java index 5306e9b1f..99c89187b 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java @@ -143,12 +143,11 @@ import com.fasterxml.jackson.databind.ObjectMapper; * @author Mathias Teier * @author Gyula Attila Csorogi */ -public class ElasticsearchRestTemplate +public class ElasticsearchRestTemplate extends AbstractElasticsearchTemplate implements ElasticsearchOperations, EsClient, ApplicationContextAware { private static final Logger logger = LoggerFactory.getLogger(ElasticsearchRestTemplate.class); private RestHighLevelClient client; - private ElasticsearchConverter elasticsearchConverter; private ResultsMapper resultsMapper; private String searchTimeout; @@ -176,9 +175,10 @@ public class ElasticsearchRestTemplate public ElasticsearchRestTemplate(RestHighLevelClient client, ElasticsearchConverter elasticsearchConverter, ResultsMapper resultsMapper) { + + super(elasticsearchConverter); Assert.notNull(client, "Client must not be null!"); - Assert.notNull(elasticsearchConverter, "ElasticsearchConverter must not be null!"); Assert.notNull(resultsMapper, "ResultsMapper must not be null!"); this.client = client; @@ -254,23 +254,7 @@ public class ElasticsearchRestTemplate @Override public boolean putMapping(Class clazz) { - if (clazz.isAnnotationPresent(Mapping.class)) { - String mappingPath = clazz.getAnnotation(Mapping.class).mappingPath(); - if (hasText(mappingPath)) { - String mappings = ResourceUtil.readFileFromClasspath(mappingPath); - if (hasText(mappings)) { - return putMapping(clazz, mappings); - } - } else { - logger.info("mappingPath in @Mapping has to be defined. Building mappings using @Field"); - } - } - try { - MappingBuilder mappingBuilder = new MappingBuilder(elasticsearchConverter); - return putMapping(clazz, mappingBuilder.buildPropertyMapping(clazz)); - } catch (Exception e) { - throw new ElasticsearchException("Failed to build mapping for " + clazz.getSimpleName(), e); - } + return putMapping(clazz, buildMapping(clazz)); } @Override @@ -279,6 +263,11 @@ public class ElasticsearchRestTemplate mapping); } + @Override + public boolean putMapping(String indexName, String type, Class clazz) { + return putMapping(indexName, type, buildMapping(clazz)); + } + @Override public boolean putMapping(String indexName, String type, Object mapping) { Assert.notNull(indexName, "No index defined for putMapping()"); diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java index 7689aa4a0..86c4e8ce0 100755 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java @@ -82,7 +82,6 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.data.elasticsearch.ElasticsearchException; import org.springframework.data.elasticsearch.annotations.Document; -import org.springframework.data.elasticsearch.annotations.Mapping; import org.springframework.data.elasticsearch.annotations.Setting; import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage; import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; @@ -124,7 +123,7 @@ import org.springframework.util.StringUtils; * @author Farid Azaza * @author Gyula Attila Csorogi */ -public class ElasticsearchTemplate implements ElasticsearchOperations, EsClient, ApplicationContextAware { +public class ElasticsearchTemplate extends AbstractElasticsearchTemplate implements ElasticsearchOperations, EsClient, ApplicationContextAware { private static final Logger QUERY_LOGGER = LoggerFactory .getLogger("org.springframework.data.elasticsearch.core.QUERY"); @@ -132,7 +131,6 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, EsClient< private static final String FIELD_SCORE = "_score"; private Client client; - private ElasticsearchConverter elasticsearchConverter; private ResultsMapper resultsMapper; private String searchTimeout; @@ -160,13 +158,13 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, EsClient< public ElasticsearchTemplate(Client client, ElasticsearchConverter elasticsearchConverter, ResultsMapper resultsMapper) { + + super(elasticsearchConverter); Assert.notNull(client, "Client must not be null!"); - Assert.notNull(elasticsearchConverter, "ElasticsearchConverter must not be null!"); Assert.notNull(resultsMapper, "ResultsMapper must not be null!"); this.client = client; - this.elasticsearchConverter = elasticsearchConverter; this.resultsMapper = resultsMapper; } @@ -221,23 +219,7 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, EsClient< @Override public boolean putMapping(Class clazz) { - if (clazz.isAnnotationPresent(Mapping.class)) { - String mappingPath = clazz.getAnnotation(Mapping.class).mappingPath(); - if (!StringUtils.isEmpty(mappingPath)) { - String mappings = ResourceUtil.readFileFromClasspath(mappingPath); - if (!StringUtils.isEmpty(mappings)) { - return putMapping(clazz, mappings); - } - } else { - LOGGER.info("mappingPath in @Mapping has to be defined. Building mappings using @Field"); - } - } - try { - MappingBuilder mappingBuilder = new MappingBuilder(elasticsearchConverter); - return putMapping(clazz, mappingBuilder.buildPropertyMapping(clazz)); - } catch (Exception e) { - throw new ElasticsearchException("Failed to build mapping for " + clazz.getSimpleName(), e); - } + return putMapping(clazz, buildMapping(clazz)); } @Override @@ -246,6 +228,11 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, EsClient< mapping); } + @Override + public boolean putMapping(String indexName, String type, Class clazz) { + return putMapping(indexName, type, buildMapping(clazz)); + } + @Override public boolean putMapping(String indexName, String type, Object mapping) { Assert.notNull(indexName, "No index defined for putMapping()"); diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java index f49f00320..3f5f81dbc 100755 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java @@ -18,6 +18,7 @@ package org.springframework.data.elasticsearch.core; import static org.apache.commons.lang.RandomStringUtils.*; import static org.assertj.core.api.Assertions.*; import static org.elasticsearch.index.query.QueryBuilders.*; +import static org.hamcrest.CoreMatchers.*; import static org.springframework.data.elasticsearch.annotations.FieldType.*; import static org.springframework.data.elasticsearch.utils.IndexBuilder.*; @@ -1438,6 +1439,22 @@ public class ElasticsearchTemplateTests { assertThat(elasticsearchTemplate.putMapping(entity)).isTrue(); } + @Test // DATAES-305 + public void shouldPutMappingWithCustomIndexName() throws Exception { + + // given + Class entity = SampleEntity.class; + elasticsearchTemplate.deleteIndex(INDEX_1_NAME); + elasticsearchTemplate.createIndex(INDEX_1_NAME); + + // when + elasticsearchTemplate.putMapping(INDEX_1_NAME, TYPE_NAME, entity); + + // then + Map mapping = elasticsearchTemplate.getMapping(INDEX_1_NAME, TYPE_NAME); + assertThat(mapping.get("properties")).isNotNull(); + } + @Test public void shouldDeleteIndexForGivenEntity() {