Search code examples
azure-cosmosdbdotnet-aspire

Aspire + CosmosDB Emulator - The SSL connection could not be established


In the default sample Aspire project, I added the CosmosDB Hosting Package Aspire.Hosting.Azure.CosmosDB in the AppHost, and the CosmosDB Component Aspire.Microsoft.Azure.Cosmos in the ApiService. I then added logic to seed some data to the CosmosDB and read it back when hitting the /weatherforecast api.

If I hit the Weather page too soon after starting up, I typically get the following exception:

System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exception. ---> System.IO.IOException: Received an unexpected EOF or 0 bytes from the transport stream.

Note! This led to a whopping big rabbithole because of the issues with running the CosmosDB emulator in a docker container, but basically the Aspire Hosting and Component do a good job of fixing up the container and connectionstring in the right way to have it actually work without needing to refer back to these older hacks.

AppHost

var cosmosDb = builder.AddAzureCosmosDB("cosmos")
    .RunAsEmulator();

ApiService

builder.AddAzureCosmosClient("cosmos");

I got around avoiding the exception in the apiservice by calling the below method before app.Run().

    internal static class CosmosExtensions
    {
        private class CosmosDB { }
        internal static async Task CreateDatabaseAndContainer(this WebApplication app)
        {
            var logger = app.Services.GetRequiredService<ILogger<CosmosDB>>();
            logger.LogInformation("Creating CosmosDB database and container");
            var client = app.Services.GetRequiredService<CosmosClient>();
            while (true)
            {
                try
                {
                    await client.ReadAccountAsync();
                    break;
                }
                catch (HttpRequestException ex) when (ex.HttpRequestError is HttpRequestError.SecureConnectionError)
                {
                    /* The CosmosDB emulator seems to take a very long time to start up, and returns this exception.
                     * System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exception.
                    ---> System.IO.IOException: Received an unexpected EOF or 0 bytes from the transport stream.
                     */
                    logger.LogWarning("CosmosDB connection retry");
                    Telemetry.CosmosDBConnectionRetries.Add(1);
                    await Task.Delay(1000);
                }
            }
            logger.LogInformation("CosmosDB connection success");
            
            Database database = await client.CreateDatabaseIfNotExistsAsync("Weather");
            Container container = await database.CreateContainerIfNotExistsAsync("Cities", "/city", 400);
            
            logger.LogInformation("CosmosDB container created");
        }
    }

But this feels like a terrible hack. I wonder what I might be missing?


Solution

  • The emulator takes a long time to start and returns SSL errors while it is starting up. I believe the Azure ComsosDB team is considering addressing the feedback with the current emulator.

    Checkout the approach taken in https://github.com/dotnet/aspire-samples/pull/321.