1
1
package org .testcontainers .containers ;
2
2
3
3
import com .github .dockerjava .api .command .InspectContainerResponse ;
4
- import io .tarantool .driver .exceptions .TarantoolConnectionException ;
5
4
6
5
import org .testcontainers .containers .exceptions .CartridgeTopologyException ;
7
6
import org .testcontainers .images .builder .ImageFromDockerfile ;
12
11
import java .util .HashMap ;
13
12
import java .util .List ;
14
13
import java .util .Map ;
15
- import java .util .concurrent .CompletableFuture ;
16
14
import java .util .concurrent .ExecutionException ;
17
15
import java .util .concurrent .TimeoutException ;
18
16
import java .util .function .Supplier ;
82
80
* specified in the http_port options, will be exposed.
83
81
*
84
82
* @author Alexey Kuzin
83
+ * @authorm Artyom Dubinin
84
+ * @author Ivan Dneprov
85
+ *
85
86
*/
86
87
public class TarantoolCartridgeContainer extends GenericContainer <TarantoolCartridgeContainer >
87
88
implements TarantoolContainerOperations <TarantoolCartridgeContainer > {
@@ -119,6 +120,7 @@ public class TarantoolCartridgeContainer extends GenericContainer<TarantoolCartr
119
120
private String directoryResourcePath = SCRIPT_RESOURCE_DIRECTORY ;
120
121
private String instanceDir = INSTANCE_DIR ;
121
122
private String topologyConfigurationFile ;
123
+ private SslContext sslContext ;
122
124
123
125
/**
124
126
* Create a container with default image and specified instances file from the classpath resources. Assumes that
@@ -186,8 +188,24 @@ public TarantoolCartridgeContainer(String dockerFile, String buildImageName,
186
188
*/
187
189
public TarantoolCartridgeContainer (String dockerFile , String buildImageName , String instancesFile ,
188
190
String topologyConfigurationFile , final Map <String , String > buildArgs ) {
189
- this (buildImage (dockerFile , buildImageName ), instancesFile , topologyConfigurationFile , buildArgs );
190
- }
191
+ this (buildImage (dockerFile , buildImageName , buildArgs ), instancesFile , topologyConfigurationFile , buildArgs );
192
+ }
193
+
194
+ // todo add SSL and mTLS cartridge test
195
+ // /**
196
+ // * Create a container with specified image and specified instances file from the classpath resources. By providing
197
+ // * the result Cartridge container image name, you can cache the image and avoid rebuilding on each test run (the
198
+ // * image is tagged with the provided name and not deleted after tests finishing).
199
+ // *
200
+ // * @param tarantoolImageParams params for cached image creating
201
+ // * @param instancesFile URL resource path to instances.yml relative in the classpath
202
+ // * @param topologyConfigurationFile URL resource path to a topology bootstrap script in the classpath
203
+ // */
204
+ // public TarantoolCartridgeContainer(TarantoolImageParams tarantoolImageParams, String instancesFile,
205
+ // String topologyConfigurationFile) {
206
+ // this(new ImageFromDockerfile(TarantoolContainerImageHelper.getImage(tarantoolImageParams)), instancesFile,
207
+ // topologyConfigurationFile, tarantoolImageParams.getBuildArgs());
208
+ // }
191
209
192
210
private TarantoolCartridgeContainer (ImageFromDockerfile image , String instancesFile , String topologyConfigurationFile ,
193
211
Map <String , String > buildArgs ) {
@@ -238,13 +256,32 @@ private static Map<String, String> mergeBuildArguments(Map<String, String> build
238
256
return args ;
239
257
}
240
258
241
- private static ImageFromDockerfile buildImage (String dockerFile , String buildImageName ) {
259
+ private static ImageFromDockerfile buildImage (String dockerFile , String buildImageName ,
260
+ final Map <String , String > buildArgs ) {
261
+ ImageFromDockerfile image ;
242
262
if (buildImageName != null && !buildImageName .isEmpty ()) {
243
- return new ImageFromDockerfile (buildImageName , false )
244
- .withFileFromClasspath ("Dockerfile" , dockerFile );
263
+ image = new ImageFromDockerfile (buildImageName , false );
264
+ } else {
265
+ image = new ImageFromDockerfile ();
245
266
}
246
- return new ImageFromDockerfile ().withFileFromClasspath ("Dockerfile" , dockerFile );
247
- }
267
+ return image .withFileFromClasspath ("Dockerfile" , dockerFile )
268
+ .withFileFromClasspath ("cartridge" , buildArgs .get ("CARTRIDGE_SRC_DIR" ) == null ?
269
+ "cartridge" : buildArgs .get ("CARTRIDGE_SRC_DIR" ));
270
+ }
271
+
272
+ // todo add SSL and mTLS cartridge test
273
+ // /**
274
+ // * Specify SSL as connection transport. And path to key and cert files inside your container for mTLS connection
275
+ // * Warning! SSL must be set as default transport on your tarantool cluster.
276
+ // * Supported only in Tarantool Enterprise
277
+ // *
278
+ // * @return this container instance
279
+ // */
280
+ // public TarantoolCartridgeContainer withSslContext(SslContext sslContext) {
281
+ // checkNotRunning();
282
+ // this.sslContext = sslContext;
283
+ // return this;
284
+ // }
248
285
249
286
/**
250
287
* Get the router host
@@ -328,6 +365,11 @@ public String getInstanceDir() {
328
365
return instanceDir ;
329
366
}
330
367
368
+ @ Override
369
+ public int getInternalPort () {
370
+ return routerPort ;
371
+ }
372
+
331
373
/**
332
374
* Get Cartridge router HTTP API hostname
333
375
*
@@ -475,7 +517,7 @@ private boolean setupTopology() {
475
517
.substring (topologyConfigurationFile .lastIndexOf ('/' ) + 1 );
476
518
477
519
try {
478
- Container . ExecResult result = execInContainer ("cartridge" ,
520
+ ExecResult result = execInContainer ("cartridge" ,
479
521
"replicasets" ,
480
522
"--run-dir=" + TARANTOOL_RUN_DIR ,
481
523
"--file=" + replicasetsFileName , "setup" , "--bootstrap-vshard" );
@@ -489,7 +531,7 @@ private boolean setupTopology() {
489
531
490
532
} else {
491
533
try {
492
- List <?> res = executeScript (topologyConfigurationFile ). get ( );
534
+ List <?> res = executeScriptDecoded (topologyConfigurationFile );
493
535
if (res .size () >= 2 && res .get (1 ) != null && res .get (1 ) instanceof Map ) {
494
536
HashMap <?, ?> error = ((HashMap <?, ?>) res .get (1 ));
495
537
// that means topology already exists
@@ -501,10 +543,6 @@ private boolean setupTopology() {
501
543
if (e .getCause () instanceof TimeoutException ) {
502
544
return true ;
503
545
// Do nothing, the cluster is reloading
504
- } else if (e .getCause () instanceof TarantoolConnectionException ) {
505
- // Probably cluster is not ready
506
- logger ().error ("Failed to setup topology: {}" , e .getMessage ());
507
- return false ;
508
546
}
509
547
} else {
510
548
throw new CartridgeTopologyException (e );
@@ -530,7 +568,7 @@ private void retryingSetupTopology() {
530
568
531
569
private void bootstrapVshard () {
532
570
try {
533
- executeCommand (VSHARD_BOOTSTRAP_COMMAND ). get () ;
571
+ executeCommand (VSHARD_BOOTSTRAP_COMMAND );
534
572
} catch (Exception e ) {
535
573
logger ().error ("Failed to bootstrap vshard cluster" , e );
536
574
throw new RuntimeException (e );
@@ -580,8 +618,8 @@ private boolean routerIsUp() {
580
618
String healthyCmd = " local cartridge = package.loaded['cartridge']" +
581
619
" return assert(cartridge ~= nil)" ;
582
620
try {
583
- List <?> result = executeCommand (healthyCmd ). get ( );
584
- return ( Boolean ) result . get ( 0 );
621
+ ExecResult result = executeCommand (healthyCmd );
622
+ return result . getStdout (). equals ( "--- \n - true \n ... \n \n " );
585
623
} catch (Exception e ) {
586
624
logger ().warn ("Error while waiting for router instance to be up: " + e .getMessage ());
587
625
return false ;
@@ -592,21 +630,31 @@ private boolean isCartridgeHealthy() {
592
630
String healthyCmd = " local cartridge = package.loaded['cartridge']" +
593
631
" return assert(cartridge) and assert(cartridge.is_healthy())" ;
594
632
try {
595
- List <?> result = executeCommand (healthyCmd ). get ( );
596
- return ( Boolean ) result . get ( 0 );
633
+ ExecResult result = executeCommand (healthyCmd );
634
+ return result . getStdout (). equals ( "--- \n - true \n ... \n \n " );
597
635
} catch (Exception e ) {
598
636
logger ().warn ("Error while waiting for cartridge healthy state: " + e .getMessage ());
599
637
return false ;
600
638
}
601
639
}
602
640
603
641
@ Override
604
- public CompletableFuture <List <?>> executeScript (String scriptResourcePath ) throws Exception {
605
- return clientHelper .executeScript (scriptResourcePath );
642
+ public ExecResult executeScript (String scriptResourcePath ) throws Exception {
643
+ return clientHelper .executeScript (scriptResourcePath , this .sslContext );
644
+ }
645
+
646
+ @ Override
647
+ public <T > T executeScriptDecoded (String scriptResourcePath ) throws Exception {
648
+ return clientHelper .executeScriptDecoded (scriptResourcePath , this .sslContext );
649
+ }
650
+
651
+ @ Override
652
+ public ExecResult executeCommand (String command ) throws Exception {
653
+ return clientHelper .executeCommand (command , this .sslContext );
606
654
}
607
655
608
656
@ Override
609
- public CompletableFuture < List <?>> executeCommand (String command , Object ... arguments ) throws Exception {
610
- return clientHelper .executeCommand (command , arguments );
657
+ public < T > T executeCommandDecoded (String command ) throws Exception {
658
+ return clientHelper .executeCommandDecoded (command , this . sslContext );
611
659
}
612
660
}
0 commit comments