diff --git a/mongodb/change-streams/pom.xml b/mongodb/change-streams/pom.xml
index 9219af6b..0f6b41b8 100644
--- a/mongodb/change-streams/pom.xml
+++ b/mongodb/change-streams/pom.xml
@@ -31,12 +31,6 @@
test
-
- de.flapdoodle.embed
- de.flapdoodle.embed.mongo
- provided
-
-
diff --git a/mongodb/change-streams/src/main/java/example/springdata/mongodb/Person.java b/mongodb/change-streams/src/main/java/example/springdata/mongodb/Person.java
index 6d2ce3ef..f7e2a3d1 100644
--- a/mongodb/change-streams/src/main/java/example/springdata/mongodb/Person.java
+++ b/mongodb/change-streams/src/main/java/example/springdata/mongodb/Person.java
@@ -29,7 +29,5 @@ import org.springframework.data.mongodb.core.mapping.Field;
* @author Christoph Strobl
*/
record Person(@Id ObjectId id, @Field("first_name") String firstname, @Field("last_name") String lastname, int age) {
- public Person(String firstname, String lastname, int age) {
- this(null, firstname, lastname, age);
- }
+
}
diff --git a/mongodb/change-streams/src/test/java/example/springdata/mongodb/ChangeStreamsTests.java b/mongodb/change-streams/src/test/java/example/springdata/mongodb/ChangeStreamsTests.java
index 19f58fe3..dd8456c4 100644
--- a/mongodb/change-streams/src/test/java/example/springdata/mongodb/ChangeStreamsTests.java
+++ b/mongodb/change-streams/src/test/java/example/springdata/mongodb/ChangeStreamsTests.java
@@ -21,19 +21,19 @@ import static org.springframework.data.mongodb.core.query.Criteria.*;
import static org.springframework.data.mongodb.core.query.Query.*;
import static org.springframework.data.mongodb.core.query.Update.*;
-import example.springdata.mongodb.util.EmbeddedMongo;
-import reactor.test.StepVerifier;
-
import java.time.Duration;
+import com.mongodb.client.MongoClient;
+import com.mongodb.client.model.changestream.ChangeStreamDocument;
+import com.mongodb.reactivestreams.client.MongoClients;
+import example.springdata.mongodb.util.MongoContainers;
+import org.assertj.core.api.Assertions;
import org.bson.Document;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
+import org.bson.types.ObjectId;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration;
import org.springframework.boot.test.autoconfigure.data.mongo.DataMongoTest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -46,11 +46,13 @@ import org.springframework.data.mongodb.core.messaging.ChangeStreamRequest;
import org.springframework.data.mongodb.core.messaging.DefaultMessageListenerContainer;
import org.springframework.data.mongodb.core.messaging.Message;
import org.springframework.data.mongodb.core.messaging.MessageListenerContainer;
-import org.springframework.test.context.junit4.SpringRunner;
-
-import com.mongodb.client.MongoClient;
-import com.mongodb.client.model.changestream.ChangeStreamDocument;
-import com.mongodb.reactivestreams.client.MongoClients;
+import org.springframework.test.context.DynamicPropertyRegistry;
+import org.springframework.test.context.DynamicPropertySource;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+import org.testcontainers.containers.MongoDBContainer;
+import org.testcontainers.junit.jupiter.Container;
+import org.testcontainers.junit.jupiter.Testcontainers;
+import reactor.test.StepVerifier;
/**
* A simple Test demonstrating required {@link Configuration} for consumption of MongoDB
@@ -60,11 +62,18 @@ import com.mongodb.reactivestreams.client.MongoClients;
* @author Christoph Strobl
* @author Mark Paluch
*/
-@RunWith(SpringRunner.class)
+@Testcontainers
+@ExtendWith(SpringExtension.class)
@DataMongoTest
public class ChangeStreamsTests {
- public static @ClassRule EmbeddedMongo replSet = EmbeddedMongo.replSet().configure();
+ @Container //
+ private static MongoDBContainer mongoDBContainer = MongoContainers.getDefaultContainer();
+
+ @DynamicPropertySource
+ static void setProperties(DynamicPropertyRegistry registry) {
+ registry.add("spring.data.mongodb.uri", mongoDBContainer::getReplicaSetUrl);
+ }
@Autowired MessageListenerContainer container; // for imperative style
@@ -72,14 +81,14 @@ public class ChangeStreamsTests {
@Autowired ReactiveMongoOperations reactiveTemplate; // for reactive style
- Person gabriel = new Person("Gabriel", "Lorca", 30);
- Person michael = new Person("Michael", "Burnham", 30);
- Person ash = new Person("Ash", "Tyler", 35);
+ Person gabriel = new Person(new ObjectId(), "Gabriel", "Lorca", 30);
+ Person michael = new Person(new ObjectId(), "Michael", "Burnham", 30);
+ Person ash = new Person(new ObjectId(), "Ash", "Tyler", 35);
/**
* Configuration? Yes we need a bit of it - Do not worry, it won't be much!
*/
- @SpringBootApplication(exclude = EmbeddedMongoAutoConfiguration.class)
+ @SpringBootApplication()
static class Config {
/**
@@ -90,7 +99,7 @@ public class ChangeStreamsTests {
*/
@Bean
MongoClient mongoClient() {
- return replSet.getMongoClient();
+ return com.mongodb.client.MongoClients.create(mongoDBContainer.getReplicaSetUrl());
}
/**
@@ -100,7 +109,7 @@ public class ChangeStreamsTests {
*/
@Bean
SimpleMongoClientDatabaseFactory mongoDbFactory() {
- return new SimpleMongoClientDatabaseFactory(replSet.getMongoClient(), "changestreams");
+ return new SimpleMongoClientDatabaseFactory(mongoClient(), "changestreams");
}
/**
@@ -110,7 +119,7 @@ public class ChangeStreamsTests {
*/
@Bean
SimpleReactiveMongoDatabaseFactory reactiveMongoDatabaseFactory() {
- return new SimpleReactiveMongoDatabaseFactory(MongoClients.create(replSet.getConnectionString()),
+ return new SimpleReactiveMongoDatabaseFactory(MongoClients.create(mongoDBContainer.getReplicaSetUrl()),
"changestreams");
}
@@ -118,7 +127,7 @@ public class ChangeStreamsTests {
* Since listening to a Change Stream using the sync
* MongoDB Java Driver is a blocking class, we need to move load to another {@link Thread} by simply using a
* {@link MessageListenerContainer}.
- *
+ *
* As this is a {@link org.springframework.context.SmartLifecycle smart lifecycle component} we do actually not need
* to worry about its lifecycle, the resource allocation and freeing.
*
diff --git a/mongodb/transactions/pom.xml b/mongodb/transactions/pom.xml
index a11745a0..a73c5640 100644
--- a/mongodb/transactions/pom.xml
+++ b/mongodb/transactions/pom.xml
@@ -31,12 +31,6 @@
test
-
- de.flapdoodle.embed
- de.flapdoodle.embed.mongo
- provided
-
-
diff --git a/mongodb/transactions/src/main/java/example/springdata/mongodb/reactive/ReactiveTransitionService.java b/mongodb/transactions/src/main/java/example/springdata/mongodb/reactive/ReactiveTransitionService.java
index af538e15..f92a493b 100644
--- a/mongodb/transactions/src/main/java/example/springdata/mongodb/reactive/ReactiveTransitionService.java
+++ b/mongodb/transactions/src/main/java/example/springdata/mongodb/reactive/ReactiveTransitionService.java
@@ -49,14 +49,10 @@ public class ReactiveTransitionService {
public Mono run(Integer id) {
- return template.inTransaction().execute(action -> {
-
return lookup(id) //
- .flatMap(process -> start(action, process)) //
+ .flatMap(process -> start(template, process)) //
.flatMap(it -> verify(it)) //
- .flatMap(process -> finish(action, process));
-
- }).next().map(Process::id);
+ .flatMap(process -> finish(template, process)).map(Process::id);
}
private Mono finish(ReactiveMongoOperations operations, Process process) {
diff --git a/mongodb/transactions/src/test/java/example/springdata/mongodb/imperative/TransitionServiceTests.java b/mongodb/transactions/src/test/java/example/springdata/mongodb/imperative/TransitionServiceTests.java
index 4549a85d..d4df792b 100644
--- a/mongodb/transactions/src/test/java/example/springdata/mongodb/imperative/TransitionServiceTests.java
+++ b/mongodb/transactions/src/test/java/example/springdata/mongodb/imperative/TransitionServiceTests.java
@@ -15,19 +15,21 @@
*/
package example.springdata.mongodb.imperative;
-import example.springdata.mongodb.Process;
-import example.springdata.mongodb.State;
-import example.springdata.mongodb.util.EmbeddedMongo;
-
import java.util.function.Consumer;
+import com.mongodb.client.MongoClient;
+import com.mongodb.client.MongoClients;
+import com.mongodb.client.model.Filters;
+import com.mongodb.client.model.Projections;
+import example.springdata.mongodb.Process;
+import example.springdata.mongodb.State;
+import example.springdata.mongodb.util.MongoContainers;
import org.assertj.core.api.Assertions;
import org.bson.Document;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@@ -35,14 +37,14 @@ import org.springframework.data.mongodb.MongoDatabaseFactory;
import org.springframework.data.mongodb.MongoTransactionManager;
import org.springframework.data.mongodb.config.AbstractMongoClientConfiguration;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
-import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.context.DynamicPropertyRegistry;
+import org.springframework.test.context.DynamicPropertySource;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
-
-import com.mongodb.client.MongoClient;
-import com.mongodb.client.model.Filters;
-import com.mongodb.client.model.Projections;
+import org.testcontainers.containers.MongoDBContainer;
+import org.testcontainers.junit.jupiter.Container;
+import org.testcontainers.junit.jupiter.Testcontainers;
/**
* Test showing MongoDB Transaction usage through a synchronous (imperative) API using Spring's managed transactions.
@@ -51,11 +53,17 @@ import com.mongodb.client.model.Projections;
* @currentRead The Core - Peter V. Brett
* @see org.springframework.transaction.annotation.Transactional
*/
-@RunWith(SpringRunner.class)
-@ContextConfiguration
+@Testcontainers
+@ExtendWith(SpringExtension.class)
public class TransitionServiceTests {
- public static @ClassRule EmbeddedMongo replSet = EmbeddedMongo.replSet().configure();
+ @Container //
+ private static MongoDBContainer mongoDBContainer = MongoContainers.getDefaultContainer();
+
+ @DynamicPropertySource
+ static void setProperties(DynamicPropertyRegistry registry) {
+ registry.add("spring.data.mongodb.uri", mongoDBContainer::getReplicaSetUrl);
+ }
static final String DB_NAME = "spring-data-tx-examples";
@@ -73,10 +81,9 @@ public class TransitionServiceTests {
return new MongoTransactionManager(dbFactory);
}
- @Override
@Bean
public MongoClient mongoClient() {
- return replSet.getMongoClient();
+ return MongoClients.create(mongoDBContainer.getReplicaSetUrl());
}
@Override
@@ -110,5 +117,4 @@ public class TransitionServiceTests {
return State.valueOf(client.getDatabase(DB_NAME).getCollection("processes").find(Filters.eq("_id", process.id()))
.projection(Projections.include("state")).first().get("state", String.class));
}
-
}
diff --git a/mongodb/transactions/src/test/java/example/springdata/mongodb/reactive/ReactiveManagedTransitionServiceTests.java b/mongodb/transactions/src/test/java/example/springdata/mongodb/reactive/ReactiveManagedTransitionServiceTests.java
index b7f2ff5c..4ccddc9e 100644
--- a/mongodb/transactions/src/test/java/example/springdata/mongodb/reactive/ReactiveManagedTransitionServiceTests.java
+++ b/mongodb/transactions/src/test/java/example/springdata/mongodb/reactive/ReactiveManagedTransitionServiceTests.java
@@ -17,16 +17,14 @@ package example.springdata.mongodb.reactive;
import static org.assertj.core.api.Assertions.*;
+import com.mongodb.reactivestreams.client.MongoClients;
import example.springdata.mongodb.Process;
+import com.mongodb.reactivestreams.client.MongoClient;
import example.springdata.mongodb.State;
-import example.springdata.mongodb.util.EmbeddedMongo;
-import reactor.core.publisher.Flux;
-import reactor.test.StepVerifier;
-
+import example.springdata.mongodb.util.MongoContainers;
import org.bson.Document;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
@@ -35,13 +33,16 @@ import org.springframework.data.mongodb.ReactiveMongoDatabaseFactory;
import org.springframework.data.mongodb.ReactiveMongoTransactionManager;
import org.springframework.data.mongodb.config.AbstractReactiveMongoConfiguration;
import org.springframework.data.mongodb.repository.config.EnableReactiveMongoRepositories;
-import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.context.DynamicPropertyRegistry;
+import org.springframework.test.context.DynamicPropertySource;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.transaction.ReactiveTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
-
-import com.mongodb.reactivestreams.client.MongoClient;
-import com.mongodb.reactivestreams.client.MongoClients;
+import org.testcontainers.containers.MongoDBContainer;
+import org.testcontainers.junit.jupiter.Container;
+import org.testcontainers.junit.jupiter.Testcontainers;
+import reactor.core.publisher.Flux;
+import reactor.test.StepVerifier;
/**
* Test showing MongoDB Transaction usage through a reactive API.
@@ -49,11 +50,17 @@ import com.mongodb.reactivestreams.client.MongoClients;
* @author Christoph Strobl
* @currentRead The Core - Peter V. Brett
*/
-@RunWith(SpringRunner.class)
-@ContextConfiguration
+@Testcontainers
+@ExtendWith(SpringExtension.class)
public class ReactiveManagedTransitionServiceTests {
- public static @ClassRule EmbeddedMongo replSet = EmbeddedMongo.replSet().configure();
+ @Container //
+ private static MongoDBContainer mongoDBContainer = MongoContainers.getDefaultContainer();
+
+ @DynamicPropertySource
+ static void setProperties(DynamicPropertyRegistry registry) {
+ registry.add("spring.data.mongodb.uri", mongoDBContainer::getReplicaSetUrl);
+ }
@Autowired ReactiveManagedTransitionService managedTransitionService;
@Autowired MongoClient client;
@@ -74,7 +81,7 @@ public class ReactiveManagedTransitionServiceTests {
@Bean
@Override
public MongoClient reactiveMongoClient() {
- return MongoClients.create(replSet.getConnectionString());
+ return MongoClients.create(mongoDBContainer.getReplicaSetUrl());
}
@Override
diff --git a/mongodb/transactions/src/test/java/example/springdata/mongodb/reactive/ReactiveTransitionServiceTests.java b/mongodb/transactions/src/test/java/example/springdata/mongodb/reactive/ReactiveTransitionServiceTests.java
deleted file mode 100644
index 3a01446f..00000000
--- a/mongodb/transactions/src/test/java/example/springdata/mongodb/reactive/ReactiveTransitionServiceTests.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright 2018-2021 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 example.springdata.mongodb.reactive;
-
-import static org.assertj.core.api.Assertions.*;
-
-import example.springdata.mongodb.Process;
-import example.springdata.mongodb.State;
-import example.springdata.mongodb.util.EmbeddedMongo;
-import reactor.core.publisher.Flux;
-import reactor.test.StepVerifier;
-
-import org.bson.Document;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.ComponentScan;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.data.mongodb.config.AbstractReactiveMongoConfiguration;
-import org.springframework.data.mongodb.repository.config.EnableReactiveMongoRepositories;
-import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.junit4.SpringRunner;
-
-import com.mongodb.reactivestreams.client.MongoClient;
-import com.mongodb.reactivestreams.client.MongoClients;
-
-/**
- * Test showing MongoDB Transaction usage through a reactive API.
- *
- * @author Christoph Strobl
- * @currentRead The Core - Peter V. Brett
- */
-@RunWith(SpringRunner.class)
-@ContextConfiguration
-public class ReactiveTransitionServiceTests {
-
- public static @ClassRule EmbeddedMongo replSet = EmbeddedMongo.replSet().configure();
-
- @Autowired ReactiveTransitionService transitionService;
- @Autowired MongoClient client;
-
- static final String DB_NAME = "spring-data-reactive-tx-examples";
-
- @Configuration
- @ComponentScan
- @EnableReactiveMongoRepositories
- static class Config extends AbstractReactiveMongoConfiguration {
-
- @Bean
- @Override
- public MongoClient reactiveMongoClient() {
- return MongoClients.create(replSet.getConnectionString());
- }
-
- @Override
- protected String getDatabaseName() {
- return DB_NAME;
- }
- }
-
- @Test
- public void reactiveTxCommitRollback() {
-
- for (var i = 0; i < 10; i++) {
- transitionService.newProcess() //
- .map(Process::id) //
- .flatMap(transitionService::run) //
- .onErrorReturn(-1).as(StepVerifier::create) //
- .consumeNextWith(val -> {}) //
- .verifyComplete();
- }
-
- Flux.from(client.getDatabase(DB_NAME).getCollection("processes").find(new Document())) //
- .buffer(10) //
- .as(StepVerifier::create) //
- .consumeNextWith(list -> {
-
- for (var document : list) {
-
- System.out.println("document: " + document);
-
- if (document.getInteger("_id") % 3 == 0) {
- assertThat(document.getString("state")).isEqualTo(State.CREATED.toString());
- } else {
- assertThat(document.getString("state")).isEqualTo(State.DONE.toString());
- }
- }
-
- }) //
- .verifyComplete();
- }
-}
diff --git a/mongodb/transactions/src/test/resources/application.properties b/mongodb/transactions/src/test/resources/application.properties
new file mode 100644
index 00000000..50904a88
--- /dev/null
+++ b/mongodb/transactions/src/test/resources/application.properties
@@ -0,0 +1 @@
+spring.data.mongodb.database=spring-data-tx-examples