From 73e9efd1a9a3491e04e2d43b784632ee2b2e28f8 Mon Sep 17 00:00:00 2001 From: Jan-Willem de Bruyn Date: Thu, 21 May 2026 09:13:34 +0200 Subject: [PATCH] Fix: consistently use the TenantId property to make sure to properly apply the new default TenantId (empty string instead of null) --- .../Middleware/TenantScopeMiddleware.cs | 2 +- .../Elsa.Persistence.Dapper/Services/Store.cs | 6 ++---- .../Elsa.Persistence.MongoDb/Common/MongoDbStore.cs | 13 +++++-------- .../Services/ProtoActorWorkflowClient.cs | 2 +- .../Jobs/ExecuteBackgroundActivityJob.cs | 4 ++-- .../Jobs/ResumeWorkflowJob.cs | 4 ++-- .../Elsa.Scheduling.Hangfire/Jobs/RunWorkflowJob.cs | 4 ++-- .../Services/HangfireBackgroundActivityScheduler.cs | 4 ++-- .../Services/HangfireWorkflowScheduler.cs | 8 ++++---- .../Services/JobKeyProvider.cs | 2 +- .../Services/QuartzWorkflowScheduler.cs | 4 ++-- .../Middleware/TenantPublishMiddleware.cs | 5 ++--- .../Middleware/TenantSendMiddleware.cs | 5 ++--- 13 files changed, 28 insertions(+), 35 deletions(-) diff --git a/src/modules/actors/Elsa.Actors.ProtoActor/Middleware/TenantScopeMiddleware.cs b/src/modules/actors/Elsa.Actors.ProtoActor/Middleware/TenantScopeMiddleware.cs index 223fa2c5..eb188dd5 100644 --- a/src/modules/actors/Elsa.Actors.ProtoActor/Middleware/TenantScopeMiddleware.cs +++ b/src/modules/actors/Elsa.Actors.ProtoActor/Middleware/TenantScopeMiddleware.cs @@ -44,7 +44,7 @@ public static Sender PropagateTenant(this Sender next, IServiceProvider sp) async Task Sender(ISenderContext context, PID target, MessageEnvelope envelope) { var tenantAccessor = sp.GetRequiredService(); - if (tenantAccessor.Tenant != null) envelope.WithHeader(HeaderNames.TenantId, tenantAccessor.Tenant.Id); + envelope.WithHeader(HeaderNames.TenantId, tenantAccessor.TenantId); await next(context, target, envelope); } diff --git a/src/modules/persistence/Elsa.Persistence.Dapper/Services/Store.cs b/src/modules/persistence/Elsa.Persistence.Dapper/Services/Store.cs index defce823..48d23f15 100644 --- a/src/modules/persistence/Elsa.Persistence.Dapper/Services/Store.cs +++ b/src/modules/persistence/Elsa.Persistence.Dapper/Services/Store.cs @@ -525,8 +525,7 @@ private void ApplyTenantFilter(ParameterizedQuery query, bool tenantAgnostic = f if (tenantAgnostic) return; - var tenant = tenantAccessor.Tenant; - var tenantId = tenant?.Id; + var tenantId = tenantAccessor.TenantId; query.Is(nameof(Record.TenantId), (object?)tenantId ?? DBNull.Value); } @@ -535,8 +534,7 @@ private void SetTenantId(T record) if (record is not Record recordWithTenant) return; - var tenant = tenantAccessor.Tenant; - var tenantId = tenant?.Id; + var tenantId = tenantAccessor.TenantId; recordWithTenant.TenantId = tenantId; } } \ No newline at end of file diff --git a/src/modules/persistence/Elsa.Persistence.MongoDb/Common/MongoDbStore.cs b/src/modules/persistence/Elsa.Persistence.MongoDb/Common/MongoDbStore.cs index af4371a0..9d66fa26 100644 --- a/src/modules/persistence/Elsa.Persistence.MongoDb/Common/MongoDbStore.cs +++ b/src/modules/persistence/Elsa.Persistence.MongoDb/Common/MongoDbStore.cs @@ -435,8 +435,7 @@ private IQueryable GetQueryableCollection(bool tenantAgnostic = false if (typeof(Entity).IsAssignableFrom(typeof(TDocument))) { - var tenant = tenantAccessor.Tenant; - var tenantId = tenant?.Id.EmptyToNull(); + var tenantId = tenantAccessor.TenantId; queryable = queryable.Where(x => (x as Entity)!.TenantId == tenantId); } @@ -445,22 +444,20 @@ private IQueryable GetQueryableCollection(bool tenantAgnostic = false private void ApplyTenantId(TDocument document) { - var tenant = tenantAccessor.Tenant; - var tenantId = tenant?.Id; + var tenantId = tenantAccessor.TenantId; if (document is Entity tenantDocument) - tenantDocument.TenantId = tenantId.EmptyToNull(); + tenantDocument.TenantId = tenantId; } private void ApplyTenantId(IEnumerable documents) { - var tenant = tenantAccessor.Tenant; - var tenantId = tenant?.Id; + var tenantId = tenantAccessor.TenantId; foreach (var document in documents) { if (document is Entity tenantDocument) - tenantDocument.TenantId = tenantId.EmptyToNull(); + tenantDocument.TenantId = tenantId; } } } diff --git a/src/modules/runtimes/Elsa.Workflows.Runtime.ProtoActor/Services/ProtoActorWorkflowClient.cs b/src/modules/runtimes/Elsa.Workflows.Runtime.ProtoActor/Services/ProtoActorWorkflowClient.cs index f487e51b..1ed7ef08 100644 --- a/src/modules/runtimes/Elsa.Workflows.Runtime.ProtoActor/Services/ProtoActorWorkflowClient.cs +++ b/src/modules/runtimes/Elsa.Workflows.Runtime.ProtoActor/Services/ProtoActorWorkflowClient.cs @@ -99,7 +99,7 @@ public Task InstanceExistsAsync(CancellationToken cancellationToken = defa private IDictionary CreateHeaders() { var headers = new Dictionary(); - if (_tenantAccessor.Tenant != null) headers[HeaderNames.TenantId] = _tenantAccessor.Tenant.Id; + headers[HeaderNames.TenantId] = _tenantAccessor.TenantId; return headers; } } \ No newline at end of file diff --git a/src/modules/scheduling/Elsa.Scheduling.Hangfire/Jobs/ExecuteBackgroundActivityJob.cs b/src/modules/scheduling/Elsa.Scheduling.Hangfire/Jobs/ExecuteBackgroundActivityJob.cs index 13f01185..226f7aa9 100644 --- a/src/modules/scheduling/Elsa.Scheduling.Hangfire/Jobs/ExecuteBackgroundActivityJob.cs +++ b/src/modules/scheduling/Elsa.Scheduling.Hangfire/Jobs/ExecuteBackgroundActivityJob.cs @@ -13,9 +13,9 @@ public class ExecuteBackgroundActivityJob(IBackgroundActivityInvoker backgroundA /// /// Executes the job. /// - public async Task ExecuteAsync(ScheduledBackgroundActivity scheduledBackgroundActivity, string? tenantId, CancellationToken cancellationToken = default) + public async Task ExecuteAsync(ScheduledBackgroundActivity scheduledBackgroundActivity, string tenantId, CancellationToken cancellationToken = default) { - var tenant = tenantId != null ? await tenantFinder.FindByIdAsync(tenantId, cancellationToken) : null; + var tenant = await tenantFinder.FindByIdAsync(tenantId, cancellationToken); using var scope = tenantAccessor.PushContext(tenant); await backgroundActivityInvoker.ExecuteAsync(scheduledBackgroundActivity, cancellationToken); } diff --git a/src/modules/scheduling/Elsa.Scheduling.Hangfire/Jobs/ResumeWorkflowJob.cs b/src/modules/scheduling/Elsa.Scheduling.Hangfire/Jobs/ResumeWorkflowJob.cs index d30b97f1..14fb4687 100644 --- a/src/modules/scheduling/Elsa.Scheduling.Hangfire/Jobs/ResumeWorkflowJob.cs +++ b/src/modules/scheduling/Elsa.Scheduling.Hangfire/Jobs/ResumeWorkflowJob.cs @@ -20,9 +20,9 @@ public class ResumeWorkflowJob(IWorkflowRuntime workflowRuntime, ITenantFinder t /// The cancellation token. // ReSharper disable once UnusedParameter.Global [AutomaticRetry(OnAttemptsExceeded = AttemptsExceededAction.Fail)] - public async Task ExecuteAsync(string taskName, ScheduleExistingWorkflowInstanceRequest request, string? tenantId, CancellationToken cancellationToken) + public async Task ExecuteAsync(string taskName, ScheduleExistingWorkflowInstanceRequest request, string tenantId, CancellationToken cancellationToken) { - var tenant = tenantId != null ? await tenantFinder.FindByIdAsync(tenantId, cancellationToken) : null; + var tenant = await tenantFinder.FindByIdAsync(tenantId, cancellationToken); using var scope = tenantAccessor.PushContext(tenant); var client = await workflowRuntime.CreateClientAsync(request.WorkflowInstanceId, cancellationToken); var runRequest = new RunWorkflowInstanceRequest diff --git a/src/modules/scheduling/Elsa.Scheduling.Hangfire/Jobs/RunWorkflowJob.cs b/src/modules/scheduling/Elsa.Scheduling.Hangfire/Jobs/RunWorkflowJob.cs index f70f9819..6ef68e34 100644 --- a/src/modules/scheduling/Elsa.Scheduling.Hangfire/Jobs/RunWorkflowJob.cs +++ b/src/modules/scheduling/Elsa.Scheduling.Hangfire/Jobs/RunWorkflowJob.cs @@ -20,9 +20,9 @@ public class RunWorkflowJob(IWorkflowRuntime workflowRuntime, ITenantFinder tena /// The cancellation token. // ReSharper disable once UnusedParameter.Global [AutomaticRetry(OnAttemptsExceeded = AttemptsExceededAction.Fail)] - public async Task ExecuteAsync(string taskName, ScheduleNewWorkflowInstanceRequest request, string? tenantId, CancellationToken cancellationToken) + public async Task ExecuteAsync(string taskName, ScheduleNewWorkflowInstanceRequest request, string tenantId, CancellationToken cancellationToken) { - var tenant = tenantId != null ? await tenantFinder.FindByIdAsync(tenantId, cancellationToken) : null; + var tenant = await tenantFinder.FindByIdAsync(tenantId, cancellationToken); using var scope = tenantAccessor.PushContext(tenant); var client = await workflowRuntime.CreateClientAsync(cancellationToken); var createAndRunRequest = new CreateAndRunWorkflowInstanceRequest diff --git a/src/modules/scheduling/Elsa.Scheduling.Hangfire/Services/HangfireBackgroundActivityScheduler.cs b/src/modules/scheduling/Elsa.Scheduling.Hangfire/Services/HangfireBackgroundActivityScheduler.cs index b464cad4..c436c7ea 100644 --- a/src/modules/scheduling/Elsa.Scheduling.Hangfire/Services/HangfireBackgroundActivityScheduler.cs +++ b/src/modules/scheduling/Elsa.Scheduling.Hangfire/Services/HangfireBackgroundActivityScheduler.cs @@ -14,7 +14,7 @@ public class HangfireBackgroundActivityScheduler(IBackgroundJobClient background { public Task CreateAsync(ScheduledBackgroundActivity scheduledBackgroundActivity, CancellationToken cancellationToken = default) { - var tenantId = tenantAccessor.Tenant?.Id; + var tenantId = tenantAccessor.TenantId; var jobId = backgroundJobClient.Create(x => x.ExecuteAsync(scheduledBackgroundActivity, tenantId, CancellationToken.None), new PendingState()); return Task.FromResult(jobId); } @@ -30,7 +30,7 @@ public Task ScheduleAsync(string jobId, CancellationToken cancellationToken = de /// public Task ScheduleAsync(ScheduledBackgroundActivity scheduledBackgroundActivity, CancellationToken cancellationToken = default) { - var tenantId = tenantAccessor.Tenant?.Id; + var tenantId = tenantAccessor.TenantId; var jobId = backgroundJobClient.Enqueue(x => x.ExecuteAsync(scheduledBackgroundActivity, tenantId, CancellationToken.None)); return Task.FromResult(jobId); } diff --git a/src/modules/scheduling/Elsa.Scheduling.Hangfire/Services/HangfireWorkflowScheduler.cs b/src/modules/scheduling/Elsa.Scheduling.Hangfire/Services/HangfireWorkflowScheduler.cs index 3b389e68..9beb345d 100644 --- a/src/modules/scheduling/Elsa.Scheduling.Hangfire/Services/HangfireWorkflowScheduler.cs +++ b/src/modules/scheduling/Elsa.Scheduling.Hangfire/Services/HangfireWorkflowScheduler.cs @@ -18,7 +18,7 @@ public class HangfireWorkflowScheduler( /// public ValueTask ScheduleAtAsync(string taskName, ScheduleNewWorkflowInstanceRequest request, DateTimeOffset at, CancellationToken cancellationToken = default) { - var tenantId = tenantAccessor.Tenant?.Id; + var tenantId = tenantAccessor.TenantId; backgroundJobClient.Schedule(job => job.ExecuteAsync(taskName, request, tenantId, CancellationToken.None), at); return ValueTask.CompletedTask; } @@ -26,7 +26,7 @@ public ValueTask ScheduleAtAsync(string taskName, ScheduleNewWorkflowInstanceReq /// public ValueTask ScheduleAtAsync(string taskName, ScheduleExistingWorkflowInstanceRequest request, DateTimeOffset at, CancellationToken cancellationToken = default) { - var tenantId = tenantAccessor.Tenant?.Id; + var tenantId = tenantAccessor.TenantId; backgroundJobClient.Schedule(job => job.ExecuteAsync(taskName, request, tenantId, CancellationToken.None), at); return ValueTask.CompletedTask; } @@ -46,7 +46,7 @@ public async ValueTask ScheduleRecurringAsync(string taskName, ScheduleExistingW /// public ValueTask ScheduleCronAsync(string taskName, ScheduleNewWorkflowInstanceRequest request, string cronExpression, CancellationToken cancellationToken = default) { - var tenantId = tenantAccessor.Tenant?.Id; + var tenantId = tenantAccessor.TenantId; recurringJobManager.AddOrUpdate(taskName, job => job.ExecuteAsync(taskName, request, tenantId, CancellationToken.None), cronExpression); return ValueTask.CompletedTask; } @@ -54,7 +54,7 @@ public ValueTask ScheduleCronAsync(string taskName, ScheduleNewWorkflowInstanceR /// public ValueTask ScheduleCronAsync(string taskName, ScheduleExistingWorkflowInstanceRequest request, string cronExpression, CancellationToken cancellationToken = default) { - var tenantId = tenantAccessor.Tenant?.Id; + var tenantId = tenantAccessor.TenantId; recurringJobManager.AddOrUpdate(taskName, job => job.ExecuteAsync(taskName, request, tenantId, CancellationToken.None), cronExpression); return ValueTask.CompletedTask; } diff --git a/src/modules/scheduling/Elsa.Scheduling.Quartz/Services/JobKeyProvider.cs b/src/modules/scheduling/Elsa.Scheduling.Quartz/Services/JobKeyProvider.cs index d1d35071..e2732459 100644 --- a/src/modules/scheduling/Elsa.Scheduling.Quartz/Services/JobKeyProvider.cs +++ b/src/modules/scheduling/Elsa.Scheduling.Quartz/Services/JobKeyProvider.cs @@ -13,7 +13,7 @@ public JobKey GetJobKey() where TJob : IJob public string GetGroupName() { - var tenantId = tenantAccessor.Tenant?.Id; + var tenantId = tenantAccessor.TenantId; return string.IsNullOrWhiteSpace(tenantId) ? "Default" : tenantId; } } \ No newline at end of file diff --git a/src/modules/scheduling/Elsa.Scheduling.Quartz/Services/QuartzWorkflowScheduler.cs b/src/modules/scheduling/Elsa.Scheduling.Quartz/Services/QuartzWorkflowScheduler.cs index 6407b4de..2a31b47b 100644 --- a/src/modules/scheduling/Elsa.Scheduling.Quartz/Services/QuartzWorkflowScheduler.cs +++ b/src/modules/scheduling/Elsa.Scheduling.Quartz/Services/QuartzWorkflowScheduler.cs @@ -130,7 +130,7 @@ private async Task ScheduleJobAsync(QuartzIScheduler scheduler, ITrigger trigger private JobDataMap CreateJobDataMap(ScheduleNewWorkflowInstanceRequest request) { return new JobDataMap() - .AddIfNotEmpty("TenantId", tenantAccessor.Tenant?.Id) + .AddIfNotEmpty("TenantId", tenantAccessor.TenantId) .AddIfNotEmpty(nameof(ScheduleNewWorkflowInstanceRequest.CorrelationId), request.CorrelationId) .AddIfNotEmpty(nameof(ScheduleNewWorkflowInstanceRequest.WorkflowDefinitionHandle.DefinitionVersionId), request.WorkflowDefinitionHandle.DefinitionVersionId) .AddIfNotEmpty(nameof(ScheduleNewWorkflowInstanceRequest.TriggerActivityId), request.TriggerActivityId) @@ -145,7 +145,7 @@ private JobDataMap CreateJobDataMap(ScheduleExistingWorkflowInstanceRequest requ var serializedActivityHandle = request.ActivityHandle != null ? jsonSerializer.Serialize(request.ActivityHandle) : null; return new JobDataMap() - .AddIfNotEmpty("TenantId", tenantAccessor.Tenant?.Id) + .AddIfNotEmpty("TenantId", tenantAccessor.TenantId) .AddIfNotEmpty(nameof(ScheduleExistingWorkflowInstanceRequest.WorkflowInstanceId), request.WorkflowInstanceId) .AddIfNotEmpty(nameof(ScheduleExistingWorkflowInstanceRequest.Input), request.Input) .AddIfNotEmpty(nameof(ScheduleExistingWorkflowInstanceRequest.Properties), request.Properties) diff --git a/src/modules/servicebus/Elsa.ServiceBus.MassTransit/Middleware/TenantPublishMiddleware.cs b/src/modules/servicebus/Elsa.ServiceBus.MassTransit/Middleware/TenantPublishMiddleware.cs index 852b51ac..0a1c2b61 100644 --- a/src/modules/servicebus/Elsa.ServiceBus.MassTransit/Middleware/TenantPublishMiddleware.cs +++ b/src/modules/servicebus/Elsa.ServiceBus.MassTransit/Middleware/TenantPublishMiddleware.cs @@ -12,10 +12,9 @@ public void Probe(ProbeContext context) public async Task Send(PublishContext context, IPipe next) { - var tenantId = tenantAccessor.Tenant?.Id; + var tenantId = tenantAccessor.TenantId; - if (!string.IsNullOrEmpty(tenantId)) - context.Headers.Set(HeaderNames.TenantId, tenantId); + context.Headers.Set(HeaderNames.TenantId, tenantId); await next.Send(context); } diff --git a/src/modules/servicebus/Elsa.ServiceBus.MassTransit/Middleware/TenantSendMiddleware.cs b/src/modules/servicebus/Elsa.ServiceBus.MassTransit/Middleware/TenantSendMiddleware.cs index fdfb4347..b5f4f267 100644 --- a/src/modules/servicebus/Elsa.ServiceBus.MassTransit/Middleware/TenantSendMiddleware.cs +++ b/src/modules/servicebus/Elsa.ServiceBus.MassTransit/Middleware/TenantSendMiddleware.cs @@ -12,10 +12,9 @@ public void Probe(ProbeContext context) public async Task Send(SendContext context, IPipe next) { - var tenantId = tenantAccessor.Tenant?.Id; + var tenantId = tenantAccessor.TenantId; - if (!string.IsNullOrEmpty(tenantId)) - context.Headers.Set(HeaderNames.TenantId, tenantId); + context.Headers.Set(HeaderNames.TenantId, tenantId); await next.Send(context); }