From 3bd5c3e1b5c2f302b28c6e3d71def6780d9b2bcb Mon Sep 17 00:00:00 2001 From: Dennis Reimann Date: Thu, 16 Apr 2020 15:39:08 +0200 Subject: [PATCH 1/4] API: Add health check endpoint --- .../BTCPayServerClient.Health.cs | 15 +++++++++++ BTCPayServer.Tests/GreenfieldAPITests.cs | 14 ++++++++++ .../GreenField/HealthController.cs | 16 ++++++++++++ .../swagger/v1/swagger.template.health.json | 26 +++++++++++++++++++ 4 files changed, 71 insertions(+) create mode 100644 BTCPayServer.Client/BTCPayServerClient.Health.cs create mode 100644 BTCPayServer/Controllers/GreenField/HealthController.cs create mode 100644 BTCPayServer/wwwroot/swagger/v1/swagger.template.health.json diff --git a/BTCPayServer.Client/BTCPayServerClient.Health.cs b/BTCPayServer.Client/BTCPayServerClient.Health.cs new file mode 100644 index 000000000..5a551142b --- /dev/null +++ b/BTCPayServer.Client/BTCPayServerClient.Health.cs @@ -0,0 +1,15 @@ +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +namespace BTCPayServer.Client +{ + public partial class BTCPayServerClient + { + public virtual async Task IsHealthy(CancellationToken token = default) + { + var response = await _httpClient.SendAsync(CreateHttpRequest("api/v1/health"), token); + return response.IsSuccessStatusCode; + } + } +} diff --git a/BTCPayServer.Tests/GreenfieldAPITests.cs b/BTCPayServer.Tests/GreenfieldAPITests.cs index d0b9dbeb7..49c3960c4 100644 --- a/BTCPayServer.Tests/GreenfieldAPITests.cs +++ b/BTCPayServer.Tests/GreenfieldAPITests.cs @@ -228,5 +228,19 @@ namespace BTCPayServer.Tests } } + + [Fact(Timeout = TestTimeout)] + [Trait("Integration", "Integration")] + public async Task HealthControllerTests() + { + using (var tester = ServerTester.Create()) + { + await tester.StartAsync(); + var unauthClient = new BTCPayServerClient(tester.PayTester.ServerUri); + + var isHealthy = await unauthClient.IsHealthy(); + Assert.True(isHealthy); + } + } } } diff --git a/BTCPayServer/Controllers/GreenField/HealthController.cs b/BTCPayServer/Controllers/GreenField/HealthController.cs new file mode 100644 index 000000000..bdc624dc7 --- /dev/null +++ b/BTCPayServer/Controllers/GreenField/HealthController.cs @@ -0,0 +1,16 @@ +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; + +namespace BTCPayServer.Controllers.GreenField +{ + [ApiController] + public class HealthController : ControllerBase + { + [AllowAnonymous] + [HttpGet("~/api/v1/health")] + public ActionResult GetHealth() + { + return Ok(); + } + } +} diff --git a/BTCPayServer/wwwroot/swagger/v1/swagger.template.health.json b/BTCPayServer/wwwroot/swagger/v1/swagger.template.health.json new file mode 100644 index 000000000..93fd4f55b --- /dev/null +++ b/BTCPayServer/wwwroot/swagger/v1/swagger.template.health.json @@ -0,0 +1,26 @@ +{ + "paths": { + "/api/v1/health": { + "get": { + "tags": [ + "Health" + ], + "summary": "Get health status", + "description": "Check whether of not the instance is up", + "operationId": "Health_GetHealth", + "responses": { + "200": { + "description": "Instance is up", + "content": {} + } + }, + "security": [] + } + } + }, + "tags": [ + { + "name": "Health" + } + ] +} From 70d1056d487ac94374dbb9eface7e324af11e6cb Mon Sep 17 00:00:00 2001 From: Dennis Reimann Date: Tue, 21 Apr 2020 10:39:04 +0200 Subject: [PATCH 2/4] API: Health endpoint returns synchronized state --- .../BTCPayServerClient.Health.cs | 7 +++--- BTCPayServer.Client/Models/ApiHealthData.cs | 10 ++++++++ BTCPayServer.Tests/GreenfieldAPITests.cs | 5 ++-- .../GreenField/HealthController.cs | 7 ++++-- .../swagger/v1/swagger.template.health.json | 24 +++++++++++++++++-- 5 files changed, 44 insertions(+), 9 deletions(-) create mode 100644 BTCPayServer.Client/Models/ApiHealthData.cs diff --git a/BTCPayServer.Client/BTCPayServerClient.Health.cs b/BTCPayServer.Client/BTCPayServerClient.Health.cs index 5a551142b..3acbb036d 100644 --- a/BTCPayServer.Client/BTCPayServerClient.Health.cs +++ b/BTCPayServer.Client/BTCPayServerClient.Health.cs @@ -1,15 +1,16 @@ using System.Net.Http; using System.Threading; using System.Threading.Tasks; +using BTCPayServer.Client.Models; namespace BTCPayServer.Client { public partial class BTCPayServerClient { - public virtual async Task IsHealthy(CancellationToken token = default) + public virtual async Task GetHealth(CancellationToken token = default) { - var response = await _httpClient.SendAsync(CreateHttpRequest("api/v1/health"), token); - return response.IsSuccessStatusCode; + var response = await _httpClient.SendAsync(CreateHttpRequest("api/v1/health", bodyPayload: new {}), token); + return await HandleResponse(response); } } } diff --git a/BTCPayServer.Client/Models/ApiHealthData.cs b/BTCPayServer.Client/Models/ApiHealthData.cs new file mode 100644 index 000000000..1f9f50663 --- /dev/null +++ b/BTCPayServer.Client/Models/ApiHealthData.cs @@ -0,0 +1,10 @@ +using BTCPayServer.Client.JsonConverters; +using Newtonsoft.Json; + +namespace BTCPayServer.Client.Models +{ + public class ApiHealthData + { + public bool Synchronized { get; set; } + } +} diff --git a/BTCPayServer.Tests/GreenfieldAPITests.cs b/BTCPayServer.Tests/GreenfieldAPITests.cs index 49c3960c4..095e63efe 100644 --- a/BTCPayServer.Tests/GreenfieldAPITests.cs +++ b/BTCPayServer.Tests/GreenfieldAPITests.cs @@ -238,8 +238,9 @@ namespace BTCPayServer.Tests await tester.StartAsync(); var unauthClient = new BTCPayServerClient(tester.PayTester.ServerUri); - var isHealthy = await unauthClient.IsHealthy(); - Assert.True(isHealthy); + var apiHealthData = await unauthClient.GetHealth(); + Assert.NotNull(apiHealthData); + Assert.True(apiHealthData.Synchronized); } } } diff --git a/BTCPayServer/Controllers/GreenField/HealthController.cs b/BTCPayServer/Controllers/GreenField/HealthController.cs index bdc624dc7..1080d9316 100644 --- a/BTCPayServer/Controllers/GreenField/HealthController.cs +++ b/BTCPayServer/Controllers/GreenField/HealthController.cs @@ -1,3 +1,5 @@ +using BTCPayServer.HostedServices; +using BTCPayServer.Client.Models; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; @@ -8,9 +10,10 @@ namespace BTCPayServer.Controllers.GreenField { [AllowAnonymous] [HttpGet("~/api/v1/health")] - public ActionResult GetHealth() + public ActionResult GetHealth(NBXplorerDashboard dashBoard) { - return Ok(); + ApiHealthData model = new ApiHealthData() {Synchronized = dashBoard.IsFullySynched()}; + return Ok(model); } } } diff --git a/BTCPayServer/wwwroot/swagger/v1/swagger.template.health.json b/BTCPayServer/wwwroot/swagger/v1/swagger.template.health.json index 93fd4f55b..c310325f3 100644 --- a/BTCPayServer/wwwroot/swagger/v1/swagger.template.health.json +++ b/BTCPayServer/wwwroot/swagger/v1/swagger.template.health.json @@ -6,18 +6,38 @@ "Health" ], "summary": "Get health status", - "description": "Check whether of not the instance is up", + "description": "Check the instance health status", "operationId": "Health_GetHealth", "responses": { "200": { "description": "Instance is up", - "content": {} + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApplicationHealthData" + } + } + } } }, "security": [] } } }, + "components": { + "schemas": { + "ApplicationHealthData": { + "type": "object", + "additionalProperties": false, + "properties": { + "synchronized": { + "type": "boolean", + "description": "True if the instance is fully synchronized" + } + } + } + } + }, "tags": [ { "name": "Health" From 22e39998e2cfbf72b9f0c4227dabb3925b9aa26b Mon Sep 17 00:00:00 2001 From: Dennis Reimann Date: Tue, 21 Apr 2020 16:43:14 +0200 Subject: [PATCH 3/4] Updates from code review Thanks @kukks! --- BTCPayServer.Client/BTCPayServerClient.Health.cs | 2 +- BTCPayServer/Controllers/GreenField/HealthController.cs | 5 ++++- BTCPayServer/wwwroot/swagger/v1/swagger.template.health.json | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/BTCPayServer.Client/BTCPayServerClient.Health.cs b/BTCPayServer.Client/BTCPayServerClient.Health.cs index 3acbb036d..2a9c70833 100644 --- a/BTCPayServer.Client/BTCPayServerClient.Health.cs +++ b/BTCPayServer.Client/BTCPayServerClient.Health.cs @@ -9,7 +9,7 @@ namespace BTCPayServer.Client { public virtual async Task GetHealth(CancellationToken token = default) { - var response = await _httpClient.SendAsync(CreateHttpRequest("api/v1/health", bodyPayload: new {}), token); + var response = await _httpClient.SendAsync(CreateHttpRequest("api/v1/health"), token); return await HandleResponse(response); } } diff --git a/BTCPayServer/Controllers/GreenField/HealthController.cs b/BTCPayServer/Controllers/GreenField/HealthController.cs index 1080d9316..618880844 100644 --- a/BTCPayServer/Controllers/GreenField/HealthController.cs +++ b/BTCPayServer/Controllers/GreenField/HealthController.cs @@ -12,7 +12,10 @@ namespace BTCPayServer.Controllers.GreenField [HttpGet("~/api/v1/health")] public ActionResult GetHealth(NBXplorerDashboard dashBoard) { - ApiHealthData model = new ApiHealthData() {Synchronized = dashBoard.IsFullySynched()}; + ApiHealthData model = new ApiHealthData() + { + Synchronized = dashBoard.IsFullySynched() + }; return Ok(model); } } diff --git a/BTCPayServer/wwwroot/swagger/v1/swagger.template.health.json b/BTCPayServer/wwwroot/swagger/v1/swagger.template.health.json index c310325f3..beaa5be9c 100644 --- a/BTCPayServer/wwwroot/swagger/v1/swagger.template.health.json +++ b/BTCPayServer/wwwroot/swagger/v1/swagger.template.health.json @@ -32,7 +32,7 @@ "properties": { "synchronized": { "type": "boolean", - "description": "True if the instance is fully synchronized" + "description": "True if the instance is fully synchronized, according to NBXplorer" } } } From a6a56e4791afc3ab42836b8663cbc3b6cc11c211 Mon Sep 17 00:00:00 2001 From: Kukks Date: Tue, 21 Apr 2020 17:09:17 +0200 Subject: [PATCH 4/4] fix controller --- BTCPayServer/Controllers/GreenField/HealthController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BTCPayServer/Controllers/GreenField/HealthController.cs b/BTCPayServer/Controllers/GreenField/HealthController.cs index 618880844..843facf1a 100644 --- a/BTCPayServer/Controllers/GreenField/HealthController.cs +++ b/BTCPayServer/Controllers/GreenField/HealthController.cs @@ -5,7 +5,7 @@ using Microsoft.AspNetCore.Mvc; namespace BTCPayServer.Controllers.GreenField { - [ApiController] + [Controller] public class HealthController : ControllerBase { [AllowAnonymous]