DATAES-628 - Adapt mappers to Document API.

This commit is contained in:
Mark Paluch 2019-08-12 15:59:19 +02:00 committed by Peter-Josef Meisch
parent 29ecd484c5
commit 7a612f3ba8
8 changed files with 175 additions and 167 deletions

View File

@ -17,11 +17,11 @@ package org.springframework.data.elasticsearch.core;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.springframework.data.annotation.ReadOnlyProperty;
import org.springframework.data.elasticsearch.Document;
import org.springframework.data.elasticsearch.core.geo.CustomGeoModule;
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity;
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty;
@ -44,6 +44,7 @@ import com.fasterxml.jackson.databind.ser.BeanSerializerModifier;
* @author Petar Tahchiev
* @author Oliver Gierke
* @author Christoph Strobl
* @author Mark Paluch
*/
public class DefaultEntityMapper implements EntityMapper {
@ -51,7 +52,7 @@ public class DefaultEntityMapper implements EntityMapper {
/**
* Creates a new {@link DefaultEntityMapper} using the given {@link MappingContext}.
*
*
* @param context must not be {@literal null}.
*/
public DefaultEntityMapper(
@ -74,7 +75,8 @@ public class DefaultEntityMapper implements EntityMapper {
*/
@Override
public String mapToString(Object object) throws IOException {
return objectMapper.writeValueAsString(object);
return objectMapper
.writeValueAsString(object instanceof Document ? new LinkedHashMap<>((Document) object) : object);
}
/*
@ -82,10 +84,10 @@ public class DefaultEntityMapper implements EntityMapper {
* @see org.springframework.data.elasticsearch.core.EntityMapper#mapObject(java.lang.Object)
*/
@Override
public Map<String, Object> mapObject(Object source) {
public Document mapObject(Object source) {
try {
return objectMapper.readValue(mapToString(source), HashMap.class);
return objectMapper.readValue(mapToString(source), Document.class);
} catch (IOException e) {
throw new MappingException(e.getMessage(), e);
}
@ -105,8 +107,7 @@ public class DefaultEntityMapper implements EntityMapper {
* @see org.springframework.data.elasticsearch.core.EntityMapper#readObject(java.util.Map, java.lang.Class)
*/
@Override
public <T> T readObject (Map<String, Object> source, Class<T> targetType) {
public <T> T readObject(Document source, Class<T> targetType) {
try {
return mapToObject(mapToString(source), targetType);
} catch (IOException e) {
@ -126,7 +127,7 @@ public class DefaultEntityMapper implements EntityMapper {
/**
* Creates a new {@link SpringDataElasticsearchModule} using the given {@link MappingContext}.
*
*
* @param context must not be {@literal null}.
*/
public SpringDataElasticsearchModule(
@ -156,7 +157,7 @@ public class DefaultEntityMapper implements EntityMapper {
this.context = context;
}
/*
/*
* (non-Javadoc)
* @see com.fasterxml.jackson.databind.ser.BeanSerializerModifier#changeProperties(com.fasterxml.jackson.databind.SerializationConfig, com.fasterxml.jackson.databind.BeanDescription, java.util.List)
*/

View File

@ -15,11 +15,7 @@
*/
package org.springframework.data.elasticsearch.core;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.elasticsearch.action.get.GetResponse;
@ -45,11 +41,6 @@ import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.mapping.model.ConvertingPropertyAccessor;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import com.fasterxml.jackson.core.JsonEncoding;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonGenerator;
/**
* @author Artur Konczak
@ -105,13 +96,7 @@ public class DefaultResultMapper extends AbstractResultMapper {
List<T> results = new ArrayList<>();
for (SearchHit hit : response.getHits()) {
if (hit != null) {
T result = null;
String hitSourceAsString = hit.getSourceAsString();
if (!StringUtils.isEmpty(hitSourceAsString)) {
result = mapEntity(hitSourceAsString, clazz);
} else {
result = mapEntity(hit.getFields().values(), clazz);
}
T result = mapSearchHit(hit, clazz);
setPersistentEntityId(result, hit.getId(), clazz);
setPersistentEntityVersion(result, hit.getVersion(), clazz);
@ -149,38 +134,14 @@ public class DefaultResultMapper extends AbstractResultMapper {
}
}
private <T> T mapEntity(Collection<DocumentField> values, Class<T> clazz) {
return mapEntity(buildJSONFromFields(values), clazz);
}
private String buildJSONFromFields(Collection<DocumentField> values) {
JsonFactory nodeFactory = new JsonFactory();
try {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
JsonGenerator generator = nodeFactory.createGenerator(stream, JsonEncoding.UTF8);
generator.writeStartObject();
for (DocumentField value : values) {
if (value.getValues().size() > 1) {
generator.writeArrayFieldStart(value.getName());
for (Object val : value.getValues()) {
generator.writeObject(val);
}
generator.writeEndArray();
} else {
generator.writeObjectField(value.getName(), value.getValue());
}
}
generator.writeEndObject();
generator.flush();
return new String(stream.toByteArray(), Charset.forName("UTF-8"));
} catch (IOException e) {
return null;
}
}
@Override
public <T> T mapResult(GetResponse response, Class<T> clazz) {
T result = mapEntity(response.getSourceAsString(), clazz);
if (!response.isExists()) {
return null;
}
T result = mapDocument(DocumentAdapters.from(response), clazz);
if (result != null) {
setPersistentEntityId(result, response.getId(), clazz);
setPersistentEntityVersion(result, response.getVersion(), clazz);
@ -193,7 +154,7 @@ public class DefaultResultMapper extends AbstractResultMapper {
List<T> list = new ArrayList<>();
for (MultiGetItemResponse response : responses.getResponses()) {
if (!response.isFailed() && response.getResponse().isExists()) {
T result = mapEntity(response.getResponse().getSourceAsString(), clazz);
T result = mapResult(response.getResponse(), clazz);
setPersistentEntityId(result, response.getResponse().getId(), clazz);
setPersistentEntityVersion(result, response.getResponse().getVersion(), clazz);
list.add(result);

View File

@ -15,8 +15,6 @@
*/
package org.springframework.data.elasticsearch.core;
import com.fasterxml.jackson.databind.ObjectReader;
import com.fasterxml.jackson.databind.ObjectWriter;
import lombok.RequiredArgsConstructor;
import java.io.IOException;
@ -34,6 +32,8 @@ import org.springframework.data.convert.EntityInstantiator;
import org.springframework.data.convert.EntityInstantiators;
import org.springframework.data.convert.EntityReader;
import org.springframework.data.convert.EntityWriter;
import org.springframework.data.elasticsearch.Document;
import org.springframework.data.elasticsearch.SearchDocument;
import org.springframework.data.elasticsearch.core.convert.ElasticsearchCustomConversions;
import org.springframework.data.elasticsearch.core.convert.ElasticsearchTypeMapper;
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity;
@ -52,6 +52,8 @@ import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectReader;
import com.fasterxml.jackson.databind.ObjectWriter;
/**
* Elasticsearch specific {@link EntityReader} & {@link EntityWriter} implementation based on domain type
@ -59,12 +61,12 @@ import com.fasterxml.jackson.databind.ObjectMapper;
*
* @author Christoph Strobl
* @author Peter-Josef Meisch
* @author Mark Paluch
* @since 3.2
*/
public class ElasticsearchEntityMapper implements
EntityConverter<ElasticsearchPersistentEntity<?>, ElasticsearchPersistentProperty, Object, Map<String, Object>>,
EntityWriter<Object, Map<String, Object>>, EntityReader<Object, Map<String, Object>>, InitializingBean,
EntityMapper {
public class ElasticsearchEntityMapper
implements EntityConverter<ElasticsearchPersistentEntity<?>, ElasticsearchPersistentProperty, Object, Document>,
EntityWriter<Object, Document>, EntityReader<Object, Document>, InitializingBean, EntityMapper {
private final MappingContext<? extends ElasticsearchPersistentEntity<?>, ElasticsearchPersistentProperty> mappingContext;
private final GenericConversionService conversionService;
@ -134,14 +136,14 @@ public class ElasticsearchEntityMapper implements
// --> READ
@Override
public <T> T readObject(Map<String, Object> source, Class<T> targetType) {
public <T> T readObject(Document source, Class<T> targetType) {
return read(targetType, source);
}
@SuppressWarnings("unchecked")
@Override
@Nullable
public <R> R read(Class<R> type, Map<String, Object> source) {
public <R> R read(Class<R> type, Document source) {
return doRead(source, ClassTypeInformation.from((Class<R>) ClassUtils.getUserClass(type)));
}
@ -320,16 +322,16 @@ public class ElasticsearchEntityMapper implements
// --> WRITE
@Override
public Map<String, Object> mapObject(Object source) {
public Document mapObject(Object source) {
LinkedHashMap<String, Object> target = new LinkedHashMap<>();
Document target = Document.create();
write(source, target);
return target;
}
@SuppressWarnings("unchecked")
@Override
public void write(@Nullable Object source, Map<String, Object> sink) {
public void write(@Nullable Object source, Document sink) {
if (source == null) {
return;
@ -351,8 +353,7 @@ public class ElasticsearchEntityMapper implements
doWrite(source, sink, type);
}
protected void doWrite(@Nullable Object source, Map<String, Object> sink,
@Nullable TypeInformation<? extends Object> typeHint) {
protected void doWrite(@Nullable Object source, Document sink, @Nullable TypeInformation<? extends Object> typeHint) {
if (source == null) {
return;
@ -382,7 +383,7 @@ public class ElasticsearchEntityMapper implements
writeEntity(entity, source, sink, null);
}
protected void writeEntity(ElasticsearchPersistentEntity<?> entity, Object source, Map<String, Object> sink,
protected void writeEntity(ElasticsearchPersistentEntity<?> entity, Object source, Document sink,
@Nullable TypeInformation containingStructure) {
PersistentPropertyAccessor<?> accessor = entity.getPropertyAccessor(source);
@ -391,11 +392,11 @@ public class ElasticsearchEntityMapper implements
typeMapper.writeType(source.getClass(), sink);
}
writeProperties(entity, accessor, sink);
writeProperties(entity, accessor, new MapValueAccessor(sink));
}
protected void writeProperties(ElasticsearchPersistentEntity<?> entity, PersistentPropertyAccessor<?> accessor,
Map<String, Object> sink) {
MapValueAccessor sink) {
for (ElasticsearchPersistentProperty property : entity) {
@ -412,19 +413,19 @@ public class ElasticsearchEntityMapper implements
if (!isSimpleType(value)) {
writeProperty(property, value, sink);
} else {
sink.put(property.getFieldName(), getWriteSimpleValue(value));
sink.set(property, getWriteSimpleValue(value));
}
}
}
protected void writeProperty(ElasticsearchPersistentProperty property, Object value, Map<String, Object> sink) {
protected void writeProperty(ElasticsearchPersistentProperty property, Object value, MapValueAccessor sink) {
Optional<Class<?>> customWriteTarget = conversions.getCustomWriteTarget(value.getClass());
if (customWriteTarget.isPresent()) {
Class<?> writeTarget = customWriteTarget.get();
sink.put(property.getFieldName(), conversionService.convert(value, writeTarget));
sink.set(property, conversionService.convert(value, writeTarget));
return;
}
@ -442,7 +443,7 @@ public class ElasticsearchEntityMapper implements
}
}
sink.put(property.getFieldName(), getWriteComplexValue(property, typeHint, value));
sink.set(property, getWriteComplexValue(property, typeHint, value));
}
protected Object getWriteSimpleValue(Object value) {
@ -479,7 +480,8 @@ public class ElasticsearchEntityMapper implements
}
private Object writeEntity(Object value, ElasticsearchPersistentProperty property, TypeInformation<?> typeHint) {
Map<String, Object> target = new LinkedHashMap<>();
Document target = Document.create();
writeEntity(mappingContext.getRequiredPersistentEntity(value.getClass()), value, target,
property.getTypeInformation());
return target;
@ -549,15 +551,15 @@ public class ElasticsearchEntityMapper implements
@Override
public String mapToString(Object source) throws IOException {
Map<String, Object> sink = new LinkedHashMap<>();
Document sink = Document.create();
write(source, sink);
return objectWriter.writeValueAsString(sink);
return objectWriter.writeValueAsString(new LinkedHashMap<>(sink));
}
@Override
public <T> T mapToObject(String source, Class<T> clazz) throws IOException {
return read(clazz, objectReader.readValue(source));
return read(clazz, Document.from(objectReader.readValue(source)));
}
// --> PRIVATE HELPERS
@ -669,6 +671,18 @@ public class ElasticsearchEntityMapper implements
public Object get(ElasticsearchPersistentProperty property) {
if (property.isIdProperty() && ((Document) target).hasId()) {
return ((Document) target).getId();
}
if (property.isVersionProperty() && ((Document) target).hasVersion()) {
return ((Document) target).getVersion();
}
if (property.isScoreProperty()) {
return ((SearchDocument) target).getScore();
}
String fieldName = property.getFieldName();
if (!fieldName.contains(".")) {
@ -691,6 +705,19 @@ public class ElasticsearchEntityMapper implements
return result;
}
public void set(ElasticsearchPersistentProperty property, Object value) {
if (property.isIdProperty()) {
((Document) target).setId((String) value);
}
if (property.isVersionProperty()) {
((Document) target).setVersion((Long) value);
}
target.put(property.getFieldName(), value);
}
@SuppressWarnings("unchecked")
private Map<String, Object> getAsMap(Object result) {

View File

@ -18,6 +18,7 @@ package org.springframework.data.elasticsearch.core;
import java.io.IOException;
import java.util.Map;
import org.springframework.data.elasticsearch.Document;
import org.springframework.lang.Nullable;
/**
@ -27,6 +28,7 @@ import org.springframework.lang.Nullable;
* @author Rizwan Idrees
* @author Mohsin Husen
* @author Christoph Strobl
* @author Mark Paluch
*/
public interface EntityMapper {
@ -41,7 +43,7 @@ public interface EntityMapper {
* @return never {@literal null}
* @since 3.2
*/
Map<String, Object> mapObject(Object source);
Document mapObject(Object source);
/**
* Map the given {@link Map} into an instance of the {@literal targetType}.
@ -53,5 +55,5 @@ public interface EntityMapper {
* @since 3.2
*/
@Nullable
<T> T readObject(Map<String, Object> source, Class<T> targetType);
<T> T readObject(Document source, Class<T> targetType);
}

View File

@ -16,10 +16,11 @@
package org.springframework.data.elasticsearch.core;
import java.io.IOException;
import java.util.Map;
import org.elasticsearch.index.get.GetResult;
import org.elasticsearch.search.SearchHit;
import org.springframework.data.elasticsearch.Document;
import org.springframework.data.elasticsearch.ElasticsearchException;
import org.springframework.data.projection.ProjectionFactory;
import org.springframework.data.projection.SpelAwareProxyProjectionFactory;
@ -34,6 +35,7 @@ import org.springframework.util.StringUtils;
* @author Mohsin Husen
* @author Artur Konczak
* @author Christoph Strobl
* @author Mark Paluch
*/
public interface ResultsMapper extends SearchResultMapper, GetResultMapper, MultiGetResultMapper {
@ -50,6 +52,7 @@ public interface ResultsMapper extends SearchResultMapper, GetResultMapper, Mult
}
@Nullable
@Deprecated
default <T> T mapEntity(String source, Class<T> clazz) {
if (StringUtils.isEmpty(source)) {
@ -63,27 +66,18 @@ public interface ResultsMapper extends SearchResultMapper, GetResultMapper, Mult
}
/**
* Map a single {@link GetResult} to an instance of the given type.
* Map a single {@link Document} to an instance of the given type.
*
* @param getResult must not be {@literal null}.
* @param document must not be {@literal null}.
* @param type must not be {@literal null}.
* @param <T>
* @return can be {@literal null} if the {@link GetResult#isSourceEmpty() is empty}.
* @since 3.2
* @return can be {@literal null} if the {@link Document#isEmpty() is empty}.
* @since 4.0
*/
@Nullable
default <T> T mapGetResult(GetResult getResult, Class<T> type) {
default <T> T mapDocument(Document document, Class<T> type) {
if (getResult.isSourceEmpty()) {
return null;
}
Map<String, Object> source = getResult.getSource();
if (!source.containsKey("id") || source.get("id") == null) {
source.put("id", getResult.getId());
}
Object mappedResult = getEntityMapper().readObject(source, type);
Object mappedResult = getEntityMapper().readObject(document, type);
if (mappedResult == null) {
return (T) null;
@ -96,6 +90,20 @@ public interface ResultsMapper extends SearchResultMapper, GetResultMapper, Mult
return type.cast(mappedResult);
}
/**
* Map a single {@link GetResult} to an instance of the given type.
*
* @param getResult must not be {@literal null}.
* @param type must not be {@literal null}.
* @param <T>
* @return can be {@literal null} if the {@link GetResult#isSourceEmpty() is empty}.
* @since 3.2
*/
@Nullable
default <T> T mapGetResult(GetResult getResult, Class<T> type) {
return mapDocument(DocumentAdapters.from(getResult), type);
}
/**
* Map a single {@link SearchHit} to an instance of the given type.
*
@ -107,26 +115,6 @@ public interface ResultsMapper extends SearchResultMapper, GetResultMapper, Mult
*/
@Nullable
default <T> T mapSearchHit(SearchHit searchHit, Class<T> type) {
if (!searchHit.hasSource()) {
return null;
}
Map<String, Object> source = searchHit.getSourceAsMap();
if (!source.containsKey("id") || source.get("id") == null) {
source.put("id", searchHit.getId());
}
Object mappedResult = getEntityMapper().readObject(source, type);
if (mappedResult == null) {
return null;
}
if (type.isInterface()) {
return getProjectionFactory().createProjection(type, mappedResult);
}
return type.cast(mappedResult);
return mapDocument(DocumentAdapters.from(searchHit), type);
}
}

View File

@ -16,11 +16,13 @@
package org.springframework.data.elasticsearch.core;
import java.io.IOException;
import java.util.Map;
import org.springframework.data.elasticsearch.Document;
/**
* @author Artur Konczak
* @author Mohsin Husen
* @author Mark Paluch
*/
public class CustomEntityMapper implements EntityMapper {
@ -41,12 +43,12 @@ public class CustomEntityMapper implements EntityMapper {
}
@Override
public Map<String, Object> mapObject(Object source) {
public Document mapObject(Object source) {
return null;
}
@Override
public <T> T readObject(Map<String, Object> source, Class<T> targetType) {
public <T> T readObject(Document source, Class<T> targetType) {
return null;
}
}

View File

@ -30,6 +30,7 @@ import java.lang.Object;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@ -38,6 +39,7 @@ import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.get.MultiGetItemResponse;
import org.elasticsearch.action.get.MultiGetResponse;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.common.bytes.BytesArray;
import org.elasticsearch.common.document.DocumentField;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
@ -172,7 +174,14 @@ public class DefaultResultMapperTests {
// given
GetResponse response = mock(GetResponse.class);
when(response.getSourceAsString()).thenReturn(createJsonCar("Ford", "Grat"));
when(response.isExists()).thenReturn(true);
Map<String, Object> sourceAsMap = new HashMap<>();
sourceAsMap.put("name", "Ford");
sourceAsMap.put("model", "Grat");
when(response.getSourceAsMap()).thenReturn(sourceAsMap);
when(response.getSourceAsBytesRef()).thenReturn(new BytesArray(" "));
// when
Car result = resultMapper.mapResult(response, Car.class);
@ -188,7 +197,9 @@ public class DefaultResultMapperTests {
public void setsIdentifierOnImmutableType() {
GetResponse response = mock(GetResponse.class);
when(response.isExists()).thenReturn(true);
when(response.getSourceAsString()).thenReturn("{}");
when(response.getSourceAsBytesRef()).thenReturn(new BytesArray("{}"));
when(response.getId()).thenReturn("identifier");
ImmutableEntity result = resultMapper.mapResult(response, ImmutableEntity.class);
@ -201,6 +212,7 @@ public class DefaultResultMapperTests {
public void setsVersionFromGetResponse() {
GetResponse response = mock(GetResponse.class);
when(response.isExists()).thenReturn(true);
when(response.getSourceAsString()).thenReturn("{}");
when(response.getVersion()).thenReturn(1234L);
@ -214,12 +226,16 @@ public class DefaultResultMapperTests {
public void setsVersionFromMultiGetResponse() {
GetResponse response1 = mock(GetResponse.class);
when(response1.isExists()).thenReturn(true);
when(response1.getSourceAsString()).thenReturn("{}");
when(response1.getSourceAsBytesRef()).thenReturn(new BytesArray("{}"));
when(response1.isExists()).thenReturn(true);
when(response1.getVersion()).thenReturn(1234L);
GetResponse response2 = mock(GetResponse.class);
when(response2.isExists()).thenReturn(true);
when(response2.getSourceAsString()).thenReturn("{}");
when(response2.getSourceAsBytesRef()).thenReturn(new BytesArray("{}"));
when(response2.isExists()).thenReturn(true);
when(response2.getVersion()).thenReturn(5678L);
@ -239,11 +255,11 @@ public class DefaultResultMapperTests {
public void setsVersionFromSearchResponse() {
SearchHit hit1 = mock(SearchHit.class);
when(hit1.getSourceAsString()).thenReturn("{}");
when(hit1.getSourceRef()).thenReturn(new BytesArray("{}"));
when(hit1.getVersion()).thenReturn(1234L);
SearchHit hit2 = mock(SearchHit.class);
when(hit2.getSourceAsString()).thenReturn("{}");
when(hit2.getSourceRef()).thenReturn(new BytesArray("{}"));
when(hit2.getVersion()).thenReturn(5678L);
SearchHits searchHits = mock(SearchHits.class);
@ -272,7 +288,13 @@ public class DefaultResultMapperTests {
private SearchHit createCarHit(String name, String model) {
SearchHit hit = mock(SearchHit.class);
when(hit.getSourceAsString()).thenReturn(createJsonCar(name, model));
String json = createJsonCar(name, model);
when(hit.getSourceAsString()).thenReturn(json);
when(hit.getSourceRef()).thenReturn(new BytesArray(json));
Map<String, Object> map = new LinkedHashMap<>();
map.put("name", name);
map.put("model", model);
when(hit.getSourceAsMap()).thenReturn(map);
return hit;
}
@ -281,6 +303,7 @@ public class DefaultResultMapperTests {
SearchHit hit = mock(SearchHit.class);
when(hit.getSourceAsString()).thenReturn(null);
when(hit.getFields()).thenReturn(createCarFields(name, model));
when(hit.iterator()).thenReturn(createCarFields(name, model).values().iterator());
return hit;
}

View File

@ -47,7 +47,7 @@ import org.springframework.data.annotation.Transient;
import org.springframework.data.annotation.TypeAlias;
import org.springframework.data.convert.ReadingConverter;
import org.springframework.data.convert.WritingConverter;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.Document;
import org.springframework.data.elasticsearch.annotations.GeoPointField;
import org.springframework.data.elasticsearch.core.convert.ElasticsearchCustomConversions;
import org.springframework.data.elasticsearch.core.geo.GeoPoint;
@ -58,7 +58,10 @@ import org.springframework.data.geo.Point;
import org.springframework.data.geo.Polygon;
/**
* Unit tests for {@link ElasticsearchEntityMapper}.
*
* @author Christoph Strobl
* @author Mark Paluch
*/
public class ElasticsearchEntityMapperUnitTests {
@ -79,16 +82,16 @@ public class ElasticsearchEntityMapperUnitTests {
Address observatoryRoad;
Place bigBunsCafe;
Map<String, Object> sarahAsMap;
Map<String, Object> t800AsMap;
Map<String, Object> kyleAsMap;
Map<String, Object> gratiotAveAsMap;
Map<String, Object> locationAsMap;
Map<String, Object> gunAsMap;
Map<String, Object> grenadeAsMap;
Map<String, Object> rifleAsMap;
Map<String, Object> shotGunAsMap;
Map<String, Object> bigBunsCafeAsMap;
Document sarahAsMap;
Document t800AsMap;
Document kyleAsMap;
Document gratiotAveAsMap;
Document locationAsMap;
Document gunAsMap;
Document grenadeAsMap;
Document rifleAsMap;
Document shotGunAsMap;
Document bigBunsCafeAsMap;
@Before
public void init() {
@ -117,7 +120,7 @@ public class ElasticsearchEntityMapperUnitTests {
t800.name = "T-800";
t800.gender = Gender.MACHINE;
t800AsMap = new LinkedHashMap<>();
t800AsMap = Document.create();
t800AsMap.put("id", "t800");
t800AsMap.put("name", "T-800");
t800AsMap.put("gender", "MACHINE");
@ -134,27 +137,27 @@ public class ElasticsearchEntityMapperUnitTests {
bigBunsCafe.street = "15 South Fremont Avenue";
bigBunsCafe.location = new Point(34.0945637D, -118.1545845D);
sarahAsMap = new LinkedHashMap<>();
sarahAsMap = Document.create();
sarahAsMap.put("id", "sarah");
sarahAsMap.put("name", "Sarah Connor");
sarahAsMap.put("gender", "MAN");
sarahAsMap.put("_class", "org.springframework.data.elasticsearch.core.ElasticsearchEntityMapperUnitTests$Person");
kyleAsMap = new LinkedHashMap<>();
kyleAsMap = Document.create();
kyleAsMap.put("id", "kyle");
kyleAsMap.put("gender", "MAN");
kyleAsMap.put("name", "Kyle Reese");
locationAsMap = new LinkedHashMap<>();
locationAsMap = Document.create();
locationAsMap.put("lat", 34.118347D);
locationAsMap.put("lon", -118.3026284D);
gratiotAveAsMap = new LinkedHashMap<>();
gratiotAveAsMap = Document.create();
gratiotAveAsMap.put("city", "Los Angeles");
gratiotAveAsMap.put("street", "2800 East Observatory Road");
gratiotAveAsMap.put("location", locationAsMap);
bigBunsCafeAsMap = new LinkedHashMap<>();
bigBunsCafeAsMap = Document.create();
bigBunsCafeAsMap.put("name", "Big Buns Cafe");
bigBunsCafeAsMap.put("city", "Los Angeles");
bigBunsCafeAsMap.put("street", "15 South Fremont Avenue");
@ -164,22 +167,22 @@ public class ElasticsearchEntityMapperUnitTests {
bigBunsCafeAsMap.put("_class",
"org.springframework.data.elasticsearch.core.ElasticsearchEntityMapperUnitTests$Place");
gunAsMap = new LinkedHashMap<>();
gunAsMap = Document.create();
gunAsMap.put("label", "Glock 19");
gunAsMap.put("shotsPerMagazine", 33);
gunAsMap.put("_class", Gun.class.getName());
grenadeAsMap = new LinkedHashMap<>();
grenadeAsMap = Document.create();
grenadeAsMap.put("label", "40 mm");
grenadeAsMap.put("_class", Grenade.class.getName());
rifleAsMap = new LinkedHashMap<>();
rifleAsMap = Document.create();
rifleAsMap.put("label", "AR-18 Assault Rifle");
rifleAsMap.put("weight", 3.17D);
rifleAsMap.put("maxShotsPerMagazine", 40);
rifleAsMap.put("_class", "rifle");
shotGunAsMap = new LinkedHashMap<>();
shotGunAsMap = Document.create();
shotGunAsMap.put("model", "Ithaca 37 Pump Shotgun");
shotGunAsMap.put("_class", ShotGun.class.getName());
}
@ -255,7 +258,7 @@ public class ElasticsearchEntityMapperUnitTests {
person.gender = Gender.MAN;
person.address = observatoryRoad;
LinkedHashMap<String, Object> sink = writeToMap(person);
Map<String, Object> sink = writeToMap(person);
assertThat(sink.get("address")).isEqualTo(gratiotAveAsMap);
}
@ -269,7 +272,7 @@ public class ElasticsearchEntityMapperUnitTests {
sarahConnor.coWorkers = Arrays.asList(kyleReese, ginger);
LinkedHashMap<String, Object> target = writeToMap(sarahConnor);
Map<String, Object> target = writeToMap(sarahConnor);
assertThat((List) target.get("coWorkers")).hasSize(2).contains(kyleAsMap);
}
@ -281,7 +284,7 @@ public class ElasticsearchEntityMapperUnitTests {
sarahConnor.inventoryList = Arrays.asList(gun, grenade);
LinkedHashMap<String, Object> target = writeToMap(sarahConnor);
Map<String, Object> target = writeToMap(sarahConnor);
assertThat((List) target.get("inventoryList")).containsExactly(gunAsMap, grenadeAsMap);
}
@ -319,7 +322,7 @@ public class ElasticsearchEntityMapperUnitTests {
sarahConnor.shippingAddresses = new LinkedHashMap<>();
sarahConnor.shippingAddresses.put("home", observatoryRoad);
LinkedHashMap<String, Object> target = writeToMap(sarahConnor);
Map<String, Object> target = writeToMap(sarahConnor);
assertThat(target.get("shippingAddresses")).isInstanceOf(Map.class);
assertThat(target.get("shippingAddresses")).isEqualTo(Collections.singletonMap("home", gratiotAveAsMap));
}
@ -331,7 +334,7 @@ public class ElasticsearchEntityMapperUnitTests {
sarahConnor.inventoryMap.put("glock19", gun);
sarahConnor.inventoryMap.put("40 mm grenade", grenade);
LinkedHashMap<String, Object> target = writeToMap(sarahConnor);
Map<String, Object> target = writeToMap(sarahConnor);
assertThat(target.get("inventoryMap")).isInstanceOf(Map.class);
assertThat((Map) target.get("inventoryMap")).containsEntry("glock19", gunAsMap).containsEntry("40 mm grenade",
grenadeAsMap);
@ -365,7 +368,7 @@ public class ElasticsearchEntityMapperUnitTests {
skynet.objectList.add(t800);
skynet.objectList.add(gun);
LinkedHashMap<String, Object> target = writeToMap(skynet);
Map<String, Object> target = writeToMap(skynet);
assertThat((List<Object>) target.get("objectList")).containsExactly(t800AsMap, gunAsMap);
}
@ -373,7 +376,7 @@ public class ElasticsearchEntityMapperUnitTests {
@Test // DATAES-530
public void readGenericList() {
LinkedHashMap<String, Object> source = new LinkedHashMap<>();
Document source = Document.create();
source.put("objectList", Arrays.asList(t800AsMap, gunAsMap));
Skynet target = entityMapper.read(Skynet.class, source);
@ -388,7 +391,7 @@ public class ElasticsearchEntityMapperUnitTests {
skynet.objectList = new ArrayList<>();
skynet.objectList.add(Arrays.asList(t800, gun));
LinkedHashMap<String, Object> target = writeToMap(skynet);
Map<String, Object> target = writeToMap(skynet);
assertThat((List<Object>) target.get("objectList")).containsExactly(Arrays.asList(t800AsMap, gunAsMap));
}
@ -396,7 +399,7 @@ public class ElasticsearchEntityMapperUnitTests {
@Test // DATAES-530
public void readGenericListList() {
LinkedHashMap<String, Object> source = new LinkedHashMap<>();
Document source = Document.create();
source.put("objectList", Arrays.asList(Arrays.asList(t800AsMap, gunAsMap)));
Skynet target = entityMapper.read(Skynet.class, source);
@ -412,7 +415,7 @@ public class ElasticsearchEntityMapperUnitTests {
skynet.objectMap.put("gun", gun);
skynet.objectMap.put("grenade", grenade);
LinkedHashMap<String, Object> target = writeToMap(skynet);
Map<String, Object> target = writeToMap(skynet);
assertThat((Map<String, Object>) target.get("objectMap")).containsEntry("gun", gunAsMap).containsEntry("grenade",
grenadeAsMap);
@ -421,7 +424,7 @@ public class ElasticsearchEntityMapperUnitTests {
@Test // DATAES-530
public void readGenericMap() {
LinkedHashMap<String, Object> source = new LinkedHashMap<>();
Document source = Document.create();
source.put("objectMap", Collections.singletonMap("glock19", gunAsMap));
Skynet target = entityMapper.read(Skynet.class, source);
@ -436,7 +439,7 @@ public class ElasticsearchEntityMapperUnitTests {
skynet.objectMap = new LinkedHashMap<>();
skynet.objectMap.put("inventory", Collections.singletonMap("glock19", gun));
LinkedHashMap<String, Object> target = writeToMap(skynet);
Map<String, Object> target = writeToMap(skynet);
assertThat((Map<String, Object>) target.get("objectMap")).containsEntry("inventory",
Collections.singletonMap("glock19", gunAsMap));
@ -445,7 +448,7 @@ public class ElasticsearchEntityMapperUnitTests {
@Test // DATAES-530
public void readGenericMapMap() {
LinkedHashMap<String, Object> source = new LinkedHashMap<>();
Document source = Document.create();
source.put("objectMap", Collections.singletonMap("inventory", Collections.singletonMap("glock19", gunAsMap)));
Skynet target = entityMapper.read(Skynet.class, source);
@ -466,7 +469,7 @@ public class ElasticsearchEntityMapperUnitTests {
@Test // DATAES-530
public void readsNestedObjectEntity() {
LinkedHashMap<String, Object> source = new LinkedHashMap<>();
Document source = Document.create();
source.put("object", t800AsMap);
Skynet target = entityMapper.read(Skynet.class, source);
@ -483,7 +486,7 @@ public class ElasticsearchEntityMapperUnitTests {
public void writesNestedAliased() {
t800.inventoryList = Collections.singletonList(rifle);
LinkedHashMap<String, Object> target = writeToMap(t800);
Map<String, Object> target = writeToMap(t800);
assertThat((List) target.get("inventoryList")).contains(rifleAsMap);
}
@ -516,7 +519,7 @@ public class ElasticsearchEntityMapperUnitTests {
sarahConnor.address = bigBunsCafe;
LinkedHashMap<String, Object> target = writeToMap(sarahConnor);
Map<String, Object> target = writeToMap(sarahConnor);
assertThat(target.get("address")).isEqualTo(bigBunsCafeAsMap);
}
@ -535,9 +538,9 @@ public class ElasticsearchEntityMapperUnitTests {
return String.format(Locale.ENGLISH, "\"%s\":{\"lat\":%.1f,\"lon\":%.1f}", name, point.getX(), point.getY());
}
private LinkedHashMap<String, Object> writeToMap(Object source) {
private Map<String, Object> writeToMap(Object source) {
LinkedHashMap<String, Object> sink = new LinkedHashMap<>();
Document sink = Document.create();
entityMapper.write(source, sink);
return sink;
}
@ -696,7 +699,8 @@ public class ElasticsearchEntityMapperUnitTests {
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Document(indexName = "test-index-geo-core-entity-mapper", type = "geo-test-index", shards = 1, replicas = 0,
@org.springframework.data.elasticsearch.annotations.Document(indexName = "test-index-geo-core-entity-mapper",
type = "geo-test-index", shards = 1, replicas = 0,
refreshInterval = "-1")
static class GeoEntity {