Skip to content
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

Remove dependencies on Migration.Tool.KXP project #297

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions Migration.Tool.Core.K11/Contexts/KeyMappingContext.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using System.Linq.Expressions;

using CMS.DataEngine;
using Migration.Tool.Core.K11.Services;

namespace Migration.Tool.Core.K11.Contexts;
Expand All @@ -11,15 +11,15 @@ public class KeyMappingContext(PrimaryKeyMappingContext primaryKeyMappingContext
public MapSourceKeyResult<TTargetKey> MapSourceKey<TSource, TTarget, TTargetKey>(Expression<Func<TSource, object>> sourceKeySelector,
Expression<Func<TSource, Guid>> sourceGuidSelector,
object? sourceKey,
Expression<Func<TTarget, TTargetKey>> targetKeySelector,
Expression<Func<TTarget, Guid>> targetGuidSelector) where TSource : class where TTarget : class
Func<TTarget, TTargetKey> targetKeySelector,
Func<Guid, TTarget?> targetByGuidProvider) where TSource : class where TTarget : AbstractInfoBase<TTarget>, new()
{
if (sourceKey is int id && primaryKeyMappingContext.MapSourceId(sourceKeySelector, id) is { Success: true, MappedId: TTargetKey targetKey })
{
return new MapSourceKeyResult<TTargetKey>(true, targetKey);
}

if (keyLocatorService.TryLocate(sourceKeySelector, targetKeySelector, sourceGuidSelector, targetGuidSelector, sourceKey, out var located))
if (keyLocatorService.TryLocate(sourceKeySelector, targetKeySelector, sourceGuidSelector, targetByGuidProvider, sourceKey, out var located))
{
return new MapSourceKeyResult<TTargetKey>(true, located);
}
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
using CMS.DataEngine;
using CMS.DataProtection;

using MediatR;

using Microsoft.Data.SqlClient;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;

Expand All @@ -12,47 +12,20 @@
using Migration.Tool.Core.K11.Contexts;
using Migration.Tool.K11;
using Migration.Tool.K11.Models;
using Migration.Tool.KXP.Context;

namespace Migration.Tool.Core.K11.Handlers;

public class MigrateDataProtectionCommandHandler : IRequestHandler<MigrateDataProtectionCommand, CommandResult>, IDisposable
public class MigrateDataProtectionCommandHandler(
ILogger<MigrateDataProtectionCommandHandler> logger,
IDbContextFactory<K11Context> k11ContextFactory,
IEntityMapper<CmsConsentAgreement, ConsentAgreementInfo> consentAgreementMapper,
IEntityMapper<CmsConsentArchive, ConsentArchiveInfo> consentArchiveMapper,
IEntityMapper<CmsConsent, ConsentInfo> consentMapper,
PrimaryKeyMappingContext primaryKeyMappingContext,
IProtocol protocol
) : IRequestHandler<MigrateDataProtectionCommand, CommandResult>
{
private static readonly int batchSize = 1000;
private readonly IEntityMapper<CmsConsentAgreement, KXP.Models.CmsConsentAgreement> consentAgreementMapper;
private readonly IEntityMapper<CmsConsentArchive, KXP.Models.CmsConsentArchive> consentArchiveMapper;
private readonly IEntityMapper<CmsConsent, KXP.Models.CmsConsent> consentMapper;
private readonly IDbContextFactory<K11Context> k11ContextFactory;
private readonly IDbContextFactory<KxpContext> kxpContextFactory;
private readonly ILogger<MigrateDataProtectionCommandHandler> logger;
private readonly PrimaryKeyMappingContext primaryKeyMappingContext;
private readonly IProtocol protocol;

private KxpContext kxpContext;

public MigrateDataProtectionCommandHandler(
ILogger<MigrateDataProtectionCommandHandler> logger,
IDbContextFactory<KxpContext> kxpContextFactory,
IDbContextFactory<K11Context> k11ContextFactory,
IEntityMapper<CmsConsent, KXP.Models.CmsConsent> consentMapper,
IEntityMapper<CmsConsentArchive, KXP.Models.CmsConsentArchive> consentArchiveMapper,
IEntityMapper<CmsConsentAgreement, KXP.Models.CmsConsentAgreement> consentAgreementMapper,
PrimaryKeyMappingContext primaryKeyMappingContext,
IProtocol protocol
)
{
this.logger = logger;
this.kxpContextFactory = kxpContextFactory;
this.k11ContextFactory = k11ContextFactory;
this.consentMapper = consentMapper;
this.consentArchiveMapper = consentArchiveMapper;
this.consentAgreementMapper = consentAgreementMapper;
this.primaryKeyMappingContext = primaryKeyMappingContext;
this.protocol = protocol;
kxpContext = this.kxpContextFactory.CreateDbContext();
}

public void Dispose() => kxpContext.Dispose();

public async Task<CommandResult> Handle(MigrateDataProtectionCommand request, CancellationToken cancellationToken)
{
Expand All @@ -72,46 +45,21 @@ private async Task<CommandResult> MigrateConsent(CancellationToken cancellationT
protocol.FetchedSource(k11Consent);
logger.LogTrace("Migrating consent {ConsentName} with ConsentGuid {ConsentGuid}", k11Consent.ConsentName, k11Consent.ConsentGuid);

var kxoConsent = await kxpContext.CmsConsents.FirstOrDefaultAsync(consent => consent.ConsentGuid == k11Consent.ConsentGuid, cancellationToken);
var kxoConsent = ConsentInfo.Provider.Get().WhereEquals(nameof(ConsentInfo.ConsentGuid), k11Consent.ConsentGuid).FirstOrDefault();
protocol.FetchedTarget(kxoConsent);

var mapped = consentMapper.Map(k11Consent, kxoConsent);
protocol.MappedTarget(mapped);

if (mapped is { Success: true } result)
{
(var cmsConsent, bool newInstance) = result;
ArgumentNullException.ThrowIfNull(cmsConsent, nameof(cmsConsent));

if (newInstance)
{
kxpContext.CmsConsents.Add(cmsConsent);
}
else
{
kxpContext.CmsConsents.Update(cmsConsent);
}
(var consentInfo, bool newInstance) = result;
ArgumentNullException.ThrowIfNull(consentInfo, nameof(consentInfo));

try
{
await kxpContext.SaveChangesAsync(cancellationToken);

protocol.Success(k11Consent, cmsConsent, mapped);
logger.LogEntitySetAction(newInstance, cmsConsent);
primaryKeyMappingContext.SetMapping<CmsConsent>(r => r.ConsentId, k11Consent.ConsentId, cmsConsent.ConsentId);
}
/*Violation in unique index or Violation in unique constraint */
catch (DbUpdateException dbUpdateException) when (dbUpdateException.InnerException is SqlException { Number: 2601 or 2627 } sqlException)
{
logger.LogEntitySetError(sqlException, newInstance, k11Consent);
protocol.Append(HandbookReferences
.DbConstraintBroken(sqlException, k11Consent)
.WithMessage("Failed to migrate consent, target database constraint broken.")
);

await kxpContext.DisposeAsync();
kxpContext = await kxpContextFactory.CreateDbContextAsync(cancellationToken);
}
ConsentInfo.Provider.Set(consentInfo);
protocol.Success(k11Consent, consentInfo, mapped);
logger.LogEntitySetAction(newInstance, consentInfo);
primaryKeyMappingContext.SetMapping<CmsConsent>(r => r.ConsentId, k11Consent.ConsentId, consentInfo.ConsentID);
}
}

Expand All @@ -127,47 +75,22 @@ private async Task<CommandResult> MigrateConsentArchive(CancellationToken cancel
protocol.FetchedSource(k11ArchiveConsent);
logger.LogTrace("Migrating consent archive with ConsentArchiveGuid {ConsentGuid}", k11ArchiveConsent.ConsentArchiveGuid);

var kxoConsentArchive = await kxpContext.CmsConsentArchives.FirstOrDefaultAsync(consentArchive => consentArchive.ConsentArchiveGuid == k11ArchiveConsent.ConsentArchiveGuid, cancellationToken);
var kxoConsentArchive = ConsentArchiveInfo.Provider.Get().WhereEquals(nameof(ConsentArchiveInfo.ConsentArchiveGuid), k11ArchiveConsent.ConsentArchiveGuid).FirstOrDefault();
protocol.FetchedTarget(kxoConsentArchive);

var mapped = consentArchiveMapper.Map(k11ArchiveConsent, kxoConsentArchive);
protocol.MappedTarget(mapped);

if (mapped is { Success: true } result)
{
(var cmsConsentArchive, bool newInstance) = result;
ArgumentNullException.ThrowIfNull(cmsConsentArchive, nameof(cmsConsentArchive));

if (newInstance)
{
kxpContext.CmsConsentArchives.Add(cmsConsentArchive);
}
else
{
kxpContext.CmsConsentArchives.Update(cmsConsentArchive);
}

try
{
await kxpContext.SaveChangesAsync(cancellationToken);

protocol.Success(k11ArchiveConsent, cmsConsentArchive, mapped);
logger.LogEntitySetAction(newInstance, cmsConsentArchive);
primaryKeyMappingContext.SetMapping<CmsConsentArchive>(r => r.ConsentArchiveGuid,
k11ArchiveConsent.ConsentArchiveId, cmsConsentArchive.ConsentArchiveId);
}
/*Violation in unique index or Violation in unique constraint */
catch (DbUpdateException dbUpdateException) when (dbUpdateException.InnerException is SqlException { Number: 2601 or 2627 } sqlException)
{
logger.LogEntitySetError(sqlException, newInstance, k11ArchiveConsent);
protocol.Append(HandbookReferences
.DbConstraintBroken(sqlException, k11ArchiveConsent)
.WithMessage("Failed to migrate consent archive, target database constraint broken.")
);

await kxpContext.DisposeAsync();
kxpContext = await kxpContextFactory.CreateDbContextAsync(cancellationToken);
}
(var consentArchiveInfo, bool newInstance) = result;
ArgumentNullException.ThrowIfNull(consentArchiveInfo, nameof(consentArchiveInfo));

ConsentArchiveInfo.Provider.Set(consentArchiveInfo);
protocol.Success(k11ArchiveConsent, consentArchiveInfo, mapped);
logger.LogEntitySetAction(newInstance, consentArchiveInfo);
primaryKeyMappingContext.SetMapping<CmsConsentArchive>(r => r.ConsentArchiveGuid,
k11ArchiveConsent.ConsentArchiveId, consentArchiveInfo.ConsentArchiveID);
}
}

Expand All @@ -179,33 +102,33 @@ private async Task<CommandResult> MigrateConsentAgreement(CancellationToken canc
await using var k11Context = await k11ContextFactory.CreateDbContextAsync(cancellationToken);
int index = 0;
int indexFull = 0;
var consentAgreementUpdates = new List<KXP.Models.CmsConsentAgreement>();
var consentAgreementNews = new List<KXP.Models.CmsConsentAgreement>();
var consentAgreementUpdates = new List<ConsentAgreementInfo>();
var consentAgreementNews = new List<ConsentAgreementInfo>();
int itemsCount = k11Context.CmsConsentAgreements.Count();

foreach (var k11ConsentAgreement in k11Context.CmsConsentAgreements)
{
protocol.FetchedSource(k11ConsentAgreement);
logger.LogTrace("Migrating consent agreement with ConsentAgreementGuid {ConsentAgreementGuid}", k11ConsentAgreement.ConsentAgreementGuid);

var kxoConsentAgreement = await kxpContext.CmsConsentAgreements.FirstOrDefaultAsync(consentAgreement => consentAgreement.ConsentAgreementGuid == k11ConsentAgreement.ConsentAgreementGuid, cancellationToken);
var kxoConsentAgreement = ConsentAgreementInfo.Provider.Get().WhereEquals(nameof(ConsentAgreementInfo.ConsentAgreementGuid), k11ConsentAgreement.ConsentAgreementGuid).FirstOrDefault();
protocol.FetchedTarget(kxoConsentAgreement);

var mapped = consentAgreementMapper.Map(k11ConsentAgreement, kxoConsentAgreement);
protocol.MappedTarget(mapped);

if (mapped is { Success: true } result)
{
(var cmsConsentAgreement, bool newInstance) = result;
ArgumentNullException.ThrowIfNull(cmsConsentAgreement, nameof(cmsConsentAgreement));
(var agreementInfo, bool newInstance) = result;
ArgumentNullException.ThrowIfNull(agreementInfo, nameof(agreementInfo));

if (newInstance)
{
consentAgreementNews.Add(cmsConsentAgreement);
consentAgreementNews.Add(agreementInfo);
}
else
{
consentAgreementUpdates.Add(cmsConsentAgreement);
ConsentAgreementInfo.Provider.Set(agreementInfo);
}
}

Expand All @@ -214,58 +137,15 @@ private async Task<CommandResult> MigrateConsentAgreement(CancellationToken canc

if (index == batchSize || indexFull == itemsCount)
{
kxpContext.CmsConsentAgreements.AddRange(consentAgreementNews);
kxpContext.CmsConsentAgreements.UpdateRange(consentAgreementUpdates);

try
{
await kxpContext.SaveChangesAsync(cancellationToken);

ConsentAgreementInfo.Provider.BulkInsert(consentAgreementNews);
foreach (var newK11ConsentAgreement in consentAgreementNews)
{
protocol.Success(k11ConsentAgreement, newK11ConsentAgreement, mapped);
logger.LogDebug("CmsConsentAgreement: with ConsentAgreementGuid \'{ConsentAgreementGuid}\' was inserted",
newK11ConsentAgreement.ConsentAgreementGuid);
}

foreach (var updateK11ConsentAgreement in consentAgreementUpdates)
{
protocol.Success(k11ConsentAgreement, updateK11ConsentAgreement, mapped);
logger.LogDebug("CmsConsentAgreement: with ConsentAgreementGuid \'{ConsentAgreementGuid}\' was updated",
updateK11ConsentAgreement.ConsentAgreementGuid);
}
}
catch (DbUpdateException dbUpdateException) when (
dbUpdateException.InnerException is SqlException sqlException &&
sqlException.Message.Contains("Cannot insert duplicate key row in object")
)
{
await kxpContext.DisposeAsync();

protocol.Append(HandbookReferences
.ErrorCreatingTargetInstance<KXP.Models.CmsConsentAgreement>(dbUpdateException)
.NeedsManualAction()
.WithIdentityPrints(consentAgreementNews)
);
logger.LogEntitiesSetError(dbUpdateException, true, consentAgreementNews);


protocol.Append(HandbookReferences
.ErrorUpdatingTargetInstance<KXP.Models.CmsConsentAgreement>(dbUpdateException)
.NeedsManualAction()
.WithIdentityPrints(consentAgreementUpdates)
);

var cai = ConsentAgreementInfo.New();
protocol.Append(HandbookReferences
.ErrorUpdatingTargetInstance<KXP.Models.CmsConsentAgreement>(dbUpdateException)
.NeedsManualAction()
.WithIdentityPrint(cai)
);

logger.LogEntitiesSetError(dbUpdateException, false, consentAgreementUpdates);

kxpContext = await kxpContextFactory.CreateDbContextAsync(cancellationToken);
}
finally
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ private async Task MigrateUserRole(int k11RoleId)
if (!primaryKeyMappingContext.TryRequireMapFromSource<CmsRole>(u => u.RoleId, k11RoleId, out int xbkRoleId))
{
var handbookRef = HandbookReferences
.MissingRequiredDependency<KXP.Models.CmsRole>(nameof(UserRoleInfo.RoleID), k11UserRole.RoleId)
.MissingRequiredDependency<RoleInfo>(nameof(UserRoleInfo.RoleID), k11UserRole.RoleId)
.NeedsManualAction();

protocol.Append(handbookRef);
Expand Down
Loading
Loading