Skip to content

Commit

Permalink
fix: OnTenantNotResolved not called correctly (#729)
Browse files Browse the repository at this point in the history
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
  • Loading branch information
thatgoofydev committed Dec 21, 2023
1 parent d7f08f9 commit a26081c
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 27 deletions.
54 changes: 27 additions & 27 deletions src/Finbuckle.MultiTenant/TenantResolver.cs
Expand Up @@ -38,47 +38,47 @@ public TenantResolver(IEnumerable<IMultiTenantStrategy> strategies, IEnumerable<

public async Task<IMultiTenantContext<T>?> ResolveAsync(object context)
{
IMultiTenantContext<T>? 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<T>(store, loggerFactory?.CreateLogger(store.GetType()) ?? NullLogger.Instance);
var tenantInfo = await _store.TryGetByIdentifierAsync(identifier);
if (tenantInfo != null)
{
result = new MultiTenantContext<T>();
result.StoreInfo = new StoreInfo<T> { 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<T>(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<T>
{
StoreInfo = new StoreInfo<T> { 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?
Expand Down
63 changes: 63 additions & 0 deletions test/Finbuckle.MultiTenant.Test/TenantResolverShould.cs
Expand Up @@ -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
Expand Down Expand Up @@ -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<IConfiguration>(configuration);
services.Configure<MultiTenantOptions>(options => options.Events.OnTenantResolved = context => Task.FromResult(resolvedContext = context));
services.AddMultiTenant<TenantInfo>()
.WithDelegateStrategy(_ => Task.FromResult<string?>("not-found"))
.WithStaticStrategy("initech")
.WithConfigurationStore();
var sp = services.BuildServiceProvider();
var resolver = sp.GetRequiredService<ITenantResolver<TenantInfo>>();

_ = resolver.ResolveAsync(new object()).Result;

Assert.NotNull(resolvedContext);
Assert.Equal("initech", resolvedContext.TenantInfo!.Identifier);
Assert.Equal(typeof(StaticStrategy), resolvedContext.StrategyType);
Assert.Equal(typeof(ConfigurationStore<TenantInfo>), resolvedContext.StoreType);
}

[Fact]
public void CallOnTenantNotResolvedEventIfNoStrategySuccess()
{
TenantNotResolvedContext? notResolvedContext = null;

var services = new ServiceCollection();
services.Configure<MultiTenantOptions>(options => options.Events.OnTenantNotResolved = context => Task.FromResult(notResolvedContext = context));
services
.AddMultiTenant<TenantInfo>()
.WithDelegateStrategy(_ => Task.FromResult<string?>(null!));
var sp = services.BuildServiceProvider();
var resolver = sp.GetRequiredService<ITenantResolver<TenantInfo>>();

_ = resolver.ResolveAsync(new object()).Result;

Assert.NotNull(notResolvedContext);
}

[Fact]
public void CallOnTenantNotResolvedEventIfNoStoreSuccess()
{
TenantNotResolvedContext? notResolvedContext = null;
var services = new ServiceCollection();
services.Configure<MultiTenantOptions>(options => options.Events.OnTenantNotResolved = context => Task.FromResult(notResolvedContext = context));
services.AddMultiTenant<TenantInfo>()
.WithStaticStrategy("not-found")
.WithInMemoryStore();
var sp = services.BuildServiceProvider();
var resolver = sp.GetRequiredService<ITenantResolver<TenantInfo>>();

_ = resolver.ResolveAsync(new object()).Result;

Assert.NotNull(notResolvedContext);
}
}
}

0 comments on commit a26081c

Please sign in to comment.