Skip to content

Commit

Permalink
Aspire 9 - minimal first version (#43)
Browse files Browse the repository at this point in the history
Allow people to use Aspire App host to play with the app and maybe contribute

* Aspire 9 first version
  • Loading branch information
fdonnet authored Nov 18, 2024
1 parent 80d63a4 commit 061de42
Show file tree
Hide file tree
Showing 24 changed files with 463 additions and 133 deletions.
73 changes: 41 additions & 32 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
LAST BIG PR implemented:
# News

- double-entry preparation
- 2 new backend apis (tx and sales-or-vat-tax)
- Blazor better token management
LAST PR implemented:

Next steps between:
- Aspire 9.0 (very minimal implementation without service discovery or test project)
- Now, you can run the apphost project and have fun

- vat-sales tax module implementation
Next steps or in progress:

- Vat-sales tax module implementation
- .Net 9 (Blazor adaptations)
- SingalR hub to trace tx status
- Blazor double-entry ui
- Aspire (re-test the thing)
- Aspire, enhance service defaults and see for discovery and maybe tests project
- will see...

# Ubik - Accounting
Expand All @@ -21,7 +22,7 @@ A .net8 project to manage double entry accounting. (it's the very beginning of a

Microservices arch and supports multi-tenants.

But for now, it's an experimental project that references a lot of things about .net 8 - Backend and Frontend sides of things -.
But for now, it's an experimental project that references a lot of things about .net 8 (9 soon) - Backend and Frontend sides of things -.

## Not ready for production

Expand All @@ -30,11 +31,23 @@ At this stage, **DO NOT USE THIS SYSTEM ON A PRODUCTION** environnement.
- **Don't forget to change all the "secrets" exposed here, and in the configuration files.**
- **Never re-use the Keycloak realm configuration file.**

## For the Kubernetes/Minikube guys
# Run - Debug

Choose between section 1), 2) or 3)

## 1) For the Aspire guys

You can run all the stuff with the host project:

`dotnet run --project .\src\Ubik.AppHost\Ubik.AppHost.csproj`

For detailed instructions on deploying locally with Minikube (full experience), please refer to the [local deployment guide](./deploy/deploy-local-readme.md).
Or, in Visual Studio, you can set the Aspire Host project as project startup and you will be able to play/debug with all the dependencies.

## Build and Run
## 2) For the Kubernetes/Minikube guys

For detailed instructions on deploying locally with Minikube, please refer to the [local deployment guide](./deploy/deploy-local-readme.md).

## 3) For the Docker guys

**At the root of the repository**, "Mount" the dependencies with Docker by running this command in your terminal:

Expand All @@ -49,9 +62,7 @@ For detailed instructions on deploying locally with Minikube (full experience),
> - Pgadmin: to admin your dbs if needed
> - Apis: backend apis (security/accounting) for integration testing
### Ready to play and debug

#### Run backend Apis or define a multiple projects startup
#### Run backend Apis or define a multiple projects startup to debug

`dotnet run --launch-profile https --project ./src/Ubik.Accounting.SalesOrVatTax.Api/Ubik.Accounting.SalesOrVatTax.Api.csproj`

Expand All @@ -69,9 +80,13 @@ For detailed instructions on deploying locally with Minikube (full experience),

`dotnet run --launch-profile https --project ./src/Ubik.Accounting.WebApp/Ubik.Accounting.WebApp.csproj`

And now (when all the stuff are up and running), you can access the very first version of a the Blazor 8 webapp here <https://localhost:7249>
## For All

After choosing your prefered way 1), 2) 3) you can access the Blazor app here:

### All the things are up
<https://localhost:7249>

# All the things are up

If you try to access the Blazor app, you will be redirected on a Keycloak login page

Expand All @@ -89,6 +104,12 @@ Try to log with different access rights and play with the only available "Accoun

Now you can run your preferred code editor and start to deep dive... (see below)

# Integration tests

If you want to contribute, see section "3) For the Docker guys" to be able to mount the dependencies and run the integration tests project. No time to update to Aspire Test and change all the related stuff (github actions etc.).

At the end, simply run `docker compose -f .\docker-compose.yml -f .\docker-integration-tests.yml up -d`, and you will be able to run the tests project.

## External libs

| Package | For what |
Expand All @@ -100,6 +121,8 @@ Now you can run your preferred code editor and start to deep dive... (see below)
| [LanguageExt.Core](https://github.com/louthy/language-ext) | use Either<Left, Right> pattern |
| [Masstransit](https://github.com/MassTransit/MassTransit) | message bus abstraction + inbox/outbox pattern |

Send some love on github to this projects...

## Yarp Proxy

-- Ubik.YarpProxy --
Expand Down Expand Up @@ -150,15 +173,11 @@ First you can maybe uncomment this lines in Ubik.Accounting.WebApp.csproj, if yo
</Target>
```

I don't know why, but my build fails in Github actions if I let this Tailwind instructions (related to the forms plugin). If someone has an idea...
`EXEC : error : Cannot find module '@tailwindcss/forms'`

**To use Tailwind in DEV**, you need to have node installed, Tailwind and Tailwind forms... I let you go on their site for installation instructions. Maybe, `npm install` command can be sufficient in the WebApp (server) project, cannot be sure because it seems to trigger a weird error in the dotnet build github actions.

| Package | For what |
|----------- | -------- |
| [BalzorPageScript](https://github.com/MackinnonBuck/blazor-page-script) | small tool that allows Tailwind to apply its Dark or Light theme on each page and component |
| [IdentityModel](https://github.com/IdentityModel) | Small extension to refresh token in OpenIdC |

Send some love on github to this projects...

Expand All @@ -167,29 +186,19 @@ Send some love on github to this projects...
(server side)

- Static components and pages
- Typed HttpClient to access the backend api
- Tailwind config - Tailwind Flowbite design layout etc
- A very minimal reverse proxy controller that allows components (automode) to call the backend api when they are WASM.
- Some stuff about security (Token cache service)

In program.cs, you can access the config of:

- Redis for token caching
- CascadingAuthenticationState
- Cookie auth with OpenIdC (connection + refresh token in OnValidatePrincipal)
- ...

=> next, implement new .Net 9 Blazor stuff related to authentication and render modes.

### Ubik.Accounting.WebApp.Client

(client-auto side)

- All components are able to run in auto mode (InteractiveServer or InteractiveWasm)
- **All components are able to run in auto mode (InteractiveServer or InteractiveWasm)**
- Authorization components (depending on authorized state)
- Minimal common components (Alerts, Buttons, Form Inputs, Grid *(Microsoft inspired/copied)*, Modal, Spinners)
- Tailwind Flowbite design for components
- The implementation of the facade that call the reverse proxy controller that call the Backend api for automode
- Error components that manage problemdetails returns from backend api (try to add a booking account with an existing code as an example)

### Ubik.Accounting.WebApp.Shared
Expand All @@ -203,7 +212,7 @@ In program.cs, you can access the config of:

-- Ubik.Accounting.Api.Tests.Integration --

- In integration tests => test all proxy endpoints
- In integration tests => test all proxy endpoints

## Others

Expand Down
30 changes: 17 additions & 13 deletions src/Ubik.Accounting.SalesOrVatTax.Api/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

var builder = WebApplication.CreateBuilder(args);

builder.AddServiceDefaults();

//Options
var authOptions = new AuthServerOptions();
builder.Configuration.GetSection(AuthServerOptions.Position).Bind(authOptions);
Expand All @@ -27,14 +29,15 @@
var swaggerUIOptions = new SwaggerUIOptions();
builder.Configuration.GetSection(SwaggerUIOptions.Position).Bind(swaggerUIOptions);

//Default httpclient
builder.Services.ConfigureHttpClientDefaults(http =>
{
http.AddStandardResilienceHandler();
});
//Default httpclient - Aspire now
//builder.Services.ConfigureHttpClientDefaults(http =>
//{
// http.AddStandardResilienceHandler();
//});

builder.Services.AddDbContextFactory<AccountingSalesTaxDbContext>(
options => options.UseNpgsql(builder.Configuration.GetConnectionString("AccountingSalesTaxDbContext")), ServiceLifetime.Scoped);
builder.EnrichNpgsqlDbContext<AccountingSalesTaxDbContext>();

Dapper.DefaultTypeMap.MatchNamesWithUnderscores = true;

Expand Down Expand Up @@ -79,14 +82,14 @@
//TODO: Cors
builder.Services.AddCustomCors();

//Tracing and metrics
builder.Logging.AddOpenTelemetry(logging =>
{
logging.IncludeFormattedMessage = true;
logging.IncludeScopes = true;
});
//Tracing and metrics
//builder.Logging.AddOpenTelemetry(logging =>
//{
// logging.IncludeFormattedMessage = true;
// logging.IncludeScopes = true;
//});

builder.Services.AddTracingAndMetrics();
//builder.Services.AddTracingAndMetrics();

//Swagger config
var xmlPath = Path.Combine(AppContext.BaseDirectory,
Expand All @@ -113,7 +116,6 @@
options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter()));

builder.Services.AddHttpContextAccessor();
builder.Services.AddEndpointsApiExplorer();

//Route config
builder.Services.Configure<RouteOptions>(options =>
Expand All @@ -128,6 +130,8 @@

var app = builder.Build();

app.MapDefaultEndpoints();

app.UseExceptionHandler(app.Logger, app.Environment);

// Configure the HTTP request pipeline.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@
<ItemGroup>
<PackageReference Include="Asp.Versioning.Mvc" Version="8.1.0" />
<PackageReference Include="Asp.Versioning.Mvc.ApiExplorer" Version="8.1.0" />
<PackageReference Include="Aspire.Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.2.2" />
<PackageReference Include="Dapper" Version="2.1.35" />
<PackageReference Include="EFCore.NamingConventions" Version="8.0.3" />
<PackageReference Include="LanguageExt.Core" Version="4.4.9" />
<PackageReference Include="Microsoft.Extensions.Http.Resilience" Version="8.10.0" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.21.0" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.10" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="7.0.0" />
Expand All @@ -33,6 +33,7 @@
<ProjectReference Include="..\Ubik.Accounting.Transaction.Contracts\Ubik.Accounting.Transaction.Contracts.csproj" />
<ProjectReference Include="..\Ubik.ApiService.Common\Ubik.ApiService.Common.csproj" />
<ProjectReference Include="..\Ubik.Db.Common\Ubik.DB.Common\Ubik.DB.Common.csproj" />
<ProjectReference Include="..\Ubik.ServiceDefaults\Ubik.ServiceDefaults.csproj" />
</ItemGroup>

<ItemGroup>
Expand Down
30 changes: 17 additions & 13 deletions src/Ubik.Accounting.Structure.Api/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public class Program
public static async Task Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
builder.AddServiceDefaults();

//Log
//TODO: Begin to log usefull things
Expand All @@ -42,11 +43,11 @@ public static async Task Main(string[] args)
//Auth server and JWT (no need, no auth)
//builder.Services.AddAuthServerAndJwt(authOptions);

//Default httpclient
builder.Services.ConfigureHttpClientDefaults(http =>
{
http.AddStandardResilienceHandler();
});
////Default httpclient - Aspire now
//builder.Services.ConfigureHttpClientDefaults(http =>
//{
// http.AddStandardResilienceHandler();
//});

//DB
builder.Services.AddDbContextFactory<AccountingDbContext>(
Expand Down Expand Up @@ -102,14 +103,14 @@ public static async Task Main(string[] args)
//TODO: Cors
builder.Services.AddCustomCors();

//Tracing and metrics
builder.Logging.AddOpenTelemetry(logging =>
{
logging.IncludeFormattedMessage = true;
logging.IncludeScopes = true;
});
////Tracing and metrics - Aspire now
//builder.Logging.AddOpenTelemetry(logging =>
//{
// logging.IncludeFormattedMessage = true;
// logging.IncludeScopes = true;
//});

builder.Services.AddTracingAndMetrics();
//builder.Services.AddTracingAndMetrics();

//Swagger config
var xmlPath = Path.Combine(AppContext.BaseDirectory,
Expand Down Expand Up @@ -149,7 +150,10 @@ public static async Task Main(string[] args)
//Build the app
var app = builder.Build();

app.MapPrometheusScrapingEndpoint();
//Build the app
app.MapDefaultEndpoints();

//app.MapPrometheusScrapingEndpoint();
//app.UseSerilogRequestLogging();
app.UseExceptionHandler(app.Logger, app.Environment);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Http.Resilience" Version="8.10.0" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.21.0" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.10" />
<PackageReference Include="Serilog.AspNetCore" Version="8.0.3" />
Expand All @@ -46,6 +45,7 @@
<ItemGroup>
<ProjectReference Include="..\Ubik.Accounting.Structure.Contracts\Ubik.Accounting.Structure.Contracts.csproj" />
<ProjectReference Include="..\Ubik.Db.Common\Ubik.DB.Common\Ubik.DB.Common.csproj" />
<ProjectReference Include="..\Ubik.ServiceDefaults\Ubik.ServiceDefaults.csproj" />
</ItemGroup>

<ItemGroup>
Expand Down
Loading

0 comments on commit 061de42

Please sign in to comment.