Skip to content

Commit a0f5d00

Browse files
twillouerrnorth
authored andcommitted
Support legacy RabbitMQ configuration format (#1692)
see #1690
1 parent 137c510 commit a0f5d00

File tree

4 files changed

+161
-81
lines changed

4 files changed

+161
-81
lines changed

modules/rabbitmq/src/main/java/org/testcontainers/containers/RabbitMQContainer.java

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -346,16 +346,42 @@ public RabbitMQContainer withExchange(String name, String type, boolean autoDele
346346
}
347347

348348
/**
349-
* Overwrites the default RabbitMQ configuration file with the supplied one
349+
* Overwrites the default RabbitMQ configuration file with the supplied one.
350350
*
351-
* @param rabbitMQConf The rabbitmq.conf file to use
351+
* @param rabbitMQConf The rabbitmq.conf file to use (in sysctl format, don't forget empty line in the end of file)
352352
* @return This container.
353353
*/
354354
public RabbitMQContainer withRabbitMQConfig(MountableFile rabbitMQConf) {
355-
withEnv("RABBITMQ_CONFIG_FILE", "/etc/rabbitmq/rabbitmq-custom.conf");
355+
356+
return withRabbitMQConfigSysctl(rabbitMQConf);
357+
}
358+
359+
/**
360+
* Overwrites the default RabbitMQ configuration file with the supplied one.
361+
*
362+
* This function doesn't work with RabbitMQ < 3.7.
363+
*
364+
* This function and the Sysctl format is recommended for RabbitMQ >= 3.7
365+
*
366+
* @param rabbitMQConf The rabbitmq.config file to use (in sysctl format, don't forget empty line in the end of file)
367+
* @return This container.
368+
*/
369+
public RabbitMQContainer withRabbitMQConfigSysctl(MountableFile rabbitMQConf) {
370+
withEnv("RABBITMQ_CONFIG_FILE", "/etc/rabbitmq/rabbitmq-custom");
356371
return withCopyFileToContainer(rabbitMQConf, "/etc/rabbitmq/rabbitmq-custom.conf");
357372
}
358373

374+
/**
375+
* Overwrites the default RabbitMQ configuration file with the supplied one.
376+
*
377+
* @param rabbitMQConf The rabbitmq.config file to use (in erlang format)
378+
* @return This container.
379+
*/
380+
public RabbitMQContainer withRabbitMQConfigErlang(MountableFile rabbitMQConf) {
381+
withEnv("RABBITMQ_CONFIG_FILE", "/etc/rabbitmq/rabbitmq-custom.config");
382+
return withCopyFileToContainer(rabbitMQConf, "/etc/rabbitmq/rabbitmq-custom.config");
383+
}
384+
359385
@NotNull
360386
private String toJson(Map<String, Object> arguments) {
361387
try {

modules/rabbitmq/src/test/java/org/testcontainers/containers/RabbitMQContainerTest.java

Lines changed: 118 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,29 @@
11
package org.testcontainers.containers;
22

3+
import static org.assertj.core.api.Assertions.assertThat;
4+
import static org.assertj.core.api.Assertions.assertThatCode;
5+
import static org.testcontainers.containers.RabbitMQContainer.SslVerification.VERIFY_PEER;
6+
import static org.testcontainers.utility.MountableFile.forClasspathResource;
7+
38
import com.google.common.collect.ImmutableMap;
49
import com.google.common.collect.ImmutableSet;
510
import com.rabbitmq.client.Channel;
611
import com.rabbitmq.client.Connection;
712
import com.rabbitmq.client.ConnectionFactory;
8-
import org.junit.Test;
9-
import org.testcontainers.utility.MountableFile;
10-
11-
import javax.net.ssl.KeyManagerFactory;
12-
import javax.net.ssl.SSLContext;
13-
import javax.net.ssl.TrustManagerFactory;
1413
import java.io.File;
1514
import java.io.FileInputStream;
1615
import java.io.IOException;
17-
import java.security.*;
16+
import java.security.KeyManagementException;
17+
import java.security.KeyStore;
18+
import java.security.KeyStoreException;
19+
import java.security.NoSuchAlgorithmException;
20+
import java.security.UnrecoverableKeyException;
1821
import java.security.cert.CertificateException;
19-
20-
import static org.assertj.core.api.Assertions.assertThat;
21-
import static org.assertj.core.api.Assertions.assertThatCode;
22-
import static org.testcontainers.containers.RabbitMQContainer.SslVerification.VERIFY_PEER;
23-
import static org.testcontainers.utility.MountableFile.forClasspathResource;
22+
import javax.net.ssl.KeyManagerFactory;
23+
import javax.net.ssl.SSLContext;
24+
import javax.net.ssl.TrustManagerFactory;
25+
import org.junit.Test;
26+
import org.testcontainers.utility.MountableFile;
2427

2528
/**
2629
* @author Martin Greber
@@ -34,7 +37,8 @@ public class RabbitMQContainerTest {
3437
public static final int DEFAULT_HTTP_PORT = 15672;
3538

3639
@Test
37-
public void shouldCreateRabbitMQContainer() {
40+
public void shouldCreateRabbitMQContainer()
41+
{
3842
try (RabbitMQContainer container = new RabbitMQContainer()) {
3943

4044
assertThat(container.getDockerImageName()).isEqualTo(DEFAULT_IMAGE);
@@ -44,163 +48,199 @@ public void shouldCreateRabbitMQContainer() {
4448
container.start();
4549

4650
assertThat(container.getAmqpsUrl()).isEqualTo(
47-
String.format("amqps://%s:%d", container.getContainerIpAddress(), container.getMappedPort(DEFAULT_AMQPS_PORT)));
51+
String.format("amqps://%s:%d", container.getContainerIpAddress(), container.getMappedPort(DEFAULT_AMQPS_PORT)));
4852
assertThat(container.getAmqpUrl()).isEqualTo(
49-
String.format("amqp://%s:%d", container.getContainerIpAddress(), container.getMappedPort(DEFAULT_AMQP_PORT)));
53+
String.format("amqp://%s:%d", container.getContainerIpAddress(), container.getMappedPort(DEFAULT_AMQP_PORT)));
5054
assertThat(container.getHttpsUrl()).isEqualTo(
51-
String.format("https://%s:%d", container.getContainerIpAddress(), container.getMappedPort(DEFAULT_HTTPS_PORT)));
55+
String.format("https://%s:%d", container.getContainerIpAddress(), container.getMappedPort(DEFAULT_HTTPS_PORT)));
5256
assertThat(container.getHttpUrl()).isEqualTo(
53-
String.format("http://%s:%d", container.getContainerIpAddress(), container.getMappedPort(DEFAULT_HTTP_PORT)));
57+
String.format("http://%s:%d", container.getContainerIpAddress(), container.getMappedPort(DEFAULT_HTTP_PORT)));
5458

5559
assertThat(container.getHttpsPort()).isEqualTo(container.getMappedPort(DEFAULT_HTTPS_PORT));
5660
assertThat(container.getHttpPort()).isEqualTo(container.getMappedPort(DEFAULT_HTTP_PORT));
5761
assertThat(container.getAmqpsPort()).isEqualTo(container.getMappedPort(DEFAULT_AMQPS_PORT));
5862
assertThat(container.getAmqpPort()).isEqualTo(container.getMappedPort(DEFAULT_AMQP_PORT));
5963

6064
assertThat(container.getLivenessCheckPortNumbers()).containsExactlyInAnyOrder(
61-
container.getMappedPort(DEFAULT_AMQP_PORT),
62-
container.getMappedPort(DEFAULT_AMQPS_PORT),
63-
container.getMappedPort(DEFAULT_HTTP_PORT),
64-
container.getMappedPort(DEFAULT_HTTPS_PORT)
65+
container.getMappedPort(DEFAULT_AMQP_PORT),
66+
container.getMappedPort(DEFAULT_AMQPS_PORT),
67+
container.getMappedPort(DEFAULT_HTTP_PORT),
68+
container.getMappedPort(DEFAULT_HTTPS_PORT)
6569
);
6670
}
6771
}
6872

6973
@Test
70-
public void shouldCreateRabbitMQContainerWithTag() {
74+
public void shouldCreateRabbitMQContainerWithTag()
75+
{
7176
try (RabbitMQContainer container = new RabbitMQContainer(DEFAULT_IMAGE)) {
7277
assertThat(container.getDockerImageName()).isEqualTo(DEFAULT_IMAGE);
7378
}
7479
}
7580

7681
@Test
77-
public void shouldCreateRabbitMQContainerWithExchange() throws IOException, InterruptedException {
82+
public void shouldCreateRabbitMQContainerWithExchange() throws IOException, InterruptedException
83+
{
7884
try (RabbitMQContainer container = new RabbitMQContainer()) {
7985
container.withExchange("test-exchange", "direct");
8086

8187
container.start();
8288

8389
assertThat(container.execInContainer("rabbitmqctl", "list_exchanges").getStdout())
84-
.containsPattern("test-exchange\\s+direct");
90+
.containsPattern("test-exchange\\s+direct");
8591
}
8692
}
8793

8894
@Test
89-
public void shouldCreateRabbitMQContainerWithQueues() throws IOException, InterruptedException {
95+
public void shouldCreateRabbitMQContainerWithQueues() throws IOException, InterruptedException
96+
{
9097
try (RabbitMQContainer container = new RabbitMQContainer()) {
9198

9299
container.withQueue("queue-one")
93-
.withQueue("queue-two", false, true, ImmutableMap.of("x-message-ttl", 1000));
100+
.withQueue("queue-two", false, true, ImmutableMap.of("x-message-ttl", 1000));
94101

95102
container.start();
96103

97104
assertThat(container.execInContainer("rabbitmqctl", "list_queues", "name", "arguments").getStdout())
98-
.containsPattern("queue-one");
105+
.containsPattern("queue-one");
99106
assertThat(container.execInContainer("rabbitmqctl", "list_queues", "name", "arguments").getStdout())
100-
.containsPattern("queue-two\\s.*x-message-ttl");
107+
.containsPattern("queue-two\\s.*x-message-ttl");
108+
}
109+
}
110+
111+
@Test
112+
public void shouldMountConfigurationFile()
113+
{
114+
try (RabbitMQContainer container = new RabbitMQContainer()) {
115+
116+
container.withRabbitMQConfig(MountableFile.forClasspathResource("/rabbitmq-custom.conf"));
117+
container.start();
118+
119+
assertThat(container.getLogs()).contains("config file(s) : /etc/rabbitmq/rabbitmq-custom.conf");
120+
assertThat(container.getLogs()).doesNotContain(" (not found)");
101121
}
102122
}
103123

124+
125+
@Test
126+
public void shouldMountConfigurationFileErlang()
127+
{
128+
try (RabbitMQContainer container = new RabbitMQContainer()) {
129+
130+
container.withRabbitMQConfigErlang(MountableFile.forClasspathResource("/rabbitmq-custom.config"));
131+
container.start();
132+
133+
assertThat(container.getLogs()).contains("config file(s) : /etc/rabbitmq/rabbitmq-custom.config");
134+
assertThat(container.getLogs()).doesNotContain(" (not found)");
135+
}
136+
}
137+
138+
104139
@Test
105-
public void shouldMountConfigurationFile() {
140+
public void shouldMountConfigurationFileSysctl()
141+
{
106142
try (RabbitMQContainer container = new RabbitMQContainer()) {
107143

108144
container.withRabbitMQConfig(MountableFile.forClasspathResource("/rabbitmq-custom.conf"));
109145
container.start();
110146

111-
assertThat(container.getLogs().contains("/etc/rabbitmq/rabbitmq-custom.conf")).isTrue();
147+
assertThat(container.getLogs()).contains("config file(s) : /etc/rabbitmq/rabbitmq-custom.conf");
148+
assertThat(container.getLogs()).doesNotContain(" (not found)");
112149
}
113150
}
114151

115152
@Test
116-
public void shouldStartTheWholeEnchilada() throws IOException, InterruptedException {
153+
public void shouldStartTheWholeEnchilada() throws IOException, InterruptedException
154+
{
117155
try (RabbitMQContainer container = new RabbitMQContainer()) {
118156
container
119-
.withVhost("vhost1")
120-
.withVhostLimit("vhost1", "max-connections", 1)
121-
.withVhost("vhost2", true)
122-
.withExchange("direct-exchange", "direct")
123-
.withExchange("topic-exchange", "topic")
124-
.withQueue("queue1")
125-
.withQueue("queue2", true, false, ImmutableMap.of("x-message-ttl", 1000))
126-
.withBinding("direct-exchange", "queue1")
127-
.withUser("user1", "password1")
128-
.withUser("user2", "password2", ImmutableSet.of("administrator"))
129-
.withPermission("vhost1", "user1", ".*", ".*", ".*")
130-
.withPolicy("max length policy", "^dog", ImmutableMap.of("max-length", 1), 1, "queues")
131-
.withPolicy("alternate exchange policy", "^direct-exchange", ImmutableMap.of("alternate-exchange", "amq.direct"))
132-
.withOperatorPolicy("operator policy 1", "^queue1", ImmutableMap.of("message-ttl", 1000), 1, "queues")
133-
.withPluginsEnabled("rabbitmq_shovel", "rabbitmq_random_exchange");
157+
.withVhost("vhost1")
158+
.withVhostLimit("vhost1", "max-connections", 1)
159+
.withVhost("vhost2", true)
160+
.withExchange("direct-exchange", "direct")
161+
.withExchange("topic-exchange", "topic")
162+
.withQueue("queue1")
163+
.withQueue("queue2", true, false, ImmutableMap.of("x-message-ttl", 1000))
164+
.withBinding("direct-exchange", "queue1")
165+
.withUser("user1", "password1")
166+
.withUser("user2", "password2", ImmutableSet.of("administrator"))
167+
.withPermission("vhost1", "user1", ".*", ".*", ".*")
168+
.withPolicy("max length policy", "^dog", ImmutableMap.of("max-length", 1), 1, "queues")
169+
.withPolicy("alternate exchange policy", "^direct-exchange", ImmutableMap.of("alternate-exchange", "amq.direct"))
170+
.withOperatorPolicy("operator policy 1", "^queue1", ImmutableMap.of("message-ttl", 1000), 1, "queues")
171+
.withPluginsEnabled("rabbitmq_shovel", "rabbitmq_random_exchange");
134172

135173
container.start();
136174

137175
assertThat(container.execInContainer("rabbitmqadmin", "list", "queues")
138-
.getStdout())
139-
.contains("queue1", "queue2");
176+
.getStdout())
177+
.contains("queue1", "queue2");
140178

141179
assertThat(container.execInContainer("rabbitmqadmin", "list", "exchanges")
142-
.getStdout())
143-
.contains("direct-exchange", "topic-exchange");
180+
.getStdout())
181+
.contains("direct-exchange", "topic-exchange");
144182

145183
assertThat(container.execInContainer("rabbitmqadmin", "list", "bindings")
146-
.getStdout())
147-
.contains("direct-exchange");
184+
.getStdout())
185+
.contains("direct-exchange");
148186

149187
assertThat(container.execInContainer("rabbitmqadmin", "list", "users")
150-
.getStdout())
151-
.contains("user1", "user2");
188+
.getStdout())
189+
.contains("user1", "user2");
152190

153191
assertThat(container.execInContainer("rabbitmqadmin", "list", "policies")
154-
.getStdout())
155-
.contains("max length policy", "alternate exchange policy");
192+
.getStdout())
193+
.contains("max length policy", "alternate exchange policy");
156194

157195
assertThat(container.execInContainer("rabbitmqadmin", "list", "operator_policies")
158-
.getStdout())
159-
.contains("operator policy 1");
196+
.getStdout())
197+
.contains("operator policy 1");
160198

161199
assertThat(container.execInContainer("rabbitmq-plugins", "is_enabled", "rabbitmq_shovel", "--quiet")
162-
.getStdout())
163-
.contains("rabbitmq_shovel is enabled");
200+
.getStdout())
201+
.contains("rabbitmq_shovel is enabled");
164202

165203
assertThat(container.execInContainer("rabbitmq-plugins", "is_enabled", "rabbitmq_random_exchange", "--quiet")
166-
.getStdout())
167-
.contains("rabbitmq_random_exchange is enabled");
204+
.getStdout())
205+
.contains("rabbitmq_random_exchange is enabled");
168206
}
169207
}
170208

171209
@Test
172-
public void shouldThrowExceptionForDodgyJson() {
210+
public void shouldThrowExceptionForDodgyJson()
211+
{
173212
try (RabbitMQContainer container = new RabbitMQContainer()) {
174213

175214
assertThatCode(() ->
176-
container.withQueue(
177-
"queue2",
178-
true,
179-
false,
180-
ImmutableMap.of("x-message-ttl", container))
215+
container.withQueue(
216+
"queue2",
217+
true,
218+
false,
219+
ImmutableMap.of("x-message-ttl", container))
181220
).hasMessageStartingWith("Failed to convert arguments into json");
182221

183222
}
184223
}
185224

186225
@Test
187-
public void shouldWorkWithSSL() {
226+
public void shouldWorkWithSSL()
227+
{
188228
try (RabbitMQContainer container = new RabbitMQContainer()) {
189229
container.withSSL(
190-
forClasspathResource("/certs/server_key.pem", 0644),
191-
forClasspathResource("/certs/server_certificate.pem", 0644),
192-
forClasspathResource("/certs/ca_certificate.pem", 0644),
193-
VERIFY_PEER,
194-
true
230+
forClasspathResource("/certs/server_key.pem", 0644),
231+
forClasspathResource("/certs/server_certificate.pem", 0644),
232+
forClasspathResource("/certs/ca_certificate.pem", 0644),
233+
VERIFY_PEER,
234+
true
195235
);
196236

197237
container.start();
198238

199239
assertThatCode(() -> {
200240
ConnectionFactory connectionFactory = new ConnectionFactory();
201241
connectionFactory.useSslProtocol(createSslContext(
202-
"certs/client_key.p12", "password",
203-
"certs/truststore.jks", "password"));
242+
"certs/client_key.p12", "password",
243+
"certs/truststore.jks", "password"));
204244
connectionFactory.enableHostnameVerification();
205245
connectionFactory.setUri(container.getAmqpsUrl());
206246
connectionFactory.setPassword(container.getAdminPassword());
@@ -213,7 +253,8 @@ public void shouldWorkWithSSL() {
213253
}
214254

215255
private SSLContext createSslContext(String keystoreFile, String keystorePassword, String truststoreFile, String truststorePassword)
216-
throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException, UnrecoverableKeyException, KeyManagementException {
256+
throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException, UnrecoverableKeyException, KeyManagementException
257+
{
217258
ClassLoader classLoader = getClass().getClassLoader();
218259

219260
KeyStore ks = KeyStore.getInstance("PKCS12");
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
loopback_users.guest = false
2-
listeners.tcp.default = 5555
2+
listeners.tcp.default = 5555
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
[
2+
{ rabbit, [
3+
{ loopback_users, [ ] },
4+
{ tcp_listeners, [ 5555 ] },
5+
{ ssl_listeners, [ ] },
6+
{ default_vhost, <<"vhost">> },
7+
{ hipe_compile, false }
8+
] },
9+
{ rabbitmq_management, [ { listener, [
10+
{ port, 15672 },
11+
{ ssl, false }
12+
] } ] }
13+
].

0 commit comments

Comments
 (0)