Skip to content

Commit

Permalink
Multitenant messaging and identification configuration extensions (#61)
Browse files Browse the repository at this point in the history
* Multitenant messaging and identification configuration extensions
  • Loading branch information
fraliv13 authored Feb 12, 2020
1 parent 1600b12 commit 7e3e36d
Show file tree
Hide file tree
Showing 15 changed files with 236 additions and 109 deletions.

This file was deleted.

13 changes: 12 additions & 1 deletion samples/MicroServices/NBB.Contracts/NBB.Contracts.Api/Startup.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using NBB.Contracts.Api.MultiTenancy;
using NBB.Contracts.ReadModel.Data;
using NBB.Correlation.AspNet;
using NBB.Messaging.MultiTenancy;
using NBB.Messaging.Nats;
using NBB.MultiTenancy.Abstractions.Hosting;
using NBB.MultiTenancy.Identification.Http.Extensions;

namespace NBB.Contracts.Api
{
Expand All @@ -23,13 +28,19 @@ public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddSingleton<IConfiguration>(Configuration);
services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();

//services.AddKafkaMessaging();
services.AddNatsMessaging();

services.AddContractsReadModelDataAccess();

services.AddMultiTenancy(Configuration);
services.AddMultitenancy(Configuration, _ =>
{
services.AddMultiTenantMessaging();
services.AddTenantHostingConfigService<TenantHostingConfigService>();
services.AddDefaultHttpTenantIdentification();
});
}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
using System.Threading.Tasks;
using NBB.Contracts.Worker.MultiTenancy;
using NBB.Messaging.MultiTenancy;
using NBB.MultiTenancy.Abstractions.Hosting;
using NBB.MultiTenancy.Identification.Messaging.Extensions;

namespace NBB.Contracts.Worker
{
Expand Down Expand Up @@ -92,7 +94,12 @@ public static async Task MainAsync(string[] args)
.UseMediatRMiddleware()
);

services.AddMultiTenancy(hostingContext.Configuration);
services.AddMultitenancy(hostingContext.Configuration, _ =>
{
services.AddTenantHostingConfigService<TenantHostingConfigService>();
services.AddMultiTenantMessaging()
.AddDefaultMessagingTenantIdentification();
});
});

var host = builder.UseConsoleLifetime().Build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ namespace NBB.Messaging.MultiTenancy
{
public static class DependencyInjectionExtensions
{
public static void AddMultiTenantMessaging(this IServiceCollection services)
public static IServiceCollection AddMultiTenantMessaging(this IServiceCollection services)
{
services.Decorate<ITopicRegistry, MultiTenancyTopicRegistryDecorator>();
services.Decorate<IMessageBusPublisher, MultiTenancyMessageBusPublisherDecorator>();

return services;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
<ProjectReference Include="..\..\Core\NBB.Core.DependencyInjection\NBB.Core.DependencyInjection.csproj" />
<ProjectReference Include="..\..\Core\NBB.Core.Pipeline\NBB.Core.Pipeline.csproj" />
<ProjectReference Include="..\..\MultiTenancy\NBB.MultiTenancy.Abstractions\NBB.MultiTenancy.Abstractions.csproj" />
<ProjectReference Include="..\..\MultiTenancy\NBB.MultiTenancy.Identification.Messaging\NBB.MultiTenancy.Identification.Messaging.csproj" />
<ProjectReference Include="..\..\MultiTenancy\NBB.MultiTenancy.Identification\NBB.MultiTenancy.Identification.csproj" />
<ProjectReference Include="..\NBB.Messaging.Abstractions\NBB.Messaging.Abstractions.csproj" />
</ItemGroup>

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@ public async Task Invoke(MessagingEnvelope message, CancellationToken cancellati
$"Invalid tenant ID for message {message.Payload.GetType()}. Expected {contextTenantId} but received {messageTenantIdHeader}");
}

if (_tenancyOptions.Value.TenancyType == TenancyType.MonoTenant && _tenancyOptions.Value.TenantId != messageTenantId)
{
throw new ApplicationException(
$"Invalid tenant ID for message {message.Payload.GetType()}. Expected {_tenancyOptions.Value.TenantId} but received {messageTenantIdHeader}");
}

if (_tenantHostingConfigService.IsShared(messageTenantId) &&
_tenancyOptions.Value.TenancyType == TenancyType.MonoTenant)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,36 @@
using Microsoft.Extensions.DependencyInjection;
using System;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using NBB.MultiTenancy.Abstractions.Options;
using NBB.MultiTenancy.Abstractions.Services;

namespace NBB.MultiTenancy.Abstractions.Hosting
{
public static class ServiceCollectionExtensions
{
public static void AddHostingConfigValidation(this IServiceCollection services)
private const string MessagingSectionName = "MultiTenancy";

public static void AddMultitenancy(this IServiceCollection services, IConfiguration configuration,
Action<TenancyHostingOptions> addTenantAwareServices)
{
var configurationSection = configuration.GetSection(MessagingSectionName);
var tenancyOptions = configurationSection.Get<TenancyHostingOptions>();
if (tenancyOptions == null || tenancyOptions.TenancyType == TenancyType.None)
{
return;
}

services.AddSingleton<IHostedService, TenancyHostingValidator>();
services.Configure<TenancyHostingOptions>(configurationSection);

addTenantAwareServices(tenancyOptions);
}

public static void AddTenantHostingConfigService<TTenantHostingConfigService>(this IServiceCollection services)
where TTenantHostingConfigService : class, ITenantHostingConfigService
{
services.AddSingleton<ITenantHostingConfigService, TTenantHostingConfigService>();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Options" Version="$(MicrosoftExtensionsPackagesVersion)" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="$(MicrosoftExtensionsPackagesVersion)" />
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="$(MicrosoftExtensionsPackagesVersion)" />
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="$(MicrosoftExtensionsPackagesVersion)" />
</ItemGroup>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using Microsoft.Extensions.DependencyInjection;
using NBB.MultiTenancy.Identification.Identifiers;
using NBB.MultiTenancy.Identification.Extensions;


namespace NBB.MultiTenancy.Identification.Http.Extensions
{
public static class DependencyInjectionExtensions
{
public static string DefaultTenantHttpHeaderName = "TenantId";
public static string DefaultTenantQueryStringParamName = "tenantId";

public static IServiceCollection AddDefaultHttpTenantIdentification(this IServiceCollection services)
{

services.AddTenantIdentification()
.AddTenantIdentificationStrategy<IdTenantIdentifier>(builder => builder
.AddTenantTokenResolver<TenantIdHeaderHttpTokenResolver>(DefaultTenantHttpHeaderName)
.AddTenantTokenResolver<QueryStringTenantIdTokenResolver>(DefaultTenantQueryStringParamName)
);

return services;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Primitives;
using NBB.MultiTenancy.Identification.Resolvers;
using System.Threading.Tasks;

namespace NBB.MultiTenancy.Identification.Http
{
public class QueryStringTenantIdTokenResolver : ITenantTokenResolver
{
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly string _parameterName;

public QueryStringTenantIdTokenResolver(IHttpContextAccessor httpContextAccessor, string parameterName)
{
_httpContextAccessor = httpContextAccessor;
_parameterName = parameterName;
}

public Task<string> GetTenantToken()
{
var parameterValues = _httpContextAccessor?.HttpContext?.Request?.Query[_parameterName];
if (!parameterValues.HasValue || parameterValues.Value == StringValues.Empty || parameterValues.Value.Count != 1)
{
return Task.FromResult<string>(null);
}

return Task.FromResult(parameterValues.Value.ToString());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using Microsoft.Extensions.DependencyInjection;
using NBB.Messaging.MultiTenancy;
using NBB.MultiTenancy.Identification.Extensions;
using NBB.MultiTenancy.Identification.Identifiers;

namespace NBB.MultiTenancy.Identification.Messaging.Extensions
{
public static class DependencyInjectionExtensions
{
public static IServiceCollection AddDefaultMessagingTenantIdentification(this IServiceCollection services)
{

services.AddTenantIdentification()
.AddTenantIdentificationStrategy<IdTenantIdentifier>(builder => builder
.AddTenantTokenResolver<TenantIdHeaderMessagingTokenResolver>(MessagingHeaders.TenantId));

return services;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\..\Messaging\NBB.Messaging.Abstractions\NBB.Messaging.Abstractions.csproj" />
<ProjectReference Include="..\..\Messaging\NBB.Messaging.MultiTenancy\NBB.Messaging.MultiTenancy.csproj" />
<ProjectReference Include="..\NBB.MultiTenancy.Identification\NBB.MultiTenancy.Identification.csproj" />
</ItemGroup>

Expand Down
Loading

0 comments on commit 7e3e36d

Please sign in to comment.