diff --git a/src/Messaging/NBB.Messaging.MultiTenancy/NBB.Messaging.MultiTenancy.csproj b/src/Messaging/NBB.Messaging.MultiTenancy/NBB.Messaging.MultiTenancy.csproj
index 1db817d0..5dbd641f 100644
--- a/src/Messaging/NBB.Messaging.MultiTenancy/NBB.Messaging.MultiTenancy.csproj
+++ b/src/Messaging/NBB.Messaging.MultiTenancy/NBB.Messaging.MultiTenancy.csproj
@@ -15,6 +15,7 @@
+
diff --git a/src/Messaging/NBB.Messaging.MultiTenancy/TenantMiddleware.cs b/src/Messaging/NBB.Messaging.MultiTenancy/TenantMiddleware.cs
index 5f4614ab..9dfd32f0 100644
--- a/src/Messaging/NBB.Messaging.MultiTenancy/TenantMiddleware.cs
+++ b/src/Messaging/NBB.Messaging.MultiTenancy/TenantMiddleware.cs
@@ -13,6 +13,9 @@
using NBB.MultiTenancy.Identification.Services;
using NBB.MultiTenancy.Abstractions;
using System.Diagnostics;
+using Microsoft.Extensions.Logging;
+using MediatR;
+using System.Linq;
namespace NBB.Messaging.MultiTenancy
{
@@ -21,45 +24,80 @@ namespace NBB.Messaging.MultiTenancy
/// obtained from the current identification strategy and builds the tenant context.
///
///
- public class TenantMiddleware : IPipelineMiddleware
- {
- private readonly ITenantContextAccessor _tenantContextAccessor;
- private readonly ITenantIdentificationService _tenantIdentificationService;
- private readonly IOptions _tenancyOptions;
- private readonly ITenantRepository _tenantRepository;
-
- public TenantMiddleware(ITenantContextAccessor tenantContextAccessor, ITenantIdentificationService tenantIdentificationService, IOptions tenancyOptions, ITenantRepository tenantRepository)
- {
- _tenantContextAccessor = tenantContextAccessor;
- _tenantIdentificationService = tenantIdentificationService;
- _tenancyOptions = tenancyOptions;
- _tenantRepository = tenantRepository;
- }
-
+ public class TenantMiddleware(
+ ITenantContextAccessor tenantContextAccessor,
+ ITenantIdentificationService tenantIdentificationService,
+ IOptions tenancyOptions,
+ ITenantRepository tenantRepository,
+ ILogger logger
+ ) : IPipelineMiddleware
+ {
public async Task Invoke(MessagingContext context, CancellationToken cancellationToken, Func next)
{
- if (_tenantContextAccessor.TenantContext != null)
+ if (tenantContextAccessor.TenantContext != null)
{
throw new ApplicationException("Tenant context is already set");
}
- if (_tenancyOptions.Value.TenancyType == TenancyType.MonoTenant)
+ if (tenancyOptions.Value.TenancyType == TenancyType.MonoTenant)
{
- _tenantContextAccessor.TenantContext = new TenantContext(Tenant.Default);
+ tenantContextAccessor.TenantContext = new TenantContext(Tenant.Default);
await next();
return;
}
- var tenantId = await _tenantIdentificationService.GetTenantIdAsync();
- var tenant = await _tenantRepository.Get(tenantId, cancellationToken)
- ?? throw new ApplicationException($"Tenant {tenantId} not found");
+ Tenant tenant;
+
+ if (context.MessagingEnvelope.Payload is INotification)
+ {
+ tenant = await TryLoadTenant(context.TopicName, cancellationToken);
+ if (tenant == null)
+ {
+ return;
+ }
+ }
+ else
+ {
+ tenant = await LoadTenant(cancellationToken);
+ }
- _tenantContextAccessor.TenantContext = new TenantContext(tenant);
- Activity.Current?.SetTag(TracingTags.TenantId, tenantId);
+ tenantContextAccessor.TenantContext = new TenantContext(tenant);
+
+ Activity.Current?.SetTag(TracingTags.TenantId, tenant.TenantId);
await next();
}
+
+ private async Task LoadTenant(CancellationToken cancellationToken)
+ {
+ var tenantId = await tenantIdentificationService.GetTenantIdAsync();
+ var tenant = await tenantRepository.Get(tenantId, cancellationToken)
+ ?? throw new ApplicationException($"Tenant {tenantId} not found");
+
+ return tenant;
+ }
+
+
+ private async Task TryLoadTenant(string topic, CancellationToken cancellationToken)
+ {
+ var tenantId = await tenantIdentificationService.TryGetTenantIdAsync();
+ if (!tenantId.HasValue)
+ {
+ logger.LogDebug("Tenant could not be identified. Message {Topic} will be ignored.", topic);
+ return null;
+ }
+
+ var tenant = await tenantRepository.TryGet(tenantId.Value, cancellationToken);
+ if (tenant == null)
+ {
+ logger.LogDebug("Tenant {Tenant} not found or not enabled. Message {Topic} will be ignored.", tenantId.Value, topic);
+ return null;
+ }
+
+ return tenant;
+ }
+
}
diff --git a/src/MultiTenancy/NBB.MultiTenancy.Abstractions/Repositories/CachedTenantRepositoryDecorator.cs b/src/MultiTenancy/NBB.MultiTenancy.Abstractions/Repositories/CachedTenantRepositoryDecorator.cs
index d9716f41..8c5aadec 100644
--- a/src/MultiTenancy/NBB.MultiTenancy.Abstractions/Repositories/CachedTenantRepositoryDecorator.cs
+++ b/src/MultiTenancy/NBB.MultiTenancy.Abstractions/Repositories/CachedTenantRepositoryDecorator.cs
@@ -23,7 +23,7 @@ public CachedTenantRepositoryDecorator(ITenantRepository tenantRepository, IDist
_cache = cache;
}
- public async Task Get(Guid id, CancellationToken token)
+ public async Task TryGet(Guid id, CancellationToken token)
{
var cacheKey = CacheTenantByIdKey(id);
var cachedTenant = await GetTenantFromCache(cacheKey, token);
@@ -31,8 +31,8 @@ public async Task Get(Guid id, CancellationToken token)
{
return cachedTenant;
}
-
- var dbTenant = await _tenantRepository.Get(id, token);
+
+ var dbTenant = await _tenantRepository.TryGet(id, token);
if (dbTenant == null)
{
return null;
diff --git a/src/MultiTenancy/NBB.MultiTenancy.Abstractions/Repositories/ConfigurationTenantRepository.cs b/src/MultiTenancy/NBB.MultiTenancy.Abstractions/Repositories/ConfigurationTenantRepository.cs
index 73c69efe..b1830014 100644
--- a/src/MultiTenancy/NBB.MultiTenancy.Abstractions/Repositories/ConfigurationTenantRepository.cs
+++ b/src/MultiTenancy/NBB.MultiTenancy.Abstractions/Repositories/ConfigurationTenantRepository.cs
@@ -43,15 +43,14 @@ public ConfigurationTenantRepository(IConfiguration configuration, IOptions Get(Guid id, CancellationToken token = default)
+ public Task TryGet(Guid id, CancellationToken token = default)
{
- if (!tenantMap.TryGetValue(id, out var result))
+ if (!tenantMap.TryGetValue(id, out var result) || !result.Enabled)
{
- throw new TenantNotFoundException(id);
+ return Task.FromResult(default(Tenant));
}
-
- return Task.FromResult(result.Enabled ? result : throw new Exception($"Tenant {result.Code} is disabled "));
+ return Task.FromResult(result);
}
public Task GetByHost(string host, CancellationToken token = default)
diff --git a/src/MultiTenancy/NBB.MultiTenancy.Abstractions/Repositories/ITenantRepository.cs b/src/MultiTenancy/NBB.MultiTenancy.Abstractions/Repositories/ITenantRepository.cs
index 9293e0e1..0ebf09d1 100644
--- a/src/MultiTenancy/NBB.MultiTenancy.Abstractions/Repositories/ITenantRepository.cs
+++ b/src/MultiTenancy/NBB.MultiTenancy.Abstractions/Repositories/ITenantRepository.cs
@@ -10,8 +10,11 @@ namespace NBB.MultiTenancy.Abstractions.Repositories
{
public interface ITenantRepository
{
- Task Get(Guid id, CancellationToken token = default);
+ Task TryGet(Guid id, CancellationToken token = default);
Task GetByHost(string host, CancellationToken token = default);
Task> GetAll(CancellationToken token = default);
+
+ async Task Get(Guid id, CancellationToken token = default)
+ => await TryGet(id, token) ?? throw new TenantNotFoundException(id);
}
}
diff --git a/test/UnitTests/MultiTenancy/NBB.MultiTenancy.Configuration.Tests/ConfigurationTenantRepositoryTests.cs b/test/UnitTests/MultiTenancy/NBB.MultiTenancy.Configuration.Tests/ConfigurationTenantRepositoryTests.cs
index a4602ca5..b9b8456c 100644
--- a/test/UnitTests/MultiTenancy/NBB.MultiTenancy.Configuration.Tests/ConfigurationTenantRepositoryTests.cs
+++ b/test/UnitTests/MultiTenancy/NBB.MultiTenancy.Configuration.Tests/ConfigurationTenantRepositoryTests.cs
@@ -190,14 +190,14 @@ public async Task get_tenant_should_throw_for_disabled_tenant()
var options = new OptionsWrapper(tenancyHostingOptions);
- var repo = new ConfigurationTenantRepository(configuration, options);
+ ITenantRepository repo = new ConfigurationTenantRepository(configuration, options);
//Act
Func action = async() =>
await repo.Get(Guid.Parse(tenantId));
//Assert
- await action.Should().ThrowAsync().WithMessage("*disabled*");
+ await action.Should().ThrowAsync();
}
[Fact]
@@ -232,7 +232,7 @@ public async Task get_should_bind_tenant_code_from_section_name()
var repo = new ConfigurationTenantRepository(configuration, options);
//arrange
- var actual = await repo.Get(System.Guid.Parse("ef8d5362-9969-4e02-8794-0d1af56816f6"));
+ var actual = await repo.TryGet(Guid.Parse("ef8d5362-9969-4e02-8794-0d1af56816f6"));
// Assert
actual.Should().NotBeNull();