diff --git a/Event Bus/MassTransit/Lab.MassTransit/Lab.MassTransit.WebAPI/Lab.MassTransit.WebAPI.csproj b/Event Bus/MassTransit/Lab.MassTransit/Lab.MassTransit.WebAPI/Lab.MassTransit.WebAPI.csproj new file mode 100644 index 00000000..72c5d824 --- /dev/null +++ b/Event Bus/MassTransit/Lab.MassTransit/Lab.MassTransit.WebAPI/Lab.MassTransit.WebAPI.csproj @@ -0,0 +1,18 @@ + + + + net8.0 + enable + enable + Linux + + + + + + + + + + + diff --git a/Event Bus/MassTransit/Lab.MassTransit/Lab.MassTransit.WebAPI/Lab.MassTransit.WebAPI.http b/Event Bus/MassTransit/Lab.MassTransit/Lab.MassTransit.WebAPI/Lab.MassTransit.WebAPI.http new file mode 100644 index 00000000..6866c1e4 --- /dev/null +++ b/Event Bus/MassTransit/Lab.MassTransit/Lab.MassTransit.WebAPI/Lab.MassTransit.WebAPI.http @@ -0,0 +1,6 @@ +@Lab.MassTransit.WebAPI_HostAddress = http://localhost:5089 + +GET {{Lab.MassTransit.WebAPI_HostAddress}}/weatherforecast/ +Accept: application/json + +### diff --git a/Event Bus/MassTransit/Lab.MassTransit/Lab.MassTransit.WebAPI/Order/CreateOrderRequest.cs b/Event Bus/MassTransit/Lab.MassTransit/Lab.MassTransit.WebAPI/Order/CreateOrderRequest.cs new file mode 100644 index 00000000..be2aea87 --- /dev/null +++ b/Event Bus/MassTransit/Lab.MassTransit/Lab.MassTransit.WebAPI/Order/CreateOrderRequest.cs @@ -0,0 +1,7 @@ +namespace Lab.MassTransit.WebAPI.Order; + +// 訂單請求 +public class CreateOrderRequest +{ + public decimal TotalAmount { get; set; } +} \ No newline at end of file diff --git a/Event Bus/MassTransit/Lab.MassTransit/Lab.MassTransit.WebAPI/Order/OrderCreated.cs b/Event Bus/MassTransit/Lab.MassTransit/Lab.MassTransit.WebAPI/Order/OrderCreated.cs new file mode 100644 index 00000000..c3c6ad2e --- /dev/null +++ b/Event Bus/MassTransit/Lab.MassTransit/Lab.MassTransit.WebAPI/Order/OrderCreated.cs @@ -0,0 +1,11 @@ +namespace Lab.MassTransit.WebAPI; + +// 訂單已建立 +public class OrderCreated +{ + public Guid OrderId { get; set; } + + public DateTime CreatedAt { get; set; } + + public decimal TotalAmount { get; set; } +} \ No newline at end of file diff --git a/Event Bus/MassTransit/Lab.MassTransit/Lab.MassTransit.WebAPI/Order/OrderCreatedConsumer.cs b/Event Bus/MassTransit/Lab.MassTransit/Lab.MassTransit.WebAPI/Order/OrderCreatedConsumer.cs new file mode 100644 index 00000000..afcdcbcc --- /dev/null +++ b/Event Bus/MassTransit/Lab.MassTransit/Lab.MassTransit.WebAPI/Order/OrderCreatedConsumer.cs @@ -0,0 +1,12 @@ +using MassTransit; + +namespace Lab.MassTransit.WebAPI; + +public class OrderCreatedConsumer : IConsumer +{ + public Task Consume(ConsumeContext context) + { + Console.WriteLine($"Order created: {context.Message.OrderId}, Total Amount: {context.Message.TotalAmount}"); + return Task.CompletedTask; + } +} \ No newline at end of file diff --git a/Event Bus/MassTransit/Lab.MassTransit/Lab.MassTransit.WebAPI/Order/OrdersController.cs b/Event Bus/MassTransit/Lab.MassTransit/Lab.MassTransit.WebAPI/Order/OrdersController.cs new file mode 100644 index 00000000..bbd71fbd --- /dev/null +++ b/Event Bus/MassTransit/Lab.MassTransit/Lab.MassTransit.WebAPI/Order/OrdersController.cs @@ -0,0 +1,36 @@ +using MassTransit; +using Microsoft.AspNetCore.Mvc; + +namespace Lab.MassTransit.WebAPI.Order; + +[ApiController] +[Route("api/[controller]")] +public class OrdersController : ControllerBase +{ + private readonly IPublishEndpoint _publishEndpoint; + public OrdersController(IPublishEndpoint publishEndpoint) + { + this._publishEndpoint = publishEndpoint; + } + + [HttpPost] + public async Task CreateOrder([FromBody] CreateOrderRequest request) + { + if (request == null) + { + return this.BadRequest("Invalid order data"); + } + + var orderCreatedEvent = new OrderCreated + { + OrderId = Guid.NewGuid(), + CreatedAt = DateTime.UtcNow, + TotalAmount = request.TotalAmount + }; + + // 生產者,發布 OrderCreated 事件 + await this._publishEndpoint.Publish(orderCreatedEvent); + + return this.Ok($"Order created with ID: {orderCreatedEvent.OrderId}"); + } +} \ No newline at end of file diff --git a/Event Bus/MassTransit/Lab.MassTransit/Lab.MassTransit.WebAPI/Program.cs b/Event Bus/MassTransit/Lab.MassTransit/Lab.MassTransit.WebAPI/Program.cs new file mode 100644 index 00000000..f4482a7b --- /dev/null +++ b/Event Bus/MassTransit/Lab.MassTransit/Lab.MassTransit.WebAPI/Program.cs @@ -0,0 +1,44 @@ +using Lab.MassTransit.WebAPI; +using MassTransit; + +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(); + +builder.Services.AddMassTransit(x => +{ + // 註冊消費者 + x.AddConsumer(); + + // 配置 MassTransit 使用 RabbitMQ + x.UsingRabbitMq((context, config) => + { + config.Host("localhost", "/", h => + { + h.Username("guest"); + h.Password("guest"); + }); + // 註冊消費者 + config.ReceiveEndpoint("order/created/event", e => { e.ConfigureConsumer(context); }); + }); +}); +builder.Services.AddControllers(); +var app = builder.Build(); + +// Configure the HTTP request pipeline. +if (app.Environment.IsDevelopment()) +{ + app.UseSwagger(); + app.UseSwaggerUI(); +} + +// 使用中介軟體和路由 +app.UseRouting(); +app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); + +app.UseHttpsRedirection(); + +app.Run(); \ No newline at end of file diff --git a/Event Bus/MassTransit/Lab.MassTransit/Lab.MassTransit.WebAPI/Properties/launchSettings.json b/Event Bus/MassTransit/Lab.MassTransit/Lab.MassTransit.WebAPI/Properties/launchSettings.json new file mode 100644 index 00000000..939c798a --- /dev/null +++ b/Event Bus/MassTransit/Lab.MassTransit/Lab.MassTransit.WebAPI/Properties/launchSettings.json @@ -0,0 +1,41 @@ +{ + "$schema": "http://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:65484", + "sslPort": 44345 + } + }, + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "http://localhost:5089", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "https://localhost:7293;http://localhost:5089", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/Event Bus/MassTransit/Lab.MassTransit/Lab.MassTransit.WebAPI/appsettings.Development.json b/Event Bus/MassTransit/Lab.MassTransit/Lab.MassTransit.WebAPI/appsettings.Development.json new file mode 100644 index 00000000..0c208ae9 --- /dev/null +++ b/Event Bus/MassTransit/Lab.MassTransit/Lab.MassTransit.WebAPI/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/Event Bus/MassTransit/Lab.MassTransit/Lab.MassTransit.WebAPI/appsettings.json b/Event Bus/MassTransit/Lab.MassTransit/Lab.MassTransit.WebAPI/appsettings.json new file mode 100644 index 00000000..10f68b8c --- /dev/null +++ b/Event Bus/MassTransit/Lab.MassTransit/Lab.MassTransit.WebAPI/appsettings.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +} diff --git a/Event Bus/MassTransit/Lab.MassTransit/Lab.MassTransit.sln b/Event Bus/MassTransit/Lab.MassTransit/Lab.MassTransit.sln new file mode 100644 index 00000000..10e3faba --- /dev/null +++ b/Event Bus/MassTransit/Lab.MassTransit/Lab.MassTransit.sln @@ -0,0 +1,21 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lab.MassTransit.WebAPI", "Lab.MassTransit.WebAPI\Lab.MassTransit.WebAPI.csproj", "{626813B6-52DA-479B-A50B-94E364E63F3C}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{34BE7295-45E2-45CE-997C-3A9F533583A5}" + ProjectSection(SolutionItems) = preProject + docker-compose.yml = docker-compose.yml + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {626813B6-52DA-479B-A50B-94E364E63F3C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {626813B6-52DA-479B-A50B-94E364E63F3C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {626813B6-52DA-479B-A50B-94E364E63F3C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {626813B6-52DA-479B-A50B-94E364E63F3C}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/Event Bus/MassTransit/Lab.MassTransit/docker-compose.yml b/Event Bus/MassTransit/Lab.MassTransit/docker-compose.yml new file mode 100644 index 00000000..2fdef00c --- /dev/null +++ b/Event Bus/MassTransit/Lab.MassTransit/docker-compose.yml @@ -0,0 +1,11 @@ +version: '3.8' +services: + rabbitmq: + container_name: rabbitmq.3 + image: "rabbitmq:3-management" + ports: + - "5672:5672" # RabbitMQ 主要連接埠 + - "15672:15672" # 管理介面連接埠 + environment: + RABBITMQ_DEFAULT_USER: guest + RABBITMQ_DEFAULT_PASS: guest