Skip to content

Commit

Permalink
Allow Azure Functions to reference CosmosDB databases and containers
Browse files Browse the repository at this point in the history
Resources that participate in Azure Functions need to implement IResourceWithAzureFunctionsConfig. Add this to the child resources in CosmosDB.

For now, only the top-level account information is passed via connection string and config properties.

Contributes to #7407
  • Loading branch information
eerhardt committed Feb 7, 2025
1 parent ad79417 commit b043383
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace Aspire.Hosting.Azure;
/// <remarks>
/// Use <see cref="AzureProvisioningResourceExtensions.ConfigureInfrastructure{T}(ApplicationModel.IResourceBuilder{T}, Action{AzureResourceInfrastructure})"/> to configure specific <see cref="Azure.Provisioning"/> properties.
/// </remarks>
public class AzureCosmosDBContainerResource : Resource, IResourceWithParent<AzureCosmosDBDatabaseResource>, IResourceWithConnectionString
public class AzureCosmosDBContainerResource : Resource, IResourceWithParent<AzureCosmosDBDatabaseResource>, IResourceWithConnectionString, IResourceWithAzureFunctionsConfig
{
/// <summary>
/// Initializes a new instance of the <see cref="AzureCosmosDBContainerResource"/> class.
Expand Down Expand Up @@ -42,4 +42,8 @@ public AzureCosmosDBContainerResource(string name, string containerName, string
/// Gets the connection string expression for the Azure Cosmos DB Database Container.
/// </summary>
public ReferenceExpression ConnectionStringExpression => Parent.ConnectionStringExpression;

// ensure Azure Functions projects can WithReference a CosmosDB database container
void IResourceWithAzureFunctionsConfig.ApplyAzureFunctionsConfiguration(IDictionary<string, object> target, string connectionName) =>
((IResourceWithAzureFunctionsConfig)Parent).ApplyAzureFunctionsConfiguration(target, connectionName);
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace Aspire.Hosting.Azure;
/// <remarks>
/// Use <see cref="AzureProvisioningResourceExtensions.ConfigureInfrastructure{T}(ApplicationModel.IResourceBuilder{T}, Action{AzureResourceInfrastructure})"/> to configure specific <see cref="Azure.Provisioning"/> properties.
/// </remarks>
public class AzureCosmosDBDatabaseResource : Resource, IResourceWithParent<AzureCosmosDBResource>, IResourceWithConnectionString
public class AzureCosmosDBDatabaseResource : Resource, IResourceWithParent<AzureCosmosDBResource>, IResourceWithConnectionString, IResourceWithAzureFunctionsConfig
{
/// <summary>
/// Initializes a new instance of the <see cref="AzureCosmosDBDatabaseResource"/> class.
Expand Down Expand Up @@ -41,4 +41,8 @@ public AzureCosmosDBDatabaseResource(string name, string databaseName, AzureCosm
/// Gets the connection string expression for the Azure Cosmos DB database.
/// </summary>
public ReferenceExpression ConnectionStringExpression => Parent.ConnectionStringExpression;

// ensure Azure Functions projects can WithReference a CosmosDB database
void IResourceWithAzureFunctionsConfig.ApplyAzureFunctionsConfiguration(IDictionary<string, object> target, string connectionName) =>
((IResourceWithAzureFunctionsConfig)Parent).ApplyAzureFunctionsConfiguration(target, connectionName);
}
44 changes: 44 additions & 0 deletions tests/Aspire.Hosting.Azure.Tests/AzureCosmosDBExtensionsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,4 +87,48 @@ public void AddAzureCosmosDBWithDataExplorer()
Assert.Throws<NotSupportedException>(() => cosmos2.RunAsEmulator(e => e.WithDataExplorer()));
#pragma warning restore ASPIRECOSMOS001 // RunAsPreviewEmulator is experimental
}

[Fact]
public void AzureCosmosDBHasCorrectConnectionStrings()
{
using var builder = TestDistributedApplicationBuilder.Create();

var cosmos = builder.AddAzureCosmosDB("cosmos");
var db1 = cosmos.AddCosmosDatabase("db1");
var container1 = db1.AddContainer("container1", "id");

// database and container should have the same connection string as the cosmos account, for now.
// In the future, we can add the database and container info to the connection string.
Assert.Equal("{cosmos.outputs.connectionString}", cosmos.Resource.ConnectionStringExpression.ValueExpression);
Assert.Equal("{cosmos.outputs.connectionString}", db1.Resource.ConnectionStringExpression.ValueExpression);
Assert.Equal("{cosmos.outputs.connectionString}", container1.Resource.ConnectionStringExpression.ValueExpression);
}

[Fact]
public void AzureCosmosDBAppliesAzureFunctionsConfiguration()
{
using var builder = TestDistributedApplicationBuilder.Create();

var cosmos = builder.AddAzureCosmosDB("cosmos");
var db1 = cosmos.AddCosmosDatabase("db1");
var container1 = db1.AddContainer("container1", "id");

var target = new Dictionary<string, object>();
((IResourceWithAzureFunctionsConfig)cosmos.Resource).ApplyAzureFunctionsConfiguration(target, "cosmos");
Assert.Collection(target.Keys.OrderBy(k => k),
k => Assert.Equal("Aspire__Microsoft__Azure__Cosmos__cosmos__AccountEndpoint", k),
k => Assert.Equal("cosmos__accountEndpoint", k));

target.Clear();
((IResourceWithAzureFunctionsConfig)db1.Resource).ApplyAzureFunctionsConfiguration(target, "db1");
Assert.Collection(target.Keys.OrderBy(k => k),
k => Assert.Equal("Aspire__Microsoft__Azure__Cosmos__db1__AccountEndpoint", k),
k => Assert.Equal("db1__accountEndpoint", k));

target.Clear();
((IResourceWithAzureFunctionsConfig)container1.Resource).ApplyAzureFunctionsConfiguration(target, "container1");
Assert.Collection(target.Keys.OrderBy(k => k),
k => Assert.Equal("Aspire__Microsoft__Azure__Cosmos__container1__AccountEndpoint", k),
k => Assert.Equal("container1__accountEndpoint", k));
}
}

0 comments on commit b043383

Please sign in to comment.