Skip to content

Commit 116b70d

Browse files
committed
Create new project: spring-cloud-azure-docker-compose/service-bus/spring-messaging
1 parent ac11e2d commit 116b70d

5 files changed

Lines changed: 302 additions & 0 deletions

File tree

pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@
7979
<module>storage/spring-cloud-azure-starter-storage-file-share/storage-file-sample</module>
8080
<module>storage/spring-cloud-azure-starter-storage-queue/storage-queue-client</module>
8181
<module>storage/spring-messaging-azure-storage-queue/storage-queue-spring-messaging</module>
82+
<module>spring-cloud-azure-docker-compose/service-bus/spring-messaging</module>
8283
<module>spring-cloud-azure-docker-compose/storage-blob</module>
8384
<module>spring-cloud-azure-testcontainers/cosmos</module>
8485
<module>spring-cloud-azure-testcontainers/service-bus/spring-cloud-stream-binders</module>
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
3+
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xmlns="http://maven.apache.org/POM/4.0.0"
5+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
6+
<modelVersion>4.0.0</modelVersion>
7+
8+
<parent>
9+
<groupId>org.springframework.boot</groupId>
10+
<artifactId>spring-boot-starter-parent</artifactId>
11+
<version>4.0.3</version>
12+
<relativePath/> <!-- lookup parent from repository -->
13+
</parent>
14+
15+
<groupId>com.azure.spring</groupId>
16+
<artifactId>spring-cloud-azure-docker-compose-for-service-bus-spring-messaging-sample</artifactId>
17+
<version>1.0.0</version>
18+
<packaging>jar</packaging>
19+
20+
<properties>
21+
<version.spring.cloud.azure>7.1.0-beta.1</version.spring.cloud.azure> <!--TODO: Change this version-->
22+
</properties>
23+
24+
<dependencyManagement>
25+
<dependencies>
26+
<dependency>
27+
<groupId>com.azure.spring</groupId>
28+
<artifactId>spring-cloud-azure-dependencies</artifactId>
29+
<version>${version.spring.cloud.azure}</version>
30+
<type>pom</type>
31+
<scope>import</scope>
32+
</dependency>
33+
</dependencies>
34+
</dependencyManagement>
35+
36+
<dependencies>
37+
<dependency>
38+
<groupId>com.azure.spring</groupId>
39+
<artifactId>spring-messaging-azure-servicebus</artifactId>
40+
</dependency>
41+
<dependency>
42+
<groupId>com.azure.spring</groupId>
43+
<artifactId>spring-cloud-azure-starter</artifactId>
44+
</dependency>
45+
<dependency>
46+
<groupId>org.springframework.boot</groupId>
47+
<artifactId>spring-boot-starter-test</artifactId>
48+
<scope>test</scope>
49+
</dependency>
50+
<dependency>
51+
<groupId>com.azure.spring</groupId>
52+
<artifactId>spring-cloud-azure-docker-compose</artifactId>
53+
<scope>test</scope>
54+
</dependency>
55+
</dependencies>
56+
57+
</project>
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
import com.azure.messaging.servicebus.ServiceBusMessage;
2+
import com.azure.messaging.servicebus.ServiceBusSenderClient;
3+
import com.azure.spring.cloud.autoconfigure.implementation.context.AzureGlobalPropertiesAutoConfiguration;
4+
import com.azure.spring.cloud.autoconfigure.implementation.servicebus.AzureServiceBusAutoConfiguration;
5+
import com.azure.spring.cloud.autoconfigure.implementation.servicebus.AzureServiceBusMessagingAutoConfiguration;
6+
import com.azure.spring.cloud.autoconfigure.implementation.servicebus.properties.AzureServiceBusConnectionDetails;
7+
import com.azure.spring.cloud.service.servicebus.consumer.ServiceBusErrorHandler;
8+
import com.azure.spring.cloud.service.servicebus.consumer.ServiceBusRecordMessageListener;
9+
import com.azure.spring.messaging.servicebus.core.ServiceBusTemplate;
10+
import org.junit.jupiter.api.Test;
11+
import org.springframework.beans.factory.annotation.Autowired;
12+
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
13+
import org.springframework.boot.test.context.SpringBootTest;
14+
import org.springframework.context.annotation.Bean;
15+
import org.springframework.context.annotation.Configuration;
16+
import org.springframework.messaging.support.MessageBuilder;
17+
18+
import java.time.Duration;
19+
import java.util.Set;
20+
import java.util.concurrent.ConcurrentHashMap;
21+
22+
import static org.assertj.core.api.Assertions.assertThat;
23+
import static org.awaitility.Awaitility.waitAtMost;
24+
25+
@SpringBootTest(properties = {
26+
"spring.docker.compose.skip.in-tests=false",
27+
"spring.docker.compose.file=classpath:servicebus-compose.yaml",
28+
"spring.docker.compose.stop.command=down",
29+
"spring.docker.compose.readiness.timeout=PT5M",
30+
"spring.cloud.azure.servicebus.namespace=sbemulatorns",
31+
"spring.cloud.azure.servicebus.entity-name=queue.1",
32+
"spring.cloud.azure.servicebus.entity-type=queue",
33+
"spring.cloud.azure.servicebus.producer.entity-name=queue.1",
34+
"spring.cloud.azure.servicebus.producer.entity-type=queue",
35+
"spring.cloud.azure.servicebus.processor.entity-name=queue.1",
36+
"spring.cloud.azure.servicebus.processor.entity-type=queue"
37+
})
38+
class ServiceBusDockerComposeTest {
39+
40+
@Autowired
41+
private AzureServiceBusConnectionDetails connectionDetails;
42+
43+
@Autowired
44+
private ServiceBusSenderClient senderClient;
45+
46+
@Autowired
47+
private ServiceBusTemplate serviceBusTemplate;
48+
49+
@Test
50+
void connectionDetailsShouldBeProvidedByFactory() {
51+
assertThat(connectionDetails).isNotNull();
52+
assertThat(connectionDetails.getConnectionString())
53+
.isNotBlank()
54+
.startsWith("Endpoint=sb://");
55+
}
56+
57+
@Test
58+
void senderClientCanSendMessage() {
59+
// Wait for Service Bus emulator to be fully ready and queue entity to be available
60+
// The emulator depends on SQL Edge and needs time to initialize the messaging entities
61+
waitAtMost(Duration.ofSeconds(120)).pollInterval(Duration.ofSeconds(2)).untilAsserted(() -> {
62+
this.senderClient.sendMessage(new ServiceBusMessage("Hello World!"));
63+
});
64+
65+
waitAtMost(Duration.ofSeconds(30)).pollDelay(Duration.ofSeconds(5)).untilAsserted(() -> {
66+
assertThat(Config.MESSAGES).contains("Hello World!");
67+
});
68+
}
69+
70+
@Test
71+
void serviceBusTemplateCanSendMessage() {
72+
// Wait for Service Bus emulator to be fully ready and queue entity to be available
73+
// The emulator depends on SQL Edge and needs time to initialize the messaging entities
74+
waitAtMost(Duration.ofSeconds(120)).pollInterval(Duration.ofSeconds(2)).untilAsserted(() -> {
75+
this.serviceBusTemplate.sendAsync("queue.1", MessageBuilder.withPayload("Hello from ServiceBusTemplate!").build()).block();
76+
});
77+
78+
waitAtMost(Duration.ofSeconds(30)).pollDelay(Duration.ofSeconds(5)).untilAsserted(() -> {
79+
assertThat(Config.MESSAGES).contains("Hello from ServiceBusTemplate!");
80+
});
81+
}
82+
83+
@Configuration(proxyBeanMethods = false)
84+
@ImportAutoConfiguration(classes = {
85+
AzureGlobalPropertiesAutoConfiguration.class,
86+
AzureServiceBusAutoConfiguration.class,
87+
AzureServiceBusMessagingAutoConfiguration.class})
88+
static class Config {
89+
90+
private static final Set<String> MESSAGES = ConcurrentHashMap.newKeySet();
91+
92+
@Bean
93+
ServiceBusRecordMessageListener processMessage() {
94+
return context -> {
95+
MESSAGES.add(context.getMessage().getBody().toString());
96+
};
97+
}
98+
99+
@Bean
100+
ServiceBusErrorHandler errorHandler() {
101+
// No-op error handler for tests: acknowledge errors without affecting test execution.
102+
return (context) -> {
103+
};
104+
}
105+
}
106+
}
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
{
2+
"UserConfig": {
3+
"Namespaces": [
4+
{
5+
"Name": "sbemulatorns",
6+
"Queues": [
7+
{
8+
"Name": "queue.1",
9+
"Properties": {
10+
"DeadLetteringOnMessageExpiration": false,
11+
"DefaultMessageTimeToLive": "PT1H",
12+
"DuplicateDetectionHistoryTimeWindow": "PT20S",
13+
"ForwardDeadLetteredMessagesTo": "",
14+
"ForwardTo": "",
15+
"LockDuration": "PT1M",
16+
"MaxDeliveryCount": 10,
17+
"RequiresDuplicateDetection": false,
18+
"RequiresSession": false
19+
}
20+
}
21+
],
22+
23+
"Topics": [
24+
{
25+
"Name": "topic.1",
26+
"Properties": {
27+
"DefaultMessageTimeToLive": "PT1H",
28+
"DuplicateDetectionHistoryTimeWindow": "PT20S",
29+
"RequiresDuplicateDetection": false
30+
},
31+
"Subscriptions": [
32+
{
33+
"Name": "subscription.1",
34+
"Properties": {
35+
"DeadLetteringOnMessageExpiration": false,
36+
"DefaultMessageTimeToLive": "PT1H",
37+
"LockDuration": "PT1M",
38+
"MaxDeliveryCount": 10,
39+
"ForwardDeadLetteredMessagesTo": "",
40+
"ForwardTo": "",
41+
"RequiresSession": false
42+
},
43+
"Rules": [
44+
{
45+
"Name": "app-prop-filter-1",
46+
"Properties": {
47+
"FilterType": "Correlation",
48+
"CorrelationFilter": {
49+
"ContentType": "application/text",
50+
"CorrelationId": "id1",
51+
"Label": "subject1",
52+
"MessageId": "msgid1",
53+
"ReplyTo": "someQueue",
54+
"ReplyToSessionId": "sessionId",
55+
"SessionId": "session1",
56+
"To": "xyz"
57+
}
58+
}
59+
}
60+
]
61+
},
62+
{
63+
"Name": "subscription.2",
64+
"Properties": {
65+
"DeadLetteringOnMessageExpiration": false,
66+
"DefaultMessageTimeToLive": "PT1H",
67+
"LockDuration": "PT1M",
68+
"MaxDeliveryCount": 10,
69+
"ForwardDeadLetteredMessagesTo": "",
70+
"ForwardTo": "",
71+
"RequiresSession": false
72+
},
73+
"Rules": [
74+
{
75+
"Name": "user-prop-filter-1",
76+
"Properties": {
77+
"FilterType": "Correlation",
78+
"CorrelationFilter": {
79+
"Properties": {
80+
"prop3": "value3"
81+
}
82+
}
83+
}
84+
}
85+
]
86+
},
87+
{
88+
"Name": "subscription.3",
89+
"Properties": {
90+
"DeadLetteringOnMessageExpiration": false,
91+
"DefaultMessageTimeToLive": "PT1H",
92+
"LockDuration": "PT1M",
93+
"MaxDeliveryCount": 10,
94+
"ForwardDeadLetteredMessagesTo": "",
95+
"ForwardTo": "",
96+
"RequiresSession": false
97+
}
98+
}
99+
]
100+
}
101+
]
102+
}
103+
],
104+
"Logging": {
105+
"Type": "File"
106+
}
107+
}
108+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
services:
2+
servicebus:
3+
image: mcr.microsoft.com/azure-messaging/servicebus-emulator:latest
4+
pull_policy: always
5+
volumes:
6+
- "./Config.json:/ServiceBus_Emulator/ConfigFiles/Config.json"
7+
ports:
8+
- "5672"
9+
environment:
10+
SQL_SERVER: sqledge
11+
MSSQL_SA_PASSWORD: A_Str0ng_Required_Password
12+
ACCEPT_EULA: Y
13+
depends_on:
14+
- sqledge
15+
networks:
16+
sb-emulator:
17+
aliases:
18+
- "sb-emulator"
19+
sqledge:
20+
image: "mcr.microsoft.com/azure-sql-edge:latest"
21+
networks:
22+
sb-emulator:
23+
aliases:
24+
- "sqledge"
25+
environment:
26+
ACCEPT_EULA: Y
27+
MSSQL_SA_PASSWORD: A_Str0ng_Required_Password
28+
29+
networks:
30+
sb-emulator:

0 commit comments

Comments
 (0)