dotnet / aspire

Tools, templates, and packages to accelerate building observable, production-ready apps
https://learn.microsoft.com/dotnet/aspire
MIT License
3.91k stars 476 forks source link

Not able to bind RabbitMQ Configuration for Ssl property (Client integration) #6573

Open Jaryllan opened 3 weeks ago

Jaryllan commented 3 weeks ago

Is there an existing issue for this?

Describe the bug

Aspire not able to bind the Ssl configuration from appsettings. The following are the few scenarios that i had tried

AppHost

builder.AddProject<Projects.WorkerService1>("workerservice1")
    .WithReference(rabbitmq);

Case 1: using builder.AddRabbitMQClient("rabbitmq") in project

Project Configuration Image

Project Code (The CertPath and ServerName cannot be bind) Image

Case 2: using builder.AddKeyedRabbitMQClient("rabbitmq") in project

Project Configuration Image

Project Code (The CertPath and ServerName cannot be bind) Image

Case 3: Similar to Case 2, but using different key name. eg: builder.AddKeyedRabbitMQClient("rabbitmq2")

Project Configuration Image

Project Code Image

To conclude based on the above 3 scenarios, case 1 and case 2 not able to bind the Ssl configuration. Only case 3 able to bind the Ssl configuration, but due to it is not matching the connectionstring's suffix name, the project not able to access the connectionstring's value.

Would like to know what causes the aspire not able to bind the Ssl configuration section. It is quite strange as the aspire can bind "ClientProvidedName" but not Ssl section.

Expected Behavior

Able to bind the Ssl configuration.

Steps To Reproduce

No response

Exceptions (if any)

No response

.NET Version info

.NET SDK: Version: 8.0.403 Commit: c64aa40a71 Workload version: 8.0.400-manifests.58db758f MSBuild version: 17.11.9+a69bbaaf5

Runtime Environment: OS Name: Windows OS Version: 10.0.22631 OS Platform: Windows RID: win-x64 Base Path: C:\Program Files\dotnet\sdk\8.0.403\

.NET workloads installed: Configured to use loose manifests when installing new manifests. [android] Installation Source: SDK 8.0.400, VS 17.11.35327.3 Manifest Version: 34.0.143/8.0.100 Manifest Path: C:\Program Files\dotnet\sdk-manifests\8.0.100\microsoft.net.sdk.android\34.0.143\WorkloadManifest.json Install Type: FileBased

[aspire] Installation Source: SDK 8.0.400, VS 17.11.35327.3 Manifest Version: 8.2.1/8.0.100 Manifest Path: C:\Program Files\dotnet\sdk-manifests\8.0.100\microsoft.net.sdk.aspire\8.2.1\WorkloadManifest.json Install Type: FileBased

[ios] Installation Source: SDK 8.0.400, VS 17.11.35327.3 Manifest Version: 18.0.8303/8.0.100 Manifest Path: C:\Program Files\dotnet\sdk-manifests\8.0.100\microsoft.net.sdk.ios\18.0.8303\WorkloadManifest.json Install Type: FileBased

[maccatalyst] Installation Source: SDK 8.0.400, VS 17.11.35327.3 Manifest Version: 18.0.8303/8.0.100 Manifest Path: C:\Program Files\dotnet\sdk-manifests\8.0.100\microsoft.net.sdk.maccatalyst\18.0.8303\WorkloadManifest.json Install Type: FileBased

[maui-windows] Installation Source: SDK 8.0.400, VS 17.11.35327.3 Manifest Version: 8.0.82/8.0.100 Manifest Path: C:\Program Files\dotnet\sdk-manifests\8.0.100\microsoft.net.sdk.maui\8.0.82\WorkloadManifest.json Install Type: FileBased

Host: Version: 8.0.10 Architecture: x64 Commit: 81cabf2857

.NET SDKs installed: 6.0.302 [C:\Program Files\dotnet\sdk] 6.0.321 [C:\Program Files\dotnet\sdk] 8.0.403 [C:\Program Files\dotnet\sdk]

.NET runtimes installed: Microsoft.AspNetCore.App 6.0.7 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 6.0.26 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 6.0.33 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 6.0.35 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 8.0.10 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.NETCore.App 6.0.7 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 6.0.26 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 6.0.33 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 6.0.35 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 8.0.10 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.WindowsDesktop.App 6.0.7 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 6.0.26 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 6.0.35 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 8.0.10 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

Other architectures found: x86 [C:\Program Files (x86)\dotnet] registered at [HKLM\SOFTWARE\dotnet\Setup\InstalledVersions\x86\InstallLocation]

Environment variables: Not set

global.json file: Not found

Learn more: https://aka.ms/dotnet/info

Download .NET: https://aka.ms/dotnet/download

Anything else?

No response

joperezr commented 2 weeks ago

Related: https://github.com/dotnet/aspire/issues/6543 (Hosting aspect of this.)

eerhardt commented 2 weeks ago

@Jaryllan - can you add a repro project for this? Check out https://github.com/dotnet/runtime/blob/main/CONTRIBUTING.md#writing-a-good-bug-report. That way we can try running the project that reproduces the problem, instead of trying to recreate the problem ourselves based off screenshots.

Jaryllan commented 2 weeks ago

AspireApp1.zip

@eerhardt, Sorry for the late response. I have attached a simple test project based on the aspire starter template to simulate such issue.

Steps:

  1. Place the breakpoint in the apiservice "builder.AddRabbitMQClient"'s factory in "Program.cs". Alternatively i have wrote a Console.Writeline to display it on the console output, which can be view from the aspire dashboard's log view.
  2. Start up/debug the aspire project.
  3. Wait for rabbitmq to fully boot up by checking the logs from the aspire dashboard
  4. Continue from aspire dashboard, click on the apiservice link to call the api.
  5. Either check the apiservice log from aspire dashboard, or view from the breakpoint if done correctly in step 1. Should be able to see that the value does not match the configured value in appsettings.json

I have also added commented code for you to switch to using builder.AddKeyedRabbitMQClient, to show that if specify the key name that is not matched with the default connectionName "rabbitmq", then it will be able to bind value from appsettings.json.

eerhardt commented 2 weeks ago

Perfect, thanks for the repro. The issue appears to be here:

https://github.com/dotnet/aspire/blob/abba3d5a9e229823577ab679303afb9cce8d0069/src/Components/Aspire.RabbitMQ.Client/AspireRabbitMQExtensions.cs#L97-L105

First, we bind to the configuration, which pulls the SSL settings from appSettings.json correctly.

But then we set factory.Uri to the connection string being passed. We do this after binding to config in order for the connection string to always "win" or be respected.

The problem comes in the RabbitMQ code. When you set the ConnectionFactory.Uri property, it overwrites the Endpoint property:

https://github.com/rabbitmq/rabbitmq-dotnet-client/blob/58ac94966d12ffbb88ccd03ea085b3516a544321/projects/RabbitMQ.Client/ConnectionFactory.cs#L677

        private void SetUri(Uri uri)
        {
            Endpoint = new AmqpTcpEndpoint();

Which then clears out the Ssl property:

https://github.com/rabbitmq/rabbitmq-dotnet-client/blob/58ac94966d12ffbb88ccd03ea085b3516a544321/projects/RabbitMQ.Client/ConnectionFactory.cs#L279-L287

        public AmqpTcpEndpoint Endpoint
        {
            get { return new AmqpTcpEndpoint(HostName, Port, Ssl, MaxInboundMessageBodySize); }
            set
            {
                Port = value.Port;
                HostName = value.HostName;
                Ssl = value.Ssl;
                MaxInboundMessageBodySize = value.MaxInboundMessageBodySize;

So all the Ssl values from config get cleared.