Skip to content

Commit

Permalink
Merge pull request #203 from TimeWarpEngineering/Cramer/2024-05-21/As…
Browse files Browse the repository at this point in the history
…pire

Cramer/2024 05 21/aspire
  • Loading branch information
StevenTCramer committed Jun 10, 2024
2 parents 91df4ab + c67e3ba commit 849acda
Show file tree
Hide file tree
Showing 107 changed files with 1,676 additions and 330 deletions.
1 change: 1 addition & 0 deletions TimeWarp.Architecture/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -315,3 +315,4 @@ GeneratedCode/
/Documentation/Developer/HowToGuides/Api_Contracts/HowToWrite_BFF_API_Contracts.pdf
/output.txt
/Source/ContainerApps/Web/Web.Spa/wwwroot/css/site.css
/Source/ContainerApps/Web/Web.Spa/Properties/launchSettings.json
13 changes: 12 additions & 1 deletion TimeWarp.Architecture/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,19 @@
<Output TaskParameter="ConsoleOutput" PropertyName="GitCommitTimestamp"/>
</Exec>
<PropertyGroup Condition="'$(GitRepoAvailable)' == 'true'">
<LastCommitDate>$([System.DateTime]::UnixEpoch.AddSeconds($(GitCommitTimestamp)).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssK"))</LastCommitDate>
<!-- Define the Unix epoch start date -->
<UnixEpochStart>1970-01-01T00:00:00Z</UnixEpochStart>

<!-- Calculate the commit date in UTC from the timestamp -->
<GitCommitDate>$([System.DateTime]::Parse($(UnixEpochStart)).AddSeconds($(GitCommitTimestamp)).ToUniversalTime().ToString('yyyy-MM-ddTHH:mm:ssK'))</GitCommitDate>

<!-- Assign the calculated date to LastCommitDate -->
<LastCommitDate>$(GitCommitDate)</LastCommitDate>
</PropertyGroup>

<!--<PropertyGroup Condition="'$(GitRepoAvailable)' == 'true'">
<LastCommitDate>$([System.DateTime]::UnixEpoch.AddSeconds($(GitCommitTimestamp)).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssK"))</LastCommitDate>
</PropertyGroup>-->
<ItemGroup Condition="'$(GitRepoAvailable)' == 'true'">
<AssemblyAttribute Include="System.Reflection.AssemblyMetadataAttribute">
<_Parameter1>CommitDate</_Parameter1>
Expand Down
25 changes: 17 additions & 8 deletions TimeWarp.Architecture/Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,20 @@
<PackageVersion Include="Ardalis.GuardClauses" Version="4.5.0" />
<PackageVersion Include="Asp.Versioning.Http" Version="7.0.0" />
<PackageVersion Include="Asp.Versioning.Mvc" Version="7.0.0" />
<PackageVersion Include="Aspire.Hosting" Version="8.0.0-preview.5.24201.12" />
<PackageVersion Include="Aspire.Hosting.AppHost" Version="8.0.0-preview.7.24251.11" />
<PackageVersion Include="Aspire.Hosting.Azure.CosmosDB" Version="8.0.1" />
<PackageVersion Include="Aspire.Hosting.Testing" Version="8.0.1" />
<PackageVersion Include="Aspire.Microsoft.Azure.Cosmos" Version="8.0.1" />
<PackageVersion Include="Aspire.Microsoft.EntityFrameworkCore.Cosmos" Version="8.0.1" />
<PackageVersion Include="AutoFixture" Version="4.18.1" />
<PackageVersion Include="AutoFixture.AutoFakeItEasy" Version="4.18.1" />
<PackageVersion Include="AutoMapper" Version="13.0.1" />
<PackageVersion Include="Azure.Extensions.AspNetCore.Configuration.Secrets" Version="1.2.2" />
<PackageVersion Include="Azure.Identity" Version="1.11.3" />
<PackageVersion Include="Blazor-State" Version="11.0.0-beta.31" />
<PackageVersion Include="BlazorComponentUtilities" Version="1.8.0" />
<PackageVersion Include="Blazor-State" Version="11.0.0-beta.31" />
<PackageVersion Include="coverlet.collector" Version="6.0.0" />
<PackageVersion Include="FakeItEasy" Version="8.2.0" />
<PackageVersion Include="Fixie" Version="3.4.0" />
<PackageVersion Include="Fixie.TestAdapter" Version="3.4.0" />
Expand All @@ -25,6 +31,7 @@
<PackageVersion Include="Grpc.Net.Client" Version="2.62.0" />
<PackageVersion Include="Grpc.Net.Client.Web" Version="2.62.0" />
<PackageVersion Include="JetBrains.Annotations" Version="2023.3.0" />
<PackageVersion Include="libphonenumber-csharp" Version="8.13.37" />
<PackageVersion Include="MediatR" Version="12.2.0" />
<PackageVersion Include="MediatR.Contracts" Version="2.0.1" />
<PackageVersion Include="MicroElements.Swashbuckle.FluentValidation" Version="6.0.0" />
Expand Down Expand Up @@ -60,6 +67,7 @@
<PackageVersion Include="Microsoft.FluentUI.AspNetCore.Components.Emoji" Version="4.6.0" />
<PackageVersion Include="Microsoft.FluentUI.AspNetCore.Components.Icons" Version="4.7.2" />
<PackageVersion Include="Microsoft.Identity.Web" Version="2.18.2" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
<PackageVersion Include="Microsoft.Playwright" Version="1.44.0" />
<PackageVersion Include="Microsoft.TypeScript.MSBuild" Version="4.6.2" />
<PackageVersion Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.19.5" />
Expand All @@ -76,6 +84,10 @@
<PackageVersion Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.8.1" />
<PackageVersion Include="OpenTelemetry.Instrumentation.Http" Version="1.8.1" />
<PackageVersion Include="OpenTelemetry.Instrumentation.Runtime" Version="1.8.1" />
<PackageVersion Include="protobuf-net.Grpc" Version="1.1.1" />
<PackageVersion Include="protobuf-net.Grpc.AspNetCore" Version="1.1.1" />
<PackageVersion Include="protobuf-net.Grpc.AspNetCore.Reflection" Version="1.1.1" />
<PackageVersion Include="protobuf-net.Grpc.Reflection" Version="1.1.1" />
<PackageVersion Include="Riok.Mapperly" Version="3.5.1" />
<PackageVersion Include="Scrutor" Version="4.2.0" />
<PackageVersion Include="Serilog.AspNetCore" Version="8.0.1" />
Expand All @@ -95,16 +107,13 @@
<PackageVersion Include="System.Net.Http.Json" Version="8.0.0" />
<PackageVersion Include="System.ServiceModel.Primitives" Version="8.0.0" />
<PackageVersion Include="TimeWarp.Fixie" Version="1.0.2" />
<PackageVersion Include="Timewarp.OptionsValidation" Version="1.0.0-beta.2" />
<PackageVersion Include="TimeWarp.SourceGenerators" Version="1.0.0-alpha.5" />
<PackageVersion Include="TimeWarp.State.Plus" Version="11.0.0-beta.31" />
<PackageVersion Include="Timewarp.OptionsValidation" Version="1.0.0-beta.2" />
<PackageVersion Include="Yarp.ReverseProxy" Version="2.1.0" />
<PackageVersion Include="libphonenumber-csharp" Version="8.13.37" />
<PackageVersion Include="protobuf-net.Grpc" Version="1.1.1" />
<PackageVersion Include="protobuf-net.Grpc.AspNetCore" Version="1.1.1" />
<PackageVersion Include="protobuf-net.Grpc.AspNetCore.Reflection" Version="1.1.1" />
<PackageVersion Include="protobuf-net.Grpc.Reflection" Version="1.1.1" />
<PackageVersion Include="timewarp-heroicons" Version="2.0.19" />
<PackageVersion Include="timewarp-simple-icons" Version="11.15.0" />
<PackageVersion Include="xunit" Version="2.5.3" />
<PackageVersion Include="xunit.runner.visualstudio" Version="2.5.3" />
<PackageVersion Include="Yarp.ReverseProxy" Version="2.1.0" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ These components represent modal dialogs used for user interactions that require

### Section Components

Section components represent significant parts of a page but do not have their own routes. They are larger than widgets and can encapsulate substantial functionality, often comprising multiple widgets or other components. Sections are integral parts of a page layout, contributing to the overall structure and functionality of a feature.
Section components represent significant parts of a page but do not have their own routes. Sections are integral parts of a page layout, contributing to the overall structure and functionality of a feature.

**Naming Convention:**
- Suffix: `Section`
Expand All @@ -139,12 +139,45 @@ Section components represent significant parts of a page but do not have their o

### Widget Components

These components are small, self-contained, and focused on a specific piece of functionality or UI element. They are often used to create a modular and reusable interface.
These components are self-contained, and focused on a specific piece of functionality or UI element. They are often used to create a modular and reusable interface. For example, a weather widget that displays the current weather conditions. And can be placed on a dashboard. Widgets can contain Sections, Forms, Tables, Charts, and Dialogs.

**Naming Convention:**
- Suffix: `Widget`
- Example: `WeatherWidget.razor`

## Layout Component Naming Conventions

Components that define the layout of a page or a section of a page. These components are used to structure the UI and organize the content.

### Pane Components

Pane components are explicitly `FluentMultiSplitterPane` contents. They are used within `FluentMultiSplitter` components to divide the layout into resizable panes. These panes can be adjusted by the user to change the size and layout of the content dynamically.

**Naming Convention:**
- Suffix: `Pane`
- Example: `LeftPane.razor`

**Usage Example:**
```html
<FluentMultiSplitter>
<FluentMultiSplitterPane>
<PagePane/>
</FluentMultiSplitterPane>
<FluentMultiSplitterPane Size="20%" Collapsible="true">
<AsidePane />
</FluentMultiSplitter>
```


### Area Components

Area components are containers that are not panes. They serve as organizational units within a page, often grouping related content. Unlike panes, area components are not user-resizable and rely on CSS techniques such as media queries, flexbox, and grid layouts to manage their size and layout.

**Naming Convention:**
- Suffix: `Area`
- Example: `SiteArea.razor`


## Example Directory Structure

```
Expand Down
3 changes: 1 addition & 2 deletions TimeWarp.Architecture/RunNpmInstall.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ try {
if (Test-Path .\node_modules\) {
Remove-Item .\node_modules\ -Force -Recurse
}
npm install
dotnet build
npm install
}
finally {
Pop-Location
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@ $Env:ASPNETCORE_ENVIRONMENT = "Development"

Push-Location $PSScriptRoot
try {
#if(web)
Push-Location ./Source/ContainerApps/Web/Web.TypeScript
Push-Location ./Source/ContainerApps/Web/Web.Spa
try {
npx run tailwind-watch
npm run css:build
}
finally {
Pop-Location
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
global using FluentValidation;
global using FluentValidation.Validators;
global using JetBrains.Annotations;
global using Microsoft.Extensions.DependencyInjection;
global using Microsoft.Extensions.Options;
global using OneOf;
global using PhoneNumbers;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,39 @@
/// You don't care what http verb is used or even what protocol is used.
/// </remarks>
[UsedImplicitly]
public abstract class BaseApiService
(
IHttpClientFactory HttpClientFactory,
string HttpClientName,
IOptions<JsonSerializerOptions> JsonSerializerOptionsAccessor
) : IApiService
public abstract class BaseApiService : IApiService
{
protected HttpClient HttpClient => HttpClientFactory.CreateClient(HttpClientName);
private readonly JsonSerializerOptions JsonSerializerOptions = JsonSerializerOptionsAccessor.Value;
protected HttpClient HttpClient { get; init; }
private readonly JsonSerializerOptions JsonSerializerOptions;

/// <summary>
/// This is the Service that is used to interact with the API.Server
/// </summary>
/// <param name="httpClientFactory"></param>
/// <param name="httpClientName"></param>
/// <param name="jsonSerializerOptionsAccessor"></param>
protected BaseApiService
(
IHttpClientFactory httpClientFactory,
string httpClientName,
IOptions<JsonSerializerOptions> jsonSerializerOptionsAccessor
)
{
JsonSerializerOptions = jsonSerializerOptionsAccessor.Value;
HttpClient = httpClientFactory.CreateClient(httpClientName);
}

/// <summary>
/// This is the Service that is used to interact with the API.Server
/// This constructor is provided for testing purposes.
/// </summary>
/// <param name="httpClient"></param>
/// <param name="jsonSerializerOptions"></param>
protected BaseApiService(HttpClient httpClient, JsonSerializerOptions jsonSerializerOptions)
{
HttpClient = httpClient;
JsonSerializerOptions = jsonSerializerOptions;
}

/// <summary>
/// Get the response for the given request
Expand Down Expand Up @@ -117,7 +141,7 @@ private static string PrepareRoute(IApiRequest apiRequest)
}
private async Task<TResponse> ReadFromJson<TResponse>(HttpResponseMessage httpResponseMessage)
{
httpResponseMessage.EnsureSuccessStatusCode();
//httpResponseMessage.EnsureSuccessStatusCode();

string json = await httpResponseMessage.Content.ReadAsStringAsync().ConfigureAwait(false);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@

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

<ItemGroup>
<ProjectReference Include="..\..\Api\Api.Server\Api.Server.csproj" />
<ProjectReference Include="..\..\Grpc\Grpc.Server\Grpc.Server.csproj" />
<ProjectReference Include="..\..\Web\Web.Server\Web.Server.csproj" />
<ProjectReference Include="..\..\Yarp\Yarp.csproj" />
<ProjectReference Include="..\Aspire.Hosting.Yarp\Aspire.Hosting.Yarp.csproj" IsAspireProjectResource="false" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
namespace TimeWarp.Architecture.Aspire;

internal class Constants
{
public const string CosmosDbResourceName = "cosmos";
public const string CosmosDbConnectionStringName = CosmosDbResourceName;
public const string CosmosDbDatabaseName = "CosmosDbContext";
public const string ApiServerProjectResourceName = "api";
public const string WebServerProjectResourceName = "web";
public const string GrpcServerProjectResourceName = "grpc";
public const string YarpProjectResourceName = "yarp";
public const string YarpResourceName = "ingress";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
global using static TimeWarp.Architecture.Aspire.Constants;
Original file line number Diff line number Diff line change
@@ -1,20 +1,44 @@
IDistributedApplicationBuilder builder = DistributedApplication.CreateBuilder(args);

IResourceBuilder<ProjectResource> apiServer =builder.AddProject<Projects.Api_Server>("api-server");
IResourceBuilder<ProjectResource> grpcServer = builder.AddProject<Projects.Grpc_Server>("grpc-server");
IResourceBuilder<AzureCosmosDBResource> cosmos = builder.AddAzureCosmosDB(CosmosDbResourceName);
IResourceBuilder<AzureCosmosDBResource> cosmosdb = cosmos.AddDatabase(CosmosDbDatabaseName);
#if DEBUG
cosmosdb.RunAsEmulator();
#endif
IResourceBuilder<ProjectResource> apiServer =builder.AddProject<Projects.Api_Server>(ApiServerProjectResourceName);
IResourceBuilder<ProjectResource> grpcServer = builder.AddProject<Projects.Grpc_Server>(GrpcServerProjectResourceName);

IResourceBuilder<ProjectResource> webServer =
builder
.AddProject<Projects.Web_Server>("web-server")
.AddProject<Projects.Web_Server>(WebServerProjectResourceName)
.WithExternalHttpEndpoints()
.WithReference(cosmosdb)
.WithReference(apiServer)
.WithReference(grpcServer);

webServer.WithReference(webServer);

builder.AddProject<Projects.Yarp>("yarp")
.WithReference(apiServer)
.WithReference(webServer)
.WithReference(grpcServer);
// builder.AddProject<Projects.Yarp>(YarpProjectResourceName)
// .WithReference(apiServer)
// .WithReference(webServer)
// .WithReference(grpcServer);

// Using Configuration File
// builder.AddYarp(YarpResourceName)
// .WithHttpEndpoint(port: 8001)
// .WithReference(apiServer)
// .WithReference(webServer)
// .WithReference(grpcServer)
// .LoadFromConfiguration("ReverseProxy");

// Using Code based routes
builder.AddYarp(YarpResourceName)
.WithHttpEndpoint(port: 8001)
// .WithHttpsEndpoint(port: 8002)
.WithEnvironment("ASPNETCORE_ENVIRONMENT", "Development")
.Route(routeId: "spa", target: webServer, path: "/{**catch-all}")
.Route(routeId: "api-server-api", target: apiServer, path: "/api/{**catch-all}")
.Route(routeId: "web-server-api", target: webServer, path: "/api/web-server/{**catch-all}")
.Route(routeId: "grpc", target: grpcServer, path: "/grpc/{**catch-all}", preservePath:false);

builder.Build().Run();
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,64 @@
"Microsoft.AspNetCore": "Warning",
"Aspire.Hosting.Dcp": "Warning"
}
},
"ReverseProxy": {
"Routes": {
"ApiRoute": {
"ClusterId": "Api.Server",
"Match": {
"Path": "/api/{**catch-all}"
}
},
"WebRoute": {
"ClusterId": "Web.Server",
"Match": {
"Path": "{**catch-all}"
}
},
"WebSwaggerRoute": {
"ClusterId": "Web.Server",
"Match": {
"Path": "/api/web-server/{**catch-all}"
}
},
"GrpcRoute": {
"ClusterId": "Grpc.Server",
"Match": {
"Path": "/grpc/{**catch-all}"
},
"Transforms": [
{
"PathRemovePrefix": "/grpc"
}
]
}
},
"Clusters": {
"Api.Server": {
"Destinations": {
"Api.Server": {
"Address": "https://api",
"Host": "localhost"
}
}
},
"Web.Server": {
"Destinations": {
"Web.Server": {
"Address": "https://web",
"Host": "localhost"
}
}
},
"Grpc.Server": {
"Destinations": {
"Grpc.Server": {
"Address": "https://grpc",
"Host": "localhost"
}
}
}
}
}
}
Loading

0 comments on commit 849acda

Please sign in to comment.