From 0b0672be84112b301b92dbf50692ed20354b1f3c Mon Sep 17 00:00:00 2001 From: Knut Haug Date: Fri, 3 Jan 2025 14:04:57 +0100 Subject: [PATCH 1/3] add own scope and dbcontext to GetSubjectResources to avoid concurrency errors --- .../Authorization/AltinnAuthorizationClient.cs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/Digdir.Domain.Dialogporten.Infrastructure/Altinn/Authorization/AltinnAuthorizationClient.cs b/src/Digdir.Domain.Dialogporten.Infrastructure/Altinn/Authorization/AltinnAuthorizationClient.cs index 4ae95cb71..2cb73845a 100644 --- a/src/Digdir.Domain.Dialogporten.Infrastructure/Altinn/Authorization/AltinnAuthorizationClient.cs +++ b/src/Digdir.Domain.Dialogporten.Infrastructure/Altinn/Authorization/AltinnAuthorizationClient.cs @@ -10,7 +10,9 @@ using Digdir.Domain.Dialogporten.Domain.Parties.Abstractions; using Digdir.Domain.Dialogporten.Domain.SubjectResources; using Digdir.Domain.Dialogporten.Infrastructure.Common.Exceptions; +using Digdir.Domain.Dialogporten.Infrastructure.Persistence; using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using ZiggyCreatures.Caching.Fusion; @@ -27,6 +29,7 @@ internal sealed class AltinnAuthorizationClient : IAltinnAuthorization private readonly IUser _user; private readonly IDialogDbContext _dialogDbContext; private readonly ILogger _logger; + private readonly IServiceScopeFactory _serviceScopeFactory; private static readonly JsonSerializerOptions SerializerOptions = new() { @@ -39,7 +42,8 @@ public AltinnAuthorizationClient( IFusionCacheProvider cacheProvider, IUser user, IDialogDbContext dialogDbContext, - ILogger logger) + ILogger logger, + IServiceScopeFactory serviceScopeFactory) { _httpClient = client ?? throw new ArgumentNullException(nameof(client)); _pdpCache = cacheProvider.GetCache(nameof(Authorization)) ?? throw new ArgumentNullException(nameof(cacheProvider)); @@ -48,6 +52,7 @@ public AltinnAuthorizationClient( _user = user ?? throw new ArgumentNullException(nameof(user)); _dialogDbContext = dialogDbContext ?? throw new ArgumentNullException(nameof(dialogDbContext)); _logger = logger ?? throw new ArgumentNullException(nameof(logger)); + _serviceScopeFactory = serviceScopeFactory ?? throw new ArgumentNullException(nameof(serviceScopeFactory)); } public async Task GetDialogDetailsAuthorization( @@ -180,10 +185,13 @@ await AuthorizationHelper.CollapseSubjectResources( return dialogSearchAuthorizationResult; } - private async Task> GetAllSubjectResources(CancellationToken cancellationToken) => - await _subjectResourcesCache.GetOrSetAsync(nameof(SubjectResource), async ct - => await _dialogDbContext.SubjectResources.ToListAsync(cancellationToken: ct), + await _subjectResourcesCache.GetOrSetAsync(nameof(SubjectResource), async ct => + { + using var scope = _serviceScopeFactory.CreateScope(); + var dbContext = scope.ServiceProvider.GetRequiredService(); + return await dbContext.SubjectResources.ToListAsync(cancellationToken: ct); + }, token: cancellationToken); private async Task PerformDialogDetailsAuthorization( From ae445bb31fefd2e241f2cb3aee4b3de59f652c9f Mon Sep 17 00:00:00 2001 From: Knut Haug Date: Fri, 3 Jan 2025 14:23:39 +0100 Subject: [PATCH 2/3] remove unused dbcontext --- .../Altinn/Authorization/AltinnAuthorizationClient.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/Digdir.Domain.Dialogporten.Infrastructure/Altinn/Authorization/AltinnAuthorizationClient.cs b/src/Digdir.Domain.Dialogporten.Infrastructure/Altinn/Authorization/AltinnAuthorizationClient.cs index 2cb73845a..4407b376b 100644 --- a/src/Digdir.Domain.Dialogporten.Infrastructure/Altinn/Authorization/AltinnAuthorizationClient.cs +++ b/src/Digdir.Domain.Dialogporten.Infrastructure/Altinn/Authorization/AltinnAuthorizationClient.cs @@ -27,7 +27,6 @@ internal sealed class AltinnAuthorizationClient : IAltinnAuthorization private readonly IFusionCache _partiesCache; private readonly IFusionCache _subjectResourcesCache; private readonly IUser _user; - private readonly IDialogDbContext _dialogDbContext; private readonly ILogger _logger; private readonly IServiceScopeFactory _serviceScopeFactory; @@ -41,7 +40,6 @@ public AltinnAuthorizationClient( HttpClient client, IFusionCacheProvider cacheProvider, IUser user, - IDialogDbContext dialogDbContext, ILogger logger, IServiceScopeFactory serviceScopeFactory) { @@ -50,7 +48,6 @@ public AltinnAuthorizationClient( _partiesCache = cacheProvider.GetCache(nameof(AuthorizedPartiesResult)) ?? throw new ArgumentNullException(nameof(cacheProvider)); _subjectResourcesCache = cacheProvider.GetCache(nameof(SubjectResource)) ?? throw new ArgumentNullException(nameof(cacheProvider)); _user = user ?? throw new ArgumentNullException(nameof(user)); - _dialogDbContext = dialogDbContext ?? throw new ArgumentNullException(nameof(dialogDbContext)); _logger = logger ?? throw new ArgumentNullException(nameof(logger)); _serviceScopeFactory = serviceScopeFactory ?? throw new ArgumentNullException(nameof(serviceScopeFactory)); } From 3f71d190ad7854cc91934e6659a860235bdbbe5f Mon Sep 17 00:00:00 2001 From: Knut Haug Date: Mon, 6 Jan 2025 10:21:13 +0100 Subject: [PATCH 3/3] Added AsNoTracking on the db fetch --- .../Altinn/Authorization/AltinnAuthorizationClient.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Digdir.Domain.Dialogporten.Infrastructure/Altinn/Authorization/AltinnAuthorizationClient.cs b/src/Digdir.Domain.Dialogporten.Infrastructure/Altinn/Authorization/AltinnAuthorizationClient.cs index 4407b376b..2f46d07ae 100644 --- a/src/Digdir.Domain.Dialogporten.Infrastructure/Altinn/Authorization/AltinnAuthorizationClient.cs +++ b/src/Digdir.Domain.Dialogporten.Infrastructure/Altinn/Authorization/AltinnAuthorizationClient.cs @@ -187,7 +187,7 @@ await _subjectResourcesCache.GetOrSetAsync(nameof(SubjectResource), async ct => { using var scope = _serviceScopeFactory.CreateScope(); var dbContext = scope.ServiceProvider.GetRequiredService(); - return await dbContext.SubjectResources.ToListAsync(cancellationToken: ct); + return await dbContext.SubjectResources.AsNoTracking().ToListAsync(cancellationToken: ct); }, token: cancellationToken);