From 403a85b09444c7b2dcb6b95066fafd2ef8267cc0 Mon Sep 17 00:00:00 2001 From: Ted Liang Date: Sat, 31 Oct 2015 22:37:50 +1100 Subject: [PATCH] DATAES-209 - Dynamic mapping using @Mapping Annotation at field level fix test fix comment in test --- .../elasticsearch/annotations/Mapping.java | 2 +- .../elasticsearch/core/MappingBuilder.java | 15 +++- .../entities/FieldDynamicMappingEntity.java | 51 +++++++++++ .../FieldDynamicMappingEntityRepository.java | 28 ++++++ ...ldDynamicMappingEntityRepositoryTests.java | 87 +++++++++++++++++++ .../mappings/test-field-mappings.json | 10 +++ 6 files changed, 190 insertions(+), 3 deletions(-) create mode 100644 src/test/java/org/springframework/data/elasticsearch/entities/FieldDynamicMappingEntity.java create mode 100644 src/test/java/org/springframework/data/elasticsearch/repositories/setting/FieldDynamicMappingEntityRepository.java create mode 100644 src/test/java/org/springframework/data/elasticsearch/repositories/setting/FieldDynamicMappingEntityRepositoryTests.java create mode 100644 src/test/resources/mappings/test-field-mappings.json diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/Mapping.java b/src/main/java/org/springframework/data/elasticsearch/annotations/Mapping.java index 122251ee6..323840495 100644 --- a/src/main/java/org/springframework/data/elasticsearch/annotations/Mapping.java +++ b/src/main/java/org/springframework/data/elasticsearch/annotations/Mapping.java @@ -26,7 +26,7 @@ import org.springframework.data.annotation.Persistent; @Persistent @Inherited @Retention(RetentionPolicy.RUNTIME) -@Target({ElementType.TYPE}) +@Target({ElementType.TYPE, ElementType.FIELD}) public @interface Mapping { String mappingPath() default ""; diff --git a/src/main/java/org/springframework/data/elasticsearch/core/MappingBuilder.java b/src/main/java/org/springframework/data/elasticsearch/core/MappingBuilder.java index d58f9db77..3d06b3bda 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/MappingBuilder.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/MappingBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 the original author or authors. + * Copyright 2014-2016 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. @@ -29,11 +29,11 @@ import org.apache.commons.lang.math.NumberUtils; import org.elasticsearch.common.lang3.StringUtils; import org.elasticsearch.common.xcontent.XContentBuilder; import org.springframework.core.GenericCollectionTypeResolver; +import org.springframework.core.io.ClassPathResource; import org.springframework.data.annotation.Transient; import org.springframework.data.elasticsearch.annotations.*; import org.springframework.data.elasticsearch.core.completion.Completion; import org.springframework.data.elasticsearch.core.geo.GeoPoint; -import org.springframework.data.geo.*; import org.springframework.data.mapping.model.SimpleTypeHolder; import org.springframework.data.util.ClassTypeInformation; import org.springframework.data.util.TypeInformation; @@ -112,6 +112,17 @@ class MappingBuilder { continue; } + if (field.isAnnotationPresent(Mapping.class)) { + String mappingPath = field.getAnnotation(Mapping.class).mappingPath(); + if (isNotBlank(mappingPath)) { + ClassPathResource mappings = new ClassPathResource(mappingPath); + if (mappings.exists()) { + xContentBuilder.rawField(field.getName(), mappings.getInputStream()); + continue; + } + } + } + boolean isGeoPointField = isGeoPointField(field); boolean isCompletionField = isCompletionField(field); diff --git a/src/test/java/org/springframework/data/elasticsearch/entities/FieldDynamicMappingEntity.java b/src/test/java/org/springframework/data/elasticsearch/entities/FieldDynamicMappingEntity.java new file mode 100644 index 000000000..0fade78c4 --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/entities/FieldDynamicMappingEntity.java @@ -0,0 +1,51 @@ +/* + * Copyright 2014 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 + * + * http://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.entities; + +import org.springframework.data.annotation.Id; +import org.springframework.data.elasticsearch.annotations.Document; +import org.springframework.data.elasticsearch.annotations.Mapping; + +/** + * Sample FieldDynamicMappingEntity for test dynamic mapping using @Mapping Annotation at field level + * + * @author Ted Liang + */ +@Document(indexName = "test-field-mapping-index", type = "test-field-mapping-type") +public class FieldDynamicMappingEntity { + + @Id + private String id; + + @Mapping(mappingPath = "/mappings/test-field-mappings.json") + private byte[] file; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public byte[] getFile() { + return file; + } + + public void setFile(byte[] file) { + this.file = file; + } +} diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/setting/FieldDynamicMappingEntityRepository.java b/src/test/java/org/springframework/data/elasticsearch/repositories/setting/FieldDynamicMappingEntityRepository.java new file mode 100644 index 000000000..27a3939dd --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/setting/FieldDynamicMappingEntityRepository.java @@ -0,0 +1,28 @@ +/* + * Copyright 2014 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 + * + * http://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.repositories.setting; + +import org.springframework.data.elasticsearch.entities.FieldDynamicMappingEntity; +import org.springframework.data.elasticsearch.repository.ElasticsearchCrudRepository; + +/** + * FieldDynamicMappingEntityRepository + * + * @author Ted Liang + */ +public interface FieldDynamicMappingEntityRepository extends ElasticsearchCrudRepository { + +} diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/setting/FieldDynamicMappingEntityRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/setting/FieldDynamicMappingEntityRepositoryTests.java new file mode 100644 index 000000000..7d17aa1fd --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/setting/FieldDynamicMappingEntityRepositoryTests.java @@ -0,0 +1,87 @@ +/* + * Copyright 2014 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 + * + * http://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.repositories.setting; + +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; +import static org.junit.Assert.assertThat; + +import java.util.Map; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; +import org.springframework.data.elasticsearch.entities.FieldDynamicMappingEntity; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +/** + * FieldDynamicMappingEntityRepositoryTests + * + * @author Ted Liang + */ +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration("classpath:dynamic-settings-test.xml") +public class FieldDynamicMappingEntityRepositoryTests { + + @Autowired + private FieldDynamicMappingEntityRepository repository; + + @Autowired + private ElasticsearchTemplate elasticsearchTemplate; + + @Before + public void before() { + elasticsearchTemplate.deleteIndex(FieldDynamicMappingEntity.class); + elasticsearchTemplate.createIndex(FieldDynamicMappingEntity.class); + elasticsearchTemplate.putMapping(FieldDynamicMappingEntity.class); + elasticsearchTemplate.refresh(FieldDynamicMappingEntity.class, true); + } + + /* + DATAES-209 + */ + @Test + public void shouldCreateMappingWithMappingAnnotationAtFieldLevel() { + //given + + //then + Map mapping = elasticsearchTemplate.getMapping(FieldDynamicMappingEntity.class); + assertThat(mapping, is(notNullValue())); + + Map properties = (Map) mapping.get("properties"); + assertThat(properties, is(notNullValue())); + + assertThat(properties.containsKey("file"), is(true)); + Map file = (Map) properties.get("file"); + assertThat(file, is(notNullValue())); + assertThat(((String) file.get("type")), is("string")); + + assertThat(file.containsKey("fields"), is(true)); + Map fields = (Map) file.get("fields"); + assertThat(fields, is(notNullValue())); + + assertThat(fields.containsKey("content"), is(true)); + Map content = (Map) fields.get("content"); + assertThat(content, is(notNullValue())); + + assertThat((String)content.get("type"), is("string")); + assertThat((String)content.get("term_vector"), is("with_positions_offsets")); + assertThat((Boolean)content.get("store"), is(Boolean.TRUE)); + } +} diff --git a/src/test/resources/mappings/test-field-mappings.json b/src/test/resources/mappings/test-field-mappings.json new file mode 100644 index 000000000..57fb17263 --- /dev/null +++ b/src/test/resources/mappings/test-field-mappings.json @@ -0,0 +1,10 @@ +{ + "type": "string", + "fields": { + "content": { + "type": "string", + "term_vector":"with_positions_offsets", + "store": true + } + } +}