dotnet / aspire

An opinionated, cloud ready stack for building observable, production ready, distributed applications in .NET
https://learn.microsoft.com/dotnet/aspire
MIT License
2.99k stars 283 forks source link

GetEndpoint fails if project uses WithHttpsEndpoint #3947

Closed WhitWaldo closed 2 weeks ago

WhitWaldo commented 2 weeks ago

I'm experiencing issues with a local run simply not working and it's citing my use of GetEndpoint("https") pointing at back the project reference (no sample repro at the moment), but I saw this issue and wanted to jump in with my own use case that can't utilize the convenience of simply registering and injecting an HttpClient to make use of the project reference.

Especially when developing locally, I make use of localhost and the various ports the services are being dynamically assigned to for auth callabcks. This wouldn't be much of an issue except that various authentication providers require a callback URL when running on localhost that includes the port, so rather than set something statically, I thought I'd have Aspire populate the endpoint in an environment variable and pass that into the page's login link (again, not using HttpClient here), but it appears to work in some circumstances and not others.

At least in my local repo, it's reproducible if I have the following:

var builder = DistributedApplication.CreateBuilder(args);

var api = builder.AddProject<Projects.MyApi>("myapi"); //This service starts up fine
var apiEndpoint = api.GetEndpoint("https");
api.WithEnvironment("ApiEndpoint", apiEndpoint);

var web = builder.AddProject<Projects.MyWeb>("myweb") // This service fails to launch
    .WithHttpsEndpoint()
    .WithReference(api)
    .WithEnvironment("ApiEndpoint", apiEndpoint);
var webEndpoint = web.GetEndpoint("https");
web.WithEnvironment("WebEndpoint", webEndpoint);

builder.Build().Run();

The error given in the service logs for MyWeb is "Failed to apply configuration value "WebEndpoint". A dependency may have failed to start". And it's true - it fails to start, but the MyApi project starts without issue.

I've been able to reproduce the issue here.

davidfowl commented 2 weeks ago

First thing to understand is this doc:

https://learn.microsoft.com/en-us/dotnet/aspire/fundamentals/networking-overview

I think explaining how it works would maybe go a long way in helping to troubleshoot. When you call AddProject, we look the launchSettings.json and read the endpoints for the relevant launch profile (more on this later) and add endpoints using the scheme as the name. So if you have a launch profile with an http endpoint only, that will define an endpoint with the name "http". If you have a launch profile with an http and https urls, then you get 2 endpoints defined with the names "http" and "https".

The "active" launch profile is different depending on whether you're in visual studio or the command line (this sucks we know). In VS it's whatever you select from the drop down (which defaults to https). On the command line, it's the first one in the file unless you explicitly specify a launch profile as part of dotnet run.

Now we should talk about WithEndpoint/WithHttpEndpoint/WithHttpsEndpoint. When you use those methods, you are creating an endpoint where the scheme ends up as the endpoint name if you don't specify one (It's not a very good default). Also, duplicate names are forbidden.

To fix your project, remove the WithHttpsEndpoint as its adding another endpoint called "https" which doesn't work.

@mitchdenny Our error reporting is bad here. We should make sure a better error is surfaced for duplicate endpoints (maybe putting these checks in when the endpoint is resolved, like we do the other ones).

cc @IEvangelist

IEvangelist commented 2 weeks ago

Also, launch profiles are covered here: https://learn.microsoft.com/en-us/dotnet/aspire/fundamentals/launch-profiles

WhitWaldo commented 2 weeks ago

@davidfowl That makes a lot of sense - thank you for the explanation!