6 Commits

Author SHA1 Message Date
802806b4c2 Renamed frontend service to Message Queue Service
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2021-01-17 18:01:15 +01:00
79dcb4d75a Added RabbitMq IsConnected
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2021-01-17 17:13:26 +01:00
7c67fa7de0 Array empty
All checks were successful
continuous-integration/drone/push Build is passing
2021-01-17 16:54:39 +01:00
e9ffe514dd Added new rabbitmq configs
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2021-01-17 16:45:11 +01:00
20a4b4d349 Moved Dockerfile, fixed RabbitMq connection fail in constructor
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2021-01-17 15:41:06 +01:00
579481ce16 Fixed Nlog.config
Some checks failed
continuous-integration/drone/push Build is failing
continuous-integration/drone/pr Build is failing
2021-01-17 13:11:14 +01:00
13 changed files with 151 additions and 43 deletions

View File

@ -82,7 +82,7 @@ namespace Birdmap.API.Controllers
Service = new() Service = new()
{ {
Id = 0, Id = 0,
Name = "Mqtt Client Service", Name = "Message Queue Service",
Uri = "localhost", Uri = "localhost",
}, },
Response = $"IsConnected: {_communicationService.IsConnected}", Response = $"IsConnected: {_communicationService.IsConnected}",

View File

@ -12,6 +12,7 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
using Microsoft.IdentityModel.Tokens; using Microsoft.IdentityModel.Tokens;
using NSwag.Generation.Processors.Security; using NSwag.Generation.Processors.Security;
using System;
using System.Text; using System.Text;
namespace Birdmap.API namespace Birdmap.API
@ -71,7 +72,7 @@ namespace Birdmap.API
{ {
opt.Title = "Birdmap"; opt.Title = "Birdmap";
opt.OperationProcessors.Add(new OperationSecurityScopeProcessor("Jwt Token")); opt.OperationProcessors.Add(new OperationSecurityScopeProcessor("Jwt Token"));
opt.AddSecurity("Jwt Token", new string[] { }, opt.AddSecurity("Jwt Token", Array.Empty<string>(),
new NSwag.OpenApiSecurityScheme new NSwag.OpenApiSecurityScheme
{ {
Type = NSwag.OpenApiSecuritySchemeType.ApiKey, Type = NSwag.OpenApiSecuritySchemeType.ApiKey,
@ -95,11 +96,9 @@ namespace Birdmap.API
app.UseOpenApi(); app.UseOpenApi();
app.UseSwaggerUi3(); app.UseSwaggerUi3();
app.UseHttpsRedirection();
app.UseStaticFiles(); app.UseStaticFiles();
app.UseSpaStaticFiles(); app.UseSpaStaticFiles();
app.UseAuthentication(); app.UseAuthentication();
app.UseRouting(); app.UseRouting();
app.UseAuthorization(); app.UseAuthorization();

View File

@ -27,10 +27,25 @@
"UseRabbitMq": false, "UseRabbitMq": false,
"Mqtt": { "Mqtt": {
"BrokerHostSettings": { "BrokerHostSettings": {
"VirtualHost": "",
"Host": "", "Host": "",
"Port": 1883 "Port": 1883
}, },
"ExchangeSettings": {
"Name": "",
"Type": "",
"Durable": false,
"AutoDelete": false
},
"QueueSettings": {
"Name": "",
"Durable": false,
"Exclusive": false,
"AutoDelete": false
},
"ClientSettings": { "ClientSettings": {
"Id": "ASP.NET Core client", "Id": "ASP.NET Core client",
"Username": "", "Username": "",

View File

@ -35,6 +35,8 @@
<!--Skip non-critical Mqtt logs--> <!--Skip non-critical Mqtt logs-->
<logger name="*.*Mqtt*.*" minlevel="Trace" maxlevel="Warning" writeTo="mqttFile" final="true"/> <logger name="*.*Mqtt*.*" minlevel="Trace" maxlevel="Warning" writeTo="mqttFile" final="true"/>
<logger name="*.*RabbitMq*.*" minlevel="Trace" maxlevel="Warning" writeTo="mqttFile" final="true"/>
<logger name="*.*CommunicationServiceBase*.*" minlevel="Trace" maxlevel="Warning" writeTo="mqttFile" final="true"/>
<!--Skip non-critical Hub logs--> <!--Skip non-critical Hub logs-->
<logger name="*.*Hubs*.*" minlevel="Trace" maxlevel="Warning" writeTo="hubsFile" final="true"/> <logger name="*.*Hubs*.*" minlevel="Trace" maxlevel="Warning" writeTo="hubsFile" final="true"/>

View File

@ -1,6 +1,8 @@
namespace Birdmap.BLL.Interfaces using Microsoft.Extensions.Hosting;
namespace Birdmap.BLL.Interfaces
{ {
public interface ICommunicationService public interface ICommunicationService : IHostedService
{ {
public bool IsConnected { get; } public bool IsConnected { get; }
} }

View File

@ -5,8 +5,7 @@ using MQTTnet.Client.Receiving;
namespace Birdmap.BLL.Interfaces namespace Birdmap.BLL.Interfaces
{ {
public interface IMqttClientService : IHostedService, public interface IMqttClientService : IMqttClientConnectedHandler,
IMqttClientConnectedHandler,
IMqttClientDisconnectedHandler, IMqttClientDisconnectedHandler,
IMqttApplicationMessageReceivedHandler IMqttApplicationMessageReceivedHandler
{ {

View File

@ -1,4 +1,11 @@
namespace Birdmap.BLL.Options namespace Birdmap.BLL.Options
{ {
public record RabbitMqClientOptions(string Hostname, int Port, string Username, string Password, string Topic); public record RabbitMqClientOptions(
string Hostname, int Port, string VirtualHost,
string Username, string Password,
string ExchangeName, string ExchangeType,
bool ExchangeDurable, bool ExchangeAutoDelete,
string QueueName,
bool QueueDurable, bool QueueAutoDelete, bool QueueExclusive,
string Topic);
} }

View File

@ -6,6 +6,7 @@ using Newtonsoft.Json;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Timer = System.Timers.Timer; using Timer = System.Timers.Timer;
@ -83,5 +84,9 @@ namespace Birdmap.BLL.Services.CommunationServices
} }
} }
} }
public abstract Task StartAsync(CancellationToken cancellationToken);
public abstract Task StopAsync(CancellationToken cancellationToken);
} }
} }

View File

@ -81,7 +81,7 @@ namespace Birdmap.BLL.Services.CommunicationServices.Mqtt
} }
} }
public async Task StartAsync(CancellationToken cancellationToken) public override async Task StartAsync(CancellationToken cancellationToken)
{ {
try try
{ {
@ -97,7 +97,7 @@ namespace Birdmap.BLL.Services.CommunicationServices.Mqtt
} }
} }
public async Task StopAsync(CancellationToken cancellationToken) public override async Task StopAsync(CancellationToken cancellationToken)
{ {
try try
{ {

View File

@ -7,21 +7,25 @@ using RabbitMQ.Client;
using RabbitMQ.Client.Events; using RabbitMQ.Client.Events;
using System; using System;
using System.Text; using System.Text;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Birdmap.BLL.Services.CommunationServices.RabbitMq namespace Birdmap.BLL.Services.CommunationServices.RabbitMq
{ {
internal class RabbitMqClientService : CommunicationServiceBase, IDisposable internal class RabbitMqClientService : CommunicationServiceBase
{ {
private readonly IConnection _connection; private IConnection _connection;
private readonly IModel _channel; private IModel _channel;
private readonly IConnectionFactory _factory;
private readonly RabbitMqClientOptions _options;
public override bool IsConnected => throw new NotImplementedException(); public override bool IsConnected => _connection.IsOpen;
public RabbitMqClientService(RabbitMqClientOptions options, ILogger<RabbitMqClientService> logger, IInputService inputService, IHubContext<DevicesHub, IDevicesHubClient> hubContext) public RabbitMqClientService(RabbitMqClientOptions options, ILogger<RabbitMqClientService> logger, IInputService inputService, IHubContext<DevicesHub, IDevicesHubClient> hubContext)
: base(logger, inputService, hubContext) : base(logger, inputService, hubContext)
{ {
var factory = new ConnectionFactory() _options = options;
_factory = new ConnectionFactory()
{ {
HostName = options.Hostname, HostName = options.Hostname,
Port = options.Port, Port = options.Port,
@ -30,25 +34,6 @@ namespace Birdmap.BLL.Services.CommunationServices.RabbitMq
AutomaticRecoveryEnabled = true, AutomaticRecoveryEnabled = true,
}; };
_connection = factory.CreateConnection();
_channel = _connection.CreateModel();
_channel.ExchangeDeclare(exchange: "topic_logs", type: "topic");
var queueName = _channel.QueueDeclare().QueueName;
_channel.QueueBind(queue: queueName,
exchange: "topic_logs",
routingKey: options.Topic);
var consumer = new AsyncEventingBasicConsumer(_channel);
consumer.Received += OnRecieved;
_channel.BasicConsume(queue: queueName,
autoAck: true,
consumer: consumer);
StartMessageTimer();
} }
private Task OnRecieved(object sender, BasicDeliverEventArgs eventArgs) private Task OnRecieved(object sender, BasicDeliverEventArgs eventArgs)
@ -62,11 +47,68 @@ namespace Birdmap.BLL.Services.CommunationServices.RabbitMq
return ProcessJsonMessageAsync(body); return ProcessJsonMessageAsync(body);
} }
public void Dispose() public override async Task StartAsync(CancellationToken cancellationToken)
{
try
{
Connect();
}
catch (Exception ex)
{
_logger.LogError(ex, $"Cannot connect. Reconnecting...");
await Task.Delay(TimeSpan.FromSeconds(5), cancellationToken);
cancellationToken.ThrowIfCancellationRequested();
await StartAsync(cancellationToken);
}
}
public override Task StopAsync(CancellationToken cancellationToken)
{
try
{ {
StopMessageTimer(); StopMessageTimer();
_channel.Close(); _channel?.Close();
_connection.Close(); _connection?.Close();
return Task.CompletedTask;
}
catch (Exception ex)
{
_logger.LogError(ex, $"Cannot disconnect...");
return Task.FromException(ex);
}
}
private void Connect()
{
_connection = _factory.CreateConnection();
_channel = _connection.CreateModel();
_channel.ExchangeDeclare(
exchange: _options.ExchangeName,
type: _options.ExchangeType,
durable: _options.ExchangeDurable,
autoDelete: _options.ExchangeAutoDelete);
_channel.QueueDeclare(
queue: _options.QueueName,
durable: _options.QueueDurable,
exclusive: _options.QueueExclusive,
autoDelete: _options.QueueAutoDelete);
_channel.QueueBind(queue: _options.QueueName,
exchange: _options.ExchangeName,
routingKey: _options.Topic);
var consumer = new AsyncEventingBasicConsumer(_channel);
consumer.Received += OnRecieved;
_channel.BasicConsume(queue: _options.QueueName,
autoAck: true,
consumer: consumer);
StartMessageTimer();
} }
} }
} }

View File

@ -61,6 +61,25 @@ namespace Birdmap.BLL
{ {
Host = brokerHost.GetValue<string>("Host"), Host = brokerHost.GetValue<string>("Host"),
Port = brokerHost.GetValue<int>("Port"), Port = brokerHost.GetValue<int>("Port"),
VirtualHost = brokerHost.GetValue<string>("VirtualHost"),
};
var exchange = mqtt.GetSection("ExchangeSettings");
var exchangeSettings = new
{
Name = exchange.GetValue<string>("Name"),
Type = exchange.GetValue<string>("Type"),
Durable = exchange.GetValue<bool>("Durable"),
AutoDelete = exchange.GetValue<bool>("AutoDelete"),
};
var queue = mqtt.GetSection("QueueSettings");
var queueSettings = new
{
Name = queue.GetValue<string>("Name"),
Durable = exchange.GetValue<bool>("Durable"),
Exclusive = exchange.GetValue<bool>("Exclusive"),
AutoDelete = exchange.GetValue<bool>("AutoDelete"),
}; };
if (configuration.GetValue<bool>("UseRabbitMq")) if (configuration.GetValue<bool>("UseRabbitMq"))
@ -68,8 +87,17 @@ namespace Birdmap.BLL
services.AddRabbitMqClientServiceWithConfig(new RabbitMqClientOptions( services.AddRabbitMqClientServiceWithConfig(new RabbitMqClientOptions(
Hostname: brokerHostSettings.Host, Hostname: brokerHostSettings.Host,
Port: brokerHostSettings.Port, Port: brokerHostSettings.Port,
VirtualHost: brokerHostSettings.VirtualHost,
Username: clientSettings.Username, Username: clientSettings.Username,
Password: clientSettings.Password, Password: clientSettings.Password,
ExchangeName: exchangeSettings.Name,
ExchangeType: exchangeSettings.Type,
ExchangeDurable: exchangeSettings.Durable,
ExchangeAutoDelete: exchangeSettings.AutoDelete,
QueueName: queueSettings.Name,
QueueDurable: queueSettings.Durable,
QueueExclusive: queueSettings.Exclusive,
QueueAutoDelete: queueSettings.AutoDelete,
Topic: clientSettings.Topic)); Topic: clientSettings.Topic));
} }
else else
@ -111,9 +139,9 @@ namespace Birdmap.BLL
private static IServiceCollection AddClientServiceWithProvider<T>(this IServiceCollection services) where T : class, ICommunicationService private static IServiceCollection AddClientServiceWithProvider<T>(this IServiceCollection services) where T : class, ICommunicationService
{ {
services.AddSingleton<T>(); services.AddSingleton<T>();
services.AddSingleton(serviceProvider => services.AddSingleton<IHostedService>(serviceProvider =>
{ {
return (IHostedService)serviceProvider.GetService<T>(); return serviceProvider.GetService<T>();
}); });
services.AddSingleton<ICommunicationServiceProvider>(serviceProvider => services.AddSingleton<ICommunicationServiceProvider>(serviceProvider =>
{ {

View File

@ -17,7 +17,7 @@ services:
- ${APPDATA}/ASP.NET/Https:/root/.aspnet/https:ro - ${APPDATA}/ASP.NET/Https:/root/.aspnet/https:ro
build: build:
context: . context: .
dockerfile: Birdmap.API/Dockerfile dockerfile: Dockerfile
depends_on: depends_on:
- db - db
environment: environment:
@ -38,9 +38,18 @@ services:
- Birdmap_Defaults__Services__KMLabz-Service=https://birb.k8s.kmlabz.com/devices - Birdmap_Defaults__Services__KMLabz-Service=https://birb.k8s.kmlabz.com/devices
- Birdmap_UseDummyServices=true - Birdmap_UseDummyServices=true
- Birdmap_ServicesBaseUrl=https://birb.k8s.kmlabz.com/ - Birdmap_ServicesBaseUrl=https://birb.k8s.kmlabz.com/
- Birdmap_UseRabbitMq=true - Birdmap_UseRabbitMq=false
- Birdmap_Mqtt__BrokerHostSettings__Host=localhost - Birdmap_Mqtt__BrokerHostSettings__Host=localhost
- Birdmap_Mqtt__BrokerHostSettings__Port=1883 - Birdmap_Mqtt__BrokerHostSettings__Port=1883
- Birdmap_Mqtt__BrokerHostSettings__VirtualHost=/
- Birdmap_Mqtt__ExchangeSettings__Name=birbmapexchange
- Birdmap_Mqtt__ExchangeSettings__Type=fanout
- Birdmap_Mqtt__ExchangeSettings__Durable=true
- Birdmap_Mqtt__ExchangeSettings__AutoDelete=true
- Birdmap_Mqtt__QueueSettings__Name=birbmapqueue
- Birdmap_Mqtt__QueueSettings__Durable=true
- Birdmap_Mqtt__QueueSettings__Exclusive=true
- Birdmap_Mqtt__QueueSettings__AutoDelete=true
- Birdmap_Mqtt__ClientSettings__Id=ASP.NET Core client - Birdmap_Mqtt__ClientSettings__Id=ASP.NET Core client
- Birdmap_Mqtt__ClientSettings__Username=username - Birdmap_Mqtt__ClientSettings__Username=username
- Birdmap_Mqtt__ClientSettings__Password=password - Birdmap_Mqtt__ClientSettings__Password=password