Skip to content

Commit

Permalink
feat(DtmClient): add QueryStatus method for query single global trans…
Browse files Browse the repository at this point in the history
…action status
  • Loading branch information
wooln committed Dec 13, 2024
1 parent 0c77dca commit 6ca3b79
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 2 deletions.
16 changes: 14 additions & 2 deletions samples/DtmSample/Controllers/MsgTestController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -276,9 +276,9 @@ public async Task<IActionResult> MsgWithTopic(CancellationToken cancellationToke

return Ok(TransResponse.BuildSucceedResponse());
}

/// <summary>
/// MSG with exist topic
/// query
/// </summary>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Expand All @@ -288,5 +288,17 @@ public async Task<IActionResult> Query(string gid, CancellationToken cancellatio
TransGlobal trans = await _dtmClient.Query(gid, cancellationToken);
return Ok(trans);
}

/// <summary>
/// query status
/// </summary>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[HttpGet("query-status")]
public async Task<IActionResult> QueryStatus(string gid, CancellationToken cancellationToken)

Check warning on line 298 in samples/DtmSample/Controllers/MsgTestController.cs

View workflow job for this annotation

GitHub Actions / build on windows-latest

Parameter 'gid' has no matching param tag in the XML comment for 'MsgTestController.QueryStatus(string, CancellationToken)' (but other parameters do)

Check warning on line 298 in samples/DtmSample/Controllers/MsgTestController.cs

View workflow job for this annotation

GitHub Actions / build on windows-latest

Parameter 'gid' has no matching param tag in the XML comment for 'MsgTestController.QueryStatus(string, CancellationToken)' (but other parameters do)

Check warning on line 298 in samples/DtmSample/Controllers/MsgTestController.cs

View workflow job for this annotation

GitHub Actions / build on ubuntu-latest

Parameter 'gid' has no matching param tag in the XML comment for 'MsgTestController.QueryStatus(string, CancellationToken)' (but other parameters do)

Check warning on line 298 in samples/DtmSample/Controllers/MsgTestController.cs

View workflow job for this annotation

GitHub Actions / build on ubuntu-latest

Parameter 'gid' has no matching param tag in the XML comment for 'MsgTestController.QueryStatus(string, CancellationToken)' (but other parameters do)
{
string status = await _dtmClient.QueryStatus(gid, cancellationToken);
return Ok(status);
}
}
}
22 changes: 22 additions & 0 deletions src/Dtmcli/DtmClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,28 @@ public async Task<TransGlobal> Query(string gid, CancellationToken cancellationT
return JsonSerializer.Deserialize<TransGlobal>(dtmContent, _jsonOptions);
}

/// <summary>
/// Query single global transaction status
/// </summary>
/// <param name="gid"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public async Task<string> QueryStatus(string gid, CancellationToken cancellationToken)
{
if (string.IsNullOrEmpty(gid)) throw new ArgumentNullException(nameof(gid));

var url = string.Concat(_dtmOptions.DtmUrl.TrimEnd(Slash), Constant.Request.URL_Query, $"?gid={gid}");
var client = _httpClientFactory.CreateClient(Constant.DtmClientHttpName);
var response = await client.GetAsync(url, cancellationToken).ConfigureAwait(false);
var dtmContent = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
DtmImp.Utils.CheckStatus(response.StatusCode, dtmContent);
var graph = JsonSerializer.Deserialize<TransGlobalForStatus>(dtmContent, _jsonOptions);
return graph.Transaction == null
? string.Empty
: graph.Transaction.Status;
}

public class DtmGid
{
[JsonPropertyName("gid")]
Expand Down
2 changes: 2 additions & 0 deletions src/Dtmcli/IDtmClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,7 @@ public interface IDtmClient
#endif

Task<TransGlobal> Query(string gid, CancellationToken cancellationToken);

Task<string> QueryStatus(string gid, CancellationToken cancellationToken);
}
}
13 changes: 13 additions & 0 deletions src/Dtmcli/TransGlobal.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,19 @@

namespace Dtmcli;

/// <summary>
/// query status only
/// </summary>
internal class TransGlobalForStatus
{
[JsonPropertyName("transaction")] public DtmTransactionForStatus Transaction { get; set; }

public class DtmTransactionForStatus
{
[JsonPropertyName("status")] public string Status { get; set; }
}
}

// convert from json(a prepared TCC global trans sample) to c# code
public class TransGlobal
{
Expand Down
58 changes: 58 additions & 0 deletions tests/Dtmcli.Tests/DtmClientTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,64 @@ public async Task Query_Should_Throw_Exception()
await client.Query(gid: "my-gid", new CancellationToken());
});
}



[Fact]
public async Task QueryStatus_Should_Succeed()
{
var factory = new Mock<IHttpClientFactory>();
var options = Microsoft.Extensions.Options.Options.Create(new DtmCommon.DtmOptions { DtmUrl = "http://localhost:8080" });
/*
{
"branches": [],
"transaction": {
"id": 7,
"gid": "mV9RGqZCV2mdn9YA6T2TPC",
"trans_type": "msg",
"status": "prepared",
"protocol": "http"
}
}
*/
var mockHttpMessageHandler = new ClientMockHttpMessageHandler(HttpStatusCode.OK, "{\n \"branches\": [],\n \"transaction\": {\n \"id\": 7,\n \"gid\": \"mV9RGqZCV2mdn9YA6T2TPC\",\n \"trans_type\": \"msg\",\n \"status\": \"prepared\",\n \"protocol\": \"http\"\n }\n} ");
factory.Setup(x => x.CreateClient(It.IsAny<string>())).Returns(new HttpClient(mockHttpMessageHandler));
var client = new DtmClient(factory.Object, options);
string status = await client.QueryStatus(gid: "my-gid", new CancellationToken());
Assert.Equal("prepared", status);
}

[Fact]
public async Task QueryStatus_Not_Exist_Gid()
{
var factory = new Mock<IHttpClientFactory>();
var options = Microsoft.Extensions.Options.Options.Create(new DtmCommon.DtmOptions { DtmUrl = "http://localhost:8080" });
/*
{
"branches": [],
"transaction": null
}
*/
var mockHttpMessageHandler = new ClientMockHttpMessageHandler(HttpStatusCode.OK, "{\n \"branches\": [],\n \"transaction\": null\n}\n");
factory.Setup(x => x.CreateClient(It.IsAny<string>())).Returns(new HttpClient(mockHttpMessageHandler));
var client = new DtmClient(factory.Object, options);
string status = await client.QueryStatus(gid: "my-gid", new CancellationToken());
Assert.Empty(status);
}

[Fact]
public async Task QueryStatus_Should_Throw_Exception()
{
var factory = new Mock<IHttpClientFactory>();
var options = Microsoft.Extensions.Options.Options.Create(new DtmCommon.DtmOptions { DtmUrl = "http://localhost:8080" });
var mockHttpMessageHandler = new ClientMockHttpMessageHandler(HttpStatusCode.InternalServerError, "");
factory.Setup(x => x.CreateClient(It.IsAny<string>())).Returns(new HttpClient(mockHttpMessageHandler));
var client = new DtmClient(factory.Object, options);
await Assert.ThrowsAsync<DtmCommon.DtmException>(async () =>
{
await client.QueryStatus(gid: "my-gid", new CancellationToken());
});
}
}

internal class ClientMockHttpMessageHandler : DelegatingHandler
Expand Down

0 comments on commit 6ca3b79

Please sign in to comment.