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

release v1.1.0 #208

Merged
merged 23 commits into from
Jul 24, 2024
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
e3dd8ac
MT-28 XbyK upgrade 29.2.0 & obsolete configuration removed
tkrch Jul 2, 2024
3b912c3
MT-28 legacy XbyK DB model regeneration + implied fixes
tkrch Jul 2, 2024
7401a2a
MT-17 migration of documents with non-unique DocumentGuid
tkrch Jul 3, 2024
f9c273a
MT-17 non-unique DocumentGUID & NodeGUID support
tkrch Jul 9, 2024
a0214b5
MT-17 cleanup
tkrch Jul 9, 2024
b318df1
#184 deprecation of XbKConnectionString
tkrch Jul 14, 2024
d69d071
#184 deprecation of XbKConnectionString - md file update
tkrch Jul 14, 2024
73ba959
#198 migration of media file refactor; fails for member users resoved
tkrch Jul 14, 2024
385963b
Merge pull request #205 from Kentico/fix/184_deprecation_of_XbKConnec…
fialafilip Jul 15, 2024
9d815ec
Merge pull request #206 from Kentico/fix/198_media_migration_non_admi…
fialafilip Jul 15, 2024
9e2a34c
confict resolving in relation to master branch
tkrch Jul 15, 2024
e677291
solution reformat to match master formatting
tkrch Jul 15, 2024
9f5f9df
conflicts resolving
tkrch Jul 15, 2024
17fd926
eol crlf
tkrch Jul 15, 2024
4e5fc0a
dotnet format autofix
tkrch Jul 15, 2024
ec82551
merge conflicts fix
tkrch Jul 16, 2024
f650f95
.editorconfig update & global reformat
tkrch Jul 16, 2024
f5c66ae
reformat and code cleanup
tkrch Jul 16, 2024
e0806a9
Merge branch 'master' into rls/v1.1.0
tkrch Jul 16, 2024
42ce815
dotnet format uncommented
tkrch Jul 22, 2024
45d664a
Feat/199 unpublished doc versions published (#209)
tkrch Jul 22, 2024
d2e4440
naming conventions update, obsolete class removal
tkrch Jul 22, 2024
94f5c49
handling of multiple attachments with same guid in source instance - …
tkrch Jul 22, 2024
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
2 changes: 2 additions & 0 deletions KVA/Migration.Toolkit.Source/Auxiliary/NodeXmlAdapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ public bool HasValueSet(string columnName)
public int? NodeParentID => _xClass.Element(NodeXmlColumns.NODE_PARENT_ID)?.Value<int>();
public int? NodeLevel => _xClass.Element(NodeXmlColumns.NODE_LEVEL)?.Value<int>();
public int? NodeSiteID => _xClass.Element(NodeXmlColumns.NODE_SITE_ID)?.Value<int>();
[Obsolete("NodeGUID is not unique, use other means of node identification", true)]
public Guid? NodeGUID => _xClass.Element(NodeXmlColumns.NODE_GUID)?.Value<Guid>();
public int? NodeOrder => _xClass.Element(NodeXmlColumns.NODE_ORDER)?.Value<int>();
public int? NodeOwner => _xClass.Element(NodeXmlColumns.NODE_OWNER)?.Value<int>();
Expand All @@ -63,6 +64,7 @@ public bool HasValueSet(string columnName)
public string? DocumentContent => _xClass.Element(NodeXmlColumns.DOCUMENT_CONTENT)?.Value;
public string? DocumentLastVersionNumber => _xClass.Element(NodeXmlColumns.DOCUMENT_LAST_VERSION_NUMBER)?.Value;
public bool? DocumentIsArchived => _xClass.Element(NodeXmlColumns.DOCUMENT_IS_ARCHIVED)?.ValueAsBool();
[Obsolete("DocumentGUID is not unique, use other means of document identification", true)]
public Guid? DocumentGUID => _xClass.Element(NodeXmlColumns.DOCUMENT_GUID)?.Value<Guid>();
public Guid? DocumentWorkflowCycleGUID => _xClass.Element(NodeXmlColumns.DOCUMENT_WORKFLOW_CYCLE_GUID)?.Value<Guid>();
public bool? DocumentCanBePublished => _xClass.Element(NodeXmlColumns.DOCUMENT_CAN_BE_PUBLISHED)?.ValueAsBool();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,20 @@
namespace Migration.Toolkit.Source.Behaviors;

using MediatR;
using Microsoft.Data.SqlClient;
using Microsoft.Extensions.Logging;
using Migration.Toolkit.Common;
using Migration.Toolkit.Common.Abstractions;
using Migration.Toolkit.Common.MigrationProtocol;
using Migration.Toolkit.Source.Model;

public class CommandConstraintBehavior<TRequest, TResponse>(
ILogger<CommandConstraintBehavior<TRequest, TResponse>> logger,
IMigrationProtocol protocol,
ToolkitConfiguration toolkitConfiguration,
ModelFacade modelFacade)
: IPipelineBehavior<TRequest, TResponse>
where TRequest : IRequest<TResponse>
where TResponse : CommandResult
{
public async Task<TResponse> Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate<TResponse> next)
public async Task<TResponse> Handle(TRequest request, RequestHandlerDelegate<TResponse> next, CancellationToken cancellationToken)
{
try
{
Expand All @@ -40,14 +37,7 @@ public async Task<TResponse> Handle(TRequest request, CancellationToken cancella
private bool PerformChecks(TRequest request)
{
var criticalCheckPassed = true;
// const string supportedVersion = "13.0.64";
// const string supportedVersion = "13.0.0";
// if (SemanticVersion.TryParse(supportedVersion, out var minimalVersion))
// {
// criticalCheckPassed &= CheckVersion(minimalVersion);
// }

// var sites = _toolkitConfiguration.RequireExplicitMapping<KX13M.CmsSite>(s => s.SiteId);
var sourceSites = modelFacade.SelectAll<ICmsSite>()
.ToList();

Expand All @@ -64,144 +54,9 @@ private bool PerformChecks(TRequest request)
criticalCheckPassed &= CheckCulture(cultureReliantCommand, sourceSites, cultures, siteCultures);
}

// criticalCheckPassed &= CheckDbCollations();

return criticalCheckPassed;
}

// private bool CheckVersion(KX13Context kx13Context, SemanticVersion minimalVersion)
// {
// var criticalCheckPassed = true;
//
// #region Check conclusion methods
//
// void UnableToReadVersionKey(string keyName)
// {
// logger.LogCritical("Unable to read CMS version (incorrect format) - SettingsKeyName '{Key}'. Ensure Kentico version is at least '{SupportedVersion}'", keyName, minimalVersion.ToString());
// protocol.Append(HandbookReferences.InvalidSourceCmsVersion().WithData(new
// {
// ErrorKind = "Settings key value incorrect format",
// SettingsKeyName = keyName,
// SupportedVersion = minimalVersion.ToString()
// }));
// criticalCheckPassed = false;
// }
//
// void VersionKeyNotFound(string keyName)
// {
// logger.LogCritical("CMS version not found - SettingsKeyName '{Key}'. Ensure Kentico version is at least '{SupportedVersion}'", keyName, minimalVersion.ToString());
// protocol.Append(HandbookReferences.InvalidSourceCmsVersion().WithData(new
// {
// ErrorKind = "Settings key not found",
// SettingsKeyName = keyName,
// SupportedVersion = minimalVersion.ToString()
// }));
// criticalCheckPassed = false;
// }
//
// void UpgradeNeeded(string keyName, string currentVersion)
// {
// logger.LogCritical("{Key} '{CurrentVersion}' is not supported for migration. Upgrade Kentico to at least '{SupportedVersion}'", keyName, currentVersion, minimalVersion.ToString());
// protocol.Append(HandbookReferences.InvalidSourceCmsVersion().WithData(new
// {
// CurrentVersion = currentVersion,
// SupportedVersion = minimalVersion.ToString()
// }));
// criticalCheckPassed = false;
// }
//
// void LowHotfix(string keyName, int currentHotfix)
// {
// logger.LogCritical("{Key} '{CurrentVersion}' hotfix is not supported for migration. Upgrade Kentico to at least '{SupportedVersion}'", keyName, currentHotfix, minimalVersion.ToString());
// protocol.Append(HandbookReferences.InvalidSourceCmsVersion().WithData(new
// {
// CurrentHotfix = currentHotfix.ToString(),
// SupportedVersion = minimalVersion.ToString()
// }));
// criticalCheckPassed = false;
// }
//
// #endregion
//
// if (kx13Context.CmsSettingsKeys.FirstOrDefault(s => s.KeyName == SettingsKeys.CMSDataVersion) is { } cmsDataVersion)
// {
// if (SemanticVersion.TryParse(cmsDataVersion.KeyValue, out var cmsDataVer))
// {
// if (cmsDataVer.IsLesserThan(minimalVersion))
// {
// UpgradeNeeded(SettingsKeys.CMSDataVersion, cmsDataVer.ToString());
// }
// }
// else
// {
// UnableToReadVersionKey(SettingsKeys.CMSDataVersion);
// }
// }
// else
// {
// VersionKeyNotFound(SettingsKeys.CMSDataVersion);
// }
//
// if (kx13Context.CmsSettingsKeys.FirstOrDefault(s => s.KeyName == SettingsKeys.CMSDBVersion) is { } cmsDbVersion)
// {
// if (SemanticVersion.TryParse(cmsDbVersion.KeyValue, out var cmsDataVer))
// {
// if (cmsDataVer.IsLesserThan(minimalVersion))
// {
// UpgradeNeeded(SettingsKeys.CMSDBVersion, cmsDataVer.ToString());
// }
// }
// else
// {
// UnableToReadVersionKey(SettingsKeys.CMSDBVersion);
// }
// }
// else
// {
// VersionKeyNotFound(SettingsKeys.CMSDBVersion);
// }
//
// if (kx13Context.CmsSettingsKeys.FirstOrDefault(s => s.KeyName == SettingsKeys.CMSHotfixDataVersion) is { } cmsHotfixDataVersion)
// {
// if (int.TryParse(cmsHotfixDataVersion.KeyValue, out var version))
// {
// if (version < minimalVersion.Hotfix)
// {
// LowHotfix(SettingsKeys.CMSHotfixDataVersion, version);
// }
// }
// else
// {
// UnableToReadVersionKey(SettingsKeys.CMSHotfixDataVersion);
// }
// }
// else
// {
// VersionKeyNotFound(SettingsKeys.CMSHotfixDataVersion);
// }
//
// if (kx13Context.CmsSettingsKeys.FirstOrDefault(s => s.KeyName == SettingsKeys.CMSHotfixVersion) is { } cmsHotfixVersion)
// {
// if (int.TryParse(cmsHotfixVersion.KeyValue, out var version))
// {
// if (version < minimalVersion.Hotfix)
// {
// LowHotfix(SettingsKeys.CMSHotfixVersion, version);
// }
// }
// else
// {
// UnableToReadVersionKey(SettingsKeys.CMSHotfixVersion);
// }
// }
// else
// {
// VersionKeyNotFound(SettingsKeys.CMSHotfixVersion);
// }
//
// return criticalCheckPassed;
// }

private bool CheckSite(List<ICmsSite> sourceSites, int sourceSiteId)
{
var criticalCheckPassed = true;
Expand Down Expand Up @@ -256,28 +111,4 @@ private bool CheckCulture(ICultureReliantCommand cultureReliantCommand, List<ICm

return criticalCheckPassed;
}

// TODO tk: 2022-11-02 create global rule
private bool CheckDbCollations()
{
var kxCollation = GetDbCollationName(toolkitConfiguration.KxConnectionString ?? throw new InvalidOperationException("KxConnectionString is required"));
var xbkCollation = GetDbCollationName(toolkitConfiguration.XbKConnectionString ?? throw new InvalidOperationException("XbKConnectionString is required"));
var collationAreSame = kxCollation == xbkCollation;
if (!collationAreSame)
{
logger.LogCritical("Source db collation '{SourceDbCollation}' is not same as target db collation {TargetDbCollation} => same collations are required", kxCollation, xbkCollation);
}

return collationAreSame;
}

private string? GetDbCollationName(string connectionString)
{
using var sqlConnection = new SqlConnection(connectionString);
using var sqlCommand = sqlConnection.CreateCommand();
sqlCommand.CommandText = "SELECT DATABASEPROPERTYEX(DB_NAME(), 'Collation')";

sqlConnection.Open();
return sqlCommand.ExecuteScalar() as string;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public class RequestHandlingBehavior<TRequest, TResponse>(
where TRequest : IRequest<TResponse>
where TResponse : CommandResult
{
public async Task<TResponse> Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate<TResponse> next)
public async Task<TResponse> Handle(TRequest request, RequestHandlerDelegate<TResponse> next, CancellationToken cancellationToken)
{
var sw = Stopwatch.StartNew();
logger.LogInformation("Handling {CommandName}", typeof(TRequest).Name);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public class XbKApiContextBehavior<TRequest, TResponse>(
where TRequest : IRequest<TResponse>
where TResponse : CommandResult
{
public async Task<TResponse> Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate<TResponse> next)
public async Task<TResponse> Handle(TRequest request, RequestHandlerDelegate<TResponse> next, CancellationToken cancellationToken)
{
initializer.EnsureApiIsInitialized();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
using System.Reflection;
using Microsoft.Extensions.Logging;
using Migration.Toolkit.Common;
using Migration.Toolkit.Common.Services;
using Migration.Toolkit.Source.Services;

public class PrimaryKeyMappingContext(
Expand All @@ -23,7 +22,7 @@ public class PrimaryKeyMappingContext(
var mappings = toolkitConfiguration.EntityConfigurations?.GetEntityConfiguration<T>().ExplicitPrimaryKeyMapping;
if (mappings?.TryGetValue(memberName, out var memberMappings) ?? false)
{
return memberMappings.TryGetValue($"{sourceId}", out var mappedId) ? mappedId : null;
return memberMappings.GetValueOrDefault($"{sourceId}");
}

return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,17 @@ AttachmentMigrator attachmentMigrator
{
public async Task<CommandResult> Handle(MigrateAttachmentsCommand request, CancellationToken cancellationToken)
{
var kx13CmsAttachments = modelFacade.SelectAll<ICmsAttachment>();
var ksCmsAttachments = modelFacade.SelectAll<ICmsAttachment>();

foreach (var kx13CmsAttachment in kx13CmsAttachments)
foreach (var ksCmsAttachment in ksCmsAttachments)
{
if (kx13CmsAttachment.AttachmentIsUnsorted != true || kx13CmsAttachment.AttachmentGroupGUID != null)
if (ksCmsAttachment.AttachmentIsUnsorted != true || ksCmsAttachment.AttachmentGroupGUID != null)
{
// those must be migrated with pages
continue;
}

var (_, canContinue, _, _) = attachmentMigrator.MigrateAttachment(kx13CmsAttachment);
var (_, canContinue, _, _) = attachmentMigrator.MigrateAttachment(ksCmsAttachment);
if (!canContinue)
break;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ public class MigrateCategoriesCommandHandler(
ModelFacade modelFacade,
IImporter importer,
ReusableSchemaService reusableSchemaService,
IUmtMapper<TagModelSource> tagModelMapper
IUmtMapper<TagModelSource> tagModelMapper,
SpoiledGuidContext spoiledGuidContext
) : IRequestHandler<MigrateCategoriesCommand, CommandResult>
{
public async Task<CommandResult> Handle(MigrateCategoriesCommand request, CancellationToken cancellationToken)
Expand Down Expand Up @@ -106,7 +107,7 @@ FROM View_CMS_Tree_Joined [TJ]
.AssertSuccess<TagInfo>(logger) is {Success:true, Info: {} tag})
{
query = """
SELECT TJ.DocumentGUID, CDC.CategoryID, TJ.DocumentCheckedOutVersionHistoryID, TJ.NodeClassID
SELECT TJ.DocumentGUID, TJ.NodeSiteID, TJ.NodeID, TJ.DocumentID, CDC.CategoryID, TJ.DocumentCheckedOutVersionHistoryID, TJ.NodeClassID
FROM View_CMS_Tree_Joined [TJ]
JOIN dbo.CMS_DocumentCategory [CDC] on [TJ].DocumentID = [CDC].DocumentID
JOIN dbo.CMS_Category CC on CDC.CategoryID = CC.CategoryID AND CC.CategoryUserID IS NULL
Expand All @@ -115,10 +116,16 @@ FROM View_CMS_Tree_Joined [TJ]

var docsWithCategories = modelFacade.Select(query, (reader, _) => new
{
DocumentGUID = reader.Unbox<Guid>("DocumentGUID"),
CategoryID = reader.Unbox<int?>("CategoryID"),
DocumentCheckedOutVersionHistoryID = reader.Unbox<int?>("DocumentCheckedOutVersionHistoryID"),
NodeClassID = reader.Unbox<int>("NodeClassID")
NodeClassID = reader.Unbox<int>("NodeClassID"),
NodeSiteID = reader.Unbox<int>("NodeSiteID"),
DocumentGUID = spoiledGuidContext.EnsureDocumentGuid(
reader.Unbox<Guid>("DocumentGUID"),
reader.Unbox<int>("NodeSiteID"),
reader.Unbox<int>("NodeID"),
reader.Unbox<int>("DocumentID")
)
}, new SqlParameter("categoryId", cmsCategory.CategoryID));

foreach (var dwc in docsWithCategories)
Expand Down
Loading