/*
* Copyright 2016-2017 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;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import lombok.Data;
import reactor.core.publisher.Flux;
import reactor.test.StepVerifier;
import java.util.List;
import org.bson.Document;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.annotation.Id;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.mongodb.core.index.Index;
import org.springframework.data.mongodb.core.index.IndexField;
import org.springframework.data.mongodb.core.index.IndexInfo;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.mongodb.reactivestreams.client.ListIndexesPublisher;
import com.mongodb.reactivestreams.client.MongoCollection;
/**
* Integration test for {@link MongoTemplate}.
*
* @author Mark Paluch
* @author Christoph Strobl
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:reactive-infrastructure.xml")
public class ReactiveMongoTemplateIndexTests {
@Rule public ExpectedException thrown = ExpectedException.none();
@Autowired SimpleReactiveMongoDatabaseFactory factory;
@Autowired ReactiveMongoTemplate template;
@Before
public void setUp() {
StepVerifier.create(template.dropCollection(Person.class)).verifyComplete();
}
@After
public void cleanUp() {}
@Test // DATAMONGO-1444
public void testEnsureIndexShouldCreateIndex() {
Person p1 = new Person("Oliver");
p1.setAge(25);
template.insert(p1);
Person p2 = new Person("Sven");
p2.setAge(40);
template.insert(p2);
StepVerifier
.create(template.indexOps(Person.class) //
.ensureIndex(new Index().on("age", Direction.DESC).unique())) //
.expectNextCount(1) //
.verifyComplete();
MongoCollection<Document> coll = template.getCollection(template.getCollectionName(Person.class));
StepVerifier.create(Flux.from(coll.listIndexes()).collectList()).consumeNextWith(indexInfo -> {
assertThat(indexInfo.size(), is(2));
Object indexKey = null;
boolean unique = false;
for (Document ix : indexInfo) {
if ("age_-1".equals(ix.get("name"))) {
indexKey = ix.get("key");
unique = (Boolean) ix.get("unique");
}
}
assertThat(((Document) indexKey), hasEntry("age", -1));
assertThat(unique, is(true));
}).verifyComplete();
}
@Test // DATAMONGO-1444
public void getIndexInfoShouldReturnCorrectIndex() {
Person p1 = new Person("Oliver");
p1.setAge(25);
StepVerifier.create(template.insert(p1)).expectNextCount(1).verifyComplete();
StepVerifier
.create(template.indexOps(Person.class) //
.ensureIndex(new Index().on("age", Direction.DESC).unique())) //
.expectNextCount(1) //
.verifyComplete();
StepVerifier.create(template.indexOps(Person.class).getIndexInfo().collectList()).consumeNextWith(indexInfos -> {
assertThat(indexInfos.size(), is(2));
IndexInfo ii = indexInfos.get(1);
assertThat(ii.isUnique(), is(true));
assertThat(ii.isSparse(), is(false));
List<IndexField> indexFields = ii.getIndexFields();
IndexField field = indexFields.get(0);
assertThat(field, is(IndexField.create("age", Direction.DESC)));
}).verifyComplete();
}
@Test // DATAMONGO-1444
public void testReadIndexInfoForIndicesCreatedViaMongoShellCommands() {
String command = "db." + template.getCollectionName(Person.class)
+ ".createIndex({'age':-1}, {'unique':true, 'sparse':true}), 1";
StepVerifier.create(template.indexOps(Person.class).dropAllIndexes()).verifyComplete();
StepVerifier.create(template.indexOps(Person.class).getIndexInfo()).verifyComplete();
StepVerifier.create(factory.getMongoDatabase().runCommand(new org.bson.Document("eval", command))) //
.expectNextCount(1) //
.verifyComplete();
ListIndexesPublisher<Document> listIndexesPublisher = template
.getCollection(template.getCollectionName(Person.class)).listIndexes();
StepVerifier.create(Flux.from(listIndexesPublisher).collectList()).consumeNextWith(indexInfos -> {
Document indexKey = null;
boolean unique = false;
for (Document document : indexInfos) {
if ("age_-1".equals(document.get("name"))) {
indexKey = (org.bson.Document) document.get("key");
unique = (Boolean) document.get("unique");
}
}
assertThat(indexKey, hasEntry("age", -1D));
assertThat(unique, is(true));
}).verifyComplete();
StepVerifier.create(Flux.from(template.indexOps(Person.class).getIndexInfo().collectList()))
.consumeNextWith(indexInfos -> {
IndexInfo info = indexInfos.get(1);
assertThat(info.isUnique(), is(true));
assertThat(info.isSparse(), is(true));
List<IndexField> indexFields = info.getIndexFields();
IndexField field = indexFields.get(0);
assertThat(field, is(IndexField.create("age", Direction.DESC)));
}).verifyComplete();
}
@Data
static class Sample {
@Id String id;
String field;
public Sample() {}
public Sample(String id, String field) {
this.id = id;
this.field = field;
}
}
}