init
This commit is contained in:
@@ -0,0 +1,116 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using DTS.Common.Interface.DASFactory;
|
||||
using DTS.Common.Interface.StatusAndProgressBar;
|
||||
|
||||
namespace DTS.DASLib.Service.StateMachine
|
||||
{
|
||||
public class DownloadParameters : IStatusParameters
|
||||
{
|
||||
#region general parameters
|
||||
/// <summary>
|
||||
/// controls whether we should remain in state or not
|
||||
/// </summary>
|
||||
public bool ProceedWhenDone { get; set; } = false;
|
||||
/// <summary>
|
||||
/// whether all das are required to finish their download
|
||||
/// </summary>
|
||||
public bool RequireAllDASFinish { get; set; } = false;
|
||||
#endregion
|
||||
|
||||
#region config file parameters
|
||||
/// <summary>
|
||||
/// holds the Download Folder setting from our config file
|
||||
/// </summary>
|
||||
public string DefaultDownloadFolder { get; set; } = string.Empty;
|
||||
/// <summary>
|
||||
/// holds the upload binaries setting from our config file
|
||||
/// </summary>
|
||||
public bool DefaultUploadBinaries { get; set; } = false;
|
||||
/// <summary>
|
||||
/// holds the upload exports setting from our config file
|
||||
/// </summary>
|
||||
public bool DefaultUploadExports { get; set; } = false;
|
||||
/// <summary>
|
||||
/// holds the upload logs setting from our config file
|
||||
/// </summary>
|
||||
public bool DefaultUploadLogs { get; set; } = false;
|
||||
/// <summary>
|
||||
/// holds the upload reports setting from our config file
|
||||
/// </summary>
|
||||
public bool DefaultUploadReports { get; set; } = false;
|
||||
/// <summary>
|
||||
/// holds the upload test setups setting from our config file
|
||||
/// </summary>
|
||||
public bool DefaultUploadSetups { get; set; } = false;
|
||||
#endregion
|
||||
|
||||
#region download function parameters
|
||||
/// <summary>
|
||||
/// defines an array of DAS which should be downloaded from
|
||||
/// </summary>
|
||||
public IDASCommunication[] DASList { get; set; } = new IDASCommunication[0];
|
||||
|
||||
/// <summary>
|
||||
/// holds the test id of our current test
|
||||
/// </summary>
|
||||
public string CurrentTestTestId { get; set; } = string.Empty;
|
||||
/// <summary>
|
||||
/// holds the test id node of our current test
|
||||
/// </summary>
|
||||
public string CurrentTestTestIdNode { get; set; } = string.Empty;
|
||||
/// <summary>
|
||||
/// holds the test directory location of our current test
|
||||
/// </summary>
|
||||
public string CurrentTestTestDirectory { get; set; } = string.Empty;
|
||||
/// <summary>
|
||||
/// holds the original test directory location of our current test
|
||||
/// </summary>
|
||||
public string CurrentTestOriginalTestDirectory { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// holds whether we're in ROI mode or not
|
||||
/// </summary>
|
||||
public bool ROI { get; set; } = false;
|
||||
/// <summary>
|
||||
/// holds whether we're in Recovery mode or not
|
||||
/// </summary>
|
||||
public bool Recovery { get; set; } = false;
|
||||
/// <summary>
|
||||
/// Used to prevent unnecessarily re-copying the folders in the Test Id folder
|
||||
/// (DASConfigs, SETUP, etc.) when running from the Download tile.
|
||||
/// </summary>
|
||||
public bool FoldersCopied { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
public ErrorCallback ErrorCallback { get; set; }
|
||||
/// <summary>
|
||||
/// resets all parameters back to defaults
|
||||
/// </summary>
|
||||
public void Reset()
|
||||
{
|
||||
DASList = new IDASCommunication[0];
|
||||
CurrentTestTestId = string.Empty;
|
||||
CurrentTestTestIdNode = string.Empty;
|
||||
DefaultDownloadFolder = string.Empty;
|
||||
DefaultUploadBinaries = false;
|
||||
DefaultUploadExports = false;
|
||||
DefaultUploadLogs = false;
|
||||
DefaultUploadReports = false;
|
||||
DefaultUploadSetups = false;
|
||||
ErrorCallback = null;
|
||||
Recovery = false;
|
||||
ROI = false;
|
||||
}
|
||||
public override string ToString()
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,410 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using DTS.Common.Interface.DASFactory;
|
||||
using DTS.Common.Interface.DASFactory.Download;
|
||||
using DTS.Common.Interface.StatusAndProgressBar;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
|
||||
namespace DTS.DASLib.Service.StateMachine
|
||||
{
|
||||
public class DownloadStatusInformation : IStatusInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// all possible status that can be relayed to consumers
|
||||
/// </summary>
|
||||
public enum StatusValues
|
||||
{
|
||||
Preparing,
|
||||
Downloading,
|
||||
CaptureAttributes,
|
||||
Failed,
|
||||
ROIFailed,
|
||||
Completed,
|
||||
Cancelling,
|
||||
Cancelled,
|
||||
CancelledPartial,
|
||||
DownloadDirectory,
|
||||
MissingHardware,
|
||||
NoDataToDownload,
|
||||
NotAllChannelsDownloaded,
|
||||
ExistingFiles,
|
||||
CleaningUp,
|
||||
QueryEventData
|
||||
}
|
||||
/// <summary>
|
||||
/// signals cancel was requested
|
||||
/// </summary>
|
||||
public ManualResetEvent CancelEvent = new ManualResetEvent(false);
|
||||
/// <summary>
|
||||
/// signals when ping and connect is finished
|
||||
/// </summary>
|
||||
public ManualResetEvent DoneEvent = new ManualResetEvent(false);
|
||||
/// <summary>
|
||||
/// action to take on completion of ping and connect
|
||||
/// </summary>
|
||||
public ActionCompleteDelegate CompleteAction { get; set; }
|
||||
/// <summary>
|
||||
/// action to take on progress notification
|
||||
/// </summary>
|
||||
public SetProgressValueDelegate ProgressAction { get; set; }
|
||||
/// <summary>
|
||||
/// action to take on a status notification
|
||||
/// </summary>
|
||||
public StatusIntDelegate StatusAction { get; set; }
|
||||
/// <summary>
|
||||
/// action to take on extended status notification
|
||||
/// </summary>
|
||||
public StatusExIntDelegate StatusExAction { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// if we were told of DAS to download from,
|
||||
/// this will be true if all the das were downloaded
|
||||
/// </summary>
|
||||
public bool AllDASFinished { get; set; } = false;
|
||||
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
AllDASFinished = false;
|
||||
CompleteAction = null;
|
||||
StatusAction = null;
|
||||
StatusExAction = null;
|
||||
ProgressAction = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// starts Downloading, returns immediately
|
||||
/// </summary>
|
||||
public void Download()
|
||||
{
|
||||
_DownloadTask = Task.Run(() =>
|
||||
{
|
||||
AllDASFinished = false;
|
||||
var param = States.Instance.DownloadStart.Status.DownloadParams;
|
||||
var global = States.Instance.DownloadStart.Status.GlobalStatusParameters;
|
||||
var dasFactory = States.Instance.DownloadStart.DASFactory;
|
||||
var errorCallback = param.ErrorCallback;
|
||||
|
||||
//get a list of all the das to download from
|
||||
var dasList = param.DASList.ToList();
|
||||
|
||||
|
||||
StatusAction?.Invoke((int)StatusValues.Preparing);
|
||||
|
||||
//check if we are supposed to download from a unit, but it's not available
|
||||
var activeDASList = dasFactory.GetDASList();
|
||||
if (dasList.Exists(das => !activeDASList.Contains(das)))
|
||||
{
|
||||
var missingList = dasList.Where(das => !activeDASList.Contains(das)).ToList();
|
||||
var dr = errorCallback?.Invoke(StatusValues.MissingHardware.ToString(), string.Join(Environment.NewLine, missingList.Select(das => das.SerialNumber).ToList()));
|
||||
if (DialogResult.OK != dr)
|
||||
{
|
||||
StatusAction?.Invoke((int)StatusValues.Failed);
|
||||
}
|
||||
}
|
||||
|
||||
//check if we have any das left to download from
|
||||
if (!dasList.Any())
|
||||
{
|
||||
StatusAction?.Invoke((int)StatusValues.Failed);
|
||||
}
|
||||
|
||||
//check that all units have config data
|
||||
if (dasList.Exists(das => das.ConfigData == null))
|
||||
{
|
||||
//throw error. by state machine definition we should have gone through Config first
|
||||
StatusExAction?.Invoke((int)StatusValues.NoDataToDownload, dasList.Where(das => das.ConfigData == null).ToArray());
|
||||
}
|
||||
|
||||
//we have das, they have config data. get the event
|
||||
var oneEvent = GetOneEvent(dasList);
|
||||
if (null == oneEvent)
|
||||
{
|
||||
StatusAction?.Invoke((int)StatusValues.Failed);
|
||||
}
|
||||
|
||||
//create folder environment
|
||||
var eventId = oneEvent.EventId;
|
||||
|
||||
|
||||
var currentTestTestId = param.CurrentTestTestId;
|
||||
var currentTestTestIdNode = param.CurrentTestTestIdNode;
|
||||
var currentTestTestDirectory = param.CurrentTestTestDirectory;
|
||||
var currentTestOriginalTestDirectory = param.CurrentTestOriginalTestDirectory;
|
||||
var defaultDownloadFolder = param.DefaultDownloadFolder;
|
||||
var DownloadFolder = Path.Combine(Environment.CurrentDirectory, defaultDownloadFolder);
|
||||
var ROI = param.ROI;
|
||||
var recovery = param.Recovery;
|
||||
var foldersCopied = param.FoldersCopied;
|
||||
|
||||
var directory = Path.Combine(DownloadFolder, eventId, currentTestTestId, "Binary");
|
||||
if (!Directory.Exists(directory))
|
||||
{
|
||||
try
|
||||
{
|
||||
Directory.CreateDirectory(directory);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
StatusAction?.Invoke((int)StatusValues.Failed);
|
||||
}
|
||||
}
|
||||
|
||||
StatusAction?.Invoke((int)StatusValues.DownloadDirectory);
|
||||
var DownloadDirectory = Path.Combine(directory, ROI ? "ROI" : "ALL");
|
||||
var TestItem = $"{defaultDownloadFolder}\\{eventId}\\{currentTestTestId}\\Binary\\{(ROI ? "ROI" : "ALL")}"; //optimize this
|
||||
|
||||
if (recovery && Directory.Exists(directory))
|
||||
{
|
||||
if (currentTestTestId != currentTestTestIdNode)
|
||||
{
|
||||
//We want to keep ROI and ALL "recovery" downloads in the same path, so use the same "Test Id" node in the path
|
||||
//Since the .../Binary folder exists, we know that this test has downloaded before, so create a recovery folder
|
||||
DownloadDirectory = Path.Combine(DownloadFolder, eventId, currentTestTestIdNode, "Binary", ROI ? "ROI" : "ALL");
|
||||
}
|
||||
|
||||
if ((currentTestTestId != currentTestTestIdNode || currentTestTestDirectory != currentTestOriginalTestDirectory) &&
|
||||
!foldersCopied)
|
||||
{
|
||||
//Either this is a "recovery" folder or the Test Id field was changed in Basic info.
|
||||
//Either way, the following files need to be copied from the original folder
|
||||
var copied = false;
|
||||
var originalTestIdNode = Path.GetFileName(currentTestOriginalTestDirectory);
|
||||
|
||||
var sourceDir = Path.Combine(DownloadFolder, eventId, originalTestIdNode, Common.Constants.DAS_CONFIGS);
|
||||
var destDir = Path.Combine(DownloadFolder, eventId, currentTestTestIdNode, Common.Constants.DAS_CONFIGS);
|
||||
DirectoryCopy(sourceDir, destDir, true, param, ref copied, false);
|
||||
|
||||
sourceDir = Path.Combine(DownloadFolder, eventId, originalTestIdNode, "Logs");
|
||||
destDir = Path.Combine(DownloadFolder, eventId, currentTestTestIdNode, "Logs");
|
||||
DirectoryCopy(sourceDir, destDir, true, param, ref copied, false);
|
||||
|
||||
sourceDir = Path.Combine(DownloadFolder, eventId, originalTestIdNode, Common.Constants.REPORT_DIR_NAME);
|
||||
destDir = Path.Combine(DownloadFolder, eventId, currentTestTestIdNode, Common.Constants.REPORT_DIR_NAME);
|
||||
DirectoryCopy(sourceDir, destDir, true, param, ref copied, false);
|
||||
|
||||
sourceDir = Path.Combine(DownloadFolder, eventId, originalTestIdNode, "SETUP");
|
||||
destDir = Path.Combine(DownloadFolder, eventId, currentTestTestIdNode, "SETUP");
|
||||
DirectoryCopy(sourceDir, destDir, true, param, ref copied, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var mre = new ManualResetEvent(false);
|
||||
mre.WaitOne();
|
||||
|
||||
if (!CancelEvent.WaitOne(1, false))
|
||||
{
|
||||
//check that all the units that should have been configured were
|
||||
var allDownloaded = Array.TrueForAll(param.DASList, d => dasList.Contains(d));
|
||||
AllDASFinished = allDownloaded;
|
||||
|
||||
CompleteAction?.Invoke();
|
||||
}
|
||||
|
||||
StatusAction?.Invoke((int)StatusValues.Completed);
|
||||
DoneEvent.Set();
|
||||
});
|
||||
}
|
||||
|
||||
private Task _DownloadTask = null;
|
||||
public async Task Cancel()
|
||||
{
|
||||
CancelEvent.Set();
|
||||
StatusAction?.Invoke((int)StatusValues.Cancelling);
|
||||
//simulate time spent waiting for cancel to be acknowledged
|
||||
Thread.Sleep(100);
|
||||
DoneEvent.WaitOne();
|
||||
StatusAction?.Invoke((int)StatusValues.Cancelled);
|
||||
}
|
||||
|
||||
#region helpers
|
||||
private static string GetHash(DownloadReport.EventInfo myEvent)
|
||||
{
|
||||
return $"{myEvent.TestID}_{myEvent.EventNumber:00}".ToUpper();
|
||||
}
|
||||
private IEventInfoAggregate GetOneEvent(List<IDASCommunication> dasList)
|
||||
{
|
||||
var eventInfo = new DownloadReport.EventInfo();
|
||||
var eventIds = new List<string>();
|
||||
var events = new Dictionary<string, IEventInfoAggregate>();
|
||||
foreach (var das in dasList)
|
||||
{
|
||||
if (null == das.EventInfo || !das.EventInfo.Events.Any()) { continue; }
|
||||
eventInfo = (DownloadReport.EventInfo)das.EventInfo.Events[0];
|
||||
var key = GetHash(eventInfo);
|
||||
if (!eventIds.Contains(key))
|
||||
{
|
||||
eventIds.Add(key);
|
||||
//TODO: Add Events, etc to
|
||||
//events.Add(key, new IEventInfoAggregate(eventInfo));
|
||||
}
|
||||
else
|
||||
{
|
||||
events[key].Add(eventInfo);
|
||||
}
|
||||
}
|
||||
IEventInfoAggregate oneEvent = null;
|
||||
if (events.Count > 0)
|
||||
{
|
||||
oneEvent = events[GetHash(eventInfo)];
|
||||
}
|
||||
return oneEvent;
|
||||
}
|
||||
/// <summary>
|
||||
/// we don't use move as we don't want to necessarily disturb directories already in the target location, and any files that are already there
|
||||
/// [but we will overwrite if a source file exists in the destination]
|
||||
/// </summary>
|
||||
/// <param name="sourceDirName"></param>
|
||||
/// <param name="destDirName"></param>
|
||||
/// <param name="copySubDirs"></param>
|
||||
/// <param name="param"></param>
|
||||
/// /// <param name="copied"></param>
|
||||
/// /// <param name="uploadingData"></param>
|
||||
public bool DirectoryCopy(string sourceDirName, string destDirName, bool copySubDirs, DownloadParameters param, ref bool copied, bool uploadingData)
|
||||
{
|
||||
try
|
||||
{
|
||||
var fileLocations = new List<string>();
|
||||
var destFileLocations = new List<string>();
|
||||
|
||||
var dirs = new List<string>();
|
||||
dirs.Add(sourceDirName);
|
||||
while (dirs.Count > 0)
|
||||
{
|
||||
var currentDir = dirs[0];
|
||||
dirs.RemoveAt(0);
|
||||
|
||||
var dir = new System.IO.DirectoryInfo(currentDir);
|
||||
if (!dir.Exists) { continue; }
|
||||
var files = dir.GetFiles();
|
||||
fileLocations.AddRange(files.Select(file => file.FullName));
|
||||
|
||||
var subDirs = dir.GetDirectories();
|
||||
dirs.AddRange(subDirs.Select(thisdir => thisdir.FullName));
|
||||
}
|
||||
|
||||
//uri requires folders end with \\
|
||||
if (!sourceDirName.EndsWith("\\")) { sourceDirName += "\\"; }
|
||||
var diSourceDir = new System.IO.DirectoryInfo(sourceDirName);
|
||||
if (!destDirName.EndsWith("\\")) { destDirName += "\\"; }
|
||||
|
||||
var curFileUndex = 1;
|
||||
var existingFiles = new List<string>();
|
||||
|
||||
for (var i = fileLocations.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var curFile = fileLocations[i];
|
||||
if (uploadingData)
|
||||
{
|
||||
var tokens = curFile.Split('\\');
|
||||
if (tokens.Contains("Binary"))
|
||||
{
|
||||
if (!param.DefaultUploadBinaries)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (tokens.Contains("DASConfigs"))
|
||||
{
|
||||
if (!param.DefaultUploadSetups)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (tokens.Contains("SETUP"))
|
||||
{
|
||||
if (!param.DefaultUploadSetups)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (tokens.Contains("Reports"))
|
||||
{
|
||||
if (!param.DefaultUploadReports)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (tokens.Contains("Logs"))
|
||||
{
|
||||
if (!param.DefaultUploadLogs)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (tokens.Contains("Exports"))
|
||||
{
|
||||
if (!param.DefaultUploadExports)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
var fiCurFile = new System.IO.FileInfo(curFile);
|
||||
|
||||
var path1 = new Uri("file:\\\\" + diSourceDir.FullName);
|
||||
var path2 = new Uri("file:\\\\" + fiCurFile.FullName);
|
||||
var diff = path1.MakeRelativeUri(path2);
|
||||
var relPath = diff.OriginalString;
|
||||
path2 = new Uri("file:\\\\" + destDirName);
|
||||
|
||||
path2 = new Uri(path2, relPath);
|
||||
|
||||
destFileLocations.Add(path2.LocalPath);
|
||||
if (System.IO.File.Exists(path2.LocalPath))
|
||||
{
|
||||
existingFiles.Add(path2.LocalPath);
|
||||
}
|
||||
}
|
||||
|
||||
if (existingFiles.Count > 0)
|
||||
{
|
||||
var temp = new Uri("file:\\\\" + destDirName);
|
||||
var dr = param.ErrorCallback?.Invoke(StatusValues.ExistingFiles.ToString(), string.Format(Resources.UploadData_Files_Exist, temp.LocalPath, "\n\n"));
|
||||
|
||||
if (DialogResult.OK != dr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
try
|
||||
{
|
||||
for (var i = 0; i < fileLocations.Count && i < destFileLocations.Count; i++)
|
||||
{
|
||||
var fiSource = new System.IO.FileInfo(fileLocations[i]);
|
||||
var fiDest = new System.IO.FileInfo(destFileLocations[destFileLocations.Count - 1 - i]);
|
||||
|
||||
if (!System.IO.Directory.Exists(fiDest.Directory.FullName)) { System.IO.Directory.CreateDirectory(fiDest.Directory.FullName); }
|
||||
|
||||
System.IO.File.Copy(fiSource.FullName, fiDest.FullName, true);
|
||||
var percent = 100D * curFileUndex++ / fileLocations.Count;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log("Upload Failure from ", sourceDirName, " to ", destDirName, ex);
|
||||
return false;
|
||||
}
|
||||
if (!uploadingData) return false;
|
||||
APILogger.Log("Upload Success from ", sourceDirName, " to ", destDirName);
|
||||
copied = true;
|
||||
Thread.Sleep(10);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log("Upload Failure from ", sourceDirName, " to ", destDirName, ex);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user