Browse Source

DATAMONGO-1919 - Allow reactive-only usage of ReactiveMongoTemplate.

We now support reactive-only usage of Spring Data MongoDB without the need to use the synchronous driver or even having it on the class path. We conditionally register CodeWScope/CodeWithScope types that are bundled with the particular driver distributions.

NoOpDbRefResolver is now a top-level type to be used with a reactive-only MongoMappingContext.

Original Pull Request: #572
pull/571/head
Mark Paluch 8 years ago committed by Christoph Strobl
parent
commit
2d36fc3050
  1. 3
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/AbstractReactiveMongoConfiguration.java
  2. 65
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMongoTemplate.java
  3. 13
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DbRefResolver.java
  4. 15
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DefaultDbRefResolver.java
  5. 69
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/NoOpDbRefResolver.java
  6. 18
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/MongoSimpleTypes.java
  7. 4
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveMongoTemplateUnitTests.java
  8. 5
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveSessionBoundMongoTemplateUnitTests.java

3
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/AbstractReactiveMongoConfiguration.java

@ -22,6 +22,7 @@ import org.springframework.data.mongodb.core.ReactiveMongoOperations; @@ -22,6 +22,7 @@ import org.springframework.data.mongodb.core.ReactiveMongoOperations;
import org.springframework.data.mongodb.core.ReactiveMongoTemplate;
import org.springframework.data.mongodb.core.SimpleReactiveMongoDatabaseFactory;
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
import org.springframework.data.mongodb.core.convert.NoOpDbRefResolver;
import com.mongodb.reactivestreams.client.MongoClient;
@ -80,7 +81,7 @@ public abstract class AbstractReactiveMongoConfiguration extends MongoConfigurat @@ -80,7 +81,7 @@ public abstract class AbstractReactiveMongoConfiguration extends MongoConfigurat
@Bean
public MappingMongoConverter mappingMongoConverter() throws Exception {
MappingMongoConverter converter = new MappingMongoConverter(ReactiveMongoTemplate.NO_OP_REF_RESOLVER,
MappingMongoConverter converter = new MappingMongoConverter(NoOpDbRefResolver.INSTANCE,
mongoMappingContext());
converter.setCustomConversions(customConversions());

65
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMongoTemplate.java

@ -32,8 +32,6 @@ import java.util.function.Consumer; @@ -32,8 +32,6 @@ import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;
import javax.annotation.Nonnull;
import org.bson.BsonTimestamp;
import org.bson.BsonValue;
import org.bson.Document;
@ -77,7 +75,16 @@ import org.springframework.data.mongodb.core.aggregation.AggregationOptions; @@ -77,7 +75,16 @@ import org.springframework.data.mongodb.core.aggregation.AggregationOptions;
import org.springframework.data.mongodb.core.aggregation.PrefixingDelegatingAggregationOperationContext;
import org.springframework.data.mongodb.core.aggregation.TypeBasedAggregationOperationContext;
import org.springframework.data.mongodb.core.aggregation.TypedAggregation;
import org.springframework.data.mongodb.core.convert.*;
import org.springframework.data.mongodb.core.convert.DbRefResolver;
import org.springframework.data.mongodb.core.convert.JsonSchemaMapper;
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
import org.springframework.data.mongodb.core.convert.MongoConverter;
import org.springframework.data.mongodb.core.convert.MongoCustomConversions;
import org.springframework.data.mongodb.core.convert.MongoJsonSchemaMapper;
import org.springframework.data.mongodb.core.convert.MongoWriter;
import org.springframework.data.mongodb.core.convert.NoOpDbRefResolver;
import org.springframework.data.mongodb.core.convert.QueryMapper;
import org.springframework.data.mongodb.core.convert.UpdateMapper;
import org.springframework.data.mongodb.core.index.MongoMappingEventPublisher;
import org.springframework.data.mongodb.core.index.ReactiveIndexOperations;
import org.springframework.data.mongodb.core.index.ReactiveMongoPersistentEntityIndexCreator;
@ -96,7 +103,6 @@ import org.springframework.data.mongodb.core.mapping.event.MongoMappingEvent; @@ -96,7 +103,6 @@ import org.springframework.data.mongodb.core.mapping.event.MongoMappingEvent;
import org.springframework.data.mongodb.core.mapreduce.MapReduceOptions;
import org.springframework.data.mongodb.core.query.Collation;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.CriteriaDefinition;
import org.springframework.data.mongodb.core.query.Meta;
import org.springframework.data.mongodb.core.query.NearQuery;
import org.springframework.data.mongodb.core.query.Query;
@ -119,7 +125,6 @@ import com.mongodb.ClientSessionOptions; @@ -119,7 +125,6 @@ import com.mongodb.ClientSessionOptions;
import com.mongodb.CursorType;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBRef;
import com.mongodb.Mongo;
import com.mongodb.MongoException;
import com.mongodb.ReadPreference;
@ -156,7 +161,7 @@ import com.mongodb.util.JSONParseException; @@ -156,7 +161,7 @@ import com.mongodb.util.JSONParseException;
*/
public class ReactiveMongoTemplate implements ReactiveMongoOperations, ApplicationContextAware {
public static final DbRefResolver NO_OP_REF_RESOLVER = new NoOpDbRefResolver();
public static final DbRefResolver NO_OP_REF_RESOLVER = NoOpDbRefResolver.INSTANCE;
private static final Logger LOGGER = LoggerFactory.getLogger(ReactiveMongoTemplate.class);
private static final String ID_FIELD = "_id";
@ -3287,54 +3292,6 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati @@ -3287,54 +3292,6 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
return new ArrayList<>(documents);
}
/**
* No-Operation {@link org.springframework.data.mongodb.core.mapping.DBRef} resolver.
*
* @author Mark Paluch
*/
static class NoOpDbRefResolver implements DbRefResolver {
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.convert.DbRefResolver#resolveDbRef(org.springframework.data.mongodb.core.mapping.MongoPersistentProperty, org.springframework.data.mongodb.core.convert.DbRefResolverCallback)
*/
@Override
@Nullable
public Object resolveDbRef(@Nonnull MongoPersistentProperty property, @Nonnull DBRef dbref,
@Nonnull DbRefResolverCallback callback, @Nonnull DbRefProxyHandler proxyHandler) {
return null;
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.convert.DbRefResolver#created(org.springframework.data.mongodb.core.mapping.MongoPersistentProperty, org.springframework.data.mongodb.core.mapping.MongoPersistentEntity, java.lang.Object)
*/
@Override
@Nullable
public DBRef createDbRef(org.springframework.data.mongodb.core.mapping.DBRef annotation,
MongoPersistentEntity<?> entity, Object id) {
return null;
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.convert.DbRefResolver#fetch(com.mongodb.DBRef)
*/
@Override
public Document fetch(DBRef dbRef) {
return null;
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.convert.DbRefResolver#bulkFetch(java.util.List)
*/
@Override
public List<Document> bulkFetch(List<DBRef> dbRefs) {
return Collections.emptyList();
}
}
/**
* {@link MongoTemplate} extension bound to a specific {@link ClientSession} that is applied when interacting with the
* server through the driver API.

13
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DbRefResolver.java

@ -22,6 +22,7 @@ import org.springframework.dao.InvalidDataAccessApiUsageException; @@ -22,6 +22,7 @@ import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
import org.springframework.lang.Nullable;
import org.springframework.util.StringUtils;
import com.mongodb.DBRef;
@ -59,9 +60,15 @@ public interface DbRefResolver { @@ -59,9 +60,15 @@ public interface DbRefResolver {
* @param id will never be {@literal null}.
* @return
*/
DBRef createDbRef(@Nullable org.springframework.data.mongodb.core.mapping.DBRef annotation,
MongoPersistentEntity<?> entity,
Object id);
default DBRef createDbRef(@Nullable org.springframework.data.mongodb.core.mapping.DBRef annotation,
MongoPersistentEntity<?> entity, Object id) {
if (annotation != null && StringUtils.hasText(annotation.db())) {
return new DBRef(annotation.db(), entity.getCollection(), id);
}
return new DBRef(entity.getCollection(), id);
}
/**
* Actually loads the {@link DBRef} from the datasource.

15
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DefaultDbRefResolver.java

@ -104,21 +104,6 @@ public class DefaultDbRefResolver implements DbRefResolver { @@ -104,21 +104,6 @@ public class DefaultDbRefResolver implements DbRefResolver {
return callback.resolve(property);
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.convert.DbRefResolver#created(org.springframework.data.mongodb.core.mapping.MongoPersistentProperty, org.springframework.data.mongodb.core.mapping.MongoPersistentEntity, java.lang.Object)
*/
@Override
public DBRef createDbRef(@Nullable org.springframework.data.mongodb.core.mapping.DBRef annotation,
MongoPersistentEntity<?> entity, Object id) {
if (annotation != null && StringUtils.hasText(annotation.db())) {
return new DBRef(annotation.db(), entity.getCollection(), id);
}
return new DBRef(entity.getCollection(), id);
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.convert.DbRefResolver#fetch(com.mongodb.DBRef)

69
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/NoOpDbRefResolver.java

@ -0,0 +1,69 @@ @@ -0,0 +1,69 @@
/*
* Copyright 2018 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.mongodb.core.convert;
import java.util.List;
import javax.annotation.Nonnull;
import org.bson.Document;
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
import org.springframework.lang.Nullable;
import org.springframework.util.StringUtils;
import com.mongodb.DBRef;
/**
* No-Operation {@link org.springframework.data.mongodb.core.mapping.DBRef} resolver throwing
* {@link UnsupportedOperationException} when attempting to resolve database references.
*
* @author Mark Paluch
* @since 2.1
*/
public enum NoOpDbRefResolver implements DbRefResolver {
INSTANCE;
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.convert.DbRefResolver#resolveDbRef(org.springframework.data.mongodb.core.mapping.MongoPersistentProperty, org.springframework.data.mongodb.core.convert.DbRefResolverCallback)
*/
@Override
@Nullable
public Object resolveDbRef(@Nonnull MongoPersistentProperty property, @Nonnull DBRef dbref,
@Nonnull DbRefResolverCallback callback, @Nonnull DbRefProxyHandler proxyHandler) {
throw new UnsupportedOperationException("DBRef resolution not supported!");
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.convert.DbRefResolver#fetch(com.mongodb.DBRef)
*/
@Override
public Document fetch(DBRef dbRef) {
throw new UnsupportedOperationException("DBRef resolution not supported!");
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.convert.DbRefResolver#bulkFetch(java.util.List)
*/
@Override
public List<Document> bulkFetch(List<DBRef> dbRefs) {
throw new UnsupportedOperationException("DBRef resolution not supported!");
}
}

18
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/MongoSimpleTypes.java

@ -24,7 +24,6 @@ import java.util.regex.Pattern; @@ -24,7 +24,6 @@ import java.util.regex.Pattern;
import org.bson.BsonObjectId;
import org.bson.types.Binary;
import org.bson.types.CodeWScope;
import org.bson.types.ObjectId;
import org.springframework.data.mapping.model.SimpleTypeHolder;
import org.springframework.data.mongodb.util.MongoClientVersion;
@ -37,6 +36,7 @@ import com.mongodb.DBRef; @@ -37,6 +36,7 @@ import com.mongodb.DBRef;
*
* @author Oliver Gierke
* @author Christoph Strobl
* @author Mark Paluch
*/
public abstract class MongoSimpleTypes {
@ -53,15 +53,21 @@ public abstract class MongoSimpleTypes { @@ -53,15 +53,21 @@ public abstract class MongoSimpleTypes {
simpleTypes.add(DBRef.class);
simpleTypes.add(ObjectId.class);
simpleTypes.add(BsonObjectId.class);
simpleTypes.add(CodeWScope.class);
simpleTypes.add(org.bson.Document.class);
simpleTypes.add(Pattern.class);
simpleTypes.add(Binary.class);
simpleTypes.add(UUID.class);
if (ClassUtils.isPresent("org.bson.types.CodeWScope", MongoSimpleTypes.class.getClassLoader())) {
simpleTypes.add(resolveClassName("org.bson.types.CodeWScope"));
}
if (ClassUtils.isPresent("org.bson.types.CodeWithScope", MongoSimpleTypes.class.getClassLoader())) {
simpleTypes.add(resolveClassName("org.bson.types.CodeWithScope"));
}
if (MongoClientVersion.isMongo34Driver()) {
simpleTypes
.add(ClassUtils.resolveClassName("org.bson.types.Decimal128", MongoSimpleTypes.class.getClassLoader()));
simpleTypes.add(resolveClassName("org.bson.types.Decimal128"));
}
MONGO_SIMPLE_TYPES = Collections.unmodifiableSet(simpleTypes);
@ -71,4 +77,8 @@ public abstract class MongoSimpleTypes { @@ -71,4 +77,8 @@ public abstract class MongoSimpleTypes {
public static final SimpleTypeHolder HOLDER = new SimpleTypeHolder(MONGO_SIMPLE_TYPES, true);
private MongoSimpleTypes() {}
private static Class<?> resolveClassName(String className) {
return ClassUtils.resolveClassName(className, MongoSimpleTypes.class.getClassLoader());
}
}

4
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveMongoTemplateUnitTests.java

@ -41,8 +41,8 @@ import org.reactivestreams.Publisher; @@ -41,8 +41,8 @@ import org.reactivestreams.Publisher;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.MongoTemplateUnitTests.AutogenerateableId;
import org.springframework.data.mongodb.core.ReactiveMongoTemplate.NoOpDbRefResolver;
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
import org.springframework.data.mongodb.core.convert.NoOpDbRefResolver;
import org.springframework.data.mongodb.core.mapping.Field;
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
import org.springframework.data.mongodb.core.query.BasicQuery;
@ -107,7 +107,7 @@ public class ReactiveMongoTemplateUnitTests { @@ -107,7 +107,7 @@ public class ReactiveMongoTemplateUnitTests {
when(aggregatePublisher.first()).thenReturn(findPublisher);
this.mappingContext = new MongoMappingContext();
this.converter = new MappingMongoConverter(new NoOpDbRefResolver(), mappingContext);
this.converter = new MappingMongoConverter(NoOpDbRefResolver.INSTANCE, mappingContext);
this.template = new ReactiveMongoTemplate(factory, converter);
}

5
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveSessionBoundMongoTemplateUnitTests.java

@ -39,10 +39,10 @@ import org.reactivestreams.Publisher; @@ -39,10 +39,10 @@ import org.reactivestreams.Publisher;
import org.springframework.data.geo.Metrics;
import org.springframework.data.geo.Point;
import org.springframework.data.mongodb.ReactiveMongoDatabaseFactory;
import org.springframework.data.mongodb.core.ReactiveMongoTemplate.NoOpDbRefResolver;
import org.springframework.data.mongodb.core.ReactiveMongoTemplate.ReactiveSessionBoundMongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
import org.springframework.data.mongodb.core.convert.NoOpDbRefResolver;
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
import org.springframework.data.mongodb.core.query.NearQuery;
import org.springframework.data.mongodb.core.query.Query;
@ -64,6 +64,7 @@ import com.mongodb.reactivestreams.client.MongoDatabase; @@ -64,6 +64,7 @@ import com.mongodb.reactivestreams.client.MongoDatabase;
* Unit tests for {@link ReactiveSessionBoundMongoTemplate}.
*
* @author Christoph Strobl
* @author Mark Paluch
*/
@SuppressWarnings("unchecked")
@RunWith(MockitoJUnitRunner.Silent.class)
@ -124,7 +125,7 @@ public class ReactiveSessionBoundMongoTemplateUnitTests { @@ -124,7 +125,7 @@ public class ReactiveSessionBoundMongoTemplateUnitTests {
factory = new SimpleReactiveMongoDatabaseFactory(client, "foo");
this.mappingContext = new MongoMappingContext();
this.converter = new MappingMongoConverter(new NoOpDbRefResolver(), mappingContext);
this.converter = new MappingMongoConverter(NoOpDbRefResolver.INSTANCE, mappingContext);
this.template = new ReactiveSessionBoundMongoTemplate(clientSession, new ReactiveMongoTemplate(factory, converter));
}

Loading…
Cancel
Save