Merge pull request #4 from bradLucifer/Net6MicroSrvSample

Net6 micro srv sample
This commit is contained in:
Hananiel Sarella 2022-09-16 11:27:06 -04:00 коммит произвёл GitHub
Родитель 574d0bd9fa cf3194bfa0
Коммит ab38fbb50a
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
17 изменённых файлов: 407 добавлений и 0 удалений

Просмотреть файл

@ -0,0 +1,56 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.1.32407.343
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{D82D5D8A-3C60-432D-9610-A6BFC3E5BB84}"
ProjectSection(SolutionItems) = preProject
ReadMe.md = ReadMe.md
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "BuildingBlocks", "BuildingBlocks", "{021EEF99-06BF-4F19-9BEB-E2297B63B492}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Product", "Product", "{6B290421-6698-4C4C-B91A-C5E5F4D7C31A}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Notification", "Notification", "{7319FDC9-68D0-4036-BC79-23E9818C1593}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Common.SeedWork", "src\BuildingBlocks\Common.SeedWork\Common.SeedWork.csproj", "{696B4E8C-D786-46C4-AA6A-FF725303C617}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Notification.API", "src\Notification\Notification.API\Notification.API.csproj", "{7AF99C5B-99F5-42A0-902C-5BDF5AFA9244}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Product.API", "src\Product\Product.API\Product.API.csproj", "{B00D5394-34AC-4261-9243-414F7782CB05}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{696B4E8C-D786-46C4-AA6A-FF725303C617}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{696B4E8C-D786-46C4-AA6A-FF725303C617}.Debug|Any CPU.Build.0 = Debug|Any CPU
{696B4E8C-D786-46C4-AA6A-FF725303C617}.Release|Any CPU.ActiveCfg = Release|Any CPU
{696B4E8C-D786-46C4-AA6A-FF725303C617}.Release|Any CPU.Build.0 = Release|Any CPU
{7AF99C5B-99F5-42A0-902C-5BDF5AFA9244}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7AF99C5B-99F5-42A0-902C-5BDF5AFA9244}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7AF99C5B-99F5-42A0-902C-5BDF5AFA9244}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7AF99C5B-99F5-42A0-902C-5BDF5AFA9244}.Release|Any CPU.Build.0 = Release|Any CPU
{B00D5394-34AC-4261-9243-414F7782CB05}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B00D5394-34AC-4261-9243-414F7782CB05}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B00D5394-34AC-4261-9243-414F7782CB05}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B00D5394-34AC-4261-9243-414F7782CB05}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{021EEF99-06BF-4F19-9BEB-E2297B63B492} = {D82D5D8A-3C60-432D-9610-A6BFC3E5BB84}
{6B290421-6698-4C4C-B91A-C5E5F4D7C31A} = {D82D5D8A-3C60-432D-9610-A6BFC3E5BB84}
{7319FDC9-68D0-4036-BC79-23E9818C1593} = {D82D5D8A-3C60-432D-9610-A6BFC3E5BB84}
{696B4E8C-D786-46C4-AA6A-FF725303C617} = {021EEF99-06BF-4F19-9BEB-E2297B63B492}
{7AF99C5B-99F5-42A0-902C-5BDF5AFA9244} = {7319FDC9-68D0-4036-BC79-23E9818C1593}
{B00D5394-34AC-4261-9243-414F7782CB05} = {6B290421-6698-4C4C-B91A-C5E5F4D7C31A}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {E872E6C6-F1F8-4377-9968-08A6148E0674}
EndGlobalSection
EndGlobal

Просмотреть файл

@ -0,0 +1,43 @@

## Basic App Flow:
1. RabbitMQ should be installed. If not then see this link https://medium.com/se.ahmedanwar/rabbitmq-installation-windows-e2072f60afe9
2. In this example, we have setup a microservices architecture to understand the flow more easily and there are also some keypoints that I have noticed which I will share.
There are two microservices
- Product.API
- Notification.API
When a request comes to `Product.API` to add a product, a notification will be generated by `Notification.API`. `Notification.API `will not be called directly hence we have used `RabbitMQ` to follow a event driven architecture.
## GuidLines:
1. In `Program.cs`, if you have used below method then configuration for RabbitMQ from `appSettings.{env}.json` will be picked:
`builder.Services.ConfigureRabbitOptions(config);`
- If you dont use that method then there is no need to specify any configuration in `appSettings.{env}.json` until you have RabbitMQ running on
default url with default credentials.
- If you call that method but did not specify anything in appsettings.env.json then it will not throw any error and will pick default
credentials automatically
**URL:**```http://localhost:15672/```
**UserName:**```guest```
**Password:**```guest```
2. ##### JSON serialization
With `true` param JSON serialization will be used:
`builder.Services.AddRabbitServices(true);`
------------

Просмотреть файл

@ -0,0 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>

Просмотреть файл

@ -0,0 +1,10 @@
using System;
namespace Common.SeedWork
{
public class Message
{
public string Type { get; set; }
public string Body { get; set; }
}
}

Просмотреть файл

@ -0,0 +1,11 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Common.SeedWork
{
public static class Queues
{
public const string ProductAddQueue = nameof(ProductAddQueue);
}
}

Просмотреть файл

@ -0,0 +1,21 @@
using Common.SeedWork;
using Steeltoe.Messaging.RabbitMQ.Attributes;
namespace Notification.API
{
public class ListenerService
{
private ILogger _logger;
public ListenerService(ILogger<ListenerService> logger)
{
_logger = logger;
}
[RabbitListener(Queues.ProductAddQueue)]
public void ListenForAMessage(Message msg)
{
_logger.LogInformation($"Received the message '{msg}' from the queue.");
}
}
}

Просмотреть файл

@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Steeltoe.Messaging.RabbitMQ" Version="3.2.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\BuildingBlocks\Common.SeedWork\Common.SeedWork.csproj" />
</ItemGroup>
</Project>

Просмотреть файл

@ -0,0 +1,47 @@
using Common.SeedWork;
using Notification.API;
using Steeltoe.Messaging.RabbitMQ.Config;
using Steeltoe.Messaging.RabbitMQ.Extensions;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
#region Services
// Add singleton that will process incoming messages
builder.Services.AddSingleton<ListenerService>();
#endregion
#region SteelToeRabbitMQ Configuration
// Add Steeltoe Rabbit services, use JSON serialization
builder.Services.AddRabbitServices(true);
// Add Steeltoe RabbitAdmin services to get queues declared
builder.Services.AddRabbitAdmin();
// Add Steeltoe RabbitTemplate for sending/receiving
builder.Services.AddRabbitTemplate();
// Add a queue to the message container that the rabbit admin will discover and declare at startup
builder.Services.AddRabbitQueue(new Queue(Queues.ProductAddQueue));
// Tell steeltoe about singleton so it can wire up queues with methods to process queues
builder.Services.AddRabbitListeners<ListenerService>();
#endregion
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.Run();

Просмотреть файл

@ -0,0 +1,31 @@
{
"$schema": "https://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:24762",
"sslPort": 44336
}
},
"profiles": {
"Notification.API": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "https://localhost:7167;http://localhost:5167",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

Просмотреть файл

@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}

Просмотреть файл

@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}

Просмотреть файл

@ -0,0 +1,9 @@
namespace Product.API.Models.Requests
{
public record AddProductRequestDTO
{
public string Name { get; set; }
public decimal Price { get; set; }
public string Description { get; set; }
}
}

Просмотреть файл

@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Steeltoe.Messaging.RabbitMQ" Version="3.2.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" />
</ItemGroup>
<ItemGroup>
<Folder Include="Models\Responses\" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\BuildingBlocks\Common.SeedWork\Common.SeedWork.csproj" />
</ItemGroup>
</Project>

Просмотреть файл

@ -0,0 +1,61 @@
using Common.SeedWork;
using Product.API.Models.Requests;
using Steeltoe.Messaging.RabbitMQ.Config;
using Steeltoe.Messaging.RabbitMQ.Core;
using Steeltoe.Messaging.RabbitMQ.Extensions;
var builder = WebApplication.CreateBuilder(args);
// Build a config object, using env vars and JSON providers.
IConfiguration config = new ConfigurationBuilder()
.AddJsonFile($"appsettings.{builder.Environment.EnvironmentName}.json")
.AddEnvironmentVariables()
.Build();
// Add services to the container.
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
#region SteelToeRabbitMQ Configuration
//When you call ConfigureRabbitOptions method then appsettings.env.json specified connection configuration will be applied otherwise
//if you dont call that method then default settings will be picked and even you dont need to specify any configuration in appsettings
//if you call that method but did not specify anything in appsettings.env.json then it will not throw any error and will pick default
//credentials automatically
builder.Services.ConfigureRabbitOptions(config);
// Add Steeltoe Rabbit services, use JSON serialization
builder.Services.AddRabbitServices(true);
// Add Steeltoe RabbitAdmin services to get queues declared
builder.Services.AddRabbitAdmin();
// Add Steeltoe RabbitTemplate for sending/receiving
builder.Services.AddRabbitTemplate();
// Add a queue to the message container that the rabbit admin will discover and declare at startup
builder.Services.AddRabbitQueue(new Queue(Queues.ProductAddQueue));
#endregion
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.MapPost("/product", async (AddProductRequestDTO request, RabbitTemplate _rabbitTemplate, RabbitAdmin _rabbitAdmin
,CancellationToken cancellationToken) =>
{
var msg = new Message() {Type="Information", Body = "Hi there from over here." };
_rabbitTemplate.ConvertAndSendAsync(Queues.ProductAddQueue, msg, cancellationToken);
return Results.Ok("Product Added Successfully");
})
.WithName("GetWeatherForecast");
app.Run();

Просмотреть файл

@ -0,0 +1,31 @@
{
"$schema": "https://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:1147",
"sslPort": 44301
}
},
"profiles": {
"Product.API": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "https://localhost:7000;http://localhost:5000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

Просмотреть файл

@ -0,0 +1,13 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"Spring": {
"RabbitMq": {
"Addresses": "amqp://admin:secret@localhost"
}
}
}

Просмотреть файл

@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}