Skip to content

Commit dcf260a

Browse files
sezal98sezalchugAniruddh25
authored
Modify Config Files according to health check endpoint (#2606)
## Why make this change? Closes #2605 ## What is this change? 1. This change includes creating the new JSON format for health check report and the related files for the same. 2. It also includes the changes required in the runtime, datasource and entities section of the config file to support the newly updated properties for health checks. 3. Further I have created an enhanced response writer for comprehensive endpoint which would take up the new config changes and return the health report and mapped it to the `/health` endpoint. ## How was this tested? This is currently tested by making sure the basic health checks are running as expected. Condition 1: Health is enabled at runtime config Here, we would get the serialized version of the basic health check. **Note: This would be improved further.** Condition 2: Health is disabled or null in runtime config Here, we would get a 404 Not Found response at the page. ## Sample Request(s) Not Found Page <img width="821" alt="image" src="https://github.com/user-attachments/assets/330e584c-cd96-4b61-afac-7225e5d8895d" /> Basic Health Check as expected <img width="215" alt="image" src="https://github.com/user-attachments/assets/aaa77479-28e6-4955-ae7f-72ec1ef8ff0b" /> Comprehensive Health Check (To Be improved further) <img width="253" alt="image" src="https://github.com/user-attachments/assets/cfe8e8bb-6741-4879-80a2-eee399d0654f" /> --------- Co-authored-by: sezalchug <[email protected]> Co-authored-by: Aniruddh Munde <[email protected]>
1 parent eefc57a commit dcf260a

16 files changed

+306
-18
lines changed
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT License.
3+
4+
namespace Azure.DataApiBuilder.Config.ObjectModel
5+
{
6+
/// <summary>
7+
/// The configuration details of the DAB Engine.
8+
/// </summary>
9+
public record ConfigurationDetails
10+
{
11+
public bool Rest { get; init; }
12+
public bool GraphQL { get; init; }
13+
public bool Caching { get; init; }
14+
public bool Telemetry { get; init; }
15+
public HostMode Mode { get; init; }
16+
}
17+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT License.
3+
4+
using System.Text.Json.Serialization;
5+
6+
namespace Azure.DataApiBuilder.Config.ObjectModel;
7+
8+
public record DatasourceHealthCheckConfig : HealthCheckConfig
9+
{
10+
// The identifier or simple name of the data source to be checked.
11+
// Required to identify data sources in case of multiple.
12+
public string? Name { get; set; }
13+
14+
// The expected milliseconds the query took to be considered healthy.
15+
// (Default: 10000ms)
16+
[JsonPropertyName("threshold-ms")]
17+
public int? ThresholdMs { get; set; }
18+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT License.
3+
4+
using System.Text.Json.Serialization;
5+
6+
namespace Azure.DataApiBuilder.Config.ObjectModel;
7+
8+
public record EntityHealthCheckConfig : HealthCheckConfig
9+
{
10+
// This provides the ability to specify the 'x' first rows to be returned by the query.
11+
// Default is 100
12+
public int? First { get; set; } = 100;
13+
14+
// The expected milliseconds the query took to be considered healthy.
15+
// (Default: 10000ms)
16+
[JsonPropertyName("threshold-ms")]
17+
public int? ThresholdMs { get; set; }
18+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT License.
3+
4+
namespace Azure.DataApiBuilder.Config.ObjectModel;
5+
6+
public record HealthCheckConfig
7+
{
8+
public bool Enabled { get; set; } = true;// Default value: true
9+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT License.
3+
4+
namespace Azure.DataApiBuilder.Config.ObjectModel;
5+
6+
public record RuntimeHealthCheckConfig : HealthCheckConfig
7+
{
8+
// TODO: Add support for caching in upcoming PRs
9+
// public int cache-ttl-seconds { get; set; };
10+
11+
// TODO: Add support for "roles": ["anonymous", "authenticated"] in upcoming PRs
12+
// public string[] Roles { get; set; };
13+
14+
// TODO: Add support for parallel stream to run the health check query in upcoming PRs
15+
// public int MaxDop { get; set; } = 1; // Parallelized streams to run Health Check (Default: 1)
16+
}

src/Config/ObjectModel/DataSource.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,12 @@ namespace Azure.DataApiBuilder.Config.ObjectModel;
1212
/// <param name="DatabaseType">Type of database to use.</param>
1313
/// <param name="ConnectionString">Connection string to access the database.</param>
1414
/// <param name="Options">Custom options for the specific database. If there are no options, this could be null.</param>
15-
public record DataSource(DatabaseType DatabaseType, string ConnectionString, Dictionary<string, object?>? Options)
15+
/// <param name="Health">Health check configuration for the datasource.</param>
16+
public record DataSource(
17+
DatabaseType DatabaseType,
18+
string ConnectionString,
19+
Dictionary<string, object?>? Options,
20+
DatasourceHealthCheckConfig? Health = null)
1621
{
1722
/// <summary>
1823
/// Converts the <c>Options</c> dictionary into a typed options object.

src/Config/ObjectModel/Entity.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ namespace Azure.DataApiBuilder.Config.ObjectModel;
99
/// <summary>
1010
/// Defines the Entities that are exposed.
1111
/// </summary>
12+
/// <param name="Health">Health check configuration for the entity.</param>
1213
/// <param name="Source">The underlying database object to which the exposed entity is connected to.</param>
1314
/// <param name="Rest">The JSON may represent this as a bool or a string and we use a custom <c>JsonConverter</c> to convert that into the .NET type.</param>
1415
/// <param name="GraphQL">The JSON may represent this as a bool or a string and we use a custom <c>JsonConverter</c> to convert that into the .NET type.</param>
@@ -24,6 +25,7 @@ public record Entity
2425
public const string PROPERTY_PATH = "path";
2526
public const string PROPERTY_METHODS = "methods";
2627

28+
public EntityHealthCheckConfig? Health { get; init; }
2729
public EntitySource Source { get; init; }
2830
public EntityGraphQLOptions GraphQL { get; init; }
2931
public EntityRestOptions Rest { get; init; }
@@ -44,8 +46,10 @@ public Entity(
4446
Dictionary<string, string>? Mappings,
4547
Dictionary<string, EntityRelationship>? Relationships,
4648
EntityCacheOptions? Cache = null,
47-
bool IsLinkingEntity = false)
49+
bool IsLinkingEntity = false,
50+
EntityHealthCheckConfig? Health = null)
4851
{
52+
this.Health = Health;
4953
this.Source = Source;
5054
this.GraphQL = GraphQL;
5155
this.Rest = Rest;

src/Config/ObjectModel/HostMode.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
// Copyright (c) Microsoft Corporation.
22
// Licensed under the MIT License.
33

4+
using System.Text.Json.Serialization;
5+
46
namespace Azure.DataApiBuilder.Config.ObjectModel;
57

8+
[JsonConverter(typeof(JsonStringEnumConverter))]
69
public enum HostMode
710
{
811
Development,

src/Config/ObjectModel/RuntimeOptions.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ namespace Azure.DataApiBuilder.Config.ObjectModel;
88

99
public record RuntimeOptions
1010
{
11+
public RuntimeHealthCheckConfig? Health { get; init; }
1112
public RestRuntimeOptions? Rest { get; init; }
1213
public GraphQLRuntimeOptions? GraphQL { get; init; }
1314
public HostOptions? Host { get; set; }
@@ -24,8 +25,10 @@ public RuntimeOptions(
2425
string? BaseRoute = null,
2526
TelemetryOptions? Telemetry = null,
2627
EntityCacheOptions? Cache = null,
27-
PaginationOptions? Pagination = null)
28+
PaginationOptions? Pagination = null,
29+
RuntimeHealthCheckConfig? Health = null)
2830
{
31+
this.Health = Health;
2932
this.Rest = Rest;
3033
this.GraphQL = GraphQL;
3134
this.Host = Host;

src/Service.Tests/Configuration/ConfigurationTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3748,7 +3748,7 @@ public async Task HealthEndpoint_ValidateContents()
37483748
}
37493749

37503750
// Validate value of 'version' property in response.
3751-
if (responseProperties.TryGetValue(key: DabHealthCheck.DAB_VERSION_KEY, out JsonElement versionValue))
3751+
if (responseProperties.TryGetValue(key: BasicHealthCheck.DAB_VERSION_KEY, out JsonElement versionValue))
37523752
{
37533753
Assert.AreEqual(
37543754
expected: ProductInfo.GetProductVersion(),
@@ -3761,7 +3761,7 @@ public async Task HealthEndpoint_ValidateContents()
37613761
}
37623762

37633763
// Validate value of 'app-name' property in response.
3764-
if (responseProperties.TryGetValue(key: DabHealthCheck.DAB_APPNAME_KEY, out JsonElement appNameValue))
3764+
if (responseProperties.TryGetValue(key: BasicHealthCheck.DAB_APPNAME_KEY, out JsonElement appNameValue))
37653765
{
37663766
Assert.AreEqual(
37673767
expected: ProductInfo.GetDataApiBuilderUserAgent(),

0 commit comments

Comments
 (0)