Add NTFS automatic ensure timeout diagnostics
This commit is contained in:
@@ -1146,7 +1146,17 @@ namespace C4IT.LIAM
|
|||||||
bool ensureTraverseGroups = false,
|
bool ensureTraverseGroups = false,
|
||||||
bool whatIf = false)
|
bool whatIf = false)
|
||||||
{
|
{
|
||||||
|
var stopwatch = Stopwatch.StartNew();
|
||||||
|
LogEntry(
|
||||||
|
$"NTFS permission ensure provider start. Stage=Start Path='{folderPath}', AllowSharePathEnsure={allowSharePathEnsure}, EnsureTraverseGroups={ensureTraverseGroups}, WhatIf={whatIf}",
|
||||||
|
LogLevels.Debug);
|
||||||
|
|
||||||
|
LogEntry($"NTFS permission ensure provider stage. Stage=Classify Path='{folderPath}'", LogLevels.Debug);
|
||||||
var classification = ClassifyPath(folderPath);
|
var classification = ClassifyPath(folderPath);
|
||||||
|
LogEntry(
|
||||||
|
$"NTFS permission ensure provider stage finished. Stage=Classify Path='{folderPath}', PathKind='{classification?.Kind}', NormalizedPath='{classification?.NormalizedPath}', Elapsed='{stopwatch.Elapsed}'",
|
||||||
|
LogLevels.Debug);
|
||||||
|
|
||||||
var allowShareKinds = allowSharePathEnsure;
|
var allowShareKinds = allowSharePathEnsure;
|
||||||
if (!IsSupportedPermissionManagedPathKind(
|
if (!IsSupportedPermissionManagedPathKind(
|
||||||
classification,
|
classification,
|
||||||
@@ -1165,6 +1175,7 @@ namespace C4IT.LIAM
|
|||||||
|
|
||||||
string matchingConfigurationKey;
|
string matchingConfigurationKey;
|
||||||
string matchingRule;
|
string matchingRule;
|
||||||
|
LogEntry($"NTFS permission ensure provider stage. Stage=Blacklist Path='{folderPath}'", LogLevels.Debug);
|
||||||
if (IsPathBlacklisted(classification, out matchingConfigurationKey, out matchingRule))
|
if (IsPathBlacklisted(classification, out matchingConfigurationKey, out matchingRule))
|
||||||
{
|
{
|
||||||
return Task.FromResult(new ResultToken(System.Reflection.MethodBase.GetCurrentMethod().ToString())
|
return Task.FromResult(new ResultToken(System.Reflection.MethodBase.GetCurrentMethod().ToString())
|
||||||
@@ -1174,6 +1185,7 @@ namespace C4IT.LIAM
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LogEntry($"NTFS permission ensure provider stage. Stage=Whitelist Path='{folderPath}'", LogLevels.Debug);
|
||||||
if (!IsPathWhitelisted(classification, false, out matchingConfigurationKey, out matchingRule))
|
if (!IsPathWhitelisted(classification, false, out matchingConfigurationKey, out matchingRule))
|
||||||
{
|
{
|
||||||
return Task.FromResult(new ResultToken(System.Reflection.MethodBase.GetCurrentMethod().ToString())
|
return Task.FromResult(new ResultToken(System.Reflection.MethodBase.GetCurrentMethod().ToString())
|
||||||
@@ -1184,6 +1196,7 @@ namespace C4IT.LIAM
|
|||||||
}
|
}
|
||||||
|
|
||||||
string levelSkipReason;
|
string levelSkipReason;
|
||||||
|
LogEntry($"NTFS permission ensure provider stage. Stage=LevelRange Path='{folderPath}'", LogLevels.Debug);
|
||||||
if (!IsPermissionLevelManagedPath(classification, out levelSkipReason))
|
if (!IsPermissionLevelManagedPath(classification, out levelSkipReason))
|
||||||
{
|
{
|
||||||
return Task.FromResult(new ResultToken(System.Reflection.MethodBase.GetCurrentMethod().ToString())
|
return Task.FromResult(new ResultToken(System.Reflection.MethodBase.GetCurrentMethod().ToString())
|
||||||
@@ -1193,7 +1206,13 @@ namespace C4IT.LIAM
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LogEntry($"NTFS permission ensure provider stage. Stage=ParentPath Path='{folderPath}'", LogLevels.Debug);
|
||||||
var parentPath = Directory.GetParent(folderPath)?.FullName;
|
var parentPath = Directory.GetParent(folderPath)?.FullName;
|
||||||
|
LogEntry(
|
||||||
|
$"NTFS permission ensure provider stage finished. Stage=ParentPath Path='{folderPath}', ParentPath='{parentPath}', Elapsed='{stopwatch.Elapsed}'",
|
||||||
|
LogLevels.Debug);
|
||||||
|
|
||||||
|
LogEntry($"NTFS permission ensure provider stage. Stage=CreateFilesystemEngine Path='{folderPath}'", LogLevels.Debug);
|
||||||
var engine = CreateFilesystemEngine(
|
var engine = CreateFilesystemEngine(
|
||||||
folderPath,
|
folderPath,
|
||||||
parentPath,
|
parentPath,
|
||||||
@@ -1202,6 +1221,9 @@ namespace C4IT.LIAM
|
|||||||
readerSids,
|
readerSids,
|
||||||
writerSids);
|
writerSids);
|
||||||
engine.WhatIf = whatIf;
|
engine.WhatIf = whatIf;
|
||||||
|
LogEntry(
|
||||||
|
$"NTFS permission ensure provider stage finished. Stage=CreateFilesystemEngine Path='{folderPath}', Elapsed='{stopwatch.Elapsed}'",
|
||||||
|
LogLevels.Debug);
|
||||||
|
|
||||||
var allowTraverseGroups = ensureTraverseGroups
|
var allowTraverseGroups = ensureTraverseGroups
|
||||||
&& IsSupportedPermissionManagedPathKind(
|
&& IsSupportedPermissionManagedPathKind(
|
||||||
@@ -1209,7 +1231,13 @@ namespace C4IT.LIAM
|
|||||||
eNtfsPathKind.Folder,
|
eNtfsPathKind.Folder,
|
||||||
eNtfsPathKind.ClassicShare,
|
eNtfsPathKind.ClassicShare,
|
||||||
eNtfsPathKind.DfsLink);
|
eNtfsPathKind.DfsLink);
|
||||||
|
LogEntry(
|
||||||
|
$"NTFS permission ensure provider stage. Stage=EngineEnsureDataAreaPermissions Path='{folderPath}', AllowTraverseGroups={allowTraverseGroups}",
|
||||||
|
LogLevels.Debug);
|
||||||
var resultToken = engine.ensureDataAreaPermissions(allowTraverseGroups);
|
var resultToken = engine.ensureDataAreaPermissions(allowTraverseGroups);
|
||||||
|
LogEntry(
|
||||||
|
$"NTFS permission ensure provider finished. Stage=EngineEnsureDataAreaPermissions Path='{folderPath}', ResultErrorId={resultToken?.resultErrorId}, ResultMessage='{resultToken?.resultMessage ?? string.Empty}', Elapsed='{stopwatch.Elapsed}'",
|
||||||
|
LogLevels.Debug);
|
||||||
if (!allowTraverseGroups && ensureTraverseGroups)
|
if (!allowTraverseGroups && ensureTraverseGroups)
|
||||||
resultToken.warnings.Add($"Traverse groups are currently only ensured for folder and share paths. Traverse processing was skipped for '{folderPath}'.");
|
resultToken.warnings.Add($"Traverse groups are currently only ensured for folder and share paths. Traverse processing was skipped for '{folderPath}'.");
|
||||||
|
|
||||||
|
|||||||
@@ -352,43 +352,90 @@ namespace C4IT_IAM_SET
|
|||||||
public ResultToken ensureDataAreaPermissions(bool ensureTraverseGroups = false)
|
public ResultToken ensureDataAreaPermissions(bool ensureTraverseGroups = false)
|
||||||
{
|
{
|
||||||
LogMethodBegin(MethodBase.GetCurrentMethod());
|
LogMethodBegin(MethodBase.GetCurrentMethod());
|
||||||
|
var stopwatch = Stopwatch.StartNew();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
DefaultLogger.LogEntry(
|
||||||
|
LogLevels.Debug,
|
||||||
|
$"NTFS engine ensure permissions start. Stage=Start Path='{newFolderPath}', BaseFolder='{baseFolder}', EnsureTraverseGroups={ensureTraverseGroups}, WhatIf={WhatIf}");
|
||||||
|
|
||||||
var resultToken = checkRequiredVariablesForEnsure();
|
var resultToken = checkRequiredVariablesForEnsure();
|
||||||
if (resultToken.resultErrorId != 0)
|
if (resultToken.resultErrorId != 0)
|
||||||
return resultToken;
|
return resultToken;
|
||||||
|
|
||||||
|
DefaultLogger.LogEntry(
|
||||||
|
LogLevels.Debug,
|
||||||
|
$"NTFS engine ensure permissions stage. Stage=NetworkConnection Path='{newFolderPath}', BaseFolder='{baseFolder}'");
|
||||||
|
|
||||||
if (Connection != null)
|
if (Connection != null)
|
||||||
Connection.Dispose();
|
Connection.Dispose();
|
||||||
|
|
||||||
using (Connection = new cNetworkConnection(baseFolder, username, new NetworkCredential("", password).Password))
|
using (Connection = new cNetworkConnection(baseFolder, username, new NetworkCredential("", password).Password))
|
||||||
{
|
{
|
||||||
|
DefaultLogger.LogEntry(
|
||||||
|
LogLevels.Debug,
|
||||||
|
$"NTFS engine ensure permissions stage finished. Stage=NetworkConnection Path='{newFolderPath}', Elapsed='{stopwatch.Elapsed}'");
|
||||||
|
|
||||||
|
DefaultLogger.LogEntry(
|
||||||
|
LogLevels.Debug,
|
||||||
|
$"NTFS engine ensure permissions stage. Stage=DirectoryExists Path='{newFolderPath}'");
|
||||||
if (!Directory.Exists(newFolderPath))
|
if (!Directory.Exists(newFolderPath))
|
||||||
{
|
{
|
||||||
resultToken.resultErrorId = 30203;
|
resultToken.resultErrorId = 30203;
|
||||||
resultToken.resultMessage = "Verzeichnis existiert nicht";
|
resultToken.resultMessage = "Verzeichnis existiert nicht";
|
||||||
return resultToken;
|
return resultToken;
|
||||||
}
|
}
|
||||||
|
DefaultLogger.LogEntry(
|
||||||
|
LogLevels.Debug,
|
||||||
|
$"NTFS engine ensure permissions stage finished. Stage=DirectoryExists Path='{newFolderPath}', Elapsed='{stopwatch.Elapsed}'");
|
||||||
|
|
||||||
|
DefaultLogger.LogEntry(
|
||||||
|
LogLevels.Debug,
|
||||||
|
$"NTFS engine ensure permissions stage. Stage=InitializeFolderContext Path='{newFolderPath}'");
|
||||||
var parentDirectory = Directory.GetParent(newFolderPath);
|
var parentDirectory = Directory.GetParent(newFolderPath);
|
||||||
if (string.IsNullOrWhiteSpace(newFolderParent))
|
if (string.IsNullOrWhiteSpace(newFolderParent))
|
||||||
newFolderParent = parentDirectory?.FullName;
|
newFolderParent = parentDirectory?.FullName;
|
||||||
|
|
||||||
InitializeFolderContext();
|
InitializeFolderContext();
|
||||||
|
DefaultLogger.LogEntry(
|
||||||
|
LogLevels.Debug,
|
||||||
|
$"NTFS engine ensure permissions stage finished. Stage=InitializeFolderContext Path='{newFolderPath}', ParentPath='{newFolderParent}', Elapsed='{stopwatch.Elapsed}'");
|
||||||
|
|
||||||
|
DefaultLogger.LogEntry(
|
||||||
|
LogLevels.Debug,
|
||||||
|
$"NTFS engine ensure permissions stage. Stage=ValidateTraverseBoundary Path='{newFolderPath}'");
|
||||||
var traverseBoundaryResult = ValidateTraverseBoundaryForCurrentFolder();
|
var traverseBoundaryResult = ValidateTraverseBoundaryForCurrentFolder();
|
||||||
if (traverseBoundaryResult.resultErrorId != 0)
|
if (traverseBoundaryResult.resultErrorId != 0)
|
||||||
return traverseBoundaryResult;
|
return traverseBoundaryResult;
|
||||||
|
DefaultLogger.LogEntry(
|
||||||
|
LogLevels.Debug,
|
||||||
|
$"NTFS engine ensure permissions stage finished. Stage=ValidateTraverseBoundary Path='{newFolderPath}', Elapsed='{stopwatch.Elapsed}'");
|
||||||
|
|
||||||
|
DefaultLogger.LogEntry(
|
||||||
|
LogLevels.Debug,
|
||||||
|
$"NTFS engine ensure permissions stage. Stage=EnsureADGroups Path='{newFolderPath}'");
|
||||||
ensureADGroups(resultToken);
|
ensureADGroups(resultToken);
|
||||||
|
DefaultLogger.LogEntry(
|
||||||
|
LogLevels.Debug,
|
||||||
|
$"NTFS engine ensure permissions stage finished. Stage=EnsureADGroups Path='{newFolderPath}', CreatedGroups={resultToken.createdGroups.Count}, ReusedGroups={resultToken.reusedGroups.Count}, Warnings={resultToken.warnings.Count}, Elapsed='{stopwatch.Elapsed}'");
|
||||||
|
|
||||||
|
DefaultLogger.LogEntry(
|
||||||
|
LogLevels.Debug,
|
||||||
|
$"NTFS engine ensure permissions stage. Stage=EnsureFolderPermissions Path='{newFolderPath}'");
|
||||||
resultToken = ensureFolderPermissions(resultToken);
|
resultToken = ensureFolderPermissions(resultToken);
|
||||||
|
DefaultLogger.LogEntry(
|
||||||
|
LogLevels.Debug,
|
||||||
|
$"NTFS engine ensure permissions stage finished. Stage=EnsureFolderPermissions Path='{newFolderPath}', ResultErrorId={resultToken.resultErrorId}, AddedAcls={resultToken.addedAclEntries.Count}, SkippedAcls={resultToken.skippedAclEntries.Count}, Elapsed='{stopwatch.Elapsed}'");
|
||||||
|
|
||||||
if (resultToken.resultErrorId != 0)
|
if (resultToken.resultErrorId != 0)
|
||||||
return resultToken;
|
return resultToken;
|
||||||
|
|
||||||
if (ensureTraverseGroups)
|
if (ensureTraverseGroups)
|
||||||
{
|
{
|
||||||
|
DefaultLogger.LogEntry(
|
||||||
|
LogLevels.Debug,
|
||||||
|
$"NTFS engine ensure permissions stage. Stage=SetTraversePermissions Path='{newFolderPath}'");
|
||||||
var traverseResult = SetTraversePermissions();
|
var traverseResult = SetTraversePermissions();
|
||||||
if (traverseResult != null)
|
if (traverseResult != null)
|
||||||
{
|
{
|
||||||
@@ -405,11 +452,17 @@ namespace C4IT_IAM_SET
|
|||||||
return resultToken;
|
return resultToken;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
DefaultLogger.LogEntry(
|
||||||
|
LogLevels.Debug,
|
||||||
|
$"NTFS engine ensure permissions stage finished. Stage=SetTraversePermissions Path='{newFolderPath}', TraverseGroups={resultToken.ensuredTraverseGroups.Count}, AddedAcls={resultToken.addedAclEntries.Count}, Elapsed='{stopwatch.Elapsed}'");
|
||||||
}
|
}
|
||||||
|
|
||||||
resultToken.resultMessage = WhatIf
|
resultToken.resultMessage = WhatIf
|
||||||
? "Gruppen- und ACL-Vorschau erfolgreich erstellt"
|
? "Gruppen- und ACL-Vorschau erfolgreich erstellt"
|
||||||
: "Gruppen und ACLs erfolgreich sichergestellt";
|
: "Gruppen und ACLs erfolgreich sichergestellt";
|
||||||
|
DefaultLogger.LogEntry(
|
||||||
|
LogLevels.Debug,
|
||||||
|
$"NTFS engine ensure permissions finished. Stage=Finished Path='{newFolderPath}', ResultErrorId={resultToken.resultErrorId}, ResultMessage='{resultToken.resultMessage}', Elapsed='{stopwatch.Elapsed}'");
|
||||||
return resultToken;
|
return resultToken;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ using C4IT_IAM_Engine;
|
|||||||
using LiamAD;
|
using LiamAD;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
@@ -77,6 +78,9 @@ namespace LiamWorkflowActivities
|
|||||||
|
|
||||||
public static class LiamWorkflowRuntime
|
public static class LiamWorkflowRuntime
|
||||||
{
|
{
|
||||||
|
private const string AutomaticNtfsEnsureTimeoutSecondsKey = "NtfsAutomaticEnsureTimeoutSeconds";
|
||||||
|
private const int DefaultAutomaticNtfsEnsureTimeoutSeconds = 300;
|
||||||
|
|
||||||
public static async Task<GetDataAreasOperationResult> GetDataAreasFromProviderAsync(cLiamProviderBase provider, string configurationId = null, bool? simulateConfiguredNtfsPermissionEnsure = null)
|
public static async Task<GetDataAreasOperationResult> GetDataAreasFromProviderAsync(cLiamProviderBase provider, string configurationId = null, bool? simulateConfiguredNtfsPermissionEnsure = null)
|
||||||
{
|
{
|
||||||
var result = new GetDataAreasOperationResult();
|
var result = new GetDataAreasOperationResult();
|
||||||
@@ -422,11 +426,19 @@ namespace LiamWorkflowActivities
|
|||||||
var allowFolderEnsure = IsAdditionalConfigurationEnabled(provider, "EnsureNtfsPermissionGroups");
|
var allowFolderEnsure = IsAdditionalConfigurationEnabled(provider, "EnsureNtfsPermissionGroups");
|
||||||
var allowSharePathEnsure = IsAdditionalConfigurationEnabled(provider, "EnsureNtfsPermissionGroupsForShares");
|
var allowSharePathEnsure = IsAdditionalConfigurationEnabled(provider, "EnsureNtfsPermissionGroupsForShares");
|
||||||
var allowTraverseEnsure = IsAdditionalConfigurationEnabled(provider, "EnsureNtfsTraverseGroups");
|
var allowTraverseEnsure = IsAdditionalConfigurationEnabled(provider, "EnsureNtfsTraverseGroups");
|
||||||
|
var ensureTimeoutSeconds = GetAdditionalConfigurationInt32(
|
||||||
|
provider,
|
||||||
|
AutomaticNtfsEnsureTimeoutSecondsKey,
|
||||||
|
DefaultAutomaticNtfsEnsureTimeoutSeconds,
|
||||||
|
0);
|
||||||
|
var ensureTimeout = ensureTimeoutSeconds > 0
|
||||||
|
? TimeSpan.FromSeconds(ensureTimeoutSeconds)
|
||||||
|
: TimeSpan.Zero;
|
||||||
if (!allowFolderEnsure && !allowSharePathEnsure && !allowTraverseEnsure)
|
if (!allowFolderEnsure && !allowSharePathEnsure && !allowTraverseEnsure)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
LogEntry(
|
LogEntry(
|
||||||
$"Automatic NTFS ensure configured. PermissionGroups={allowFolderEnsure}, PermissionGroupsForShares={allowSharePathEnsure}, TraverseGroups={allowTraverseEnsure}, DataAreas={dataAreas.Count}, WhatIf={simulateOnly}",
|
$"Automatic NTFS ensure configured. PermissionGroups={allowFolderEnsure}, PermissionGroupsForShares={allowSharePathEnsure}, TraverseGroups={allowTraverseEnsure}, DataAreas={dataAreas.Count}, WhatIf={simulateOnly}, TimeoutSeconds={ensureTimeoutSeconds}",
|
||||||
LogLevels.Debug);
|
LogLevels.Debug);
|
||||||
|
|
||||||
if (allowFolderEnsure || allowSharePathEnsure)
|
if (allowFolderEnsure || allowSharePathEnsure)
|
||||||
@@ -449,7 +461,10 @@ namespace LiamWorkflowActivities
|
|||||||
ResultToken ensureResult;
|
ResultToken ensureResult;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ensureResult = await ntfsProvider.EnsureMissingPermissionGroupsAsync(
|
ensureResult = await RunAutomaticNtfsEnsureOperationAsync(
|
||||||
|
folderPath,
|
||||||
|
"permission group ensure",
|
||||||
|
() => ntfsProvider.EnsureMissingPermissionGroupsAsync(
|
||||||
folderPath,
|
folderPath,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
@@ -457,7 +472,8 @@ namespace LiamWorkflowActivities
|
|||||||
null,
|
null,
|
||||||
allowSharePathEnsure,
|
allowSharePathEnsure,
|
||||||
ensureTraverseInPermissionPhase,
|
ensureTraverseInPermissionPhase,
|
||||||
simulateOnly);
|
simulateOnly),
|
||||||
|
ensureTimeout);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -477,6 +493,12 @@ namespace LiamWorkflowActivities
|
|||||||
|
|
||||||
if (ensureResult.resultErrorId != 0)
|
if (ensureResult.resultErrorId != 0)
|
||||||
{
|
{
|
||||||
|
if (IsAutomaticNtfsEnsureTimeout(ensureResult))
|
||||||
|
{
|
||||||
|
SetAutomaticEnsureTimeoutError(result, folderPath, ensureResult, "permission group ensure");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
LogEntry(
|
LogEntry(
|
||||||
$"Automatic NTFS permission group ensure skipped for '{folderPath}' after resultErrorId={ensureResult.resultErrorId}. ResultMessage='{ensureResult.resultMessage ?? string.Empty}'",
|
$"Automatic NTFS permission group ensure skipped for '{folderPath}' after resultErrorId={ensureResult.resultErrorId}. ResultMessage='{ensureResult.resultMessage ?? string.Empty}'",
|
||||||
LogLevels.Warning);
|
LogLevels.Warning);
|
||||||
@@ -514,10 +536,14 @@ namespace LiamWorkflowActivities
|
|||||||
ResultToken ensureResult;
|
ResultToken ensureResult;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ensureResult = await ntfsProvider.EnsureTraverseGroupsAsync(
|
ensureResult = await RunAutomaticNtfsEnsureOperationAsync(
|
||||||
|
folderPath,
|
||||||
|
"traverse group ensure",
|
||||||
|
() => ntfsProvider.EnsureTraverseGroupsAsync(
|
||||||
folderPath,
|
folderPath,
|
||||||
null,
|
null,
|
||||||
simulateOnly);
|
simulateOnly),
|
||||||
|
ensureTimeout);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -537,6 +563,12 @@ namespace LiamWorkflowActivities
|
|||||||
|
|
||||||
if (ensureResult.resultErrorId != 0)
|
if (ensureResult.resultErrorId != 0)
|
||||||
{
|
{
|
||||||
|
if (IsAutomaticNtfsEnsureTimeout(ensureResult))
|
||||||
|
{
|
||||||
|
SetAutomaticEnsureTimeoutError(result, folderPath, ensureResult, "traverse group ensure");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
LogEntry(
|
LogEntry(
|
||||||
$"Automatic NTFS traverse group ensure skipped for '{folderPath}' after resultErrorId={ensureResult.resultErrorId}. ResultMessage='{ensureResult.resultMessage ?? string.Empty}'",
|
$"Automatic NTFS traverse group ensure skipped for '{folderPath}' after resultErrorId={ensureResult.resultErrorId}. ResultMessage='{ensureResult.resultMessage ?? string.Empty}'",
|
||||||
LogLevels.Warning);
|
LogLevels.Warning);
|
||||||
@@ -557,6 +589,55 @@ namespace LiamWorkflowActivities
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static async Task<ResultToken> RunAutomaticNtfsEnsureOperationAsync(
|
||||||
|
string folderPath,
|
||||||
|
string operationLabel,
|
||||||
|
Func<Task<ResultToken>> operation,
|
||||||
|
TimeSpan timeout)
|
||||||
|
{
|
||||||
|
var operationTask = Task.Run(operation);
|
||||||
|
#pragma warning disable 4014
|
||||||
|
// Fire-and-forget observer for exceptions that happen after a timeout.
|
||||||
|
operationTask.ContinueWith(
|
||||||
|
task => LogException(task.Exception),
|
||||||
|
TaskContinuationOptions.OnlyOnFaulted);
|
||||||
|
#pragma warning restore 4014
|
||||||
|
|
||||||
|
if (timeout <= TimeSpan.Zero)
|
||||||
|
return await operationTask;
|
||||||
|
|
||||||
|
var completedTask = await Task.WhenAny(operationTask, Task.Delay(timeout));
|
||||||
|
if (completedTask == operationTask)
|
||||||
|
return await operationTask;
|
||||||
|
|
||||||
|
var message =
|
||||||
|
$"Automatic NTFS {operationLabel} timed out for '{folderPath}' after {timeout.TotalSeconds:F0}s. " +
|
||||||
|
"The workflow will stop automatic NTFS ensure processing for this run. " +
|
||||||
|
"The underlying NTFS/AD operation may still finish in the worker process.";
|
||||||
|
LogEntry(message, LogLevels.Error);
|
||||||
|
return new ResultToken("AutomaticNtfsEnsureTimeout")
|
||||||
|
{
|
||||||
|
resultErrorId = 30010,
|
||||||
|
resultMessage = message
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool IsAutomaticNtfsEnsureTimeout(ResultToken ensureResult)
|
||||||
|
{
|
||||||
|
return ensureResult?.resultErrorId == 30010;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void SetAutomaticEnsureTimeoutError(
|
||||||
|
GetDataAreasOperationResult result,
|
||||||
|
string folderPath,
|
||||||
|
ResultToken ensureResult,
|
||||||
|
string operationLabel)
|
||||||
|
{
|
||||||
|
result.ErrorCode = "WF_GET_DATAAREAS_ENSURE_NTFS_GROUPS_TIMEOUT";
|
||||||
|
result.ErrorMessage = ensureResult?.resultMessage
|
||||||
|
?? $"Automatic NTFS {operationLabel} timed out for '{folderPath}'.";
|
||||||
|
}
|
||||||
|
|
||||||
private static NtfsAutomaticEnsurePreviewEntry MapAutomaticEnsurePreview(string folderPath, ResultToken ensureResult)
|
private static NtfsAutomaticEnsurePreviewEntry MapAutomaticEnsurePreview(string folderPath, ResultToken ensureResult)
|
||||||
{
|
{
|
||||||
return new NtfsAutomaticEnsurePreviewEntry
|
return new NtfsAutomaticEnsurePreviewEntry
|
||||||
@@ -662,6 +743,33 @@ namespace LiamWorkflowActivities
|
|||||||
|| rawValue.Equals("yes", StringComparison.OrdinalIgnoreCase);
|
|| rawValue.Equals("yes", StringComparison.OrdinalIgnoreCase);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static int GetAdditionalConfigurationInt32(cLiamProviderBase provider, string key, int defaultValue, int minValue)
|
||||||
|
{
|
||||||
|
if (provider?.AdditionalConfiguration == null || string.IsNullOrWhiteSpace(key))
|
||||||
|
return defaultValue;
|
||||||
|
|
||||||
|
if (!provider.AdditionalConfiguration.TryGetValue(key, out var rawValue) || string.IsNullOrWhiteSpace(rawValue))
|
||||||
|
return defaultValue;
|
||||||
|
|
||||||
|
if (!int.TryParse(rawValue.Trim(), NumberStyles.Integer, CultureInfo.InvariantCulture, out var parsedValue))
|
||||||
|
{
|
||||||
|
LogEntry(
|
||||||
|
$"AdditionalConfiguration '{key}' has invalid integer value '{rawValue}'. Defaulting to {defaultValue}.",
|
||||||
|
LogLevels.Warning);
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parsedValue < minValue)
|
||||||
|
{
|
||||||
|
LogEntry(
|
||||||
|
$"AdditionalConfiguration '{key}' value {parsedValue} is below minimum {minValue}. Defaulting to {defaultValue}.",
|
||||||
|
LogLevels.Warning);
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return parsedValue;
|
||||||
|
}
|
||||||
|
|
||||||
private static bool IsWorkflowWhatIfEnabled(cLiamProviderBase provider)
|
private static bool IsWorkflowWhatIfEnabled(cLiamProviderBase provider)
|
||||||
{
|
{
|
||||||
return IsAdditionalConfigurationEnabled(provider, "WhatIf");
|
return IsAdditionalConfigurationEnabled(provider, "WhatIf");
|
||||||
|
|||||||
Reference in New Issue
Block a user