Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 14 additions & 4 deletions playground/CustomResources/CustomResources.AppHost/TestResource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@
// The .NET Foundation licenses this file to you under the MIT license.

using System.Globalization;
using Aspire.Hosting.Eventing;
using Aspire.Hosting.Lifecycle;
using Microsoft.Extensions.Logging;

static class TestResourceExtensions
{
public static IResourceBuilder<TestResource> AddTestResource(this IDistributedApplicationBuilder builder, string name)
{
builder.Services.TryAddLifecycleHook<TestResourceLifecycleHook>();
builder.Services.TryAddEventingSubscriber<TestResourceLifecycle>();

var rb = builder.AddResource(new TestResource(name))
.WithInitialState(new()
Expand All @@ -27,13 +28,16 @@ public static IResourceBuilder<TestResource> AddTestResource(this IDistributedAp
}
}

internal sealed class TestResourceLifecycleHook(ResourceNotificationService notificationService, ResourceLoggerService loggerService) : IDistributedApplicationLifecycleHook, IAsyncDisposable
internal sealed class TestResourceLifecycle(
ResourceNotificationService notificationService,
ResourceLoggerService loggerService
) : IDistributedApplicationEventingSubscriber
{
private readonly CancellationTokenSource _tokenSource = new();

public Task BeforeStartAsync(DistributedApplicationModel appModel, CancellationToken cancellationToken = default)
public Task OnBeforeStartAsync(BeforeStartEvent @event, CancellationToken cancellationToken = default)
{
foreach (var resource in appModel.Resources.OfType<TestResource>())
foreach (var resource in @event.Model.Resources.OfType<TestResource>())
{
var states = new[] { "Starting", "Running", "Finished", "Uploading", "Downloading", "Processing", "Provisioning" };
var stateStyles = new[] { "info", "success", "warning", "error" };
Expand Down Expand Up @@ -76,6 +80,12 @@ public ValueTask DisposeAsync()
_tokenSource.Cancel();
return default;
}

public Task SubscribeAsync(IDistributedApplicationEventing eventing, DistributedApplicationExecutionContext executionContext, CancellationToken cancellationToken)
{
eventing.Subscribe<BeforeStartEvent>(OnBeforeStartAsync);
return Task.CompletedTask;
}
}

sealed class TestResource(string name) : Resource(name)
Expand Down
15 changes: 11 additions & 4 deletions playground/HealthChecks/HealthChecksSandbox.AppHost/Program.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using Aspire.Hosting.Eventing;
using Aspire.Hosting.Lifecycle;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Diagnostics.HealthChecks;

var builder = DistributedApplication.CreateBuilder(args);

builder.Services.TryAddLifecycleHook<TestResourceLifecycleHook>();
builder.Services.TryAddEventingSubscriber<TestResourceLifecycle>();

AddTestResource("healthy", HealthStatus.Healthy, "I'm fine, thanks for asking.");
AddTestResource("unhealthy", HealthStatus.Unhealthy, "I can't do that, Dave.", exceptionMessage: "Feeling unhealthy.");
Expand Down Expand Up @@ -60,11 +61,11 @@ void AddTestResource(string name, HealthStatus status, string? description = nul

internal sealed class TestResource(string name) : Resource(name);

internal sealed class TestResourceLifecycleHook(ResourceNotificationService notificationService) : IDistributedApplicationLifecycleHook
internal sealed class TestResourceLifecycle(ResourceNotificationService notificationService) : IDistributedApplicationEventingSubscriber
{
public Task BeforeStartAsync(DistributedApplicationModel appModel, CancellationToken cancellationToken)
public Task OnBeforeStartAsync(BeforeStartEvent @event, CancellationToken cancellationToken)
{
foreach (var resource in appModel.Resources.OfType<TestResource>())
foreach (var resource in @event.Model.Resources.OfType<TestResource>())
{
Task.Run(
async () =>
Expand All @@ -80,4 +81,10 @@ await notificationService.PublishUpdateAsync(

return Task.CompletedTask;
}

public Task SubscribeAsync(IDistributedApplicationEventing eventing, DistributedApplicationExecutionContext executionContext, CancellationToken cancellationToken)
{
eventing.Subscribe<BeforeStartEvent>(OnBeforeStartAsync);
return Task.CompletedTask;
}
}
18 changes: 14 additions & 4 deletions playground/Stress/Stress.AppHost/TestResource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@

using System.Globalization;
using Aspire.Dashboard.Model;
using Aspire.Hosting.Eventing;
using Aspire.Hosting.Lifecycle;
using Microsoft.Extensions.Logging;

static class TestResourceExtensions
{
public static IResourceBuilder<TestResource> AddTestResource(this IDistributedApplicationBuilder builder, string name)
{
builder.Services.TryAddLifecycleHook<TestResourceLifecycleHook>();
builder.Services.TryAddEventingSubscriber<TestResourceLifecycle>();

var rb = builder.AddResource(new TestResource(name))
.WithInitialState(new()
Expand Down Expand Up @@ -46,13 +47,16 @@ public static IResourceBuilder<TestNestedResource> AddNestedResource(this IDistr
}
}

internal sealed class TestResourceLifecycleHook(ResourceNotificationService notificationService, ResourceLoggerService loggerService) : IDistributedApplicationLifecycleHook, IAsyncDisposable
internal sealed class TestResourceLifecycle(
ResourceNotificationService notificationService,
ResourceLoggerService loggerService
) : IDistributedApplicationEventingSubscriber, IAsyncDisposable
{
private readonly CancellationTokenSource _tokenSource = new();

public Task BeforeStartAsync(DistributedApplicationModel appModel, CancellationToken cancellationToken = default)
public Task OnBeforeStartAsync(BeforeStartEvent @event, CancellationToken cancellationToken = default)
{
foreach (var resource in appModel.Resources.OfType<TestResource>())
foreach (var resource in @event.Model.Resources.OfType<TestResource>())
{
var states = new[] { "Starting", "Running", "Finished" };

Expand Down Expand Up @@ -94,6 +98,12 @@ public ValueTask DisposeAsync()
_tokenSource.Cancel();
return default;
}

public Task SubscribeAsync(IDistributedApplicationEventing eventing, DistributedApplicationExecutionContext executionContext, CancellationToken cancellationToken)
{
eventing.Subscribe<BeforeStartEvent>(OnBeforeStartAsync);
return Task.CompletedTask;
}
}

sealed class TestResource(string name) : Resource(name)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ internal static IDistributedApplicationBuilder AddAzureContainerAppsInfrastructu
// so Azure resources don't need to add the default role assignments themselves
builder.Services.Configure<AzureProvisioningOptions>(o => o.SupportsTargetedRoleAssignments = true);

builder.Services.TryAddLifecycleHook<AzureContainerAppsInfrastructure>();
builder.Services.TryAddEventingSubscriber<AzureContainerAppsInfrastructure>();

return builder;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

using Aspire.Hosting.ApplicationModel;
using Aspire.Hosting.Azure.AppContainers;
using Aspire.Hosting.Eventing;
using Aspire.Hosting.Lifecycle;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
Expand All @@ -13,25 +14,19 @@ namespace Aspire.Hosting.Azure;

/// <summary>
/// Represents the infrastructure for Azure Container Apps within the Aspire Hosting environment.
/// Implements the <see cref="IDistributedApplicationLifecycleHook"/> interface to provide lifecycle hooks for distributed applications.
/// </summary>
internal sealed class AzureContainerAppsInfrastructure(
ILogger<AzureContainerAppsInfrastructure> logger,
IOptions<AzureProvisioningOptions> provisioningOptions,
DistributedApplicationExecutionContext executionContext) : IDistributedApplicationLifecycleHook
DistributedApplicationExecutionContext executionContext,
IOptions<AzureProvisioningOptions> options) : IDistributedApplicationEventingSubscriber
{
public async Task BeforeStartAsync(DistributedApplicationModel appModel, CancellationToken cancellationToken = default)
private async Task OnBeforeStartAsync(BeforeStartEvent @event, CancellationToken cancellationToken = default)
{
if (executionContext.IsRunMode)
{
return;
}

var caes = appModel.Resources.OfType<AzureContainerAppEnvironmentResource>().ToArray();
var caes = @event.Model.Resources.OfType<AzureContainerAppEnvironmentResource>().ToArray();

if (caes.Length == 0)
{
EnsureNoPublishAsAcaAnnotations(appModel);
EnsureNoPublishAsAcaAnnotations(@event.Model);
return;
}

Expand All @@ -42,9 +37,9 @@ public async Task BeforeStartAsync(DistributedApplicationModel appModel, Cancell
executionContext,
environment);

foreach (var r in appModel.GetComputeResources())
foreach (var r in @event.Model.GetComputeResources())
{
var containerApp = await containerAppEnvironmentContext.CreateContainerAppAsync(r, provisioningOptions.Value, cancellationToken).ConfigureAwait(false);
var containerApp = await containerAppEnvironmentContext.CreateContainerAppAsync(r, options.Value, cancellationToken).ConfigureAwait(false);

// Capture information about the container registry used by the
// container app environment in the deployment target information
Expand All @@ -68,4 +63,14 @@ private static void EnsureNoPublishAsAcaAnnotations(DistributedApplicationModel
}
}
}

public Task SubscribeAsync(IDistributedApplicationEventing eventing, DistributedApplicationExecutionContext executionContext, CancellationToken cancellationToken)
{
if (!executionContext.IsRunMode)
{
eventing.Subscribe<BeforeStartEvent>(OnBeforeStartAsync);
}

return Task.CompletedTask;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ internal static IDistributedApplicationBuilder AddAzureAppServiceInfrastructureC

builder.Services.Configure<AzureProvisioningOptions>(options => options.SupportsTargetedRoleAssignments = true);

builder.Services.TryAddLifecycleHook<AzureAppServiceInfrastructure>();
builder.Services.TryAddEventingSubscriber<AzureAppServiceInfrastructure>();

return builder;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.

using Aspire.Hosting.ApplicationModel;
using Aspire.Hosting.Eventing;
using Aspire.Hosting.Lifecycle;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
Expand All @@ -11,21 +12,20 @@ namespace Aspire.Hosting.Azure.AppService;
internal sealed class AzureAppServiceInfrastructure(
ILogger<AzureAppServiceInfrastructure> logger,
IOptions<AzureProvisioningOptions> provisioningOptions,
DistributedApplicationExecutionContext executionContext) :
IDistributedApplicationLifecycleHook
DistributedApplicationExecutionContext executionContext) : IDistributedApplicationEventingSubscriber
{
public async Task BeforeStartAsync(DistributedApplicationModel appModel, CancellationToken cancellationToken = default)
private async Task OnBeforeStartAsync(BeforeStartEvent @event, CancellationToken cancellationToken = default)
{
if (!executionContext.IsPublishMode)
{
return;
}

var appServiceEnvironments = appModel.Resources.OfType<AzureAppServiceEnvironmentResource>().ToArray();
var appServiceEnvironments = @event.Model.Resources.OfType<AzureAppServiceEnvironmentResource>().ToArray();

if (appServiceEnvironments.Length == 0)
{
EnsureNoPublishAsAzureAppServiceWebsiteAnnotations(appModel);
EnsureNoPublishAsAzureAppServiceWebsiteAnnotations(@event.Model);
return;
}

Expand All @@ -36,7 +36,7 @@ public async Task BeforeStartAsync(DistributedApplicationModel appModel, Cancell
executionContext,
appServiceEnvironment);

foreach (var resource in appModel.GetComputeResources())
foreach (var resource in @event.Model.GetComputeResources())
{
// Support project resources and containers with Dockerfile
if (resource is not ProjectResource && !(resource.IsContainer() && resource.TryGetAnnotationsOfType<DockerfileBuildAnnotation>(out _)))
Expand Down Expand Up @@ -67,4 +67,10 @@ private static void EnsureNoPublishAsAzureAppServiceWebsiteAnnotations(Distribut
}
}
}

public Task SubscribeAsync(IDistributedApplicationEventing eventing, DistributedApplicationExecutionContext executionContext, CancellationToken cancellationToken)
{
eventing.Subscribe<BeforeStartEvent>(OnBeforeStartAsync);
return Task.CompletedTask;
}
}
Loading
Loading