Browse Source

Polishing.

Remove unused expression parser and make sure to obtain the EvaluationContext from the index resolver if configured.

Original Pull Request: #5049
issue/aot-doc
Christoph Strobl 2 months ago
parent
commit
38dcb1a5a7
No known key found for this signature in database
GPG Key ID: E6054036D0C37A4B
  1. 21
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexResolver.java
  2. 70
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexResolverUnitTests.java

21
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexResolver.java

@ -61,7 +61,6 @@ import org.springframework.data.mongodb.util.DurationUtil;
import org.springframework.data.mongodb.util.spel.ExpressionUtils; import org.springframework.data.mongodb.util.spel.ExpressionUtils;
import org.springframework.data.spel.EvaluationContextProvider; import org.springframework.data.spel.EvaluationContextProvider;
import org.springframework.expression.EvaluationContext; import org.springframework.expression.EvaluationContext;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.ClassUtils; import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils; import org.springframework.util.ObjectUtils;
@ -85,7 +84,6 @@ import org.springframework.util.StringUtils;
public class MongoPersistentEntityIndexResolver implements IndexResolver { public class MongoPersistentEntityIndexResolver implements IndexResolver {
private static final Log LOGGER = LogFactory.getLog(MongoPersistentEntityIndexResolver.class); private static final Log LOGGER = LogFactory.getLog(MongoPersistentEntityIndexResolver.class);
private static final SpelExpressionParser PARSER = new SpelExpressionParser();
private final MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext; private final MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext;
private EvaluationContextProvider evaluationContextProvider = EvaluationContextProvider.DEFAULT; private EvaluationContextProvider evaluationContextProvider = EvaluationContextProvider.DEFAULT;
@ -495,7 +493,7 @@ public class MongoPersistentEntityIndexResolver implements IndexResolver {
return new org.bson.Document(dotPath, 1); return new org.bson.Document(dotPath, 1);
} }
Object keyDefToUse = ExpressionUtils.evaluate(keyDefinitionString, () -> getValueEvaluationContextForProperty(entity)); Object keyDefToUse = ExpressionUtils.evaluate(keyDefinitionString, () -> getValueEvaluationContext(entity));
org.bson.Document dbo = (keyDefToUse instanceof org.bson.Document document) ? document org.bson.Document dbo = (keyDefToUse instanceof org.bson.Document document) ? document
: org.bson.Document.parse(ObjectUtils.nullSafeToString(keyDefToUse)); : org.bson.Document.parse(ObjectUtils.nullSafeToString(keyDefToUse));
@ -563,7 +561,7 @@ public class MongoPersistentEntityIndexResolver implements IndexResolver {
} }
Duration timeout = computeIndexTimeout(index.expireAfter(), Duration timeout = computeIndexTimeout(index.expireAfter(),
getValueEvaluationContextForProperty(persistentProperty.getOwner())); getValueEvaluationContext(persistentProperty.getOwner()));
if (!timeout.isNegative()) { if (!timeout.isNegative()) {
indexDefinition.expire(timeout); indexDefinition.expire(timeout);
} }
@ -579,7 +577,7 @@ public class MongoPersistentEntityIndexResolver implements IndexResolver {
private PartialIndexFilter evaluatePartialFilter(String filterExpression, @Nullable PersistentEntity<?, ?> entity) { private PartialIndexFilter evaluatePartialFilter(String filterExpression, @Nullable PersistentEntity<?, ?> entity) {
Object result = ExpressionUtils.evaluate(filterExpression, () -> getValueEvaluationContextForProperty(entity)); Object result = ExpressionUtils.evaluate(filterExpression, () -> getValueEvaluationContext(entity));
if (result instanceof org.bson.Document document) { if (result instanceof org.bson.Document document) {
return PartialIndexFilter.of(document); return PartialIndexFilter.of(document);
@ -590,7 +588,7 @@ public class MongoPersistentEntityIndexResolver implements IndexResolver {
private org.bson.Document evaluateWildcardProjection(String projectionExpression, @Nullable PersistentEntity<?, ?> entity) { private org.bson.Document evaluateWildcardProjection(String projectionExpression, @Nullable PersistentEntity<?, ?> entity) {
Object result = ExpressionUtils.evaluate(projectionExpression, () -> getValueEvaluationContextForProperty(entity)); Object result = ExpressionUtils.evaluate(projectionExpression, () -> getValueEvaluationContext(entity));
if (result instanceof org.bson.Document document) { if (result instanceof org.bson.Document document) {
return document; return document;
@ -601,7 +599,7 @@ public class MongoPersistentEntityIndexResolver implements IndexResolver {
private Collation evaluateCollation(String collationExpression, @Nullable PersistentEntity<?, ?> entity) { private Collation evaluateCollation(String collationExpression, @Nullable PersistentEntity<?, ?> entity) {
Object result = ExpressionUtils.evaluate(collationExpression, () -> getValueEvaluationContextForProperty(entity)); Object result = ExpressionUtils.evaluate(collationExpression, () -> getValueEvaluationContext(entity));
if (result instanceof org.bson.Document document) { if (result instanceof org.bson.Document document) {
return Collation.from(document); return Collation.from(document);
} }
@ -657,14 +655,13 @@ public class MongoPersistentEntityIndexResolver implements IndexResolver {
* @param persistentEntity can be {@literal null} * @param persistentEntity can be {@literal null}
* @return * @return
*/ */
private ValueEvaluationContext getValueEvaluationContextForProperty(@Nullable PersistentEntity<?, ?> persistentEntity) { ValueEvaluationContext getValueEvaluationContext(@Nullable PersistentEntity<?, ?> persistentEntity) {
if (persistentEntity instanceof BasicMongoPersistentEntity<?> mongoEntity) { if (persistentEntity instanceof BasicMongoPersistentEntity<?> mongoEntity && ObjectUtils.nullSafeEquals(evaluationContextProvider, EvaluationContextProvider.DEFAULT)) {
return mongoEntity.getValueEvaluationContext(null); return mongoEntity.getValueEvaluationContext(null);
} }
return ValueEvaluationContext.of( return ValueEvaluationContext.of(new StandardEnvironment(), getEvaluationContext());
new StandardEnvironment(), getEvaluationContext());
} }
/** /**
@ -716,7 +713,7 @@ public class MongoPersistentEntityIndexResolver implements IndexResolver {
String nameToUse = ""; String nameToUse = "";
if (StringUtils.hasText(indexName)) { if (StringUtils.hasText(indexName)) {
Object result = ExpressionUtils.evaluate(indexName, () -> getValueEvaluationContextForProperty(entity)); Object result = ExpressionUtils.evaluate(indexName, () -> getValueEvaluationContext(entity));
if (result != null) { if (result != null) {
nameToUse = ObjectUtils.nullSafeToString(result); nameToUse = ObjectUtils.nullSafeToString(result);

70
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexResolverUnitTests.java

@ -26,6 +26,7 @@ import java.util.Arrays;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@ -33,8 +34,6 @@ import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses; import org.junit.runners.Suite.SuiteClasses;
import org.springframework.core.annotation.AliasFor; import org.springframework.core.annotation.AliasFor;
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.StandardEnvironment;
import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.data.annotation.Id; import org.springframework.data.annotation.Id;
import org.springframework.data.core.TypeInformation; import org.springframework.data.core.TypeInformation;
@ -56,6 +55,9 @@ import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity; import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty; import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
import org.springframework.data.mongodb.core.mapping.Unwrapped; import org.springframework.data.mongodb.core.mapping.Unwrapped;
import org.springframework.data.spel.EvaluationContextProvider;
import org.springframework.expression.EvaluationContext;
import org.springframework.mock.env.MockEnvironment;
/** /**
* Tests for {@link MongoPersistentEntityIndexResolver}. * Tests for {@link MongoPersistentEntityIndexResolver}.
@ -108,23 +110,6 @@ public class MongoPersistentEntityIndexResolverUnitTests {
assertThat(definitions).isNotEmpty(); assertThat(definitions).isNotEmpty();
} }
@Test // GH-4980
public void shouldSupportPropertyPlaceholderInExpireAfter() {
StandardEnvironment environment = new StandardEnvironment();
environment.getPropertySources().addFirst(new MapPropertySource("test", Map.of("ttl.timeout", "10m")));
MongoMappingContext mappingContext = new MongoMappingContext();
mappingContext.setEnvironment(environment);
MongoPersistentEntityIndexResolver resolver = new MongoPersistentEntityIndexResolver(mappingContext);
List<IndexDefinitionHolder> indexDefinitions = (List<IndexDefinitionHolder>) resolver
.resolveIndexFor(WithExpireAfterAsPropertyPlaceholder.class);
assertThat(indexDefinitions).hasSize(1);
assertThat(indexDefinitions.get(0).getIndexOptions()).containsEntry("expireAfterSeconds", 600L);
}
@Test // DATAMONGO-899 @Test // DATAMONGO-899
public void deeplyNestedIndexPathIsResolvedCorrectly() { public void deeplyNestedIndexPathIsResolvedCorrectly() {
@ -316,6 +301,53 @@ public class MongoPersistentEntityIndexResolverUnitTests {
org.bson.Document.parse("{'value': {'$exists': true}}")); org.bson.Document.parse("{'value': {'$exists': true}}"));
} }
@Test // GH-4980
public void resolvesPropertyPlaceholderInExpireAfter() {
MockEnvironment environment = new MockEnvironment();
environment.setProperty("ttl.timeout", "10m");
MongoMappingContext mappingContext = new MongoMappingContext();
mappingContext.setInitialEntitySet(Set.of(WithExpireAfterAsPropertyPlaceholder.class));
mappingContext.setEnvironment(environment);
mappingContext.initialize();
MongoPersistentEntityIndexResolver resolver = new MongoPersistentEntityIndexResolver(mappingContext);
List<IndexDefinitionHolder> indexDefinitions = (List<IndexDefinitionHolder>) resolver
.resolveIndexFor(WithExpireAfterAsPropertyPlaceholder.class);
assertThat(indexDefinitions).hasSize(1);
assertThat(indexDefinitions.get(0).getIndexOptions()).containsEntry("expireAfterSeconds", 600L);
}
@Test // GH-4980
public void usesValueExpressionResolversCorrectly() {
MockEnvironment environment = new MockEnvironment();
environment.setProperty("ttl.timeout", "10m");
MongoMappingContext mappingContext = new MongoMappingContext();
mappingContext.setInitialEntitySet(Set.of(WithExpireAfterAsPropertyPlaceholder.class));
mappingContext.setEnvironment(environment);
mappingContext.initialize();
MongoPersistentEntityIndexResolver resolver = new MongoPersistentEntityIndexResolver(mappingContext);
BasicMongoPersistentEntity<?> basicMongoPersistentEntity = mock(BasicMongoPersistentEntity.class);
resolver.getValueEvaluationContext(basicMongoPersistentEntity);
verify(basicMongoPersistentEntity).getValueEvaluationContext(any());
EvaluationContext evaluationContext = mock(EvaluationContext.class);
EvaluationContextProvider contextProviderMock = mock(EvaluationContextProvider.class);
when(contextProviderMock.getEvaluationContext(any())).thenReturn(evaluationContext);
resolver.setEvaluationContextProvider(contextProviderMock);
assertThat(resolver.getValueEvaluationContext(basicMongoPersistentEntity).getEvaluationContext())
.isEqualTo(evaluationContext);
}
@Document("Zero") @Document("Zero")
class IndexOnLevelZero { class IndexOnLevelZero {
@Indexed String indexedProperty; @Indexed String indexedProperty;

Loading…
Cancel
Save