Hi,
I can't reproduce the problem
Configure<AbpDistributedEventBusOptions>(options =>
{
options.Inboxes.Configure(config =>
{
config.UseDbContext<Qa8002DbContext>();
});
options.Outboxes.Configure(config =>
{
config.UseDbContext<Qa8002DbContext>();
});
});
public class MyTestService : ApplicationService
{
private readonly IDistributedEventBus _eventBus;
public MyTestService(IDistributedEventBus eventBus)
{
_eventBus = eventBus;
}
public async Task CreateEventsAsync()
{
//"shared1", "shared2", "isolate"
var tenants = new[] { "3B7480C1-872D-CBCC-1D43-3A15597E0445", "84A19B02-745B-027B-97ED-3A15597E4331", "EDEA2337-4766-42D6-0B2F-3A15597E7B91" };
foreach (var tenant in tenants)
{
using (CurrentTenant.Change(Guid.Parse(tenant)))
{
await _eventBus.PublishAsync(new TestEventData()
{
Test = tenant
});
}
}
}
}
public class TestEventData
{
public string Test { get; set; }
}
public class TestEventHandler : IDistributedEventHandler<TestEventData>, ITransientDependency
{
private readonly ILogger<TestEventHandler> _logger;
public TestEventHandler(ILogger<TestEventHandler> logger)
{
_logger = logger;
}
public Task HandleEventAsync(TestEventData eventData)
{
var tenantDict = new Dictionary<string, String>
{
["EDEA2337-4766-42D6-0B2F-3A15597E7B91"] = "isolate",
["84A19B02-745B-027B-97ED-3A15597E4331"] = "shared2",
["3B7480C1-872D-CBCC-1D43-3A15597E0445"] = "shared1"
};
_logger.LogInformation("TestEventHandler------------: "+ tenantDict[eventData.Test]);
return Task.CompletedTask;
}
}
[17:18:55 INF] Found 3 events in the outbox.
[17:18:55 INF] Sent 3 events to message broker
[17:18:57 INF] Found 3 events in the inbox.
[17:18:57 INF] TestEventHandler------------: shared1
[17:18:57 INF] Processed the incoming event with id = afabaf6c42563eb6c5e33a15598cf978
[17:18:57 INF] TestEventHandler------------: shared2
[17:18:57 INF] Processed the incoming event with id = 80761db05ef683d318643a15598cf99b
[17:18:57 INF] TestEventHandler------------: isolate
[17:18:57 INF] Processed the incoming event with id = 5268bae9e7c83be0c0fc3a15598cf9a5
Hi,
this may be a problem, I will check it.
Hi,
I can confirm this is a bug,
Here is the temporary solution
[ExposeServices(typeof(LogoutModel))]
public class IdentityServerSupportedLogoutModel : LogoutModel
{
protected IIdentityServerInteractionService Interaction { get; }
public IdentityServerSupportedLogoutModel(
IIdentityServerInteractionService interaction
)
{
Interaction = interaction;
}
public override async Task<IActionResult> OnGetAsync()
{
await SignInManager.SignOutAsync();
var logoutId = Request.Query["logoutId"].ToString();
if (!string.IsNullOrEmpty(logoutId))
{
var logoutContext = await Interaction.GetLogoutContextAsync(logoutId);
await SaveSecurityLogAsync(logoutContext?.ClientId);
await SignInManager.SignOutAsync();
// for ui to see an anonymous user
HttpContext.User = new ClaimsPrincipal(new ClaimsIdentity());
var queryCulture = logoutContext?.Parameters.Get("culture");
var queryUICulture = logoutContext?.Parameters.Get("ui-culture");
var vm = new
{
PostLogoutRedirectUri = logoutContext?.PostLogoutRedirectUri,
ClientName = logoutContext?.ClientName,
SignOutIframeUrl = logoutContext?.SignOutIFrameUrl,
Culture = queryCulture,
UICulture = queryUICulture
};
Logger.LogInformation($"Redirecting to LoggedOut Page...");
return RedirectToPage("./LoggedOut", vm);
}
await SaveSecurityLogAsync();
if (ReturnUrl != null)
{
return LocalRedirect(ReturnUrl);
}
Logger.LogInformation(
$"IdentityServerSupportedLogoutModel couldn't find postLogoutUri... Redirecting to:/Account/Login..");
return RedirectToPage("/Account/Login");
}
protected virtual async Task SaveSecurityLogAsync(string clientId = null)
{
if (CurrentUser.IsAuthenticated)
{
await IdentitySecurityLogManager.SaveAsync(new IdentitySecurityLogContext()
{
Identity = IdentitySecurityLogIdentityConsts.Identity,
Action = IdentitySecurityLogActionConsts.Logout,
ClientId = clientId
});
}
}
}
I have noticed that when distributed events are generated in the tenants with isolated databases, they are added to the AbpEventOutbox table of those databases
Could you share some screenshots?
Hi,
you can try this
var $form = $('#formElement');
$form.on('submit', function (e) {
e.preventDefault();
if ($form.valid()) {
abp.message.confirm(
...,
async function (isConfirmed) {
if (isConfirmed) {
e.preventDefault();
$form.ajaxSubmit({
success: function (result) {
....
},
error: function (result) {
abp.notify.error(result.responseJSON.error.message);
abp.ui.clearBusy();
}
});
}
}
);
}
else {
abp.ui.clearBusy();
}
});
Hi,
It looks not related to Identityserver.
could you share the project with me? i will check it.
Hi,
How to register the above worker class to the multi-tenany.
You need to get all tenants first. You can try to use ADO.NET to get all tenants and register workers class to the multi-tenany
SqlConnection connection = new(connectionString);
var tenants = await connection....;
foreach(var tenant in tenants)
{
context.Services.AddHostedService....
}
But there is a problem, When you add a new tenant, you need to restart the application.
I recommend you to loop through all tenants in the worker
public class CamundaWorker ....
{
public ......()
{
var tenants = await TenantRepository.GetListAsync();
foreach(var tenant in tenants)
{
using(CurrentTenant.Change(tenant.Id))
{
...
}
}
}
}
Hi,
All events are stored in a shared database. they are not tenant-isolated.
So it's one for database shared for all tenants and one worker per application
Hi
You can try
{
"items": [
{
"text": "Overview",
"path": "...",
"Previous": {
"Name": "Single-layer solution",
"Path": "testing/overall"
},
"Next": {
"Name": "Integration tests",
"Path": "testing/integration-tests"
}
}
]
}