From 98eb74b75cc6dc89de9a9243dbb2adee43415138 Mon Sep 17 00:00:00 2001 From: "Marvin B. Lillehaug" Date: Sun, 15 Dec 2024 22:28:54 +0100 Subject: [PATCH 1/7] ServicebusEmulatorContainer, SqlEdgeContainer --- .../ServicebusEmulatorContainer.java | 32 +++++++++++++++++++ .../containers/SqlEdgeContainer.java | 32 +++++++++++++++++++ .../ServicebusEmulatorContainerTest.java | 17 ++++++++++ .../containers/SqlEdgeContainerTest.java | 18 +++++++++++ 4 files changed, 99 insertions(+) create mode 100644 modules/azure/src/main/java/org/testcontainers/containers/ServicebusEmulatorContainer.java create mode 100644 modules/azure/src/main/java/org/testcontainers/containers/SqlEdgeContainer.java create mode 100644 modules/azure/src/test/java/org/testcontainers/containers/ServicebusEmulatorContainerTest.java create mode 100644 modules/azure/src/test/java/org/testcontainers/containers/SqlEdgeContainerTest.java diff --git a/modules/azure/src/main/java/org/testcontainers/containers/ServicebusEmulatorContainer.java b/modules/azure/src/main/java/org/testcontainers/containers/ServicebusEmulatorContainer.java new file mode 100644 index 00000000000..0e3fc43fbf6 --- /dev/null +++ b/modules/azure/src/main/java/org/testcontainers/containers/ServicebusEmulatorContainer.java @@ -0,0 +1,32 @@ +package org.testcontainers.containers; + +import org.testcontainers.containers.wait.strategy.Wait; +import org.testcontainers.utility.DockerImageName; + +public class ServicebusEmulatorContainer extends GenericContainer { + private static final DockerImageName DEFAULT_IMAGE_NAME = DockerImageName.parse( + "mcr.microsoft.com/azure-messaging/servicebus-emulator" + ); + + private static final int PORT = 1433; + + /** + * @param dockerImageName specified docker image name to run + */ + public ServicebusEmulatorContainer(final DockerImageName dockerImageName) { + super(dockerImageName); + dockerImageName.assertCompatibleWith(DEFAULT_IMAGE_NAME); + withExposedPorts(PORT); + waitingFor(Wait.forLogMessage(".*Emulator Service is Successfully Up!\\r\\n$", 1)); + Network network = Network.newNetwork(); + withNetwork(network); + withNetworkAliases("sb-emulator"); + dependsOn( + new SqlEdgeContainer(DockerImageName.parse("mcr.microsoft.com/azure-sql-edge:latest")) + .withNetwork(network) + .withNetworkAliases("sqledge") + ); + addEnv("ACCEPT_EULA", "Y"); + addEnv("CONFIG_PATH", "/home/marv/Downloads/asb/config.json"); + } +} diff --git a/modules/azure/src/main/java/org/testcontainers/containers/SqlEdgeContainer.java b/modules/azure/src/main/java/org/testcontainers/containers/SqlEdgeContainer.java new file mode 100644 index 00000000000..2143d53cdb3 --- /dev/null +++ b/modules/azure/src/main/java/org/testcontainers/containers/SqlEdgeContainer.java @@ -0,0 +1,32 @@ +package org.testcontainers.containers; + +import org.testcontainers.containers.wait.strategy.Wait; +import org.testcontainers.utility.DockerImageName; + +/** + * Testcontainers implementation for Sql Edge. + *

+ * Supported image: {@code mcr.microsoft.com/azure-sql-edge} + *

+ * Exposed ports: 1433 + */ +public class SqlEdgeContainer extends GenericContainer { + private static final DockerImageName DEFAULT_IMAGE_NAME = DockerImageName.parse( + "mcr.microsoft.com/azure-sql-edge" + ); + + private static final int PORT = 1433; + + /** + * @param dockerImageName specified docker image name to run + */ + public SqlEdgeContainer(final DockerImageName dockerImageName) { + super(dockerImageName); + dockerImageName.assertCompatibleWith(DEFAULT_IMAGE_NAME); + withExposedPorts(PORT); + waitingFor(Wait.forLogMessage(".*Service Broker manager has started.\\r\\n$", 1)); + addEnv("ACCEPT_EULA", "Y"); + addEnv("MSSQL_SA_PASSWORD", "J3R4uUWLTjDqTXoQnvXu"); + } + +} diff --git a/modules/azure/src/test/java/org/testcontainers/containers/ServicebusEmulatorContainerTest.java b/modules/azure/src/test/java/org/testcontainers/containers/ServicebusEmulatorContainerTest.java new file mode 100644 index 00000000000..8610abb64ba --- /dev/null +++ b/modules/azure/src/test/java/org/testcontainers/containers/ServicebusEmulatorContainerTest.java @@ -0,0 +1,17 @@ +package org.testcontainers.containers; + +import org.junit.Rule; +import org.junit.Test; +import org.testcontainers.utility.DockerImageName; + +public class ServicebusEmulatorContainerTest { + @Rule + public ServicebusEmulatorContainer servicebusEmulatorContainer = new ServicebusEmulatorContainer( + DockerImageName.parse("mcr.microsoft.com/azure-messaging/servicebus-emulator") + ); + + @Test + public void testWIthASBClient() { + String containerId = servicebusEmulatorContainer.getContainerId(); + } +} diff --git a/modules/azure/src/test/java/org/testcontainers/containers/SqlEdgeContainerTest.java b/modules/azure/src/test/java/org/testcontainers/containers/SqlEdgeContainerTest.java new file mode 100644 index 00000000000..b105955c7cb --- /dev/null +++ b/modules/azure/src/test/java/org/testcontainers/containers/SqlEdgeContainerTest.java @@ -0,0 +1,18 @@ +package org.testcontainers.containers; + + +import org.junit.Rule; +import org.junit.Test; +import org.testcontainers.utility.DockerImageName; + +public class SqlEdgeContainerTest { + @Rule + public SqlEdgeContainer sqlEdgeContainer = new SqlEdgeContainer( + DockerImageName.parse("mcr.microsoft.com/azure-sql-edge:latest") + ); + + @Test + public void testWithJdbc() { + String host = sqlEdgeContainer.getHost(); + } +} From 684a274014745790cfc6ca9cee53be853ea20b61 Mon Sep 17 00:00:00 2001 From: "Marvin B. Lillehaug" Date: Tue, 14 Jan 2025 20:00:17 +0100 Subject: [PATCH 2/7] Tests pass, needed azure-messaging-servicebus:7.17.8 --- modules/azure/build.gradle | 4 + .../ServicebusEmulatorContainer.java | 33 ++++-- .../ServicebusEmulatorContainerTest.java | 37 +++++- .../src/test/resources/servicebus-config.json | 108 ++++++++++++++++++ 4 files changed, 171 insertions(+), 11 deletions(-) create mode 100644 modules/azure/src/test/resources/servicebus-config.json diff --git a/modules/azure/build.gradle b/modules/azure/build.gradle index c6cfb6738d0..d2093f020f0 100644 --- a/modules/azure/build.gradle +++ b/modules/azure/build.gradle @@ -5,9 +5,13 @@ dependencies { // TODO use JDK's HTTP client and/or Apache HttpClient5 shaded 'com.squareup.okhttp3:okhttp:4.12.0' + implementation project(':mssqlserver') + testImplementation 'com.microsoft.sqlserver:mssql-jdbc:12.8.1.jre8' + testImplementation 'org.assertj:assertj-core:3.26.3' testImplementation 'com.azure:azure-cosmos:4.63.3' testImplementation 'com.azure:azure-storage-blob:12.29.0' testImplementation 'com.azure:azure-storage-queue:12.24.0' testImplementation 'com.azure:azure-data-tables:12.5.0' + testImplementation 'com.azure:azure-messaging-servicebus:7.17.8' } diff --git a/modules/azure/src/main/java/org/testcontainers/containers/ServicebusEmulatorContainer.java b/modules/azure/src/main/java/org/testcontainers/containers/ServicebusEmulatorContainer.java index 0e3fc43fbf6..8f337023569 100644 --- a/modules/azure/src/main/java/org/testcontainers/containers/ServicebusEmulatorContainer.java +++ b/modules/azure/src/main/java/org/testcontainers/containers/ServicebusEmulatorContainer.java @@ -3,12 +3,12 @@ import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.utility.DockerImageName; -public class ServicebusEmulatorContainer extends GenericContainer { +public class ServicebusEmulatorContainer> extends GenericContainer { private static final DockerImageName DEFAULT_IMAGE_NAME = DockerImageName.parse( "mcr.microsoft.com/azure-messaging/servicebus-emulator" ); - private static final int PORT = 1433; + private static final int PORT = 5672; /** * @param dockerImageName specified docker image name to run @@ -17,16 +17,31 @@ public ServicebusEmulatorContainer(final DockerImageName dockerImageName) { super(dockerImageName); dockerImageName.assertCompatibleWith(DEFAULT_IMAGE_NAME); withExposedPorts(PORT); - waitingFor(Wait.forLogMessage(".*Emulator Service is Successfully Up!\\r\\n$", 1)); - Network network = Network.newNetwork(); - withNetwork(network); + + waitingFor(Wait.forLogMessage(".*Emulator Service is Successfully Up!.*", 1)); + + withNetwork(Network.SHARED); withNetworkAliases("sb-emulator"); + MSSQLServerContainer mssqlServerContainer = new MSSQLServerContainer(DockerImageName.parse("mcr.microsoft.com/mssql/server:2022-CU14-ubuntu-22.04")) + .acceptLicense(); + String mssqlNetworkAlias = "sqledge"; dependsOn( - new SqlEdgeContainer(DockerImageName.parse("mcr.microsoft.com/azure-sql-edge:latest")) - .withNetwork(network) - .withNetworkAliases("sqledge") + mssqlServerContainer + .withNetwork(Network.SHARED) + .withNetworkAliases(mssqlNetworkAlias) ); + addEnv("MSSQL_SA_PASSWORD", mssqlServerContainer.getPassword()); + addEnv("SQL_SERVER", mssqlNetworkAlias); + acceptLicense(); + addEnv("CONFIG_PATH", "/home/marvin.lillehaug/src/testcontainers-java/modules/azure/src/test/resources/servicebus-config.json"); + } + + /** + * Accepts the license for the Azure Service Bus Emulator container by setting the ACCEPT_EULA=Y + * variable as described at https://github.com/Azure/azure-service-bus-emulator-installer/blob/main/README.md#license + */ + public SELF acceptLicense() { addEnv("ACCEPT_EULA", "Y"); - addEnv("CONFIG_PATH", "/home/marv/Downloads/asb/config.json"); + return self(); } } diff --git a/modules/azure/src/test/java/org/testcontainers/containers/ServicebusEmulatorContainerTest.java b/modules/azure/src/test/java/org/testcontainers/containers/ServicebusEmulatorContainerTest.java index 8610abb64ba..526ddf65e7b 100644 --- a/modules/azure/src/test/java/org/testcontainers/containers/ServicebusEmulatorContainerTest.java +++ b/modules/azure/src/test/java/org/testcontainers/containers/ServicebusEmulatorContainerTest.java @@ -1,9 +1,22 @@ package org.testcontainers.containers; +import com.azure.core.util.IterableStream; +import com.azure.messaging.servicebus.ServiceBusClientBuilder; +import com.azure.messaging.servicebus.ServiceBusMessage; +import com.azure.messaging.servicebus.ServiceBusReceivedMessage; +import com.azure.messaging.servicebus.ServiceBusReceiverClient; +import com.azure.messaging.servicebus.ServiceBusSenderClient; +import com.azure.messaging.servicebus.models.ServiceBusReceiveMode; import org.junit.Rule; import org.junit.Test; import org.testcontainers.utility.DockerImageName; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +import static org.assertj.core.api.Assertions.assertThat; + public class ServicebusEmulatorContainerTest { @Rule public ServicebusEmulatorContainer servicebusEmulatorContainer = new ServicebusEmulatorContainer( @@ -11,7 +24,27 @@ public class ServicebusEmulatorContainerTest { ); @Test - public void testWIthASBClient() { - String containerId = servicebusEmulatorContainer.getContainerId(); + public void testWithASBClient() { + Integer mappedPort = servicebusEmulatorContainer.getMappedPort(5672); + List sentMessages = Arrays.asList("Hello World"); + try(ServiceBusSenderClient sender = new ServiceBusClientBuilder() + .connectionString("Endpoint=sb://localhost:" + mappedPort + ";SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=SAS_KEY_VALUE;UseDevelopmentEmulator=true;") + .sender() + .queueName("queue.1") + .buildClient()) { + for (String m : sentMessages) { + sender.sendMessage(new ServiceBusMessage(m)); + } + } + try(ServiceBusReceiverClient reciever = new ServiceBusClientBuilder() + .connectionString("Endpoint=sb://localhost:" + mappedPort + ";SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=SAS_KEY_VALUE;UseDevelopmentEmulator=true;") + .receiver() + .queueName("queue.1") + .receiveMode(ServiceBusReceiveMode.RECEIVE_AND_DELETE) + .buildClient()) { + IterableStream messagesStream = reciever.receiveMessages(sentMessages.size()); + List recievedMessages = messagesStream.stream().map(m -> m.getBody().toString()).collect(Collectors.toList()); + assertThat(recievedMessages).isEqualTo(sentMessages); + } } } diff --git a/modules/azure/src/test/resources/servicebus-config.json b/modules/azure/src/test/resources/servicebus-config.json new file mode 100644 index 00000000000..6f437735787 --- /dev/null +++ b/modules/azure/src/test/resources/servicebus-config.json @@ -0,0 +1,108 @@ +{ + "UserConfig": { + "Namespaces": [ + { + "Name": "sbemulatorns", + "Queues": [ + { + "Name": "queue.1", + "Properties": { + "DeadLetteringOnMessageExpiration": false, + "DefaultMessageTimeToLive": "PT1H", + "DuplicateDetectionHistoryTimeWindow": "PT20S", + "ForwardDeadLetteredMessagesTo": "", + "ForwardTo": "", + "LockDuration": "PT1M", + "MaxDeliveryCount": 10, + "RequiresDuplicateDetection": false, + "RequiresSession": false + } + } + ], + + "Topics": [ + { + "Name": "topic.1", + "Properties": { + "DefaultMessageTimeToLive": "PT1H", + "DuplicateDetectionHistoryTimeWindow": "PT20S", + "RequiresDuplicateDetection": false + }, + "Subscriptions": [ + { + "Name": "subscription.1", + "Properties": { + "DeadLetteringOnMessageExpiration": false, + "DefaultMessageTimeToLive": "PT1H", + "LockDuration": "PT1M", + "MaxDeliveryCount": 10, + "ForwardDeadLetteredMessagesTo": "", + "ForwardTo": "", + "RequiresSession": false + }, + "Rules": [ + { + "Name": "app-prop-filter-1", + "Properties": { + "FilterType": "Correlation", + "CorrelationFilter": { + "ContentType": "application/text", + "CorrelationId": "id1", + "Label": "subject1", + "MessageId": "msgid1", + "ReplyTo": "someQueue", + "ReplyToSessionId": "sessionId", + "SessionId": "session1", + "To": "xyz" + } + } + } + ] + }, + { + "Name": "subscription.2", + "Properties": { + "DeadLetteringOnMessageExpiration": false, + "DefaultMessageTimeToLive": "PT1H", + "LockDuration": "PT1M", + "MaxDeliveryCount": 10, + "ForwardDeadLetteredMessagesTo": "", + "ForwardTo": "", + "RequiresSession": false + }, + "Rules": [ + { + "Name": "user-prop-filter-1", + "Properties": { + "FilterType": "Correlation", + "CorrelationFilter": { + "Properties": { + "prop3": "value3" + } + } + } + } + ] + }, + { + "Name": "subscription.3", + "Properties": { + "DeadLetteringOnMessageExpiration": false, + "DefaultMessageTimeToLive": "PT1H", + "LockDuration": "PT1M", + "MaxDeliveryCount": 10, + "ForwardDeadLetteredMessagesTo": "", + "ForwardTo": "", + "RequiresSession": false + } + } + ] + } + ] + } + ], + "Logging": { + "Type": "File" + } + } +} From 000dd697108f1a55d0fe7e091f9b23f0971a318c Mon Sep 17 00:00:00 2001 From: "Marvin B. Lillehaug" Date: Tue, 14 Jan 2025 20:28:17 +0100 Subject: [PATCH 3/7] Tests pass, needed azure-messaging-servicebus:7.17.8 --- .../ServicebusEmulatorContainer.java | 14 +++++++- .../ServicebusEmulatorContainerTest.java | 32 ++++++++++++++++--- 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/modules/azure/src/main/java/org/testcontainers/containers/ServicebusEmulatorContainer.java b/modules/azure/src/main/java/org/testcontainers/containers/ServicebusEmulatorContainer.java index 8f337023569..6bf4b7a73c8 100644 --- a/modules/azure/src/main/java/org/testcontainers/containers/ServicebusEmulatorContainer.java +++ b/modules/azure/src/main/java/org/testcontainers/containers/ServicebusEmulatorContainer.java @@ -2,6 +2,7 @@ import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.utility.DockerImageName; +import org.testcontainers.utility.MountableFile; public class ServicebusEmulatorContainer> extends GenericContainer { private static final DockerImageName DEFAULT_IMAGE_NAME = DockerImageName.parse( @@ -33,7 +34,13 @@ public ServicebusEmulatorContainer(final DockerImageName dockerImageName) { addEnv("MSSQL_SA_PASSWORD", mssqlServerContainer.getPassword()); addEnv("SQL_SERVER", mssqlNetworkAlias); acceptLicense(); - addEnv("CONFIG_PATH", "/home/marvin.lillehaug/src/testcontainers-java/modules/azure/src/test/resources/servicebus-config.json"); + } + + public SELF withConfigFile(MountableFile configFile) { + return withCopyFileToContainer( + configFile, + "/ServiceBus_Emulator/ConfigFiles/Config.json" + ); } /** @@ -44,4 +51,9 @@ public SELF acceptLicense() { addEnv("ACCEPT_EULA", "Y"); return self(); } + + public String getConnectionString() { + Integer mappedPort = getMappedPort(5672); + return "Endpoint=sb://localhost:" + mappedPort + ";SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=SAS_KEY_VALUE;UseDevelopmentEmulator=true;"; + } } diff --git a/modules/azure/src/test/java/org/testcontainers/containers/ServicebusEmulatorContainerTest.java b/modules/azure/src/test/java/org/testcontainers/containers/ServicebusEmulatorContainerTest.java index 526ddf65e7b..e4f246ca328 100644 --- a/modules/azure/src/test/java/org/testcontainers/containers/ServicebusEmulatorContainerTest.java +++ b/modules/azure/src/test/java/org/testcontainers/containers/ServicebusEmulatorContainerTest.java @@ -24,11 +24,10 @@ public class ServicebusEmulatorContainerTest { ); @Test - public void testWithASBClient() { - Integer mappedPort = servicebusEmulatorContainer.getMappedPort(5672); + public void testWithDefaultConfig() { List sentMessages = Arrays.asList("Hello World"); try(ServiceBusSenderClient sender = new ServiceBusClientBuilder() - .connectionString("Endpoint=sb://localhost:" + mappedPort + ";SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=SAS_KEY_VALUE;UseDevelopmentEmulator=true;") + .connectionString(servicebusEmulatorContainer.getConnectionString()) .sender() .queueName("queue.1") .buildClient()) { @@ -37,7 +36,7 @@ public void testWithASBClient() { } } try(ServiceBusReceiverClient reciever = new ServiceBusClientBuilder() - .connectionString("Endpoint=sb://localhost:" + mappedPort + ";SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=SAS_KEY_VALUE;UseDevelopmentEmulator=true;") + .connectionString(servicebusEmulatorContainer.getConnectionString()) .receiver() .queueName("queue.1") .receiveMode(ServiceBusReceiveMode.RECEIVE_AND_DELETE) @@ -47,4 +46,29 @@ public void testWithASBClient() { assertThat(recievedMessages).isEqualTo(sentMessages); } } + + + @Test + public void testWithCustomConfig() { + List sentMessages = Arrays.asList("Hello World"); + try(ServiceBusSenderClient sender = new ServiceBusClientBuilder() + .connectionString(servicebusEmulatorContainer.getConnectionString()) + .sender() + .queueName("queue.666") + .buildClient()) { + for (String m : sentMessages) { + sender.sendMessage(new ServiceBusMessage(m)); + } + } + try(ServiceBusReceiverClient reciever = new ServiceBusClientBuilder() + .connectionString(servicebusEmulatorContainer.getConnectionString()) + .receiver() + .queueName("queue.666") + .receiveMode(ServiceBusReceiveMode.RECEIVE_AND_DELETE) + .buildClient()) { + IterableStream messagesStream = reciever.receiveMessages(sentMessages.size()); + List recievedMessages = messagesStream.stream().map(m -> m.getBody().toString()).collect(Collectors.toList()); + assertThat(recievedMessages).isEqualTo(sentMessages); + } + } } From 6b8af57976474b927c8bca3c26a686dfb3dc4f09 Mon Sep 17 00:00:00 2001 From: "Marvin B. Lillehaug" Date: Tue, 14 Jan 2025 20:00:17 +0100 Subject: [PATCH 4/7] Tests pass, needed azure-messaging-servicebus:7.17.8 --- .../ServicebusEmulatorContainerTest.java | 32 +++---------------- 1 file changed, 4 insertions(+), 28 deletions(-) diff --git a/modules/azure/src/test/java/org/testcontainers/containers/ServicebusEmulatorContainerTest.java b/modules/azure/src/test/java/org/testcontainers/containers/ServicebusEmulatorContainerTest.java index e4f246ca328..526ddf65e7b 100644 --- a/modules/azure/src/test/java/org/testcontainers/containers/ServicebusEmulatorContainerTest.java +++ b/modules/azure/src/test/java/org/testcontainers/containers/ServicebusEmulatorContainerTest.java @@ -24,10 +24,11 @@ public class ServicebusEmulatorContainerTest { ); @Test - public void testWithDefaultConfig() { + public void testWithASBClient() { + Integer mappedPort = servicebusEmulatorContainer.getMappedPort(5672); List sentMessages = Arrays.asList("Hello World"); try(ServiceBusSenderClient sender = new ServiceBusClientBuilder() - .connectionString(servicebusEmulatorContainer.getConnectionString()) + .connectionString("Endpoint=sb://localhost:" + mappedPort + ";SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=SAS_KEY_VALUE;UseDevelopmentEmulator=true;") .sender() .queueName("queue.1") .buildClient()) { @@ -36,7 +37,7 @@ public void testWithDefaultConfig() { } } try(ServiceBusReceiverClient reciever = new ServiceBusClientBuilder() - .connectionString(servicebusEmulatorContainer.getConnectionString()) + .connectionString("Endpoint=sb://localhost:" + mappedPort + ";SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=SAS_KEY_VALUE;UseDevelopmentEmulator=true;") .receiver() .queueName("queue.1") .receiveMode(ServiceBusReceiveMode.RECEIVE_AND_DELETE) @@ -46,29 +47,4 @@ public void testWithDefaultConfig() { assertThat(recievedMessages).isEqualTo(sentMessages); } } - - - @Test - public void testWithCustomConfig() { - List sentMessages = Arrays.asList("Hello World"); - try(ServiceBusSenderClient sender = new ServiceBusClientBuilder() - .connectionString(servicebusEmulatorContainer.getConnectionString()) - .sender() - .queueName("queue.666") - .buildClient()) { - for (String m : sentMessages) { - sender.sendMessage(new ServiceBusMessage(m)); - } - } - try(ServiceBusReceiverClient reciever = new ServiceBusClientBuilder() - .connectionString(servicebusEmulatorContainer.getConnectionString()) - .receiver() - .queueName("queue.666") - .receiveMode(ServiceBusReceiveMode.RECEIVE_AND_DELETE) - .buildClient()) { - IterableStream messagesStream = reciever.receiveMessages(sentMessages.size()); - List recievedMessages = messagesStream.stream().map(m -> m.getBody().toString()).collect(Collectors.toList()); - assertThat(recievedMessages).isEqualTo(sentMessages); - } - } } From 66f2fbc75750edef815a89c351d5b962958ba936 Mon Sep 17 00:00:00 2001 From: "Marvin B. Lillehaug" Date: Thu, 16 Jan 2025 20:05:02 +0100 Subject: [PATCH 5/7] Updated documentation and tests --- docs/modules/azure.md | 30 +++++++- .../AzureServicebusEmulatorContainer.java} | 39 ++++++++-- .../AzureServicebusEmulatorContainerTest.java | 74 +++++++++++++++++++ .../ServicebusEmulatorContainerTest.java | 50 ------------- .../src/test/resources/servicebus-config.json | 2 +- 5 files changed, 137 insertions(+), 58 deletions(-) rename modules/azure/src/main/java/org/testcontainers/{containers/ServicebusEmulatorContainer.java => azure/AzureServicebusEmulatorContainer.java} (56%) create mode 100644 modules/azure/src/test/java/org/testcontainers/azure/AzureServicebusEmulatorContainerTest.java delete mode 100644 modules/azure/src/test/java/org/testcontainers/containers/ServicebusEmulatorContainerTest.java diff --git a/docs/modules/azure.md b/docs/modules/azure.md index 19c141c7639..1ce8a0d4940 100644 --- a/docs/modules/azure.md +++ b/docs/modules/azure.md @@ -5,12 +5,13 @@ This module is INCUBATING. While it is ready for use and operational in the curr Testcontainers module for the Microsoft Azure's [SDK](https://github.com/Azure/azure-sdk-for-java). -Currently, the module supports `Azurite` and `CosmosDB` emulators. In order to use them, you should use the following classes: +Currently, the module supports `Azurite`, `CosmosDB`, and `Servicebus` emulators. In order to use them, you should use the following classes: Class | Container Image -|- AzuriteContainer | [mcr.microsoft.com/azure-storage/azurite](https://github.com/microsoft/containerregistry) CosmosDBEmulatorContainer | [mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator](https://github.com/microsoft/containerregistry) +AzureServicebusEmulatorContainer | [mcr.microsoft.com/azure-messaging/servicebus-emulator](https://github.com/microsoft/containerregistry) ## Usage example @@ -104,6 +105,33 @@ Test against the Emulator: [Testing against Azure CosmosDB Emulator container](../../modules/azure/src/test/java/org/testcontainers/containers/CosmosDBEmulatorContainerTest.java) inside_block:testWithClientAgainstEmulatorContainer +### Azure service bus Emulator + +Start Azure service bus Emulator during a test: + + +[Starting a Azure Service bus Emulator container](../../modules/azure/src/test/java/org/testcontainers/azure/AzureServicebusEmulatorContainerTest.java) inside_block:emulatorContainerDefaultConfig + + +!!! note + This starts the service bus emulator with the [default config](https://github.com/Azure/azure-service-bus-emulator-installer/blob/main/ServiceBus-Emulator/Config/Config.json) + +Start Azure service bus Emulator with custom config during a test: + + +[Starting a Azure Service bus Emulator container with custom config](../../modules/azure/src/test/java/org/testcontainers/azure/AzureServicebusEmulatorContainerTest.java) inside_block:emulatorContainerCustomConfig + + +Build Azure Service bus sender client: + + +[Testing against Azure Service bus Emulator container](../../modules/azure/src/test/java/org/testcontainers/azure/AzureServicebusEmulatorContainerTest.java) inside_block:buildClient + + +* See [Overview of the Azure Service Bus emulator](https://learn.microsoft.com/en-us/azure/service-bus-messaging/overview-emulator) for features and limitations. +* [Test locally by using the Azure Service Bus emulator](https://learn.microsoft.com/en-us/azure/service-bus-messaging/test-locally-with-service-bus-emulator?tabs=docker-linux-container) + + ## Adding this module to your project dependencies Add the following dependency to your `pom.xml`/`build.gradle` file: diff --git a/modules/azure/src/main/java/org/testcontainers/containers/ServicebusEmulatorContainer.java b/modules/azure/src/main/java/org/testcontainers/azure/AzureServicebusEmulatorContainer.java similarity index 56% rename from modules/azure/src/main/java/org/testcontainers/containers/ServicebusEmulatorContainer.java rename to modules/azure/src/main/java/org/testcontainers/azure/AzureServicebusEmulatorContainer.java index 6bf4b7a73c8..5b8f1bb8159 100644 --- a/modules/azure/src/main/java/org/testcontainers/containers/ServicebusEmulatorContainer.java +++ b/modules/azure/src/main/java/org/testcontainers/azure/AzureServicebusEmulatorContainer.java @@ -1,10 +1,30 @@ -package org.testcontainers.containers; +package org.testcontainers.azure; +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.containers.MSSQLServerContainer; +import org.testcontainers.containers.Network; import org.testcontainers.containers.wait.strategy.Wait; import org.testcontainers.utility.DockerImageName; import org.testcontainers.utility.MountableFile; -public class ServicebusEmulatorContainer> extends GenericContainer { +/** + * Testcontainers implementation for Azure service bus emulator. + *

+ * Supported image: {@code mcr.microsoft.com/azure-messaging/servicebus-emulator} + *

+ *

Exposed ports: 5672

+ *

+ * If the official client, azure-messaging-servicebus, is used the oldest version supported is 7.17.8. + *

+ *

+ * By default, emulator uses config.json configuration file. + * To supply your own config your own config using {@code withConfigFile(MountableFile)} + *

+ *

+ * The service bus emulator requires a database, so a {@code MSSQLServerContainer} is also started. + *

+ */ +public class AzureServicebusEmulatorContainer extends GenericContainer { private static final DockerImageName DEFAULT_IMAGE_NAME = DockerImageName.parse( "mcr.microsoft.com/azure-messaging/servicebus-emulator" ); @@ -14,7 +34,7 @@ public class ServicebusEmulatorContainerconfig.json + * @return this + */ + public AzureServicebusEmulatorContainer withConfigFile(MountableFile configFile) { return withCopyFileToContainer( configFile, "/ServiceBus_Emulator/ConfigFiles/Config.json" @@ -47,11 +71,14 @@ public SELF withConfigFile(MountableFile configFile) { * Accepts the license for the Azure Service Bus Emulator container by setting the ACCEPT_EULA=Y * variable as described at https://github.com/Azure/azure-service-bus-emulator-installer/blob/main/README.md#license */ - public SELF acceptLicense() { + public AzureServicebusEmulatorContainer acceptLicense() { addEnv("ACCEPT_EULA", "Y"); return self(); } + /** + * @return connection string for connecting to the service bus. + */ public String getConnectionString() { Integer mappedPort = getMappedPort(5672); return "Endpoint=sb://localhost:" + mappedPort + ";SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=SAS_KEY_VALUE;UseDevelopmentEmulator=true;"; diff --git a/modules/azure/src/test/java/org/testcontainers/azure/AzureServicebusEmulatorContainerTest.java b/modules/azure/src/test/java/org/testcontainers/azure/AzureServicebusEmulatorContainerTest.java new file mode 100644 index 00000000000..81d8b1cd618 --- /dev/null +++ b/modules/azure/src/test/java/org/testcontainers/azure/AzureServicebusEmulatorContainerTest.java @@ -0,0 +1,74 @@ +package org.testcontainers.azure; + +import com.azure.core.util.IterableStream; +import com.azure.messaging.servicebus.ServiceBusClientBuilder; +import com.azure.messaging.servicebus.ServiceBusMessage; +import com.azure.messaging.servicebus.ServiceBusReceivedMessage; +import com.azure.messaging.servicebus.ServiceBusReceiverClient; +import com.azure.messaging.servicebus.ServiceBusSenderClient; +import com.azure.messaging.servicebus.models.ServiceBusReceiveMode; +import org.junit.Test; +import org.testcontainers.utility.DockerImageName; +import org.testcontainers.utility.MountableFile; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +import static org.assertj.core.api.Assertions.assertThat; + +public class AzureServicebusEmulatorContainerTest { + + @Test + public void testWithDefaultConfig() { + try( + // emulatorContainerDefaultConfig { + AzureServicebusEmulatorContainer azureServicebusEmulatorContainer = new AzureServicebusEmulatorContainer( + DockerImageName.parse("mcr.microsoft.com/azure-messaging/servicebus-emulator") + ) + // } + ) { + sendAndReceive(azureServicebusEmulatorContainer, "queue.1"); + } + } + + @Test + public void testWithCustomConfig() { + try( + // emulatorContainerCustomConfig { + AzureServicebusEmulatorContainer azureServicebusEmulatorContainer = new AzureServicebusEmulatorContainer( + DockerImageName.parse("mcr.microsoft.com/azure-messaging/servicebus-emulator") + ).withConfigFile(MountableFile.forClasspathResource("/servicebus-config.json")) + // } + ) { + sendAndReceive(azureServicebusEmulatorContainer, "our.queue"); + } + } + + private static void sendAndReceive(AzureServicebusEmulatorContainer azureServicebusEmulatorContainer, String queueName) { + List sentMessages = Arrays.asList("Hello World"); + try ( + // buildClient { + ServiceBusSenderClient sender = new ServiceBusClientBuilder() + .connectionString(azureServicebusEmulatorContainer.getConnectionString()) + .sender() + .queueName(queueName) + .buildClient() + // } + ) { + for (String m : sentMessages) { + sender.sendMessage(new ServiceBusMessage(m)); + } + } + try (ServiceBusReceiverClient reciever = new ServiceBusClientBuilder() + .connectionString(azureServicebusEmulatorContainer.getConnectionString()) + .receiver() + .queueName(queueName) + .receiveMode(ServiceBusReceiveMode.RECEIVE_AND_DELETE) + .buildClient()) { + IterableStream messagesStream = reciever.receiveMessages(sentMessages.size()); + List recievedMessages = messagesStream.stream().map(m -> m.getBody().toString()).collect(Collectors.toList()); + assertThat(recievedMessages).isEqualTo(sentMessages); + } + } +} diff --git a/modules/azure/src/test/java/org/testcontainers/containers/ServicebusEmulatorContainerTest.java b/modules/azure/src/test/java/org/testcontainers/containers/ServicebusEmulatorContainerTest.java deleted file mode 100644 index 526ddf65e7b..00000000000 --- a/modules/azure/src/test/java/org/testcontainers/containers/ServicebusEmulatorContainerTest.java +++ /dev/null @@ -1,50 +0,0 @@ -package org.testcontainers.containers; - -import com.azure.core.util.IterableStream; -import com.azure.messaging.servicebus.ServiceBusClientBuilder; -import com.azure.messaging.servicebus.ServiceBusMessage; -import com.azure.messaging.servicebus.ServiceBusReceivedMessage; -import com.azure.messaging.servicebus.ServiceBusReceiverClient; -import com.azure.messaging.servicebus.ServiceBusSenderClient; -import com.azure.messaging.servicebus.models.ServiceBusReceiveMode; -import org.junit.Rule; -import org.junit.Test; -import org.testcontainers.utility.DockerImageName; - -import java.util.Arrays; -import java.util.List; -import java.util.stream.Collectors; - -import static org.assertj.core.api.Assertions.assertThat; - -public class ServicebusEmulatorContainerTest { - @Rule - public ServicebusEmulatorContainer servicebusEmulatorContainer = new ServicebusEmulatorContainer( - DockerImageName.parse("mcr.microsoft.com/azure-messaging/servicebus-emulator") - ); - - @Test - public void testWithASBClient() { - Integer mappedPort = servicebusEmulatorContainer.getMappedPort(5672); - List sentMessages = Arrays.asList("Hello World"); - try(ServiceBusSenderClient sender = new ServiceBusClientBuilder() - .connectionString("Endpoint=sb://localhost:" + mappedPort + ";SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=SAS_KEY_VALUE;UseDevelopmentEmulator=true;") - .sender() - .queueName("queue.1") - .buildClient()) { - for (String m : sentMessages) { - sender.sendMessage(new ServiceBusMessage(m)); - } - } - try(ServiceBusReceiverClient reciever = new ServiceBusClientBuilder() - .connectionString("Endpoint=sb://localhost:" + mappedPort + ";SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=SAS_KEY_VALUE;UseDevelopmentEmulator=true;") - .receiver() - .queueName("queue.1") - .receiveMode(ServiceBusReceiveMode.RECEIVE_AND_DELETE) - .buildClient()) { - IterableStream messagesStream = reciever.receiveMessages(sentMessages.size()); - List recievedMessages = messagesStream.stream().map(m -> m.getBody().toString()).collect(Collectors.toList()); - assertThat(recievedMessages).isEqualTo(sentMessages); - } - } -} diff --git a/modules/azure/src/test/resources/servicebus-config.json b/modules/azure/src/test/resources/servicebus-config.json index 6f437735787..dbac910ad53 100644 --- a/modules/azure/src/test/resources/servicebus-config.json +++ b/modules/azure/src/test/resources/servicebus-config.json @@ -5,7 +5,7 @@ "Name": "sbemulatorns", "Queues": [ { - "Name": "queue.1", + "Name": "our.queue", "Properties": { "DeadLetteringOnMessageExpiration": false, "DefaultMessageTimeToLive": "PT1H", From 8f4f95feab69553019098cb300a53f943ae9ca81 Mon Sep 17 00:00:00 2001 From: "Marvin B. Lillehaug" Date: Thu, 16 Jan 2025 20:05:35 +0100 Subject: [PATCH 6/7] Removed SqlEdgeContainer since it crash on startup. --- .../containers/SqlEdgeContainer.java | 32 ------------------- .../containers/SqlEdgeContainerTest.java | 18 ----------- 2 files changed, 50 deletions(-) delete mode 100644 modules/azure/src/main/java/org/testcontainers/containers/SqlEdgeContainer.java delete mode 100644 modules/azure/src/test/java/org/testcontainers/containers/SqlEdgeContainerTest.java diff --git a/modules/azure/src/main/java/org/testcontainers/containers/SqlEdgeContainer.java b/modules/azure/src/main/java/org/testcontainers/containers/SqlEdgeContainer.java deleted file mode 100644 index 2143d53cdb3..00000000000 --- a/modules/azure/src/main/java/org/testcontainers/containers/SqlEdgeContainer.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.testcontainers.containers; - -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.utility.DockerImageName; - -/** - * Testcontainers implementation for Sql Edge. - *

- * Supported image: {@code mcr.microsoft.com/azure-sql-edge} - *

- * Exposed ports: 1433 - */ -public class SqlEdgeContainer extends GenericContainer { - private static final DockerImageName DEFAULT_IMAGE_NAME = DockerImageName.parse( - "mcr.microsoft.com/azure-sql-edge" - ); - - private static final int PORT = 1433; - - /** - * @param dockerImageName specified docker image name to run - */ - public SqlEdgeContainer(final DockerImageName dockerImageName) { - super(dockerImageName); - dockerImageName.assertCompatibleWith(DEFAULT_IMAGE_NAME); - withExposedPorts(PORT); - waitingFor(Wait.forLogMessage(".*Service Broker manager has started.\\r\\n$", 1)); - addEnv("ACCEPT_EULA", "Y"); - addEnv("MSSQL_SA_PASSWORD", "J3R4uUWLTjDqTXoQnvXu"); - } - -} diff --git a/modules/azure/src/test/java/org/testcontainers/containers/SqlEdgeContainerTest.java b/modules/azure/src/test/java/org/testcontainers/containers/SqlEdgeContainerTest.java deleted file mode 100644 index b105955c7cb..00000000000 --- a/modules/azure/src/test/java/org/testcontainers/containers/SqlEdgeContainerTest.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.testcontainers.containers; - - -import org.junit.Rule; -import org.junit.Test; -import org.testcontainers.utility.DockerImageName; - -public class SqlEdgeContainerTest { - @Rule - public SqlEdgeContainer sqlEdgeContainer = new SqlEdgeContainer( - DockerImageName.parse("mcr.microsoft.com/azure-sql-edge:latest") - ); - - @Test - public void testWithJdbc() { - String host = sqlEdgeContainer.getHost(); - } -} From ef308d79028dbc26be536b24fc7ed837f3164c4f Mon Sep 17 00:00:00 2001 From: "Marvin B. Lillehaug" Date: Thu, 16 Jan 2025 20:38:21 +0100 Subject: [PATCH 7/7] Removed test with default config --- docs/modules/azure.md | 14 +++++----- .../AzureServicebusEmulatorContainerTest.java | 28 ++++++------------- 2 files changed, 15 insertions(+), 27 deletions(-) diff --git a/docs/modules/azure.md b/docs/modules/azure.md index 1ce8a0d4940..2d26be1a8cb 100644 --- a/docs/modules/azure.md +++ b/docs/modules/azure.md @@ -110,17 +110,17 @@ Test against the Emulator: Start Azure service bus Emulator during a test: -[Starting a Azure Service bus Emulator container](../../modules/azure/src/test/java/org/testcontainers/azure/AzureServicebusEmulatorContainerTest.java) inside_block:emulatorContainerDefaultConfig +[Starting a Azure Service bus Emulator container with custom config](../../modules/azure/src/test/java/org/testcontainers/azure/AzureServicebusEmulatorContainerTest.java) inside_block:emulatorContainerCustomConfig !!! note - This starts the service bus emulator with the [default config](https://github.com/Azure/azure-service-bus-emulator-installer/blob/main/ServiceBus-Emulator/Config/Config.json) - -Start Azure service bus Emulator with custom config during a test: + This starts the service bus emulator with a custom config. + To use [default config](https://github.com/Azure/azure-service-bus-emulator-installer/blob/main/ServiceBus-Emulator/Config/Config.json) + omit `withConfigFile(...)`. - -[Starting a Azure Service bus Emulator container with custom config](../../modules/azure/src/test/java/org/testcontainers/azure/AzureServicebusEmulatorContainerTest.java) inside_block:emulatorContainerCustomConfig - +!!! note + The service bus emulator requires a database, so a [MSSQLServerContainer](../../modules/mssqlserver/src/main/java/org/testcontainers/containers/MSSQLServerContainer.java) + is started. Build Azure Service bus sender client: diff --git a/modules/azure/src/test/java/org/testcontainers/azure/AzureServicebusEmulatorContainerTest.java b/modules/azure/src/test/java/org/testcontainers/azure/AzureServicebusEmulatorContainerTest.java index 81d8b1cd618..a51fd7331a1 100644 --- a/modules/azure/src/test/java/org/testcontainers/azure/AzureServicebusEmulatorContainerTest.java +++ b/modules/azure/src/test/java/org/testcontainers/azure/AzureServicebusEmulatorContainerTest.java @@ -19,19 +19,6 @@ public class AzureServicebusEmulatorContainerTest { - @Test - public void testWithDefaultConfig() { - try( - // emulatorContainerDefaultConfig { - AzureServicebusEmulatorContainer azureServicebusEmulatorContainer = new AzureServicebusEmulatorContainer( - DockerImageName.parse("mcr.microsoft.com/azure-messaging/servicebus-emulator") - ) - // } - ) { - sendAndReceive(azureServicebusEmulatorContainer, "queue.1"); - } - } - @Test public void testWithCustomConfig() { try( @@ -41,19 +28,20 @@ public void testWithCustomConfig() { ).withConfigFile(MountableFile.forClasspathResource("/servicebus-config.json")) // } ) { - sendAndReceive(azureServicebusEmulatorContainer, "our.queue"); + azureServicebusEmulatorContainer.start(); + sendAndReceive(azureServicebusEmulatorContainer.getConnectionString(), "our.queue"); } } - private static void sendAndReceive(AzureServicebusEmulatorContainer azureServicebusEmulatorContainer, String queueName) { + private static void sendAndReceive(String connectionString, String queueName) { List sentMessages = Arrays.asList("Hello World"); try ( // buildClient { ServiceBusSenderClient sender = new ServiceBusClientBuilder() - .connectionString(azureServicebusEmulatorContainer.getConnectionString()) - .sender() - .queueName(queueName) - .buildClient() + .connectionString(connectionString) + .sender() + .queueName(queueName) + .buildClient() // } ) { for (String m : sentMessages) { @@ -61,7 +49,7 @@ private static void sendAndReceive(AzureServicebusEmulatorContainer azureService } } try (ServiceBusReceiverClient reciever = new ServiceBusClientBuilder() - .connectionString(azureServicebusEmulatorContainer.getConnectionString()) + .connectionString(connectionString) .receiver() .queueName(queueName) .receiveMode(ServiceBusReceiveMode.RECEIVE_AND_DELETE)