Skip to content
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

added cosmosdb sample #321

Open
wants to merge 23 commits into
base: main
Choose a base branch
from
Open

added cosmosdb sample #321

wants to merge 23 commits into from

Conversation

bradygaster
Copy link
Member

Adds Cosmos DB sample per #74

samples/AspireWithCosmosDb/README.md Outdated Show resolved Hide resolved
samples/AspireWithCosmosDb/README.md Show resolved Hide resolved
samples/AspireWithCosmosDb/README.md Show resolved Hide resolved
samples/AspireWithCosmosDb/README.md Show resolved Hide resolved
@DamianEdwards
Copy link
Member

@bradygaster you'll need to figure out how to make this sample pass the test cleanly as currently the apiservice fails to start it seems.

@bradygaster
Copy link
Member Author

Pretty sure I captured all the changes suggested by @DamianEdwards and @Pilchie save 1 - i couldn't get the app to work properly when i have RunAsEmulator in the App Host code. If @Pilchie has guidance on how to work past the error i've sent him i'll implement it, otherwise i think this has everything everyone requested and is ready to go.

@DamianEdwards
Copy link
Member

I still see some build warnings and the test still isn't passing?

@bradygaster
Copy link
Member Author

added the RunAsEmulator command as it matches the implementation in the playground project and the comment @DamianEdwards requested, in lieu of the fact that i couldn't get it working with the emulator.

@bradygaster
Copy link
Member Author

Guess the emulator is broken on my machine. For once, it not working on my machine isn't a bad thing? :)

@DamianEdwards
Copy link
Member

Only thing left would be to add a test case at https://github.com/dotnet/aspire-samples/blob/main/tests/SamplesIntegrationTests/AppHostTests.cs#L125 so that we get proper coverage of this new sample.

@bradygaster
Copy link
Member Author

bradygaster commented Jun 19, 2024

Made a few small tweaks - otel refs and removal of the gRPC-related items in defaults.

public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
// The Cosmos DB emulator can take a very long time to start (multiple minutes) so use a custom resilience strategy
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cc @Pilchie so he sees how @DamianEdwards was able to work through this - I pinged the team today so mention we'd run into these issues, so wanted to give y'all an update on the completion. Thanks @DamianEdwards!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should put this code in the component.

cc @eerhardt

Copy link
Member

@eerhardt eerhardt Jun 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. @Pilchie mentioned offline that they were going to change the emulator to not respond until it was ready. That would solve the issues with getting SSL errors during startup.
  2. We could add this to the CosmosClientOptions.HttpFactory by default. It would be better if the library had resilience built into it though.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think if we set the HttpClientFactory option we then own all other aspects setting up the HttpClient instance that the Cosmos client currently handles, including those affected by properties on the connecting string, e.g. disabling the SSL validation check. This is what I ran into when attempting that approach.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to merge this as-is or edit the code in the component in such a manner we can make the sample less-meh? I vote for merging it and then I'll update it once we change the component if @eerhardt informs me once the work is done. :)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd agree we should wait for the component changes.

FYI - the component is owned by @Pilchie's team. We should work with them to get it updated as necessary.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just wanted to comment that I'm aware of this and following up. I think there is a plan to build some of this into the container itself so that this sort of thing isn't necessary, but I will let you know. cc @kirankumarkolli

@DamianEdwards
Copy link
Member

@bradygaster @Pilchie I pushed some changes that hopefully make this more reliable:

  • Added retries to the DatabaseBootstrapper using a Polly resiliency pipeline with enough retries and time to allow the emulator container to start (hopefully)
  • Changed the DatabaseBootstrapper from a raw IHostedService to a BackgroundService so its startup doesn't impact the lifecycle of the app. As it was, Kestrel couldn't start until the DatabaseBootstrapper had successfully completed, and if it failed the app would just crash.
  • Made DatabaseBootstrapper double as an IHealthCheck so it can report its status and the test can ensure /health succeeds before moving on to trying to hit /todos

It seems problematic that the Cosmos DB component doesn't enable enough retries by default to allow the emulator to startup. Also I found it confusing that the Cosmos DB resource reports itself as having only a TCP endpoint but then it clearly uses HTTP at runtime, but because it doesn't use IHttpClientFactory it doesn't get any of the default Aspire HTTP resiliency applied. I attempted to wire the Cosmos client up to IHttpClientFactory but found it more complex than simply wrapping retries around the creation logic due to having to separate it from the default resiliency (as that wasn't resilient enough) and having to manually handle the HTTPS cert again.

Comment on lines 11 to 12
<PackageReference Include="Azure.Identity" Version="1.12.0" />
<PackageReference Include="Microsoft.Azure.Cosmos" Version="3.41.0" />
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<PackageReference Include="Azure.Identity" Version="1.12.0" />
<PackageReference Include="Microsoft.Azure.Cosmos" Version="3.41.0" />

Why are these necessary? You should be able to just have line 10.

Copy link
Member

@DamianEdwards DamianEdwards Jun 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Vulnerability in Azure.Identity in versions lower than that and we haven't updated the component yet. I just followed the bouncing ball in the NuGet Package Manager UI in VS.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bradygaster @eerhardt We shouldn't have samples with vulnerable packages, even transitively. This is what I see in VS for the transitive reference to Azure.Identity
image

Customers need to update transitive references to resolve these issues and so IMO it's appropriate to do so in samples too. When we ship updated versions of the Aspire packages that update the transitive versions used we can remove the explicit references.

Comment on lines +15 to +16
builder.Services.AddHealthChecks()
.Add(new("cosmos", sp => sp.GetRequiredService<DatabaseBootstrapper>(), null, null));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is odd to have in our sample, when the decision was to not have a health check in the component.

dotnet/aspire#359 (comment)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right but this isn't a health check of Cosmos, it's a health check of whether the bootstrapper has completed successfully. Once the bootstrapper has completed this health check is always healthy and doesn't hit Cosmos on its own.

…ithCosmos.ApiService.csproj

Co-authored-by: Eric Erhardt <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants