66import lombok .extern .slf4j .Slf4j ;
77import org .testcontainers .containers .wait .strategy .Wait ;
88import org .testcontainers .utility .DockerImageName ;
9+ import org .testcontainers .utility .MountableFile ;
910
1011import java .io .IOException ;
1112
@@ -29,6 +30,10 @@ public class MongoDBContainer extends GenericContainer<MongoDBContainer> {
2930
3031 private static final String MONGODB_DATABASE_NAME_DEFAULT = "test" ;
3132
33+ private static final String STARTER_SCRIPT = "/testcontainers_start.sh" ;
34+
35+ private boolean shardingEnabled ;
36+
3237 /**
3338 * @deprecated use {@link MongoDBContainer(DockerImageName)} instead
3439 */
@@ -46,8 +51,44 @@ public MongoDBContainer(final DockerImageName dockerImageName) {
4651 dockerImageName .assertCompatibleWith (DEFAULT_IMAGE_NAME );
4752
4853 withExposedPorts (MONGODB_INTERNAL_PORT );
49- withCommand ("--replSet" , "docker-rs" );
50- waitingFor (Wait .forLogMessage ("(?i).*waiting for connections.*" , 1 ));
54+ }
55+
56+ @ Override
57+ public void configure () {
58+ if (shardingEnabled ) {
59+ withCreateContainerCmdModifier (cmd -> {
60+ cmd .withEntrypoint ("sh" );
61+ });
62+ withCommand ("-c" , "while [ ! -f " + STARTER_SCRIPT + " ]; do sleep 0.1; done; " + STARTER_SCRIPT );
63+ waitingFor (Wait .forLogMessage ("(?i).*mongos ready.*" , 1 ));
64+ } else {
65+ withCommand ("--replSet" , "docker-rs" );
66+ waitingFor (Wait .forLogMessage ("(?i).*waiting for connections.*" , 1 ));
67+ }
68+ }
69+
70+ @ Override
71+ protected void containerIsStarting (InspectContainerResponse containerInfo ) {
72+ if (shardingEnabled ) {
73+ copyFileToContainer (MountableFile .forClasspathResource ("/sharding.sh" , 0777 ), STARTER_SCRIPT );
74+ }
75+ }
76+
77+ /**
78+ * Enables sharding on the cluster
79+ *
80+ * @return this
81+ */
82+ public MongoDBContainer withSharding () {
83+ this .shardingEnabled = true ;
84+ return this ;
85+ }
86+
87+ @ Override
88+ protected void containerIsStarted (InspectContainerResponse containerInfo , boolean reused ) {
89+ if (!shardingEnabled ) {
90+ initReplicaSet (reused );
91+ }
5192 }
5293
5394 /**
@@ -81,15 +122,6 @@ public String getReplicaSetUrl(final String databaseName) {
81122 return getConnectionString () + "/" + databaseName ;
82123 }
83124
84- @ Override
85- protected void containerIsStarted (InspectContainerResponse containerInfo , boolean reused ) {
86- if (reused && isReplicationSetAlreadyInitialized ()) {
87- log .debug ("Replica set already initialized." );
88- } else {
89- initReplicaSet ();
90- }
91- }
92-
93125 private String [] buildMongoEvalCommand (final String command ) {
94126 return new String [] {
95127 "sh" ,
@@ -133,20 +165,24 @@ private void checkMongoNodeExitCodeAfterWaiting(final Container.ExecResult execR
133165 }
134166
135167 @ SneakyThrows (value = { IOException .class , InterruptedException .class })
136- private void initReplicaSet () {
137- log .debug ("Initializing a single node node replica set..." );
138- final ExecResult execResultInitRs = execInContainer (buildMongoEvalCommand ("rs.initiate();" ));
139- log .debug (execResultInitRs .getStdout ());
140- checkMongoNodeExitCode (execResultInitRs );
141-
142- log .debug (
143- "Awaiting for a single node replica set initialization up to {} attempts" ,
144- AWAIT_INIT_REPLICA_SET_ATTEMPTS
145- );
146- final ExecResult execResultWaitForMaster = execInContainer (buildMongoEvalCommand (buildMongoWaitCommand ()));
147- log .debug (execResultWaitForMaster .getStdout ());
168+ private void initReplicaSet (boolean reused ) {
169+ if (reused && isReplicationSetAlreadyInitialized ()) {
170+ log .debug ("Replica set already initialized." );
171+ } else {
172+ log .debug ("Initializing a single node node replica set..." );
173+ final ExecResult execResultInitRs = execInContainer (buildMongoEvalCommand ("rs.initiate();" ));
174+ log .debug (execResultInitRs .getStdout ());
175+ checkMongoNodeExitCode (execResultInitRs );
148176
149- checkMongoNodeExitCodeAfterWaiting (execResultWaitForMaster );
177+ log .debug (
178+ "Awaiting for a single node replica set initialization up to {} attempts" ,
179+ AWAIT_INIT_REPLICA_SET_ATTEMPTS
180+ );
181+ final ExecResult execResultWaitForMaster = execInContainer (buildMongoEvalCommand (buildMongoWaitCommand ()));
182+ log .debug (execResultWaitForMaster .getStdout ());
183+
184+ checkMongoNodeExitCodeAfterWaiting (execResultWaitForMaster );
185+ }
150186 }
151187
152188 public static class ReplicaSetInitializationException extends RuntimeException {
0 commit comments