/// <summary> /// Called when the service is started. /// </summary> protected override void OnServiceStart() { _innerEyeSegmentationClient?.Dispose(); _innerEyeSegmentationClient = null; if (_getInnerEyeSegmentationClient != null) { _innerEyeSegmentationClient = _getInnerEyeSegmentationClient.Invoke(); Task.WaitAll(PingAsync(stopServiceOnAuthFailures: false)); } _configurationServiceConfig = _getConfigurationServiceConfig(); // Initialize the log LogInformation(LogEntry.CreateInitialize()); // Start the services. _services.ForEach(x => x.Start()); }
/// <summary> /// Called when [update tick] is called. This will wait for all work to execute then will pause for desired interval delay. /// </summary> /// <param name="cancellationToken">The cancellation token.</param> /// <returns> /// The async task. /// </returns> protected override async Task OnUpdateTickAsync(CancellationToken cancellationToken) { // Check we can still ping with the license key // This call will stop this service if the license key is invalid. await PingAsync().ConfigureAwait(false); await Task.Delay(_configurationServiceConfig.ConfigurationRefreshDelay, cancellationToken).ConfigureAwait(false); var config = _getConfigurationServiceConfig(); if (config.ConfigCreationDateTime > _configurationServiceConfig.ConfigCreationDateTime && DateTime.UtcNow >= config.ApplyConfigDateTime) { LogInformation(LogEntry.Create(ServiceStatus.NewConfigurationAvailable)); _innerEyeSegmentationClient?.Dispose(); _innerEyeSegmentationClient = null; if (_getInnerEyeSegmentationClient != null) { _innerEyeSegmentationClient = _getInnerEyeSegmentationClient.Invoke(); } // Update the current configuration. _configurationServiceConfig = config; // Stop the services _services.ForEach(x => x.OnStop()); // Re-initialize the log LogInformation(LogEntry.CreateInitialize()); // Start the services again _services.ForEach(x => x.Start()); LogInformation(LogEntry.Create(ServiceStatus.NewConfigurationApplied)); } }
public void ReceiveServiceRestartTest() { var callingAet = "ProstateRTMl"; var client = GetMockInnerEyeSegmentationClient(); var mockConfigurationServiceConfigProvider = new MockConfigurationProvider <ConfigurationServiceConfig>(); var configurationServiceConfig1 = new ConfigurationServiceConfig( configurationRefreshDelaySeconds: 1); var configurationServiceConfig2 = new ConfigurationServiceConfig( configurationServiceConfig1.ConfigCreationDateTime.AddSeconds(5), configurationServiceConfig1.ApplyConfigDateTime.AddSeconds(10)); mockConfigurationServiceConfigProvider.ConfigurationQueue.Clear(); mockConfigurationServiceConfigProvider.ConfigurationQueue.Enqueue(configurationServiceConfig1); mockConfigurationServiceConfigProvider.ConfigurationQueue.Enqueue(configurationServiceConfig2); var mockReceiverConfigurationProvider2 = new MockConfigurationProvider <ReceiveServiceConfig>(); var testReceiveServiceConfig1 = GetTestGatewayReceiveServiceConfig(110); var testReceiveServiceConfig2 = GetTestGatewayReceiveServiceConfig(111); mockReceiverConfigurationProvider2.ConfigurationQueue.Clear(); mockReceiverConfigurationProvider2.ConfigurationQueue.Enqueue(testReceiveServiceConfig1); mockReceiverConfigurationProvider2.ConfigurationQueue.Enqueue(testReceiveServiceConfig2); using (var receiveService = CreateReceiveService(mockReceiverConfigurationProvider2.GetConfiguration)) using (var uploadQueue = receiveService.UploadQueue) using (var configurationService = CreateConfigurationService( client, mockConfigurationServiceConfigProvider.GetConfiguration, receiveService)) { // Start the service configurationService.Start(); uploadQueue.Clear(); // Clear the message queue SpinWait.SpinUntil(() => receiveService.StartCount == 2); // Send on the new config var result = DcmtkHelpers.SendFileUsingDCMTK( @"Images\1ValidSmall\1.dcm", testReceiveServiceConfig1.GatewayDicomEndPoint.Port, ScuProfile.LEExplicitCT, TestContext, applicationEntityTitle: callingAet, calledAETitle: testReceiveServiceConfig1.GatewayDicomEndPoint.Title); // Check this did send on the old config Assert.IsFalse(string.IsNullOrWhiteSpace(result)); // Send on the new config result = DcmtkHelpers.SendFileUsingDCMTK( @"Images\1ValidSmall\1.dcm", testReceiveServiceConfig2.GatewayDicomEndPoint.Port, ScuProfile.LEExplicitCT, TestContext, applicationEntityTitle: callingAet, calledAETitle: testReceiveServiceConfig2.GatewayDicomEndPoint.Title); // Check this did send on the new config Assert.IsTrue(string.IsNullOrWhiteSpace(result)); var receiveQueueItem = TransactionalDequeue <UploadQueueItem>(uploadQueue); Assert.IsNotNull(receiveQueueItem); Assert.AreEqual(callingAet, receiveQueueItem.CallingApplicationEntityTitle); Assert.AreEqual(testReceiveServiceConfig2.GatewayDicomEndPoint.Title, receiveQueueItem.CalledApplicationEntityTitle); Assert.IsFalse(string.IsNullOrEmpty(receiveQueueItem.AssociationFolderPath)); var saveDirectoryInfo = new DirectoryInfo(receiveQueueItem.AssociationFolderPath); Assert.IsTrue(saveDirectoryInfo.Exists); var files = saveDirectoryInfo.GetFiles(); // Check we received one file over this association Assert.AreEqual(1, files.Length); // Attempt to get another item from the queue Assert.ThrowsException <MessageQueueReadException>(() => TransactionalDequeue <UploadQueueItem>(uploadQueue)); } }
public async Task ProcessorServiceRestartTest() { var tempFolder = CreateTemporaryDirectory(); foreach (var file in new DirectoryInfo(@"Images\1ValidSmall\").GetFiles()) { file.CopyTo(Path.Combine(tempFolder.FullName, file.Name)); } var client = GetMockInnerEyeSegmentationClient(); var mockConfigurationServiceConfigProvider = new MockConfigurationProvider <ConfigurationServiceConfig>(); var configurationServiceConfig1 = new ConfigurationServiceConfig( configurationRefreshDelaySeconds: 1); var configurationServiceConfig2 = new ConfigurationServiceConfig( configurationServiceConfig1.ConfigCreationDateTime.AddSeconds(5), configurationServiceConfig1.ApplyConfigDateTime.AddSeconds(10)); mockConfigurationServiceConfigProvider.ConfigurationQueue.Enqueue(configurationServiceConfig1); mockConfigurationServiceConfigProvider.ConfigurationQueue.Enqueue(configurationServiceConfig2); var resultDirectory = CreateTemporaryDirectory(); using (var dicomDataReceiver = new ListenerDataReceiver(new ListenerDicomSaver(resultDirectory.FullName))) { var eventCount = 0; var folderPath = string.Empty; dicomDataReceiver.DataReceived += (sender, e) => { folderPath = e.FolderPath; Interlocked.Increment(ref eventCount); }; var testAETConfigModel = GetTestAETConfigModel(); StartDicomDataReceiver(dicomDataReceiver, testAETConfigModel.AETConfig.Destination.Port); using (var pushService = CreatePushService()) using (var uploadService = CreateUploadService(client)) using (var uploadQueue = uploadService.UploadQueue) using (var downloadService = CreateDownloadService(client)) using (var configurationService = CreateConfigurationService( client, mockConfigurationServiceConfigProvider.GetConfiguration, downloadService, uploadService, pushService)) { // Start the service configurationService.Start(); uploadQueue.Clear(); // Clear the message queue SpinWait.SpinUntil(() => pushService.StartCount == 2); SpinWait.SpinUntil(() => uploadService.StartCount == 2); SpinWait.SpinUntil(() => downloadService.StartCount == 2); TransactionalEnqueue( uploadQueue, new UploadQueueItem( calledApplicationEntityTitle: testAETConfigModel.CalledAET, callingApplicationEntityTitle: testAETConfigModel.CallingAET, associationFolderPath: tempFolder.FullName, rootDicomFolderPath: tempFolder.FullName, associationGuid: Guid.NewGuid(), associationDateTime: DateTime.UtcNow)); SpinWait.SpinUntil(() => eventCount >= 3); Assert.IsFalse(string.IsNullOrWhiteSpace(folderPath)); var dicomFile = await DicomFile.OpenAsync(new DirectoryInfo(folderPath).GetFiles()[0].FullName); Assert.IsNotNull(dicomFile); dicomFile = null; TryDeleteDirectory(folderPath); } } }