public bool TryCreateMonitor(AcquisitionMonitor monitor, out string message) { if (Directory.Exists(monitor.Location)) { if (monitor.ExpectedChannelCount == 2) { if (_managerSource.AddMonitor(monitor)) { message = ""; return true; } else { message = "A worker for that location is already active."; return false; } } else { message = "Only 2-channel acquisitions are supported at this time."; return false; } } else { message = "The directory does not exist."; return false; } }
public void PostMonitor_ShouldAddMonitor() { var context = new TestAcquisitionContext(); var controller = new MonitorController(context); var mon = new AcquisitionMonitor() { Id = 1, Location = @"C:\Test\Location1" }; controller.PostMonitor(mon); Assert.AreEqual(1, context.Monitors.Count); }
public void TestDeltaZBasic() { AcquisitionMonitor monitor = new AcquisitionMonitor(); bool dayWasCreated, groupWasCreated; TileDay day = monitor.CreateOrGetDay("2016-06-29", out dayWasCreated); TileGroup group = day.CreateOrGetTileGroup("2016-06-29" + Path.DirectorySeparatorChar + "00", out groupWasCreated); Tile tile1 = CreateTile(group, "00001", 1, 1.5, false); // Create tile should be initialized to NaN Assert.IsTrue(double.IsNaN(tile1.Contents.DeltaZ)); group.AddTile(tile1); // Tile without acquisition (no Z position) should have deltaZ NaN Assert.IsTrue(double.IsNaN(tile1.Contents.DeltaZ)); Tile tile2 = CreateTile(group, "00002", 2, 3.3); group.AddTile(tile2); // First entry in zIndex map - deltaZ should be zero Assert.AreEqual<double>(0, tile2.Contents.DeltaZ); Tile tile3 = CreateTile(group, "00003", 3, 4.3); group.AddTile(tile3); // Standard behavior - next lattice position Assert.AreEqual<double>(4.3 - 3.3, tile3.Contents.DeltaZ); // Add a tile from a lower lattice position - update as appropriate tile1.HaveAcquisition = true; Assert.AreEqual<double>(0, tile1.Contents.DeltaZ); Assert.AreEqual<double>(3.3 - 1.5, tile2.Contents.DeltaZ); Assert.AreEqual<double>(4.3 - 3.3, tile3.Contents.DeltaZ); // A new tile comes in layer 2 with a lower Z - deltaZ in layer 3 should update. Tile tile4 = CreateTile(group, "00004", 2, 3.2); group.AddTile(tile4); Assert.AreEqual<double>(0, tile1.Contents.DeltaZ); Assert.AreEqual<double>(3.3 - 1.5, tile2.Contents.DeltaZ); Assert.AreEqual<double>(3.2 - 1.5, tile4.Contents.DeltaZ); Assert.AreEqual<double>(4.3 - 3.2, tile3.Contents.DeltaZ); }
public void TestDuplicatesGeneral() { AcquisitionMonitor monitor = new AcquisitionMonitor() { Location = Path.Combine(TestFileData.LocalUnitTestDataLocation, "testsets", "duplicates"), ExpectedChannelCount = 2, MinTiffFileSize = 0.1 }; AcquisitionWorker worker = new AcquisitionWorker(monitor); worker.MaxHistoricalDaysToMonitorEmerging = 1; bool res = worker.Start().Result; while (worker.ExistingQueueSize > 0) Thread.Sleep(250); Thread.Sleep(1000); worker.Stop(); Assert.AreEqual(2, monitor.Days.Count, "Day count"); Assert.AreEqual(10, monitor.Tiles.Count, "Tile count"); Assert.AreEqual(1, monitor.IncompleteTiles.Count, "Incomplete count"); Assert.AreEqual(4, monitor.Lattice.Duplicates.Count, "Duplicate count"); Assert.AreEqual(100, monitor.Lattice.Duplicates[0].Position.X); Assert.AreEqual(50, monitor.Lattice.Duplicates[0].Position.Y); Assert.AreEqual(20, monitor.Lattice.Duplicates[0].Position.Z); Assert.AreEqual(3, monitor.Lattice.Duplicates[0].TileCount); Assert.AreEqual(100, monitor.Lattice.Duplicates[1].Position.X); Assert.AreEqual(55, monitor.Lattice.Duplicates[1].Position.Y); Assert.AreEqual(20, monitor.Lattice.Duplicates[1].Position.Z); Assert.AreEqual(2, monitor.Lattice.Duplicates[1].TileCount); Assert.AreEqual(20, monitor.Lattice.Duplicates[2].Position.X); Assert.AreEqual(60, monitor.Lattice.Duplicates[2].Position.Y); Assert.AreEqual(40, monitor.Lattice.Duplicates[2].Position.Z); Assert.AreEqual(2, monitor.Lattice.Duplicates[2].TileCount); Assert.AreEqual(70, monitor.Lattice.Duplicates[3].Position.X); Assert.AreEqual(80, monitor.Lattice.Duplicates[3].Position.Y); Assert.AreEqual(90, monitor.Lattice.Duplicates[3].Position.Z); Assert.AreEqual(2, monitor.Lattice.Duplicates[3].TileCount); }
public void TestRestoreCacheNoValidate() { MetadataCache cache = new MetadataCache(); AcquisitionMonitor monitor = new AcquisitionMonitor() { Location = Path.Combine(TestFileData.LocalUnitTestDataLocation, "metadata", "duplicates"), ExpectedChannelCount = 2, MinTiffFileSize = 0.1 }; UserOptions.Default.VerifyDeserializationPaths = false; DeserializationContext context = cache.Restore(monitor); Assert.AreEqual(9, context.CompleteCount, "Context Complete count"); Assert.AreEqual(1, context.Incomplete.Count, "Context Incomplete count"); Assert.AreEqual(19, context.PendingImages.Count, "Context PendingImages count"); Assert.IsTrue(context.ImplicitChannelImageFileSize > 0.0, "Context ImplicitChannelImageFileSize"); Assert.AreEqual(2, context.ImplicitChannelImageFrameCount, "Context ImplicitChannelImageFrameCount"); Assert.AreEqual(2, monitor.Days.Count, "Day count"); Assert.AreEqual(10, monitor.Tiles.Count, "Tile count"); Assert.AreEqual(1, monitor.IncompleteTiles.Count, "Incomplete count"); Assert.AreEqual(4, monitor.Lattice.Duplicates.Count, "Duplicate count"); Assert.AreEqual(100, monitor.Lattice.Duplicates[0].Position.X); Assert.AreEqual(50, monitor.Lattice.Duplicates[0].Position.Y); Assert.AreEqual(20, monitor.Lattice.Duplicates[0].Position.Z); Assert.AreEqual(3, monitor.Lattice.Duplicates[0].TileCount); Assert.AreEqual(100, monitor.Lattice.Duplicates[1].Position.X); Assert.AreEqual(55, monitor.Lattice.Duplicates[1].Position.Y); Assert.AreEqual(20, monitor.Lattice.Duplicates[1].Position.Z); Assert.AreEqual(2, monitor.Lattice.Duplicates[1].TileCount); Assert.AreEqual(20, monitor.Lattice.Duplicates[2].Position.X); Assert.AreEqual(60, monitor.Lattice.Duplicates[2].Position.Y); Assert.AreEqual(40, monitor.Lattice.Duplicates[2].Position.Z); Assert.AreEqual(2, monitor.Lattice.Duplicates[2].TileCount); Assert.AreEqual(70, monitor.Lattice.Duplicates[3].Position.X); Assert.AreEqual(80, monitor.Lattice.Duplicates[3].Position.Y); Assert.AreEqual(90, monitor.Lattice.Duplicates[3].Position.Z); Assert.AreEqual(2, monitor.Lattice.Duplicates[3].TileCount); }
public void TestRestoreCacheValidate() { MetadataCache cache = new MetadataCache(); AcquisitionMonitor monitor = new AcquisitionMonitor() { Location = Path.Combine(TestFileData.LocalUnitTestDataLocation, "metadata", "duplicates"), ExpectedChannelCount = 2, MinTiffFileSize = 0.1 }; UserOptions.Default.VerifyDeserializationPaths = true; DeserializationContext context = cache.Restore(monitor); Assert.AreEqual(0, context.CompleteCount, "Context Complete count"); Assert.AreEqual(0, context.Incomplete.Count, "Context Incomplete count"); Assert.AreEqual(0, context.PendingImages.Count, "Context PendingImages count"); Assert.AreEqual(0.0, context.ImplicitChannelImageFileSize, "Context ImplicitChannelImageFileSize"); Assert.AreEqual(Int32.MinValue, context.ImplicitChannelImageFrameCount, "Context ImplicitChannelImageFrameCount"); Assert.AreEqual(0, monitor.Days.Count, "Day count"); Assert.AreEqual(0, monitor.Tiles.Count, "Tile count"); Assert.AreEqual(0, monitor.IncompleteTiles.Count, "Incomplete count"); Assert.AreEqual(0, monitor.Lattice.Duplicates.Count, "Duplicate count"); }
public void Backup(AcquisitionMonitor monitor, bool isSessionBackup = false) { Contract.Requires(monitor != null); var metaDataFileName = Path.Combine(monitor.Location, FileName + ".json"); if (!File.Exists(metaDataFileName)) { return; } MonitorStatus currentStatus = monitor.Status; try { monitor.Status = MonitorStatus.BackupCache; if (!Directory.Exists(monitor.Location)) { throw new Exception(String.Format("{0} is no longer reachable.", monitor.Location)); } var metaDataBackupFileName = metaDataFileName + (isSessionBackup ? LastSessionExtension : BackupExtension); AcquireFilePermissions(new string[] { metaDataFileName, metaDataBackupFileName }); File.Copy(metaDataFileName, metaDataBackupFileName, true); Trace.TraceInformation("Existing metadata backup to to {0}", metaDataBackupFileName); } catch (Exception e) { Trace.TraceError("An unexpected error during metadata backup: {0}", e.Message); } monitor.Status = currentStatus; }
public void TestIncompleteGeneral() { AcquisitionMonitor monitor = new AcquisitionMonitor() { Location = Path.Combine(TestFileData.LocalUnitTestDataLocation, "testsets", "incomplete"), ExpectedChannelCount = 2, MinTiffFileSize = 0.1 }; AcquisitionWorker worker = new AcquisitionWorker(monitor); worker.MaxHistoricalDaysToMonitorEmerging = 1; bool res = worker.Start().Result; while (worker.ExistingQueueSize > 0) Thread.Sleep(250); worker.Stop(); Thread.Sleep(1000); // Assumes inclusion of an complete empty folder: Test.Unit\data\testsets\incomplete\2015-07-01\00\00011 // that does not get checked into GitHub as an empty folder. Create this folder in your local repository // to enable this test to pass. Assert.AreEqual(2, monitor.Days.Count); Assert.AreEqual(13, monitor.Tiles.Count); Assert.AreEqual(11, monitor.IncompleteTiles.Count); Assert.AreEqual(0, monitor.Lattice.Duplicates.Count); }
public DeserializationContext Restore(AcquisitionMonitor monitor) { Contract.Requires(monitor != null); var metaDataFileName = Path.Combine(monitor.Location, FileName + ".json"); if (!File.Exists(metaDataFileName)) { return null; } DeserializationContext result = null; MonitorStatus currentStatus = monitor.Status; monitor.Status = MonitorStatus.LoadingCache; try { if (!Directory.Exists(monitor.Location)) { throw new Exception(String.Format("{0} is no longer reachable.", monitor.Location)); } AcquireFilePermissions(new string[] { metaDataFileName }, FileIOPermissionAccess.Read); Trace.TraceInformation("Loading cached tile data from {0}.", metaDataFileName); SerializedMonitor data = JsonConvert.DeserializeObject<SerializedMonitor>(File.ReadAllText(metaDataFileName)); Trace.TraceInformation("\tLoaded {0} tiles over {1} days.", data.NumberOfTiles, data.NumberOfDays); if (data.Version < SerializationVersion.V01) { throw new Exception(String.Format("Ignoring metadata cache version {0}. Minimum version is {1}.", data.Version, SerializationVersion.V01)); } if (data.WhenCached == DateTime.MinValue) { data.WhenCached = File.GetCreationTimeUtc(metaDataFileName); } monitor.Status = MonitorStatus.ParsingCache; Trace.TraceInformation("Restoring loaded tile data."); result = monitor.Deserialize(data); Trace.TraceInformation("\tData restored."); } catch (Exception e) { Trace.TraceError("Unexpected error reading metadata file. {0}", e.Message); } monitor.Status = currentStatus; return result; }
public void Save(AcquisitionMonitor monitor) { Contract.Requires(monitor != null); MonitorStatus currentStatus = monitor.Status; monitor.Status = MonitorStatus.SaveCache; DateTime lastCached = monitor.WhenCached; try { if (!Directory.Exists(monitor.Location)) { throw new Exception(String.Format("{0} is no longer reachable.", monitor.Location)); } Backup(monitor); var metaDataFileName = Path.Combine(monitor.Location, FileName + ".json"); var metaDataFileNameTemp = metaDataFileName + ".temp"; AcquireFilePermissions(new string[] { metaDataFileName, metaDataFileNameTemp }); monitor.WhenCached = DateTime.Now; var txt = JsonConvert.SerializeObject(monitor.Serialize(), new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() }); File.WriteAllText(metaDataFileNameTemp, txt); File.Delete(metaDataFileName); File.Move(metaDataFileNameTemp, metaDataFileName); } catch (Exception e) { Trace.TraceError("An unexpected error while saving the metadata file: {0}", e.Message); monitor.WhenCached = lastCached; } monitor.Status = currentStatus; }
/// <summary> /// Encapsulates the task of observing a root directory for tile additions and changes. /// </summary> /// <param name="monitor"></param> public AcquisitionWorker(AcquisitionMonitor monitor) { Contract.Requires(monitor != null); _model = monitor; _hasStarted = false; _deserializeCompleteCount = 0; _cts = new CancellationTokenSource(); // Timers (not started) _topLevelMonitoringTimer = new System.Timers.Timer(UserOptions.Default.TopLevelDirectoryPollingIntervalMinutes * 60 * 1000); _topLevelMonitoringTimer.Elapsed += TopLevelMonitoringElapsed; _incompleteMonitoringTimer = new System.Timers.Timer(UserOptions.Default.IncompleteTilePollingIntervalMinutes * 60 * 1000); _incompleteMonitoringTimer.Elapsed += EvaluateIncompleteList; // Queues _incompleteMonitoringQueue = new TileQueue(); _existingTileQueue = new TileQueue(); // Discovery workers (not started) _discoveryWorkers = new ConcurrentDictionary<TileGroup, TileGroupEmergingWorker>(); _existingOnlyWorkers = new ConcurrentDictionary<TileGroup, TileGroupExistingWorker>(); // Evaluate workers (not started) _emergingProcessingWorker = new TileEvaluateWorker(null, _incompleteMonitoringQueue, true); _existingProcessingWorkers = new List<TileEvaluateWorker>(); for (int idx = 0; idx < _existingProcessorCount; idx++) { _existingProcessingWorkers.Add(new TileEvaluateWorker(_existingTileQueue, _incompleteMonitoringQueue, false)); } _incompleteProcessingWorker = new TileEvaluateWorker(null, _incompleteMonitoringQueue, false); _duplicateTileWorker = new DuplicateTileWorker(); // Metadata storage. if (UserOptions.Default.SerializeMetadata) { _metadataCache = new MetadataCache(); } else { Trace.TraceInformation("Metadata cache has been disabled. Changes will not be recorded."); } }
private async void AddCmd_Execute(object target, ExecutedRoutedEventArgs evt) { Properties.Settings.Default.LastDirectory = watchFolderTextBox.Text; Properties.Settings.Default.Save(); string location = watchFolderTextBox.Text; double size; if (!Double.TryParse(minSizeTextBox.Text, out size) || size < 0) { MessageBox.Show("The minimum TIFF file size must be a positive numeric value.", "Failed to Add Monitor", MessageBoxButton.OK, MessageBoxImage.Error); return; } var monitor = new AcquisitionMonitor() { Location = location, MinTiffFileSize = size, TargetCutThickness = 0 }; Properties.Settings.Default.LastMinTiffFileSize = size; Properties.Settings.Default.Save(); using (var client = new HttpClient()) { client.BaseAddress = new Uri(String.Format("http://localhost:{0}/", Properties.Settings.Default.Port.ToString())); client.DefaultRequestHeaders.Accept.Clear(); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); var response = await client.PostAsJsonAsync("api/monitors", monitor); if (!response.IsSuccessStatusCode) { string error; try { var r = await response.Content.ReadAsStringAsync(); var defintion = new { message = "" }; var msg = JsonConvert.DeserializeAnonymousType(r, defintion); error = msg.message; } catch (Exception ex) { error = "The directory can not be monitored due to an unknown error. " + ex.Message; } MessageBox.Show(error, "Failed to Add Monitor", MessageBoxButton.OK, MessageBoxImage.Error); } } }
public IHttpActionResult PostMonitor(AcquisitionMonitor watcher) { string errorMessage; if (_context.TryCreateMonitor(watcher, out errorMessage)) { return Ok(); } return BadRequest(errorMessage); }