public async Task Invoke(MessagingContext context, CancellationToken cancellationToken, Func <Task> next) { if (_tenancyOptions.Value.TenancyType == TenancyType.None) { await next(); return; } var tenantId = await _tenantIdentificationService.GetTenantIdAsync(); if (!context.MessagingEnvelope.Headers.TryGetValue(MessagingHeaders.TenantId, out var messageTenantIdHeader)) { throw new ApplicationException($"The tenant ID message header is missing from the message envelope"); } if (!Guid.TryParse(messageTenantIdHeader, out var messageTenantId)) { throw new ApplicationException($"The tenant ID message header is invalid"); } if (messageTenantId != tenantId) { throw new ApplicationException( $"Invalid tenant ID for message {context.MessagingEnvelope.Payload.GetType()}. Expected {tenantId} but received {messageTenantIdHeader}"); } if (_tenancyOptions.Value.TenancyType == TenancyType.MonoTenant && _tenancyOptions.Value.TenantId != messageTenantId) { throw new ApplicationException( $"Invalid tenant ID for message {context.MessagingEnvelope.Payload.GetType()}. Expected {_tenancyOptions.Value.TenantId} but received {messageTenantIdHeader}"); } var tenant = await _tenantRepository.Get(tenantId, cancellationToken) ?? throw new ApplicationException($"Tenant {tenantId} not found"); if (tenant.IsShared && _tenancyOptions.Value.TenancyType == TenancyType.MonoTenant) { throw new ApplicationException( $"Received a message for shared tenant {messageTenantIdHeader} in a MonoTenant hosting"); } if (!tenant.IsShared && _tenancyOptions.Value.TenancyType == TenancyType.MultiTenant) { throw new ApplicationException( $"Received a message for premium tenant {messageTenantIdHeader} in a MultiTenant (shared) context"); } if (_tenantContextAccessor.TenantContext != null) { throw new ApplicationException("Tenant context is already set"); } _tenantContextAccessor.TenantContext = new TenantContext(tenant); await next(); }
public async Task Invoke(HttpContext context, ITenantIdentificationService tenantIdentificationService, ITenantContextAccessor tenantContextAccessor, ITenantRepository tenantRepository, IOptions <TenancyHostingOptions> tenancyOptions) { if (tenancyOptions.Value.TenancyType == TenancyType.None) { await _next(context); return; } if (tenantContextAccessor.TenantContext != null) { throw new ApplicationException("Tenant context is already set"); } var tenantId = await tenantIdentificationService.GetTenantIdAsync(); var tenant = await tenantRepository.Get(tenantId, context.RequestAborted) ?? throw new ApplicationException($"Tenant {tenantId} not found"); if (tenant.IsShared && tenancyOptions.Value.TenancyType == TenancyType.MonoTenant) { throw new ApplicationException( $"Received a message for shared tenant {tenantId} in a MonoTenant hosting"); } if (!tenant.IsShared && tenancyOptions.Value.TenancyType == TenancyType.MultiTenant) { throw new ApplicationException( $"Received a message for premium tenant {tenantId} in a MultiTenant (shared) context"); } if (tenancyOptions.Value.TenancyType == TenancyType.MonoTenant && tenancyOptions.Value.TenantId != tenantId) { throw new ApplicationException( $"Invalid tenant ID. Expected {tenancyOptions.Value.TenantId} but received {tenantId}"); } tenantContextAccessor.TenantContext = new TenantContext(tenant); await _next(context); }