Skip to content
This repository has been archived by the owner on Apr 13, 2020. It is now read-only.

Commit

Permalink
Solves issue #4
Browse files Browse the repository at this point in the history
  • Loading branch information
eiximenis committed May 15, 2018
1 parent f0c1259 commit 7fe1454
Show file tree
Hide file tree
Showing 8 changed files with 119 additions and 14 deletions.
8 changes: 6 additions & 2 deletions samples/HttpApi-Basic/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;

namespace HttpApi_Basic
{

public class Startup
{
public Startup(IConfiguration configuration)
Expand All @@ -26,9 +28,11 @@ public void ConfigureServices(IServiceCollection services)
//add sql server health check
setup.AddSqlServer("Server=.;Initial Catalog=master;Integrated Security=true");
//add custom health check
setup.Add(new ActionLiveness("cat", "catapi", (httpContext, cancellationToken) =>
//add custom health check using factory method. Using factory method allows us to get services through IServiceProvider
setup.Add("catapi", sp => new ActionLiveness("cat", "catapi", (httpContext, cancellationToken) =>
{
var log = sp.GetRequiredService<ILogger<ActionLiveness>>();
log.LogInformation("Running ActionLiveness");
if ((DateTime.UtcNow.Minute & 1) == 1)
{
return Task.FromResult(("OK", true));
Expand Down
28 changes: 17 additions & 11 deletions src/BeatPulse/Core/BeatPulseContext.cs
Original file line number Diff line number Diff line change
@@ -1,26 +1,30 @@
using System;
using System.Collections.Generic;
using System.Linq;

namespace BeatPulse.Core
{
public sealed class BeatPulseContext
{
private readonly Dictionary<string, IBeatPulseLiveness> _activeLiveness = new Dictionary<string, IBeatPulseLiveness>();
private readonly Dictionary<string, IBeatPulseLivenessRegistration> _registeredLiveness = new Dictionary<string, IBeatPulseLivenessRegistration>();

public BeatPulseContext Add(IBeatPulseLiveness liveness)
private IServiceProvider _serviceProvider;

internal void UseServiceProvider(IServiceProvider sp) => _serviceProvider = sp;

public BeatPulseContext Add(IBeatPulseLivenessRegistration registration)
{
if (liveness == null)
if (registration == null)
{
throw new ArgumentNullException(nameof(liveness));
throw new ArgumentNullException(nameof(registration));
}

var path = liveness.Path;

var path = registration.Path;
if (!string.IsNullOrEmpty(path))
{
if (!_activeLiveness.ContainsKey(path))
if (!_registeredLiveness.ContainsKey(path))
{
_activeLiveness.Add(path, liveness);
_registeredLiveness.Add(path, registration);
}
else
{
Expand All @@ -32,21 +36,23 @@ public BeatPulseContext Add(IBeatPulseLiveness liveness)
else
{
throw new InvalidOperationException("The global path is automatically used for beat pulse.");

}
}


internal IBeatPulseLiveness FindLiveness(string path)
{
_activeLiveness.TryGetValue(path, out IBeatPulseLiveness check);
_registeredLiveness.TryGetValue(path, out IBeatPulseLivenessRegistration check);

return check;
return check?.GetOrCreateLiveness(_serviceProvider);
}

internal IEnumerable<IBeatPulseLiveness> AllLiveness
{
get
{
return _activeLiveness.Values;
return _registeredLiveness.Values.Select(r => r.GetOrCreateLiveness(_serviceProvider));
}
}
}
Expand Down
23 changes: 23 additions & 0 deletions src/BeatPulse/Core/BeatPulseFactoryRegistration.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace BeatPulse.Core
{
public class BeatPulseFactoryRegistration : IBeatPulseLivenessRegistration
{
private readonly Func<IServiceProvider, IBeatPulseLiveness> _creator;

public string Path { get; }
public Guid Id { get; }

public BeatPulseFactoryRegistration(string path, Func<IServiceProvider, IBeatPulseLiveness> creator)
{
_creator = creator ?? throw new ArgumentNullException(nameof(creator));
Id = Guid.NewGuid();
Path = path;
}

public IBeatPulseLiveness GetOrCreateLiveness(IServiceProvider sp) => _creator.Invoke(sp);
}
}
23 changes: 23 additions & 0 deletions src/BeatPulse/Core/BeatPulseInstanceRegistration.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace BeatPulse.Core
{
public class BeatPulseInstanceRegistration : IBeatPulseLivenessRegistration
{

private readonly IBeatPulseLiveness _instance;

public string Path => _instance.Path;
public Guid Id { get; }

public BeatPulseInstanceRegistration(IBeatPulseLiveness liveness)
{
_instance = liveness ?? throw new ArgumentNullException(nameof(liveness));
Id = Guid.NewGuid();
}

public IBeatPulseLiveness GetOrCreateLiveness(IServiceProvider sp) => _instance;
}
}
3 changes: 2 additions & 1 deletion src/BeatPulse/Core/BeatPulseService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@ public class BeatPulseService
private readonly ILogger<BeatPulseService> _logger;
private readonly IHostingEnvironment _environment;

public BeatPulseService(BeatPulseContext context, IHostingEnvironment environment, ILogger<BeatPulseService> logger)
public BeatPulseService(BeatPulseContext context, IHostingEnvironment environment, ILogger<BeatPulseService> logger, IServiceProvider serviceProvider)
{
_beatPulseContext = context ?? throw new ArgumentNullException(nameof(context));
_environment = environment ?? throw new ArgumentNullException(nameof(environment));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
context.UseServiceProvider(serviceProvider);
}

public async Task<IEnumerable<LivenessResult>> IsHealthy(string path, BeatPulseOptions options, HttpContext httpContext)
Expand Down
14 changes: 14 additions & 0 deletions src/BeatPulse/Core/BulsePulseContextExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace BeatPulse.Core
{
public static class BulsePulseContextExtensions
{
public static BeatPulseContext Add(this BeatPulseContext ctx, IBeatPulseLiveness liveness)
=> ctx.Add(new BeatPulseInstanceRegistration(liveness));
public static BeatPulseContext Add(this BeatPulseContext ctx, string path, Func<IServiceProvider, IBeatPulseLiveness> creator)
=> ctx.Add(new BeatPulseFactoryRegistration(path, creator));
}
}
14 changes: 14 additions & 0 deletions src/BeatPulse/Core/IBeatPulseLivenessRegistration.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace BeatPulse.Core
{
public interface IBeatPulseLivenessRegistration
{
Guid Id { get; }
string Path { get; }
IBeatPulseLiveness GetOrCreateLiveness(IServiceProvider sp);
}

}
20 changes: 20 additions & 0 deletions tests/UnitTests/BeatPulse/ServiceCollectionExtensionsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,17 @@ public void register_beat_pulse_contxt()
.BeOfType<BeatPulseContext>();
}

[Fact]
public void set_valid_serviceprovider_to_context_to_allow_resolve_serviced_liveness()
{
var service = _serviceProvider.GetService<IBeatPulseService>(); // Need to resolve IBeatPulseService because its it who injects IServiceProvider to context
var beatPulseContext = _serviceProvider.GetService<BeatPulseContext>();
string path2;
beatPulseContext.FindLiveness(nameof(path2))
.Should()
.NotBeNull();
}

[Fact]
public void execute_the_context_setup()
{
Expand All @@ -54,17 +65,26 @@ public void execute_the_context_setup()

class DefaultStartup
{
class FooService { }
public void ConfigureServices(IServiceCollection services)
{
string name;
string path;
string path2;

var taskResult = Task.FromResult((string.Empty, true));

services.AddBeatPulse(context =>
{
context.Add(new ActionLiveness(nameof(name), nameof(path), (httpcontext, cancellationToken) => taskResult));
context.Add(nameof(path2), sp =>
{
var service = sp.GetRequiredService<FooService>();
return new ActionLiveness(nameof(path2), nameof(path2), (httpcontext, cancellationToken) => taskResult);
});
});

services.AddTransient<FooService>();
}

public void Configure(IApplicationBuilder app)
Expand Down

0 comments on commit 7fe1454

Please sign in to comment.