Skip to content

Commit 69d2b6f

Browse files
committed
Add Azure Event Hubs Emulator container to Azure module
- Fix code review findings Signed-off-by: Esta Nagy <[email protected]>
1 parent 7071595 commit 69d2b6f

File tree

2 files changed

+93
-76
lines changed

2 files changed

+93
-76
lines changed

modules/azure/src/main/java/org/testcontainers/azure/AzureEventHubsEmulatorContainer.java

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,25 +32,39 @@ public class AzureEventHubsEmulatorContainer extends GenericContainer<AzureEvent
3232
"mcr.microsoft.com/azure-messaging/eventhubs-emulator"
3333
);
3434

35-
private final AzuriteContainer azuriteContainer;
35+
private AzuriteContainer azuriteContainer;
3636

3737
private boolean useKafka;
3838

3939
/**
4040
* @param dockerImageName specified docker image name to run
4141
*/
42-
public AzureEventHubsEmulatorContainer(
43-
final DockerImageName dockerImageName,
44-
final AzuriteContainer azuriteContainer
45-
) {
42+
public AzureEventHubsEmulatorContainer(final String dockerImageName) {
43+
this(DockerImageName.parse(dockerImageName));
44+
}
45+
46+
/**
47+
* @param dockerImageName specified docker image name to run
48+
*/
49+
public AzureEventHubsEmulatorContainer(final DockerImageName dockerImageName) {
4650
super(dockerImageName);
4751
dockerImageName.assertCompatibleWith(DEFAULT_IMAGE_NAME);
48-
this.azuriteContainer = azuriteContainer;
49-
dependsOn(this.azuriteContainer);
5052
waitingFor(Wait.forLogMessage(".*Emulator Service is Successfully Up!.*", 1));
5153
withExposedPorts(DEFAULT_AMQP_PORT);
5254
}
5355

56+
/**
57+
* * Sets the Azurite dependency needed by the Event Hubs Container,
58+
*
59+
* @param azuriteContainer The Azurite container used by Event HUbs as a dependency
60+
* @return this
61+
*/
62+
public AzureEventHubsEmulatorContainer withAzuriteContainer(final AzuriteContainer azuriteContainer) {
63+
this.azuriteContainer = azuriteContainer;
64+
dependsOn(this.azuriteContainer);
65+
return this;
66+
}
67+
5468
/**
5569
* Provide the broker configuration to the container.
5670
*
@@ -83,6 +97,13 @@ public AzureEventHubsEmulatorContainer enableKafka() {
8397

8498
@Override
8599
protected void configure() {
100+
if (azuriteContainer == null) {
101+
throw new IllegalStateException(
102+
"The image " +
103+
getDockerImageName() +
104+
" requires an Azurite container. Please provide one with the withAzuriteContainer method!"
105+
);
106+
}
86107
final String azuriteHost = azuriteContainer.getNetworkAliases().get(0);
87108
withEnv("BLOB_SERVER", azuriteHost);
88109
withEnv("METADATA_SERVER", azuriteHost);

modules/azure/src/test/java/org/testcontainers/azure/AzureEventHubsEmulatorContainerTest.java

Lines changed: 65 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,9 @@
1717
import org.apache.kafka.clients.producer.ProducerRecord;
1818
import org.apache.kafka.common.serialization.StringDeserializer;
1919
import org.apache.kafka.common.serialization.StringSerializer;
20-
import org.awaitility.Awaitility;
2120
import org.junit.Rule;
2221
import org.junit.Test;
2322
import org.testcontainers.containers.Network;
24-
import org.testcontainers.utility.DockerImageName;
2523
import org.testcontainers.utility.MountableFile;
2624

2725
import java.time.Duration;
@@ -32,87 +30,85 @@
3230

3331
import static org.assertj.core.api.Assertions.assertThat;
3432
import static org.assertj.core.api.Assertions.tuple;
33+
import static org.awaitility.Awaitility.await;
3534
import static org.awaitility.Awaitility.waitAtMost;
3635

3736
public class AzureEventHubsEmulatorContainerTest {
3837

3938
@Rule
4039
// network {
4140
public Network network = Network.newNetwork();
42-
4341
// }
4442

4543
@Rule
4644
// azuriteContainer {
4745
public AzuriteContainer azuriteContainer = new AzuriteContainer("mcr.microsoft.com/azure-storage/azurite:3.33.0")
48-
.withNetwork(network);
49-
46+
.withNetwork(network);
5047
// }
5148

5249
@Rule
5350
// emulatorContainer {
5451
public AzureEventHubsEmulatorContainer emulator = new AzureEventHubsEmulatorContainer(
55-
DockerImageName.parse("mcr.microsoft.com/azure-messaging/eventhubs-emulator:2.0.1"),
56-
azuriteContainer
52+
"mcr.microsoft.com/azure-messaging/eventhubs-emulator:2.0.1"
5753
)
58-
.acceptLicense()
59-
.enableKafka() //optional
60-
.withNetwork(network)
61-
.withConfig(MountableFile.forClasspathResource("/eventhubs_config.json"));
62-
54+
.acceptLicense()
55+
.enableKafka() //optional
56+
.withNetwork(network)
57+
.withConfig(MountableFile.forClasspathResource("/eventhubs_config.json"))
58+
.withAzuriteContainer(azuriteContainer);
6359
// }
6460

6561
@Test
6662
public void testWithEventHubsClient() {
6763
try (
68-
// createProducerAndConsumer {
69-
EventHubProducerClient producer = new EventHubClientBuilder()
70-
.connectionString(emulator.getConnectionString())
71-
.fullyQualifiedNamespace("emulatorNs1")
72-
.eventHubName("eh1")
73-
.buildProducerClient();
74-
EventHubConsumerClient consumer = new EventHubClientBuilder()
75-
.connectionString(emulator.getConnectionString())
76-
.fullyQualifiedNamespace("emulatorNs1")
77-
.eventHubName("eh1")
78-
.consumerGroup("cg1")
79-
.buildConsumerClient()
80-
// }
64+
// createProducerAndConsumer {
65+
EventHubProducerClient producer = new EventHubClientBuilder()
66+
.connectionString(emulator.getConnectionString())
67+
.fullyQualifiedNamespace("emulatorNs1")
68+
.eventHubName("eh1")
69+
.buildProducerClient();
70+
EventHubConsumerClient consumer = new EventHubClientBuilder()
71+
.connectionString(emulator.getConnectionString())
72+
.fullyQualifiedNamespace("emulatorNs1")
73+
.eventHubName("eh1")
74+
.consumerGroup("cg1")
75+
.buildConsumerClient()
76+
// }
8177
) {
8278
producer.send(Collections.singletonList(new EventData("test")));
8379

8480
waitAtMost(Duration.ofSeconds(30))
85-
.pollDelay(Duration.ofSeconds(5))
86-
.untilAsserted(() -> {
87-
IterableStream<PartitionEvent> events = consumer.receiveFromPartition(
88-
"0",
89-
1,
90-
EventPosition.earliest(),
91-
Duration.ofSeconds(2)
92-
);
93-
Optional<PartitionEvent> event = events.stream().findFirst();
94-
assertThat(event).isPresent();
95-
assertThat(event.get().getData().getBodyAsString()).isEqualTo("test");
96-
});
81+
.pollDelay(Duration.ofSeconds(5))
82+
.untilAsserted(() -> {
83+
IterableStream<PartitionEvent> events = consumer.receiveFromPartition(
84+
"0",
85+
1,
86+
EventPosition.earliest(),
87+
Duration.ofSeconds(2)
88+
);
89+
Optional<PartitionEvent> event = events.stream().findFirst();
90+
assertThat(event).isPresent();
91+
assertThat(event.get().getData().getBodyAsString()).isEqualTo("test");
92+
});
9793
}
9894
}
9995

10096
@Test
10197
public void testWithKafkaClient() throws Exception {
10298
// kafkaProperties {
10399
ImmutableMap<String, String> commonProperties = ImmutableMap
104-
.<String, String>builder()
105-
.put("bootstrap.servers", emulator.getBootstrapServers())
106-
.put("sasl.mechanism", "PLAIN")
107-
.put("security.protocol", "SASL_PLAINTEXT")
108-
.put(
109-
"sasl.jaas.config",
110-
String.format(
111-
"org.apache.kafka.common.security.plain.PlainLoginModule required username=\"$ConnectionString\" password=\"%s\";",
112-
emulator.getConnectionString()
100+
.<String, String>builder()
101+
.put("bootstrap.servers", emulator.getBootstrapServers())
102+
.put("sasl.mechanism", "PLAIN")
103+
.put("security.protocol", "SASL_PLAINTEXT")
104+
.put(
105+
"sasl.jaas.config",
106+
String.format(
107+
"org.apache.kafka.common.security.plain.PlainLoginModule required username=\"$ConnectionString\" password=\"%s\";",
108+
emulator.getConnectionString()
109+
)
113110
)
114-
)
115-
.build();
111+
.build();
116112
// }
117113

118114
Properties producerProperties = new Properties();
@@ -123,34 +119,34 @@ public void testWithKafkaClient() throws Exception {
123119
consumerProperties.setProperty(ConsumerConfig.GROUP_ID_CONFIG, "tc-" + UUID.randomUUID());
124120
consumerProperties.setProperty(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
125121
consumerProperties.putAll(commonProperties);
122+
126123
try (
127-
KafkaProducer<String, String> producer = new KafkaProducer<>(
128-
producerProperties,
129-
new StringSerializer(),
130-
new StringSerializer()
131-
);
132-
KafkaConsumer<String, String> consumer = new KafkaConsumer<>(
133-
consumerProperties,
134-
new StringDeserializer(),
135-
new StringDeserializer()
136-
);
124+
KafkaProducer<String, String> producer = new KafkaProducer<>(
125+
producerProperties,
126+
new StringSerializer(),
127+
new StringSerializer()
128+
);
129+
KafkaConsumer<String, String> consumer = new KafkaConsumer<>(
130+
consumerProperties,
131+
new StringDeserializer(),
132+
new StringDeserializer()
133+
);
137134
) {
138135
String topicName = "eh1";
139136
consumer.subscribe(Collections.singletonList(topicName));
140137

141138
producer.send(new ProducerRecord<>(topicName, "testcontainers", "rulezzz")).get();
142139

143-
Awaitility
144-
.await()
145-
.atMost(Duration.ofSeconds(10))
146-
.untilAsserted(() -> {
147-
ConsumerRecords<String, String> records = consumer.poll(Duration.ofMillis(100));
148-
149-
assertThat(records)
150-
.hasSize(1)
151-
.extracting(ConsumerRecord::topic, ConsumerRecord::key, ConsumerRecord::value)
152-
.containsExactly(tuple(topicName, "testcontainers", "rulezzz"));
153-
});
140+
await()
141+
.atMost(Duration.ofSeconds(10))
142+
.untilAsserted(() -> {
143+
ConsumerRecords<String, String> records = consumer.poll(Duration.ofMillis(100));
144+
145+
assertThat(records)
146+
.hasSize(1)
147+
.extracting(ConsumerRecord::topic, ConsumerRecord::key, ConsumerRecord::value)
148+
.containsExactly(tuple(topicName, "testcontainers", "rulezzz"));
149+
});
154150

155151
consumer.unsubscribe();
156152
}

0 commit comments

Comments
 (0)