Initial commit
This commit is contained in:
+399
@@ -0,0 +1,399 @@
|
|||||||
|
## Ignore Visual Studio temporary files, build results, and
|
||||||
|
## files generated by popular Visual Studio add-ons.
|
||||||
|
##
|
||||||
|
## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore
|
||||||
|
|
||||||
|
# User-specific files
|
||||||
|
*.rsuser
|
||||||
|
*.suo
|
||||||
|
*.user
|
||||||
|
*.userosscache
|
||||||
|
*.sln.docstates
|
||||||
|
data/
|
||||||
|
|
||||||
|
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||||
|
*.userprefs
|
||||||
|
|
||||||
|
# Mono auto generated files
|
||||||
|
mono_crash.*
|
||||||
|
|
||||||
|
# Build results
|
||||||
|
[Dd]ebug/
|
||||||
|
[Dd]ebugPublic/
|
||||||
|
[Rr]elease/
|
||||||
|
[Rr]eleases/
|
||||||
|
x64/
|
||||||
|
x86/
|
||||||
|
[Ww][Ii][Nn]32/
|
||||||
|
[Aa][Rr][Mm]/
|
||||||
|
[Aa][Rr][Mm]64/
|
||||||
|
bld/
|
||||||
|
[Bb]in/
|
||||||
|
[Oo]bj/
|
||||||
|
[Ll]og/
|
||||||
|
[Ll]ogs/
|
||||||
|
|
||||||
|
# Visual Studio 2015/2017 cache/options directory
|
||||||
|
.vs/
|
||||||
|
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||||
|
#wwwroot/
|
||||||
|
|
||||||
|
# Visual Studio 2017 auto generated files
|
||||||
|
Generated\ Files/
|
||||||
|
|
||||||
|
# MSTest test Results
|
||||||
|
[Tt]est[Rr]esult*/
|
||||||
|
[Bb]uild[Ll]og.*
|
||||||
|
|
||||||
|
# NUnit
|
||||||
|
*.VisualState.xml
|
||||||
|
TestResult.xml
|
||||||
|
nunit-*.xml
|
||||||
|
|
||||||
|
# Build Results of an ATL Project
|
||||||
|
[Dd]ebugPS/
|
||||||
|
[Rr]eleasePS/
|
||||||
|
dlldata.c
|
||||||
|
|
||||||
|
# Benchmark Results
|
||||||
|
BenchmarkDotNet.Artifacts/
|
||||||
|
|
||||||
|
# .NET Core
|
||||||
|
project.lock.json
|
||||||
|
project.fragment.lock.json
|
||||||
|
artifacts/
|
||||||
|
|
||||||
|
# ASP.NET Scaffolding
|
||||||
|
ScaffoldingReadMe.txt
|
||||||
|
|
||||||
|
# StyleCop
|
||||||
|
StyleCopReport.xml
|
||||||
|
|
||||||
|
# Files built by Visual Studio
|
||||||
|
*_i.c
|
||||||
|
*_p.c
|
||||||
|
*_h.h
|
||||||
|
*.ilk
|
||||||
|
*.meta
|
||||||
|
*.obj
|
||||||
|
*.iobj
|
||||||
|
*.pch
|
||||||
|
*.pdb
|
||||||
|
*.ipdb
|
||||||
|
*.pgc
|
||||||
|
*.pgd
|
||||||
|
*.rsp
|
||||||
|
*.sbr
|
||||||
|
*.tlb
|
||||||
|
*.tli
|
||||||
|
*.tlh
|
||||||
|
*.tmp
|
||||||
|
*.tmp_proj
|
||||||
|
*_wpftmp.csproj
|
||||||
|
*.log
|
||||||
|
*.tlog
|
||||||
|
*.vspscc
|
||||||
|
*.vssscc
|
||||||
|
.builds
|
||||||
|
*.pidb
|
||||||
|
*.svclog
|
||||||
|
*.scc
|
||||||
|
|
||||||
|
# Chutzpah Test files
|
||||||
|
_Chutzpah*
|
||||||
|
|
||||||
|
# Visual C++ cache files
|
||||||
|
ipch/
|
||||||
|
*.aps
|
||||||
|
*.ncb
|
||||||
|
*.opendb
|
||||||
|
*.opensdf
|
||||||
|
*.sdf
|
||||||
|
*.cachefile
|
||||||
|
*.VC.db
|
||||||
|
*.VC.VC.opendb
|
||||||
|
|
||||||
|
# Visual Studio profiler
|
||||||
|
*.psess
|
||||||
|
*.vsp
|
||||||
|
*.vspx
|
||||||
|
*.sap
|
||||||
|
|
||||||
|
# Visual Studio Trace Files
|
||||||
|
*.e2e
|
||||||
|
|
||||||
|
# TFS 2012 Local Workspace
|
||||||
|
$tf/
|
||||||
|
|
||||||
|
# Guidance Automation Toolkit
|
||||||
|
*.gpState
|
||||||
|
|
||||||
|
# ReSharper is a .NET coding add-in
|
||||||
|
_ReSharper*/
|
||||||
|
*.[Rr]e[Ss]harper
|
||||||
|
*.DotSettings.user
|
||||||
|
|
||||||
|
# TeamCity is a build add-in
|
||||||
|
_TeamCity*
|
||||||
|
|
||||||
|
# DotCover is a Code Coverage Tool
|
||||||
|
*.dotCover
|
||||||
|
|
||||||
|
# AxoCover is a Code Coverage Tool
|
||||||
|
.axoCover/*
|
||||||
|
!.axoCover/settings.json
|
||||||
|
|
||||||
|
# Coverlet is a free, cross platform Code Coverage Tool
|
||||||
|
coverage*.json
|
||||||
|
coverage*.xml
|
||||||
|
coverage*.info
|
||||||
|
|
||||||
|
# Visual Studio code coverage results
|
||||||
|
*.coverage
|
||||||
|
*.coveragexml
|
||||||
|
|
||||||
|
# NCrunch
|
||||||
|
_NCrunch_*
|
||||||
|
.*crunch*.local.xml
|
||||||
|
nCrunchTemp_*
|
||||||
|
|
||||||
|
# MightyMoose
|
||||||
|
*.mm.*
|
||||||
|
AutoTest.Net/
|
||||||
|
|
||||||
|
# Web workbench (sass)
|
||||||
|
.sass-cache/
|
||||||
|
|
||||||
|
# Installshield output folder
|
||||||
|
[Ee]xpress/
|
||||||
|
|
||||||
|
# DocProject is a documentation generator add-in
|
||||||
|
DocProject/buildhelp/
|
||||||
|
DocProject/Help/*.HxT
|
||||||
|
DocProject/Help/*.HxC
|
||||||
|
DocProject/Help/*.hhc
|
||||||
|
DocProject/Help/*.hhk
|
||||||
|
DocProject/Help/*.hhp
|
||||||
|
DocProject/Help/Html2
|
||||||
|
DocProject/Help/html
|
||||||
|
|
||||||
|
# Click-Once directory
|
||||||
|
publish/
|
||||||
|
|
||||||
|
# Publish Web Output
|
||||||
|
*.[Pp]ublish.xml
|
||||||
|
*.azurePubxml
|
||||||
|
# Note: Comment the next line if you want to checkin your web deploy settings,
|
||||||
|
# but database connection strings (with potential passwords) will be unencrypted
|
||||||
|
*.pubxml
|
||||||
|
*.publishproj
|
||||||
|
|
||||||
|
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
||||||
|
# checkin your Azure Web App publish settings, but sensitive information contained
|
||||||
|
# in these scripts will be unencrypted
|
||||||
|
PublishScripts/
|
||||||
|
|
||||||
|
# NuGet Packages
|
||||||
|
*.nupkg
|
||||||
|
# NuGet Symbol Packages
|
||||||
|
*.snupkg
|
||||||
|
# The packages folder can be ignored because of Package Restore
|
||||||
|
**/[Pp]ackages/*
|
||||||
|
# except build/, which is used as an MSBuild target.
|
||||||
|
!**/[Pp]ackages/build/
|
||||||
|
# Uncomment if necessary however generally it will be regenerated when needed
|
||||||
|
#!**/[Pp]ackages/repositories.config
|
||||||
|
# NuGet v3's project.json files produces more ignorable files
|
||||||
|
*.nuget.props
|
||||||
|
*.nuget.targets
|
||||||
|
|
||||||
|
# Microsoft Azure Build Output
|
||||||
|
csx/
|
||||||
|
*.build.csdef
|
||||||
|
|
||||||
|
# Microsoft Azure Emulator
|
||||||
|
ecf/
|
||||||
|
rcf/
|
||||||
|
|
||||||
|
# Windows Store app package directories and files
|
||||||
|
AppPackages/
|
||||||
|
BundleArtifacts/
|
||||||
|
Package.StoreAssociation.xml
|
||||||
|
_pkginfo.txt
|
||||||
|
*.appx
|
||||||
|
*.appxbundle
|
||||||
|
*.appxupload
|
||||||
|
|
||||||
|
# Visual Studio cache files
|
||||||
|
# files ending in .cache can be ignored
|
||||||
|
*.[Cc]ache
|
||||||
|
# but keep track of directories ending in .cache
|
||||||
|
!?*.[Cc]ache/
|
||||||
|
|
||||||
|
# Others
|
||||||
|
ClientBin/
|
||||||
|
~$*
|
||||||
|
*~
|
||||||
|
*.dbmdl
|
||||||
|
*.dbproj.schemaview
|
||||||
|
*.jfm
|
||||||
|
*.pfx
|
||||||
|
*.publishsettings
|
||||||
|
orleans.codegen.cs
|
||||||
|
|
||||||
|
# Including strong name files can present a security risk
|
||||||
|
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
|
||||||
|
#*.snk
|
||||||
|
|
||||||
|
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||||
|
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||||
|
#bower_components/
|
||||||
|
|
||||||
|
# RIA/Silverlight projects
|
||||||
|
Generated_Code/
|
||||||
|
|
||||||
|
# Backup & report files from converting an old project file
|
||||||
|
# to a newer Visual Studio version. Backup files are not needed,
|
||||||
|
# because we have git ;-)
|
||||||
|
_UpgradeReport_Files/
|
||||||
|
Backup*/
|
||||||
|
UpgradeLog*.XML
|
||||||
|
UpgradeLog*.htm
|
||||||
|
ServiceFabricBackup/
|
||||||
|
*.rptproj.bak
|
||||||
|
|
||||||
|
# SQL Server files
|
||||||
|
*.mdf
|
||||||
|
*.ldf
|
||||||
|
*.ndf
|
||||||
|
|
||||||
|
# Business Intelligence projects
|
||||||
|
*.rdl.data
|
||||||
|
*.bim.layout
|
||||||
|
*.bim_*.settings
|
||||||
|
*.rptproj.rsuser
|
||||||
|
*- [Bb]ackup.rdl
|
||||||
|
*- [Bb]ackup ([0-9]).rdl
|
||||||
|
*- [Bb]ackup ([0-9][0-9]).rdl
|
||||||
|
|
||||||
|
# Microsoft Fakes
|
||||||
|
FakesAssemblies/
|
||||||
|
|
||||||
|
# GhostDoc plugin setting file
|
||||||
|
*.GhostDoc.xml
|
||||||
|
|
||||||
|
# Node.js Tools for Visual Studio
|
||||||
|
.ntvs_analysis.dat
|
||||||
|
node_modules/
|
||||||
|
|
||||||
|
# Visual Studio 6 build log
|
||||||
|
*.plg
|
||||||
|
|
||||||
|
# Visual Studio 6 workspace options file
|
||||||
|
*.opt
|
||||||
|
|
||||||
|
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
|
||||||
|
*.vbw
|
||||||
|
|
||||||
|
# Visual Studio 6 auto-generated project file (contains which files were open etc.)
|
||||||
|
*.vbp
|
||||||
|
|
||||||
|
# Visual Studio 6 workspace and project file (working project files containing files to include in project)
|
||||||
|
*.dsw
|
||||||
|
*.dsp
|
||||||
|
|
||||||
|
# Visual Studio 6 technical files
|
||||||
|
*.ncb
|
||||||
|
*.aps
|
||||||
|
|
||||||
|
# Visual Studio LightSwitch build output
|
||||||
|
**/*.HTMLClient/GeneratedArtifacts
|
||||||
|
**/*.DesktopClient/GeneratedArtifacts
|
||||||
|
**/*.DesktopClient/ModelManifest.xml
|
||||||
|
**/*.Server/GeneratedArtifacts
|
||||||
|
**/*.Server/ModelManifest.xml
|
||||||
|
_Pvt_Extensions
|
||||||
|
|
||||||
|
# Paket dependency manager
|
||||||
|
.paket/paket.exe
|
||||||
|
paket-files/
|
||||||
|
|
||||||
|
# FAKE - F# Make
|
||||||
|
.fake/
|
||||||
|
|
||||||
|
# CodeRush personal settings
|
||||||
|
.cr/personal
|
||||||
|
|
||||||
|
# Python Tools for Visual Studio (PTVS)
|
||||||
|
__pycache__/
|
||||||
|
*.pyc
|
||||||
|
|
||||||
|
# Cake - Uncomment if you are using it
|
||||||
|
# tools/**
|
||||||
|
# !tools/packages.config
|
||||||
|
|
||||||
|
# Tabs Studio
|
||||||
|
*.tss
|
||||||
|
|
||||||
|
# Telerik's JustMock configuration file
|
||||||
|
*.jmconfig
|
||||||
|
|
||||||
|
# BizTalk build output
|
||||||
|
*.btp.cs
|
||||||
|
*.btm.cs
|
||||||
|
*.odx.cs
|
||||||
|
*.xsd.cs
|
||||||
|
|
||||||
|
# OpenCover UI analysis results
|
||||||
|
OpenCover/
|
||||||
|
|
||||||
|
# Azure Stream Analytics local run output
|
||||||
|
ASALocalRun/
|
||||||
|
|
||||||
|
# MSBuild Binary and Structured Log
|
||||||
|
*.binlog
|
||||||
|
|
||||||
|
# NVidia Nsight GPU debugger configuration file
|
||||||
|
*.nvuser
|
||||||
|
|
||||||
|
# MFractors (Xamarin productivity tool) working folder
|
||||||
|
.mfractor/
|
||||||
|
|
||||||
|
# Local History for Visual Studio
|
||||||
|
.localhistory/
|
||||||
|
|
||||||
|
# Visual Studio History (VSHistory) files
|
||||||
|
.vshistory/
|
||||||
|
|
||||||
|
# BeatPulse healthcheck temp database
|
||||||
|
healthchecksdb
|
||||||
|
|
||||||
|
# Backup folder for Package Reference Convert tool in Visual Studio 2017
|
||||||
|
MigrationBackup/
|
||||||
|
|
||||||
|
# Ionide (cross platform F# VS Code tools) working folder
|
||||||
|
.ionide/
|
||||||
|
|
||||||
|
# Fody - auto-generated XML schema
|
||||||
|
FodyWeavers.xsd
|
||||||
|
|
||||||
|
# VS Code files for those working on multiple tools
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/settings.json
|
||||||
|
!.vscode/tasks.json
|
||||||
|
!.vscode/launch.json
|
||||||
|
!.vscode/extensions.json
|
||||||
|
*.code-workspace
|
||||||
|
|
||||||
|
# Local History for Visual Studio Code
|
||||||
|
.history/
|
||||||
|
|
||||||
|
# Windows Installer files from build outputs
|
||||||
|
*.cab
|
||||||
|
*.msi
|
||||||
|
*.msix
|
||||||
|
*.msm
|
||||||
|
*.msp
|
||||||
|
|
||||||
|
# JetBrains Rider
|
||||||
|
*.sln.iml
|
||||||
+27
@@ -0,0 +1,27 @@
|
|||||||
|
using TriunniaLabs.Arch.Sample.Aspire.AppHost;
|
||||||
|
|
||||||
|
var builder = DistributedApplication.CreateBuilder(args);
|
||||||
|
|
||||||
|
// Sql Server: One server hosting all databases for an all-in-one setup
|
||||||
|
var sqlServer = builder.AddSampleSqlServer(); // http://host.docker.internal:51000
|
||||||
|
|
||||||
|
// Control Panel: Start here. Run the solution, which will start Aspire. Go to http://localhost:50000 in your browser to access the Control Panel.
|
||||||
|
// In the Control Panel, create your application and set up the Application Api.
|
||||||
|
// Copy its encrypted settings to both ApplicationApiSetup.cs and appsettings.json in the Sample Server, then uncomment it here.
|
||||||
|
// Run the health check on the Application Api from the Control Panel. Repeat for all other Apis, including your app.
|
||||||
|
builder.AddControlPanel(sqlServer); // http://host.docker.internal:50000
|
||||||
|
|
||||||
|
// Arch Apis: Pick which ones you need for your application. Uncomment only once they have been set up in the Control Panel. Application Api is required.
|
||||||
|
// builder.AddApplicationApi(sqlServer); // http://host.docker.internal:50001
|
||||||
|
// builder.AddKeysApi(sqlServer); // http://host.docker.internal:50002
|
||||||
|
// builder.AddTokensApi(sqlServer); // http://host.docker.internal:50003
|
||||||
|
// builder.AddEmailApi(sqlServer); // http://host.docker.internal:50004
|
||||||
|
// builder.AddUsersApi(sqlServer); // http://host.docker.internal:50005
|
||||||
|
// builder.AddCommentsApi(sqlServer); // http://host.docker.internal:50006
|
||||||
|
// builder.AddEntityApi(sqlServer); // http://host.docker.internal:50007
|
||||||
|
// builder.AddFilesApi(); // http://host.docker.internal:50008
|
||||||
|
|
||||||
|
// Your Application: Uncomment once you have set up your application in the Control Panel. It will run on port 50009.
|
||||||
|
// builder.AddProject("SampleServer", "..\\..\\TriunniaLabs.Arch.Sample.Server\\TriunniaLabs.Arch.Sample.Server.csproj");
|
||||||
|
|
||||||
|
builder.Build().Run();
|
||||||
+30
@@ -0,0 +1,30 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://json.schemastore.org/launchsettings.json",
|
||||||
|
"profiles": {
|
||||||
|
"https": {
|
||||||
|
"commandName": "Project",
|
||||||
|
"dotnetRunMessages": true,
|
||||||
|
"launchBrowser": true,
|
||||||
|
"applicationUrl": "https://localhost:17209;http://localhost:15193",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development",
|
||||||
|
"DOTNET_ENVIRONMENT": "Development",
|
||||||
|
"ASPIRE_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:21057",
|
||||||
|
"ASPIRE_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:22051"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"http": {
|
||||||
|
"commandName": "Project",
|
||||||
|
"dotnetRunMessages": true,
|
||||||
|
"launchBrowser": true,
|
||||||
|
"applicationUrl": "http://localhost:15240",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development",
|
||||||
|
"DOTNET_ENVIRONMENT": "Development",
|
||||||
|
"ASPIRE_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:19042",
|
||||||
|
"ASPIRE_DASHBOARD_MCP_ENDPOINT_URL": "http://localhost:18273",
|
||||||
|
"ASPIRE_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:20197"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+41
@@ -0,0 +1,41 @@
|
|||||||
|
namespace TriunniaLabs.Arch.Sample.Aspire.AppHost
|
||||||
|
{
|
||||||
|
internal static class ApplicationApiSetup
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a resource for the Application Api on port 50001.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="builder">Reference to the application builder.</param>
|
||||||
|
/// <param name="sqlServer">Reference to the Sql Server resource.</param>
|
||||||
|
public static void AddApplicationApi(this IDistributedApplicationBuilder builder, IResourceBuilder<SqlServerServerResource> sqlServer)
|
||||||
|
{
|
||||||
|
var applicationApiDb = sqlServer.AddDatabase("ApplicationApiDb");
|
||||||
|
var applicationApi = builder.AddContainer("ApplicationApi", "gitea.triunnialabs.com/triunnialabs/arch-application-api", "0.9.8")
|
||||||
|
.WithEndpoint(50001, 8080, isProxied: false, name: "http")
|
||||||
|
.WithEndpoint("http", e => e.TargetHost = "0.0.0.0")
|
||||||
|
|
||||||
|
// Obtain the values for these fields from the Control Panel
|
||||||
|
.WithEnvironment("Microservice__Name", "")
|
||||||
|
.WithEnvironment("Microservice__EnvelopePassword", "")
|
||||||
|
.WithEnvironment("Microservice__EnableDiagnostics", "true") // Set to false in production deployments
|
||||||
|
.WithEnvironment("Microservice__Application__Url", "")
|
||||||
|
.WithEnvironment("Microservice__Application__ApplicationId", "")
|
||||||
|
.WithEnvironment("Microservice__Application__ApiKey", "")
|
||||||
|
.WithEnvironment("Microservice__Application__EnvelopePassword", "")
|
||||||
|
.WithEnvironment("Microservice__ProtectedMemory__HmacSha512HashKey", "")
|
||||||
|
.WithEnvironment("Microservice__ProtectedMemory__AesEncryptionPassword", "")
|
||||||
|
.WithEnvironment("Microservice__ProtectedMemory__AesEncryptionSalt", "")
|
||||||
|
.WithEnvironment("SqlServer__ConnectionString", "")
|
||||||
|
.WithEnvironment("SqlServer__ReadOnlyConnectionString", "")
|
||||||
|
.WithEnvironment("YubiHsm__ConnectorUrl", "")
|
||||||
|
.WithEnvironment("Guardian__AccessToken", "")
|
||||||
|
.WithEnvironment("Guardian__BootstrapKeyObjectId", "")
|
||||||
|
|
||||||
|
// Api will write log and other files to this relatiove source folder
|
||||||
|
.WithBindMount("..\\..\\..\\data\\ApplicationApi", "/opt/triunnialabs/arch/application-api")
|
||||||
|
|
||||||
|
.WithReference(applicationApiDb)
|
||||||
|
.WaitFor(applicationApiDb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+39
@@ -0,0 +1,39 @@
|
|||||||
|
namespace TriunniaLabs.Arch.Sample.Aspire.AppHost
|
||||||
|
{
|
||||||
|
internal static class ComomentsApiSetup
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a resource for the Comments Api on port 50006.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="builder">Reference to the application builder.</param>
|
||||||
|
/// <param name="sqlServer">Reference to the Sql Server resource.</param>
|
||||||
|
public static void AddCommentsApi(this IDistributedApplicationBuilder builder, IResourceBuilder<SqlServerServerResource> sqlServer)
|
||||||
|
{
|
||||||
|
var commentsApiDb = sqlServer.AddDatabase("CommentsApiDb");
|
||||||
|
builder.AddContainer("CommentsApi", "gitea.triunnialabs.com/triunnialabs/arch-comments-api", "0.1.0")
|
||||||
|
.WithEndpoint(50006, 8080, isProxied: false, name: "http")
|
||||||
|
.WithEndpoint("http", e => e.TargetHost = "0.0.0.0")
|
||||||
|
|
||||||
|
// Obtain the values for these fields from the Control Panel
|
||||||
|
.WithEnvironment("Microservice__Name", "")
|
||||||
|
.WithEnvironment("Microservice__EnvelopePassword", "")
|
||||||
|
.WithEnvironment("Microservice__EnableDiagnostics", "true") // Set to false in production deployments
|
||||||
|
.WithEnvironment("Microservice__Application__Url", "")
|
||||||
|
.WithEnvironment("Microservice__Application__ApplicationId", "")
|
||||||
|
.WithEnvironment("Microservice__Application__ApiKey", "")
|
||||||
|
.WithEnvironment("Microservice__Application__EnvelopePassword", "")
|
||||||
|
.WithEnvironment("Microservice__ProtectedMemory__HmacSha512HashKey", "")
|
||||||
|
.WithEnvironment("Microservice__ProtectedMemory__AesEncryptionPassword", "")
|
||||||
|
.WithEnvironment("Microservice__ProtectedMemory__AesEncryptionSalt", "")
|
||||||
|
.WithEnvironment("Microservice__ProtectedMemory__AesEncryptionIterations", "")
|
||||||
|
.WithEnvironment("SqlServer__ConnectionString", "")
|
||||||
|
.WithEnvironment("SqlServer__ReadOnlyConnectionString", "")
|
||||||
|
|
||||||
|
// Api will write log and other files to this relatiove source folder
|
||||||
|
.WithBindMount("..\\..\\..\\data\\CommentsApi", "/opt/triunnialabs/arch/comments-api")
|
||||||
|
|
||||||
|
.WithReference(commentsApiDb)
|
||||||
|
.WaitFor(commentsApiDb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+46
@@ -0,0 +1,46 @@
|
|||||||
|
namespace TriunniaLabs.Arch.Sample.Aspire.AppHost
|
||||||
|
{
|
||||||
|
internal static class EmailApiSetup
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a resource for the Email Api on port 50004.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="builder">Reference to the application builder.</param>
|
||||||
|
/// <param name="sqlServer">Reference to the Sql Server resource.</param>
|
||||||
|
public static void AddEmailApi(this IDistributedApplicationBuilder builder, IResourceBuilder<SqlServerServerResource> sqlServer)
|
||||||
|
{
|
||||||
|
var emailApiDb = sqlServer.AddDatabase("EmailApiDb");
|
||||||
|
builder.AddContainer("EmailApi", "gitea.triunnialabs.com/triunnialabs/arch-email-api", "0.2.2")
|
||||||
|
.WithEndpoint(50004, 8080, isProxied: false, name: "http")
|
||||||
|
.WithEndpoint("http", e => e.TargetHost = "0.0.0.0")
|
||||||
|
|
||||||
|
// Obtain the values for these fields from the Control Panel
|
||||||
|
.WithEnvironment("Microservice__Name", "")
|
||||||
|
.WithEnvironment("Microservice__EnvelopePassword", "")
|
||||||
|
.WithEnvironment("Microservice__EnableDiagnostics", "true") // Set to false in production deployments
|
||||||
|
.WithEnvironment("Microservice__Application__Url", "")
|
||||||
|
.WithEnvironment("Microservice__Application__ApplicationId", "")
|
||||||
|
.WithEnvironment("Microservice__Application__ApiKey", "")
|
||||||
|
.WithEnvironment("Microservice__Application__EnvelopePassword", "")
|
||||||
|
.WithEnvironment("Microservice__ProtectedMemory__HmacSha512HashKey", "")
|
||||||
|
.WithEnvironment("Microservice__ProtectedMemory__AesEncryptionPassword", "")
|
||||||
|
.WithEnvironment("Microservice__ProtectedMemory__AesEncryptionSalt", "")
|
||||||
|
.WithEnvironment("Microservice__ProtectedMemory__AesEncryptionIterations", "")
|
||||||
|
.WithEnvironment("SqlServer__ConnectionString", "")
|
||||||
|
.WithEnvironment("SqlServer__ReadOnlyConnectionString", "")
|
||||||
|
.WithEnvironment("Postmark__ServerToken", "") // Postmark is required for sending emails
|
||||||
|
.WithEnvironment("Postmark__WebhookAuthUser", "") // Other providers to be added as demand requires (SendGrid, etc.)
|
||||||
|
.WithEnvironment("Postmark__WebhookAuthPassword", "")
|
||||||
|
.WithEnvironment("TokensApi__Url", "") // Email Api requires Tokens Api
|
||||||
|
.WithEnvironment("TokensApi__ApplicationId", "")
|
||||||
|
.WithEnvironment("TokensApi__ApiKey", "")
|
||||||
|
.WithEnvironment("TokensApi__EnvelopePassword", "")
|
||||||
|
|
||||||
|
// Api will write log and other files to this relatiove source folder
|
||||||
|
.WithBindMount("..\\..\\..\\data\\EmailApi", "/opt/triunnialabs/arch/email-api")
|
||||||
|
|
||||||
|
.WithReference(emailApiDb)
|
||||||
|
.WaitFor(emailApiDb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+39
@@ -0,0 +1,39 @@
|
|||||||
|
namespace TriunniaLabs.Arch.Sample.Aspire.AppHost
|
||||||
|
{
|
||||||
|
internal static class EntityApiSetup
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a resource for the Entity Api on port 50007.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="builder">Reference to the application builder.</param>
|
||||||
|
/// <param name="sqlServer">Reference to the Sql Server resource.</param>
|
||||||
|
public static void AddEntityApi(this IDistributedApplicationBuilder builder, IResourceBuilder<SqlServerServerResource> sqlServer)
|
||||||
|
{
|
||||||
|
var entityApiDb = sqlServer.AddDatabase("EntityApiDb");
|
||||||
|
builder.AddContainer("EntityApi", "gitea.triunnialabs.com/triunnialabs/arch-entity-api", "0.1.4")
|
||||||
|
.WithEndpoint(50007, 8080, isProxied: false, name: "http")
|
||||||
|
.WithEndpoint("http", e => e.TargetHost = "0.0.0.0")
|
||||||
|
|
||||||
|
// Obtain the values for these fields from the Control Panel
|
||||||
|
.WithEnvironment("Microservice__Name", "")
|
||||||
|
.WithEnvironment("Microservice__EnvelopePassword", "")
|
||||||
|
.WithEnvironment("Microservice__EnableDiagnostics", "true") // Set to false in production deployments
|
||||||
|
.WithEnvironment("Microservice__Application__Url", "")
|
||||||
|
.WithEnvironment("Microservice__Application__ApplicationId", "")
|
||||||
|
.WithEnvironment("Microservice__Application__ApiKey", "")
|
||||||
|
.WithEnvironment("Microservice__Application__EnvelopePassword", "")
|
||||||
|
.WithEnvironment("Microservice__ProtectedMemory__HmacSha512HashKey", "")
|
||||||
|
.WithEnvironment("Microservice__ProtectedMemory__AesEncryptionPassword", "")
|
||||||
|
.WithEnvironment("Microservice__ProtectedMemory__AesEncryptionSalt", "")
|
||||||
|
.WithEnvironment("Microservice__ProtectedMemory__AesEncryptionIterations", "")
|
||||||
|
.WithEnvironment("SqlServer__ConnectionString", "")
|
||||||
|
.WithEnvironment("SqlServer__ReadOnlyConnectionString", "")
|
||||||
|
|
||||||
|
// Api will write log and other files to this relatiove source folder
|
||||||
|
.WithBindMount("..\\..\\..\\data\\EntityApi", "/opt/triunnialabs/arch/entity-api")
|
||||||
|
|
||||||
|
.WithReference(entityApiDb)
|
||||||
|
.WaitFor(entityApiDb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+33
@@ -0,0 +1,33 @@
|
|||||||
|
namespace TriunniaLabs.Arch.Sample.Aspire.AppHost
|
||||||
|
{
|
||||||
|
internal static class FilesApiSetup
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a resource for the Files Api on port 50008.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="builder">Reference to the application builder.</param>
|
||||||
|
public static void AddFilesApi(this IDistributedApplicationBuilder builder)
|
||||||
|
{
|
||||||
|
builder.AddContainer("FilesApi", "gitea.triunnialabs.com/triunnialabs/arch-files-api", "0.1.3")
|
||||||
|
.WithEndpoint(50008, 8080, isProxied: false, name: "http")
|
||||||
|
.WithEndpoint("http", e => e.TargetHost = "0.0.0.0")
|
||||||
|
|
||||||
|
// Obtain the values for these fields from the Control Panel
|
||||||
|
.WithEnvironment("Microservice__Name", "")
|
||||||
|
.WithEnvironment("Microservice__EnvelopePassword", "")
|
||||||
|
.WithEnvironment("Microservice__EnableDiagnostics", "true") // Set to false in production deployments
|
||||||
|
.WithEnvironment("Microservice__Application__Url", "")
|
||||||
|
.WithEnvironment("Microservice__Application__ApplicationId", "")
|
||||||
|
.WithEnvironment("Microservice__Application__ApiKey", "")
|
||||||
|
.WithEnvironment("Microservice__Application__EnvelopePassword", "")
|
||||||
|
.WithEnvironment("Microservice__ProtectedMemory__HmacSha512HashKey", "")
|
||||||
|
.WithEnvironment("Microservice__ProtectedMemory__AesEncryptionPassword", "")
|
||||||
|
.WithEnvironment("Microservice__ProtectedMemory__AesEncryptionSalt", "")
|
||||||
|
.WithEnvironment("Microservice__ProtectedMemory__AesEncryptionIterations", "")
|
||||||
|
.WithEnvironment("FilesApi__DataPath", "")
|
||||||
|
|
||||||
|
// Api will write log and other files to this relatiove source folder
|
||||||
|
.WithBindMount("..\\..\\..\\data\\FilesApi", "/opt/triunnialabs/arch/files-api");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+39
@@ -0,0 +1,39 @@
|
|||||||
|
namespace TriunniaLabs.Arch.Sample.Aspire.AppHost
|
||||||
|
{
|
||||||
|
internal static class KeysApiSetup
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a resource for the Keys Api on port 50002.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="builder">Reference to the application builder.</param>
|
||||||
|
/// <param name="sqlServer">Reference to the Sql Server resource.</param>
|
||||||
|
public static void AddKeysApi(this IDistributedApplicationBuilder builder, IResourceBuilder<SqlServerServerResource> sqlServer)
|
||||||
|
{
|
||||||
|
var keysApiDb = sqlServer.AddDatabase("KeysApiDb");
|
||||||
|
builder.AddContainer("KeysApi", "gitea.triunnialabs.com/triunnialabs/arch-keys-api", "0.1.17")
|
||||||
|
.WithEndpoint(50002, 8080, isProxied: false, name: "http")
|
||||||
|
.WithEndpoint("http", e => e.TargetHost = "0.0.0.0")
|
||||||
|
|
||||||
|
// Obtain the values for these fields from the Control Panel
|
||||||
|
.WithEnvironment("Microservice__Name", "")
|
||||||
|
.WithEnvironment("Microservice__EnvelopePassword", "")
|
||||||
|
.WithEnvironment("Microservice__EnableDiagnostics", "true") // Set to false in production deployments
|
||||||
|
.WithEnvironment("Microservice__Application__Url", "")
|
||||||
|
.WithEnvironment("Microservice__Application__ApplicationId", "")
|
||||||
|
.WithEnvironment("Microservice__Application__ApiKey", "")
|
||||||
|
.WithEnvironment("Microservice__Application__EnvelopePassword", "")
|
||||||
|
.WithEnvironment("Microservice__ProtectedMemory__HmacSha512HashKey", "")
|
||||||
|
.WithEnvironment("Microservice__ProtectedMemory__AesEncryptionPassword", "")
|
||||||
|
.WithEnvironment("Microservice__ProtectedMemory__AesEncryptionSalt", "")
|
||||||
|
.WithEnvironment("Microservice__ProtectedMemory__AesEncryptionIterations", "")
|
||||||
|
.WithEnvironment("SqlServer__ConnectionString", "")
|
||||||
|
.WithEnvironment("SqlServer__ReadOnlyConnectionString", "")
|
||||||
|
|
||||||
|
// Api will write log and other files to this relatiove source folder
|
||||||
|
.WithBindMount("..\\..\\..\\data\\KeysApi", "/opt/triunnialabs/arch/keys-api")
|
||||||
|
|
||||||
|
.WithReference(keysApiDb)
|
||||||
|
.WaitFor(keysApiDb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+39
@@ -0,0 +1,39 @@
|
|||||||
|
namespace TriunniaLabs.Arch.Sample.Aspire.AppHost
|
||||||
|
{
|
||||||
|
internal static class TokensApiSetup
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a resource for the Tokens Api on port 50003.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="builder">Reference to the application builder.</param>
|
||||||
|
/// <param name="sqlServer">Reference to the Sql Server resource.</param>
|
||||||
|
public static void AddTokensApi(this IDistributedApplicationBuilder builder, IResourceBuilder<SqlServerServerResource> sqlServer)
|
||||||
|
{
|
||||||
|
var tokensApiDb = sqlServer.AddDatabase("TokensApiDb");
|
||||||
|
builder.AddContainer("TokensApi", "gitea.triunnialabs.com/triunnialabs/arch-tokens-api", "0.3.1")
|
||||||
|
.WithEndpoint(50003, 8080, isProxied: false, name: "http")
|
||||||
|
.WithEndpoint("http", e => e.TargetHost = "0.0.0.0")
|
||||||
|
|
||||||
|
// Obtain the values for these fields from the Control Panel
|
||||||
|
.WithEnvironment("Microservice__Name", "")
|
||||||
|
.WithEnvironment("Microservice__EnvelopePassword", "")
|
||||||
|
.WithEnvironment("Microservice__EnableDiagnostics", "true") // Set to false in production deployments
|
||||||
|
.WithEnvironment("Microservice__Application__Url", "")
|
||||||
|
.WithEnvironment("Microservice__Application__ApplicationId", "")
|
||||||
|
.WithEnvironment("Microservice__Application__ApiKey", "")
|
||||||
|
.WithEnvironment("Microservice__Application__EnvelopePassword", "")
|
||||||
|
.WithEnvironment("Microservice__ProtectedMemory__HmacSha512HashKey", "")
|
||||||
|
.WithEnvironment("Microservice__ProtectedMemory__AesEncryptionPassword", "")
|
||||||
|
.WithEnvironment("Microservice__ProtectedMemory__AesEncryptionSalt", "")
|
||||||
|
.WithEnvironment("Microservice__ProtectedMemory__AesEncryptionIterations", "")
|
||||||
|
.WithEnvironment("SqlServer__ConnectionString", "")
|
||||||
|
.WithEnvironment("SqlServer__ReadOnlyConnectionString", "")
|
||||||
|
|
||||||
|
// Api will write log and other files to this relatiove source folder
|
||||||
|
.WithBindMount("..\\..\\..\\data\\TokensApi", "/opt/triunnialabs/arch/tokens-api")
|
||||||
|
|
||||||
|
.WithReference(tokensApiDb)
|
||||||
|
.WaitFor(tokensApiDb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+52
@@ -0,0 +1,52 @@
|
|||||||
|
namespace TriunniaLabs.Arch.Sample.Aspire.AppHost
|
||||||
|
{
|
||||||
|
internal static class UsersApiSetup
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a resource for the Users Api on port 50005.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="builder">Reference to the application builder.</param>
|
||||||
|
/// <param name="sqlServer">Reference to the Sql Server resource.</param>
|
||||||
|
public static void AddUsersApi(this IDistributedApplicationBuilder builder, IResourceBuilder<SqlServerServerResource> sqlServer)
|
||||||
|
{
|
||||||
|
var usersApiDb = sqlServer.AddDatabase("UsersApiDb");
|
||||||
|
builder.AddContainer("UsersApi", "gitea.triunnialabs.com/triunnialabs/arch-users-api", "0.2.44")
|
||||||
|
.WithEndpoint(50005, 8080, isProxied: false, name: "http")
|
||||||
|
.WithEndpoint("http", e => e.TargetHost = "0.0.0.0")
|
||||||
|
|
||||||
|
// Obtain the values for these fields from the Control Panel
|
||||||
|
.WithEnvironment("Microservice__Name", "")
|
||||||
|
.WithEnvironment("Microservice__EnvelopePassword", "")
|
||||||
|
.WithEnvironment("Microservice__EnableDiagnostics", "true") // Set to false in production deployments
|
||||||
|
.WithEnvironment("Microservice__Application__Url", "")
|
||||||
|
.WithEnvironment("Microservice__Application__ApplicationId", "")
|
||||||
|
.WithEnvironment("Microservice__Application__ApiKey", "")
|
||||||
|
.WithEnvironment("Microservice__Application__EnvelopePassword", "")
|
||||||
|
.WithEnvironment("Microservice__ProtectedMemory__HmacSha512HashKey", "")
|
||||||
|
.WithEnvironment("Microservice__ProtectedMemory__AesEncryptionPassword", "")
|
||||||
|
.WithEnvironment("Microservice__ProtectedMemory__AesEncryptionSalt", "")
|
||||||
|
.WithEnvironment("Microservice__ProtectedMemory__AesEncryptionIterations", "")
|
||||||
|
.WithEnvironment("SqlServer__ConnectionString", "")
|
||||||
|
.WithEnvironment("SqlServer__ReadOnlyConnectionString", "")
|
||||||
|
.WithEnvironment("TokensApi__Url", "") // Users Api requires Tokens Api
|
||||||
|
.WithEnvironment("TokensApi__ApplicationId", "")
|
||||||
|
.WithEnvironment("TokensApi__ApiKey", "")
|
||||||
|
.WithEnvironment("TokensApi__EnvelopePassword", "")
|
||||||
|
.WithEnvironment("KeysApi__Url", "") // Users Api requires Keys Api
|
||||||
|
.WithEnvironment("KeysApi__ApplicationId", "")
|
||||||
|
.WithEnvironment("KeysApi__ApiKey", "")
|
||||||
|
.WithEnvironment("KeysApi__EnvelopePassword", "")
|
||||||
|
.WithEnvironment("EmailApi__Url", "") // Users Api requires Email Api
|
||||||
|
.WithEnvironment("EmailApi__ApplicationId", "")
|
||||||
|
.WithEnvironment("EmailApi__ApiKey", "")
|
||||||
|
.WithEnvironment("EmailApi__EnvelopePassword", "")
|
||||||
|
.WithEnvironment("UsersApi__AuthenticationScheme", "MySampleAuthScheme") // Set to your authentication scheme name (appears in browser)
|
||||||
|
|
||||||
|
// Api will write log and other files to this relatiove source folder
|
||||||
|
.WithBindMount("..\\..\\..\\data\\UsersApi", "/opt/triunnialabs/arch/users-api")
|
||||||
|
|
||||||
|
.WithReference(usersApiDb)
|
||||||
|
.WaitFor(usersApiDb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+22
@@ -0,0 +1,22 @@
|
|||||||
|
namespace TriunniaLabs.Arch.Sample.Aspire.AppHost
|
||||||
|
{
|
||||||
|
internal static class ControlPanelSetup
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a resource for the Control Panel on port 50000.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="builder">Reference to the application builder.</param>
|
||||||
|
/// <param name="sqlServer">Reference to the Sql Server resource.</param>
|
||||||
|
public static void AddControlPanel(this IDistributedApplicationBuilder builder, IResourceBuilder<SqlServerServerResource> sqlServer)
|
||||||
|
{
|
||||||
|
var controlPanelDb = sqlServer.AddDatabase("ControlPanelDb");
|
||||||
|
builder.AddContainer("ControlPanel", "gitea.triunnialabs.com/triunnialabs/arch-control-panel", "0.0.22")
|
||||||
|
.WithEndpoint(50000, 8080, isProxied: false, name: "http")
|
||||||
|
.WithEndpoint("http", e => e.TargetHost = "0.0.0.0")
|
||||||
|
.WithEnvironment("ControlPanel__DataPath", "/opt/triunnialabs/arch/controlpanel")
|
||||||
|
.WithBindMount("..\\..\\..\\data\\ControlPanel", "/opt/triunnialabs/arch/controlpanel")
|
||||||
|
.WithReference(controlPanelDb)
|
||||||
|
.WaitFor(controlPanelDb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+21
@@ -0,0 +1,21 @@
|
|||||||
|
namespace TriunniaLabs.Arch.Sample.Aspire.AppHost
|
||||||
|
{
|
||||||
|
internal static class SqlServerSetup
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a resource for a Sql Server database on port 51000.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="builder">Reference to the application builder.</param>
|
||||||
|
/// <returns>
|
||||||
|
/// Returns the Sql Server resource.
|
||||||
|
/// </returns>
|
||||||
|
public static IResourceBuilder<SqlServerServerResource> AddSampleSqlServer(this IDistributedApplicationBuilder builder)
|
||||||
|
{
|
||||||
|
var password = builder.AddParameter("password", "p@ssw0rd");
|
||||||
|
var sqlServer = builder.AddSqlServer("Sample-SqlServer", password, 51000)
|
||||||
|
.WithDataVolume("Sample-SqlServer-Data")
|
||||||
|
.WithEndpoint("tcp", e => { e.IsProxied = false; });
|
||||||
|
return sqlServer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
<Project Sdk="Aspire.AppHost.Sdk/13.2.4">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net10.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<UserSecretsId>eaa9faa0-83e2-49df-8f34-af7c4906a005</UserSecretsId>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Aspire.Hosting.AppHost" Version="13.3.5" />
|
||||||
|
<PackageReference Include="Aspire.Hosting.SqlServer" Version="13.3.5" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft.AspNetCore": "Warning"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft.AspNetCore": "Warning",
|
||||||
|
"Aspire.Hosting.Dcp": "Warning"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+127
@@ -0,0 +1,127 @@
|
|||||||
|
using Microsoft.AspNetCore.Builder;
|
||||||
|
using Microsoft.AspNetCore.Diagnostics.HealthChecks;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.Diagnostics.HealthChecks;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Microsoft.Extensions.ServiceDiscovery;
|
||||||
|
using OpenTelemetry;
|
||||||
|
using OpenTelemetry.Metrics;
|
||||||
|
using OpenTelemetry.Trace;
|
||||||
|
|
||||||
|
namespace Microsoft.Extensions.Hosting;
|
||||||
|
|
||||||
|
// Adds common Aspire services: service discovery, resilience, health checks, and OpenTelemetry.
|
||||||
|
// This project should be referenced by each service project in your solution.
|
||||||
|
// To learn more about using this project, see https://aka.ms/dotnet/aspire/service-defaults
|
||||||
|
public static class Extensions
|
||||||
|
{
|
||||||
|
private const string HealthEndpointPath = "/health";
|
||||||
|
private const string AlivenessEndpointPath = "/alive";
|
||||||
|
|
||||||
|
public static TBuilder AddServiceDefaults<TBuilder>(this TBuilder builder) where TBuilder : IHostApplicationBuilder
|
||||||
|
{
|
||||||
|
builder.ConfigureOpenTelemetry();
|
||||||
|
|
||||||
|
builder.AddDefaultHealthChecks();
|
||||||
|
|
||||||
|
builder.Services.AddServiceDiscovery();
|
||||||
|
|
||||||
|
builder.Services.ConfigureHttpClientDefaults(http =>
|
||||||
|
{
|
||||||
|
// Turn on resilience by default
|
||||||
|
http.AddStandardResilienceHandler();
|
||||||
|
|
||||||
|
// Turn on service discovery by default
|
||||||
|
http.AddServiceDiscovery();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Uncomment the following to restrict the allowed schemes for service discovery.
|
||||||
|
// builder.Services.Configure<ServiceDiscoveryOptions>(options =>
|
||||||
|
// {
|
||||||
|
// options.AllowedSchemes = ["https"];
|
||||||
|
// });
|
||||||
|
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TBuilder ConfigureOpenTelemetry<TBuilder>(this TBuilder builder) where TBuilder : IHostApplicationBuilder
|
||||||
|
{
|
||||||
|
builder.Logging.AddOpenTelemetry(logging =>
|
||||||
|
{
|
||||||
|
logging.IncludeFormattedMessage = true;
|
||||||
|
logging.IncludeScopes = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.Services.AddOpenTelemetry()
|
||||||
|
.WithMetrics(metrics =>
|
||||||
|
{
|
||||||
|
metrics.AddAspNetCoreInstrumentation()
|
||||||
|
.AddHttpClientInstrumentation()
|
||||||
|
.AddRuntimeInstrumentation();
|
||||||
|
})
|
||||||
|
.WithTracing(tracing =>
|
||||||
|
{
|
||||||
|
tracing.AddSource(builder.Environment.ApplicationName)
|
||||||
|
.AddAspNetCoreInstrumentation(tracing =>
|
||||||
|
// Exclude health check requests from tracing
|
||||||
|
tracing.Filter = context =>
|
||||||
|
!context.Request.Path.StartsWithSegments(HealthEndpointPath)
|
||||||
|
&& !context.Request.Path.StartsWithSegments(AlivenessEndpointPath)
|
||||||
|
)
|
||||||
|
// Uncomment the following line to enable gRPC instrumentation (requires the OpenTelemetry.Instrumentation.GrpcNetClient package)
|
||||||
|
//.AddGrpcClientInstrumentation()
|
||||||
|
.AddHttpClientInstrumentation();
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.AddOpenTelemetryExporters();
|
||||||
|
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static TBuilder AddOpenTelemetryExporters<TBuilder>(this TBuilder builder) where TBuilder : IHostApplicationBuilder
|
||||||
|
{
|
||||||
|
var useOtlpExporter = !string.IsNullOrWhiteSpace(builder.Configuration["OTEL_EXPORTER_OTLP_ENDPOINT"]);
|
||||||
|
|
||||||
|
if (useOtlpExporter)
|
||||||
|
{
|
||||||
|
builder.Services.AddOpenTelemetry().UseOtlpExporter();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uncomment the following lines to enable the Azure Monitor exporter (requires the Azure.Monitor.OpenTelemetry.AspNetCore package)
|
||||||
|
//if (!string.IsNullOrEmpty(builder.Configuration["APPLICATIONINSIGHTS_CONNECTION_STRING"]))
|
||||||
|
//{
|
||||||
|
// builder.Services.AddOpenTelemetry()
|
||||||
|
// .UseAzureMonitor();
|
||||||
|
//}
|
||||||
|
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TBuilder AddDefaultHealthChecks<TBuilder>(this TBuilder builder) where TBuilder : IHostApplicationBuilder
|
||||||
|
{
|
||||||
|
builder.Services.AddHealthChecks()
|
||||||
|
// Add a default liveness check to ensure app is responsive
|
||||||
|
.AddCheck("self", () => HealthCheckResult.Healthy(), ["live"]);
|
||||||
|
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static WebApplication MapDefaultEndpoints(this WebApplication app)
|
||||||
|
{
|
||||||
|
// Adding health checks endpoints to applications in non-development environments has security implications.
|
||||||
|
// See https://aka.ms/dotnet/aspire/healthchecks for details before enabling these endpoints in non-development environments.
|
||||||
|
if (app.Environment.IsDevelopment())
|
||||||
|
{
|
||||||
|
// All health checks must pass for app to be considered ready to accept traffic after starting
|
||||||
|
app.MapHealthChecks(HealthEndpointPath);
|
||||||
|
|
||||||
|
// Only health checks tagged with the "live" tag must pass for app to be considered alive
|
||||||
|
app.MapHealthChecks(AlivenessEndpointPath, new HealthCheckOptions
|
||||||
|
{
|
||||||
|
Predicate = r => r.Tags.Contains("live")
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return app;
|
||||||
|
}
|
||||||
|
}
|
||||||
+22
@@ -0,0 +1,22 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net10.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<IsAspireSharedProject>true</IsAspireSharedProject>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<FrameworkReference Include="Microsoft.AspNetCore.App" />
|
||||||
|
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Http.Resilience" Version="10.6.0" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.ServiceDiscovery" Version="10.6.0" />
|
||||||
|
<PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.15.3" />
|
||||||
|
<PackageReference Include="OpenTelemetry.Extensions.Hosting" Version="1.15.3" />
|
||||||
|
<PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.15.2" />
|
||||||
|
<PackageReference Include="OpenTelemetry.Instrumentation.Http" Version="1.15.1" />
|
||||||
|
<PackageReference Include="OpenTelemetry.Instrumentation.Runtime" Version="1.15.1" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"appHost": {
|
||||||
|
"path": "TriunniaLabs.Arch.Sample.Aspire.AppHost/TriunniaLabs.Arch.Sample.Aspire.AppHost.csproj"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,132 @@
|
|||||||
|
using MessagePack;
|
||||||
|
using Microsoft.AspNetCore.Authentication;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
using System.Security.Claims;
|
||||||
|
using System.Text.Encodings.Web;
|
||||||
|
using TriunniaLabs.Arch.Api.Users.Client;
|
||||||
|
using TriunniaLabs.Arch.Microservice;
|
||||||
|
using TriunniaLabs.Memory.Protected;
|
||||||
|
|
||||||
|
namespace TriunniaLabs.Arch.Sample.Server
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// An authentication handler that validates a user's token/session.
|
||||||
|
/// </summary>
|
||||||
|
public class UserAuthenticationHandler : AuthenticationHandler<UserAuthenticationHandlerOptions>
|
||||||
|
{
|
||||||
|
// Services
|
||||||
|
private readonly ILogger<UserAuthenticationHandler> _logger;
|
||||||
|
private readonly UsersApiSettings _settings;
|
||||||
|
private readonly IFormatterResolver _formatterResolver;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Constructor.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="options">Reference to the options class for this handler.</param>
|
||||||
|
/// <param name="loggerFactory">Reference to the logger factory.</param>
|
||||||
|
/// <param name="urlEncoder">Reference to the url encoder.</param>
|
||||||
|
/// <param name="logger">Reference to the logger.</param>
|
||||||
|
/// <param name="settings">Reference to the users api settings.</param>
|
||||||
|
/// <param name="formatterResolver">Reference to the MessagePack formatter resolver.</param>
|
||||||
|
public UserAuthenticationHandler(IOptionsMonitor<UserAuthenticationHandlerOptions> options, ILoggerFactory loggerFactory, UrlEncoder urlEncoder,
|
||||||
|
ILogger<UserAuthenticationHandler> logger, IOptions<UsersApiSettings> settings,
|
||||||
|
IFormatterResolver formatterResolver)
|
||||||
|
: base(options, loggerFactory, urlEncoder)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
_settings = settings.Value;
|
||||||
|
_formatterResolver = formatterResolver;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Handles token authentication.
|
||||||
|
/// </summary>
|
||||||
|
protected async override Task<AuthenticateResult> HandleAuthenticateAsync()
|
||||||
|
{
|
||||||
|
using (_logger.ScopeWithMethod())
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_logger.LogInformation("Authenticate user...");
|
||||||
|
|
||||||
|
// Look for the authorization header
|
||||||
|
if (Request.Headers.ContainsKey("Authorization") == false)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("Not applicable: Authorization header not found.");
|
||||||
|
return await Task.FromResult(AuthenticateResult.NoResult());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the authorization header
|
||||||
|
var header = Request.Headers["Authorization"].ToString().Split(new string[] { " " }, System.StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
if (header.Length != 2)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("Not applicable: Incorrect authentication scheme - header length.");
|
||||||
|
return await Task.FromResult(AuthenticateResult.NoResult());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify that it is an appropriate header
|
||||||
|
if (header[0] != _settings.AuthenticationScheme)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("Not applicable: Incorrect authentication scheme - header name.");
|
||||||
|
return await Task.FromResult(AuthenticateResult.NoResult());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the token
|
||||||
|
if (string.IsNullOrEmpty(header[1]) == true)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("Authentication failed: Invalid token.");
|
||||||
|
return await Task.FromResult(AuthenticateResult.Fail("Invalid token.")).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
var relayProtector = ProtectedProtocol.RelayMessageProtector<string>(_formatterResolver);
|
||||||
|
var token = relayProtector.Receive(header[1].Replace("\"", ""));
|
||||||
|
if (token.IsEmpty)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("Authentication failed: Invalid token.");
|
||||||
|
return await Task.FromResult(AuthenticateResult.Fail("Invalid token.")).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Token comes in Relay protected. Need to use Standard protected for ValidateSessionAsync.
|
||||||
|
var standardProtector = ProtectedProtocol.StandardProtector<string>(_formatterResolver);
|
||||||
|
token.Reconfigure(standardProtector);
|
||||||
|
|
||||||
|
// Validate the session using a fresh-scoped Users Api client so the standard-protected
|
||||||
|
// auth header does not contaminate the shared _usersApiClient used by relay controllers.
|
||||||
|
// Relay controllers that call unauthenticated Users Api endpoints (e.g. CheckEmail) must
|
||||||
|
// not forward an auth header, otherwise the Users Api auth handler fails to relay-decrypt
|
||||||
|
// the standard-protected token and returns 500.
|
||||||
|
var ipAddress = Request.HttpContext.Connection?.RemoteIpAddress?.ToString() ?? "";
|
||||||
|
var protectedIpAddress = ipAddress.AsProtected();
|
||||||
|
using var validationScope = Context.RequestServices.CreateScope();
|
||||||
|
var validationClient = validationScope.ServiceProvider.GetRequiredService<IUsersApiClient>();
|
||||||
|
validationClient.SetAuthorizationHeader(token);
|
||||||
|
validationClient.SetIpAddressOriginHeader(protectedIpAddress);
|
||||||
|
var userId = await validationClient.ValidateSessionAsync(token, protectedIpAddress).ConfigureAwait(false);
|
||||||
|
if (userId is null)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("Authentication failed: Unauthorized.");
|
||||||
|
return await Task.FromResult(AuthenticateResult.Fail("Unauthorized.")).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Token is valid and user is authenticated
|
||||||
|
_logger.LogInformation("Authentication successful.");
|
||||||
|
|
||||||
|
// Generate a principal object for the user
|
||||||
|
var claims = new[] { new Claim(ClaimTypes.NameIdentifier, userId.ToString()) };
|
||||||
|
var identity = new ClaimsIdentity(claims, nameof(UserAuthenticationHandler));
|
||||||
|
var principal = new ClaimsPrincipal(identity);
|
||||||
|
|
||||||
|
// Create an authentication ticket for the user.
|
||||||
|
var ticket = new AuthenticationTicket(principal, Scheme.Name);
|
||||||
|
|
||||||
|
// Return a success code with the authentication ticket
|
||||||
|
return await Task.FromResult(AuthenticateResult.Success(ticket)).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, ex.Message);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
using Microsoft.AspNetCore.Authentication;
|
||||||
|
|
||||||
|
namespace TriunniaLabs.Arch.Sample.Server
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// An options class for the User Authentication Handler.
|
||||||
|
/// </summary>
|
||||||
|
public class UserAuthenticationHandlerOptions : AuthenticationSchemeOptions
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
using Microsoft.Extensions.Diagnostics.HealthChecks;
|
||||||
|
|
||||||
|
namespace TriunniaLabs.Arch.Sample.Server
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A health check to allow other services to check this service for uptime.
|
||||||
|
/// </summary>
|
||||||
|
public class HealthCheck : IHealthCheck
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Checks the health of the server to determine its condition.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="context">The context under which the health check is run.</param>
|
||||||
|
/// <param name="cancellationToken">A cancellation to use </param>
|
||||||
|
public Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
// Just return healthy as this is only an uptime check for now
|
||||||
|
return Task.FromResult(HealthCheckResult.Healthy());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
using System.Net;
|
||||||
|
|
||||||
|
namespace TriunniaLabs.Arch.Sample.Server
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A middleware that specifies a dummy ip address for use with the test server.
|
||||||
|
/// </summary>
|
||||||
|
public class DummyIpAddressMiddleware : IMiddleware
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Occurs when this middleware is invoked.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="context">The <see cref="HttpContext"/> for the current request.</param>
|
||||||
|
/// <param name="next">The delegate representing the remaining middleware in the request pipeline.</param>
|
||||||
|
/// <returns>A <see cref="Task"/> that represents the execution of this middleware.</returns>
|
||||||
|
public async Task InvokeAsync(HttpContext context, RequestDelegate next)
|
||||||
|
{
|
||||||
|
// Set localhost ip address
|
||||||
|
context.Connection.RemoteIpAddress = IPAddress.Parse("::1");
|
||||||
|
|
||||||
|
// Pass control to the next middleware
|
||||||
|
await next(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,108 @@
|
|||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
using System.Reflection;
|
||||||
|
using TriunniaLabs.Arch.Api.Comments.Client;
|
||||||
|
using TriunniaLabs.Arch.Api.Email.Client;
|
||||||
|
using TriunniaLabs.Arch.Api.Entity.Client;
|
||||||
|
using TriunniaLabs.Arch.Api.Files.Client;
|
||||||
|
using TriunniaLabs.Arch.Api.Keys.Client;
|
||||||
|
using TriunniaLabs.Arch.Api.Tokens.Client;
|
||||||
|
using TriunniaLabs.Arch.Api.Users.Client;
|
||||||
|
using TriunniaLabs.Arch.Microservice;
|
||||||
|
using TriunniaLabs.Arch.Relay.Email.Server;
|
||||||
|
using TriunniaLabs.Arch.Relay.Users.Server;
|
||||||
|
using TriunniaLabs.Arch.Sample.Server;
|
||||||
|
using TriunniaLabs.Memory.Protected;
|
||||||
|
|
||||||
|
// Start the ASP.NET application builder
|
||||||
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
|
builder.Services.AddControllers();
|
||||||
|
|
||||||
|
// Triunnia Labs: Set up your application to use Arch and add any services it directly depends on
|
||||||
|
builder.Host.UseTriunniaLabsMicroservice(EnvironmentType.Development);
|
||||||
|
builder.Services.AddTriunniaLabsMicroservice(builder.Configuration);
|
||||||
|
builder.Services.AddTriunniaLabsKeysApi(builder.Configuration, builder.Services.AddStandardMessagePackFormatters);
|
||||||
|
builder.Services.AddTriunniaLabsTokensApi(builder.Configuration, builder.Services.AddStandardMessagePackFormatters);
|
||||||
|
builder.Services.AddTriunniaLabsEmailApi(builder.Configuration, builder.Services.AddStandardMessagePackFormatters);
|
||||||
|
builder.Services.AddTriunniaLabsUsersApi(builder.Configuration, builder.Services.AddStandardMessagePackFormatters);
|
||||||
|
builder.Services.AddTriunniaLabsCommentsApi(builder.Configuration, builder.Services.AddStandardMessagePackFormatters);
|
||||||
|
builder.Services.AddTriunniaLabsEntityApi(builder.Configuration, builder.Services.AddStandardMessagePackFormatters);
|
||||||
|
builder.Services.AddTriunniaLabsFilesApi(builder.Configuration, builder.Services.AddStandardMessagePackFormatters);
|
||||||
|
|
||||||
|
// Configuration
|
||||||
|
builder.Services.AddRouting(options => options.LowercaseUrls = true);
|
||||||
|
|
||||||
|
// Diagnostics: Add a diagnostics provider so you can debug your configuration from the Control Panel
|
||||||
|
builder.Services.AddTransient<IDiagnosticConfigurationProvider, DiagnosicConfigurationProvider>();
|
||||||
|
|
||||||
|
// Converters: MessagePack is used for serialization within Arch and is part of the Protected Memory system.
|
||||||
|
// You may need to add some converters for your application to function.
|
||||||
|
builder.Services.AddKeyedSingleton<IByteArrayConverter<string>, MessagePackUntrustedByteArrayConverter<string>>("MessagePackUntrustedByteArrayConverter<System.String>");
|
||||||
|
builder.Services.AddKeyedSingleton<IByteArrayConverter<string[]>, MessagePackUntrustedByteArrayConverter<string[]>>("MessagePackUntrustedByteArrayConverter<System.String[]>");
|
||||||
|
builder.Services.AddKeyedSingleton<IByteArrayConverter<Guid>, MessagePackUntrustedByteArrayConverter<Guid>>("MessagePackUntrustedByteArrayConverter<System.Guid>");
|
||||||
|
|
||||||
|
// MessagePack Formatters: Any custom object or data type will need to be registered so that it can be handled by the Protected Memory system.
|
||||||
|
// All of your app's request/response objects, DTOs, and models should be registered.
|
||||||
|
builder.Services.AddStandardMessagePackFormatters(new[]
|
||||||
|
{
|
||||||
|
typeof(bool),
|
||||||
|
typeof(bool?),
|
||||||
|
typeof(char),
|
||||||
|
typeof(DateTime),
|
||||||
|
typeof(DateTime?)
|
||||||
|
});
|
||||||
|
|
||||||
|
// Authentication
|
||||||
|
var settings = builder.Services.BuildServiceProvider().GetRequiredService<IOptions<UsersApiSettings>>().Value;
|
||||||
|
builder.Services.AddAuthentication(options => options.DefaultScheme = settings.AuthenticationScheme)
|
||||||
|
.AddScheme<UserAuthenticationHandlerOptions, UserAuthenticationHandler>(settings.AuthenticationScheme, options => { })
|
||||||
|
.AddScheme<ApplicationAuthenticationHandlerOptions, ApplicationAuthenticationHandler>(ArchConstants.ApplicationAuthenticationScheme, options => { });
|
||||||
|
|
||||||
|
// Controllers
|
||||||
|
builder.Services.AddMvc()
|
||||||
|
.AddApplicationPart(Assembly.GetExecutingAssembly()).AddControllersAsServices()
|
||||||
|
.AddTriunniaLabsUsersApiRelay(builder.Services.AddStandardMessagePackFormatters)
|
||||||
|
.AddTriunniaLabsEmailApiRelay();
|
||||||
|
|
||||||
|
// Health Checks
|
||||||
|
builder.Services.AddHealthChecks().AddCheck<HealthCheck>("health-check");
|
||||||
|
|
||||||
|
// Middleware
|
||||||
|
if (builder.Environment.IsDevelopment())
|
||||||
|
builder.Services.AddSingleton<DummyIpAddressMiddleware>();
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
var app = builder.Build();
|
||||||
|
|
||||||
|
// Triunnia Labs
|
||||||
|
app.UseTriunniaLabsMicroservice();
|
||||||
|
|
||||||
|
// Configure the HTTP request pipeline.
|
||||||
|
if (app.Environment.IsDevelopment())
|
||||||
|
{
|
||||||
|
app.UseMiddleware<DummyIpAddressMiddleware>();
|
||||||
|
app.UseDeveloperExceptionPage();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
app.UseExceptionHandler("/Error");
|
||||||
|
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
|
||||||
|
app.UseHsts();
|
||||||
|
app.UseResponseCompression();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Https and Static Files
|
||||||
|
app.UseHttpsRedirection();
|
||||||
|
app.UseStaticFiles();
|
||||||
|
|
||||||
|
// Authentication, Routing, and Authorization
|
||||||
|
app.UseAuthorization();
|
||||||
|
app.UseRouting();
|
||||||
|
app.UseAuthorization();
|
||||||
|
|
||||||
|
// Controllers and Routing
|
||||||
|
app.MapControllers();
|
||||||
|
app.MapHealthChecks("/diagnostics/health-check");
|
||||||
|
|
||||||
|
// Run the server
|
||||||
|
app.Run();
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://json.schemastore.org/launchsettings.json",
|
||||||
|
"profiles": {
|
||||||
|
"TriunniaLabs.Arch.Sample.Server": {
|
||||||
|
"commandName": "Project",
|
||||||
|
"launchBrowser": true,
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
},
|
||||||
|
"dotnetRunMessages": true,
|
||||||
|
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
|
||||||
|
"applicationUrl": "http://localhost:50009;https://localhost:51009"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
using TriunniaLabs.Arch.Api.Email.Client;
|
||||||
|
using TriunniaLabs.Arch.Api.Entity.Client;
|
||||||
|
using TriunniaLabs.Arch.Api.Files.Client;
|
||||||
|
using TriunniaLabs.Arch.Api.Users.Client;
|
||||||
|
using TriunniaLabs.Arch.Microservice;
|
||||||
|
|
||||||
|
namespace TriunniaLabs.Arch.Sample.Server
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A provider for supplying additional configuration information for the purpose of diagnostics.
|
||||||
|
/// </summary>
|
||||||
|
public class DiagnosicConfigurationProvider : IDiagnosticConfigurationProvider
|
||||||
|
{
|
||||||
|
// Data
|
||||||
|
private readonly UsersApiSettings _usersApiSettings;
|
||||||
|
private readonly EmailApiSettings _emailApiSettings;
|
||||||
|
private readonly EntityApiSettings _entityApiSettings;
|
||||||
|
private readonly FilesApiSettings _filesApiSettings;
|
||||||
|
|
||||||
|
// Services
|
||||||
|
private readonly ILogger<DiagnosicConfigurationProvider> _logger;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Constructor.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="usersApiSettings">Reference to the Users Api setttings.</param>
|
||||||
|
/// <param name="emailApiSettings">Reference to the Email Api setttings.</param>
|
||||||
|
/// <param name="entityApiSettings">Reference to the Entity Api setttings.</param>
|
||||||
|
/// <param name="filesApiSettings">Reference to the Files Api setttings.</param>
|
||||||
|
/// <param name="logger">Reference to the logger.</param>
|
||||||
|
public DiagnosicConfigurationProvider(IOptions<UsersApiSettings> usersApiSettings, IOptions<EmailApiSettings> emailApiSettings,
|
||||||
|
IOptions<EntityApiSettings> entityApiSettings, IOptions<FilesApiSettings> filesApiSettings,
|
||||||
|
ILogger<DiagnosicConfigurationProvider> logger)
|
||||||
|
{
|
||||||
|
_usersApiSettings = usersApiSettings?.Value ?? throw new ArgumentNullException(nameof(usersApiSettings));
|
||||||
|
_emailApiSettings = emailApiSettings?.Value ?? throw new ArgumentNullException(nameof(emailApiSettings));
|
||||||
|
_entityApiSettings = entityApiSettings?.Value ?? throw new ArgumentNullException(nameof(entityApiSettings));
|
||||||
|
_filesApiSettings = filesApiSettings?.Value ?? throw new ArgumentNullException(nameof(filesApiSettings));
|
||||||
|
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Supplies custom settings used by the microservice to the diagnostic report.
|
||||||
|
/// Call <see cref="DiagnosticSettingsResponse.AddSetting{T}(string, Memory.Protected.Protected{T}?)" /> to add each setting.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="report">The diagnostic report to configure.</param>
|
||||||
|
public void SupplySettings(DiagnosticSettingsResponse report)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Add all additional protected configuration settings for your application here.
|
||||||
|
// They will be reported to the Control Panel via its Diagnostics feature when EnableDiagnostics is true.
|
||||||
|
|
||||||
|
report.AddSetting("UsersApi.ApplicationId", _usersApiSettings.ApplicationId);
|
||||||
|
report.AddSetting("UsersApi.Url", _usersApiSettings.Url);
|
||||||
|
report.AddSetting("UsersApi.ApiKey", _usersApiSettings.ApiKey);
|
||||||
|
report.AddSetting("UsersApi.EnvelopePassword", _usersApiSettings.EnvelopePassword);
|
||||||
|
|
||||||
|
report.AddSetting("EmailApi.ApplicationId", _emailApiSettings.ApplicationId);
|
||||||
|
report.AddSetting("EmailApi.Url", _emailApiSettings.Url);
|
||||||
|
report.AddSetting("EmailApi.ApiKey", _emailApiSettings.ApiKey);
|
||||||
|
report.AddSetting("EmailApi.EnvelopePassword", _emailApiSettings.EnvelopePassword);
|
||||||
|
|
||||||
|
report.AddSetting("EntityApi.ApplicationId", _entityApiSettings.ApplicationId);
|
||||||
|
report.AddSetting("EntityApi.Url", _entityApiSettings.Url);
|
||||||
|
report.AddSetting("EntityApi.ApiKey", _entityApiSettings.ApiKey);
|
||||||
|
report.AddSetting("EntityApi.EnvelopePassword", _entityApiSettings.EnvelopePassword);
|
||||||
|
|
||||||
|
report.AddSetting("FilesApi.ApplicationId", _filesApiSettings.ApplicationId);
|
||||||
|
report.AddSetting("FilesApi.Url", _filesApiSettings.Url);
|
||||||
|
report.AddSetting("FilesApi.ApiKey", _filesApiSettings.ApiKey);
|
||||||
|
report.AddSetting("FilesApi.EnvelopePassword", _filesApiSettings.EnvelopePassword);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Unable to supply settings for configuration diagnostic.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net10.0</TargetFramework>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="TriunniaLabs.Arch.Api.Comments.Client" Version="0.1.0" />
|
||||||
|
<PackageReference Include="TriunniaLabs.Arch.Api.Email.Client" Version="0.2.2" />
|
||||||
|
<PackageReference Include="TriunniaLabs.Arch.Api.Entity.Client" Version="0.1.4" />
|
||||||
|
<PackageReference Include="TriunniaLabs.Arch.Api.Files.Client" Version="0.1.3" />
|
||||||
|
<PackageReference Include="TriunniaLabs.Arch.Api.Keys.Client" Version="0.1.17" />
|
||||||
|
<PackageReference Include="TriunniaLabs.Arch.Api.Tokens.Client" Version="0.3.1" />
|
||||||
|
<PackageReference Include="TriunniaLabs.Arch.Api.Users.Client" Version="0.2.44" />
|
||||||
|
<PackageReference Include="TriunniaLabs.Arch.Microservice" Version="0.9.8" />
|
||||||
|
<PackageReference Include="TriunniaLabs.Arch.Relay.Email.Server" Version="0.2.2" />
|
||||||
|
<PackageReference Include="TriunniaLabs.Arch.Relay.Users.Server" Version="0.2.44" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
@@ -0,0 +1,98 @@
|
|||||||
|
{
|
||||||
|
"Microservice": {
|
||||||
|
"Name": "",
|
||||||
|
"EnvelopePassword": "",
|
||||||
|
"EnableDiagnostics": true,
|
||||||
|
"Application": {
|
||||||
|
"Url": "",
|
||||||
|
"ApplicationId": "",
|
||||||
|
"ApiKey": "",
|
||||||
|
"EnvelopePassword": ""
|
||||||
|
},
|
||||||
|
"ProtectedMemory": {
|
||||||
|
"HmacSha512HashKey": "",
|
||||||
|
"AesEncryptionPassword": "",
|
||||||
|
"AesEncryptionSalt": "",
|
||||||
|
"AesEncryptionIterations": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"KeysApi": {
|
||||||
|
"Url": "",
|
||||||
|
"ApplicationId": "",
|
||||||
|
"ApiKey": "",
|
||||||
|
"EnvelopePassword": ""
|
||||||
|
},
|
||||||
|
|
||||||
|
"TokensApi": {
|
||||||
|
"Url": "",
|
||||||
|
"ApplicationId": "",
|
||||||
|
"ApiKey": "",
|
||||||
|
"EnvelopePassword": ""
|
||||||
|
},
|
||||||
|
|
||||||
|
"EmailApi": {
|
||||||
|
"Url": "",
|
||||||
|
"ApplicationId": "",
|
||||||
|
"ApiKey": "",
|
||||||
|
"EnvelopePassword": ""
|
||||||
|
},
|
||||||
|
|
||||||
|
"UsersApi": {
|
||||||
|
"Url": "",
|
||||||
|
"ApplicationId": "",
|
||||||
|
"ApiKey": "",
|
||||||
|
"EnvelopePassword": "",
|
||||||
|
"AuthenticationScheme": "MySampleAuthScheme"
|
||||||
|
},
|
||||||
|
|
||||||
|
"CommentsApi": {
|
||||||
|
"Url": "",
|
||||||
|
"ApplicationId": "",
|
||||||
|
"ApiKey": "",
|
||||||
|
"EnvelopePassword": ""
|
||||||
|
},
|
||||||
|
|
||||||
|
"EntityApi": {
|
||||||
|
"Url": "",
|
||||||
|
"ApplicationId": "",
|
||||||
|
"ApiKey": "",
|
||||||
|
"EnvelopePassword": ""
|
||||||
|
},
|
||||||
|
|
||||||
|
"FilesApi": {
|
||||||
|
"Url": "",
|
||||||
|
"ApplicationId": "",
|
||||||
|
"ApiKey": "",
|
||||||
|
"EnvelopePassword": ""
|
||||||
|
},
|
||||||
|
|
||||||
|
"Serilog": {
|
||||||
|
"Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.File" ],
|
||||||
|
"MinimumLevel": {
|
||||||
|
"Default": "Debug",
|
||||||
|
"Override": {
|
||||||
|
"Microsoft": "Warning",
|
||||||
|
"System": "Warning"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"WriteTo": [
|
||||||
|
{
|
||||||
|
"Name": "Console",
|
||||||
|
"Args": {
|
||||||
|
"formatter": "Serilog.Formatting.Compact.CompactJsonFormatter, Serilog.Formatting.Compact"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "File",
|
||||||
|
"Args": {
|
||||||
|
"path": "Logs/log-.txt",
|
||||||
|
"formatter": "Serilog.Formatting.Compact.CompactJsonFormatter, Serilog.Formatting.Compact",
|
||||||
|
"rollingInterval": "Day",
|
||||||
|
"retainedFileCountLimit": 7
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
<Solution>
|
||||||
|
<Project Path="TriunniaLabs.Arch.Sample.Aspire/TriunniaLabs.Arch.Sample.Aspire.AppHost/TriunniaLabs.Arch.Sample.Aspire.AppHost.csproj" Id="6cb44d36-37cb-47cb-b6dc-e3f1900b3eb5" />
|
||||||
|
<Project Path="TriunniaLabs.Arch.Sample.Aspire/TriunniaLabs.Arch.Sample.Aspire.ServiceDefaults/TriunniaLabs.Arch.Sample.Aspire.ServiceDefaults.csproj" />
|
||||||
|
<Project Path="TriunniaLabs.Arch.Sample.Server/TriunniaLabs.Arch.Sample.Server.csproj" />
|
||||||
|
</Solution>
|
||||||
Reference in New Issue
Block a user