11/*
2- * Copyright 2002-2021 the original author or authors.
2+ * Copyright 2020-2022 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.
1414 * limitations under the License.
1515 */
1616
17- package org .springframework .integration .mongodb . rules ;
17+ package org .springframework .integration .mongodb ;
1818
1919import java .time .Duration ;
2020
2121import org .bson .Document ;
2222import org .bson .UuidRepresentation ;
2323import org .bson .conversions .Bson ;
24- import org .junit .Rule ;
24+ import org .junit .jupiter .api .BeforeAll ;
25+ import org .testcontainers .containers .GenericContainer ;
26+ import org .testcontainers .junit .jupiter .Testcontainers ;
2527
2628import org .springframework .dao .DataAccessException ;
2729import org .springframework .data .annotation .Id ;
4042import org .springframework .integration .mongodb .outbound .MessageCollectionCallback ;
4143import org .springframework .messaging .Message ;
4244
45+ import com .mongodb .ConnectionString ;
4346import com .mongodb .MongoClientSettings ;
4447import com .mongodb .MongoException ;
4548import com .mongodb .client .MongoClients ;
4649import com .mongodb .client .MongoCollection ;
4750
48-
4951/**
50- * Convenience base class that enables unit test methods to rely upon the {@link MongoDbAvailable} annotation.
52+ * The base contract for all tests requiring a MongoDb connection.
53+ * The Testcontainers 'reuse' option must be disabled, so, Ryuk container is started
54+ * and will clean all the containers up from this test suite after JVM exit.
55+ * Since the Redis container instance is shared via static property, it is going to be
56+ * started only once per JVM, therefore the target Docker container is reused automatically.
5157 *
5258 * @author Oleg Zhurakousky
5359 * @author Xavier Padro
5460 * @author Artem Bilan
5561 * @author David Turanski
62+ * @author Artem Vozhdayenko
5663 *
57- * @since 2.1
64+ * @since 6.0
5865 */
59- public abstract class MongoDbAvailableTests {
60-
61- @ Rule
62- public MongoDbAvailableRule mongoDbAvailableRule = new MongoDbAvailableRule ();
63-
64- public static final MongoDatabaseFactory MONGO_DATABASE_FACTORY =
65- new SimpleMongoClientDatabaseFactory (
66- MongoClients .create (
67- MongoClientSettings .builder ().uuidRepresentation (UuidRepresentation .STANDARD ).build ()),
68- "test" );
69-
70- public static final ReactiveMongoDatabaseFactory REACTIVE_MONGO_DATABASE_FACTORY =
71- new SimpleReactiveMongoDatabaseFactory (
72- com .mongodb .reactivestreams .client .MongoClients .create (
73- MongoClientSettings .builder ().uuidRepresentation (UuidRepresentation .STANDARD ).build ()),
74- "test" );
75-
76- protected MongoDatabaseFactory prepareMongoFactory (String ... additionalCollectionsToDrop ) {
77- cleanupCollections (MONGO_DATABASE_FACTORY , additionalCollectionsToDrop );
78- return MONGO_DATABASE_FACTORY ;
66+ @ Testcontainers (disabledWithoutDocker = true )
67+ public interface MongoDbContainerTest {
68+
69+ GenericContainer <?> MONGO_CONTAINER = new GenericContainer <>("mongo:5.0.9" )
70+ .withExposedPorts (27017 );
71+
72+ @ BeforeAll
73+ static void startContainer () {
74+ MONGO_CONTAINER .start ();
75+ }
76+
77+ static MongoDatabaseFactory createMongoDbFactory () {
78+ return new SimpleMongoClientDatabaseFactory (MongoClients .create (getMongoClientSettings ()), "test" );
79+ }
80+
81+ static ReactiveMongoDatabaseFactory createReactiveMongoDbFactory () {
82+ return new SimpleReactiveMongoDatabaseFactory (
83+ com .mongodb .reactivestreams .client .MongoClients .create (getMongoClientSettings ()),
84+ "test" );
85+ }
86+
87+ private static MongoClientSettings getMongoClientSettings () {
88+ return MongoClientSettings .builder ()
89+ .applyConnectionString (new ConnectionString (
90+ "mongodb://localhost:" + MONGO_CONTAINER .getFirstMappedPort ()))
91+ .uuidRepresentation (UuidRepresentation .STANDARD ).build ();
92+ }
93+
94+ static void prepareMongoData (MongoDatabaseFactory mongoDatabaseFactory , String ... additionalCollectionsToDrop ) {
95+ cleanupCollections (mongoDatabaseFactory , additionalCollectionsToDrop );
7996 }
8097
81- protected ReactiveMongoDatabaseFactory prepareReactiveMongoFactory (String ... additionalCollectionsToDrop ) {
82- cleanupCollections (REACTIVE_MONGO_DATABASE_FACTORY , additionalCollectionsToDrop );
83- return REACTIVE_MONGO_DATABASE_FACTORY ;
98+ static void prepareReactiveMongoData (ReactiveMongoDatabaseFactory mongoDatabaseFactory , String ... additionalCollectionsToDrop ) {
99+ cleanupCollections (mongoDatabaseFactory , additionalCollectionsToDrop );
84100 }
85101
86- protected void cleanupCollections (ReactiveMongoDatabaseFactory mongoDbFactory ,
102+ static void cleanupCollections (ReactiveMongoDatabaseFactory mongoDbFactory ,
87103 String ... additionalCollectionsToDrop ) {
88104
89105 ReactiveMongoTemplate template = new ReactiveMongoTemplate (mongoDbFactory );
@@ -95,7 +111,7 @@ protected void cleanupCollections(ReactiveMongoDatabaseFactory mongoDbFactory,
95111 }
96112 }
97113
98- protected void cleanupCollections (MongoDatabaseFactory mongoDbFactory , String ... additionalCollectionsToDrop ) {
114+ static void cleanupCollections (MongoDatabaseFactory mongoDbFactory , String ... additionalCollectionsToDrop ) {
99115 MongoTemplate template = new MongoTemplate (mongoDbFactory );
100116 template .dropCollection ("messages" );
101117 template .dropCollection ("configurableStoreMessages" );
@@ -105,7 +121,7 @@ protected void cleanupCollections(MongoDatabaseFactory mongoDbFactory, String...
105121 }
106122 }
107123
108- protected Person createPerson () {
124+ static Person createPerson () {
109125 Address address = new Address ();
110126 address .setCity ("Philadelphia" );
111127 address .setStreet ("2121 Rawn street" );
@@ -117,7 +133,7 @@ protected Person createPerson() {
117133 return person ;
118134 }
119135
120- protected Person createPerson (String name ) {
136+ static Person createPerson (String name ) {
121137 Address address = new Address ();
122138 address .setCity ("Philadelphia" );
123139 address .setStreet ("2121 Rawn street" );
@@ -129,7 +145,7 @@ protected Person createPerson(String name) {
129145 return person ;
130146 }
131147
132- public static class Person {
148+ class Person {
133149
134150 @ Id
135151 private String id ;
@@ -156,7 +172,7 @@ public void setName(String name) {
156172
157173 }
158174
159- public static class Address {
175+ class Address {
160176
161177 private String street ;
162178
@@ -190,7 +206,7 @@ public void setState(String state) {
190206
191207 }
192208
193- public static class TestMongoConverter extends MappingMongoConverter {
209+ class TestMongoConverter extends MappingMongoConverter {
194210
195211 public TestMongoConverter (
196212 MongoDatabaseFactory mongoDbFactory ,
@@ -211,7 +227,7 @@ public <S> S read(Class<S> clazz, Bson source) {
211227
212228 }
213229
214- public static class ReactiveTestMongoConverter extends MappingMongoConverter {
230+ class ReactiveTestMongoConverter extends MappingMongoConverter {
215231
216232 public ReactiveTestMongoConverter (
217233 ReactiveMongoDatabaseFactory mongoDbFactory ,
@@ -232,7 +248,7 @@ public <S> S read(Class<S> clazz, Bson source) {
232248
233249 }
234250
235- public static class TestCollectionCallback implements MessageCollectionCallback <Long > {
251+ class TestCollectionCallback implements MessageCollectionCallback <Long > {
236252
237253 @ Override
238254 public Long doInCollection (MongoCollection <Document > collection , Message <?> message )
0 commit comments