added two samples
This commit is contained in:
130
VendorManagement/ServiceDefaults/Extensions.cs
Normal file
130
VendorManagement/ServiceDefaults/Extensions.cs
Normal file
@@ -0,0 +1,130 @@
|
||||
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
VendorManagement/ServiceDefaults/ServiceDefaults.csproj
Normal file
22
VendorManagement/ServiceDefaults/ServiceDefaults.csproj
Normal file
@@ -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.1.0"/>
|
||||
<PackageReference Include="Microsoft.Extensions.ServiceDiscovery" Version="10.1.0"/>
|
||||
<PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.14.0"/>
|
||||
<PackageReference Include="OpenTelemetry.Extensions.Hosting" Version="1.14.0"/>
|
||||
<PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.14.0"/>
|
||||
<PackageReference Include="OpenTelemetry.Instrumentation.Http" Version="1.14.0"/>
|
||||
<PackageReference Include="OpenTelemetry.Instrumentation.Runtime" Version="1.14.0"/>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
4
VendorManagement/VendorManagement.slnx
Normal file
4
VendorManagement/VendorManagement.slnx
Normal file
@@ -0,0 +1,4 @@
|
||||
<Solution>
|
||||
<Project Path="ServiceDefaults/ServiceDefaults.csproj" />
|
||||
<Project Path="Vendors.Api/Vendors.Api.csproj" />
|
||||
</Solution>
|
||||
37
VendorManagement/Vendors.Api/Program.cs
Normal file
37
VendorManagement/Vendors.Api/Program.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
|
||||
using Microsoft.OpenApi;
|
||||
using Scalar.AspNetCore;
|
||||
using Vendors.Api;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
builder.AddServiceDefaults();
|
||||
builder.Services.AddOpenApi(config =>
|
||||
{
|
||||
config.AddDocumentTransformer((doc, ctx, ct) =>
|
||||
{
|
||||
doc.Info = new OpenApiInfo()
|
||||
{
|
||||
Title = "Vendors API for Classroom Training",
|
||||
Description =
|
||||
"This API provides a list of vendors and allows lookup by unique identifier. It is intended for use in classroom training scenarios. \n\n The API Key can be anything that ends in three integers. Those integers are multiplied by 100 and the result is delayed by that number of milliseconds.",
|
||||
};
|
||||
return Task.CompletedTask;
|
||||
});
|
||||
});
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
|
||||
app.MapVendorApiEndpoints();
|
||||
app.MapOpenApi();
|
||||
app.MapScalarApiReference(options =>
|
||||
{
|
||||
options.Theme = ScalarTheme.BluePlanet;
|
||||
options.Title = "Vendors API Reference";
|
||||
|
||||
});
|
||||
|
||||
app.MapDefaultEndpoints();
|
||||
|
||||
app.MapGet("/", () => Results.Redirect("/scalar")).WithDescription("Redirect to API Reference").WithDisplayName("Home Redirect");
|
||||
app.Run();
|
||||
23
VendorManagement/Vendors.Api/Properties/launchSettings.json
Normal file
23
VendorManagement/Vendors.Api/Properties/launchSettings.json
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/launchsettings.json",
|
||||
"profiles": {
|
||||
"http": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"launchBrowser": true,
|
||||
"applicationUrl": "http://vendors_api.dev.localhost:5242",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"https": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"launchBrowser": true,
|
||||
"applicationUrl": "https://vendors_api.dev.localhost:7057;http://vendors_api.dev.localhost:5242",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
38
VendorManagement/Vendors.Api/StaticVendorList.cs
Normal file
38
VendorManagement/Vendors.Api/StaticVendorList.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
namespace Vendors.Api;
|
||||
|
||||
public static class StaticVendorList
|
||||
{
|
||||
public static readonly List<Vendor> Vendors = new()
|
||||
{
|
||||
new Vendor(Guid.Parse("b1d6f5a1-3f49-4b14-9b6b-0c1d0a1f0001"), "Microsoft", "https://www.microsoft.com", new VendorContact("Alice Johnson", "alice.johnson@microsoft.example", "+1-425-555-0101")),
|
||||
new Vendor(Guid.Parse("b1d6f5a1-3f49-4b14-9b6b-0c1d0a1f0002"), "Google", "https://www.google.com", new VendorContact("Ravi Patel", "ravi.patel@google.example", "+1-650-555-0102")),
|
||||
new Vendor(Guid.Parse("b1d6f5a1-3f49-4b14-9b6b-0c1d0a1f0003"), "Amazon Web Services", "https://aws.amazon.com", new VendorContact("Monica Reyes", "monica.reyes@aws.example", "+1-206-555-0103")),
|
||||
new Vendor(Guid.Parse("b1d6f5a1-3f49-4b14-9b6b-0c1d0a1f0004"), "IBM", "https://www.ibm.com", new VendorContact("David Lee", "david.lee@ibm.example", "+1-914-555-0104")),
|
||||
new Vendor(Guid.Parse("b1d6f5a1-3f49-4b14-9b6b-0c1d0a1f0005"), "Oracle", "https://www.oracle.com", new VendorContact("Samantha Green", "samantha.green@oracle.example", "+1-650-555-0105")),
|
||||
new Vendor(Guid.Parse("b1d6f5a1-3f49-4b14-9b6b-0c1d0a1f0006"), "Salesforce", "https://www.salesforce.com", new VendorContact("Carlos Martinez", "carlos.martinez@salesforce.example", "+1-415-555-0106")),
|
||||
new Vendor(Guid.Parse("b1d6f5a1-3f49-4b14-9b6b-0c1d0a1f0007"), "Atlassian", "https://www.atlassian.com", new VendorContact("Emily Chen", "emily.chen@atlassian.example", "+1-800-555-0107")),
|
||||
new Vendor(Guid.Parse("b1d6f5a1-3f49-4b14-9b6b-0c1d0a1f0008"), "GitHub", "https://github.com", new VendorContact("Liam O'Connor", "liam.oconnor@github.example", "+1-415-555-0108")),
|
||||
new Vendor(Guid.Parse("b1d6f5a1-3f49-4b14-9b6b-0c1d0a1f0009"), "GitLab", "https://about.gitlab.com", new VendorContact("Zara Khan", "zara.khan@gitlab.example", "+1-415-555-0109")),
|
||||
new Vendor(Guid.Parse("b1d6f5a1-3f49-4b14-9b6b-0c1d0a1f0010"), "Docker", "https://www.docker.com", new VendorContact("Tom Baker", "tom.baker@docker.example", null)),
|
||||
new Vendor(Guid.Parse("b1d6f5a1-3f49-4b14-9b6b-0c1d0a1f0011"), "Red Hat", "https://www.redhat.com", new VendorContact("Priya Nair", "priya.nair@redhat.example", "+1-617-555-0111")),
|
||||
new Vendor(Guid.Parse("b1d6f5a1-3f49-4b14-9b6b-0c1d0a1f0012"), "SAP", "https://www.sap.com", new VendorContact("Oliver Brown", "oliver.brown@sap.example", "+49-89-555-0112")),
|
||||
new Vendor(Guid.Parse("b1d6f5a1-3f49-4b14-9b6b-0c1d0a1f0013"), "VMware", "https://www.vmware.com", new VendorContact("Hannah Wilson", "hannah.wilson@vmware.example", "+1-650-555-0113")),
|
||||
new Vendor(Guid.Parse("b1d6f5a1-3f49-4b14-9b6b-0c1d0a1f0014"), "Elastic", "https://www.elastic.co", new VendorContact("Mateo Alvarez", "mateo.alvarez@elastic.example", "+1-512-555-0114")),
|
||||
new Vendor(Guid.Parse("b1d6f5a1-3f49-4b14-9b6b-0c1d0a1f0015"), "MongoDB", "https://www.mongodb.com", new VendorContact("Yuki Tanaka", "yuki.tanaka@mongodb.example", "+1-646-555-0115")),
|
||||
new Vendor(Guid.Parse("b1d6f5a1-3f49-4b14-9b6b-0c1d0a1f0016"), "Datadog", "https://www.datadoghq.com", new VendorContact("Noah Wright", "noah.wright@datadog.example", null)),
|
||||
new Vendor(Guid.Parse("b1d6f5a1-3f49-4b14-9b6b-0c1d0a1f0017"), "Splunk", "https://www.splunk.com", new VendorContact("Aisha Mohammed", "aisha.mohammed@splunk.example", "+1-415-555-0117")),
|
||||
new Vendor(Guid.Parse("b1d6f5a1-3f49-4b14-9b6b-0c1d0a1f0018"), "HashiCorp", "https://www.hashicorp.com", new VendorContact("Ethan Park", "ethan.park@hashicorp.example", "+1-415-555-0118")),
|
||||
new Vendor(Guid.Parse("b1d6f5a1-3f49-4b14-9b6b-0c1d0a1f0019"), "Twilio", "https://www.twilio.com", new VendorContact("Nina Rossi", "nina.rossi@twilio.example", "+1-415-555-0119")),
|
||||
new Vendor(Guid.Parse("b1d6f5a1-3f49-4b14-9b6b-0c1d0a1f0020"), "Stripe", "https://stripe.com", new VendorContact("Jordan King", "jordan.king@stripe.example", null)),
|
||||
new Vendor(Guid.Parse("b1d6f5a1-3f49-4b14-9b6b-0c1d0a1f0021"), "Slack", "https://slack.com", new VendorContact("Maya Singh", "maya.singh@slack.example", "+1-415-555-0121")),
|
||||
new Vendor(Guid.Parse("b1d6f5a1-3f49-4b14-9b6b-0c1d0a1f0022"), "Segment (Twilio)", "https://segment.com", new VendorContact("Victor Hugo", "victor.hugo@segment.example", "+1-415-555-0122")),
|
||||
new Vendor(Guid.Parse("b1d6f5a1-3f49-4b14-9b6b-0c1d0a1f0023"), "New Relic", "https://newrelic.com", new VendorContact("Sofia Petrova", "sofia.petrova@newrelic.example", "+1-650-555-0123")),
|
||||
new Vendor(Guid.Parse("b1d6f5a1-3f49-4b14-9b6b-0c1d0a1f0024"), "Figma", "https://www.figma.com", new VendorContact("Connor Blake", "connor.blake@figma.example", null)),
|
||||
new Vendor(Guid.Parse("b1d6f5a1-3f49-4b14-9b6b-0c1d0a1f0025"), "JetBrains", "https://www.jetbrains.com", new VendorContact("Irina Kozlova", "irina.kozlova@jetbrains.example", "+1-415-555-0125")),
|
||||
};
|
||||
}
|
||||
|
||||
public record Vendor(Guid Id, string Name, string WebSiteUrl, VendorContact Contact);
|
||||
|
||||
public record VendorContact(string Name, string Email, string? PhoneNumber);
|
||||
|
||||
72
VendorManagement/Vendors.Api/VendorApiExtensions.cs
Normal file
72
VendorManagement/Vendors.Api/VendorApiExtensions.cs
Normal file
@@ -0,0 +1,72 @@
|
||||
namespace Vendors.Api;
|
||||
|
||||
public static class VendorApiExtensions
|
||||
{
|
||||
extension(IEndpointRouteBuilder endpoints)
|
||||
{
|
||||
public IEndpointRouteBuilder MapVendorApiEndpoints()
|
||||
{
|
||||
var group = endpoints.MapGroup("/vendors")
|
||||
.WithDescription("Vendor List And Lookup")
|
||||
.WithDisplayName("Vendor List");
|
||||
|
||||
group.MapGet("", GetVendors).WithDisplayName("Vendor List").WithDescription("Get the list of vendors");
|
||||
|
||||
group.MapGet("{id:guid}", GetVendorById)
|
||||
.WithDisplayName("Vendor By Id")
|
||||
.WithDescription("Get a vendor by its unique identifier");
|
||||
|
||||
return endpoints;
|
||||
}
|
||||
|
||||
static async Task<IResult> GetVendors(string? apiKey)
|
||||
{
|
||||
if (apiKey is null)
|
||||
{
|
||||
return TypedResults.BadRequest("API_KEY is required");
|
||||
}
|
||||
|
||||
var lastThree = apiKey.Length >= 3 ? apiKey[^3..] : apiKey;
|
||||
if (!int.TryParse(lastThree, out var delaySeconds))
|
||||
{
|
||||
return TypedResults.BadRequest("API_KEY must end with three digits");
|
||||
}
|
||||
|
||||
await Task.Delay(delaySeconds * 100);
|
||||
var response = new
|
||||
{
|
||||
Note = "This is fake data for a classroom example", Vendors = StaticVendorList.Vendors
|
||||
};
|
||||
|
||||
return TypedResults.Ok(response);
|
||||
}
|
||||
|
||||
static async Task<IResult> GetVendorById(Guid id, string? apiKey)
|
||||
{
|
||||
// get the last three characters of the API key
|
||||
// if they are an integer, delay that many seconds
|
||||
// if they are not return a 400 bad request
|
||||
if (apiKey is null)
|
||||
{
|
||||
return TypedResults.BadRequest("API_KEY is required");
|
||||
}
|
||||
|
||||
var lastThree = apiKey.Length >= 3 ? apiKey[^3..] : apiKey;
|
||||
if (!int.TryParse(lastThree, out var delaySeconds))
|
||||
{
|
||||
return TypedResults.BadRequest("API_KEY must end with three digits");
|
||||
}
|
||||
|
||||
await Task.Delay(delaySeconds * 100);
|
||||
|
||||
var vendor = StaticVendorList.Vendors.FirstOrDefault(v => v.Id == id);
|
||||
|
||||
if (vendor == null)
|
||||
{
|
||||
return TypedResults.NotFound();
|
||||
}
|
||||
|
||||
return TypedResults.Ok(vendor);
|
||||
}
|
||||
}
|
||||
}
|
||||
20
VendorManagement/Vendors.Api/Vendors.Api.csproj
Normal file
20
VendorManagement/Vendors.Api/Vendors.Api.csproj
Normal file
@@ -0,0 +1,20 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\ServiceDefaults\ServiceDefaults.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Aspire.Npgsql" Version="13.1.0" />
|
||||
<PackageReference Include="Marten.AspNetCore" Version="8.19.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="10.0.2" />
|
||||
<PackageReference Include="Scalar.AspNetCore" Version="2.12.30" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
}
|
||||
}
|
||||
9
VendorManagement/Vendors.Api/appsettings.json
Normal file
9
VendorManagement/Vendors.Api/appsettings.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*"
|
||||
}
|
||||
15
wolverine-nats/WolverineAndNats/.idea/.idea.WolverineAndNats/.idea/.gitignore
generated
vendored
Normal file
15
wolverine-nats/WolverineAndNats/.idea/.idea.WolverineAndNats/.idea/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Rider ignored files
|
||||
/contentModel.xml
|
||||
/modules.xml
|
||||
/projectSettingsUpdater.xml
|
||||
/.idea.WolverineAndNats.iml
|
||||
# Ignored default folder with query files
|
||||
/queries/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="AgentMigrationStateService">
|
||||
<option name="migrationStatus" value="COMPLETED" />
|
||||
</component>
|
||||
</project>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Ask2AgentMigrationStateService">
|
||||
<option name="migrationStatus" value="COMPLETED" />
|
||||
</component>
|
||||
</project>
|
||||
19
wolverine-nats/WolverineAndNats/.idea/.idea.WolverineAndNats/.idea/dataSources.xml
generated
Normal file
19
wolverine-nats/WolverineAndNats/.idea/.idea.WolverineAndNats/.idea/dataSources.xml
generated
Normal file
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="DataSourceManagerImpl" format="xml" multifile-model="true">
|
||||
<data-source source="LOCAL" name="pg" uuid="ce1a7cb8-729e-46fe-9898-8bf0c03ad5cf">
|
||||
<driver-ref>postgresql</driver-ref>
|
||||
<synchronize>true</synchronize>
|
||||
<jdbc-driver>org.postgresql.Driver</jdbc-driver>
|
||||
<jdbc-url>jdbc:postgresql://localhost:51238/?password=v0%7Ew8n1%7BE%29KYsw-1*3st0R&user=postgres</jdbc-url>
|
||||
<working-dir>$ProjectFileDir$</working-dir>
|
||||
</data-source>
|
||||
<data-source source="LOCAL" name="pg" uuid="567fbbf8-b474-4c51-b1d6-afcfe5c05a76">
|
||||
<driver-ref>postgresql</driver-ref>
|
||||
<synchronize>true</synchronize>
|
||||
<jdbc-driver>org.postgresql.Driver</jdbc-driver>
|
||||
<jdbc-url>jdbc:postgresql://localhost:54454/?password=v0%7Ew8n1%7BE%29KYsw-1*3st0R&user=postgres</jdbc-url>
|
||||
<working-dir>$ProjectFileDir$</working-dir>
|
||||
</data-source>
|
||||
</component>
|
||||
</project>
|
||||
6
wolverine-nats/WolverineAndNats/.idea/.idea.WolverineAndNats/.idea/db-forest-config.xml
generated
Normal file
6
wolverine-nats/WolverineAndNats/.idea/.idea.WolverineAndNats/.idea/db-forest-config.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="db-tree-configuration">
|
||||
<option name="data" value="---------------------------------------- 1:0:ce1a7cb8-729e-46fe-9898-8bf0c03ad5cf 2:0:567fbbf8-b474-4c51-b1d6-afcfe5c05a76 " />
|
||||
</component>
|
||||
</project>
|
||||
4
wolverine-nats/WolverineAndNats/.idea/.idea.WolverineAndNats/.idea/encodings.xml
generated
Normal file
4
wolverine-nats/WolverineAndNats/.idea/.idea.WolverineAndNats/.idea/encodings.xml
generated
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Encoding" addBOMForNewFiles="with BOM under Windows, with no BOM otherwise" />
|
||||
</project>
|
||||
8
wolverine-nats/WolverineAndNats/.idea/.idea.WolverineAndNats/.idea/indexLayout.xml
generated
Normal file
8
wolverine-nats/WolverineAndNats/.idea/.idea.WolverineAndNats/.idea/indexLayout.xml
generated
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="UserContentModel">
|
||||
<attachedFolders />
|
||||
<explicitIncludes />
|
||||
<explicitExcludes />
|
||||
</component>
|
||||
</project>
|
||||
7
wolverine-nats/WolverineAndNats/.idea/.idea.WolverineAndNats/.idea/vcs.xml
generated
Normal file
7
wolverine-nats/WolverineAndNats/.idea/.idea.WolverineAndNats/.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
<mapping directory="$PROJECT_DIR$/../../.." vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
20
wolverine-nats/WolverineAndNats/ApiOne/ApiOne.csproj
Normal file
20
wolverine-nats/WolverineAndNats/ApiOne/ApiOne.csproj
Normal file
@@ -0,0 +1,20 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Messages\Messages.csproj" />
|
||||
<ProjectReference Include="..\ServiceDefaults\ServiceDefaults.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Aspire.Npgsql" Version="13.1.0" />
|
||||
<PackageReference Include="WolverineFx.Marten" Version="5.13.0" />
|
||||
<PackageReference Include="WolverineFx.Nats" Version="5.13.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,44 @@
|
||||
using Messages;
|
||||
using Wolverine;
|
||||
|
||||
namespace ApiOne.Endpoints;
|
||||
|
||||
public static class Extensions
|
||||
{
|
||||
extension(IEndpointRouteBuilder endpoints)
|
||||
{
|
||||
public IEndpointRouteBuilder MapApiOneEndpoints()
|
||||
{
|
||||
endpoints.MapPost("/messages", async (SendMessage request, IMessageBus messageBus) =>
|
||||
{
|
||||
await messageBus.PublishAsync(request);
|
||||
return Results.Accepted();
|
||||
});
|
||||
|
||||
endpoints.MapPost("/math", async (AddThem request, IMessageBus bus) =>
|
||||
{
|
||||
var result = await bus.InvokeAsync<NumbersAdded>(request);
|
||||
return Results.Ok(result);
|
||||
});
|
||||
|
||||
endpoints.MapPost("/users", async (UserCreate user, IMessageBus bus) =>
|
||||
{
|
||||
var doc = new UserDocument(Guid.NewGuid(), user.Name);
|
||||
await bus.PublishAsync(doc);
|
||||
return Results.Accepted();
|
||||
});
|
||||
endpoints.MapPut("/users/{id:guid}/name", async (Guid id, UserCreate user, IMessageBus bus) =>
|
||||
{
|
||||
var nameChanged = new UserNameChanged(id, user.Name);
|
||||
await bus.PublishAsync(nameChanged);
|
||||
return Results.Accepted();
|
||||
});
|
||||
|
||||
return endpoints;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public record UserCreate(string Name);
|
||||
|
||||
|
||||
56
wolverine-nats/WolverineAndNats/ApiOne/Program.cs
Normal file
56
wolverine-nats/WolverineAndNats/ApiOne/Program.cs
Normal file
@@ -0,0 +1,56 @@
|
||||
using ApiOne.Endpoints;
|
||||
using Marten;
|
||||
using Messages;
|
||||
using Wolverine;
|
||||
using Wolverine.Marten;
|
||||
using Wolverine.Nats;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
builder.AddServiceDefaults();
|
||||
builder.AddNpgsqlDataSource("db-one");
|
||||
|
||||
builder.UseWolverine(options =>
|
||||
{
|
||||
options.UseNats(builder.Configuration.GetConnectionString("nats") ??
|
||||
throw new Exception("No NATS connection string configured"))
|
||||
.AutoProvision()
|
||||
.UseJetStream(js =>
|
||||
{
|
||||
js.MaxDeliver = 5;
|
||||
js.AckWait = TimeSpan.FromSeconds(30);
|
||||
})
|
||||
|
||||
.DefineStream("PEOPLE", stream =>
|
||||
stream.WithSubject("people.>")
|
||||
.WithLimits(maxMessages: 5_000, maxAge: TimeSpan.FromDays(5))
|
||||
//.WithReplicas(3)
|
||||
.EnableScheduledDelivery());
|
||||
|
||||
|
||||
|
||||
options.PublishMessage<SendMessage>()
|
||||
.ToNatsSubject("messages-sent");
|
||||
|
||||
options.PublishMessage<UserDocument>()
|
||||
.ToNatsSubject("people.created");
|
||||
options.PublishMessage<UserNameChanged>()
|
||||
.ToNatsSubject("people.name-changed");
|
||||
|
||||
options.PublishMessage<AddThem>()
|
||||
.ToNatsSubject("math.add");
|
||||
|
||||
});
|
||||
|
||||
builder.Services.AddMarten(config =>
|
||||
{
|
||||
|
||||
}).UseLightweightSessions()
|
||||
.IntegrateWithWolverine()
|
||||
.UseNpgsqlDataSource();
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
app.MapGet("/", () => "Hello World!");
|
||||
app.MapApiOneEndpoints();
|
||||
app.MapDefaultEndpoints();
|
||||
app.Run();
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/launchsettings.json",
|
||||
"profiles": {
|
||||
|
||||
"https": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"launchBrowser": false,
|
||||
"applicationUrl": "https://apione.dev.localhost:7131",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
}
|
||||
}
|
||||
10
wolverine-nats/WolverineAndNats/ApiOne/appsettings.json
Normal file
10
wolverine-nats/WolverineAndNats/ApiOne/appsettings.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning",
|
||||
"Npgsql": "Warning"
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*"
|
||||
}
|
||||
BIN
wolverine-nats/WolverineAndNats/ApiOne/bin/Debug/net10.0/ApiOne
Executable file
BIN
wolverine-nats/WolverineAndNats/ApiOne/bin/Debug/net10.0/ApiOne
Executable file
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"runtimeOptions": {
|
||||
"tfm": "net10.0",
|
||||
"frameworks": [
|
||||
{
|
||||
"name": "Microsoft.NETCore.App",
|
||||
"version": "10.0.0"
|
||||
},
|
||||
{
|
||||
"name": "Microsoft.AspNetCore.App",
|
||||
"version": "10.0.0"
|
||||
}
|
||||
],
|
||||
"configProperties": {
|
||||
"System.GC.Server": true,
|
||||
"System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": false
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
{"Version":1,"ManifestType":"Build","Endpoints":[]}
|
||||
BIN
wolverine-nats/WolverineAndNats/ApiOne/bin/Debug/net10.0/Aspire.Npgsql.dll
Executable file
BIN
wolverine-nats/WolverineAndNats/ApiOne/bin/Debug/net10.0/Aspire.Npgsql.dll
Executable file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
wolverine-nats/WolverineAndNats/ApiOne/bin/Debug/net10.0/FSharp.Core.dll
Executable file
BIN
wolverine-nats/WolverineAndNats/ApiOne/bin/Debug/net10.0/FSharp.Core.dll
Executable file
Binary file not shown.
Binary file not shown.
BIN
wolverine-nats/WolverineAndNats/ApiOne/bin/Debug/net10.0/HealthChecks.NpgSql.dll
Executable file
BIN
wolverine-nats/WolverineAndNats/ApiOne/bin/Debug/net10.0/HealthChecks.NpgSql.dll
Executable file
Binary file not shown.
BIN
wolverine-nats/WolverineAndNats/ApiOne/bin/Debug/net10.0/Humanizer.dll
Executable file
BIN
wolverine-nats/WolverineAndNats/ApiOne/bin/Debug/net10.0/Humanizer.dll
Executable file
Binary file not shown.
BIN
wolverine-nats/WolverineAndNats/ApiOne/bin/Debug/net10.0/JasperFx.Events.dll
Executable file
BIN
wolverine-nats/WolverineAndNats/ApiOne/bin/Debug/net10.0/JasperFx.Events.dll
Executable file
Binary file not shown.
Binary file not shown.
BIN
wolverine-nats/WolverineAndNats/ApiOne/bin/Debug/net10.0/JasperFx.dll
Executable file
BIN
wolverine-nats/WolverineAndNats/ApiOne/bin/Debug/net10.0/JasperFx.dll
Executable file
Binary file not shown.
BIN
wolverine-nats/WolverineAndNats/ApiOne/bin/Debug/net10.0/Marten.dll
Executable file
BIN
wolverine-nats/WolverineAndNats/ApiOne/bin/Debug/net10.0/Marten.dll
Executable file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
wolverine-nats/WolverineAndNats/ApiOne/bin/Debug/net10.0/NATS.Client.Core.dll
Executable file
BIN
wolverine-nats/WolverineAndNats/ApiOne/bin/Debug/net10.0/NATS.Client.Core.dll
Executable file
Binary file not shown.
BIN
wolverine-nats/WolverineAndNats/ApiOne/bin/Debug/net10.0/NATS.Client.Hosting.dll
Executable file
BIN
wolverine-nats/WolverineAndNats/ApiOne/bin/Debug/net10.0/NATS.Client.Hosting.dll
Executable file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
wolverine-nats/WolverineAndNats/ApiOne/bin/Debug/net10.0/NATS.Net.dll
Executable file
BIN
wolverine-nats/WolverineAndNats/ApiOne/bin/Debug/net10.0/NATS.Net.dll
Executable file
Binary file not shown.
Binary file not shown.
BIN
wolverine-nats/WolverineAndNats/ApiOne/bin/Debug/net10.0/NetTopologySuite.dll
Executable file
BIN
wolverine-nats/WolverineAndNats/ApiOne/bin/Debug/net10.0/NetTopologySuite.dll
Executable file
Binary file not shown.
BIN
wolverine-nats/WolverineAndNats/ApiOne/bin/Debug/net10.0/NewId.dll
Executable file
BIN
wolverine-nats/WolverineAndNats/ApiOne/bin/Debug/net10.0/NewId.dll
Executable file
Binary file not shown.
BIN
wolverine-nats/WolverineAndNats/ApiOne/bin/Debug/net10.0/Newtonsoft.Json.dll
Executable file
BIN
wolverine-nats/WolverineAndNats/ApiOne/bin/Debug/net10.0/Newtonsoft.Json.dll
Executable file
Binary file not shown.
Binary file not shown.
BIN
wolverine-nats/WolverineAndNats/ApiOne/bin/Debug/net10.0/Npgsql.Json.NET.dll
Executable file
BIN
wolverine-nats/WolverineAndNats/ApiOne/bin/Debug/net10.0/Npgsql.Json.NET.dll
Executable file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
wolverine-nats/WolverineAndNats/ApiOne/bin/Debug/net10.0/Npgsql.dll
Executable file
BIN
wolverine-nats/WolverineAndNats/ApiOne/bin/Debug/net10.0/Npgsql.dll
Executable file
Binary file not shown.
Binary file not shown.
BIN
wolverine-nats/WolverineAndNats/ApiOne/bin/Debug/net10.0/OpenTelemetry.Api.dll
Executable file
BIN
wolverine-nats/WolverineAndNats/ApiOne/bin/Debug/net10.0/OpenTelemetry.Api.dll
Executable file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
wolverine-nats/WolverineAndNats/ApiOne/bin/Debug/net10.0/OpenTelemetry.dll
Executable file
BIN
wolverine-nats/WolverineAndNats/ApiOne/bin/Debug/net10.0/OpenTelemetry.dll
Executable file
Binary file not shown.
BIN
wolverine-nats/WolverineAndNats/ApiOne/bin/Debug/net10.0/Polly.Core.dll
Executable file
BIN
wolverine-nats/WolverineAndNats/ApiOne/bin/Debug/net10.0/Polly.Core.dll
Executable file
Binary file not shown.
BIN
wolverine-nats/WolverineAndNats/ApiOne/bin/Debug/net10.0/Polly.Extensions.dll
Executable file
BIN
wolverine-nats/WolverineAndNats/ApiOne/bin/Debug/net10.0/Polly.Extensions.dll
Executable file
Binary file not shown.
BIN
wolverine-nats/WolverineAndNats/ApiOne/bin/Debug/net10.0/Polly.RateLimiting.dll
Executable file
BIN
wolverine-nats/WolverineAndNats/ApiOne/bin/Debug/net10.0/Polly.RateLimiting.dll
Executable file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
wolverine-nats/WolverineAndNats/ApiOne/bin/Debug/net10.0/Spectre.Console.dll
Executable file
BIN
wolverine-nats/WolverineAndNats/ApiOne/bin/Debug/net10.0/Spectre.Console.dll
Executable file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user