Skip to content

Commit cc1e951

Browse files
author
Tomasz Forys
committed
[Bug]: SolaceContainer misses permissions when using non-default VPN #10370
- queues support and permissions on solace container - JUnits coverage - Adding missing javadocs
1 parent 71cc729 commit cc1e951

File tree

6 files changed

+128
-43
lines changed

6 files changed

+128
-43
lines changed

modules/solace/src/main/java/org/testcontainers/solace/Service.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,25 @@
44
* Services that are supported by Testcontainers implementation
55
*/
66
public enum Service {
7+
/**
8+
* Advanced Message Queuing Protocol
9+
*/
710
AMQP("amqp", 5672, "amqp", false),
11+
/**
12+
* Message Queuing Telemetry Transport
13+
*/
814
MQTT("mqtt", 1883, "tcp", false),
15+
/**
16+
* Representational State Transfer
17+
*/
918
REST("rest", 9000, "http", false),
19+
/**
20+
* Solace Message Format
21+
*/
1022
SMF("smf", 55555, "tcp", true),
23+
/**
24+
* Solace Message Format with SSL
25+
*/
1126
SMF_SSL("smf", 55443, "tcps", true);
1227

1328
private final String name;

modules/solace/src/main/java/org/testcontainers/solace/SolaceContainer.java

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,19 @@ public SolaceContainer(String dockerImageName) {
6565
this(DockerImageName.parse(dockerImageName));
6666
}
6767

68+
/**
69+
* Create a new solace container with the specified docker image.
70+
*
71+
* @param dockerImageName the image name that should be used.
72+
*/
6873
public SolaceContainer(DockerImageName dockerImageName) {
6974
super(dockerImageName);
7075
dockerImageName.assertCompatibleWith(DEFAULT_IMAGE_NAME);
7176
withCreateContainerCmdModifier(cmd -> {
72-
cmd.getHostConfig().withShmSize(SHM_SIZE).withUlimits(new Ulimit[] { new Ulimit("nofile", 2448L, 6592L) });
77+
cmd
78+
.getHostConfig()
79+
.withShmSize(SHM_SIZE)
80+
.withUlimits(new Ulimit[] { new Ulimit("nofile", 2448L, 1048576L) });
7381
});
7482
this.waitStrategy = Wait.forLogMessage(SOLACE_READY_MESSAGE, 1).withStartupTimeout(Duration.ofSeconds(60));
7583
withExposedPorts(8080);
@@ -103,6 +111,17 @@ private Transferable createConfigurationScript() {
103111
updateConfigScript(scriptBuilder, "create message-vpn " + vpn);
104112
updateConfigScript(scriptBuilder, "no shutdown");
105113
updateConfigScript(scriptBuilder, "exit");
114+
updateConfigScript(scriptBuilder, "client-profile default message-vpn " + vpn);
115+
updateConfigScript(scriptBuilder, "message-spool");
116+
updateConfigScript(scriptBuilder, "allow-guaranteed-message-send");
117+
updateConfigScript(scriptBuilder, "allow-guaranteed-message-receive");
118+
updateConfigScript(scriptBuilder, "allow-guaranteed-endpoint-create");
119+
updateConfigScript(scriptBuilder, "allow-guaranteed-endpoint-create-durability all");
120+
updateConfigScript(scriptBuilder, "exit");
121+
updateConfigScript(scriptBuilder, "exit");
122+
updateConfigScript(scriptBuilder, "message-spool message-vpn " + vpn);
123+
updateConfigScript(scriptBuilder, "max-spool-usage 60000");
124+
updateConfigScript(scriptBuilder, "exit");
106125
}
107126

108127
// Configure username and password
@@ -235,7 +254,7 @@ public SolaceContainer withCredentials(final String username, final String passw
235254
/**
236255
* Adds the topic configuration
237256
*
238-
* @param topic Name of the topic
257+
* @param topic Name of the topic
239258
* @param service Service to be supported on provided topic
240259
* @return This container.
241260
*/
@@ -260,7 +279,7 @@ public SolaceContainer withVpn(String vpn) {
260279
* Sets the solace server ceritificates
261280
*
262281
* @param certFile Server certificate
263-
* @param caFile Certified Authority certificate
282+
* @param caFile Certified Authority certificate
264283
* @return This container.
265284
*/
266285
public SolaceContainer withClientCert(final MountableFile certFile, final MountableFile caFile) {

modules/solace/src/test/java/org/testcontainers/solace/SolaceContainerAMQPTest.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,6 @@
66
import org.slf4j.Logger;
77
import org.slf4j.LoggerFactory;
88

9-
import java.util.concurrent.CountDownLatch;
10-
import java.util.concurrent.TimeUnit;
11-
129
import javax.jms.Connection;
1310
import javax.jms.ConnectionFactory;
1411
import javax.jms.JMSException;
@@ -17,6 +14,8 @@
1714
import javax.jms.Session;
1815
import javax.jms.TextMessage;
1916
import javax.jms.Topic;
17+
import java.util.concurrent.CountDownLatch;
18+
import java.util.concurrent.TimeUnit;
2019

2120
import static org.assertj.core.api.Assertions.assertThat;
2221

@@ -31,7 +30,7 @@ public class SolaceContainerAMQPTest {
3130
@Test
3231
public void testSolaceContainer() throws JMSException {
3332
try (
34-
SolaceContainer solaceContainer = new SolaceContainer("solace/solace-pubsub-standard:10.2")
33+
SolaceContainer solaceContainer = new SolaceContainer("solace/solace-pubsub-standard:10.25.0")
3534
.withTopic(TOPIC_NAME, Service.AMQP)
3635
.withVpn("amqp-vpn")
3736
) {

modules/solace/src/test/java/org/testcontainers/solace/SolaceContainerMQTTTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public class SolaceContainerMQTTTest {
2727
@Test
2828
public void testSolaceContainer() {
2929
try (
30-
SolaceContainer solaceContainer = new SolaceContainer("solace/solace-pubsub-standard:10.2")
30+
SolaceContainer solaceContainer = new SolaceContainer("solace/solace-pubsub-standard:10.25.0")
3131
.withTopic(TOPIC_NAME, Service.MQTT)
3232
.withVpn("mqtt-vpn")
3333
) {

modules/solace/src/test/java/org/testcontainers/solace/SolaceContainerRESTTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public class SolaceContainerRESTTest {
2828
@Test
2929
public void testSolaceContainer() throws IOException {
3030
try (
31-
SolaceContainer solaceContainer = new SolaceContainer("solace/solace-pubsub-standard:10.2")
31+
SolaceContainer solaceContainer = new SolaceContainer("solace/solace-pubsub-standard:10.25.0")
3232
.withTopic(TOPIC_NAME, Service.REST)
3333
.withVpn("rest-vpn")
3434
) {

modules/solace/src/test/java/org/testcontainers/solace/SolaceContainerSMFTest.java

Lines changed: 86 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
package org.testcontainers.solace;
22

33
import com.solacesystems.jcsmp.BytesXMLMessage;
4+
import com.solacesystems.jcsmp.ConsumerFlowProperties;
5+
import com.solacesystems.jcsmp.EndpointProperties;
46
import com.solacesystems.jcsmp.JCSMPException;
57
import com.solacesystems.jcsmp.JCSMPFactory;
68
import com.solacesystems.jcsmp.JCSMPProperties;
79
import com.solacesystems.jcsmp.JCSMPSession;
810
import com.solacesystems.jcsmp.JCSMPStreamingPublishCorrelatingEventHandler;
11+
import com.solacesystems.jcsmp.Queue;
912
import com.solacesystems.jcsmp.TextMessage;
1013
import com.solacesystems.jcsmp.Topic;
1114
import com.solacesystems.jcsmp.XMLMessageConsumer;
@@ -30,40 +33,77 @@ public class SolaceContainerSMFTest {
3033

3134
private static final Topic TOPIC = JCSMPFactory.onlyInstance().createTopic("Topic/ActualTopic");
3235

36+
private static final Queue QUEUE = JCSMPFactory.onlyInstance().createQueue("Queue");
37+
3338
@Test
3439
public void testSolaceContainerWithSimpleAuthentication() {
3540
try (
3641
// solaceContainerSetup {
37-
SolaceContainer solaceContainer = new SolaceContainer("solace/solace-pubsub-standard:10.2")
42+
SolaceContainer solaceContainer = new SolaceContainer("solace/solace-pubsub-standard:10.25.0")
3843
.withCredentials("user", "pass")
39-
.withTopic("Topic/ActualTopic", Service.SMF)
44+
.withTopic(TOPIC.getName(), Service.SMF)
4045
.withVpn("test_vpn")
4146
// }
4247
) {
4348
solaceContainer.start();
4449
JCSMPSession session = createSessionWithBasicAuth(solaceContainer);
4550
assertThat(session).isNotNull();
46-
assertThat(consumeMessageFromSolace(session)).isEqualTo(MESSAGE);
51+
consumeMessageFromTopics(session);
4752
session.closeSession();
4853
}
4954
}
5055

56+
@Test
57+
public void testSolaceContainerWithCreateFlow() {
58+
try (
59+
// solaceContainerSetup {
60+
SolaceContainer solaceContainer = new SolaceContainer("solace/solace-pubsub-standard:10.25.0")
61+
.withCredentials("user", "pass")
62+
.withTopic(TOPIC.getName(), Service.SMF)
63+
.withVpn("test_vpn")
64+
// }
65+
) {
66+
solaceContainer.start();
67+
JCSMPSession session = createSessionWithBasicAuth(solaceContainer);
68+
assertThat(session).isNotNull();
69+
testCreateFlow(session);
70+
session.closeSession();
71+
}
72+
}
73+
74+
private static void testCreateFlow(JCSMPSession session) {
75+
try {
76+
EndpointProperties endpointProperties = new EndpointProperties();
77+
endpointProperties.setAccessType(EndpointProperties.ACCESSTYPE_NONEXCLUSIVE);
78+
endpointProperties.setQuota(1000);
79+
session.provision(QUEUE, endpointProperties, JCSMPSession.FLAG_IGNORE_ALREADY_EXISTS);
80+
session.addSubscription(QUEUE, TOPIC, JCSMPSession.WAIT_FOR_CONFIRM);
81+
ConsumerFlowProperties flowProperties = new ConsumerFlowProperties().setEndpoint(QUEUE);
82+
TestConsumer listener = new TestConsumer();
83+
session.createFlow(listener, flowProperties).start();
84+
publishMessageToSolaceTopic(session);
85+
listener.waitForMessage();
86+
} catch (Exception e) {
87+
throw new RuntimeException("Cannot process message using solace topic/queue: " + e.getMessage(), e);
88+
}
89+
}
90+
5191
@Test
5292
public void testSolaceContainerWithCertificates() {
5393
try (
5494
// solaceContainerUsageSSL {
55-
SolaceContainer solaceContainer = new SolaceContainer("solace/solace-pubsub-standard:10.6")
95+
SolaceContainer solaceContainer = new SolaceContainer("solace/solace-pubsub-standard:10.25.0")
5696
.withClientCert(
5797
MountableFile.forClasspathResource("solace.pem"),
5898
MountableFile.forClasspathResource("rootCA.crt")
5999
)
60-
.withTopic("Topic/ActualTopic", Service.SMF_SSL)
100+
.withTopic(TOPIC.getName(), Service.SMF_SSL)
61101
// }
62102
) {
63103
solaceContainer.start();
64104
JCSMPSession session = createSessionWithCertificates(solaceContainer);
65105
assertThat(session).isNotNull();
66-
assertThat(consumeMessageFromSolace(session)).isEqualTo(MESSAGE);
106+
consumeMessageFromTopics(session);
67107
session.closeSession();
68108
}
69109
}
@@ -112,7 +152,7 @@ private static JCSMPSession createSession(JCSMPProperties properties) {
112152
}
113153
}
114154

115-
private void publishMessageToSolace(JCSMPSession session) throws JCSMPException {
155+
private static void publishMessageToSolaceTopic(JCSMPSession session) throws JCSMPException {
116156
XMLMessageProducer producer = session.getMessageProducer(
117157
new JCSMPStreamingPublishCorrelatingEventHandler() {
118158
@Override
@@ -131,37 +171,49 @@ public void handleErrorEx(Object o, JCSMPException e, long l) {
131171
producer.send(msg, TOPIC);
132172
}
133173

134-
private String consumeMessageFromSolace(JCSMPSession session) {
135-
CountDownLatch latch = new CountDownLatch(1);
174+
private static void consumeMessageFromTopics(JCSMPSession session) {
136175
try {
137-
String[] result = new String[1];
138-
XMLMessageConsumer cons = session.getMessageConsumer(
139-
new XMLMessageListener() {
140-
@Override
141-
public void onReceive(BytesXMLMessage msg) {
142-
if (msg instanceof TextMessage) {
143-
TextMessage textMessage = (TextMessage) msg;
144-
String message = textMessage.getText();
145-
result[0] = message;
146-
LOGGER.info("TextMessage received: " + message);
147-
}
148-
latch.countDown();
149-
}
150-
151-
@Override
152-
public void onException(JCSMPException e) {
153-
LOGGER.error("Exception received: " + e.getMessage());
154-
latch.countDown();
155-
}
156-
}
157-
);
176+
TestConsumer listener = new TestConsumer();
177+
XMLMessageConsumer cons = session.getMessageConsumer(listener);
158178
session.addSubscription(TOPIC);
159179
cons.start();
160-
publishMessageToSolace(session);
161-
assertThat(latch.await(10L, TimeUnit.SECONDS)).isTrue();
162-
return result[0];
180+
publishMessageToSolaceTopic(session);
181+
listener.waitForMessage();
163182
} catch (Exception e) {
164-
throw new RuntimeException("Cannot receive message from solace", e);
183+
throw new RuntimeException("Cannot process message using solace: " + e.getMessage(), e);
184+
}
185+
}
186+
187+
static class TestConsumer implements XMLMessageListener {
188+
189+
private final CountDownLatch latch = new CountDownLatch(1);
190+
191+
private String result;
192+
193+
@Override
194+
public void onReceive(BytesXMLMessage msg) {
195+
if (msg instanceof TextMessage) {
196+
TextMessage textMessage = (TextMessage) msg;
197+
String message = textMessage.getText();
198+
result = message;
199+
LOGGER.info("Message received: " + message);
200+
}
201+
latch.countDown();
202+
}
203+
204+
@Override
205+
public void onException(JCSMPException e) {
206+
LOGGER.error("Exception received: " + e.getMessage());
207+
latch.countDown();
208+
}
209+
210+
private void waitForMessage() {
211+
try {
212+
assertThat(latch.await(10L, TimeUnit.SECONDS)).isTrue();
213+
assertThat(result).isEqualTo(MESSAGE);
214+
} catch (Exception e) {
215+
throw new RuntimeException("Cannot receive message from solace: " + e.getMessage(), e);
216+
}
165217
}
166218
}
167219
}

0 commit comments

Comments
 (0)