diff --git a/doc/dependency_decisions.yml b/doc/dependency_decisions.yml index bee058ae7..76a3d3473 100755 --- a/doc/dependency_decisions.yml +++ b/doc/dependency_decisions.yml @@ -774,16 +774,16 @@ - :who: neilsouth :why: Apache-2.0 (https://github.com/Project-MONAI/monai-deploy-messaging/raw/main/LICENSE) :versions: - - 1.0.3 - - 1.0.4 + - 1.0.5-rc0006 + - 1.0.5 :when: 2023-10-13 18:06:21.511789690 Z - - :approve - Monai.Deploy.Messaging.RabbitMQ - :who: neilsouth :why: Apache-2.0 (https://github.com/Project-MONAI/monai-deploy-messaging/raw/main/LICENSE) :versions: - - 1.0.3 - - 1.0.4 + - 1.0.5-rc0006 + - 1.0.5 :when: 2023-10-13 18:06:21.511789690 Z - - :approve - Monai.Deploy.Storage diff --git a/src/CLI/Services/ConfigurationOptionAccessor.cs b/src/CLI/Services/ConfigurationOptionAccessor.cs old mode 100644 new mode 100755 index c61ae761c..a086c6ece --- a/src/CLI/Services/ConfigurationOptionAccessor.cs +++ b/src/CLI/Services/ConfigurationOptionAccessor.cs @@ -30,6 +30,11 @@ public interface IConfigurationOptionAccessor /// int DicomListeningPort { get; set; } + /// + /// Gets or sets the ExternalApp DICOM SCP listening port from appsettings.json. + /// + int ExternalAppDicomListeningPort { get; set; } + /// /// Gets or sets the HL7 listening port from appsettings.json. /// @@ -112,6 +117,21 @@ public int DicomListeningPort } } + public int ExternalAppDicomListeningPort + { + get + { + return GetValueFromJsonPath("InformaticsGateway.dicom.scp.externalAppPort"); + } + set + { + Guard.Against.OutOfRangePort(value, nameof(ExternalAppDicomListeningPort)); + var jObject = ReadConfigurationFile(); + jObject["InformaticsGateway"]["dicom"]["scp"]["externalAppPort"] = value; + SaveConfigurationFile(jObject); + } + } + public int Hl7ListeningPort { get diff --git a/src/Configuration/ScpConfiguration.cs b/src/Configuration/ScpConfiguration.cs old mode 100644 new mode 100755 index 6b66626ee..bac9a2952 --- a/src/Configuration/ScpConfiguration.cs +++ b/src/Configuration/ScpConfiguration.cs @@ -34,6 +34,12 @@ public class ScpConfiguration [ConfigurationKeyName("port")] public int Port { get; set; } = 104; + /// + /// Gets or sets Port number to be used for SCP service. + /// + [ConfigurationKeyName("externalAppPort")] + public int ExternalAppPort { get; set; } = 105; + /// /// Gets or sets maximum number of simultaneous DICOM associations for the SCP service. /// diff --git a/src/InformaticsGateway/Logging/Log.100.200.ScpService.cs b/src/InformaticsGateway/Logging/Log.100.200.ScpService.cs index df26a9cf3..12ec50dbd 100755 --- a/src/InformaticsGateway/Logging/Log.100.200.ScpService.cs +++ b/src/InformaticsGateway/Logging/Log.100.200.ScpService.cs @@ -62,14 +62,12 @@ public static partial class Log public static partial void FailedToUpdateAppliationEntityHandlerWithUpdatedAEChange(this ILogger logger, string aeTitle, Exception? ex = null); // SCP Service - [LoggerMessage(EventId = 200, Level = LogLevel.Information, Message = "Initializing SCP Service at port {port}...")] - public static partial void ScpServiceLoading(this ILogger logger, int port); [LoggerMessage(EventId = 201, Level = LogLevel.Critical, Message = "Failed to initialize SCP listener.")] public static partial void ScpListenerInitializationFailure(this ILogger logger); - [LoggerMessage(EventId = 202, Level = LogLevel.Information, Message = "SCP listening on port: {port}.")] - public static partial void ScpListeningOnPort(this ILogger logger, int port); + [LoggerMessage(EventId = 202, Level = LogLevel.Information, Message = "{serviceName} listening on port: {port}.")] + public static partial void ScpListeningOnPort(this ILogger logger, string serviceName, int port); [LoggerMessage(EventId = 203, Level = LogLevel.Information, Message = "C-ECHO request received.")] public static partial void CEchoReceived(this ILogger logger); diff --git a/src/InformaticsGateway/Program.cs b/src/InformaticsGateway/Program.cs index 477405cd9..a822754b1 100755 --- a/src/InformaticsGateway/Program.cs +++ b/src/InformaticsGateway/Program.cs @@ -162,6 +162,7 @@ internal static IHostBuilder CreateHostBuilder(string[] args) => services.AddHostedService(/*p => p.GetService()*/); services.AddHostedService(/*p => p.GetService()*/); services.AddHostedService(/*p => p.GetService()*/); + services.AddHostedService(); services.AddHostedService(/*p => p.GetService()*/); services.AddHostedService(); services.AddHostedService(/*p => p.GetService()*/); diff --git a/src/InformaticsGateway/Services/Common/ScpInputTypeEnum.cs b/src/InformaticsGateway/Services/Common/ScpInputTypeEnum.cs new file mode 100755 index 000000000..280effdfe --- /dev/null +++ b/src/InformaticsGateway/Services/Common/ScpInputTypeEnum.cs @@ -0,0 +1,24 @@ +/* + * Copyright 2023 MONAI Consortium + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace Monai.Deploy.InformaticsGateway.Services.Common +{ + public enum ScpInputTypeEnum + { + WorkflowTrigger, + ExternalAppReturn + } +} diff --git a/src/InformaticsGateway/Services/Scp/ApplicationEntityManager.cs b/src/InformaticsGateway/Services/Scp/ApplicationEntityManager.cs index 6f3ce0aff..a14e34e02 100755 --- a/src/InformaticsGateway/Services/Scp/ApplicationEntityManager.cs +++ b/src/InformaticsGateway/Services/Scp/ApplicationEntityManager.cs @@ -30,6 +30,7 @@ using Monai.Deploy.InformaticsGateway.Configuration; using Monai.Deploy.InformaticsGateway.Database.Api.Repositories; using Monai.Deploy.InformaticsGateway.Logging; +using Monai.Deploy.InformaticsGateway.Services.Common; using Monai.Deploy.InformaticsGateway.Services.Storage; namespace Monai.Deploy.InformaticsGateway.Services.Scp @@ -92,7 +93,7 @@ private void OnApplicationStopping() _unsubscriberForMonaiAeChangedNotificationService.Dispose(); } - public async Task HandleCStoreRequest(DicomCStoreRequest request, string calledAeTitle, string callingAeTitle, Guid associationId) + public async Task HandleCStoreRequest(DicomCStoreRequest request, string calledAeTitle, string callingAeTitle, Guid associationId, ScpInputTypeEnum type) { Guard.Against.Null(request, nameof(request)); @@ -108,10 +109,10 @@ public async Task HandleCStoreRequest(DicomCStoreRequest request, string throw new InsufficientStorageAvailableException($"Insufficient storage available. Available storage space: {_storageInfoProvider.AvailableFreeSpace:D}"); } - return await HandleInstance(request, calledAeTitle, callingAeTitle, associationId).ConfigureAwait(false); + return await HandleInstance(request, calledAeTitle, callingAeTitle, associationId, type).ConfigureAwait(false); } - private async Task HandleInstance(DicomCStoreRequest request, string calledAeTitle, string callingAeTitle, Guid associationId) + private async Task HandleInstance(DicomCStoreRequest request, string calledAeTitle, string callingAeTitle, Guid associationId, ScpInputTypeEnum type) { var uids = _dicomToolkit.GetStudySeriesSopInstanceUids(request.File); diff --git a/src/InformaticsGateway/Services/Scp/ExternalAppScpService.cs b/src/InformaticsGateway/Services/Scp/ExternalAppScpService.cs new file mode 100755 index 000000000..18e06e677 --- /dev/null +++ b/src/InformaticsGateway/Services/Scp/ExternalAppScpService.cs @@ -0,0 +1,94 @@ +/* + * Copyright 2021-2023 MONAI Consortium + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using Ardalis.GuardClauses; +using FellowOakDicom.Network; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; +using Monai.Deploy.InformaticsGateway.Api.Rest; +using Monai.Deploy.InformaticsGateway.Configuration; +using Monai.Deploy.InformaticsGateway.Logging; + + +namespace Monai.Deploy.InformaticsGateway.Services.Scp +{ + internal class ExternalAppScpService : ScpServiceBase + { + private readonly IServiceScope _serviceScope; + private readonly ILogger _logger; + private readonly ILogger _scpServiceInternalLogger; + private readonly IOptions _configuration; + private readonly IApplicationEntityManager _associationDataProvider; + + public override string ServiceName => "External App DICOM SCP Service"; + + public ExternalAppScpService(IServiceScopeFactory serviceScopeFactory, + IApplicationEntityManager applicationEntityManager, + IHostApplicationLifetime appLifetime, + IOptions configuration) : base(serviceScopeFactory, applicationEntityManager, appLifetime, configuration) + { + Guard.Against.Null(serviceScopeFactory, nameof(serviceScopeFactory)); + Guard.Against.Null(applicationEntityManager, nameof(applicationEntityManager)); + Guard.Against.Null(appLifetime, nameof(appLifetime)); + Guard.Against.Null(configuration, nameof(configuration)); + + _associationDataProvider = applicationEntityManager; + + _serviceScope = serviceScopeFactory.CreateScope(); + var logginFactory = _serviceScope.ServiceProvider.GetService(); + + _logger = logginFactory!.CreateLogger(); + _scpServiceInternalLogger = logginFactory!.CreateLogger(); + _configuration = configuration; + } + + public override void ServiceStart() + { + var ScpPort = _configuration.Value.Dicom.Scp.ExternalAppPort; + try + { + _logger.ServiceStarting(ServiceName); + Server = DicomServerFactory.Create( + NetworkManager.IPv4Any, + ScpPort, + logger: _scpServiceInternalLogger, + userState: _associationDataProvider); + + Server.Options.IgnoreUnsupportedTransferSyntaxChange = true; + Server.Options.LogDimseDatasets = _configuration.Value.Dicom.Scp.LogDimseDatasets; + Server.Options.MaxClientsAllowed = _configuration.Value.Dicom.Scp.MaximumNumberOfAssociations; + + if (Server.Exception != null) + { + _logger.ScpListenerInitializationFailure(); + throw Server.Exception; + } + + Status = ServiceStatus.Running; + _logger.ScpListeningOnPort(ServiceName, ScpPort); + } + catch (System.Exception ex) + { + Status = ServiceStatus.Cancelled; + _logger.ServiceFailedToStart(ServiceName, ex); + AppLifetime.StopApplication(); + } + + } + } +} diff --git a/src/InformaticsGateway/Services/Scp/ExternalAppScpServiceInternal.cs b/src/InformaticsGateway/Services/Scp/ExternalAppScpServiceInternal.cs new file mode 100755 index 000000000..8a41f2c54 --- /dev/null +++ b/src/InformaticsGateway/Services/Scp/ExternalAppScpServiceInternal.cs @@ -0,0 +1,71 @@ +/* + * Copyright 2021-2023 MONAI Consortium + * Copyright 2019-2021 NVIDIA Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; +using System.Text; +using System.Threading.Tasks; +using FellowOakDicom.Network; +using Microsoft.Extensions.Logging; +using Monai.Deploy.InformaticsGateway.Api.Models; +using Monai.Deploy.InformaticsGateway.Common; +using Monai.Deploy.InformaticsGateway.Logging; + + +namespace Monai.Deploy.InformaticsGateway.Services.Scp +{ + internal class ExternalAppScpServiceInternal : ScpServiceInternalBase + { + + private readonly DicomAssociationInfo _associationInfo; + private readonly ILogger _logger; + + public ExternalAppScpServiceInternal(INetworkStream stream, Encoding fallbackEncoding, ILogger logger, DicomServiceDependencies dicomServiceDependencies) + : base(stream, fallbackEncoding, logger, dicomServiceDependencies) + { + _logger = logger ?? throw new ArgumentNullException(nameof(logger)); + _associationInfo = new DicomAssociationInfo(); + } + public override async Task OnCStoreRequestAsync(DicomCStoreRequest request) + { + try + { + _logger?.TransferSyntaxUsed(request.TransferSyntax); + var payloadId = await AssociationDataProvider!.HandleCStoreRequest(request, Association.CalledAE, Association.CallingAE, AssociationId, Common.ScpInputTypeEnum.ExternalAppReturn).ConfigureAwait(false); + _associationInfo.FileReceived(payloadId); + return new DicomCStoreResponse(request, DicomStatus.Success); + } + catch (InsufficientStorageAvailableException ex) + { + _logger?.CStoreFailedDueToLowStorageSpace(ex); + _associationInfo.Errors = $"Failed to store file due to low disk space: {ex}"; + return new DicomCStoreResponse(request, DicomStatus.ResourceLimitation); + } + catch (System.IO.IOException ex) when ((ex.HResult & 0xFFFF) == Constants.ERROR_HANDLE_DISK_FULL || (ex.HResult & 0xFFFF) == Constants.ERROR_DISK_FULL) + { + _logger?.CStoreFailedWithNoSpace(ex); + _associationInfo.Errors = $"Failed to store file due to low disk space: {ex}"; + return new DicomCStoreResponse(request, DicomStatus.StorageStorageOutOfResources); + } + catch (Exception ex) + { + _logger?.CStoreFailed(ex); + _associationInfo.Errors = $"Failed to store file: {ex}"; + return new DicomCStoreResponse(request, DicomStatus.ProcessingFailure); + } + } + } +} diff --git a/src/InformaticsGateway/Services/Scp/IApplicationEntityManager.cs b/src/InformaticsGateway/Services/Scp/IApplicationEntityManager.cs old mode 100644 new mode 100755 index 7c42996c5..d8c224a04 --- a/src/InformaticsGateway/Services/Scp/IApplicationEntityManager.cs +++ b/src/InformaticsGateway/Services/Scp/IApplicationEntityManager.cs @@ -20,6 +20,7 @@ using FellowOakDicom.Network; using Microsoft.Extensions.Options; using Monai.Deploy.InformaticsGateway.Configuration; +using Monai.Deploy.InformaticsGateway.Services.Common; namespace Monai.Deploy.InformaticsGateway.Services.Scp { @@ -35,7 +36,7 @@ public interface IApplicationEntityManager /// Called AE Title to be associated with the call. /// Calling AE Title to be associated with the call. /// Unique association ID. - Task HandleCStoreRequest(DicomCStoreRequest request, string calledAeTitle, string callingAeTitle, Guid associationId); + Task HandleCStoreRequest(DicomCStoreRequest request, string calledAeTitle, string callingAeTitle, Guid associationId, ScpInputTypeEnum type = ScpInputTypeEnum.WorkflowTrigger); /// /// Checks if a MONAI AET is configured. diff --git a/src/InformaticsGateway/Services/Scp/ScpServiceBase.cs b/src/InformaticsGateway/Services/Scp/ScpServiceBase.cs index 5023134c4..8d2afd36c 100755 --- a/src/InformaticsGateway/Services/Scp/ScpServiceBase.cs +++ b/src/InformaticsGateway/Services/Scp/ScpServiceBase.cs @@ -48,7 +48,7 @@ internal abstract class ScpServiceBase : IHostedService, IDisposable, IMonaiServ private readonly IOptions _configuration; protected FoDicomNetwork.IDicomServer? Server; public ServiceStatus Status { get; set; } = ServiceStatus.Unknown; - public virtual string ServiceName => "DICOM SCP Service"; + public abstract string ServiceName { get; } public ScpServiceBase(IServiceScopeFactory serviceScopeFactory, IApplicationEntityManager applicationEntityManager, @@ -98,7 +98,6 @@ public Task StopAsync(CancellationToken cancellationToken) public void ServiceStartBase(int ScpPort) { - _logger.ScpServiceLoading(ScpPort); try { @@ -120,7 +119,7 @@ public void ServiceStartBase(int ScpPort) } Status = ServiceStatus.Running; - _logger.ScpListeningOnPort(ScpPort); + _logger.ScpListeningOnPort(ServiceName, ScpPort); } catch (System.Exception ex) { diff --git a/src/InformaticsGateway/Services/Scp/ScpServiceInternal.cs b/src/InformaticsGateway/Services/Scp/ScpServiceInternal.cs index 1f9d1c521..a19ef3825 100755 --- a/src/InformaticsGateway/Services/Scp/ScpServiceInternal.cs +++ b/src/InformaticsGateway/Services/Scp/ScpServiceInternal.cs @@ -48,7 +48,7 @@ public override async Task OnCStoreRequestAsync(DicomCStore try { _logger?.TransferSyntaxUsed(request.TransferSyntax); - var payloadId = await AssociationDataProvider!.HandleCStoreRequest(request, Association.CalledAE, Association.CallingAE, AssociationId).ConfigureAwait(false); + var payloadId = await AssociationDataProvider!.HandleCStoreRequest(request, Association.CalledAE, Association.CallingAE, AssociationId, Common.ScpInputTypeEnum.WorkflowTrigger).ConfigureAwait(false); _associationInfo.FileReceived(payloadId); return new DicomCStoreResponse(request, DicomStatus.Success); } diff --git a/src/InformaticsGateway/Services/Scu/ScuService.cs b/src/InformaticsGateway/Services/Scu/ScuService.cs index 809f12cfa..1833955d7 100755 --- a/src/InformaticsGateway/Services/Scu/ScuService.cs +++ b/src/InformaticsGateway/Services/Scu/ScuService.cs @@ -205,7 +205,6 @@ public Task StartAsync(CancellationToken cancellationToken) }, CancellationToken.None); Status = ServiceStatus.Running; - _logger.ServiceRunning(ServiceName); if (task.IsCompleted) return task; return Task.CompletedTask; diff --git a/src/InformaticsGateway/Test/Services/Scp/ApplicationEntityManagerTest.cs b/src/InformaticsGateway/Test/Services/Scp/ApplicationEntityManagerTest.cs index cc0c75d6d..574f1dcc3 100755 --- a/src/InformaticsGateway/Test/Services/Scp/ApplicationEntityManagerTest.cs +++ b/src/InformaticsGateway/Test/Services/Scp/ApplicationEntityManagerTest.cs @@ -109,7 +109,7 @@ public async Task HandleCStoreRequest_ShallThrowIfAENotConfigured() var request = GenerateRequest(); var exception = await Assert.ThrowsAsync(async () => { - await manager.HandleCStoreRequest(request, "BADAET", "CallingAET", Guid.NewGuid()); + await manager.HandleCStoreRequest(request, "BADAET", "CallingAET", Guid.NewGuid(), InformaticsGateway.Services.Common.ScpInputTypeEnum.WorkflowTrigger); }); Assert.Equal("Called AE Title 'BADAET' is not configured", exception.Message); @@ -139,7 +139,7 @@ public async Task HandleCStoreRequest_ThrowWhenOnLowStorageSpace() var request = GenerateRequest(); await Assert.ThrowsAsync(async () => { - await manager.HandleCStoreRequest(request, aet, "CallingAET", Guid.NewGuid()); + await manager.HandleCStoreRequest(request, aet, "CallingAET", Guid.NewGuid(), InformaticsGateway.Services.Common.ScpInputTypeEnum.WorkflowTrigger); }); _logger.VerifyLogging($"{aet} added to AE Title Manager.", LogLevel.Information, Times.Once()); @@ -298,7 +298,7 @@ public async Task ShallHandleCStoreRequest() Assert.True(await manager.IsAeTitleConfiguredAsync("AE1").ConfigureAwait(false)); var request = GenerateRequest(); - await manager.HandleCStoreRequest(request, "AE1", "AE", associationId); + await manager.HandleCStoreRequest(request, "AE1", "AE", associationId, InformaticsGateway.Services.Common.ScpInputTypeEnum.WorkflowTrigger); _applicationEntityHandler.Verify(p => p.HandleInstanceAsync( diff --git a/src/InformaticsGateway/Test/Services/Scp/ScpServiceTest.cs b/src/InformaticsGateway/Test/Services/Scp/ScpServiceTest.cs index c8209a0f3..e1aeaa341 100755 --- a/src/InformaticsGateway/Test/Services/Scp/ScpServiceTest.cs +++ b/src/InformaticsGateway/Test/Services/Scp/ScpServiceTest.cs @@ -28,6 +28,7 @@ using Monai.Deploy.InformaticsGateway.Api.Rest; using Monai.Deploy.InformaticsGateway.Common; using Monai.Deploy.InformaticsGateway.Configuration; +using Monai.Deploy.InformaticsGateway.Services.Common; using Monai.Deploy.InformaticsGateway.Services.Scp; using Monai.Deploy.InformaticsGateway.SharedTest; using Moq; @@ -234,7 +235,7 @@ public async Task CStore_OnCStoreRequest_InsufficientStorageAvailableException() _associationDataProvider.Setup(p => p.IsValidSourceAsync(It.IsAny(), It.IsAny())).ReturnsAsync(true); _associationDataProvider.Setup(p => p.IsAeTitleConfiguredAsync(It.IsAny())).ReturnsAsync(true); _associationDataProvider.Setup(p => p.CanStore).Returns(true); - _associationDataProvider.Setup(p => p.HandleCStoreRequest(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())).Throws(new InsufficientStorageAvailableException()); + _associationDataProvider.Setup(p => p.HandleCStoreRequest(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())).Throws(new InsufficientStorageAvailableException()); var countdownEvent = new CountdownEvent(3); var service = await CreateService(); @@ -266,7 +267,7 @@ public async Task CStore_OnCStoreRequest_IoException() _associationDataProvider.Setup(p => p.IsValidSourceAsync(It.IsAny(), It.IsAny())).ReturnsAsync(true); _associationDataProvider.Setup(p => p.IsAeTitleConfiguredAsync(It.IsAny())).ReturnsAsync(true); _associationDataProvider.Setup(p => p.CanStore).Returns(true); - _associationDataProvider.Setup(p => p.HandleCStoreRequest(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())).Throws(new IOException { HResult = Constants.ERROR_HANDLE_DISK_FULL }); + _associationDataProvider.Setup(p => p.HandleCStoreRequest(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())).Throws(new IOException { HResult = Constants.ERROR_HANDLE_DISK_FULL }); var countdownEvent = new CountdownEvent(3); var service = await CreateService(); @@ -297,7 +298,7 @@ public async Task CStore_OnCStoreRequest_Exception() _associationDataProvider.Setup(p => p.IsValidSourceAsync(It.IsAny(), It.IsAny())).ReturnsAsync(true); _associationDataProvider.Setup(p => p.IsAeTitleConfiguredAsync(It.IsAny())).ReturnsAsync(true); _associationDataProvider.Setup(p => p.CanStore).Returns(true); - _associationDataProvider.Setup(p => p.HandleCStoreRequest(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())).Throws(new Exception()); + _associationDataProvider.Setup(p => p.HandleCStoreRequest(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())).Throws(new Exception()); var countdownEvent = new CountdownEvent(3); var service = await CreateService(); @@ -329,7 +330,7 @@ public async Task CStore_OnCStoreRequest_Success() _associationDataProvider.Setup(p => p.IsValidSourceAsync(It.IsAny(), It.IsAny())).ReturnsAsync(true); _associationDataProvider.Setup(p => p.IsAeTitleConfiguredAsync(It.IsAny())).ReturnsAsync(true); _associationDataProvider.Setup(p => p.CanStore).Returns(true); - _associationDataProvider.Setup(p => p.HandleCStoreRequest(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())); + _associationDataProvider.Setup(p => p.HandleCStoreRequest(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())); var countdownEvent = new CountdownEvent(3); var service = await CreateService(); @@ -361,7 +362,7 @@ public async Task CStore_OnClientAbort() _associationDataProvider.Setup(p => p.IsValidSourceAsync(It.IsAny(), It.IsAny())).ReturnsAsync(true); _associationDataProvider.Setup(p => p.IsAeTitleConfiguredAsync(It.IsAny())).ReturnsAsync(true); _associationDataProvider.Setup(p => p.CanStore).Returns(true); - _associationDataProvider.Setup(p => p.HandleCStoreRequest(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())); + _associationDataProvider.Setup(p => p.HandleCStoreRequest(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())); var countdownEvent = new CountdownEvent(1); var service = await CreateService(); diff --git a/src/InformaticsGateway/appsettings.Development.json b/src/InformaticsGateway/appsettings.Development.json index 3f774ab5f..6c6e82c55 100755 --- a/src/InformaticsGateway/appsettings.Development.json +++ b/src/InformaticsGateway/appsettings.Development.json @@ -10,7 +10,7 @@ "InformaticsGateway": { "dicom": { "scp": { - "port": 1104, + "port": 104, "rejectUnknownSources": false } }, @@ -27,7 +27,7 @@ "username": "rabbitmq", "password": "rabbitmq", "virtualHost": "monaideploy", - "exchange": "monaideploy", + "exchange": "monaideploy" } }, "storage": { diff --git a/src/InformaticsGateway/appsettings.json b/src/InformaticsGateway/appsettings.json index 000114c4e..6ccdc1d4c 100755 --- a/src/InformaticsGateway/appsettings.json +++ b/src/InformaticsGateway/appsettings.json @@ -57,6 +57,7 @@ "dicom": { "scp": { "port": 104, + "externalAppPort": 105, "logDimseDatasets": false, "rejectUnknownSources": true },