diff --git a/src/Aspire.Hosting.Azure/AzurePublishingContext.cs b/src/Aspire.Hosting.Azure/AzurePublishingContext.cs index 65f99633f50..0cfe98e3eef 100644 --- a/src/Aspire.Hosting.Azure/AzurePublishingContext.cs +++ b/src/Aspire.Hosting.Azure/AzurePublishingContext.cs @@ -117,9 +117,9 @@ private async Task WriteAzureArtifactsOutputAsync(IPublishingStep step, Distribu .Where(r => !r.IsExcludedFromPublish()) .ToList(); - MapParameter(environment.ResourceGroupName); - MapParameter(environment.Location); - MapParameter(environment.PrincipalId); + await MapParameterAsync(environment.ResourceGroupName, cancellationToken).ConfigureAwait(false); + await MapParameterAsync(environment.Location, cancellationToken).ConfigureAwait(false); + await MapParameterAsync(environment.PrincipalId, cancellationToken).ConfigureAwait(false); var resourceGroupParam = ParameterLookup[environment.ResourceGroupName]; MainInfrastructure.Add(resourceGroupParam); @@ -163,14 +163,14 @@ private async Task WriteAzureArtifactsOutputAsync(IPublishingStep step, Distribu // Map parameters from existing resources if (resource.TryGetLastAnnotation(out var existingAnnotation)) { - Visit(existingAnnotation.ResourceGroup, MapParameter); - Visit(existingAnnotation.Name, MapParameter); + await VisitAsync(existingAnnotation.ResourceGroup, MapParameterAsync, cancellationToken).ConfigureAwait(false); + await VisitAsync(existingAnnotation.Name, MapParameterAsync, cancellationToken).ConfigureAwait(false); } // Map parameters for the resource itself foreach (var parameter in resource.Parameters) { - Visit(parameter.Value, MapParameter); + await VisitAsync(parameter.Value, MapParameterAsync, cancellationToken).ConfigureAwait(false); } } @@ -359,7 +359,7 @@ await task.SucceedAsync( } } - private void MapParameter(object? candidate) + private async Task MapParameterAsync(object candidate, CancellationToken cancellationToken = default) { if (candidate is ParameterResource p && !ParameterLookup.ContainsKey(p)) { @@ -372,7 +372,11 @@ private void MapParameter(object? candidate) if (!p.Secret && p.Default is not null) { - pp.Value = p.Value; + var value = await p.GetValueAsync(cancellationToken).ConfigureAwait(false); + if (value is not null) + { + pp.Value = value; + } } ParameterLookup[p] = pp; @@ -400,6 +404,27 @@ private static void Visit(object? value, Action visitor, HashSet } } + private static Task VisitAsync(object? value, Func visitor, CancellationToken cancellationToken = default) => + VisitAsync(value, visitor, [], cancellationToken); + + private static async Task VisitAsync(object? value, Func visitor, HashSet visited, CancellationToken cancellationToken = default) + { + if (value is null || !visited.Add(value)) + { + return; + } + + await visitor(value, cancellationToken).ConfigureAwait(false); + + if (value is IValueWithReferences vwr) + { + foreach (var reference in vwr.References) + { + await VisitAsync(reference, visitor, visited, cancellationToken).ConfigureAwait(false); + } + } + } + /// /// Saves the compiled Bicep template to disk. /// diff --git a/src/Aspire.Hosting.Docker/DockerComposePublishingContext.cs b/src/Aspire.Hosting.Docker/DockerComposePublishingContext.cs index c0b030774c3..324ca29e82e 100644 --- a/src/Aspire.Hosting.Docker/DockerComposePublishingContext.cs +++ b/src/Aspire.Hosting.Docker/DockerComposePublishingContext.cs @@ -155,7 +155,15 @@ private async Task WriteDockerComposeOutputAsync(DistributedApplicationModel mod foreach (var entry in environment.CapturedEnvironmentVariables ?? []) { - var (key, (description, defaultValue, _)) = entry; + var (key, (description, defaultValue, source)) = entry; + + // If the source is a parameter and there's no explicit default value, + // resolve the parameter's default value asynchronously + if (defaultValue is null && source is ParameterResource parameter && !parameter.Secret && parameter.Default is not null) + { + defaultValue = await parameter.GetValueAsync(cancellationToken).ConfigureAwait(false); + } + envFile.AddIfMissing(key, defaultValue, description); } diff --git a/src/Aspire.Hosting.Docker/DockerComposeServiceExtensions.cs b/src/Aspire.Hosting.Docker/DockerComposeServiceExtensions.cs index db4991f5368..1f82feaf416 100644 --- a/src/Aspire.Hosting.Docker/DockerComposeServiceExtensions.cs +++ b/src/Aspire.Hosting.Docker/DockerComposeServiceExtensions.cs @@ -98,7 +98,7 @@ public static string AsEnvironmentPlaceholder(this ParameterResource parameter, return dockerComposeService.Parent.AddEnvironmentVariable( env, description: $"Parameter {parameter.Name}", - defaultValue: parameter.Secret || parameter.Default is null ? null : parameter.Value, + defaultValue: null, source: parameter ); } diff --git a/src/Aspire.Hosting.Kubernetes/KubernetesPublishingContext.cs b/src/Aspire.Hosting.Kubernetes/KubernetesPublishingContext.cs index b8d4ae74968..31f58f1579a 100644 --- a/src/Aspire.Hosting.Kubernetes/KubernetesPublishingContext.cs +++ b/src/Aspire.Hosting.Kubernetes/KubernetesPublishingContext.cs @@ -80,7 +80,7 @@ private async Task WriteKubernetesOutputAsync(DistributedApplicationModel model, } await WriteKubernetesTemplatesForResource(resource, serviceResource.GetTemplatedResources()).ConfigureAwait(false); - AppendResourceContextToHelmValues(resource, serviceResource); + await AppendResourceContextToHelmValuesAsync(resource, serviceResource).ConfigureAwait(false); } } @@ -88,14 +88,14 @@ private async Task WriteKubernetesOutputAsync(DistributedApplicationModel model, await WriteKubernetesHelmValuesAsync().ConfigureAwait(false); } - private void AppendResourceContextToHelmValues(IResource resource, KubernetesResource resourceContext) + private async Task AppendResourceContextToHelmValuesAsync(IResource resource, KubernetesResource resourceContext) { - AddValuesToHelmSection(resource, resourceContext.Parameters, HelmExtensions.ParametersKey); - AddValuesToHelmSection(resource, resourceContext.EnvironmentVariables, HelmExtensions.ConfigKey); - AddValuesToHelmSection(resource, resourceContext.Secrets, HelmExtensions.SecretsKey); + await AddValuesToHelmSectionAsync(resource, resourceContext.Parameters, HelmExtensions.ParametersKey).ConfigureAwait(false); + await AddValuesToHelmSectionAsync(resource, resourceContext.EnvironmentVariables, HelmExtensions.ConfigKey).ConfigureAwait(false); + await AddValuesToHelmSectionAsync(resource, resourceContext.Secrets, HelmExtensions.SecretsKey).ConfigureAwait(false); } - private void AddValuesToHelmSection( + private async Task AddValuesToHelmSectionAsync( IResource resource, Dictionary contextItems, string helmKey) @@ -114,7 +114,19 @@ private void AddValuesToHelmSection( continue; } - paramValues[key] = helmExpressionWithValue.Value ?? string.Empty; + string? value; + + // If there's a parameter source, resolve its value asynchronously + if (helmExpressionWithValue.ParameterSource is ParameterResource parameter) + { + value = await parameter.GetValueAsync(cancellationToken).ConfigureAwait(false); + } + else + { + value = helmExpressionWithValue.Value; + } + + paramValues[key] = value ?? string.Empty; } if (paramValues.Count > 0) diff --git a/src/Aspire.Hosting.Kubernetes/KubernetesResource.cs b/src/Aspire.Hosting.Kubernetes/KubernetesResource.cs index 6528721b0ad..45f5e57ccc4 100644 --- a/src/Aspire.Hosting.Kubernetes/KubernetesResource.cs +++ b/src/Aspire.Hosting.Kubernetes/KubernetesResource.cs @@ -311,10 +311,25 @@ private void ProcessEnvironmentDefaultValue(object value, string key, string res EnvironmentVariables[key] = new(configExpression, value.ToString() ?? string.Empty); } - internal class HelmExpressionWithValue(string helmExpression, string? value) + internal class HelmExpressionWithValue { - public string HelmExpression { get; } = helmExpression; - public string? Value { get; } = value; + public HelmExpressionWithValue(string helmExpression, string? value) + { + HelmExpression = helmExpression; + Value = value; + ParameterSource = null; + } + + public HelmExpressionWithValue(string helmExpression, ParameterResource parameterSource) + { + HelmExpression = helmExpression; + Value = null; + ParameterSource = parameterSource; + } + + public string HelmExpression { get; } + public string? Value { get; } + public ParameterResource? ParameterSource { get; } public bool IsHelmSecretExpression => HelmExpression.ContainsHelmSecretExpression(); public bool ValueContainsSecretExpression => Value?.ContainsHelmSecretExpression() ?? false; public bool ValueContainsHelmExpression => Value?.ContainsHelmExpression() ?? false; diff --git a/src/Aspire.Hosting.Kubernetes/KubernetesServiceResourceExtensions.cs b/src/Aspire.Hosting.Kubernetes/KubernetesServiceResourceExtensions.cs index 1fa80f232dc..e80b87c1b3d 100644 --- a/src/Aspire.Hosting.Kubernetes/KubernetesServiceResourceExtensions.cs +++ b/src/Aspire.Hosting.Kubernetes/KubernetesServiceResourceExtensions.cs @@ -122,8 +122,15 @@ private static HelmExpressionWithValue AllocateParameter(ParameterResource param formattedName.ToHelmSecretExpression(resource.Name) : formattedName.ToHelmConfigExpression(resource.Name); - var value = parameter.Default is null || parameter.Secret ? null : parameter.Value; - return new(expression, value); + // Store the parameter itself for deferred resolution instead of resolving the value immediately + if (parameter.Default is null || parameter.Secret) + { + return new(expression, (string?)null); + } + else + { + return new(expression, parameter); + } } private static HelmExpressionWithValue ResolveUnknownValue(IManifestExpressionProvider parameter, IResource resource) diff --git a/src/Aspire.Hosting/ApplicationModel/ParameterResource.cs b/src/Aspire.Hosting/ApplicationModel/ParameterResource.cs index fd9ea7ce464..233ed178dd5 100644 --- a/src/Aspire.Hosting/ApplicationModel/ParameterResource.cs +++ b/src/Aspire.Hosting/ApplicationModel/ParameterResource.cs @@ -31,6 +31,10 @@ public ParameterResource(string name, Func callback, /// /// Gets the value of the parameter. /// + /// + /// This property is obsolete. Use for async access or pass the directly to methods that accept it (e.g., environment variables). + /// + [Obsolete("Use GetValueAsync for async access or pass the ParameterResource directly to methods that accept it (e.g., environment variables).")] public string Value => GetValueAsync(default).AsTask().GetAwaiter().GetResult()!; internal string ValueInternal => _lazyValue.Value; diff --git a/tests/Aspire.Hosting.Azure.Tests/AzureRedisExtensionsTests.cs b/tests/Aspire.Hosting.Azure.Tests/AzureRedisExtensionsTests.cs index 2a4895ade18..1a85b3bb73c 100644 --- a/tests/Aspire.Hosting.Azure.Tests/AzureRedisExtensionsTests.cs +++ b/tests/Aspire.Hosting.Azure.Tests/AzureRedisExtensionsTests.cs @@ -103,7 +103,9 @@ public async Task AddAzureRedisRunAsContainerProducesCorrectConnectionString() Assert.True(redis.Resource.IsContainer(), "The resource should now be a container resource."); Assert.NotNull(redisResource?.PasswordParameter); +#pragma warning disable CS0618 // Type or member is obsolete Assert.Equal($"localhost:12455,password={redisResource.PasswordParameter.Value}", await redis.Resource.ConnectionStringExpression.GetValueAsync(CancellationToken.None)); +#pragma warning restore CS0618 // Type or member is obsolete } [Fact] @@ -195,7 +197,9 @@ public async Task PublishAsRedisPublishesRedisAsAzureRedisInfrastructure() Assert.True(redis.Resource.IsContainer()); Assert.NotNull(redis.Resource.PasswordParameter); +#pragma warning disable CS0618 // Type or member is obsolete Assert.Equal($"localhost:12455,password={redis.Resource.PasswordParameter.Value}", await redis.Resource.GetConnectionStringAsync()); +#pragma warning restore CS0618 // Type or member is obsolete var manifest = await AzureManifestUtils.GetManifestWithBicep(redis.Resource); diff --git a/tests/Aspire.Hosting.Milvus.Tests/MilvusFunctionalTests.cs b/tests/Aspire.Hosting.Milvus.Tests/MilvusFunctionalTests.cs index a0dafe89d35..bbac5958cf1 100644 --- a/tests/Aspire.Hosting.Milvus.Tests/MilvusFunctionalTests.cs +++ b/tests/Aspire.Hosting.Milvus.Tests/MilvusFunctionalTests.cs @@ -76,7 +76,9 @@ public async Task WithDataShouldPersistStateBetweenUsages(bool useVolume) { using var builder1 = TestDistributedApplicationBuilder.CreateWithTestContainerRegistry(testOutputHelper); var milvus1 = builder1.AddMilvus("milvus1"); +#pragma warning disable CS0618 // Type or member is obsolete var password = milvus1.Resource.ApiKeyParameter.Value; +#pragma warning restore CS0618 // Type or member is obsolete var db1 = milvus1.AddDatabase("milvusdb1", dbname); diff --git a/tests/Aspire.Hosting.MongoDB.Tests/AddMongoDBTests.cs b/tests/Aspire.Hosting.MongoDB.Tests/AddMongoDBTests.cs index 35ce89d6982..5483c7a512e 100644 --- a/tests/Aspire.Hosting.MongoDB.Tests/AddMongoDBTests.cs +++ b/tests/Aspire.Hosting.MongoDB.Tests/AddMongoDBTests.cs @@ -87,9 +87,13 @@ public async Task MongoDBCreatesConnectionString() Assert.NotNull(connectionStringResource); var connectionString = await connectionStringResource.GetConnectionStringAsync(); +#pragma warning disable CS0618 // Type or member is obsolete Assert.Equal($"mongodb://admin:{dbResource.Parent.PasswordParameter?.Value}@localhost:27017?authSource=admin&authMechanism=SCRAM-SHA-256", await serverResource.GetConnectionStringAsync()); +#pragma warning restore CS0618 // Type or member is obsolete Assert.Equal("mongodb://admin:{mongodb-password.value}@{mongodb.bindings.tcp.host}:{mongodb.bindings.tcp.port}?authSource=admin&authMechanism=SCRAM-SHA-256", serverResource.ConnectionStringExpression.ValueExpression); +#pragma warning disable CS0618 // Type or member is obsolete Assert.Equal($"mongodb://admin:{dbResource.Parent.PasswordParameter?.Value}@localhost:27017/mydatabase?authSource=admin&authMechanism=SCRAM-SHA-256", connectionString); +#pragma warning restore CS0618 // Type or member is obsolete Assert.Equal("mongodb://admin:{mongodb-password.value}@{mongodb.bindings.tcp.host}:{mongodb.bindings.tcp.port}/mydatabase?authSource=admin&authMechanism=SCRAM-SHA-256", connectionStringResource.ConnectionStringExpression.ValueExpression); } diff --git a/tests/Aspire.Hosting.MongoDB.Tests/MongoDbFunctionalTests.cs b/tests/Aspire.Hosting.MongoDB.Tests/MongoDbFunctionalTests.cs index 053ea1689e1..65e3676d41a 100644 --- a/tests/Aspire.Hosting.MongoDB.Tests/MongoDbFunctionalTests.cs +++ b/tests/Aspire.Hosting.MongoDB.Tests/MongoDbFunctionalTests.cs @@ -117,7 +117,9 @@ public async Task WithDataShouldPersistStateBetweenUsages(bool useVolume) { using var builder1 = TestDistributedApplicationBuilder.CreateWithTestContainerRegistry(testOutputHelper); var mongodb1 = builder1.AddMongoDB("mongodb"); +#pragma warning disable CS0618 // Type or member is obsolete var password = mongodb1.Resource.PasswordParameter!.Value; +#pragma warning restore CS0618 // Type or member is obsolete var db1 = mongodb1.AddDatabase(dbName); if (useVolume) diff --git a/tests/Aspire.Hosting.MySql.Tests/MySqlFunctionalTests.cs b/tests/Aspire.Hosting.MySql.Tests/MySqlFunctionalTests.cs index a1f906b2d80..e335ff34af8 100644 --- a/tests/Aspire.Hosting.MySql.Tests/MySqlFunctionalTests.cs +++ b/tests/Aspire.Hosting.MySql.Tests/MySqlFunctionalTests.cs @@ -129,7 +129,9 @@ public async Task WithDataShouldPersistStateBetweenUsages(bool useVolume) using var builder1 = TestDistributedApplicationBuilder.CreateWithTestContainerRegistry(testOutputHelper); var mysql1 = builder1.AddMySql("mysql").WithEnvironment("MYSQL_DATABASE", mySqlDbName); +#pragma warning disable CS0618 // Type or member is obsolete var password = mysql1.Resource.PasswordParameter.Value; +#pragma warning restore CS0618 // Type or member is obsolete var db1 = mysql1.AddDatabase(mySqlDbName); diff --git a/tests/Aspire.Hosting.Nats.Tests/AddNatsTests.cs b/tests/Aspire.Hosting.Nats.Tests/AddNatsTests.cs index 5dbf1c81632..0a96ba18d01 100644 --- a/tests/Aspire.Hosting.Nats.Tests/AddNatsTests.cs +++ b/tests/Aspire.Hosting.Nats.Tests/AddNatsTests.cs @@ -39,7 +39,9 @@ public async Task AddNatsSetsDefaultUserNameAndPasswordAndIncludesThemInConnecti .WithEndpoint("tcp", e => e.AllocatedEndpoint = new AllocatedEndpoint(e, "localhost", 4222)); Assert.NotNull(nats.Resource.PasswordParameter); +#pragma warning disable CS0618 // Type or member is obsolete Assert.False(string.IsNullOrEmpty(nats.Resource.PasswordParameter!.Value)); +#pragma warning restore CS0618 // Type or member is obsolete using var app = appBuilder.Build(); @@ -50,7 +52,9 @@ public async Task AddNatsSetsDefaultUserNameAndPasswordAndIncludesThemInConnecti Assert.NotNull(connectionStringResource); var connectionString = await connectionStringResource.GetConnectionStringAsync(); +#pragma warning disable CS0618 // Type or member is obsolete Assert.Equal($"nats://nats:{natsResource.PasswordParameter?.Value}@localhost:4222", connectionString); +#pragma warning restore CS0618 // Type or member is obsolete Assert.Equal("nats://nats:{nats-password.value}@{nats.bindings.tcp.host}:{nats.bindings.tcp.port}", connectionStringResource.ConnectionStringExpression.ValueExpression); } @@ -67,8 +71,10 @@ public async Task AddNatsSetsUserNameAndPasswordAndIncludesThemInConnection() Assert.NotNull(nats.Resource.UserNameParameter); Assert.NotNull(nats.Resource.PasswordParameter); +#pragma warning disable CS0618 // Type or member is obsolete Assert.Equal("usr", nats.Resource.UserNameParameter!.Value); Assert.Equal("password", nats.Resource.PasswordParameter!.Value); +#pragma warning restore CS0618 // Type or member is obsolete using var app = appBuilder.Build(); diff --git a/tests/Aspire.Hosting.Oracle.Tests/OracleFunctionalTests.cs b/tests/Aspire.Hosting.Oracle.Tests/OracleFunctionalTests.cs index 829c6343644..c5b43117e6a 100644 --- a/tests/Aspire.Hosting.Oracle.Tests/OracleFunctionalTests.cs +++ b/tests/Aspire.Hosting.Oracle.Tests/OracleFunctionalTests.cs @@ -94,7 +94,9 @@ public async Task WithDataShouldPersistStateBetweenUsages(bool useVolume) var oracle1 = builder1.AddOracle("oracle"); +#pragma warning disable CS0618 // Type or member is obsolete var password = oracle1.Resource.PasswordParameter.Value; +#pragma warning restore CS0618 // Type or member is obsolete var db1 = oracle1.AddDatabase(oracleDbName); diff --git a/tests/Aspire.Hosting.PostgreSQL.Tests/AddPostgresTests.cs b/tests/Aspire.Hosting.PostgreSQL.Tests/AddPostgresTests.cs index e90edbdd46b..e88c2c8c54c 100644 --- a/tests/Aspire.Hosting.PostgreSQL.Tests/AddPostgresTests.cs +++ b/tests/Aspire.Hosting.PostgreSQL.Tests/AddPostgresTests.cs @@ -158,7 +158,9 @@ public async Task PostgresCreatesConnectionString() var connectionString = await connectionStringResource.GetConnectionStringAsync(); Assert.Equal("Host={postgres.bindings.tcp.host};Port={postgres.bindings.tcp.port};Username=postgres;Password={postgres-password.value}", connectionStringResource.ConnectionStringExpression.ValueExpression); +#pragma warning disable CS0618 // Type or member is obsolete Assert.Equal($"Host=localhost;Port=2000;Username=postgres;Password={postgres.Resource.PasswordParameter.Value}", connectionString); +#pragma warning restore CS0618 // Type or member is obsolete } [Fact] @@ -491,7 +493,9 @@ public async Task WithPostgresProducesValidServersJsonFile() Assert.Equal("postgres", servers.GetProperty("1").GetProperty("Username").GetString()); Assert.Equal("prefer", servers.GetProperty("1").GetProperty("SSLMode").GetString()); Assert.Equal("postgres", servers.GetProperty("1").GetProperty("MaintenanceDB").GetString()); +#pragma warning disable CS0618 // Type or member is obsolete Assert.Equal($"echo '{pg1.Resource.PasswordParameter.Value}'", servers.GetProperty("1").GetProperty("PasswordExecCommand").GetString()); +#pragma warning restore CS0618 // Type or member is obsolete // Make sure the second server is correct. Assert.Equal(pg2.Resource.Name, servers.GetProperty("2").GetProperty("Name").GetString()); @@ -501,7 +505,9 @@ public async Task WithPostgresProducesValidServersJsonFile() Assert.Equal("myuser", servers.GetProperty("2").GetProperty("Username").GetString()); Assert.Equal("prefer", servers.GetProperty("2").GetProperty("SSLMode").GetString()); Assert.Equal("postgres", servers.GetProperty("2").GetProperty("MaintenanceDB").GetString()); +#pragma warning disable CS0618 // Type or member is obsolete Assert.Equal($"echo '{pg2.Resource.PasswordParameter.Value}'", servers.GetProperty("2").GetProperty("PasswordExecCommand").GetString()); +#pragma warning restore CS0618 // Type or member is obsolete } [Fact] @@ -619,6 +625,7 @@ public void CanAddDatabasesWithTheSameNameOnMultipleServers() private static string CreatePgWebBookmarkfileContent(PostgresDatabaseResource postgresDatabase) { +#pragma warning disable CS0618 // Type or member is obsolete var user = postgresDatabase.Parent.UserNameParameter?.Value ?? "postgres"; // We're hardcoding references to container resources based on a default Aspire network @@ -631,6 +638,7 @@ private static string CreatePgWebBookmarkfileContent(PostgresDatabaseResource po database = "{postgresDatabase.DatabaseName}" sslmode = "disable" """; +#pragma warning restore CS0618 // Type or member is obsolete return fileContent; } @@ -672,6 +680,8 @@ public async Task VerifyPostgresServerResourceWithUserName() .WithEndpoint("tcp", e => e.AllocatedEndpoint = new AllocatedEndpoint(e, "localhost", 2000)); var connectionString = await postgres.Resource.GetConnectionStringAsync(); +#pragma warning disable CS0618 // Type or member is obsolete Assert.Equal($"Host=localhost;Port=2000;Username=user1;Password={postgres.Resource.PasswordParameter.Value}", connectionString); +#pragma warning restore CS0618 // Type or member is obsolete } } diff --git a/tests/Aspire.Hosting.RabbitMQ.Tests/RabbitMQFunctionalTests.cs b/tests/Aspire.Hosting.RabbitMQ.Tests/RabbitMQFunctionalTests.cs index 2d02f943aa5..fc45616436c 100644 --- a/tests/Aspire.Hosting.RabbitMQ.Tests/RabbitMQFunctionalTests.cs +++ b/tests/Aspire.Hosting.RabbitMQ.Tests/RabbitMQFunctionalTests.cs @@ -104,7 +104,9 @@ public async Task WithDataShouldPersistStateBetweenUsages(bool useVolume) { using var builder1 = TestDistributedApplicationBuilder.CreateWithTestContainerRegistry(testOutputHelper); var rabbitMQ1 = builder1.AddRabbitMQ("rabbitMQ"); +#pragma warning disable CS0618 // Type or member is obsolete var password = rabbitMQ1.Resource.PasswordParameter.Value; +#pragma warning restore CS0618 // Type or member is obsolete if (useVolume) { diff --git a/tests/Aspire.Hosting.Redis.Tests/AddRedisTests.cs b/tests/Aspire.Hosting.Redis.Tests/AddRedisTests.cs index 740082bd2b6..e96145c2e63 100644 --- a/tests/Aspire.Hosting.Redis.Tests/AddRedisTests.cs +++ b/tests/Aspire.Hosting.Redis.Tests/AddRedisTests.cs @@ -321,7 +321,9 @@ public async Task WithRedisInsightProducesCorrectEnvironmentVariables() (item) => { Assert.Equal("RI_REDIS_PASSWORD1", item.Key); +#pragma warning disable CS0618 // Type or member is obsolete Assert.Equal(redis1.Resource.PasswordParameter!.Value, item.Value); +#pragma warning restore CS0618 // Type or member is obsolete }, (item) => { @@ -341,7 +343,9 @@ public async Task WithRedisInsightProducesCorrectEnvironmentVariables() (item) => { Assert.Equal("RI_REDIS_PASSWORD2", item.Key); +#pragma warning disable CS0618 // Type or member is obsolete Assert.Equal(redis2.Resource.PasswordParameter!.Value, item.Value); +#pragma warning restore CS0618 // Type or member is obsolete }, (item) => { @@ -496,7 +500,9 @@ public async Task SingleRedisInstanceWithoutPasswordProducesCorrectRedisHostsVar DistributedApplicationOperation.Run, TestServiceProvider.Instance); +#pragma warning disable CS0618 // Type or member is obsolete Assert.Equal($"myredis1:{redis.Resource.Name}:6379:0:{redis.Resource.PasswordParameter?.Value}", config["REDIS_HOSTS"]); +#pragma warning restore CS0618 // Type or member is obsolete } [Fact] @@ -541,7 +547,9 @@ public async Task MultipleRedisInstanceProducesCorrectRedisHostsVariable() DistributedApplicationOperation.Run, TestServiceProvider.Instance); +#pragma warning disable CS0618 // Type or member is obsolete Assert.Equal($"myredis1:{redis1.Resource.Name}:6379:0:{redis1.Resource.PasswordParameter?.Value},myredis2:myredis2:6379:0:{redis2.Resource.PasswordParameter?.Value}", config["REDIS_HOSTS"]); +#pragma warning restore CS0618 // Type or member is obsolete } [Theory] diff --git a/tests/Aspire.Hosting.SqlServer.Tests/SqlServerFunctionalTests.cs b/tests/Aspire.Hosting.SqlServer.Tests/SqlServerFunctionalTests.cs index 49840528aa1..985fd32bb85 100644 --- a/tests/Aspire.Hosting.SqlServer.Tests/SqlServerFunctionalTests.cs +++ b/tests/Aspire.Hosting.SqlServer.Tests/SqlServerFunctionalTests.cs @@ -138,7 +138,9 @@ public async Task WithDataShouldPersistStateBetweenUsages(bool useVolume) var sqlserver1 = builder1.AddSqlServer("sqlserver"); var db1 = sqlserver1.AddDatabase(databaseName); +#pragma warning disable CS0618 // Type or member is obsolete var password = sqlserver1.Resource.PasswordParameter.Value; +#pragma warning restore CS0618 // Type or member is obsolete if (useVolume) { diff --git a/tests/Aspire.Hosting.Tests/AddParameterTests.cs b/tests/Aspire.Hosting.Tests/AddParameterTests.cs index 9e567dc48e3..a1e12299ad7 100644 --- a/tests/Aspire.Hosting.Tests/AddParameterTests.cs +++ b/tests/Aspire.Hosting.Tests/AddParameterTests.cs @@ -62,7 +62,9 @@ public void ParametersWithConfigurationValueDoNotGetDefaultValue() var appModel = app.Services.GetRequiredService(); var parameterResource = Assert.Single(appModel.Resources.OfType()); +#pragma warning disable CS0618 // Type or member is obsolete Assert.Equal("ValueFromConfiguration", parameterResource.Value); +#pragma warning restore CS0618 // Type or member is obsolete } [Theory] @@ -97,7 +99,9 @@ public async Task ParametersWithDefaultValueStringOverloadUsedRegardlessOfConfig // Make sure the code value is used, ignoring any config value var parameterResource = Assert.Single(appModel.Resources.OfType(), r => r.Name == "pass"); +#pragma warning disable CS0618 // Type or member is obsolete Assert.Equal($"DefaultValue", parameterResource.Value); +#pragma warning restore CS0618 // Type or member is obsolete // The manifest should not include anything about the default value var paramManifest = await ManifestUtils.GetManifest(appModel.Resources.OfType().Single(r => r.Name == "pass")).DefaultTimeout(); @@ -147,7 +151,9 @@ public async Task ParametersWithDefaultValueGetPublishedIfPublishFlagIsPassed(bo // Make sure the code value is used, ignoring any config value var parameterResource = Assert.Single(appModel.Resources.OfType(), r => r.Name == "pass"); +#pragma warning disable CS0618 // Type or member is obsolete Assert.Equal($"DefaultValue", parameterResource.Value); +#pragma warning restore CS0618 // Type or member is obsolete // The manifest should include the default value, since we passed publishValueAsDefault: true var paramManifest = await ManifestUtils.GetManifest(appModel.Resources.OfType().Single(r => r.Name == "pass")).DefaultTimeout(); @@ -206,13 +212,17 @@ public async Task ParametersWithDefaultValueObjectOverloadUseConfigurationValueW var parameterResource = Assert.Single(appModel.Resources.OfType(), r => r.Name == "pass"); if (hasConfig) { +#pragma warning disable CS0618 // Type or member is obsolete Assert.Equal("ValueFromConfiguration", parameterResource.Value); +#pragma warning restore CS0618 // Type or member is obsolete } else { +#pragma warning disable CS0618 // Type or member is obsolete Assert.NotEqual("ValueFromConfiguration", parameterResource.Value); // We can't test the exact value since it's random, but we can test the length Assert.Equal(10, parameterResource.Value.Length); +#pragma warning restore CS0618 // Type or member is obsolete } // The manifest should always include the fields for the generated default value @@ -268,7 +278,9 @@ public async Task ParametersCanGetValueFromNonDefaultConfigurationKeys() var appModel = app.Services.GetRequiredService(); var parameterResource = Assert.Single(appModel.Resources.OfType(), r => r.Name == "val"); +#pragma warning disable CS0618 // Type or member is obsolete Assert.Equal($"MyAccessToken", parameterResource.Value); +#pragma warning restore CS0618 // Type or member is obsolete // The manifest is not affected by the custom configuration key var paramManifest = await ManifestUtils.GetManifest(appModel.Resources.OfType().Single(r => r.Name == "val")).DefaultTimeout(); diff --git a/tests/Aspire.Hosting.Tests/DistributedApplicationTests.cs b/tests/Aspire.Hosting.Tests/DistributedApplicationTests.cs index e07d96f400f..afd62b4b502 100644 --- a/tests/Aspire.Hosting.Tests/DistributedApplicationTests.cs +++ b/tests/Aspire.Hosting.Tests/DistributedApplicationTests.cs @@ -1178,14 +1178,18 @@ public async Task ProxylessContainerCanBeReferenced() var service = Assert.Single(exeList, c => $"{testName}-servicea".Equals(c.AppModelResourceName)); var env = Assert.Single(service.Spec.Env!, e => e.Name == $"ConnectionStrings__{testName}-redis"); +#pragma warning disable CS0618 // Type or member is obsolete Assert.Equal($"localhost:1234,password={redis.Resource.PasswordParameter?.Value}", env.Value); +#pragma warning restore CS0618 // Type or member is obsolete var list = await s.ListAsync().DefaultTimeout(); var redisContainer = Assert.Single(list, c => Regex.IsMatch(c.Name(), $"{testName}-redis-{ReplicaIdRegex}")); Assert.Equal(1234, Assert.Single(redisContainer.Spec.Ports!).HostPort); var otherRedisEnv = Assert.Single(service.Spec.Env!, e => e.Name == $"ConnectionStrings__{testName}-redisNoPort"); +#pragma warning disable CS0618 // Type or member is obsolete Assert.Equal($"localhost:6379,password={redisNoPort.Resource.PasswordParameter?.Value}", otherRedisEnv.Value); +#pragma warning restore CS0618 // Type or member is obsolete var otherRedisContainer = Assert.Single(list, c => Regex.IsMatch(c.Name(), $"{testName}-redisNoPort-{ReplicaIdRegex}")); Assert.Equal(6379, Assert.Single(otherRedisContainer.Spec.Ports!).HostPort); @@ -1232,14 +1236,18 @@ public async Task WithEndpointProxySupportDisablesProxies() var service = Assert.Single(exeList, c => $"{testName}-servicea".Equals(c.AppModelResourceName)); var env = Assert.Single(service.Spec.Env!, e => e.Name == $"ConnectionStrings__{testName}-redis"); +#pragma warning disable CS0618 // Type or member is obsolete Assert.Equal($"localhost:1234,password={redis.Resource.PasswordParameter!.Value}", env.Value); +#pragma warning restore CS0618 // Type or member is obsolete var list = await s.ListAsync().DefaultTimeout(); var redisContainer = Assert.Single(list, c => Regex.IsMatch(c.Name(), $"{testName}-redis-{ReplicaIdRegex}")); Assert.Equal(1234, Assert.Single(redisContainer.Spec.Ports!).HostPort); var otherRedisEnv = Assert.Single(service.Spec.Env!, e => e.Name == $"ConnectionStrings__{testName}-redisNoPort"); +#pragma warning disable CS0618 // Type or member is obsolete Assert.Equal($"localhost:6379,password={redisNoPort.Resource.PasswordParameter!.Value}", otherRedisEnv.Value); +#pragma warning restore CS0618 // Type or member is obsolete var otherRedisContainer = Assert.Single(list, c => Regex.IsMatch(c.Name(), $"{testName}-redisNoPort-{ReplicaIdRegex}")); Assert.Equal(6379, Assert.Single(otherRedisContainer.Spec.Ports!).HostPort); diff --git a/tests/Aspire.Hosting.Tests/Orchestrator/ParameterProcessorTests.cs b/tests/Aspire.Hosting.Tests/Orchestrator/ParameterProcessorTests.cs index 344f617dbcb..e02f6282010 100644 --- a/tests/Aspire.Hosting.Tests/Orchestrator/ParameterProcessorTests.cs +++ b/tests/Aspire.Hosting.Tests/Orchestrator/ParameterProcessorTests.cs @@ -34,7 +34,9 @@ public async Task InitializeParametersAsync_WithValidParameters_SetsActiveState( { Assert.NotNull(param.WaitForValueTcs); Assert.True(param.WaitForValueTcs.Task.IsCompletedSuccessfully); +#pragma warning disable CS0618 // Type or member is obsolete Assert.Equal(param.Value, await param.WaitForValueTcs.Task); +#pragma warning restore CS0618 // Type or member is obsolete } } @@ -58,7 +60,9 @@ public async Task InitializeParametersAsync_WithValidParametersAndDashboardEnabl { Assert.NotNull(param.WaitForValueTcs); Assert.True(param.WaitForValueTcs.Task.IsCompletedSuccessfully); +#pragma warning disable CS0618 // Type or member is obsolete Assert.Equal(param.Value, await param.WaitForValueTcs.Task); +#pragma warning restore CS0618 // Type or member is obsolete } }