Compare commits

...

13 Commits

Author SHA1 Message Date
Christoph Strobl
1a39010ac2 Hacking 2019-08-27 13:51:13 +02:00
Christoph Strobl
e3837aa720 DATAMONGO-2347 - Prepare issue branch. 2019-08-26 13:38:05 +02:00
Christoph Strobl
66b318dabe DATAMONGO-2351 - Polishing.
Fix broken tests and favor StepVerifier over block() for reactive ones.

Original Pull Request: #781
2019-08-23 07:22:09 +02:00
Artyom Gabeev
b78569374a DATAMONGO-2351 - Return zero deleted count for unacknowledged deleteBy.
Original Pull Request: #781
2019-08-23 07:21:55 +02:00
Mark Paluch
79921a7260 DATAMONGO-2342 - Add build job against MongoDB 4.0 2019-08-16 13:19:27 +02:00
Christoph Strobl
bcd8f242e5 DATAMONGO-2342 - Upgrade ci job to MongoDB 4.2
Original pull request: #778.
2019-08-16 11:52:28 +02:00
Christoph Strobl
73fab14b21 DATAMONGO-2342 - Upgrade MongoDB java & reactive streams Driver to 3.11 and 1.12.
Original pull request: #778.
2019-08-16 11:52:23 +02:00
Christoph Strobl
d4505880c7 DATAMONGO-2339 - Fix QueryMapper field name resolution for properties containing underscore.
We now prevent splitting of paths that contain underscores if the entity contains a property that matches.

Original pull request: #777.
2019-08-13 10:26:43 +02:00
Mark Paluch
a54b91392e DATAMONGO-2338 - Open RepositoryFactoryBeans for extension.
createRepositoryFactory() is now no longer final allowing for overriding the method. This change aligns with the remanining store modules.
2019-08-06 15:57:08 +02:00
Mark Paluch
5dc7e7c65f DATAMONGO-2337 - Add HTTPS entries into spring.schemas.
To resolve XSD files properly from the classpath, their HTTPS reference must be present in the spring.schemas to avoid internet interaction for resolving an XSD file.
2019-08-06 15:55:37 +02:00
Greg Turnquist
8802e2c36f DATAMONGO-2280 - Force check for updates. 2019-08-05 11:07:18 -05:00
Mark Paluch
d8189620d2 DATAMONGO-2303 - After release cleanups. 2019-08-05 15:53:02 +02:00
Mark Paluch
fd6411f0ed DATAMONGO-2303 - Prepare next development iteration. 2019-08-05 15:53:01 +02:00
21 changed files with 370 additions and 26 deletions

45
Jenkinsfile vendored
View File

@@ -46,6 +46,22 @@ pipeline {
}
}
}
stage('Publish JDK 8 + MongoDB 4.2') {
when {
changeset "ci/openjdk8-mongodb-4.2/**"
}
agent { label 'data' }
options { timeout(time: 30, unit: 'MINUTES') }
steps {
script {
def image = docker.build("springci/spring-data-openjdk8-with-mongodb-4.2", "ci/openjdk8-mongodb-4.2/")
docker.withRegistry('', 'hub.docker.com-springbuildmaster') {
image.push()
}
}
}
}
}
}
@@ -58,7 +74,7 @@ pipeline {
}
agent {
docker {
image 'springci/spring-data-openjdk8-with-mongodb-4.0:latest'
image 'springci/spring-data-openjdk8-with-mongodb-4.2:latest'
label 'data'
args '-v $HOME:/tmp/jenkins-home'
}
@@ -71,7 +87,7 @@ pipeline {
sh 'sleep 10'
sh 'mongo --eval "rs.initiate({_id: \'rs0\', members:[{_id: 0, host: \'127.0.0.1:27017\'}]});"'
sh 'sleep 15'
sh 'MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw clean dependency:list test -Dsort -B'
sh 'MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw clean dependency:list test -Dsort -U -B'
}
}
@@ -83,6 +99,25 @@ pipeline {
}
}
parallel {
stage("test: mongodb 4.0") {
agent {
docker {
image 'springci/spring-data-openjdk8-with-mongodb-4.0:latest'
label 'data'
args '-v $HOME:/tmp/jenkins-home'
}
}
options { timeout(time: 30, unit: 'MINUTES') }
steps {
sh 'rm -rf ?'
sh 'mkdir -p /tmp/mongodb/db /tmp/mongodb/log'
sh 'mongod --dbpath /tmp/mongodb/db --replSet rs0 --fork --logpath /tmp/mongodb/log/mongod.log &'
sh 'sleep 10'
sh 'mongo --eval "rs.initiate({_id: \'rs0\', members:[{_id: 0, host: \'127.0.0.1:27017\'}]});"'
sh 'sleep 15'
sh 'MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw clean dependency:list test -Dsort -U -B'
}
}
stage("test: mongodb 4.1") {
agent {
docker {
@@ -99,7 +134,7 @@ pipeline {
sh 'sleep 10'
sh 'mongo --eval "rs.initiate({_id: \'rs0\', members:[{_id: 0, host: \'127.0.0.1:27017\'}]});"'
sh 'sleep 15'
sh 'MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw clean dependency:list test -Dsort -B'
sh 'MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw clean dependency:list test -Dsort -U -B'
}
}
}
@@ -134,7 +169,7 @@ pipeline {
"-Dartifactory.staging-repository=libs-snapshot-local " +
"-Dartifactory.build-name=spring-data-mongodb " +
"-Dartifactory.build-number=${BUILD_NUMBER} " +
'-Dmaven.test.skip=true clean deploy -B'
'-Dmaven.test.skip=true clean deploy -U -B'
}
}
@@ -161,7 +196,7 @@ pipeline {
"-Dartifactory.username=${ARTIFACTORY_USR} " +
"-Dartifactory.password=${ARTIFACTORY_PSW} " +
"-Dartifactory.distribution-repository=temp-private-local " +
'-Dmaven.test.skip=true clean deploy -B'
'-Dmaven.test.skip=true clean deploy -U -B'
}
}
}

View File

@@ -0,0 +1,14 @@
FROM adoptopenjdk/openjdk8:latest
RUN apt-get update && apt-get install -y apt-transport-https apt-utils gnupg2
RUN apt-key adv --keyserver hkps://keyserver.ubuntu.com:443 --recv e162f504a20cdf15827f718d4b7c549a058f8b6b
RUN echo "deb [ arch=amd64 ] https://repo.mongodb.org/apt/ubuntu bionic/mongodb-org/4.2 multiverse" | tee /etc/apt/sources.list.d/mongodb-org-4.2.list
RUN apt-get update
RUN apt-get install -y mongodb-org=4.2.0 mongodb-org-server=4.2.0 mongodb-org-shell=4.2.0 mongodb-org-mongos=4.2.0 mongodb-org-tools=4.2.0
RUN apt-get clean \
&& rm -rf /var/lib/apt/lists/*

14
pom.xml
View File

@@ -5,7 +5,7 @@
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId>
<version>2.2.0.RC2</version>
<version>2.2.0.DATAMONGO-2347-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Spring Data MongoDB</name>
@@ -15,7 +15,7 @@
<parent>
<groupId>org.springframework.data.build</groupId>
<artifactId>spring-data-parent</artifactId>
<version>2.2.0.RC2</version>
<version>2.2.0.BUILD-SNAPSHOT</version>
</parent>
<modules>
@@ -26,9 +26,9 @@
<properties>
<project.type>multi</project.type>
<dist.id>spring-data-mongodb</dist.id>
<springdata.commons>2.2.0.RC2</springdata.commons>
<mongo>3.11.0-rc0</mongo>
<mongo.reactivestreams>1.12.0-rc0</mongo.reactivestreams>
<springdata.commons>2.2.0.BUILD-SNAPSHOT</springdata.commons>
<mongo>3.11.0</mongo>
<mongo.reactivestreams>1.12.0</mongo.reactivestreams>
<jmh.version>1.19</jmh.version>
</properties>
@@ -134,8 +134,8 @@
<repositories>
<repository>
<id>spring-libs-milestone</id>
<url>https://repo.spring.io/libs-milestone</url>
<id>spring-libs-snapshot</id>
<url>https://repo.spring.io/libs-snapshot</url>
</repository>
</repositories>

View File

@@ -7,7 +7,7 @@
<parent>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId>
<version>2.2.0.RC2</version>
<version>2.2.0.DATAMONGO-2347-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@@ -14,7 +14,7 @@
<parent>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId>
<version>2.2.0.RC2</version>
<version>2.2.0.DATAMONGO-2347-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@@ -11,7 +11,7 @@
<parent>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId>
<version>2.2.0.RC2</version>
<version>2.2.0.DATAMONGO-2347-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@@ -252,6 +252,8 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
MongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(typeToUse);
// hacking - use below will allow kotlin test to pass
// MongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(rawType);
if (entity == null) {
throw new MappingException(String.format(INVALID_TYPE_TO_READ, target, typeToUse.getType()));
}

View File

@@ -33,7 +33,6 @@ import org.bson.BsonValue;
import org.bson.Document;
import org.bson.conversions.Bson;
import org.bson.types.ObjectId;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.domain.Example;
@@ -1099,6 +1098,11 @@ public class QueryMapper {
private PropertyPath forName(String path) {
try {
if (entity.getPersistentProperty(path) != null) {
return PropertyPath.from(Pattern.quote(path), entity.getTypeInformation());
}
return PropertyPath.from(path, entity.getTypeInformation());
} catch (PropertyReferenceException | InvalidPersistentPropertyPath e) {

View File

@@ -229,6 +229,10 @@ interface MongoQueryExecution {
/**
* {@link MongoQueryExecution} removing documents matching the query.
*
* @author Oliver Gierke
* @author Mark Paluch
* @author Artyom Gabeev
* @author Christoph Strobl
* @since 1.5
*/
@RequiredArgsConstructor
@@ -252,7 +256,7 @@ interface MongoQueryExecution {
}
DeleteResult writeResult = operations.remove(query, type, collectionName);
return writeResult != null ? writeResult.getDeletedCount() : 0L;
return writeResult.wasAcknowledged() ? writeResult.getDeletedCount() : 0L;
}
}
}

View File

@@ -109,6 +109,7 @@ interface ReactiveMongoQueryExecution {
* {@link ReactiveMongoQueryExecution} removing documents matching the query.
*
* @author Mark Paluch
* @author Artyom Gabeev
*/
@RequiredArgsConstructor
final class DeleteExecution implements ReactiveMongoQueryExecution {
@@ -127,7 +128,8 @@ interface ReactiveMongoQueryExecution {
return operations.findAllAndRemove(query, type, collection);
}
return operations.remove(query, type, collection).map(DeleteResult::getDeletedCount);
return operations.remove(query, type, collection)
.map(deleteResult -> deleteResult.wasAcknowledged() ? deleteResult.getDeletedCount() : 0L);
}
}

View File

@@ -84,7 +84,7 @@ public class MongoRepositoryFactoryBean<T extends Repository<S, ID>, S, ID exten
* #createRepositoryFactory()
*/
@Override
protected final RepositoryFactorySupport createRepositoryFactory() {
protected RepositoryFactorySupport createRepositoryFactory() {
RepositoryFactorySupport factory = getFactoryInstance(operations);

View File

@@ -89,7 +89,7 @@ public class ReactiveMongoRepositoryFactoryBean<T extends Repository<S, ID>, S,
* #createRepositoryFactory()
*/
@Override
protected final RepositoryFactorySupport createRepositoryFactory() {
protected RepositoryFactorySupport createRepositoryFactory() {
RepositoryFactorySupport factory = getFactoryInstance(operations);

View File

@@ -11,3 +11,16 @@ http\://www.springframework.org/schema/data/mongo/spring-mongo-1.10.2.xsd=org/sp
http\://www.springframework.org/schema/data/mongo/spring-mongo-2.0.xsd=org/springframework/data/mongodb/config/spring-mongo-2.0.xsd
http\://www.springframework.org/schema/data/mongo/spring-mongo-2.2.xsd=org/springframework/data/mongodb/config/spring-mongo-2.0.xsd
http\://www.springframework.org/schema/data/mongo/spring-mongo.xsd=org/springframework/data/mongodb/config/spring-mongo-2.2.xsd
https\://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd=org/springframework/data/mongodb/config/spring-mongo-1.0.xsd
https\://www.springframework.org/schema/data/mongo/spring-mongo-1.1.xsd=org/springframework/data/mongodb/config/spring-mongo-1.1.xsd
https\://www.springframework.org/schema/data/mongo/spring-mongo-1.2.xsd=org/springframework/data/mongodb/config/spring-mongo-1.2.xsd
https\://www.springframework.org/schema/data/mongo/spring-mongo-1.3.xsd=org/springframework/data/mongodb/config/spring-mongo-1.3.xsd
https\://www.springframework.org/schema/data/mongo/spring-mongo-1.4.xsd=org/springframework/data/mongodb/config/spring-mongo-1.4.xsd
https\://www.springframework.org/schema/data/mongo/spring-mongo-1.5.xsd=org/springframework/data/mongodb/config/spring-mongo-1.5.xsd
https\://www.springframework.org/schema/data/mongo/spring-mongo-1.7.xsd=org/springframework/data/mongodb/config/spring-mongo-1.7.xsd
https\://www.springframework.org/schema/data/mongo/spring-mongo-1.8.xsd=org/springframework/data/mongodb/config/spring-mongo-1.8.xsd
https\://www.springframework.org/schema/data/mongo/spring-mongo-1.10.xsd=org/springframework/data/mongodb/config/spring-mongo-1.10.xsd
https\://www.springframework.org/schema/data/mongo/spring-mongo-1.10.2.xsd=org/springframework/data/mongodb/config/spring-mongo-1.10.2.xsd
https\://www.springframework.org/schema/data/mongo/spring-mongo-2.0.xsd=org/springframework/data/mongodb/config/spring-mongo-2.0.xsd
https\://www.springframework.org/schema/data/mongo/spring-mongo-2.2.xsd=org/springframework/data/mongodb/config/spring-mongo-2.0.xsd
https\://www.springframework.org/schema/data/mongo/spring-mongo.xsd=org/springframework/data/mongodb/config/spring-mongo-2.2.xsd

View File

@@ -32,7 +32,6 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.data.annotation.Id;

View File

@@ -29,6 +29,7 @@ import java.net.URL;
import java.time.LocalDateTime;
import java.util.*;
import org.bson.json.JsonWriterSettings;
import org.bson.types.Code;
import org.bson.types.Decimal128;
import org.bson.types.ObjectId;
@@ -60,12 +61,14 @@ import org.springframework.data.geo.Point;
import org.springframework.data.geo.Polygon;
import org.springframework.data.geo.Shape;
import org.springframework.data.mapping.MappingException;
import org.springframework.data.mapping.PersistentProperty;
import org.springframework.data.mapping.model.MappingInstantiationException;
import org.springframework.data.mongodb.core.DocumentTestUtils;
import org.springframework.data.mongodb.core.convert.DocumentAccessorUnitTests.NestedType;
import org.springframework.data.mongodb.core.convert.DocumentAccessorUnitTests.ProjectingType;
import org.springframework.data.mongodb.core.convert.MappingMongoConverterUnitTests.ClassWithMapUsingEnumAsKey.FooBarEnum;
import org.springframework.data.mongodb.core.geo.Sphere;
import org.springframework.data.mongodb.core.mapping.BasicMongoPersistentEntity;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;
import org.springframework.data.mongodb.core.mapping.FieldType;
@@ -74,6 +77,7 @@ import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
import org.springframework.data.mongodb.core.mapping.PersonPojoStringId;
import org.springframework.data.mongodb.core.mapping.TextScore;
import org.springframework.data.util.ClassTypeInformation;
import org.springframework.data.util.TypeInformation;
import org.springframework.test.util.ReflectionTestUtils;
import com.mongodb.BasicDBList;
@@ -2529,4 +2533,139 @@ public class MappingMongoConverterUnitTests {
Date dateAsObjectId;
}
static class Model<EVT, ID> {
private final @Id Long id;
private final EVT event;
public Model(Long id, EVT event) {
this.id = id;
this.event = event;
}
@Override
public String toString() {
return "Model{" + "id=" + id + ", event=" + event + '}';
}
}
static abstract class DomainEvent<EVT, REF_ID> {
private final REF_ID aggregateId;
private final EVT root;
DomainEvent(REF_ID aggregateId, EVT root) {
this.aggregateId = aggregateId;
this.root = root;
}
public EVT getRoot() {
return root;
}
public REF_ID getAggregateId() {
return aggregateId;
}
}
final static class ConcreteEvent extends DomainEvent<Details, Long> {
ConcreteEvent(Long aggregateId, Details root) {
super(aggregateId, root);
}
@Override
public String toString() {
return "ConcreteEvent{" + "id=" + getAggregateId() + ", root=" + getRoot() + '}';
}
}
final static class Details {
private final String value;
public Details(String value) {
this.value = value;
}
@Override
public String toString() {
return "Details{" + "value='" + value + '\'' + '}';
}
}
@Test
public void javaReadWithGenerics() {
Model model = new Model(1L, new ConcreteEvent(100L, new Details("details")));
org.bson.Document target = new org.bson.Document();
converter.write(model, target);
System.out.println("target: " + target.toJson(JsonWriterSettings.builder().indent(true).build()));
Model back = converter.read(Model.class, target);
System.out.println("back: " + back);
}
@Test
public void kotlinReadWithGenerics() {
StoredEvent event = new StoredEvent(1L, new OfferCreated(100L, new OfferDetails("details")));
org.bson.Document target = new org.bson.Document();
converter.write(event, target);
System.out.println("target: " + target.toJson(JsonWriterSettings.builder().indent(true).build()));
// KotlinClassGeneratingEntityInstantiator kci = new KotlinClassGeneratingEntityInstantiator().createInstance()
StoredEvent back = converter.read(StoredEvent.class, target);
System.out.println("back: " + back);
// OfferCreated
}
// @Test
// public void cti() {
//
// ClassTypeInformation<ConcreteEvent> javaInfo = ClassTypeInformation.from(ConcreteEvent.class);
// System.out.println("javaInfo: " + javaInfo);
// TypeInformation<?> javaProperty = javaInfo.getProperty("root");
// System.out.println("javaProperty: " + javaProperty.getType());
//
// ClassTypeInformation<OfferCreated> kotlinInfo = ClassTypeInformation.from(OfferCreated.class);
// System.out.println("kotlinInfo: " + kotlinInfo);
// TypeInformation<?> kotlinProperty = kotlinInfo.getProperty("root");
// System.out.println("kotlinProperty: " + kotlinProperty.getType());
//
// MongoMappingContext mappingContext = new MongoMappingContext();
// mappingContext.afterPropertiesSet();
//
// BasicMongoPersistentEntity<?> mpe = mappingContext.getPersistentEntity(OfferCreated.class);
//
// PersistentProperty mpp = mpe.getPersistentProperty("root");
// TypeInformation ti = mpp.getTypeInformation();
//
// BasicMongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(ti);
// System.out.println("entity type: " + entity.getType());
// System.out.println("ti: " + ti);
// System.out.println("kotlinPersistentProperty: " + ti.getType());
//
// }
//
// @Test
// public void c4() {
//
//
// TypeInformation<? extends DomainEvent> cti = ClassTypeInformation.from(DomainEvent.class);
// TypeInformation<? extends DomainEvent> evt = cti.specialize(ClassTypeInformation.from(OfferCreated.class));
//
// TypeInformation<?> x = evt.getProperty("root");
// System.out.println("x.getType(): " + x.getType());
//
//
// }
}

View File

@@ -881,6 +881,15 @@ public class QueryMapperUnitTests {
assertThat(document).isEqualTo(new org.bson.Document("scripts", new Code(script)));
}
@Test // DATAMONGO-2339
public void findByIdUsesMappedIdFieldNameWithUnderscoreCorrectly() {
org.bson.Document target = mapper.getMappedObject(new org.bson.Document("with_underscore", "id-1"),
context.getPersistentEntity(WithIdPropertyContainingUnderscore.class));
assertThat(target).isEqualTo(new org.bson.Document("_id", "id-1"));
}
@Document
public class Foo {
@Id private ObjectId id;
@@ -1013,4 +1022,8 @@ public class QueryMapperUnitTests {
@Field(targetType = FieldType.SCRIPT) //
List<String> scripts;
}
static class WithIdPropertyContainingUnderscore {
@Id String with_underscore;
}
}

View File

@@ -99,6 +99,8 @@ public class AbstractMongoQueryUnitTests {
doReturn(executableFind).when(mongoOperationsMock).query(any());
doReturn(withQueryMock).when(executableFind).as(any());
doReturn(withQueryMock).when(withQueryMock).matching(any());
when(mongoOperationsMock.remove(any(), any(), anyString())).thenReturn(deleteResultMock);
}
@Test // DATAMONGO-566
@@ -131,7 +133,7 @@ public class AbstractMongoQueryUnitTests {
public void testDeleteExecutionReturnsNrDocumentsDeletedFromWriteResult() {
when(deleteResultMock.getDeletedCount()).thenReturn(100L);
when(mongoOperationsMock.remove(any(), eq(Person.class), eq("persons"))).thenReturn(deleteResultMock);
when(deleteResultMock.wasAcknowledged()).thenReturn(true);
MongoQueryFake query = createQueryForMethod("deletePersonByLastname", String.class);
query.setDeleteQuery(true);

View File

@@ -15,7 +15,9 @@
*/
package org.springframework.data.mongodb.repository.query;
import static org.mockito.ArgumentMatchers.*;
import static org.assertj.core.api.Assertions.*;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.*;
import java.lang.reflect.Method;
@@ -27,7 +29,6 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.geo.Distance;
@@ -47,6 +48,7 @@ import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
import org.springframework.data.mongodb.core.query.NearQuery;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.repository.Person;
import org.springframework.data.mongodb.repository.query.MongoQueryExecution.DeleteExecution;
import org.springframework.data.mongodb.repository.query.MongoQueryExecution.PagedExecution;
import org.springframework.data.mongodb.repository.query.MongoQueryExecution.PagingGeoNearExecution;
import org.springframework.data.projection.ProjectionFactory;
@@ -58,11 +60,14 @@ import org.springframework.data.repository.query.QueryMethodEvaluationContextPro
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.util.ReflectionUtils;
import com.mongodb.client.result.DeleteResult;
/**
* Unit tests for {@link MongoQueryExecution}.
*
* @author Mark Paluch
* @author Oliver Gierke
* @author Artyom Gabeev
* @soundtrack U Can't Touch This - MC Hammer
*/
@RunWith(MockitoJUnitRunner.class)
@@ -173,6 +178,24 @@ public class MongoQueryExecutionUnitTests {
verify(terminatingMock).count();
}
@Test // DATAMONGO-2351
public void acknowledgedDeleteReturnsDeletedCount() {
when(mongoOperationsMock.remove(any(Query.class), any(Class.class), anyString()))
.thenReturn(DeleteResult.acknowledged(10));
assertThat(new DeleteExecution(mongoOperationsMock, queryMethod).execute(new Query())).isEqualTo(10L);
}
@Test // DATAMONGO-2351
public void unacknowledgedDeleteReturnsZeroDeletedCount() {
when(mongoOperationsMock.remove(any(Query.class), any(Class.class), anyString()))
.thenReturn(DeleteResult.unacknowledged());
assertThat(new DeleteExecution(mongoOperationsMock, queryMethod).execute(new Query())).isEqualTo(0L);
}
interface PersonRepository extends Repository<Person, Long> {
GeoPage<Person> findByLocationNear(Point point, Distance distance, Pageable pageable);

View File

@@ -16,10 +16,14 @@
package org.springframework.data.mongodb.repository.query;
import static org.assertj.core.api.Assertions.*;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.*;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
import java.lang.reflect.Method;
import java.util.Arrays;
@@ -29,7 +33,7 @@ import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.reactivestreams.Publisher;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Range;
@@ -41,20 +45,25 @@ import org.springframework.data.mongodb.core.ReactiveMongoOperations;
import org.springframework.data.mongodb.core.query.NearQuery;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.repository.Person;
import org.springframework.data.mongodb.repository.query.ReactiveMongoQueryExecution.DeleteExecution;
import org.springframework.data.mongodb.repository.query.ReactiveMongoQueryExecution.GeoNearExecution;
import org.springframework.data.util.ClassTypeInformation;
import org.springframework.util.ClassUtils;
import com.mongodb.client.result.DeleteResult;
/**
* Unit tests for {@link ReactiveMongoQueryExecution}.
*
* @author Mark Paluch
* @author Artyom Gabeev
*/
@RunWith(MockitoJUnitRunner.class)
public class ReactiveMongoQueryExecutionUnitTests {
@Mock private ReactiveMongoOperations operations;
@Mock private MongoParameterAccessor parameterAccessor;
@Mock private MongoQueryMethod method;
@Test // DATAMONGO-1444
public void geoNearExecutionShouldApplyQuerySettings() throws Exception {
@@ -101,6 +110,30 @@ public class ReactiveMongoQueryExecutionUnitTests {
assertThat(nearQuery.getMaxDistance()).isNull();
}
@Test // DATAMONGO-2351
public void acknowledgedDeleteReturnsDeletedCount() {
when(operations.remove(any(Query.class), any(Class.class), anyString()))
.thenReturn(Mono.just(DeleteResult.acknowledged(10)));
Mono.from((Publisher<Long>) new DeleteExecution(operations, method).execute(new Query(), Class.class, "")) //
.as(StepVerifier::create) //
.expectNext(10L) //
.verifyComplete();
}
@Test // DATAMONGO-2351
public void unacknowledgedDeleteReturnsZeroDeletedCount() {
when(operations.remove(any(Query.class), any(Class.class), anyString()))
.thenReturn(Mono.just(DeleteResult.unacknowledged()));
Mono.from((Publisher<Long>) new DeleteExecution(operations, method).execute(new Query(), Class.class, "")) //
.as(StepVerifier::create) //
.expectNext(0L) //
.verifyComplete();
}
interface GeoRepo {
Flux<GeoResult<Person>> geoNear();
}

View File

@@ -118,6 +118,7 @@ public class MongoTestUtils {
.withWriteConcern(WriteConcern.MAJORITY).withReadPreference(ReadPreference.primary());
Mono.from(database.getCollection(collectionName).drop()) //
.retryBackoff(3, Duration.ofMillis(250)) //
.as(StepVerifier::create) //
.expectNext(Success.SUCCESS) //
.verifyComplete();

View File

@@ -0,0 +1,60 @@
/*
* Copyright 2019 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
*
* https://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 org.springframework.data.annotation.Id
import org.springframework.data.mongodb.core.mapping.Document
@Document(collection = "domain_events")
data class StoredEvent<AGGREGATE, ID>(@Id val sequenceNo: Long = 0, val event: DomainEvent<AGGREGATE, ID>? = null)
abstract class DomainEvent<AGGREGATE, ID>(val aggregateId: ID, val root: AGGREGATE) {
override fun toString(): String {
return "DomainEvent(aggregateId=$aggregateId, root=$root)"
}
}
class OfferCreated(aggregateId: Long, root: OfferDetails)
: DomainEvent<OfferDetails, Long>(aggregateId, root) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as OfferCreated
if (aggregateId != other.aggregateId) return false
if (root != other.root) return false
return true
}
override fun hashCode(): Int {
var result = aggregateId.hashCode()
result = 31 * result + root.hashCode()
return result
}
override fun toString(): String {
return "OfferCreated(aggregateId=$aggregateId, root=$root)"
}
}
data class OfferDetails(val name: String)