11package com .redis .testcontainers ;
22
3- import java .io .IOException ;
4- import java .nio .charset .StandardCharsets ;
53import java .util .Objects ;
64
75import org .slf4j .Logger ;
86import org .slf4j .LoggerFactory ;
9- import org .testcontainers .DockerClientFactory ;
10- import org .testcontainers .containers .ContainerLaunchException ;
11- import org .testcontainers .containers .GenericContainer ;
12- import org .testcontainers .containers .output .FrameConsumerResultCallback ;
13- import org .testcontainers .containers .output .OutputFrame ;
14- import org .testcontainers .containers .output .ToStringConsumer ;
15- import org .testcontainers .containers .wait .strategy .Wait ;
16- import org .testcontainers .shaded .org .apache .commons .lang3 .ClassUtils ;
177import org .testcontainers .utility .DockerImageName ;
18- import org .testcontainers .utility .TestEnvironment ;
198
20- import com .github .dockerjava .api .DockerClient ;
21- import com .github .dockerjava .api .command .ExecCreateCmdResponse ;
22- import com .github .dockerjava .api .command .InspectContainerResponse ;
23- import com .github .dockerjava .api .command .InspectExecResponse ;
24- import com .github .dockerjava .api .exception .DockerException ;
259import com .redis .enterprise .Admin ;
2610import com .redis .enterprise .Database ;
2711import com .redis .enterprise .RedisModule ;
2812
29- public class RedisEnterpriseContainer extends GenericContainer <RedisEnterpriseContainer > implements RedisServer {
13+ public class RedisEnterpriseContainer extends AbstractRedisEnterpriseContainer <RedisEnterpriseContainer > {
3014
31- public static final DockerImageName DEFAULT_IMAGE_NAME = DockerImageName .parse ("redislabs/redis" );
32- public static final String DEFAULT_TAG = "latest" ;
3315 public static final int DEFAULT_DATABASE_SHARD_COUNT = 2 ;
3416 public static final int DEFAULT_DATABASE_PORT = 12000 ;
3517 public static final String DEFAULT_DATABASE_NAME = "testcontainers" ;
3618 public static final RedisModule [] DEFAULT_DATABASE_MODULES = { RedisModule .JSON , RedisModule .SEARCH ,
3719 RedisModule .TIMESERIES , RedisModule .BLOOM };
3820
3921 private static final Logger log = LoggerFactory .getLogger (RedisEnterpriseContainer .class );
40- private static final String NODE_EXTERNAL_ADDR = "0.0.0.0" ;
41- private static final String RLADMIN = "/opt/redislabs/bin/rladmin" ;
42- private static final Long EXIT_CODE_SUCCESS = 0L ;
43- private static final int WEB_UI_PORT = 8443 ;
4422
23+ private final Admin admin = new Admin ();
4524 private Database database = defaultDatabase ();
4625
4726 public static Database defaultDatabase () {
@@ -50,17 +29,11 @@ public static Database defaultDatabase() {
5029 }
5130
5231 public RedisEnterpriseContainer (String dockerImageName ) {
53- this ( DockerImageName . parse ( dockerImageName ) );
32+ super ( dockerImageName );
5433 }
5534
5635 public RedisEnterpriseContainer (final DockerImageName dockerImageName ) {
5736 super (dockerImageName );
58- addFixedExposedPort (Admin .DEFAULT_PORT , Admin .DEFAULT_PORT );
59- addFixedExposedPort (WEB_UI_PORT , WEB_UI_PORT );
60- addFixedExposedPort (database .getPort (), database .getPort ());
61- withPrivilegedMode (true );
62- waitingFor (Wait .forLogMessage (".*success: job_scheduler entered RUNNING state, process has stayed up for.*\\ n" ,
63- 1 ));
6437 }
6538
6639 public Database getDatabase () {
@@ -75,94 +48,36 @@ public RedisEnterpriseContainer withDatabase(Database database) {
7548 return this ;
7649 }
7750
78- private Admin admin () {
79- Admin admin = new Admin ();
80- admin .withHost (getRedisHost ());
81- return admin ;
82- }
83-
8451 @ Override
85- protected void containerIsStarted (InspectContainerResponse containerInfo ) {
86- super .containerIsStarted (containerInfo );
87- try (Admin admin = admin ()) {
88- log .info ("Waiting for cluster bootstrap" );
89- admin .waitForBoostrap ();
90- createCluster ();
91- Database response = admin .createDatabase (database );
92- log .info ("Created database {} with UID {}" , response .getName (), response .getUid ());
93- } catch (Exception e ) {
94- throw new ContainerLaunchException ("Could not initialize Redis Enterprise container" , e );
95- }
96- }
97-
98- private void createCluster () {
99- log .info ("Creating cluster" );
100- if (!TestEnvironment .dockerExecutionDriverSupportsExec ()) {
101- // at time of writing, this is the expected result in CircleCI.
102- throw new UnsupportedOperationException (
103- "Your docker daemon is running the \" lxc\" driver, which doesn't support \" docker exec\" ." );
104- }
105-
106- InspectContainerResponse containerInfo = getContainerInfo ();
107- if (!isRunning (containerInfo )) {
108- throw new IllegalStateException ("execInContainer can only be used while the Container is running" );
109- }
110-
111- String containerId = containerInfo .getId ();
112- String containerName = containerInfo .getName ();
113-
114- DockerClient dockerClient = DockerClientFactory .instance ().client ();
115-
116- String [] commands = new String [] { RLADMIN , "cluster" , "create" , "name" , "cluster.local" , "username" ,
117- Admin .DEFAULT_USER_NAME , "password" , Admin .DEFAULT_PASSWORD , "external_addr" , NODE_EXTERNAL_ADDR };
118- log .debug ("{}: Running \" exec\" command: {}" , containerName , commands );
119- final ExecCreateCmdResponse execCreateCmdResponse = dockerClient .execCreateCmd (containerId )
120- .withAttachStdout (true ).withAttachStderr (true ).withCmd (commands ).withPrivileged (true ).exec ();
121-
122- final ToStringConsumer stdoutConsumer = new ToStringConsumer ();
123- final ToStringConsumer stderrConsumer = new ToStringConsumer ();
124-
125- try (FrameConsumerResultCallback callback = new FrameConsumerResultCallback ()) {
126- callback .addConsumer (OutputFrame .OutputType .STDOUT , stdoutConsumer );
127- callback .addConsumer (OutputFrame .OutputType .STDERR , stderrConsumer );
128- dockerClient .execStartCmd (execCreateCmdResponse .getId ()).exec (callback ).awaitCompletion ();
129- InspectExecResponse execResponse = dockerClient .inspectExecCmd (execCreateCmdResponse .getId ()).exec ();
130- if (EXIT_CODE_SUCCESS .equals (execResponse .getExitCodeLong ())) {
131- return ;
132- }
133- if (log .isErrorEnabled ()) {
134- log .error ("Could not create cluster: {}" , stderrConsumer .toString (StandardCharsets .UTF_8 ));
135- }
136- throw new ContainerLaunchException ("Could not create cluster" );
137- } catch (InterruptedException e ) {
138- Thread .currentThread ().interrupt ();
139- throw new ContainerLaunchException ("Could not create cluster" , e );
140- } catch (IOException e ) {
141- log .error ("Could not close result callback" , e );
142- }
52+ protected String getAdminUserName () {
53+ return admin .getUserName ();
14354 }
14455
14556 @ Override
146- public boolean isRedisCluster () {
147- return database . isOssCluster ();
57+ protected String getAdminPassword () {
58+ return admin . getPassword ();
14859 }
14960
15061 @ Override
151- public String toString () {
152- return ClassUtils .getShortClassName (RedisEnterpriseContainer .class );
62+ protected void doStart () {
63+ admin .withHost (getHost ());
64+ addFixedExposedPort (admin .getPort (), admin .getPort ());
65+ addFixedExposedPort (database .getPort (), database .getPort ());
66+ super .doStart ();
15367 }
15468
155- private boolean isRunning (InspectContainerResponse containerInfo ) {
156- try {
157- return containerInfo != null && Boolean .TRUE .equals (containerInfo .getState ().getRunning ());
158- } catch (DockerException e ) {
159- return false ;
160- }
69+ @ Override
70+ protected void createCluster () throws Exception {
71+ log .info ("Waiting for cluster bootstrap" );
72+ admin .waitForBoostrap ();
73+ super .createCluster ();
74+ Database response = admin .createDatabase (database );
75+ log .info ("Created database {} with UID {}" , response .getName (), response .getUid ());
16176 }
16277
16378 @ Override
164- public String getRedisHost () {
165- return getHost ();
79+ public boolean isRedisCluster () {
80+ return database . isOssCluster ();
16681 }
16782
16883 @ Override
0 commit comments