Skip to content

Commit

Permalink
add health check to code and docker (#7)
Browse files Browse the repository at this point in the history
Co-authored-by: Piotr Rojek <[email protected]>
  • Loading branch information
piotr-rojek and dra9ula authored Feb 12, 2023
1 parent 7c17f94 commit 59d3173
Show file tree
Hide file tree
Showing 9 changed files with 128 additions and 45 deletions.
8 changes: 6 additions & 2 deletions src/ServiceBusEmulator.Host/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,17 @@ FROM --platform=amd64 mcr.microsoft.com/dotnet/sdk:7.0 AS build-env
WORKDIR /app/src/ServiceBusEmulator.Host
RUN dotnet publish -c Release -o /app/out

FROM mcr.microsoft.com/dotnet/runtime:7.0
FROM mcr.microsoft.com/dotnet/aspnet:7.0

ENV DOTNET_ENVIRONMENT=Docker

RUN apt-get update
RUN apt-get --yes install curl
HEALTHCHECK --interval=5s --timeout=10s --retries=3 CMD curl --fail http://localhost:80/health || exit 1

WORKDIR /app
COPY --from=build-env /app/out .
COPY --from=server-cert /home/testca/cert.pfx .
COPY --from=server-cert /home/testca/cacert.cer .

ENTRYPOINT ["dotnet", "ServiceBusEmulator.Host.dll"]
17 changes: 8 additions & 9 deletions src/ServiceBusEmulator.Host/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,14 @@
using ServiceBusEmulator;
using ServiceBusEmulator.RabbitMq;

IHost host = Host.CreateDefaultBuilder(args)
.ConfigureServices(services =>
{
_ = services.AddServiceBusEmulator();
_ = services.AddServiceBusEmulatorRabbitMqBackend();
})
.Build();

Trace.TraceLevel = TraceLevel.Frame;
Trace.TraceListener = (l, f, a) => Console.WriteLine(DateTime.Now.ToString("[hh:mm:ss.fff]") + " " + string.Format(f, a));

host.Run();
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddServiceBusEmulator();
builder.Services.AddServiceBusEmulatorRabbitMqBackend();

var app = builder.Build();
app.UseHealthChecks("/health");
app.UseRouting();
app.Run();
2 changes: 1 addition & 1 deletion src/ServiceBusEmulator.Host/ServiceBusEmulator.Host.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk.Worker">
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
Expand Down
3 changes: 3 additions & 0 deletions src/ServiceBusEmulator.RabbitMq/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public static IServiceCollection AddServiceBusEmulatorRabbitMqBackend(this IServ

_ = services.AddSingleton<ILinkProcessor, RabbitMqLinkProcessor>();
_ = services.AddSingleton<IRabbitMqLinkRegister, RabbitMqLinkRegister>();
_ = services.AddSingleton<IRabbitMqChannelFactory, RabbitMqChannelFactory>();
_ = services.AddTransient<IRabbitMqLinkEndpointFactory, RabbitMqLinkEndpointFactory>();
_ = services.AddTransient<IRabbitMqManagementCommandFactory, RabbitMqManagementCommandFactory>();
_ = services.AddTransient<IRabbitMqDeliveryTagTracker, RabbitMqDeliveryTagTracker>();
Expand All @@ -35,6 +36,8 @@ public static IServiceCollection AddServiceBusEmulatorRabbitMqBackend(this IServ

_ = services.AddOptions<RabbitMqBackendOptions>().Configure(configure).BindConfiguration("Emulator:RabbitMq");

_ = services.AddHealthChecks().AddCheck<RabbitMqHealthCheck>("rabbitmq");

return services;
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using RabbitMQ.Client;

namespace ServiceBusEmulator.RabbitMq.Links
{
public interface IRabbitMqChannelFactory
{
IModel CreateChannel();
}
}
68 changes: 68 additions & 0 deletions src/ServiceBusEmulator.RabbitMq/Links/RabbitMqChannelFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
using Microsoft.Extensions.Options;
using RabbitMQ.Client;
using ServiceBusEmulator.RabbitMq.Options;

namespace ServiceBusEmulator.RabbitMq.Links
{
public class RabbitMqChannelFactory : IRabbitMqChannelFactory, IDisposable
{
private readonly RabbitMqBackendOptions _options;

private IConnection? _connection;
private ConnectionFactory _connectionFactory;

private bool _disposed;

public RabbitMqChannelFactory(IOptions<RabbitMqBackendOptions> options)
{
_options = options.Value;

_connectionFactory = new()
{
Password = _options.Password,
UserName = _options.Username,
HostName = _options.Host,
Port = _options.Port
};
}

protected IConnection Connection
{
get
{
if (_disposed)
{
throw new ObjectDisposedException(nameof(RabbitMqChannelFactory));
}

if (!(_connection?.IsOpen ?? false))
{
lock (_connectionFactory)
{
if (!(_connection?.IsOpen ?? false))
{
_connection = _connectionFactory.CreateConnection();
}
}
}

return _connection;
}
}

public IModel CreateChannel()
{
return Connection.CreateModel();
}

public void Dispose()
{
if (!_disposed && _connection != null)
{
_connection.Dispose();
_connection = null;
}
_disposed = true;
}
}
}
37 changes: 4 additions & 33 deletions src/ServiceBusEmulator.RabbitMq/Links/RabbitMqLinkProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,60 +2,31 @@
using Amqp.Framing;
using Amqp.Listener;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using RabbitMQ.Client;
using ServiceBusEmulator.Abstractions.Security;
using ServiceBusEmulator.RabbitMq.Options;

namespace ServiceBusEmulator.RabbitMq.Links
{
public class RabbitMqLinkProcessor : ILinkProcessor
{
private readonly RabbitMqBackendOptions _options;
private readonly IRabbitMqLinkEndpointFactory _linkEndpointFactory;
private readonly IRabbitMqLinkRegister _linkRegister;
private readonly IRabbitMqChannelFactory _channelFactory;
private readonly IRabbitMqInitializer _initializer;
private readonly ISecurityContext _securityContext;
private readonly ILogger _logger;

private RabbitMQ.Client.IConnection? _connection;
private RabbitMQ.Client.ConnectionFactory _connectionFactory;

public RabbitMqLinkProcessor(IRabbitMqInitializer intializer, ISecurityContext securityContext, IOptions<RabbitMqBackendOptions> options, ILogger<RabbitMqLinkProcessor> logger, IRabbitMqLinkRegister linkRegister, IRabbitMqLinkEndpointFactory linkEndpointFactory)
public RabbitMqLinkProcessor(IRabbitMqChannelFactory channelFactory,IRabbitMqInitializer intializer, ISecurityContext securityContext, ILogger<RabbitMqLinkProcessor> logger, IRabbitMqLinkRegister linkRegister, IRabbitMqLinkEndpointFactory linkEndpointFactory)
{
_options = options.Value;
_connectionFactory = new()
{
Password = _options.Password,
UserName = _options.Username,
HostName = _options.Host,
Port = _options.Port
};
_channelFactory = channelFactory;
_initializer = intializer;
_securityContext = securityContext;
_logger = logger;
_linkRegister = linkRegister;
_linkEndpointFactory = linkEndpointFactory;
}

protected RabbitMQ.Client.IConnection Connection
{
get
{
if (!(_connection?.IsOpen ?? false))
{
lock (_connectionFactory)
{
if (!(_connection?.IsOpen ?? false))
{
_connection = _connectionFactory.CreateConnection();
}
}
}

return _connection;
}
}

public void Process(AttachContext attachContext)
{
Expand All @@ -73,7 +44,7 @@ public void Process(AttachContext attachContext)
return;
}

IModel channel = Connection.CreateModel();
IModel channel = _channelFactory.CreateChannel();
_initializer.Initialize(channel);

(var linkEndpoint, int initialCredit) = _linkEndpointFactory.CreateEndpoint(channel, attachContext.Attach, attachContext.Link.Role);
Expand Down
28 changes: 28 additions & 0 deletions src/ServiceBusEmulator.RabbitMq/RabbitMqHealthCheck.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using Microsoft.Extensions.Diagnostics.HealthChecks;
using ServiceBusEmulator.RabbitMq.Links;

namespace ServiceBusEmulator.RabbitMq
{
public class RabbitMqHealthCheck : IHealthCheck
{
private readonly IRabbitMqChannelFactory _channelFactory;

public RabbitMqHealthCheck(IRabbitMqChannelFactory channelFactory)
{
_channelFactory = channelFactory;
}

public Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default)
{
try
{
using var model = _channelFactory.CreateChannel();
return Task.FromResult(HealthCheckResult.Healthy());
}
catch (Exception ex)
{
return Task.FromResult(new HealthCheckResult(context.Registration.FailureStatus, exception: ex));
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks" Version="7.0.2" />
<PackageReference Include="RabbitMQ.Client" Version="6.4.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.0" />
</ItemGroup>
Expand Down

0 comments on commit 59d3173

Please sign in to comment.