Skip to content

Commit f04f17b

Browse files
authored
Merge pull request #107 from wooln/feature/unit-test-MSG-delayed-consum
Feature/unit test msg delayed consum
2 parents ba01fed + b8ba2d4 commit f04f17b

18 files changed

Lines changed: 399 additions & 49 deletions

File tree

.github/workflows/build_and_it.yml

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,16 +56,24 @@ jobs:
5656
curl "127.0.0.1:36789/api/dtmsvr/newGid"
5757
- name: Setup Busi Service
5858
run: |
59-
cd tests/BusiGrpcService
59+
cd tests/BusiIntegrationService
6060
nohup dotnet run > /home/runner/work/client-csharp/client-csharp/logs/app.log 2>&1 &
61-
- name: Run Integration Tests
61+
- name: Run Integration Tests (Dtmgrpc)
6262
env:
6363
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1
6464
DOTNET_NOLOGO: 1
6565
DOTNET_CLI_HOME: ${{ runner.temp }}/dotnet-cli-home
6666
run: |
6767
dotnet build tests/Dtmgrpc.IntegrationTests/Dtmgrpc.IntegrationTests.csproj
6868
dotnet test --framework=net8.0 tests/Dtmgrpc.IntegrationTests/Dtmgrpc.IntegrationTests.csproj
69+
- name: Run Integration Tests (Dtmcli)
70+
env:
71+
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1
72+
DOTNET_NOLOGO: 1
73+
DOTNET_CLI_HOME: ${{ runner.temp }}/dotnet-cli-home
74+
run: |
75+
dotnet build tests/Dtmcli.IntegrationTests/Dtmcli.IntegrationTests.csproj
76+
dotnet test --framework=net8.0 tests/Dtmcli.IntegrationTests/Dtmcli.IntegrationTests.csproj
6977
- name: Upload logs
7078
if: always()
7179
uses: actions/upload-artifact@v4

DtmClient.sln

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{AFCF4E29-660
2525
EndProject
2626
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{ED5B84F1-876F-4617-A4F4-5C160319310C}"
2727
EndProject
28-
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BusiGrpcService", "tests\BusiGrpcService\BusiGrpcService.csproj", "{FFF41358-6974-4E87-840D-C61E1B6BEDC3}"
28+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BusiIntegrationService", "tests\BusiIntegrationService\BusiIntegrationService.csproj", "{FFF41358-6974-4E87-840D-C61E1B6BEDC3}"
2929
EndProject
3030
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dtmgrpc.IntegrationTests", "tests\Dtmgrpc.IntegrationTests\Dtmgrpc.IntegrationTests.csproj", "{AFDB3DCD-55CE-402F-A1B0-FCD4737FE314}"
3131
EndProject
@@ -47,6 +47,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dtmgrpc.StrongName", "src\s
4747
EndProject
4848
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dtmworkflow.StrongName", "src\strong-name\Dtmworkflow.StrongName\Dtmworkflow.StrongName.csproj", "{96634D84-A11E-448C-8033-CC643F96558A}"
4949
EndProject
50+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dtmcli.IntegrationTests", "tests\Dtmcli.IntegrationTests\Dtmcli.IntegrationTests.csproj", "{500E31D7-71A3-4DE6-8CFF-8AEB416A968F}"
51+
EndProject
5052
Global
5153
GlobalSection(SolutionConfigurationPlatforms) = preSolution
5254
Debug|Any CPU = Debug|Any CPU
@@ -125,6 +127,10 @@ Global
125127
{96634D84-A11E-448C-8033-CC643F96558A}.Debug|Any CPU.Build.0 = Debug|Any CPU
126128
{96634D84-A11E-448C-8033-CC643F96558A}.Release|Any CPU.ActiveCfg = Release|Any CPU
127129
{96634D84-A11E-448C-8033-CC643F96558A}.Release|Any CPU.Build.0 = Release|Any CPU
130+
{500E31D7-71A3-4DE6-8CFF-8AEB416A968F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
131+
{500E31D7-71A3-4DE6-8CFF-8AEB416A968F}.Debug|Any CPU.Build.0 = Debug|Any CPU
132+
{500E31D7-71A3-4DE6-8CFF-8AEB416A968F}.Release|Any CPU.ActiveCfg = Release|Any CPU
133+
{500E31D7-71A3-4DE6-8CFF-8AEB416A968F}.Release|Any CPU.Build.0 = Release|Any CPU
128134
EndGlobalSection
129135
GlobalSection(SolutionProperties) = preSolution
130136
HideSolutionNode = FALSE
@@ -149,6 +155,7 @@ Global
149155
{3196931A-26B1-4C48-BA66-003356153C34} = {A8DF688D-43CE-4227-B5FD-F65760DE7967}
150156
{60051A80-A987-43B7-A5D1-284B8FD330D4} = {A8DF688D-43CE-4227-B5FD-F65760DE7967}
151157
{96634D84-A11E-448C-8033-CC643F96558A} = {A8DF688D-43CE-4227-B5FD-F65760DE7967}
158+
{500E31D7-71A3-4DE6-8CFF-8AEB416A968F} = {ED5B84F1-876F-4617-A4F4-5C160319310C}
152159
EndGlobalSection
153160
GlobalSection(ExtensibilityGlobals) = postSolution
154161
SolutionGuid = {A872C3EE-D0B6-4943-8C7D-9ADD28AC029A}

tests/BusiGrpcService/Program.cs

Lines changed: 0 additions & 25 deletions
This file was deleted.

tests/BusiGrpcService/appsettings.json

Lines changed: 0 additions & 15 deletions
This file was deleted.

tests/BusiGrpcService/BusiGrpcService.csproj renamed to tests/BusiIntegrationService/BusiIntegrationService.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
<TargetFramework>net8.0</TargetFramework>
55
<!--<Nullable>enable</Nullable>-->
66
<ImplicitUsings>enable</ImplicitUsings>
7+
<RootNamespace>BusiIntegrationService</RootNamespace>
78
</PropertyGroup>
89

910
<ItemGroup>
@@ -12,6 +13,7 @@
1213
</ItemGroup>
1314

1415
<ItemGroup>
16+
<ProjectReference Include="..\..\src\Dtmcli\Dtmcli.csproj" />
1517
<ProjectReference Include="..\..\src\Dtmgrpc\Dtmgrpc.csproj" />
1618
<ProjectReference Include="..\..\src\DtmSERedisBarrier\DtmSERedisBarrier.csproj" />
1719
</ItemGroup>
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
using System.Text.Json;
2+
using BusiIntegrationService.Dtos;
3+
using Microsoft.AspNetCore.Mvc;
4+
5+
namespace BusiIntegrationService.Controllers
6+
{
7+
[ApiController]
8+
[Route("http/busi.Busi")]
9+
public class BusiApiController : ControllerBase
10+
{
11+
private readonly ILogger<BusiApiController> _logger;
12+
private readonly Dtmcli.IBranchBarrierFactory _barrierFactory;
13+
private readonly Dtmgrpc.IBranchBarrierFactory _grpcBarrierFactory;
14+
15+
public BusiApiController(ILogger<BusiApiController> logger, Dtmcli.IBranchBarrierFactory barrierFactory, Dtmgrpc.IBranchBarrierFactory grpcBarrierFactory)
16+
{
17+
_logger = logger;
18+
_barrierFactory = barrierFactory;
19+
_grpcBarrierFactory = grpcBarrierFactory;
20+
}
21+
22+
[HttpGet("Test")]
23+
public async Task<IActionResult> Test()
24+
{
25+
return this.Ok(nameof(this.Test));
26+
}
27+
28+
[HttpPost("TransIn")]
29+
public async Task<IActionResult> TransIn([FromBody] BusiRequest request)
30+
{
31+
_logger.LogInformation("TransIn req={req}", JsonSerializer.Serialize(request));
32+
33+
if (DateTime.Now < request.EffectTime)
34+
return this.StatusCode(425, new { error = "Early" });
35+
36+
if (string.IsNullOrWhiteSpace(request.TransInResult) || request.TransInResult.Equals("SUCCESS"))
37+
{
38+
await Task.CompletedTask;
39+
return Ok();
40+
}
41+
else if (request.TransInResult.Equals("FAILURE"))
42+
{
43+
return StatusCode(422, new { error = "FAILURE" }); // 422 Unprocessable Entity for business failure
44+
}
45+
else if (request.TransInResult.Equals("ONGOING"))
46+
{
47+
return StatusCode(425, new { error = "ONGOING" }); // 425 Too Early for ongoing state
48+
}
49+
50+
return StatusCode(500, new { error = $"unknown result {request.TransInResult}" });
51+
}
52+
53+
[HttpPost("TransOut")]
54+
public async Task<IActionResult> TransOut([FromBody] BusiRequest request)
55+
{
56+
_logger.LogInformation("TransOut req={req}", JsonSerializer.Serialize(request));
57+
58+
if (DateTime.Now < request.EffectTime)
59+
return this.StatusCode(425, new { error = "Early" });
60+
61+
if (string.IsNullOrWhiteSpace(request.TransOutResult) || request.TransOutResult.Equals("SUCCESS"))
62+
{
63+
await Task.CompletedTask;
64+
return Ok();
65+
}
66+
else if (request.TransOutResult.Equals("FAILURE"))
67+
{
68+
return StatusCode(422, new { error = "FAILURE" }); // 422 Unprocessable Entity for business failure
69+
}
70+
else if (request.TransOutResult.Equals("ONGOING"))
71+
{
72+
return StatusCode(425, new { error = "ONGOING" }); // 425 Too Early for ongoing state
73+
}
74+
75+
return StatusCode(500, new { error = $"unknown result {request.TransOutResult}" });
76+
}
77+
}
78+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
using System.Text.Json.Serialization;
2+
3+
namespace BusiIntegrationService.Dtos
4+
{
5+
public class BusiRequest
6+
{
7+
[JsonPropertyName("amount")]
8+
public long Amount { get; set; }
9+
10+
[JsonPropertyName("transOutResult")]
11+
public string TransOutResult { get; set; } = string.Empty;
12+
13+
[JsonPropertyName("transInResult")]
14+
public string TransInResult { get; set; } = string.Empty;
15+
16+
[JsonPropertyName("effectTime")] public DateTime EffectTime { get; set; }
17+
}
18+
19+
public class BusiReply
20+
{
21+
[JsonPropertyName("message")]
22+
public string Message { get; set; } = string.Empty;
23+
}
24+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using BusiIntegrationService;
2+
using BusiIntegrationService.Services;
3+
using Dtmcli;
4+
using Dtmgrpc;
5+
using Microsoft.AspNetCore.Server.Kestrel.Core;
6+
7+
// Enable HTTP/2 support for unencrypted HTTP connections (required for gRPC over HTTP)
8+
AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
9+
10+
var builder = WebApplication.CreateBuilder(args);
11+
12+
builder.Services.AddGrpc(options =>
13+
{
14+
// Configure gRPC to allow unencrypted HTTP/2 connections (for local development)
15+
options.EnableDetailedErrors = true;
16+
});
17+
builder.Services.AddDtmGrpc(x =>
18+
{
19+
x.DtmGrpcUrl = "http://localhost:36790";
20+
});
21+
builder.Services.AddDtmcli(option =>
22+
{
23+
option.DtmUrl = "http://localhost:36789";
24+
});
25+
26+
// Add controllers for HTTP API
27+
builder.Services.AddControllers();
28+
29+
var app = builder.Build();
30+
31+
// Configure the HTTP request pipeline.
32+
app.MapGrpcService<BusiApiService>();
33+
app.MapControllers(); // Map the HTTP API controllers
34+
app.MapGet("/", () => "Communication with gRPC endpoints must be made through a gRPC client. To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909");
35+
36+
app.Run();

tests/BusiGrpcService/Properties/launchSettings.json renamed to tests/BusiIntegrationService/Properties/launchSettings.json

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
{
22
"profiles": {
3-
"BusiGrpcService": {
3+
"BusiIntegrationService": {
44
"commandName": "Project",
55
"dotnetRunMessages": true,
66
"launchBrowser": false,
7-
"applicationUrl": "http://localhost:5251;https://localhost:7251",
87
"environmentVariables": {
98
"ASPNETCORE_ENVIRONMENT": "Development"
109
}
1110
}
1211
}
13-
}
12+
}

tests/BusiGrpcService/Services/BusiApiService.cs renamed to tests/BusiIntegrationService/Services/BusiApiService.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
using DtmCommon;
99
using DtmSERedisBarrier;
1010

11-
namespace BusiGrpcService.Services
11+
namespace BusiIntegrationService.Services
1212
{
1313
public class BusiApiService : Busi.BusiBase
1414
{
@@ -27,6 +27,9 @@ public BusiApiService(ILogger<BusiApiService> logger, Dtmgrpc.IDtmgRPCClient cli
2727
public override async Task<Empty> TransIn(BusiReq request, ServerCallContext context)
2828
{
2929
_logger.LogInformation("TransIn req={req}", JsonSerializer.Serialize(request));
30+
31+
if (request.EffectTime != null && DateTime.UtcNow < request.EffectTime.ToDateTime())
32+
throw new Grpc.Core.RpcException(new Status(StatusCode.FailedPrecondition, "ONGOING"));
3033

3134
if (string.IsNullOrWhiteSpace(request.TransInResult) || request.TransInResult.Equals("SUCCESS"))
3235
{
@@ -49,6 +52,9 @@ public override async Task<Empty> TransInTcc(BusiReq request, ServerCallContext
4952
{
5053
_logger.LogInformation("TransIn req={req}", JsonSerializer.Serialize(request));
5154

55+
if (request.EffectTime != null && request.EffectTime.ToDateTime() < DateTime.Now)
56+
throw new Grpc.Core.RpcException(new Status(StatusCode.FailedPrecondition, "ONGOING"));
57+
5258
if (string.IsNullOrWhiteSpace(request.TransInResult) || request.TransInResult.Equals("SUCCESS"))
5359
{
5460
await Task.CompletedTask;
@@ -87,6 +93,10 @@ public override async Task<Empty> TransInRevert(BusiReq request, ServerCallConte
8793
public override async Task<Empty> TransOut(BusiReq request, ServerCallContext context)
8894
{
8995
_logger.LogInformation("TransOut req={req}", JsonSerializer.Serialize(request));
96+
97+
if (request.EffectTime != null && DateTime.UtcNow < request.EffectTime.ToDateTime())
98+
throw new Grpc.Core.RpcException(new Status(StatusCode.FailedPrecondition, "ONGOING"));
99+
90100
await Task.CompletedTask;
91101
return new Empty();
92102
}

0 commit comments

Comments
 (0)