Skip to content

Commit

Permalink
Move attachemntenricher to CommonEnricherConfig +semver: minor
Browse files Browse the repository at this point in the history
  • Loading branch information
MrHinsh committed Mar 5, 2024
1 parent 6fe4619 commit 99230e3
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,37 @@
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.TeamFoundation.Server;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using Microsoft.TeamFoundation.WorkItemTracking.Proxy;
using MigrationTools._EngineV1.Configuration.Processing;
using MigrationTools._EngineV1.Enrichers;
using MigrationTools.DataContracts;
using MigrationTools.Endpoints;
using MigrationTools.Enrichers;
using MigrationTools.Processors;
using Serilog;

namespace MigrationTools.Enrichers
namespace MigrationTools.ProcessorEnrichers
{
public class TfsAttachmentEnricher : IAttachmentMigrationEnricher
public class TfsAttachmentEnricher : WorkItemProcessorEnricher, IAttachmentMigrationEnricher
{
private WorkItemServer _server;
private string _exportBasePath;
private string _exportWiPath;
private int _maxAttachmentSize;
private TfsAttachmentEnricherOptions _options;
private WorkItemServer _workItemServer;

public TfsAttachmentEnricher(WorkItemServer workItemServer, string exportBasePath, int maxAttachmentSize = 480000000)
public TfsAttachmentEnricher(IServiceProvider services, ILogger<WorkItemProcessorEnricher> logger) : base(services, logger)
{
_server = workItemServer;
_exportBasePath = exportBasePath;
_maxAttachmentSize = maxAttachmentSize;
}

public void ProcessAttachemnts(WorkItemData source, WorkItemData target, bool save = true)
{
SetupWorkItemServer();
if (source is null)
{
throw new ArgumentNullException(nameof(source));
Expand All @@ -35,14 +42,13 @@ public void ProcessAttachemnts(WorkItemData source, WorkItemData target, bool sa
{
throw new ArgumentNullException(nameof(target));
}

Log.Information("AttachmentMigrationEnricher: Migrating {AttachmentCount} attachemnts from {SourceWorkItemID} to {TargetWorkItemID}", source.ToWorkItem().Attachments.Count, source.Id, target.Id);
Log.LogInformation("AttachmentMigrationEnricher: Migrating {AttachmentCount} attachemnts from {SourceWorkItemID} to {TargetWorkItemID}", source.ToWorkItem().Attachments.Count, source.Id, target.Id);
_exportWiPath = Path.Combine(_exportBasePath, source.ToWorkItem().Id.ToString());
if (System.IO.Directory.Exists(_exportWiPath))
if (Directory.Exists(_exportWiPath))
{
System.IO.Directory.Delete(_exportWiPath, true);
Directory.Delete(_exportWiPath, true);
}
System.IO.Directory.CreateDirectory(_exportWiPath);
Directory.CreateDirectory(_exportWiPath);


int count = 0;
Expand All @@ -51,81 +57,84 @@ public void ProcessAttachemnts(WorkItemData source, WorkItemData target, bool sa
count++;
if (count > 100)
{
break;
break;
}

try
{
string filepath = null;
System.IO.Directory.CreateDirectory(Path.Combine(_exportWiPath, wia.Id.ToString()));
Directory.CreateDirectory(Path.Combine(_exportWiPath, wia.Id.ToString()));
filepath = ExportAttachment(source.ToWorkItem(), wia, _exportWiPath);
Log.Debug("AttachmentMigrationEnricher: Exported {Filename} to disk", System.IO.Path.GetFileName(filepath));
Log.LogDebug("AttachmentMigrationEnricher: Exported {Filename} to disk", Path.GetFileName(filepath));
if (filepath != null)
{
ImportAttachment(target.ToWorkItem(), wia, filepath, save);
Log.Debug("AttachmentMigrationEnricher: Imported {Filename} from disk", System.IO.Path.GetFileName(filepath));
Log.LogDebug("AttachmentMigrationEnricher: Imported {Filename} from disk", Path.GetFileName(filepath));
}
}
catch (Exception ex)
{
Log.Error(ex, "AttachmentMigrationEnricher:Unable to process atachment from source wi {SourceWorkItemId} called {AttachmentName}", source.ToWorkItem().Id, wia.Name);
Log.LogError(ex, "AttachmentMigrationEnricher:Unable to process atachment from source wi {SourceWorkItemId} called {AttachmentName}", source.ToWorkItem().Id, wia.Name);
}
}
if (save)
{
target.SaveToAzureDevOps();
Log.Information("Work iTem now has {AttachmentCount} attachemnts", source.ToWorkItem().Attachments.Count);
Log.LogInformation("Work iTem now has {AttachmentCount} attachemnts", source.ToWorkItem().Attachments.Count);
CleanUpAfterSave();
}
}

public void CleanUpAfterSave()
{
if (_exportWiPath != null && System.IO.Directory.Exists(_exportWiPath))
SetupWorkItemServer();
if (_exportWiPath != null && Directory.Exists(_exportWiPath))
{
try
{
System.IO.Directory.Delete(_exportWiPath, true);
Directory.Delete(_exportWiPath, true);
_exportWiPath = null;
}
catch (Exception)
{
Log.Warning(" ERROR: Unable to delete folder {0}", _exportWiPath);
Log.LogWarning(" ERROR: Unable to delete folder {0}", _exportWiPath);
}
}
}

private string ExportAttachment(WorkItem wi, Attachment wia, string exportpath)
{
SetupWorkItemServer();
string fname = GetSafeFilename(wia.Name);
Log.Debug(fname);
Log.LogDebug(fname);

string fpath = Path.Combine(exportpath, wia.Id.ToString(), fname);

if (!File.Exists(fpath))
{
Log.Debug(string.Format("...downloading {0} to {1}", fname, exportpath));
Log.LogDebug(string.Format("...downloading {0} to {1}", fname, exportpath));
try
{
var fileLocation = _server.DownloadFile(wia.Id);
File.Copy(fileLocation, fpath, true);
}
catch (Exception ex)
{
Log.Error(ex, "Exception downloading attachements");
Log.LogError(ex, "Exception downloading attachements");
return null;
}
}
else
{
Log.Debug("...already downloaded");
Log.LogDebug("...already downloaded");
}
return fpath;
}

private void ImportAttachment(WorkItem targetWorkItem, Attachment wia, string filepath, bool save = true)
{
var filename = System.IO.Path.GetFileName(filepath);
SetupWorkItemServer();
var filename = Path.GetFileName(filepath);
FileInfo fi = new FileInfo(filepath);
if (_maxAttachmentSize > fi.Length)
{
Expand All @@ -152,18 +161,43 @@ private void ImportAttachment(WorkItem targetWorkItem, Attachment wia, string fi
}
else
{
Log.Debug(" [SKIP] WorkItem {0} already contains attachment {1}", targetWorkItem.Id, filepath);
Log.LogDebug(" [SKIP] WorkItem {0} already contains attachment {1}", targetWorkItem.Id, filepath);
}
}
else
{
Log.Warning(" [SKIP] Attachment {filename} on Work Item {targetWorkItemId} is bigger than the limit of {maxAttachmentSize} bites for Azure DevOps.", filename, targetWorkItem.Id, _maxAttachmentSize);
Log.LogWarning(" [SKIP] Attachment {filename} on Work Item {targetWorkItemId} is bigger than the limit of {maxAttachmentSize} bites for Azure DevOps.", filename, targetWorkItem.Id, _maxAttachmentSize);
}
}

public string GetSafeFilename(string filename)
{
return string.Join("_", filename.Split(Path.GetInvalidFileNameChars()));
}

private void SetupWorkItemServer()
{
if (_workItemServer != null)
{
IMigrationEngine engine = Services.GetRequiredService<IMigrationEngine>();
_workItemServer = engine.Source.GetService<WorkItemServer>();
}
}

protected override void RefreshForProcessorType(IProcessor processor)
{
throw new NotImplementedException();
}

protected override void EntryForProcessorType(IProcessor processor)
{
throw new NotImplementedException();
}

public override void Configure(IProcessorEnricherOptions options)
{
_options = (TfsAttachmentEnricherOptions)options;

}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using System;
using System.Collections.Generic;
using Microsoft.TeamFoundation.Build.Client;
using MigrationTools.ProcessorEnrichers;

namespace MigrationTools.Enrichers
{
public class TfsAttachmentEnricherOptions : ProcessorEnricherOptions, ITfsAttachmentEnricherOptions
{
public override Type ToConfigure => typeof(TfsAttachmentEnricher);

public string ExportBasePath { get; set; }
public string MaxAttachmentSize { get; set; }

public override void SetDefaults()
{
Enabled = true;
ExportBasePath = @"c:\temp\WorkItemAttachmentExport";
MaxAttachmentSize = "480000000";
}

static public TfsAttachmentEnricherOptions GetDefaults()
{
var result = new TfsAttachmentEnricherOptions();
result.SetDefaults();
return result;
}
}

public interface ITfsAttachmentEnricherOptions
{
public string ExportBasePath { get; set; }
public string MaxAttachmentSize { get; set; }

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public class WorkItemMigrationContext : MigrationProcessorBase
private List<string> _ignore;

private ILogger contextLog;
private IAttachmentMigrationEnricher attachmentEnricher;
private TfsAttachmentEnricher attachmentEnricher;
private IWorkItemProcessorEnricher embededImagesEnricher;
private IWorkItemProcessorEnricher _workItemEmbededLinkEnricher;
private StringManipulatorEnricher _stringManipulatorEnricher;
Expand Down Expand Up @@ -121,7 +121,7 @@ private void ImportCommonEnricherConfigs()
PullCommonEnrichersConfig<TfsRevisionManager, TfsRevisionManagerOptions>(_engineConfig.CommonEnrichersConfig, _revisionManager);
PullCommonEnrichersConfig<TfsWorkItemLinkEnricher, TfsWorkItemLinkEnricherOptions>(_engineConfig.CommonEnrichersConfig, _workItemLinkEnricher);
PullCommonEnrichersConfig<StringManipulatorEnricher, StringManipulatorEnricherOptions>(_engineConfig.CommonEnrichersConfig, _stringManipulatorEnricher);

PullCommonEnrichersConfig<TfsAttachmentEnricher, TfsAttachmentEnricherOptions>(_engineConfig.CommonEnrichersConfig, attachmentEnricher);
}

internal void TraceWriteLine(LogEventLevel level, string message, Dictionary<string, object> properties = null)
Expand All @@ -146,8 +146,7 @@ protected override void InternalExecute()
//////////////////////////////////////////////////
ValidatePatTokenRequirement();
//////////////////////////////////////////////////
var workItemServer = Engine.Source.GetService<WorkItemServer>();
attachmentEnricher = new TfsAttachmentEnricher(workItemServer, _config.AttachmentWorkingPath, _config.AttachmentMaxSize);

embededImagesEnricher = Services.GetRequiredService<TfsEmbededImagesEnricher>();
gitRepositoryEnricher = Services.GetRequiredService<TfsGitRepositoryEnricher>();

Expand Down

0 comments on commit 99230e3

Please sign in to comment.