Skip to content

Commit 7564e43

Browse files
Paul ReardonPaul Reardon
authored andcommitted
Add Sample and Readme.MD
1 parent 40ae976 commit 7564e43

File tree

16 files changed

+369
-2
lines changed

16 files changed

+369
-2
lines changed

README.md

Lines changed: 102 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,102 @@
1-
# AzureServiceBusEmulator.Configuration
2-
A Library to help build Azure Service Bus configuration files
1+
## AzureServiceBusEmulator.Configuration Package
2+
3+
This library contains a library that can be used to programaticaly generate Configuration files for [Azure Service Bus Emulator](https://learn.microsoft.com/en-us/azure/service-bus-messaging/overview-emulator) so that they can be used for local development setups.
4+
5+
### The Configuration Builder
6+
The configuration Builder `AsbEmulatorConfigurationBuilder` is the entry-point into this project
7+
8+
The Create configuration for a Namespace with two Queues and a Topic
9+
10+
```csharp
11+
var asbEmulatorConfig = AsbEmulatorConfigurationBuilder.WithNamespace("local", nOptions =>
12+
nOptions.WithQueue("Queue1")
13+
.WithQueue("Queue2")
14+
.WithTopic("Topic1", tOptions =>
15+
tOptions.WithSubscription("Subscription1")
16+
.WithSubscription("Subscription2"))
17+
).Build();
18+
19+
File.WriteAllText("Config.json", JsonSerializer.Serialize(asbEmulatorConfig, new JsonSerializerOptions() { WriteIndented = true }));
20+
```
21+
22+
This will produce the following Config file:
23+
24+
```json
25+
{
26+
"UserConfig" : {
27+
"Namespaces" : [ {
28+
"Name" : "local",
29+
"Queues" : [ {
30+
"Name" : "Queue1",
31+
"Properties" : {
32+
"DeadLetteringOnMessageExpiration" : false,
33+
"DefaultMessageTimeToLive" : "PT1H",
34+
"DuplicateDetectionHistoryTimeWindow" : "PT20S",
35+
"ForwardDeadLetteredMessagesTo" : "",
36+
"ForwardTo" : "",
37+
"LockDuration" : "PT1M",
38+
"MaxDeliveryCount" : 3,
39+
"RequiresDuplicateDetection" : false,
40+
"RequiresSession" : false
41+
}
42+
}, {
43+
"Name" : "Queue2",
44+
"Properties" : {
45+
"DeadLetteringOnMessageExpiration" : false,
46+
"DefaultMessageTimeToLive" : "PT1H",
47+
"DuplicateDetectionHistoryTimeWindow" : "PT20S",
48+
"ForwardDeadLetteredMessagesTo" : "",
49+
"ForwardTo" : "",
50+
"LockDuration" : "PT1M",
51+
"MaxDeliveryCount" : 3,
52+
"RequiresDuplicateDetection" : false,
53+
"RequiresSession" : false
54+
}
55+
} ],
56+
"Topics" : [ {
57+
"Name" : "Topic1",
58+
"Properties" : {
59+
"DefaultMessageTimeToLive" : "PT1H",
60+
"DuplicateDetectionHistoryTimeWindow" : "PT20S",
61+
"RequiresDuplicateDetection" : false
62+
},
63+
"Subscriptions" : [ {
64+
"Name" : "Subscription1",
65+
"Properties" : {
66+
"DeadLetteringOnMessageExpiration" : false,
67+
"DefaultMessageTimeToLive" : "PT1H",
68+
"DuplicateDetectionHistoryTimeWindow" : "PT20S",
69+
"ForwardDeadLetteredMessagesTo" : "",
70+
"ForwardTo" : "",
71+
"LockDuration" : "PT1M",
72+
"MaxDeliveryCount" : 3,
73+
"RequiresDuplicateDetection" : false,
74+
"RequiresSession" : false
75+
},
76+
"Rules" : [ ]
77+
}, {
78+
"Name" : "Subscription2",
79+
"Properties" : {
80+
"DeadLetteringOnMessageExpiration" : false,
81+
"DefaultMessageTimeToLive" : "PT1H",
82+
"DuplicateDetectionHistoryTimeWindow" : "PT20S",
83+
"ForwardDeadLetteredMessagesTo" : "",
84+
"ForwardTo" : "",
85+
"LockDuration" : "PT1M",
86+
"MaxDeliveryCount" : 3,
87+
"RequiresDuplicateDetection" : false,
88+
"RequiresSession" : false
89+
},
90+
"Rules" : [ ]
91+
} ]
92+
} ]
93+
} ],
94+
"Logging" : {
95+
"Type" : "File"
96+
}
97+
}
98+
}
99+
```
100+
101+
### Samples
102+
- [ASBExample](samples/ASBExample/Readme.md) : This is a Basic Example the that generates the ASB Emulator Config file based on all Topics that it knows about.

samples/ASBExample/.env

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Environment file for user defined variables in docker-compose.yml
2+
3+
# 1. CONFIG_PATH: Path to Config.json file
4+
# Ex: CONFIG_PATH="C:\\Config\\Config.json"
5+
CONFIG_PATH="./Config.json"
6+
7+
# 2. ACCEPT_EULA: Pass 'Y' to accept license terms for Azure SQL Edge and Azure Service Bus emulator.
8+
# Service Bus emulator EULA : https://github.com/Azure/azure-service-bus-emulator-installer/blob/main/EMULATOR_EULA.txt
9+
# SQL Edge EULA : https://go.microsoft.com/fwlink/?linkid=2139274
10+
ACCEPT_EULA="Y"
11+
12+
# 3. MSSQL_SA_PASSWORD to be filled by user as per policy : https://learn.microsoft.com/en-us/sql/relational-databases/security/strong-passwords?view=sql-server-linux-ver16
13+
SQL_PASSWORD: "Password123!"

samples/ASBExample/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Config.json
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net8.0</TargetFramework>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
<Nullable>enable</Nullable>
8+
</PropertyGroup>
9+
10+
<ItemGroup>
11+
<PackageReference Include="Azure.Messaging.ServiceBus" />
12+
<PackageReference Include="ReardonTech.AzureServiceBusEmulator.Configuration" />
13+
</ItemGroup>
14+
15+
<ItemGroup>
16+
<ProjectReference Include="..\ASBExample.Shared\ASBExample.Shared.csproj" />
17+
</ItemGroup>
18+
19+
</Project>
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
using System.Text.Json;
2+
using ASBExample.Shared;
3+
using Azure.Messaging.ServiceBus;
4+
using ReardonTech.AzureServiceBusEmulator.Configuration;
5+
6+
const string workerSubscription = "ASBExample-ReceiverConsole";
7+
8+
#if DEBUG
9+
// Generate Files
10+
var asbEmulatorConfig = AsbEmulatorConfigurationBuilder.WithNamespace("local", nOptions =>
11+
{
12+
foreach (var topic in MessageAddresses.Topics)
13+
{
14+
nOptions.WithTopic(topic.Value, tOptions => tOptions.WithSubscription(workerSubscription));
15+
}
16+
}).Build();
17+
18+
var contentPath = AppDomain.CurrentDomain.BaseDirectory;
19+
File.WriteAllText(Path.Combine(contentPath, "..\\..\\..\\..\\Config.json"), JsonSerializer.Serialize(asbEmulatorConfig, new JsonSerializerOptions() { WriteIndented = true }));
20+
21+
#endif
22+
// Rest of Application
23+
24+
var client = new ServiceBusClient("Endpoint=sb://localhost;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=SAS_KEY_VALUE;UseDevelopmentEmulator=true;");
25+
26+
var commandProcessor = client.CreateProcessor(MessageAddresses.GetTopic<GreetingCommand>(), workerSubscription);
27+
commandProcessor.ProcessMessageAsync += async (ProcessMessageEventArgs args) =>
28+
{
29+
var greeting = args.Message.Body.ToObjectFromJson<GreetingCommand>();
30+
var greetingName = greeting?.Name ?? "Name Unknown";
31+
var greetingMessage = "Hello " + greetingName;
32+
33+
Console.WriteLine(greetingMessage);
34+
var sender = client.CreateSender(MessageAddresses.GetTopic<GreetingEvent>());
35+
36+
var greetingEvent = new GreetingEvent(greetingName, greetingMessage);
37+
await sender.SendMessageAsync(new ServiceBusMessage(JsonSerializer.Serialize(greetingEvent)));
38+
};
39+
commandProcessor.ProcessErrorAsync += (ProcessErrorEventArgs args) => { Console.WriteLine(args.Exception);
40+
return Task.CompletedTask;
41+
};
42+
43+
var eventProcessor = client.CreateProcessor(MessageAddresses.GetTopic<GreetingEvent>(), workerSubscription);
44+
eventProcessor.ProcessMessageAsync += (ProcessMessageEventArgs args) =>
45+
{
46+
Console.WriteLine(args.Message.Body.ToObjectFromJson<GreetingEvent>());
47+
return Task.CompletedTask;
48+
};
49+
eventProcessor.ProcessErrorAsync += (ProcessErrorEventArgs args) => { Console.WriteLine(args.Exception);
50+
return Task.CompletedTask;
51+
};
52+
53+
await commandProcessor.StartProcessingAsync(CancellationToken.None);
54+
await eventProcessor.StartProcessingAsync(CancellationToken.None);
55+
56+
Console.WriteLine("Press any key to stop the receiver.");
57+
Console.ReadKey();
58+
await commandProcessor.StopProcessingAsync(CancellationToken.None);
59+
await eventProcessor.StopProcessingAsync(CancellationToken.None);
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net8.0</TargetFramework>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
<Nullable>enable</Nullable>
8+
</PropertyGroup>
9+
10+
<ItemGroup>
11+
<ProjectReference Include="..\ASBExample.Shared\ASBExample.Shared.csproj" />
12+
</ItemGroup>
13+
14+
<ItemGroup>
15+
<PackageReference Include="Azure.Messaging.ServiceBus" />
16+
</ItemGroup>
17+
18+
</Project>
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
using System.Text.Json;
2+
using ASBExample.Shared;
3+
using Azure.Messaging.ServiceBus;
4+
5+
var client =
6+
new ServiceBusClient(
7+
"Endpoint=sb://localhost;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=SAS_KEY_VALUE;UseDevelopmentEmulator=true;");
8+
9+
var greetingSender = client.CreateSender(MessageAddresses.GetTopic<GreetingCommand>());
10+
11+
Console.WriteLine("Type any name and press Enter to send a greeting, or q and enter to exit:");
12+
13+
var running = true;
14+
while (running)
15+
{
16+
var input = Console.ReadLine() ?? "Name not Provided";
17+
if(input == "q")
18+
running = false;
19+
else
20+
{
21+
var greetingCommand = new GreetingCommand(input);
22+
await greetingSender.SendMessageAsync(new ServiceBusMessage(JsonSerializer.Serialize(greetingCommand)));
23+
}
24+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net8.0</TargetFramework>
5+
<ImplicitUsings>enable</ImplicitUsings>
6+
<Nullable>enable</Nullable>
7+
</PropertyGroup>
8+
9+
</Project>
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
namespace ASBExample.Shared;
2+
3+
/// <summary>
4+
/// Send a Greeting
5+
/// </summary>
6+
/// <param name="Name">The name of the person to greet</param>
7+
public record GreetingCommand(string Name);
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
namespace ASBExample.Shared;
2+
3+
/// <summary>
4+
/// Person has been Greeted
5+
/// </summary>
6+
/// <param name="Name">The name of the Person that was Greeted</param>
7+
/// <param name="Message">The message used to Greet the Person</param>
8+
public record GreetingEvent(string Name, string Message);

0 commit comments

Comments
 (0)