Skip to content

Commit 0b3de87

Browse files
committed
chore: Azure SB Emulator for testing & local development (#434)
* test: AzureSB emulator for tests * chore: Support azuresb connection string for local dev * chore: emulator connectionstring in .env.example
1 parent 013f7d3 commit 0b3de87

File tree

14 files changed

+286
-58
lines changed

14 files changed

+286
-58
lines changed

.env.example

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -55,16 +55,19 @@ RABBITMQ_LOG_QUEUE="outpost-log"
5555
# GCP_PUBSUB_LOG_SUBSCRIPTION="outpost-log-sub"
5656

5757
## Azure ServiceBus
58-
AZURE_SERVICEBUS_TENANT_ID=""
59-
AZURE_SERVICEBUS_CLIENT_ID=""
60-
AZURE_SERVICEBUS_CLIENT_SECRET=""
61-
AZURE_SERVICEBUS_SUBSCRIPTION_ID=""
62-
AZURE_SERVICEBUS_RESOURCE_GROUP=""
63-
AZURE_SERVICEBUS_NAMESPACE=""
64-
AZURE_SERVICEBUS_DELIVERY_TOPIC="outpost-delivery"
65-
AZURE_SERVICEBUS_DELIVERY_SUBSCRIPTION="outpost-delivery-sub"
66-
AZURE_SERVICEBUS_LOG_TOPIC="outpost-log"
67-
AZURE_SERVICEBUS_LOG_SUBSCRIPTION="outpost-log-sub"
58+
# AZURE_SERVICEBUS_TENANT_ID=""
59+
# AZURE_SERVICEBUS_CLIENT_ID=""
60+
# AZURE_SERVICEBUS_CLIENT_SECRET=""
61+
# AZURE_SERVICEBUS_SUBSCRIPTION_ID=""
62+
# AZURE_SERVICEBUS_RESOURCE_GROUP=""
63+
# AZURE_SERVICEBUS_NAMESPACE=""
64+
# AZURE_SERVICEBUS_DELIVERY_TOPIC="outpost-delivery"
65+
# AZURE_SERVICEBUS_DELIVERY_SUBSCRIPTION="outpost-delivery-sub"
66+
# AZURE_SERVICEBUS_LOG_TOPIC="outpost-log"
67+
# AZURE_SERVICEBUS_LOG_SUBSCRIPTION="outpost-log-sub"
68+
# or for local emulator:
69+
# AZURE_SERVICEBUS_CONNECTION_STRING="Endpoint=sb://azuresb;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=SAS_KEY_VALUE;UseDevelopmentEmulator=true;"
70+
6871

6972

7073
# ============================== PublishMQ ==============================

.env.test

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
1+
# DBs
12
TEST_POSTGRES_URL="localhost:35432"
23
TEST_CLICKHOUSE_URL="localhost:39000"
4+
# MQs
5+
TEST_RABBITMQ_URL="localhost:35672"
36
TEST_LOCALSTACK_URL="localhost:34566"
47
TEST_GCP_URL="localhost:38085"
5-
TEST_RABBITMQ_URL="localhost:35672"
8+
TEST_AZURE_SB_CONNSTRING="Endpoint=sb://localhost;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=SAS_KEY_VALUE;UseDevelopmentEmulator=true;"
9+
# Misc
610
TEST_MOCKSERVER_URL="localhost:35555"

Makefile

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,21 @@ down/uptrace:
4141
up/portal:
4242
cd internal/portal && npm install && npm run dev
4343

44+
up/azure:
45+
docker compose -f build/dev/azure/compose.yml up -d
46+
47+
down/azure:
48+
docker compose -f build/dev/azure/compose.yml down --volumes
49+
4450
up/test:
4551
docker-compose -f build/test/compose.yml up -d
4652

4753
down/test:
4854
docker-compose -f build/test/compose.yml down --volumes
4955

56+
test/setup:
57+
bash scripts/test-setup-info.sh
58+
5059
test:
5160
go test $(TEST) $(TESTARGS)
5261

build/dev/azure/compose.yml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
name: "outpost-azure"
2+
3+
services:
4+
azuresb:
5+
image: mcr.microsoft.com/azure-messaging/servicebus-emulator:latest
6+
volumes:
7+
- "./config.json:/ServiceBus_Emulator/ConfigFiles/Config.json"
8+
ports:
9+
- "5672:5672"
10+
- "5300:5300"
11+
environment:
12+
SQL_SERVER: sqledge
13+
MSSQL_SA_PASSWORD: "Password!"
14+
ACCEPT_EULA: "Y"
15+
SQL_WAIT_INTERVAL: "5"
16+
depends_on:
17+
- sqledge
18+
19+
sqledge:
20+
image: mcr.microsoft.com/azure-sql-edge:latest
21+
environment:
22+
ACCEPT_EULA: "Y"
23+
MSSQL_SA_PASSWORD: "Password!"
24+
25+
networks:
26+
default:
27+
name: outpost
28+
external: true

build/dev/azure/config.json

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
{
2+
"UserConfig": {
3+
"Namespaces": [
4+
{
5+
"Name": "sbemulatorns",
6+
"Queues": [],
7+
"Topics": [
8+
// dev
9+
{
10+
"Name": "outpost-delivery",
11+
"Properties": {},
12+
"Subscriptions": [
13+
{
14+
"Name": "outpost-delivery-sub",
15+
"Properties": {
16+
"MaxDeliveryCount": 6
17+
},
18+
"Rules": []
19+
}
20+
]
21+
},
22+
{
23+
"Name": "outpost-log",
24+
"Properties": {},
25+
"Subscriptions": [
26+
{
27+
"Name": "outpost-log-sub",
28+
"Properties": {
29+
"MaxDeliveryCount": 6
30+
},
31+
"Rules": []
32+
}
33+
]
34+
},
35+
36+
// tests
37+
{
38+
"Name": "TestIntegrationMQ_AzureServiceBus-topic",
39+
"Properties": {},
40+
"Subscriptions": [
41+
{
42+
"Name": "TestIntegrationMQ_AzureServiceBus-subscription",
43+
"Properties": {},
44+
"Rules": []
45+
}
46+
]
47+
}
48+
]
49+
}
50+
],
51+
"Logging": {
52+
"Type": "Console"
53+
}
54+
}
55+
}

build/dev/deps/compose.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,9 @@ services:
6363
rabbitmq:
6464
image: rabbitmq:3-management
6565
ports:
66-
- 5672:5672
66+
# Reserve 5672 for AzureSB Emulator which doens't support custom ports.
67+
# We may not need to expose 5672 at all if we run the full local dev env with Docker Compose.
68+
# - 5673:5672
6769
- 15672:15672
6870
volumes:
6971
- rabbitmq:/var/lib/rabbitmq

internal/config/mqconfig_azure.go

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ import (
88
)
99

1010
type AzureServiceBusConfig struct {
11+
// Using AzureSB with ConnectionString will skip infra management
12+
ConnectionString string `yaml:"connection_string" env:"AZURE_SERVICEBUS_CONNECTION_STRING" desc:"Azure Service Bus connection string" required:"N"`
13+
1114
TenantID string `yaml:"tenant_id" env:"AZURE_SERVICEBUS_TENANT_ID" desc:"Azure Active Directory tenant ID" required:"Y"`
1215
ClientID string `yaml:"client_id" env:"AZURE_SERVICEBUS_CLIENT_ID" desc:"Service principal client ID" required:"Y"`
1316
ClientSecret string `yaml:"client_secret" env:"AZURE_SERVICEBUS_CLIENT_SECRET" desc:"Service principal client secret" required:"Y"`
@@ -16,17 +19,17 @@ type AzureServiceBusConfig struct {
1619
Namespace string `yaml:"namespace" env:"AZURE_SERVICEBUS_NAMESPACE" desc:"Azure Service Bus namespace" required:"Y"`
1720

1821
DeliveryTopic string `yaml:"delivery_topic" env:"AZURE_SERVICEBUS_DELIVERY_TOPIC" desc:"Topic name for delivery queue" required:"N" default:"outpost-delivery"`
19-
DeliverySubscription string `yaml:"delivery_subscription" env:"AZURE_SERVICEBUS_DELIVERY_SUBSCRIPTION" desc:"Subscription name for delivery queue" required:"N" default:"outpost-delivery-subscription"`
22+
DeliverySubscription string `yaml:"delivery_subscription" env:"AZURE_SERVICEBUS_DELIVERY_SUBSCRIPTION" desc:"Subscription name for delivery queue" required:"N" default:"outpost-delivery-sub"`
2023
LogTopic string `yaml:"log_topic" env:"AZURE_SERVICEBUS_LOG_TOPIC" desc:"Topic name for log queue" required:"N" default:"outpost-log"`
21-
LogSubscription string `yaml:"log_subscription" env:"AZURE_SERVICEBUS_LOG_SUBSCRIPTION" desc:"Subscription name for log queue" required:"N" default:"outpost-log-subscription"`
24+
LogSubscription string `yaml:"log_subscription" env:"AZURE_SERVICEBUS_LOG_SUBSCRIPTION" desc:"Subscription name for log queue" required:"N" default:"outpost-log-sub"`
2225

2326
// connectionStringOnce sync.Once
2427
// connectionString string
2528
// connectionStringError error
2629
}
2730

2831
func (c *AzureServiceBusConfig) IsConfigured() bool {
29-
return c.TenantID != "" && c.ClientID != "" && c.ClientSecret != "" && c.SubscriptionID != "" && c.ResourceGroup != "" && c.Namespace != ""
32+
return c.ConnectionString != "" || (c.TenantID != "" && c.ClientID != "" && c.ClientSecret != "" && c.SubscriptionID != "" && c.ResourceGroup != "" && c.Namespace != "")
3033
}
3134

3235
func (c *AzureServiceBusConfig) GetProviderType() string {
@@ -65,14 +68,15 @@ func (c *AzureServiceBusConfig) ToInfraConfig(queueType string) *mqinfra.MQInfra
6568

6669
return &mqinfra.MQInfraConfig{
6770
AzureServiceBus: &mqinfra.AzureServiceBusInfraConfig{
68-
TenantID: c.TenantID,
69-
ClientID: c.ClientID,
70-
ClientSecret: c.ClientSecret,
71-
SubscriptionID: c.SubscriptionID,
72-
ResourceGroup: c.ResourceGroup,
73-
Namespace: c.Namespace,
74-
Topic: topic,
75-
Subscription: subscription,
71+
ConnectionString: c.ConnectionString,
72+
TenantID: c.TenantID,
73+
ClientID: c.ClientID,
74+
ClientSecret: c.ClientSecret,
75+
SubscriptionID: c.SubscriptionID,
76+
ResourceGroup: c.ResourceGroup,
77+
Namespace: c.Namespace,
78+
Topic: topic,
79+
Subscription: subscription,
7680
},
7781
}
7882
}
@@ -85,6 +89,16 @@ func (c *AzureServiceBusConfig) ToQueueConfig(ctx context.Context, queueType str
8589
topic := c.getTopicByQueueType(queueType)
8690
subscription := c.getSubscriptionByQueueType(queueType)
8791

92+
if c.ConnectionString != "" {
93+
return &mqs.QueueConfig{
94+
AzureServiceBus: &mqs.AzureServiceBusConfig{
95+
ConnectionString: c.ConnectionString,
96+
Topic: topic,
97+
Subscription: subscription,
98+
},
99+
}, nil
100+
}
101+
88102
return &mqs.QueueConfig{
89103
AzureServiceBus: &mqs.AzureServiceBusConfig{
90104
Topic: topic,

internal/mqinfra/azureservicebus.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ func (infra *infraAzureServiceBus) Exist(ctx context.Context) (bool, error) {
2121

2222
cfg := infra.cfg.AzureServiceBus
2323

24+
if cfg.ConnectionString != "" {
25+
return true, nil
26+
}
27+
2428
// Create credential for authentication
2529
cred, err := azidentity.NewClientSecretCredential(
2630
cfg.TenantID,
@@ -71,6 +75,10 @@ func (infra *infraAzureServiceBus) Declare(ctx context.Context) error {
7175

7276
cfg := infra.cfg.AzureServiceBus
7377

78+
if cfg.ConnectionString != "" {
79+
return nil
80+
}
81+
7482
// Create credential for authentication
7583
cred, err := azidentity.NewClientSecretCredential(
7684
cfg.TenantID,
@@ -146,6 +154,10 @@ func (infra *infraAzureServiceBus) TearDown(ctx context.Context) error {
146154

147155
cfg := infra.cfg.AzureServiceBus
148156

157+
if cfg.ConnectionString != "" {
158+
return nil
159+
}
160+
149161
// Create credential for authentication
150162
cred, err := azidentity.NewClientSecretCredential(
151163
cfg.TenantID,

internal/mqinfra/mqinfra.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ type AWSSQSInfraConfig struct {
3333
}
3434

3535
type AzureServiceBusInfraConfig struct {
36+
ConnectionString string // If set, skip infra management
37+
3638
TenantID string
3739
ClientID string
3840
ClientSecret string

internal/mqinfra/mqinfra_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,7 @@ func TestIntegrationMQInfra_GCPPubSub(t *testing.T) {
324324
}
325325

326326
func TestIntegrationMQInfra_AzureServiceBus(t *testing.T) {
327-
t.Skip("skip AzureServiceBus integration test for now since there's no emulator yet")
327+
t.Skip("skip TestIntegrationMQInfra_AzureServiceBus integration test for now since the emulator doesn't support managing resources")
328328

329329
topic := uuid.New().String()
330330
subscription := topic + "-subscription"

0 commit comments

Comments
 (0)