Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions Greentube.Monitoring.sln
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Greentube.Monitoring.Apache
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Greentube.Monitoring.IntegrationTests", "test\Greentube.Monitoring.IntegrationTests\Greentube.Monitoring.IntegrationTests.csproj", "{B9FAE3D9-FB45-479B-ADAE-5A81B0EED0A8}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Greentube.Monitoring.InternalResource", "src\Greentube.Monitoring.InternalResource\Greentube.Monitoring.InternalResource.csproj", "{6C953298-9D57-49A7-8123-C110A99EADA6}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Coverage|Any CPU = Coverage|Any CPU
Expand Down Expand Up @@ -125,6 +127,12 @@ Global
{B9FAE3D9-FB45-479B-ADAE-5A81B0EED0A8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B9FAE3D9-FB45-479B-ADAE-5A81B0EED0A8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B9FAE3D9-FB45-479B-ADAE-5A81B0EED0A8}.Release|Any CPU.Build.0 = Release|Any CPU
{6C953298-9D57-49A7-8123-C110A99EADA6}.Coverage|Any CPU.ActiveCfg = Debug|Any CPU
{6C953298-9D57-49A7-8123-C110A99EADA6}.Coverage|Any CPU.Build.0 = Debug|Any CPU
{6C953298-9D57-49A7-8123-C110A99EADA6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6C953298-9D57-49A7-8123-C110A99EADA6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6C953298-9D57-49A7-8123-C110A99EADA6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6C953298-9D57-49A7-8123-C110A99EADA6}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -143,6 +151,7 @@ Global
{D5DEE9C7-0A0A-4789-BD75-F78F5037C69A} = {843C8ED0-4792-40E0-8903-A3E5FF74A0A3}
{DA5A72B9-EEED-4CFF-97A4-C5FE6BC90FB6} = {AE749C50-94C1-445C-B13F-E9D19372CBDB}
{B9FAE3D9-FB45-479B-ADAE-5A81B0EED0A8} = {AE749C50-94C1-445C-B13F-E9D19372CBDB}
{6C953298-9D57-49A7-8123-C110A99EADA6} = {843C8ED0-4792-40E0-8903-A3E5FF74A0A3}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {BC80F7F7-4B53-4822-BFCB-50AC6E0EE384}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="1.0.2" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Greentube.Monitoring\Greentube.Monitoring.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
namespace Greentube.Monitoring.InternalResource
{
/// <summary>
/// Represents internal resource state
/// </summary>
public interface IInternalResourceMonitored
{
/// <summary>
/// Gets a value indicating whether this resource is up.
/// </summary>
/// <value>
/// <c>true</c> if this instance is up; otherwise, <c>false</c>.
/// </value>
bool IsUp { get; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using System.Threading;
using System.Threading.Tasks;

namespace Greentube.Monitoring.InternalResource
{
public sealed class InternalResourceHealthCheckStrategy : IHealthCheckStrategy
{
private readonly IInternalResourceMonitored _internalResourceMonitored;

public InternalResourceHealthCheckStrategy(IInternalResourceMonitored internalResourceMonitored)
{
_internalResourceMonitored = internalResourceMonitored;
}

public Task<bool> Check(CancellationToken token)
{
return Task.FromResult(_internalResourceMonitored.IsUp);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using Microsoft.Extensions.Logging;

namespace Greentube.Monitoring.InternalResource
{
/// <summary>
/// Internal resource monitor
///<seealso cref="ResourceMonitor" />
/// </summary>
public sealed class InternalResourceMonitor : ResourceMonitor
{
public InternalResourceMonitor(
string resourceName,
InternalResourceHealthCheckStrategy verificationStrategy,
IResourceMonitorConfiguration configuration,
ILogger<ResourceMonitor> logger,
bool isCritical = false)
: base(resourceName, verificationStrategy, configuration, logger, isCritical)
{
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;

namespace Greentube.Monitoring.InternalResource
{
public static class InternalResourceMonitoringExtensions
{
/// <summary>
/// Adds the internal resource monitor.
/// </summary>
/// <param name="options">The options.</param>
/// <param name="internalResource">Instance of internal resource that has state</param>
/// <param name="resourceName">Name of the resource. Defaults to: Uri.AbsoluteUri.</param>
/// <param name="isCritical">if set to <c>true</c> [is critical].</param>
/// <param name="configOverride">The configuration override.</param>
public static void AddInternalResourceMonitor(
this MonitoringOptions options,
IInternalResourceMonitored internalResource,
string resourceName,
bool isCritical = false,
IResourceMonitorConfiguration configOverride = null)
{
options.AddResourceMonitor((conf, provider) =>
{
var logger = provider.GetRequiredService<ILogger<InternalResourceMonitor>>();
return new InternalResourceMonitor(
resourceName,
new InternalResourceHealthCheckStrategy(internalResource),
configOverride ?? conf,
logger, isCritical
);
});
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\Greentube.Monitoring.InternalResource\Greentube.Monitoring.InternalResource.csproj" />
<ProjectReference Include="..\..\src\Greentube.Monitoring.AspNetCore\Greentube.Monitoring.AspNetCore.csproj" />
<ProjectReference Include="..\..\src\Greentube.Monitoring\Greentube.Monitoring.csproj" />
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
using System;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.TestHost;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json;
using Xunit;

namespace Greentube.Monitoring.IntegrationTests
{
public class InternalResourceMonitorTests
{
private readonly TestServer _server;

public InternalResourceMonitorTests()
{
var webHostBuilder = new WebHostBuilder();
_server = new TestServer(webHostBuilder.UseStartup<TestStartup>());
}

[Fact]
public async Task InternalStateIsMonitored()
{
var client = _server.CreateClient();

// check if node is up
var healthCheckResponse = await GetHealth(client);
Assert.True(healthCheckResponse.Up);

// set internalState to down
await client.GetAsync("/?SetToDown");

await Task.Delay(TimeSpan.FromMilliseconds(500));
// check if node is down
healthCheckResponse = await GetHealth(client);
Assert.False(healthCheckResponse.Up);

// set internalState to down
await client.GetAsync("/?SetToUp");

await Task.Delay(TimeSpan.FromMilliseconds(500));
// check if node is up again
healthCheckResponse = await GetHealth(client);
Assert.True(healthCheckResponse.Up);
}

private static async Task<HealthCheckResponse> GetHealth(HttpClient client)
{
var httpResponseMessage = await client.GetAsync("/health?Detailed");
var content = await httpResponseMessage.Content.ReadAsStringAsync();
var healthCheckResponse =
JsonConvert.DeserializeObject<HealthCheckResponse>(content);
return healthCheckResponse;
}

private class HealthCheckResponse
{
public bool Up { get; set; }
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Text;
using Greentube.Monitoring.InternalResource;

namespace Greentube.Monitoring.IntegrationTests
{
class SimpleInternalResource: IInternalResourceMonitored
{
public bool IsUp { get; set; } = false;
}
}
14 changes: 14 additions & 0 deletions test/Greentube.Monitoring.IntegrationTests/TestStartup.cs
Original file line number Diff line number Diff line change
@@ -1,26 +1,40 @@
using System;
using System.Reflection;
using Greentube.Monitoring.DependencyInjection;
using Greentube.Monitoring.InternalResource;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;


namespace Greentube.Monitoring.IntegrationTests
{
public sealed class TestStartup
{
private SimpleInternalResource _testInternalResource;
public IServiceProvider ConfigureServices(IServiceCollection services)
{
_testInternalResource = new SimpleInternalResource { IsUp = true };
services.AddMonitoring(Assembly.GetEntryAssembly(), options =>
{
options.AddShutdownMonitor(configOverride:new ResourceMonitorConfiguration(true, TimeSpan.FromMilliseconds(100), TimeSpan.FromMilliseconds(100)));
options.AddInternalResourceMonitor(_testInternalResource, "simple resource", configOverride: new ResourceMonitorConfiguration(true, TimeSpan.FromMilliseconds(100), TimeSpan.FromMilliseconds(100)), isCritical: true);
});
return services.BuildServiceProvider();
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseMonitoringEndpoint(options => options.Path = "/health");

app.Run(async context =>
{
if (context.Request.Query.ContainsKey("SetToUp"))
{ _testInternalResource.IsUp = true;}

if (context.Request.Query.ContainsKey("SetToDown"))
{ _testInternalResource.IsUp = false; }
});
}
}
}