Skip to content

Commit

Permalink
Moved a few things around and started adding support for .NET Aspire.
Browse files Browse the repository at this point in the history
  • Loading branch information
IEvangelist committed Dec 19, 2024
1 parent e24a40e commit 33e7437
Show file tree
Hide file tree
Showing 57 changed files with 1,133 additions and 61 deletions.
1 change: 1 addition & 0 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<LangVersion>preview</LangVersion>
<EnableConfigurationBindingGenerator>true</EnableConfigurationBindingGenerator>
</PropertyGroup>
</Project>
12 changes: 11 additions & 1 deletion Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,29 @@
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="Aspire.Hosting" Version="9.0.0" />
<PackageVersion Include="Aspire.Hosting.AppHost" Version="9.0.0" />
<PackageVersion Include="Blazor.LocalStorage" Version="9.0.1" />
<PackageVersion Include="coverlet.collector" Version="6.0.2" />
<PackageVersion Include="GitHub.Actions.Core" Version="8.1.1" />
<PackageVersion Include="GitHub.Actions.Octokit" Version="8.1.1" />
<PackageVersion Include="GitHubActionsTestLogger" Version="2.3.3" />
<PackageVersion Include="Microsoft.AspNetCore.OpenApi" Version="9.0.0" />
<PackageVersion Include="Microsoft.AspNetCore.SignalR.Client.Core" Version="9.0.0" />
<PackageVersion Include="Microsoft.AspNetCore.SignalR.Protocols.MessagePack" Version="8.0.10" />
<PackageVersion Include="Microsoft.Extensions.Caching.Memory" Version="9.0.0" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Abstractions" Version="9.0.0" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Binder" Version="9.0.0" />
<PackageVersion Include="Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions" Version="9.0.0" />
<PackageVersion Include="Microsoft.Extensions.Hosting.Abstractions" Version="9.0.0" />
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="9.0.0" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="9.0.0" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="9.0.0" />
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="9.0.0" />
<PackageVersion Include="Microsoft.Extensions.Compliance.Redaction" Version="9.0.0" />
<PackageVersion Include="Microsoft.Extensions.Options" Version="9.0.0" />
<PackageVersion Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="9.0.0" />
<PackageVersion Include="Microsoft.Extensions.Options.DataAnnotations" Version="9.0.0" />
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="8.0.0" />
<PackageVersion Include="Microsoft.Testing.Platform.MSBuild" Version="1.4.3" />
<PackageVersion Include="MSTest.Engine" Version="1.0.0-alpha.24562.1" />
Expand All @@ -27,7 +37,7 @@
<PackageVersion Include="Nito.AsyncEx.Coordination" Version="5.1.2" />
<PackageVersion Include="Pathological.Globbing" Version="9.0.0" />
<PackageVersion Include="Swashbuckle.AspNetCore" Version="7.2.0" />
<PackageVersion Include="Markdig" Version="0.38.0" />
<PackageVersion Include="Markdig" Version="0.39.0" />
<PackageVersion Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="9.0.0" />
<PackageVersion Include="Microsoft.AspNetCore.SignalR.Client" Version="9.0.0" />
<PackageVersion Include="System.Linq.Async" Version="6.0.1" />
Expand Down
4 changes: 4 additions & 0 deletions playground/ProfanityFilter.AppHost/CustomData/CustomWords.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
IsPostBack
WebForms
SilverLight
SOAP
26 changes: 26 additions & 0 deletions playground/ProfanityFilter.AppHost/ProfanityFilter.AppHost.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<Project Sdk="Microsoft.NET.Sdk">

<Sdk Name="Aspire.AppHost.Sdk" Version="9.0.0" />

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>$(DefaultTargetFramework)</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsAspireHost>true</IsAspireHost>
<UserSecretsId>e5321ea8-a659-4588-a117-d53dc2c6a5cc</UserSecretsId>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Aspire.Hosting.AppHost" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\ProfanityFilter.Hosting\ProfanityFilter.Hosting.csproj" IsAspireProjectResource="false" />
</ItemGroup>

<ItemGroup>
<Folder Include="CustomData\" />
</ItemGroup>

</Project>
9 changes: 9 additions & 0 deletions playground/ProfanityFilter.AppHost/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Copyright (c) David Pine. All rights reserved.
// Licensed under the MIT License.

var builder = DistributedApplication.CreateBuilder(args);

_ = builder.AddProfanityFilter("profanity-filter")
.WithDataBindMount("./CustomData");

builder.Build().Run();
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}
9 changes: 9 additions & 0 deletions playground/ProfanityFilter.AppHost/appsettings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning",
"Aspire.Hosting.Dcp": "Warning"
}
}
}
30 changes: 30 additions & 0 deletions profanity-filter.sln
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,16 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{EAC63754
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ProfanityFilter.WebApi", "src\ProfanityFilter.WebApi\ProfanityFilter.WebApi.csproj", "{163A89FA-5F97-4332-B5DA-3E7BDDA97E7C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProfanityFilter.Client", "src\ProfanityFilter.Client\ProfanityFilter.Client.csproj", "{C7A1DB9B-A209-4F97-A264-195B4C39241A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProfanityFilter.Shared", "src\ProfanityFilter.Shared\ProfanityFilter.Shared.csproj", "{482EDC8C-D8F1-4934-8274-F24D14D9E4B0}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProfanityFilter.Hosting", "src\ProfanityFilter.Hosting\ProfanityFilter.Hosting.csproj", "{ED750950-FD39-4FF9-B3DC-48FC171164F7}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "playground", "playground", "{02EA681E-C7D8-13C7-8484-4AC65E1B71E8}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProfanityFilter.AppHost", "playground\ProfanityFilter.AppHost\ProfanityFilter.AppHost.csproj", "{B5E3CB82-3306-4DD6-96BB-17995027FCA3}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -58,6 +68,22 @@ Global
{163A89FA-5F97-4332-B5DA-3E7BDDA97E7C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{163A89FA-5F97-4332-B5DA-3E7BDDA97E7C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{163A89FA-5F97-4332-B5DA-3E7BDDA97E7C}.Release|Any CPU.Build.0 = Release|Any CPU
{C7A1DB9B-A209-4F97-A264-195B4C39241A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C7A1DB9B-A209-4F97-A264-195B4C39241A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C7A1DB9B-A209-4F97-A264-195B4C39241A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C7A1DB9B-A209-4F97-A264-195B4C39241A}.Release|Any CPU.Build.0 = Release|Any CPU
{482EDC8C-D8F1-4934-8274-F24D14D9E4B0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{482EDC8C-D8F1-4934-8274-F24D14D9E4B0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{482EDC8C-D8F1-4934-8274-F24D14D9E4B0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{482EDC8C-D8F1-4934-8274-F24D14D9E4B0}.Release|Any CPU.Build.0 = Release|Any CPU
{ED750950-FD39-4FF9-B3DC-48FC171164F7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{ED750950-FD39-4FF9-B3DC-48FC171164F7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{ED750950-FD39-4FF9-B3DC-48FC171164F7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{ED750950-FD39-4FF9-B3DC-48FC171164F7}.Release|Any CPU.Build.0 = Release|Any CPU
{B5E3CB82-3306-4DD6-96BB-17995027FCA3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B5E3CB82-3306-4DD6-96BB-17995027FCA3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B5E3CB82-3306-4DD6-96BB-17995027FCA3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B5E3CB82-3306-4DD6-96BB-17995027FCA3}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -68,6 +94,10 @@ Global
{A1F889D2-290B-42C2-A61C-877C97F9D5EB} = {EAC63754-09D3-49C9-ACDF-ECF73AA1D922}
{37D19359-799E-468B-B404-7A920C7FD1CA} = {EAC63754-09D3-49C9-ACDF-ECF73AA1D922}
{163A89FA-5F97-4332-B5DA-3E7BDDA97E7C} = {28623E11-D15F-4448-82F6-B86A7D59B1D4}
{C7A1DB9B-A209-4F97-A264-195B4C39241A} = {28623E11-D15F-4448-82F6-B86A7D59B1D4}
{482EDC8C-D8F1-4934-8274-F24D14D9E4B0} = {28623E11-D15F-4448-82F6-B86A7D59B1D4}
{ED750950-FD39-4FF9-B3DC-48FC171164F7} = {28623E11-D15F-4448-82F6-B86A7D59B1D4}
{B5E3CB82-3306-4DD6-96BB-17995027FCA3} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {72DBDAF8-D0CD-4A55-A944-0E1787FFA5C6}
Expand Down
8 changes: 6 additions & 2 deletions src/ProfanityFilter.Action/GlobalUsings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,27 @@
global using System.Diagnostics;
global using System.Diagnostics.CodeAnalysis;
global using System.Text.RegularExpressions;

global using Actions.Core.Extensions;
global using Actions.Core.Markdown;
global using Actions.Core.Services;
global using Actions.Core.Summaries;
global using Actions.Octokit;
global using Actions.Octokit.Extensions;

global using GitHub;
global using GitHub.Models;

global using Microsoft.Extensions.DependencyInjection;
global using Microsoft.Extensions.Hosting;

global using ProfanityFilter.Action;
global using ProfanityFilter.Action.Clients;
global using ProfanityFilter.Action.Extensions;
global using ProfanityFilter.Action.Models;
global using ProfanityFilter.Services;
global using ProfanityFilter.Services.Filters;
global using ProfanityFilter.Services.Results;
global using ProfanityFilter.Shared;

global using ContextSummaryPair = (
Actions.Octokit.Context Context,
Actions.Core.Summaries.Summary Summary);
Expand Down
88 changes: 88 additions & 0 deletions src/ProfanityFilter.Client/DefaultRealtimeClient.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
// Copyright (c) David Pine. All rights reserved.
// Licensed under the MIT License.

namespace ProfanityFilter.Client;

internal sealed class DefaultRealtimeClient(
IOptions<ProfanityFilterOptions> options,
ILogger<DefaultRealtimeClient> logger) : IRealtimeClient
{
private readonly HubConnection _connection = new HubConnectionBuilder()
.WithUrl(options.Value.RealtimeUri)
.WithAutomaticReconnect()
.WithStatefulReconnect()
.Build();

/// <inheritdoc />
async ValueTask IRealtimeClient.StartAsync(CancellationToken cancellationToken)
{
_connection.Closed += OnHubConnectionClosedAsync;
_connection.Reconnected += OnHubConnectionReconnectedAsync;
_connection.Reconnecting += OnHubConnectionReconnectingAsync;

await _connection.StartAsync(cancellationToken);
}

/// <inheritdoc />
async ValueTask IRealtimeClient.StopAsync(CancellationToken cancellationToken)
{
_connection.Closed -= OnHubConnectionClosedAsync;
_connection.Reconnected -= OnHubConnectionReconnectedAsync;
_connection.Reconnecting -= OnHubConnectionReconnectingAsync;

await _connection.StopAsync(cancellationToken);
}

private Task OnHubConnectionClosedAsync(Exception? exception)
{
logger.HubConnectionClosed(exception);

return Task.CompletedTask;
}

private Task OnHubConnectionReconnectingAsync(Exception? exception)
{
logger.HubReconnecting(exception);

return Task.CompletedTask;
}

private Task OnHubConnectionReconnectedAsync(string? arg)
{
logger.HubReconnected(arg);

return Task.CompletedTask;
}

/// <inheritdoc />
async IAsyncEnumerable<ProfanityFilterResponse> IRealtimeClient.LiveStreamAsync(
IAsyncEnumerable<ProfanityFilterRequest> liveRequests,
[EnumeratorCancellation] CancellationToken cancellationToken)
{
var channel = Channel.CreateUnbounded<ProfanityFilterResponse>();

_connection.On<ProfanityFilterResponse>(
"live", response => channel.Writer.TryWrite(response));

var sendTask = Task.Run(async () =>
{
await foreach (var request in liveRequests.WithCancellation(cancellationToken))
{
await _connection.SendAsync("LiveStream", request, cancellationToken);
}

channel.Writer.Complete();
},
cancellationToken);

while (await channel.Reader.WaitToReadAsync(cancellationToken))
{
while (channel.Reader.TryRead(out var response))
{
yield return response;
}
}

await sendTask;
}
}
54 changes: 54 additions & 0 deletions src/ProfanityFilter.Client/DefaultRestClient.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Copyright (c) David Pine. All rights reserved.
// Licensed under the MIT License.

namespace ProfanityFilter.Client;

/// <inheritdoc cref="IRestClient" />
internal sealed class DefaultRestClient(HttpClient client) : IRestClient
{
/// <inheritdoc />
async Task<IMaybe<ProfanityFilterResponse>> IRestClient.ApplyFilterAsync(ProfanityFilterRequest request)
{
using var response = await client.PostAsJsonAsync(
"filter", request, JsonSerializationContext.Default.ProfanityFilterRequest);

response.EnsureSuccessStatusCode();

var result = await response.Content.ReadFromJsonAsync(
JsonSerializationContext.Default.ProfanityFilterResponse);

return result.AsMaybe();
}

/// <inheritdoc />
Task<IMaybe<string[]>> IRestClient.GetDataByNameAsync(string name)
{
return GetMaybeAsync($"data/{name}", JsonSerializationContext.Default.StringArray);
}

/// <inheritdoc />
Task<IMaybe<string[]>> IRestClient.GetDataNamesAsync()
{
return GetMaybeAsync("data", JsonSerializationContext.Default.StringArray);
}

/// <inheritdoc />
Task<IMaybe<StrategyResponse[]>> IRestClient.GetStrategiesAsync()
{
return GetMaybeAsync("strategies", JsonSerializationContext.Default.StrategyResponseArray);
}

/// <inheritdoc />
Task<IMaybe<FilterTargetResponse[]>> IRestClient.GetTargetsAsync()
{
return GetMaybeAsync("targets", JsonSerializationContext.Default.FilterTargetResponseArray);
}

/// <inheritdoc />
async Task<IMaybe<T>> GetMaybeAsync<T>(string uri, JsonTypeInfo<T> typeInfo)
{
var data = await client.GetFromJsonAsync(uri, typeInfo);

return data.AsMaybe();
}
}
Loading

0 comments on commit 33e7437

Please sign in to comment.