From a26081c960786c3eb33f9b2173feed6c33427a74 Mon Sep 17 00:00:00 2001 From: Jeroen Verwimp Date: Thu, 21 Dec 2023 04:54:34 +0100 Subject: [PATCH] fix: OnTenantNotResolved not called correctly (#729) fix issue with OnTenantNotResolved only firing if the store failed to find a match rather than either the strategy not finding an identifier or the store not finding a match. fixes #628 --- src/Finbuckle.MultiTenant/TenantResolver.cs | 54 ++++++++-------- .../TenantResolverShould.cs | 63 +++++++++++++++++++ 2 files changed, 90 insertions(+), 27 deletions(-) diff --git a/src/Finbuckle.MultiTenant/TenantResolver.cs b/src/Finbuckle.MultiTenant/TenantResolver.cs index b5adf44c..af7d66b4 100644 --- a/src/Finbuckle.MultiTenant/TenantResolver.cs +++ b/src/Finbuckle.MultiTenant/TenantResolver.cs @@ -38,47 +38,47 @@ public TenantResolver(IEnumerable strategies, IEnumerable< public async Task?> ResolveAsync(object context) { - IMultiTenantContext? result = null; - + string? identifier = null; foreach (var strategy in Strategies) { var _strategy = new MultiTenantStrategyWrapper(strategy, loggerFactory?.CreateLogger(strategy.GetType()) ?? NullLogger.Instance); - var identifier = await _strategy.GetIdentifierAsync(context); + identifier = await _strategy.GetIdentifierAsync(context); if (options.CurrentValue.IgnoredIdentifiers.Contains(identifier, StringComparer.OrdinalIgnoreCase)) { (loggerFactory?.CreateLogger(GetType()) ?? NullLogger.Instance).LogInformation("Ignored identifier: {Identifier}", identifier); identifier = null; } + + if (identifier == null) + continue; - if (identifier != null) + foreach (var store in Stores) { - foreach (var store in Stores) - { - var _store = new MultiTenantStoreWrapper(store, loggerFactory?.CreateLogger(store.GetType()) ?? NullLogger.Instance); - var tenantInfo = await _store.TryGetByIdentifierAsync(identifier); - if (tenantInfo != null) - { - result = new MultiTenantContext(); - result.StoreInfo = new StoreInfo { Store = store, StoreType = store.GetType() }; - result.StrategyInfo = new StrategyInfo { Strategy = strategy, StrategyType = strategy.GetType() }; - result.TenantInfo = tenantInfo; - - await options.CurrentValue.Events.OnTenantResolved(new TenantResolvedContext { Context = - context, TenantInfo = tenantInfo, StrategyType = strategy.GetType(), StoreType = store.GetType()}); - - break; - } - } + var _store = new MultiTenantStoreWrapper(store, loggerFactory?.CreateLogger(store.GetType()) ?? NullLogger.Instance); + var tenantInfo = await _store.TryGetByIdentifierAsync(identifier); + if (tenantInfo == null) + continue; - if (result != null) - break; - - await options.CurrentValue.Events.OnTenantNotResolved(new TenantNotResolvedContext { Context = context, Identifier = identifier }); + await options.CurrentValue.Events.OnTenantResolved(new TenantResolvedContext + { + Context = context, + TenantInfo = tenantInfo, + StrategyType = strategy.GetType(), + StoreType = store.GetType() + }); + + return new MultiTenantContext + { + StoreInfo = new StoreInfo { Store = store, StoreType = store.GetType() }, + StrategyInfo = new StrategyInfo { Strategy = strategy, StrategyType = strategy.GetType() }, + TenantInfo = tenantInfo + }; } } - - return result; + + await options.CurrentValue.Events.OnTenantNotResolved(new TenantNotResolvedContext { Context = context, Identifier = identifier }); + return null; } // TODO move this to the base interface? diff --git a/test/Finbuckle.MultiTenant.Test/TenantResolverShould.cs b/test/Finbuckle.MultiTenant.Test/TenantResolverShould.cs index edf1f479..b4b2e967 100644 --- a/test/Finbuckle.MultiTenant.Test/TenantResolverShould.cs +++ b/test/Finbuckle.MultiTenant.Test/TenantResolverShould.cs @@ -8,6 +8,7 @@ using Finbuckle.MultiTenant.Strategies; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; +using System.Collections.Generic; using Xunit; namespace Finbuckle.MultiTenant.Test @@ -213,5 +214,67 @@ public void ReturnNullIfNoStoreSuccess() Assert.Null(result); } + + [Fact] + public void CallOnTenantResolvedEventIfSuccess() + { + TenantResolvedContext? resolvedContext = null; + + var configuration = new ConfigurationBuilder() + .AddJsonFile("ConfigurationStoreTestSettings.json") + .Build(); + + var services = new ServiceCollection(); + services.AddSingleton(configuration); + services.Configure(options => options.Events.OnTenantResolved = context => Task.FromResult(resolvedContext = context)); + services.AddMultiTenant() + .WithDelegateStrategy(_ => Task.FromResult("not-found")) + .WithStaticStrategy("initech") + .WithConfigurationStore(); + var sp = services.BuildServiceProvider(); + var resolver = sp.GetRequiredService>(); + + _ = resolver.ResolveAsync(new object()).Result; + + Assert.NotNull(resolvedContext); + Assert.Equal("initech", resolvedContext.TenantInfo!.Identifier); + Assert.Equal(typeof(StaticStrategy), resolvedContext.StrategyType); + Assert.Equal(typeof(ConfigurationStore), resolvedContext.StoreType); + } + + [Fact] + public void CallOnTenantNotResolvedEventIfNoStrategySuccess() + { + TenantNotResolvedContext? notResolvedContext = null; + + var services = new ServiceCollection(); + services.Configure(options => options.Events.OnTenantNotResolved = context => Task.FromResult(notResolvedContext = context)); + services + .AddMultiTenant() + .WithDelegateStrategy(_ => Task.FromResult(null!)); + var sp = services.BuildServiceProvider(); + var resolver = sp.GetRequiredService>(); + + _ = resolver.ResolveAsync(new object()).Result; + + Assert.NotNull(notResolvedContext); + } + + [Fact] + public void CallOnTenantNotResolvedEventIfNoStoreSuccess() + { + TenantNotResolvedContext? notResolvedContext = null; + var services = new ServiceCollection(); + services.Configure(options => options.Events.OnTenantNotResolved = context => Task.FromResult(notResolvedContext = context)); + services.AddMultiTenant() + .WithStaticStrategy("not-found") + .WithInMemoryStore(); + var sp = services.BuildServiceProvider(); + var resolver = sp.GetRequiredService>(); + + _ = resolver.ResolveAsync(new object()).Result; + + Assert.NotNull(notResolvedContext); + } } } \ No newline at end of file