-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Fix Multitenancy Support and Normalize Tenant ID Handling #7217
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
27 commits
Select commit
Hold shift + click to select a range
15fd780
Enable multitenancy support and normalize tenant ID handling.
sfmskywalker 847a427
Add ADR for adopting empty string as the default tenant ID
sfmskywalker 07fe0e7
Apply suggestion from @sfmskywalker
sfmskywalker e385234
Update doc/adr/graph.dot
sfmskywalker 62c9989
Normalize spacing and improve readability in `Program.cs`. Fix multit…
sfmskywalker 02ac3e5
Merge remote-tracking branch 'origin/bug/tenant-id' into bug/tenant-id
sfmskywalker 0fe0919
Fix ADR numbering and update TOC
sfmskywalker f027e05
Add ADRs for flowchart execution model, tenant deletion event, merge …
sfmskywalker 1c92763
Add unit tests for tenant ID normalization and multitenancy pipeline …
sfmskywalker d849aea
Update unit tests for `ActivityConstructionResult`
sfmskywalker 6c1e6fc
Enable configuration-based multitenancy with tenant-specific settings
sfmskywalker 970ca15
Update database indexes to include `TenantId` for multitenancy support
sfmskywalker 4395aff
Add tenant filtering to `DefaultWorkflowDefinitionStorePopulator`
sfmskywalker 42a7c49
Update doc/adr/toc.md
sfmskywalker dec0f4a
Remove `CommonPersistenceFeature` as it has been deprecated
sfmskywalker d5e4e59
Merge remote-tracking branch 'origin/bug/tenant-id' into bug/tenant-id
sfmskywalker 9bcd6ca
Add tenant-specific filtering to workflow import logic in `DefaultWor…
sfmskywalker 6833d5e
Replace hardcoded tenant ID with `Tenant.DefaultTenantId` in integrat…
sfmskywalker d86dc21
Update database indexes and migration logic to support `TenantId` for…
sfmskywalker 7ec5bef
Remove `TenantId` from workflow identity construction in concurrent t…
sfmskywalker f4a184a
Introduce `SelectiveMockLockProvider` for precise lock mocking in tests
sfmskywalker 0b271d6
Update Elsa.sln
sfmskywalker ee44768
Normalize tenant ID handling in `DefaultWorkflowDefinitionStorePopula…
sfmskywalker d693d58
Merge remote-tracking branch 'origin/bug/tenant-id' into bug/tenant-id
sfmskywalker f612c87
Refactor `TenantResolverResult` to support explicit resolved/unresolv…
sfmskywalker 8b22c06
Normalize tenant ID handling in `DefaultWorkflowDefinitionStorePopula…
sfmskywalker cc36043
Refactor `DefaultWorkflowDefinitionStorePopulatorTests`: streamline o…
sfmskywalker File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
...oken-centric-flowchart-execution-model.md → ...oken-centric-flowchart-execution-model.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,4 @@ | ||
| # 4. Token-Centric Flowchart Execution Model | ||
| # 5. Token-Centric Flowchart Execution Model | ||
|
|
||
| Date: 2025-05-06 | ||
|
|
||
|
|
||
2 changes: 1 addition & 1 deletion
2
doc/adr/0005-tenant-deleted-event.md → doc/adr/0006-tenant-deleted-event.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,4 @@ | ||
| # 5. Tenant Deleted Event | ||
| # 6. Tenant Deleted Event | ||
|
|
||
| Date: 2025-08-05 | ||
|
|
||
|
|
||
2 changes: 1 addition & 1 deletion
2
...plicit-merge-modes-for-flowchart-joins.md → ...plicit-merge-modes-for-flowchart-joins.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| # 8. Empty String as Default Tenant ID | ||
|
|
||
| Date: 2026-01-27 | ||
|
|
||
| ## Status | ||
|
|
||
| Accepted | ||
|
|
||
| ## Context | ||
|
|
||
| The multitenancy system in Elsa supports an optional mode where, when multitenancy is disabled, the system assumes a single tenant. When enabled, there's still a default tenant involved. The convention has been to use `null` as the tenant ID for the default tenant. | ||
|
|
||
| However, this convention created several issues: | ||
|
|
||
| 1. **Dictionary compatibility**: The `DefaultTenantResolverPipelineInvoker` attempts to build a dictionary of tenants by their ID using `ToDictionary(x => x.Id)`, which throws an exception because dictionaries do not support null keys. | ||
| 2. **Inconsistency**: The codebase used `null`, empty string (`""`), and string literal `"default"` interchangeably to refer to the default tenant across different parts of the system (e.g., in configuration files and database records). | ||
| 3. **Code clarity**: Using `null` as a sentinel value for "default" is implicit and can be unclear to developers reading the code. | ||
|
|
||
| ## Decision | ||
|
|
||
| We will standardize on using an **empty string** (`""`) as the tenant ID for the default tenant instead of `null`. This decision includes: | ||
|
|
||
| 1. **Define a constant**: Add `Tenant.DefaultTenantId = ""` to explicitly document the convention. | ||
| 2. **Update Tenant.Default**: Change `Tenant.Default.Id` from `null!` to use the `DefaultTenantId` constant. | ||
| 3. **Add normalization helper**: Create a `NormalizeTenantId()` extension method that converts `null` to empty string, ensuring backwards compatibility with code that still uses null. | ||
| 4. **Apply normalization consistently**: Use the normalization method in: | ||
| - Dictionary creation in `DefaultTenantResolverPipelineInvoker` | ||
| - Tenant lookups in `TenantResolverContext` | ||
| - Any other places where tenant IDs are compared or used as dictionary keys | ||
|
|
||
| ## Consequences | ||
|
|
||
| ### Positive | ||
|
|
||
| - **No more exceptions**: Empty string is a valid dictionary key, eliminating the runtime exception in `DefaultTenantResolverPipelineInvoker`. | ||
| - **Backwards compatible**: The `NormalizeTenantId()` extension method ensures that existing code using `null` or empty string will work correctly. | ||
| - **Explicit convention**: The `DefaultTenantId` constant makes the convention clear and self-documenting. | ||
| - **Simplified logic**: Reduces the need for null-checking throughout the multitenancy code. | ||
| - **Consistency**: Aligns with parts of the codebase that were already using empty string (e.g., in configuration files). | ||
|
|
||
| ### Negative | ||
|
|
||
| - **Migration consideration**: Existing data stores that have `null` tenant IDs will need to be normalized to empty strings, though the normalization helper provides a runtime solution. | ||
| - **String vs null semantics**: Some developers may find using empty string less intuitive than null for representing "no tenant", though this is mitigated by the explicit constant. | ||
|
|
||
| ### Neutral | ||
|
|
||
| - The empty string convention is common in multitenancy systems and aligns with string-based identifier patterns used elsewhere in the codebase. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
src/modules/Elsa.Common/Multitenancy/Contracts/ITenantResolver.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
17 changes: 0 additions & 17 deletions
17
src/modules/Elsa.Persistence.EFCore.Common/CommonPersistenceFeature.cs
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.