Skip to content

Commit 2fab1e1

Browse files
committed
DATAMONGO-1682 - Polishing.
Require non-null arguments in DefaultReactiveIndexOperations constructor. Remove superfluous publisher creation indirections. Use StepVerifier.verifyComplete() to verify the step sequence. Use provided entity type in template API to construct index operations. Original pull request: #474.
1 parent d5006bb commit 2fab1e1

File tree

6 files changed

+61
-71
lines changed

6 files changed

+61
-71
lines changed

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

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@
2323

2424
import org.bson.Document;
2525
import org.springframework.dao.DataAccessException;
26-
import org.springframework.data.mongodb.core.convert.QueryMapper;
2726
import org.springframework.data.mongodb.MongoDbFactory;
27+
import org.springframework.data.mongodb.core.convert.QueryMapper;
2828
import org.springframework.data.mongodb.core.index.IndexDefinition;
2929
import org.springframework.data.mongodb.core.index.IndexInfo;
3030
import org.springframework.data.mongodb.core.index.IndexOperations;
@@ -38,7 +38,7 @@
3838

3939
/**
4040
* Default implementation of {@link IndexOperations}.
41-
*
41+
*
4242
* @author Mark Pollack
4343
* @author Oliver Gierke
4444
* @author Komi Innocent
@@ -56,7 +56,7 @@ public class DefaultIndexOperations implements IndexOperations {
5656

5757
/**
5858
* Creates a new {@link DefaultIndexOperations}.
59-
*
59+
*
6060
* @param mongoDbFactory must not be {@literal null}.
6161
* @param collectionName must not be {@literal null}.
6262
* @param queryMapper must not be {@literal null}.
@@ -98,24 +98,22 @@ public String ensureIndex(final IndexDefinition indexDefinition) {
9898

9999
Document indexOptions = indexDefinition.getIndexOptions();
100100

101-
if (indexOptions != null) {
102-
103-
IndexOptions ops = IndexConverters.indexDefinitionToIndexOptionsConverter().convert(indexDefinition);
101+
if (indexOptions == null) {
102+
return collection.createIndex(indexDefinition.getIndexKeys());
103+
}
104104

105-
if (indexOptions.containsKey(PARTIAL_FILTER_EXPRESSION_KEY)) {
105+
IndexOptions ops = IndexConverters.indexDefinitionToIndexOptionsConverter().convert(indexDefinition);
106106

107-
Assert.isInstanceOf(Document.class, indexOptions.get(PARTIAL_FILTER_EXPRESSION_KEY));
107+
if (indexOptions.containsKey(PARTIAL_FILTER_EXPRESSION_KEY)) {
108108

109-
ops.partialFilterExpression( mapper.getMappedObject(
110-
(Document) indexOptions.get(PARTIAL_FILTER_EXPRESSION_KEY), lookupPersistentEntity(type, collectionName)));
111-
}
109+
Assert.isInstanceOf(Document.class, indexOptions.get(PARTIAL_FILTER_EXPRESSION_KEY));
112110

113-
return collection.createIndex(indexDefinition.getIndexKeys(), ops);
111+
ops.partialFilterExpression(mapper.getMappedObject((Document) indexOptions.get(PARTIAL_FILTER_EXPRESSION_KEY),
112+
lookupPersistentEntity(type, collectionName)));
114113
}
115-
return collection.createIndex(indexDefinition.getIndexKeys());
116-
}
117114

118-
);
115+
return collection.createIndex(indexDefinition.getIndexKeys(), ops);
116+
});
119117
}
120118

121119
private MongoPersistentEntity<?> lookupPersistentEntity(Class<?> entityType, String collection) {

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

Lines changed: 32 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2016 the original author or authors.
2+
* Copyright 2016-2017 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -25,15 +25,13 @@
2525
import org.springframework.data.mongodb.core.convert.QueryMapper;
2626
import org.springframework.data.mongodb.core.index.IndexDefinition;
2727
import org.springframework.data.mongodb.core.index.IndexInfo;
28-
import org.springframework.data.mongodb.core.index.IndexOperations;
2928
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
3029
import org.springframework.util.Assert;
3130

3231
import com.mongodb.client.model.IndexOptions;
33-
import com.mongodb.reactivestreams.client.ListIndexesPublisher;
3432

3533
/**
36-
* Default implementation of {@link IndexOperations}.
34+
* Default implementation of {@link ReactiveIndexOperations}.
3735
*
3836
* @author Mark Paluch
3937
* @author Christoph Strobl
@@ -53,21 +51,28 @@ public class DefaultReactiveIndexOperations implements ReactiveIndexOperations {
5351
*
5452
* @param mongoOperations must not be {@literal null}.
5553
* @param collectionName must not be {@literal null}.
54+
* @param queryMapper must not be {@literal null}.
5655
*/
5756
public DefaultReactiveIndexOperations(ReactiveMongoOperations mongoOperations, String collectionName,
5857
QueryMapper queryMapper) {
59-
60-
this(mongoOperations, collectionName, queryMapper, null);
58+
this(mongoOperations, collectionName, queryMapper, Optional.empty());
6159
}
6260

6361
/**
6462
* Creates a new {@link DefaultReactiveIndexOperations}.
6563
*
6664
* @param mongoOperations must not be {@literal null}.
6765
* @param collectionName must not be {@literal null}.
66+
* @param queryMapper must not be {@literal null}.
67+
* @param type used for mapping potential partial index filter expression, must not be {@literal null}.
6868
*/
6969
public DefaultReactiveIndexOperations(ReactiveMongoOperations mongoOperations, String collectionName,
7070
QueryMapper queryMapper, Class<?> type) {
71+
this(mongoOperations, collectionName, queryMapper, Optional.of(type));
72+
}
73+
74+
private DefaultReactiveIndexOperations(ReactiveMongoOperations mongoOperations, String collectionName,
75+
QueryMapper queryMapper, Optional<Class<?>> type) {
7176

7277
Assert.notNull(mongoOperations, "ReactiveMongoOperations must not be null!");
7378
Assert.notNull(collectionName, "Collection must not be null!");
@@ -76,7 +81,7 @@ public DefaultReactiveIndexOperations(ReactiveMongoOperations mongoOperations, S
7681
this.mongoOperations = mongoOperations;
7782
this.collectionName = collectionName;
7883
this.queryMapper = queryMapper;
79-
this.type = Optional.ofNullable(type);
84+
this.type = type;
8085
}
8186

8287
/* (non-Javadoc)
@@ -88,51 +93,44 @@ public Mono<String> ensureIndex(final IndexDefinition indexDefinition) {
8893

8994
Document indexOptions = indexDefinition.getIndexOptions();
9095

91-
if (indexOptions != null) {
92-
93-
IndexOptions ops = IndexConverters.indexDefinitionToIndexOptionsConverter().convert(indexDefinition);
96+
if (indexOptions == null) {
97+
return collection.createIndex(indexDefinition.getIndexKeys());
98+
}
9499

95-
if (indexOptions.containsKey(PARTIAL_FILTER_EXPRESSION_KEY)) {
100+
IndexOptions ops = IndexConverters.indexDefinitionToIndexOptionsConverter().convert(indexDefinition);
96101

97-
Assert.isInstanceOf(Document.class, indexOptions.get(PARTIAL_FILTER_EXPRESSION_KEY));
102+
if (indexOptions.containsKey(PARTIAL_FILTER_EXPRESSION_KEY)) {
98103

99-
MongoPersistentEntity<?> entity = type
100-
.map(val -> (MongoPersistentEntity) queryMapper.getMappingContext().getRequiredPersistentEntity(val))
101-
.orElseGet(() -> lookupPersistentEntity(collectionName));
104+
Assert.isInstanceOf(Document.class, indexOptions.get(PARTIAL_FILTER_EXPRESSION_KEY));
102105

103-
ops = ops.partialFilterExpression(
104-
queryMapper.getMappedObject((Document) indexOptions.get(PARTIAL_FILTER_EXPRESSION_KEY), entity));
105-
}
106+
MongoPersistentEntity<?> entity = type
107+
.map(val -> (MongoPersistentEntity) queryMapper.getMappingContext().getRequiredPersistentEntity(val))
108+
.orElseGet(() -> lookupPersistentEntity(collectionName));
106109

107-
return collection.createIndex(indexDefinition.getIndexKeys(), ops);
110+
ops = ops.partialFilterExpression(
111+
queryMapper.getMappedObject(indexOptions.get(PARTIAL_FILTER_EXPRESSION_KEY, Document.class), entity));
108112
}
109113

110-
return collection.createIndex(indexDefinition.getIndexKeys());
114+
return collection.createIndex(indexDefinition.getIndexKeys(), ops);
115+
111116
}).next();
112117
}
113118

114119
private MongoPersistentEntity<?> lookupPersistentEntity(String collection) {
115120

116121
Collection<? extends MongoPersistentEntity<?>> entities = queryMapper.getMappingContext().getPersistentEntities();
117122

118-
for (MongoPersistentEntity<?> entity : entities) {
119-
if (entity.getCollection().equals(collection)) {
120-
return entity;
121-
}
122-
}
123-
124-
return null;
123+
return entities.stream() //
124+
.filter(entity -> entity.getCollection().equals(collection)) //
125+
.findFirst() //
126+
.orElse(null);
125127
}
126128

127129
/* (non-Javadoc)
128130
* @see org.springframework.data.mongodb.core.ReactiveIndexOperations#dropIndex(java.lang.String)
129131
*/
130132
public Mono<Void> dropIndex(final String name) {
131-
132-
return mongoOperations.execute(collectionName, collection -> {
133-
134-
return Mono.from(collection.dropIndex(name));
135-
}).flatMap(success -> Mono.<Void> empty()).next();
133+
return mongoOperations.execute(collectionName, collection -> collection.dropIndex(name)).then();
136134
}
137135

138136
/* (non-Javadoc)
@@ -147,11 +145,7 @@ public Mono<Void> dropAllIndexes() {
147145
*/
148146
public Flux<IndexInfo> getIndexInfo() {
149147

150-
return mongoOperations.execute(collectionName, collection -> {
151-
152-
ListIndexesPublisher<Document> indexesPublisher = collection.listIndexes(Document.class);
153-
154-
return Flux.from(indexesPublisher).map(IndexConverters.documentToIndexInfoConverter()::convert);
155-
});
148+
return mongoOperations.execute(collectionName, collection -> collection.listIndexes(Document.class)) //
149+
.map(IndexConverters.documentToIndexInfoConverter()::convert);
156150
}
157151
}

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -548,7 +548,8 @@ public IndexOperations indexOps(String collectionName) {
548548
}
549549

550550
public IndexOperations indexOps(Class<?> entityClass) {
551-
return new DefaultIndexOperations(getMongoDbFactory(), determineCollectionName(entityClass), queryMapper);
551+
return new DefaultIndexOperations(getMongoDbFactory(), determineCollectionName(entityClass), queryMapper,
552+
entityClass);
552553
}
553554

554555
public BulkOperations bulkOps(BulkMode bulkMode, String collectionName) {

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,5 +56,4 @@ public interface ReactiveIndexOperations {
5656
* @return index information on the collection
5757
*/
5858
Flux<IndexInfo> getIndexInfo();
59-
6059
}

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,8 @@ public ReactiveIndexOperations indexOps(String collectionName) {
309309
* @see org.springframework.data.mongodb.core.ReactiveMongoOperations#reactiveIndexOps(java.lang.Class)
310310
*/
311311
public ReactiveIndexOperations indexOps(Class<?> entityClass) {
312-
return new DefaultReactiveIndexOperations(this, determineCollectionName(entityClass), this.queryMapper);
312+
return new DefaultReactiveIndexOperations(this, determineCollectionName(entityClass), this.queryMapper,
313+
entityClass);
313314
}
314315

315316
public String getCollectionName(Class<?> entityClass) {
@@ -1915,8 +1916,7 @@ String determineCollectionName(Class<?> entityClass) {
19151916
"No class parameter provided, entity collection can't be determined!");
19161917
}
19171918

1918-
MongoPersistentEntity<?> entity = mappingContext.getRequiredPersistentEntity(entityClass);
1919-
return entity.getCollection();
1919+
return mappingContext.getRequiredPersistentEntity(entityClass).getCollection();
19201920
}
19211921

19221922
private static MappingMongoConverter getDefaultMongoConverter() {

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

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,10 @@
1616
package org.springframework.data.mongodb.core;
1717

1818
import static org.assertj.core.api.Assertions.*;
19-
import static org.hamcrest.core.Is.*;
2019
import static org.junit.Assume.*;
2120
import static org.springframework.data.mongodb.core.index.PartialIndexFilter.*;
2221
import static org.springframework.data.mongodb.core.query.Criteria.*;
2322

24-
import reactor.core.publisher.Mono;
2523
import reactor.test.StepVerifier;
2624

2725
import java.util.function.Predicate;
@@ -87,10 +85,10 @@ public void setUp() {
8785
String collectionName = this.template.getCollectionName(DefaultIndexOperationsIntegrationTestsSample.class);
8886

8987
this.collection = this.template.getMongoDatabase().getCollection(collectionName, Document.class);
90-
Mono.from(this.collection.dropIndexes()).subscribe();
91-
9288
this.indexOps = new DefaultReactiveIndexOperations(template, collectionName,
9389
new QueryMapper(template.getConverter()));
90+
91+
StepVerifier.create(this.collection.dropIndexes()).expectNextCount(1).verifyComplete();
9492
}
9593

9694
private void queryMongoVersionIfNecessary() {
@@ -104,7 +102,7 @@ private void queryMongoVersionIfNecessary() {
104102
@Test // DATAMONGO-1518
105103
public void shouldCreateIndexWithCollationCorrectly() {
106104

107-
assumeThat(mongoVersion.isGreaterThanOrEqualTo(THREE_DOT_FOUR), is(true));
105+
assumeTrue(mongoVersion.isGreaterThanOrEqualTo(THREE_DOT_FOUR));
108106

109107
IndexDefinition id = new Index().named("with-collation").on("xyz", Direction.ASC)
110108
.collation(Collation.of("de_AT").caseFirst(CaseFirst.off()));
@@ -132,13 +130,13 @@ public void shouldCreateIndexWithCollationCorrectly() {
132130

133131
assertThat(result).isEqualTo(expected);
134132
}) //
135-
.thenAwait();
133+
.verifyComplete();
136134
}
137135

138136
@Test // DATAMONGO-1682
139137
public void shouldApplyPartialFilterCorrectly() {
140138

141-
assumeThat(mongoVersion.isGreaterThanOrEqualTo(THREE_DOT_TWO), is(true));
139+
assumeTrue(mongoVersion.isGreaterThanOrEqualTo(THREE_DOT_TWO));
142140

143141
IndexDefinition id = new Index().named("partial-with-criteria").on("k3y", Direction.ASC)
144142
.partial(of(where("q-t-y").gte(10)));
@@ -149,13 +147,13 @@ public void shouldApplyPartialFilterCorrectly() {
149147
.consumeNextWith(indexInfo -> {
150148
assertThat(indexInfo.getPartialFilterExpression()).isEqualTo("{ \"q-t-y\" : { \"$gte\" : 10 } }");
151149
}) //
152-
.thenAwait();
150+
.verifyComplete();
153151
}
154152

155153
@Test // DATAMONGO-1682
156154
public void shouldApplyPartialFilterWithMappedPropertyCorrectly() {
157155

158-
assumeThat(mongoVersion.isGreaterThanOrEqualTo(THREE_DOT_TWO), is(true));
156+
assumeTrue(mongoVersion.isGreaterThanOrEqualTo(THREE_DOT_TWO));
159157

160158
IndexDefinition id = new Index().named("partial-with-mapped-criteria").on("k3y", Direction.ASC)
161159
.partial(of(where("quantity").gte(10)));
@@ -165,13 +163,13 @@ public void shouldApplyPartialFilterWithMappedPropertyCorrectly() {
165163
StepVerifier.create(indexOps.getIndexInfo().filter(this.indexByName("partial-with-mapped-criteria"))) //
166164
.consumeNextWith(indexInfo -> {
167165
assertThat(indexInfo.getPartialFilterExpression()).isEqualTo("{ \"qty\" : { \"$gte\" : 10 } }");
168-
}).thenAwait();
166+
}).verifyComplete();
169167
}
170168

171169
@Test // DATAMONGO-1682
172170
public void shouldApplyPartialDBOFilterCorrectly() {
173171

174-
assumeThat(mongoVersion.isGreaterThanOrEqualTo(THREE_DOT_TWO), is(true));
172+
assumeTrue(mongoVersion.isGreaterThanOrEqualTo(THREE_DOT_TWO));
175173

176174
IndexDefinition id = new Index().named("partial-with-dbo").on("k3y", Direction.ASC)
177175
.partial(of(new org.bson.Document("qty", new org.bson.Document("$gte", 10))));
@@ -182,14 +180,14 @@ public void shouldApplyPartialDBOFilterCorrectly() {
182180
.consumeNextWith(indexInfo -> {
183181
assertThat(indexInfo.getPartialFilterExpression()).isEqualTo("{ \"qty\" : { \"$gte\" : 10 } }");
184182
}) //
185-
.thenAwait();
183+
.verifyComplete();
186184

187185
}
188186

189187
@Test // DATAMONGO-1682
190188
public void shouldFavorExplicitMappingHintViaClass() {
191189

192-
assumeThat(mongoVersion.isGreaterThanOrEqualTo(THREE_DOT_TWO), is(true));
190+
assumeTrue(mongoVersion.isGreaterThanOrEqualTo(THREE_DOT_TWO));
193191

194192
IndexDefinition id = new Index().named("partial-with-inheritance").on("k3y", Direction.ASC)
195193
.partial(of(where("age").gte(10)));

0 commit comments

Comments
 (0)