Skip to content

Commit

Permalink
Merge pull request #116 from natenho/feature/105-readiness-endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
natenho authored Jun 11, 2023
2 parents b7d32fc + ce871d8 commit f11e981
Show file tree
Hide file tree
Showing 21 changed files with 355 additions and 65 deletions.
3 changes: 2 additions & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -265,8 +265,9 @@ __pycache__/
**/.dockerignore
**/*.md
.github/
doc/
nupkg/
test/
website/
**/*.log
src/Mockaco/Mocks*/**/*.*
!src/Mockaco/Mocks/hello.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
using Microsoft.Extensions.Options;
using Mockaco;
using Mockaco.Verifyer;
using Microsoft.Extensions.Diagnostics.HealthChecks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Diagnostics.HealthChecks;

namespace Microsoft.AspNetCore.Builder
{
Expand All @@ -10,8 +13,23 @@ public static class MockacoApplicationBuilder
public static IApplicationBuilder UseMockaco(this IApplicationBuilder app, Action<IApplicationBuilder> configure)
{
app.UseRouting();

var options = app.ApplicationServices.GetRequiredService<IOptions<MockacoOptions>>().Value;
app.UseEndpoints(endpoints => endpoints.Map($"/{options.VerificationEndpointPrefix}/{options.VerificationEndpointName}", VerifyerExtensions.Verify));

app.UseEndpoints(endpoints =>
{
endpoints.Map($"/{options.VerificationEndpointPrefix ?? options.MockacoEndpoint}/{options.VerificationEndpointName}", VerifyerExtensions.Verify);

endpoints.MapHealthChecks($"/{options.MockacoEndpoint}/ready", new HealthCheckOptions
{
Predicate = healthCheck => healthCheck.Tags.Contains("ready")
});

endpoints.MapHealthChecks($"/{options.MockacoEndpoint}/health", new HealthCheckOptions
{
Predicate = _ => false
});
});

app.UseMiddleware<ErrorHandlingMiddleware>();
configure(app);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Diagnostics.HealthChecks;
using Microsoft.Extensions.Options;
using Mockaco;
using Mockaco.HealthChecks;
using Mockaco.Settings;

namespace Microsoft.Extensions.DependencyInjection
Expand Down Expand Up @@ -30,13 +32,22 @@ private static IServiceCollection AddConfiguration(this IServiceCollection servi
.Configure<MockacoOptions>(config)
.Configure<TemplateFileProviderOptions>(config.GetSection("TemplateFileProvider"));

private static IServiceCollection AddCommonServices(this IServiceCollection services) =>
private static IServiceCollection AddCommonServices(this IServiceCollection services)
{
services
.AddMemoryCache()
.AddHttpClient()
.AddInternalServices()
.AddHostedService<MockProviderWarmUp>();

services
.AddSingleton<StartupHealthCheck>()
.AddHealthChecks()
.AddCheck<StartupHealthCheck>("Startup", tags: new[] { "ready" });

return services;
}

private static IServiceCollection AddInternalServices(this IServiceCollection services) =>
services
.AddSingleton<VerificationRouteValueTransformer>()
Expand Down
25 changes: 25 additions & 0 deletions src/Mockaco.AspNetCore/HealthChecks/StartupHealthCheck.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using Microsoft.Extensions.Diagnostics.HealthChecks;

namespace Mockaco.HealthChecks
{
public class StartupHealthCheck : IHealthCheck
{
private volatile bool _isReady;

public bool StartupCompleted
{
get => _isReady;
set => _isReady = value;
}

public Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default)
{
if (StartupCompleted)
{
return Task.FromResult(HealthCheckResult.Healthy("The startup has completed."));
}

return Task.FromResult(HealthCheckResult.Unhealthy("That startup is still running."));
}
}
}
9 changes: 8 additions & 1 deletion src/Mockaco.AspNetCore/MockProvider.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Diagnostics.HealthChecks;
using Microsoft.Extensions.Logging;
using Mockaco.HealthChecks;
using Mono.TextTemplating;
using Newtonsoft.Json;
using System;
Expand All @@ -18,6 +20,7 @@ internal class MockProvider : IMockProvider
private readonly ITemplateProvider _templateProvider;
private readonly ITemplateTransformer _templateTransformer;
private readonly IGlobalVariableStorage _globalVariableStorage;
private readonly StartupHealthCheck _healthCheck;
private readonly ILogger<MockProvider> _logger;

public MockProvider
Expand All @@ -26,6 +29,7 @@ public MockProvider
ITemplateProvider templateProvider,
ITemplateTransformer templateTransformer,
IGlobalVariableStorage globalVariableStorage,
StartupHealthCheck healthCheck,
ILogger<MockProvider> logger)
{
_cache = new List<Mock>();
Expand All @@ -36,6 +40,7 @@ public MockProvider

_templateTransformer = templateTransformer;
_globalVariableStorage = globalVariableStorage;
_healthCheck = healthCheck;
_logger = logger;
}

Expand Down Expand Up @@ -114,6 +119,8 @@ public async Task WarmUp()

_cache = mocks.OrderByDescending(r => r.HasCondition).ToList();

_healthCheck.StartupCompleted = true;

_logger.LogTrace("{0} finished in {1} ms", nameof(WarmUp), stopwatch.ElapsedMilliseconds);
}

Expand Down
20 changes: 13 additions & 7 deletions src/Mockaco.AspNetCore/Mockaco.AspNetCore.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -44,23 +44,29 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Bogus" Version="33.0.2" />
<PackageReference Include="GitVersion.MsBuild" Version="5.6.10">
<PackageReference Include="Bogus" Version="34.0.2" />
<PackageReference Include="GitVersion.MsBuild" Version="5.12.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="MAB.DotIgnore" Version="3.0.2" />
<PackageReference Include="Microsoft.OpenApi.Readers" Version="1.2.3" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Scripting" Version="3.9.0" />
<PackageReference Include="Microsoft.CodeAnalysis.PublicApiAnalyzers" Version="3.3.3">
<PackageReference Include="Microsoft.OpenApi.Readers" Version="1.6.4" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Scripting" Version="4.6.0" />
<PackageReference Include="Microsoft.CodeAnalysis.PublicApiAnalyzers" Version="3.3.4">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
<PackageReference Include="Polly" Version="7.2.2" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Polly" Version="7.2.3" />
<PackageReference Include="System.CommandLine" Version="2.0.0-beta1.21308.1" />
</ItemGroup>

<ItemGroup>
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo">
<_Parameter1>Mockaco.Tests</_Parameter1>
</AssemblyAttribute>
</ItemGroup>

<ItemGroup>
<None Include="Resources\mockaco-icon.png">
<Pack>True</Pack>
Expand Down
5 changes: 4 additions & 1 deletion src/Mockaco.AspNetCore/Options/MockacoOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ public class MockacoOptions

public int MatchedRoutesCacheDuration { get; set; }

public string MockacoEndpoint { get; set; }

// Deprecated (use MockacoEndpoint instead)
public string VerificationEndpointPrefix { get; set; }

public string VerificationEndpointName { get; set; }
Expand All @@ -30,7 +33,7 @@ public MockacoOptions()
References = new List<string>();
Imports = new List<string>();
MatchedRoutesCacheDuration = 60;
VerificationEndpointPrefix = "_mockaco";
MockacoEndpoint = "_mockaco";
VerificationEndpointName = "verification";
TemplateFileProvider = new();
}
Expand Down
7 changes: 7 additions & 0 deletions src/Mockaco.AspNetCore/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
Bogus.PhoneNumberExtensions
Microsoft.AspNetCore.Builder.MockacoApplicationBuilder
Microsoft.Extensions.DependencyInjection.MockacoServiceCollection
Mockaco.HealthChecks.StartupHealthCheck
Mockaco.HealthChecks.StartupHealthCheck.CheckHealthAsync(Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckContext context, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckResult>
Mockaco.HealthChecks.StartupHealthCheck.StartupCompleted.get -> bool
Mockaco.HealthChecks.StartupHealthCheck.StartupCompleted.set -> void
Mockaco.HealthChecks.StartupHealthCheck.StartupHealthCheck() -> void
Mockaco.IFakerFactory
Mockaco.IFakerFactory.GetDefaultFaker() -> Bogus.Faker
Mockaco.IFakerFactory.GetFaker(System.Collections.Generic.IEnumerable<string> acceptLanguages) -> Bogus.Faker
Expand Down Expand Up @@ -47,6 +52,8 @@ Mockaco.MockacoOptions.Imports.get -> System.Collections.Generic.List<string>
Mockaco.MockacoOptions.Imports.set -> void
Mockaco.MockacoOptions.MatchedRoutesCacheDuration.get -> int
Mockaco.MockacoOptions.MatchedRoutesCacheDuration.set -> void
Mockaco.MockacoOptions.MockacoEndpoint.get -> string
Mockaco.MockacoOptions.MockacoEndpoint.set -> void
Mockaco.MockacoOptions.MockacoOptions() -> void
Mockaco.MockacoOptions.References.get -> System.Collections.Generic.List<string>
Mockaco.MockacoOptions.References.set -> void
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,12 @@ private void SetMockRootPath(string path)
var fullPath = Path.IsPathRooted(path)
? path
: Path.Combine(Directory.GetCurrentDirectory(), path);


if (!Directory.Exists(fullPath))
{
Directory.CreateDirectory(fullPath);
}

var fileProvider = new PhysicalFileProvider(fullPath, ExclusionFilters.Hidden | ExclusionFilters.System);

_fileProvider?.Dispose();
Expand Down
14 changes: 7 additions & 7 deletions src/Mockaco/Mockaco.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -44,16 +44,16 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="GitVersion.MsBuild" Version="5.6.10">
<PackageReference Include="GitVersion.MsBuild" Version="5.12.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.FileProviders.Physical" Version="5.0.0" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.10.8" />
<PackageReference Include="Serilog.AspNetCore" Version="4.1.0" />
<PackageReference Include="Serilog.Settings.Configuration" Version="3.1.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" />
<PackageReference Include="Serilog.Sinks.File" Version="4.1.0" />
<PackageReference Include="Microsoft.Extensions.FileProviders.Physical" Version="6.0.0" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.18.1" />
<PackageReference Include="Serilog.AspNetCore" Version="7.0.0" />
<PackageReference Include="Serilog.Settings.Configuration" Version="7.0.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="4.1.0" />
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
<PackageReference Include="System.CommandLine" Version="2.0.0-beta1.21308.1" />
</ItemGroup>

Expand Down
4 changes: 2 additions & 2 deletions src/Mockaco/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,9 @@ public static IHostBuilder CreateHostBuilder(string[] args) =>

configuration.AddCommandLine(args, switchMappings);
})
.UseSerilog((context, loggerConfiguration) => loggerConfiguration.ReadFrom.Configuration(context.Configuration))
.UseStartup<Startup>();
});
})
.UseSerilog((context, loggerConfiguration) => loggerConfiguration.ReadFrom.Configuration(context.Configuration));

private static CommandLineBuilder CreateCommandLineBuilder(string[] args, IHost host)
{
Expand Down
6 changes: 3 additions & 3 deletions src/Mockaco/Settings/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
"DefaultHttpContentType": "application/json",
"References": [],
"Imports": [],
"MatchedRoutesCacheDuration": 60,
"VerificationEndpointName": "verification",
"VerificationEndpointPrefix": "_mockaco"
"MatchedRoutesCacheDuration": 60,
"MockacoEndpoint": "_mockaco",
"VerificationEndpointName": "verification"
},
"AllowedHosts": "*",
"Serilog": {
Expand Down
79 changes: 42 additions & 37 deletions test/Mockaco.Tests/Mockaco.Tests.csproj
Original file line number Diff line number Diff line change
@@ -1,45 +1,50 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<RootNamespace>Mockaco.Tests</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

<ItemGroup>
<Content Include="Templating\Response\mockaco.jpg">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="FluentAssertions" Version="6.11.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.2" />
<PackageReference Include="Moq" Version="4.18.4" />
<PackageReference Include="Testcontainers" Version="3.2.0" />
<PackageReference Include="xunit" Version="2.4.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="6.0.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>

<ItemGroup>
<PackageReference Include="FluentAssertions" Version="5.10.3" />
<PackageReference Include="Microsoft.AspNetCore.Http" Version="2.2.2" />
<PackageReference Include="Microsoft.AspNetCore.Http.Extensions" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Http" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="5.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.10.0" />
<PackageReference Include="Moq" Version="4.16.1" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Mockaco.AspNetCore\Mockaco.AspNetCore.csproj" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\Mockaco\Mockaco.csproj" />
</ItemGroup>
<ItemGroup>
<Content Include="Templating\Response\mockaco.jpg">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>

<ItemGroup>
<None Update="Templating\Transforms_Plain_Json_Template.json">
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Templating\Transforms_Scripted_Json_Template.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</None>
</ItemGroup>
<ItemGroup>
<None Update="Templating\Transforms_Plain_Json_Template.json">
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Templating\Transforms_Scripted_Json_Template.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</None>
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public void Throws_Exception_When_Request_Has_Invalid_Json(string givenBody)

bodyStrategy.Invoking(async _ => await _.ReadBodyAsJson(httpRequest.Object))
.Should()
.Throw<JsonReaderException>();
.ThrowAsync<JsonReaderException>();
}

[Theory]
Expand Down
1 change: 1 addition & 0 deletions test/Mockaco.Tests/Usings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
global using Xunit;
4 changes: 4 additions & 0 deletions website/docs/configuration/_category_.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"label": "Configuration",
"position": 7
}
Loading

0 comments on commit f11e981

Please sign in to comment.