-
Notifications
You must be signed in to change notification settings - Fork 10
Example added to illustrate how to publish to multiple different queues. #1346
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
skeetor
wants to merge
1
commit into
GDATASoftwareAG:master
Choose a base branch
from
skeetor:development
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
7 changes: 7 additions & 0 deletions
7
examples/PublishToMultipleQueuesRabbitMQ/Model/InputMessage.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| namespace PublishToMultipleQueuesRabbitMQ.Model; | ||
|
|
||
| public record InputMessage | ||
| { | ||
| public string FancyText { get; set; } = "FooBar"; | ||
| public int FancyNumber { get; set; } = 42; | ||
| } |
9 changes: 9 additions & 0 deletions
9
examples/PublishToMultipleQueuesRabbitMQ/Model/LeftMessage.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| namespace PublishToMultipleQueuesRabbitMQ.Model; | ||
|
|
||
| // Since we send the same data to the queue, we can use a baseclass with the actual | ||
| // values, but still need to define an individual type for the queue. | ||
| public record LeftMessage : OutputMessage | ||
| { | ||
| // Or add additional data here. | ||
| public string Left { get; set; } = "Left"; | ||
| } |
7 changes: 7 additions & 0 deletions
7
examples/PublishToMultipleQueuesRabbitMQ/Model/OutputMessage.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| namespace PublishToMultipleQueuesRabbitMQ.Model; | ||
|
|
||
| public record OutputMessage | ||
| { | ||
| public string NotSoFancyText { get; set; } | ||
| public int NotSoFancyNumber { get; set; } | ||
| } |
8 changes: 8 additions & 0 deletions
8
examples/PublishToMultipleQueuesRabbitMQ/Model/RightMessage.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| namespace PublishToMultipleQueuesRabbitMQ.Model; | ||
|
|
||
| // Since we send the same data to the queue, we can use a baseclass with the actual | ||
| // values, but still need to define an individual type for the queue. | ||
| public record RightMessage : OutputMessage | ||
| { | ||
| // Or add additional data here. | ||
| } |
68 changes: 68 additions & 0 deletions
68
examples/PublishToMultipleQueuesRabbitMQ/NoOutputService.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,68 @@ | ||
| using System; | ||
| using System.Linq; | ||
| using System.Threading; | ||
| using System.Threading.Tasks; | ||
| using Motor.Extensions.Hosting.Abstractions; | ||
| using Motor.Extensions.Hosting.CloudEvents; | ||
| using PublishToMultipleQueuesRabbitMQ.Model; | ||
|
|
||
| namespace PublishToMultipleQueuesRabbitMQ; | ||
|
|
||
| public class NoOutputService( | ||
| ITypedMessagePublisher<LeftMessage> leftPublisher, | ||
| ITypedMessagePublisher<RightMessage> rightPublisher) | ||
| : INoOutputService<InputMessage> | ||
| { | ||
| // Handle incoming messages | ||
| private static int _messageCount = 0; | ||
|
|
||
| public Task<ProcessedMessageStatus> HandleMessageAsync(MotorCloudEvent<InputMessage> inputEvent, CancellationToken token = default) | ||
| { | ||
| // Get the input message from the cloud event | ||
| var input = inputEvent.TypedData; | ||
|
|
||
| // Sometimes we dont have anything to publish. | ||
| if (string.IsNullOrEmpty(input.FancyText)) | ||
| { | ||
| // Might need to be logged, or published to some additional queue, or can simply be ignored. | ||
| return Task.FromResult(ProcessedMessageStatus.Success); | ||
| } | ||
|
|
||
| _messageCount++; | ||
|
|
||
| // In all other cases we publish to the queue dictated by our business logic. | ||
| if (_messageCount % 2 == 0) | ||
| { | ||
| var left = CreateLeftMessage(input); | ||
| leftPublisher.PublishMessageAsync(inputEvent.CreateNew(left), token); | ||
| } | ||
| else | ||
| { | ||
| var right = CreateRightMessage(input); | ||
| rightPublisher.PublishMessageAsync(inputEvent.CreateNew(right), token); | ||
| } | ||
|
|
||
| return Task.FromResult(ProcessedMessageStatus.Success); | ||
| } | ||
|
|
||
| private static LeftMessage CreateLeftMessage(InputMessage input) | ||
| { | ||
| var output = new LeftMessage | ||
| { | ||
| NotSoFancyText = input.FancyText.Reverse().ToString(), | ||
| NotSoFancyNumber = input.FancyNumber * -1, | ||
| }; | ||
| return output; | ||
| } | ||
|
|
||
| private static RightMessage CreateRightMessage(InputMessage input) | ||
| { | ||
| var output = new RightMessage | ||
| { | ||
| NotSoFancyText = input.FancyText + " " + DateTime.Now, | ||
| NotSoFancyNumber = input.FancyNumber * 3, | ||
| }; | ||
|
|
||
| return output; | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,72 @@ | ||
| using PublishToMultipleQueuesRabbitMQ.Model; | ||
| using PublishToMultipleQueuesRabbitMQ; | ||
| using Microsoft.Extensions.DependencyInjection; | ||
| using Microsoft.Extensions.Hosting; | ||
| using Motor.Extensions.ContentEncoding.Gzip; | ||
| using Motor.Extensions.Conversion.SystemJson; | ||
| using Motor.Extensions.Hosting.Abstractions; | ||
| using Motor.Extensions.Hosting.Consumer; | ||
| using Motor.Extensions.Hosting.Publisher; | ||
| using Motor.Extensions.Hosting.RabbitMQ; | ||
| using Motor.Extensions.Utilities; | ||
|
|
||
| await MotorHost.CreateDefaultBuilder() | ||
| // Configure the types of the input message | ||
| .ConfigureNoOutputService<InputMessage>() | ||
| .ConfigureServices((_, services) => | ||
| { | ||
| // Add a handler for the input message. this handler is a INoOutputService | ||
| // because we would have to specify the output type here, which we can't because | ||
| // the handler wants to send to different queues, depending on the incoming | ||
| // message data and its associated business logic. | ||
| // This handler is called for every new incoming message. | ||
| services.AddTransient<INoOutputService<InputMessage>, NoOutputService>(); | ||
| }) | ||
| // Add the incoming communication modules. | ||
| .ConfigureConsumer<InputMessage>((_, builder) => | ||
| { | ||
| // In this case the messages are received from RabbitMQ | ||
| builder.AddRabbitMQ(); | ||
| // The encoding of the incoming message, such that the handler is able to deserialize the message | ||
| builder.AddSystemJson(); | ||
| // (Optional) Enable support for incoming messages that are gzip compressed. Uncompressed messages will still | ||
| // work to make the migration to compression backwards-compatible. | ||
| builder.AddGzipDecompression(); | ||
| }) | ||
| // Now add the different queues. For each individual queue | ||
| // we have to add here individual sections. Because of the template argument, each | ||
| // section needs to have its own message type. You can currently not send the same | ||
| // message type to different queues. Note that these dont have to be separate objects though. | ||
| // So if you want to send the same message to multiple queues, you can define your data in a | ||
| // base class, and then create an empty derived type, which is to be used here in the setup (as | ||
| // shown in this example). | ||
|
|
||
| // Add one publishing queue. | ||
| .ConfigurePublisher<LeftMessage>((_, builder) => | ||
| { | ||
| // In this case the messages are sent to one RabbitMQ queue. | ||
| // We could still use the default name for any of the config sections, but | ||
| // using a descriptive name is better, especially because we still have | ||
| // the other queue, or as many as needed, with different settings. | ||
| // Obviously only one queue can have the default name anyway. | ||
| builder.AddRabbitMQ("LeftQueue"); | ||
|
|
||
| // The encoding of the outgoing message, such that the handler is able to serialize the message | ||
| builder.AddSystemJson(); | ||
|
|
||
| // (Optional) Compress the serialized data of the outgoing message with gzip. | ||
| builder.AddGzipCompression(); | ||
| }) | ||
| // Add another publishing queue. | ||
| .ConfigurePublisher<RightMessage>((_, builder) => | ||
| { | ||
| // In this case the messages are sent to the other RabbitMQ queue. | ||
| builder.AddRabbitMQ("RightQueue"); | ||
|
|
||
| // The encoding of the outgoing message, such that the handler is able to serialize the message | ||
| builder.AddSystemJson(); | ||
|
|
||
| // (Optional) Compress the serialized data of the outgoing message with gzip. | ||
| builder.AddGzipCompression(); | ||
| }) | ||
| .RunConsoleAsync(); |
27 changes: 27 additions & 0 deletions
27
examples/PublishToMultipleQueuesRabbitMQ/Properties/launchSettings.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| { | ||
| "iisSettings": { | ||
| "windowsAuthentication": false, | ||
| "anonymousAuthentication": true, | ||
| "iisExpress": { | ||
| "applicationUrl": "http://localhost:58904/", | ||
| "sslPort": 44350 | ||
| } | ||
| }, | ||
| "profiles": { | ||
| "IIS Express": { | ||
| "commandName": "IISExpress", | ||
| "launchBrowser": true, | ||
| "environmentVariables": { | ||
| "ASPNETCORE_ENVIRONMENT": "Development" | ||
| } | ||
| }, | ||
| "ConsumeAndPublishWithRabbitMQ": { | ||
| "commandName": "Project", | ||
| "launchBrowser": true, | ||
| "environmentVariables": { | ||
| "ASPNETCORE_ENVIRONMENT": "Development" | ||
| }, | ||
| "applicationUrl": "https://localhost:5001;http://localhost:5000" | ||
| } | ||
| } | ||
| } |
25 changes: 25 additions & 0 deletions
25
examples/PublishToMultipleQueuesRabbitMQ/PublishToMultipleQueuesRabbitMQ.csproj
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| <Project Sdk="Microsoft.NET.Sdk.Web"> | ||
|
|
||
| <PropertyGroup> | ||
| <OutputType>Exe</OutputType> | ||
| <TargetFrameworks>net8.0;net9.0</TargetFrameworks> | ||
| <Product>Motor.NET</Product> | ||
| </PropertyGroup> | ||
|
|
||
| <ItemGroup> | ||
| <ProjectReference Include="..\..\src\Motor.Extensions.ContentEncoding.Gzip\Motor.Extensions.ContentEncoding.Gzip.csproj" /> | ||
| <ProjectReference Include="..\..\src\Motor.Extensions.Conversion.SystemJson\Motor.Extensions.Conversion.SystemJson.csproj" /> | ||
| <ProjectReference Include="..\..\src\Motor.Extensions.Hosting.RabbitMQ\Motor.Extensions.Hosting.RabbitMQ.csproj" /> | ||
| <ProjectReference Include="..\..\src\Motor.Extensions.Utilities\Motor.Extensions.Utilities.csproj" /> | ||
| </ItemGroup> | ||
|
|
||
| <ItemGroup> | ||
| <None Update="appsettings.json"> | ||
| <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | ||
| </None> | ||
| <None Update="appsettings.Production.json"> | ||
| <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | ||
| </None> | ||
| </ItemGroup> | ||
|
|
||
| </Project> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| This example shows how to use MotorNET to publish to multiple different queues. | ||
| The method shown here uses a RabbitMQ but of course the pattern can be applied to any of the | ||
| other publishers as well. Or it can be combined with other services as well. | ||
| So suppose you have a SingleOutputService which always publishes to a certain queue, | ||
| but in some cases you might want to send data to another queue. |
17 changes: 17 additions & 0 deletions
17
examples/PublishToMultipleQueuesRabbitMQ/appsettings.Production.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| { | ||
| "Serilog": { | ||
| "MinimumLevel": { | ||
| "Default": "Information" | ||
| } | ||
| }, | ||
| "RabbitMQConsumer": { | ||
| "Queue": { | ||
| "Name": "ExampleProductionQueue" | ||
| } | ||
| }, | ||
| "RabbitMQPublisher": { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This entry looks obsolete |
||
| "PublishingTarget": { | ||
| "RoutingKey": "production" | ||
| } | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| { | ||
| "Serilog": { | ||
| "MinimumLevel": { | ||
| "Default": "Debug", | ||
| "Override": { | ||
| "Microsoft": "Warning", | ||
| "Microsoft.Hosting.Lifetime": "Information", | ||
| "System": "Warning" | ||
| } | ||
| } | ||
| }, | ||
| "RabbitMQConsumer": { | ||
| "Host": "localhost", | ||
| "VirtualHost": "/", | ||
| "User": "guest", | ||
| "Password": "guest", | ||
| "Queue": { | ||
| "Name": "ExampleQueue", | ||
| "Bindings": [ | ||
| { | ||
| "Exchange": "amq.topic", | ||
| "RoutingKey": "input" | ||
| } | ||
| ] | ||
| }, | ||
| "PrefetchCount": 10 | ||
| }, | ||
| "LeftQueue": | ||
| { | ||
| "Host": "localhost", | ||
| "VirtualHost": "/", | ||
| "User": "guest", | ||
| "Password": "guest", | ||
| "PublishingTarget": | ||
| { | ||
| "Exchange": "amq.topic", | ||
| "RoutingKey": "output.left" | ||
| } | ||
| }, | ||
| "RightQueue": { | ||
| "Host": "localhost", | ||
| "VirtualHost": "/", | ||
| "User": "guest", | ||
| "Password": "guest", | ||
| "PublishingTarget": | ||
| { | ||
| "Exchange": "amq.topic", | ||
| "RoutingKey": "output.right" | ||
| } | ||
| } | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm finally working on Motor.NET again and I just noticed that the static code analysis fails.
I don't know if the error is visible to you, but Codacy complains about accessing a static variable from a non-static context. That may be a bit nitpicky, but alternatively, you could just flip a coin to decide which publisher gets the message. That would still show the purpose of the example.