Skip to content

Commit

Permalink
Respond to PR feedback
Browse files Browse the repository at this point in the history
- Write the connectionString to the manifest if it is provided.
- Use DistributedApplicationException
  • Loading branch information
eerhardt committed Oct 6, 2023
1 parent 4062f57 commit 433ed2e
Show file tree
Hide file tree
Showing 10 changed files with 80 additions and 31 deletions.
2 changes: 1 addition & 1 deletion src/Aspire.Hosting/Postgres/IPostgresComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ namespace Aspire.Hosting.Postgres;

public interface IPostgresComponent : IDistributedApplicationComponent
{
string GetConnectionString(string? databaseName = null);
string? GetConnectionString(string? databaseName = null);
}
31 changes: 24 additions & 7 deletions src/Aspire.Hosting/Postgres/PostgresBuilderExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,25 @@ public static IDistributedApplicationComponentBuilder<PostgresContainerComponent
});
}

public static IDistributedApplicationComponentBuilder<PostgresComponent> AddPostgres(this IDistributedApplicationBuilder builder, string name, string connectionString)
public static IDistributedApplicationComponentBuilder<PostgresComponent> AddPostgres(this IDistributedApplicationBuilder builder, string name, string? connectionString)
{
return builder.AddComponent(new PostgresComponent(name, connectionString))
.WithAnnotation(new ManifestPublishingCallbackAnnotation(WritePostgresComponentToManifest));
var postgres = new PostgresComponent(name, connectionString);

return builder.AddComponent(postgres)
.WithAnnotation(new ManifestPublishingCallbackAnnotation((jsonWriter, cancellationToken) =>
WritePostgresComponentToManifest(jsonWriter, postgres.GetConnectionString(), cancellationToken)));
}

private static async Task WritePostgresComponentToManifest(Utf8JsonWriter jsonWriter, CancellationToken cancellationToken)
private static Task WritePostgresComponentToManifest(Utf8JsonWriter jsonWriter, CancellationToken cancellationToken) =>
WritePostgresComponentToManifest(jsonWriter, null, cancellationToken);

private static async Task WritePostgresComponentToManifest(Utf8JsonWriter jsonWriter, string? connectionString, CancellationToken cancellationToken)
{
jsonWriter.WriteString("type", "postgres.v1");
if (!string.IsNullOrEmpty(connectionString))
{
jsonWriter.WriteString("connectionString", connectionString);
}
await jsonWriter.FlushAsync(cancellationToken).ConfigureAwait(false);
}

Expand All @@ -50,18 +60,25 @@ private static async Task WritePostgresComponentToManifest(Utf8JsonWriter jsonWr
public static IDistributedApplicationComponentBuilder<T> WithPostgresDatabase<T>(this IDistributedApplicationComponentBuilder<T> builder, IDistributedApplicationComponentBuilder<IPostgresComponent> postgresBuilder, string? databaseName = null, string? connectionName = null)
where T : IDistributedApplicationComponentWithEnvironment
{
var postgres = postgresBuilder.Component;
connectionName = connectionName ?? postgresBuilder.Component.Name;

return builder.WithEnvironment((context) =>
{
var connectionStringName = $"{ConnectionStringEnvironmentName}{connectionName}";
if (context.PublisherName == "manifest")
{
context.EnvironmentVariables[$"{ConnectionStringEnvironmentName}{connectionName}"] = $"{{{postgresBuilder.Component.Name}.connectionString}}";
context.EnvironmentVariables[connectionStringName] = $"{{{postgres.Name}.connectionString}}";
return;
}
var connectionString = postgresBuilder.Component.GetConnectionString(databaseName);
context.EnvironmentVariables[$"{ConnectionStringEnvironmentName}{connectionName}"] = connectionString;
var connectionString = postgres.GetConnectionString(databaseName);
if (string.IsNullOrEmpty(connectionString))
{
throw new DistributedApplicationException($"A connection string for Postgres '{postgres.Name}' could not be retrieved.");
}
context.EnvironmentVariables[connectionStringName] = connectionString;
});
}
}
5 changes: 3 additions & 2 deletions src/Aspire.Hosting/Postgres/PostgresComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@

namespace Aspire.Hosting.Postgres;

public class PostgresComponent(string name, string connectionString) : DistributedApplicationComponent(name), IPostgresComponent
public class PostgresComponent(string name, string? connectionString) : DistributedApplicationComponent(name), IPostgresComponent
{
public string GetConnectionString(string? databaseName = null) =>
public string? GetConnectionString(string? databaseName = null) =>
connectionString is null ? null :
databaseName is null ?
connectionString :
connectionString.EndsWith(';') ?
Expand Down
4 changes: 2 additions & 2 deletions src/Aspire.Hosting/Postgres/PostgresContainerComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ public string GetConnectionString(string? databaseName = null)
{
if (!this.TryGetAllocatedEndPoints(out var allocatedEndpoints))
{
throw new InvalidOperationException("Expected allocated endpoints!");
throw new DistributedApplicationException("Expected allocated endpoints!");
}

if (!this.TryGetLastAnnotation<PostgresPasswordAnnotation>(out var passwordAnnotation))
{
throw new InvalidOperationException($"Postgres does not have a password set!");
throw new DistributedApplicationException($"Postgres does not have a password set!");
}

var allocatedEndpoint = allocatedEndpoints.Single(); // We should only have one endpoint for Postgres.
Expand Down
2 changes: 1 addition & 1 deletion src/Aspire.Hosting/Redis/IRedisComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ namespace Aspire.Hosting.Redis;

public interface IRedisComponent : IDistributedApplicationComponent
{
string GetConnectionString();
string? GetConnectionString();
}
29 changes: 22 additions & 7 deletions src/Aspire.Hosting/Redis/RedisBuilderExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,34 +22,49 @@ public static IDistributedApplicationComponentBuilder<RedisContainerComponent> A
return componentBuilder;
}

public static IDistributedApplicationComponentBuilder<RedisComponent> AddRedis(this IDistributedApplicationBuilder builder, string name, string connectionString)
public static IDistributedApplicationComponentBuilder<RedisComponent> AddRedis(this IDistributedApplicationBuilder builder, string name, string? connectionString)
{
return builder.AddComponent(new RedisComponent(name, connectionString))
.WithAnnotation(new ManifestPublishingCallbackAnnotation(WriteRedisComponentToManifest));
var redis = new RedisComponent(name, connectionString);

return builder.AddComponent(redis)
.WithAnnotation(new ManifestPublishingCallbackAnnotation((jsonWriter, cancellationToken) =>
WriteRedisComponentToManifest(jsonWriter, redis.GetConnectionString(), cancellationToken)));
}

private static async Task WriteRedisComponentToManifest(Utf8JsonWriter jsonWriter, CancellationToken cancellationToken)
private static Task WriteRedisComponentToManifest(Utf8JsonWriter jsonWriter, CancellationToken cancellationToken) =>
WriteRedisComponentToManifest(jsonWriter, null, cancellationToken);

private static async Task WriteRedisComponentToManifest(Utf8JsonWriter jsonWriter, string? connectionString, CancellationToken cancellationToken)
{
jsonWriter.WriteString("type", "redis.v1");
if (!string.IsNullOrEmpty(connectionString))
{
jsonWriter.WriteString("connectionString", connectionString);
}
await jsonWriter.FlushAsync(cancellationToken).ConfigureAwait(false);
}

public static IDistributedApplicationComponentBuilder<T> WithRedis<T>(this IDistributedApplicationComponentBuilder<T> builder, IDistributedApplicationComponentBuilder<IRedisComponent> redisBuilder, string? connectionName = null)
where T : IDistributedApplicationComponentWithEnvironment
{
connectionName = connectionName ?? redisBuilder.Component.Name;
var redis = redisBuilder.Component;
connectionName = connectionName ?? redis.Name;

return builder.WithEnvironment((context) =>
{
var connectionStringName = $"{ConnectionStringEnvironmentName}{connectionName}";
if (context.PublisherName == "manifest")
{
context.EnvironmentVariables[connectionStringName] = $"{{{redisBuilder.Component.Name}.connectionString}}";
context.EnvironmentVariables[connectionStringName] = $"{{{redis.Name}.connectionString}}";
return;
}
var connectionString = redisBuilder.Component.GetConnectionString();
var connectionString = redis.GetConnectionString();
if (string.IsNullOrEmpty(connectionString))
{
throw new DistributedApplicationException($"A connection string for Redis '{redis.Name}' could not be retrieved.");
}
context.EnvironmentVariables[connectionStringName] = connectionString;
});
}
Expand Down
4 changes: 2 additions & 2 deletions src/Aspire.Hosting/Redis/RedisComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

namespace Aspire.Hosting.Redis;

public class RedisComponent(string name, string connectionString) : DistributedApplicationComponent(name), IRedisComponent
public class RedisComponent(string name, string? connectionString) : DistributedApplicationComponent(name), IRedisComponent
{
public string GetConnectionString() => connectionString;
public string? GetConnectionString() => connectionString;
}
2 changes: 1 addition & 1 deletion src/Aspire.Hosting/SqlServer/ISqlServerComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ namespace Aspire.Hosting.SqlServer;

public interface ISqlServerComponent : IDistributedApplicationComponent
{
string GetConnectionString(string? databaseName = null);
string? GetConnectionString(string? databaseName = null);
}
27 changes: 21 additions & 6 deletions src/Aspire.Hosting/SqlServer/SqlServerBuilderExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,21 +24,32 @@ public static IDistributedApplicationComponentBuilder<SqlServerContainerComponen
return componentBuilder;
}

public static IDistributedApplicationComponentBuilder<SqlServerComponent> AddSqlServer(this IDistributedApplicationBuilder builder, string name, string connectionString)
public static IDistributedApplicationComponentBuilder<SqlServerComponent> AddSqlServer(this IDistributedApplicationBuilder builder, string name, string? connectionString)
{
return builder.AddComponent(new SqlServerComponent(name, connectionString))
.WithAnnotation(new ManifestPublishingCallbackAnnotation(WriteSqlServerComponentToManifest));
var sqlServer = new SqlServerComponent(name, connectionString);

return builder.AddComponent(sqlServer)
.WithAnnotation(new ManifestPublishingCallbackAnnotation((jsonWriter, cancellationToken) =>
WriteSqlServerComponentToManifest(jsonWriter, sqlServer.GetConnectionString(), cancellationToken)));
}

private static async Task WriteSqlServerComponentToManifest(Utf8JsonWriter jsonWriter, CancellationToken cancellationToken)
private static Task WriteSqlServerComponentToManifest(Utf8JsonWriter jsonWriter, CancellationToken cancellationToken) =>
WriteSqlServerComponentToManifest(jsonWriter, null, cancellationToken);

private static async Task WriteSqlServerComponentToManifest(Utf8JsonWriter jsonWriter, string? connectionString, CancellationToken cancellationToken)
{
jsonWriter.WriteString("type", "sqlserver.v1");
if (!string.IsNullOrEmpty(connectionString))
{
jsonWriter.WriteString("connectionString", connectionString);
}
await jsonWriter.FlushAsync(cancellationToken).ConfigureAwait(false);
}

public static IDistributedApplicationComponentBuilder<T> WithSqlServer<T>(this IDistributedApplicationComponentBuilder<T> builder, IDistributedApplicationComponentBuilder<SqlServerContainerComponent> sqlBuilder, string? databaseName, string? connectionName = null)
where T : IDistributedApplicationComponentWithEnvironment
{
var sql = sqlBuilder.Component;
connectionName = connectionName ?? sqlBuilder.Component.Name;

return builder.WithEnvironment((context) =>
Expand All @@ -47,11 +58,15 @@ public static IDistributedApplicationComponentBuilder<T> WithSqlServer<T>(this I
if (context.PublisherName == "manifest")
{
context.EnvironmentVariables[connectionStringName] = $"{{{sqlBuilder.Component.Name}.connectionString}}";
context.EnvironmentVariables[connectionStringName] = $"{{{sql.Name}.connectionString}}";
return;
}
var connectionString = sqlBuilder.Component.GetConnectionString(databaseName);
var connectionString = sql.GetConnectionString(databaseName);
if (string.IsNullOrEmpty(connectionString))
{
throw new DistributedApplicationException($"A connection string for SqlServer '{sql.Name}' could not be retrieved.");
}
context.EnvironmentVariables[connectionStringName] = connectionString;
});
}
Expand Down
5 changes: 3 additions & 2 deletions src/Aspire.Hosting/SqlServer/SqlServerComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@

namespace Aspire.Hosting.SqlServer;

public class SqlServerComponent(string name, string connectionString) : DistributedApplicationComponent(name), ISqlServerComponent
public class SqlServerComponent(string name, string? connectionString) : DistributedApplicationComponent(name), ISqlServerComponent
{
public string GetConnectionString(string? databaseName = null) =>
public string? GetConnectionString(string? databaseName = null) =>
connectionString is null ? null :
databaseName is null ?
connectionString :
connectionString.EndsWith(';') ?
Expand Down

0 comments on commit 433ed2e

Please sign in to comment.