diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 103a984..fd66366 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -28,6 +28,10 @@ jobs: dotnet --list-runtimes - name: Build with dotnet + env: + DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1 + DOTNET_NOLOGO: 1 + DOTNET_CLI_HOME: ${{ runner.temp }}/dotnet-cli-home run: | dotnet build DtmClient.sln @@ -44,6 +48,10 @@ jobs: # dotnet test --framework=net6.0 tests/Dtmworkflow.Tests/Dtmworkflow.Tests.csproj --collect:"XPlat Code Coverage" - name: Run tests on net8.0 + env: + DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1 + DOTNET_NOLOGO: 1 + DOTNET_CLI_HOME: ${{ runner.temp }}/dotnet-cli-home run: | dotnet test --framework=net8.0 tests/Dtmcli.Tests/Dtmcli.Tests.csproj --collect:"XPlat Code Coverage" dotnet test --framework=net8.0 tests/Dtmgrpc.Tests/Dtmgrpc.Tests.csproj --collect:"XPlat Code Coverage" @@ -68,4 +76,4 @@ jobs: fail_ci_if_error: true files: ${{ github.workspace }}/coverage/cli.xml,${{ github.workspace }}/coverage/grpc.xml,${{ github.workspace }}/coverage/wf.xml name: codecov-dtm-client-csharp - verbose: true + verbose: true \ No newline at end of file diff --git a/.github/workflows/build_and_it.yml b/.github/workflows/build_and_it.yml index d5fafaf..30895bf 100644 --- a/.github/workflows/build_and_it.yml +++ b/.github/workflows/build_and_it.yml @@ -59,6 +59,10 @@ jobs: cd tests/BusiGrpcService nohup dotnet run > /home/runner/work/client-csharp/client-csharp/logs/app.log 2>&1 & - name: Run Integration Tests + env: + DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1 + DOTNET_NOLOGO: 1 + DOTNET_CLI_HOME: ${{ runner.temp }}/dotnet-cli-home run: | dotnet build tests/Dtmgrpc.IntegrationTests/Dtmgrpc.IntegrationTests.csproj dotnet test --framework=net8.0 tests/Dtmgrpc.IntegrationTests/Dtmgrpc.IntegrationTests.csproj @@ -67,4 +71,4 @@ jobs: uses: actions/upload-artifact@v4 with: name: dtm-logs - path: /home/runner/work/client-csharp/client-csharp/logs + path: /home/runner/work/client-csharp/client-csharp/logs \ No newline at end of file diff --git a/.github/workflows/release_stable.yml b/.github/workflows/release_stable.yml index 93d1eff..717a008 100644 --- a/.github/workflows/release_stable.yml +++ b/.github/workflows/release_stable.yml @@ -17,6 +17,10 @@ jobs: with: dotnet-version: 8.0.x - name: Build with dotnet + env: + DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1 + DOTNET_NOLOGO: 1 + DOTNET_CLI_HOME: ${{ runner.temp }}/dotnet-cli-home run: | dotnet build --configuration Release --source https://api.nuget.org/v3/index.json src/Dtmcli/Dtmcli.csproj dotnet build --configuration Release --source https://api.nuget.org/v3/index.json src/strong-name/Dtmcli.StrongName/Dtmcli.StrongName.csproj @@ -30,6 +34,10 @@ jobs: dotnet build --configuration Release --source https://api.nuget.org/v3/index.json src/Dtmworkflow/Dtmworkflow.csproj dotnet build --configuration Release --source https://api.nuget.org/v3/index.json src/strong-name/Dtmworkflow.StrongName/Dtmworkflow.StrongName.csproj - name: Pack with dotnet + env: + DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1 + DOTNET_NOLOGO: 1 + DOTNET_CLI_HOME: ${{ runner.temp }}/dotnet-cli-home run: | dotnet pack src/Dtmcli/Dtmcli.csproj -o /home/runner/work/nugetpkgs -c Release --no-build dotnet pack src/strong-name/Dtmcli.StrongName/Dtmcli.StrongName.csproj -o /home/runner/work/nugetpkgs -c Release --no-build @@ -62,8 +70,12 @@ jobs: - name: list nugetpkgs run: ls nugetpkgs - name: Release + env: + DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1 + DOTNET_NOLOGO: 1 + DOTNET_CLI_HOME: ${{ runner.temp }}/dotnet-cli-home run: | for file in nugetpkgs/*.nupkg do dotnet nuget push $file -k ${{ secrets.NUGET_API_KEY }} --skip-duplicate -s https://www.nuget.org/api/v2/package - done + done \ No newline at end of file diff --git a/.github/workflows/release_unstable.yml b/.github/workflows/release_unstable.yml index d2bac59..8cb3539 100644 --- a/.github/workflows/release_unstable.yml +++ b/.github/workflows/release_unstable.yml @@ -17,6 +17,10 @@ jobs: with: dotnet-version: 8.0.x - name: Build with dotnet + env: + DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1 + DOTNET_NOLOGO: 1 + DOTNET_CLI_HOME: ${{ runner.temp }}/dotnet-cli-home run: | dotnet build --configuration Release --source https://api.nuget.org/v3/index.json src/Dtmcli/Dtmcli.csproj dotnet build --configuration Release --source https://api.nuget.org/v3/index.json src/strong-name/Dtmcli.StrongName/Dtmcli.StrongName.csproj @@ -30,6 +34,10 @@ jobs: dotnet build --configuration Release --source https://api.nuget.org/v3/index.json src/Dtmworkflow/Dtmworkflow.csproj dotnet build --configuration Release --source https://api.nuget.org/v3/index.json src/strong-name/Dtmworkflow.StrongName/Dtmworkflow.StrongName.csproj - name: Pack with dotnet + env: + DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1 + DOTNET_NOLOGO: 1 + DOTNET_CLI_HOME: ${{ runner.temp }}/dotnet-cli-home run: | ver=alpha`date +%Y%m%d%H%M%S` dotnet pack src/Dtmcli/Dtmcli.csproj --version-suffix $ver -o /home/runner/work/nugetpkgs -c Release --no-build @@ -63,8 +71,12 @@ jobs: - name: list nugetpkgs run: ls nugetpkgs - name: Release + env: + DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1 + DOTNET_NOLOGO: 1 + DOTNET_CLI_HOME: ${{ runner.temp }}/dotnet-cli-home run: | for file in nugetpkgs/*.nupkg do dotnet nuget push $file -k ${{ secrets.NUGET_API_KEY }} --skip-duplicate -s https://www.nuget.org/api/v2/package - done + done \ No newline at end of file diff --git a/samples/DtmSample/Controllers/WfTestController.cs b/samples/DtmSample/Controllers/WfTestController.cs index 614e969..c1e7d5a 100644 --- a/samples/DtmSample/Controllers/WfTestController.cs +++ b/samples/DtmSample/Controllers/WfTestController.cs @@ -7,12 +7,10 @@ using Microsoft.Extensions.Options; using System; using System.IO; -using System.Diagnostics; using System.Net.Http; using System.Net.Http.Headers; using System.Text; using System.Text.Json; -using System.Text.Unicode; using System.Threading; using System.Threading.Tasks; using Exception = System.Exception; @@ -257,5 +255,84 @@ public async Task TccRollBack(CancellationToken cancellationToken return Ok(TransResponse.BuildFailureResponse()); } } + + + private static readonly string wfNameForResume = "wfNameForResume"; + + /// + /// + /// + /// + /// + [HttpPost("wf-crash")] + public async Task Crash(CancellationToken cancellationToken) + { + if (!_globalTransaction.Exists(wfNameForResume)) + { + _globalTransaction.Register(wfNameForResume, async (wf, data) => + { + var content = new ByteArrayContent(data); + content.Headers.ContentType = new MediaTypeHeaderValue("application/json"); + + var outClient = wf.NewBranch().NewRequest(); + await outClient.PostAsync(_settings.BusiUrl + "/TransOut", content); + + // the first branch succeed, then crashed, the dtm server will call back the flowing wf-call-back + // manual stop application + Environment.Exit(0); + + var inClient = wf.NewBranch().NewRequest(); + await inClient.PostAsync(_settings.BusiUrl + "/TransIn", content); + + return null; + }); + } + + var req = JsonSerializer.Serialize(new TransRequest("1", -30)); + await _globalTransaction.Execute(wfNameForResume, Guid.NewGuid().ToString("N"), Encoding.UTF8.GetBytes(req), true); + + return Ok(TransResponse.BuildSucceedResponse()); + } + + [HttpPost("wf-resume")] + public async Task WfResume(CancellationToken cancellationToken) + { + try + { + if (!_globalTransaction.Exists(wfNameForResume)) + { + // register again after manual crash by Environment.Exit(0); + _globalTransaction.Register(wfNameForResume, async (wf, data) => + { + var content = new ByteArrayContent(data); + content.Headers.ContentType = new MediaTypeHeaderValue("application/json"); + + var outClient = wf.NewBranch().NewRequest(); + await outClient.PostAsync(_settings.BusiUrl + "/TransOut", content); + + var inClient = wf.NewBranch().NewRequest(); + await inClient.PostAsync(_settings.BusiUrl + "/TransIn", content); + + return null; + }); + } + + // prepared call ExecuteByQS + using var bodyMemoryStream = new MemoryStream(); + await Request.Body.CopyToAsync(bodyMemoryStream, cancellationToken); + byte[] bytes = bodyMemoryStream.ToArray(); + string body = Encoding.UTF8.GetString(bytes); + _logger.LogDebug($"body: {body}"); + + await _globalTransaction.ExecuteByQS(Request.Query, bodyMemoryStream.ToArray()); + + return Ok(TransResponse.BuildSucceedResponse()); + } + catch (Exception ex) + { + _logger.LogError(ex, "Workflow Error"); + return Ok(TransResponse.BuildFailureResponse()); + } + } } }