Skip to content

Commit

Permalink
more fixups
Browse files Browse the repository at this point in the history
Signed-off-by: Neil South <neil.south@answerdigital.com>
  • Loading branch information
neildsouth committed Dec 4, 2023
1 parent 5175a3a commit a6dce3a
Show file tree
Hide file tree
Showing 12 changed files with 74 additions and 60 deletions.
14 changes: 13 additions & 1 deletion src/Api/Hl7ApplicationConfigEntity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using FellowOakDicom;
using Monai.Deploy.InformaticsGateway.Api.Storage;
Expand All @@ -28,6 +28,13 @@ namespace Monai.Deploy.InformaticsGateway.Api
{
public class Hl7ApplicationConfigEntity : MongoDBEntityBase
{
/// <summary>
/// Gets or sets the name of a Hl7 application entity.
/// This value must be unique.
/// </summary>
[Key, Column(Order = 0)]
public string Name { get; set; } = default!;

/// <summary>
/// Gets or sets the sending identifier.
/// </summary>
Expand All @@ -48,6 +55,11 @@ public class Hl7ApplicationConfigEntity : MongoDBEntityBase
[JsonProperty("data_mapping")]
public List<StringKeyValuePair> DataMapping { get; set; } = new();

/// <summary>
/// Optional list of data input plug-in type names to be executed by the <see cref="IInputHL7DataPlugInEngine"/>.
/// </summary>
public List<string> PlugInAssemblies { get; set; } = default!;

public IEnumerable<string> Validate()
{
var errors = new List<string>();
Expand Down
20 changes: 20 additions & 0 deletions src/Database/EntityFramework/Configuration/Hl7ApplicationConfigConfiguration.cs
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@
* limitations under the License.
*/

using System.Text.Json.Serialization;
using System.Text.Json;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.ChangeTracking;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Monai.Deploy.InformaticsGateway.Api;

Expand All @@ -24,7 +27,24 @@ internal class Hl7ApplicationConfigConfiguration : IEntityTypeConfiguration<Hl7A
{
public void Configure(EntityTypeBuilder<Hl7ApplicationConfigEntity> builder)
{
var valueComparer = new ValueComparer<List<string>>(
(c1, c2) => c1!.SequenceEqual(c2!),
c => c.Aggregate(0, (a, v) => HashCode.Combine(a, v.GetHashCode())),
c => c.ToList());

var jsonSerializerSettings = new JsonSerializerOptions
{
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
};

builder.HasKey(j => j.Id);
builder.Property(j => j.PlugInAssemblies)
.HasConversion(
v => JsonSerializer.Serialize(v, jsonSerializerSettings),
v => JsonSerializer.Deserialize<List<string>>(v, jsonSerializerSettings)!)
.Metadata.SetValueComparer(valueComparer);

builder.HasIndex(p => p.Name, "idx_hl7_name").IsUnique();
}
}
}
11 changes: 5 additions & 6 deletions src/InformaticsGateway/Services/Export/ExportServiceBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,9 @@ public async Task StopAsync(CancellationToken cancellationToken)
_cancellationTokenSource.Cancel();
_logger.ServiceStopping(ServiceName);
Status = ServiceStatus.Stopped;
#pragma warning disable CA2016 // Forward the 'CancellationToken' parameter to methods
await Task.Delay(250).ConfigureAwait(false);
#pragma warning restore CA2016 // Forward the 'CancellationToken' parameter to methods
_cancellationTokenSource.Dispose();
return;
}
Expand Down Expand Up @@ -459,12 +461,9 @@ private async Task<DestinationApplicationEntity> LookupDestinationAsync(string d
var repository = scope.ServiceProvider.GetRequiredService<IDestinationApplicationEntityRepository>();
var destination = await repository.FindByNameAsync(destinationName, cancellationToken).ConfigureAwait(false);

if (destination is null)
{
throw new ConfigurationException($"Specified destination '{destinationName}' does not exist.");
}

return destination;
return destination is null
? throw new ConfigurationException($"Specified destination '{destinationName}' does not exist.")
: destination;
}

protected virtual async Task<DestinationApplicationEntity?> GetDestination(ExportRequestDataMessage exportRequestData, string destinationName, CancellationToken cancellationToken)
Expand Down
17 changes: 6 additions & 11 deletions src/InformaticsGateway/Services/Export/Hl7ExportService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,6 @@ protected override async Task HandleDesination(ExportRequestDataMessage exportRe
{
Guard.Against.Null(exportRequestData, nameof(exportRequestData));

var manualResetEvent = new ManualResetEvent(false);
var destination = await GetHL7Destination(exportRequestData, destinationName, cancellationToken).ConfigureAwait(false);
if (destination is null)
{
Expand All @@ -98,7 +97,7 @@ protected override async Task HandleDesination(ExportRequestDataMessage exportRe

try
{
await ExecuteHl7Export(exportRequestData, manualResetEvent, destination!, cancellationToken).ConfigureAwait(false);
await ExecuteHl7Export(exportRequestData, destination!, cancellationToken).ConfigureAwait(false);
}
catch (Exception ex)
{
Expand All @@ -108,7 +107,6 @@ protected override async Task HandleDesination(ExportRequestDataMessage exportRe

private async Task ExecuteHl7Export(
ExportRequestDataMessage exportRequestData,
ManualResetEvent manualResetEvent,
HL7DestinationEntity destination,
CancellationToken cancellationToken) => await Policy
.Handle<Exception>()
Expand Down Expand Up @@ -139,12 +137,9 @@ private async Task<HL7DestinationEntity> LookupDestinationAsync(string destinati
var repository = scope.ServiceProvider.GetRequiredService<IHL7DestinationEntityRepository>();
var destination = await repository.FindByNameAsync(destinationName, cancellationToken).ConfigureAwait(false);

if (destination is null)
{
throw new ConfigurationException($"Specified destination '{destinationName}' does not exist.");
}

return destination;
return destination is null
? throw new ConfigurationException($"Specified destination '{destinationName}' does not exist.")
: destination;
}

private async Task<HL7DestinationEntity?> GetHL7Destination(ExportRequestDataMessage exportRequestData, string destinationName, CancellationToken cancellationToken)
Expand All @@ -160,9 +155,9 @@ private async Task<HL7DestinationEntity> LookupDestinationAsync(string destinati
}
}

protected override async Task<ExportRequestDataMessage> ExecuteOutputDataEngineCallback(ExportRequestDataMessage exportDataRequest)
protected override Task<ExportRequestDataMessage> ExecuteOutputDataEngineCallback(ExportRequestDataMessage exportDataRequest)
{
return exportDataRequest;
return Task.FromResult(exportDataRequest);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@ namespace Monai.Deploy.InformaticsGateway.Services.HealthLevel7
{
internal interface IMllpClientFactory
{
IMllpClient CreateClient(ITcpClientAdapter client, Hl7Configuration configurations, IMllpExtract mIIpExtract, ILogger<MllpClient> logger);
IMllpClient CreateClient(ITcpClientAdapter client, Hl7Configuration configurations, ILogger<MllpClient> logger);
}

internal class MllpClientFactory : IMllpClientFactory
{
public IMllpClient CreateClient(ITcpClientAdapter client, Hl7Configuration configurations, IMllpExtract mIIpExtract, ILogger<MllpClient> logger)
=> new MllpClient(client, configurations, mIIpExtract, logger);
public IMllpClient CreateClient(ITcpClientAdapter client, Hl7Configuration configurations, ILogger<MllpClient> logger)
=> new MllpClient(client, configurations, logger);
}
}
7 changes: 2 additions & 5 deletions src/InformaticsGateway/Services/HealthLevel7/MllpClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ internal sealed class MllpClient : IMllpClient
private readonly List<Exception> _exceptions;
private readonly List<Message> _messages;
private readonly IDisposable _loggerScope;
private readonly IMllpExtract _mIIpExtract;
private bool _disposedValue;

public Guid ClientId { get; }
Expand All @@ -48,12 +47,11 @@ public string ClientIp
get { return _client.RemoteEndPoint.ToString() ?? string.Empty; }
}

public MllpClient(ITcpClientAdapter client, Hl7Configuration configurations, IMllpExtract mIIpExtract, ILogger<MllpClient> logger)
public MllpClient(ITcpClientAdapter client, Hl7Configuration configurations, ILogger<MllpClient> logger)
{
_client = client ?? throw new ArgumentNullException(nameof(client));
_configurations = configurations ?? throw new ArgumentNullException(nameof(configurations));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_mIIpExtract = mIIpExtract ?? throw new ArgumentNullException(nameof(_mIIpExtract));

ClientId = Guid.NewGuid();
_exceptions = new List<Exception>();
Expand Down Expand Up @@ -112,8 +110,6 @@ private async Task<IList<Message>> ReceiveData(INetworkStream clientStream, Canc
break;
}

linkedCancellationTokenSource.Dispose();

data += Encoding.UTF8.GetString(messageBuffer.ToArray());

do
Expand Down Expand Up @@ -147,6 +143,7 @@ private async Task<IList<Message>> ReceiveData(INetworkStream clientStream, Canc
}
} while (true);
}
linkedCancellationTokenSource.Dispose();
return messages;
}

Expand Down
7 changes: 3 additions & 4 deletions src/InformaticsGateway/Services/HealthLevel7/MllpExtract.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public async Task<Message> ExtractInfo(Hl7FileStorageMetadata meta, Message mess
}
// extract data for the given fields
// Use Id to get record from Db
var details = await GetExtAppDetails(configItem, message);
var details = await GetExtAppDetails(configItem, message).ConfigureAwait(false);

if (details is null)
{
Expand Down Expand Up @@ -101,9 +101,9 @@ public async Task<Message> ExtractInfo(Hl7FileStorageMetadata meta, Message mess
switch (type)
{
case DataLinkType.PatientId:
return await _externalAppDetailsRepository.GetByPatientIdOutboundAsync(tagId, new CancellationToken());
return await _externalAppDetailsRepository.GetByPatientIdOutboundAsync(tagId, new CancellationToken()).ConfigureAwait(false); ;
case DataLinkType.StudyInstanceUid:
return await _externalAppDetailsRepository.GetByStudyIdOutboundAsync(tagId, new CancellationToken());
return await _externalAppDetailsRepository.GetByStudyIdOutboundAsync(tagId, new CancellationToken()).ConfigureAwait(false); ;
default:
break;
}
Expand All @@ -115,7 +115,6 @@ public async Task<Message> ExtractInfo(Hl7FileStorageMetadata meta, Message mess
{
foreach (var item in config)
{
var t = message.GetValue(item.SendingId.Key);
if (item.SendingId.Value == message.GetValue(item.SendingId.Key))
{
return item;
Expand Down
11 changes: 3 additions & 8 deletions src/InformaticsGateway/Services/HealthLevel7/MllpService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@
using System.Threading;
using System.Threading.Tasks;
using Ardalis.GuardClauses;
using CommunityToolkit.HighPerformance.Buffers;
using FellowOakDicom.Network;
using HL7.Dotnetcore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
Expand Down Expand Up @@ -139,7 +137,7 @@ private async Task BackgroundProcessing(CancellationToken cancellationToken)
continue;
}

mllpClient = _mllpClientFactory.CreateClient(client, _configuration.Value.Hl7, _mIIpExtract, _logginFactory.CreateLogger<MllpClient>());
mllpClient = _mllpClientFactory.CreateClient(client, _configuration.Value.Hl7, _logginFactory.CreateLogger<MllpClient>());
_ = mllpClient.Start(OnDisconnect, cancellationToken);
_activeTasks.TryAdd(mllpClient.ClientId, mllpClient);
}
Expand Down Expand Up @@ -229,12 +227,9 @@ public async Task SendMllp(IPAddress address, int port, string hl7Message, Cance
{
try
{
using var linkedCancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
linkedCancellationTokenSource.CancelAfter(_configuration.Value.Hl7.ClientTimeoutMilliseconds);

var body = $"{Resources.AsciiVT}{hl7Message}{Resources.AsciiFS}{Resources.AcsiiCR}";
var sendMessageByteBuffer = Encoding.UTF8.GetBytes(body);
await WriteMessage(sendMessageByteBuffer, address, port, linkedCancellationTokenSource.Token).ConfigureAwait(false);
await WriteMessage(sendMessageByteBuffer, address, port).ConfigureAwait(false);
}
catch (ArgumentOutOfRangeException)
{
Expand All @@ -248,7 +243,7 @@ public async Task SendMllp(IPAddress address, int port, string hl7Message, Cance
}
}

private async Task WriteMessage(byte[] sendMessageByteBuffer, IPAddress address, int port, CancellationToken linkedCancellationToken)
private async Task WriteMessage(byte[] sendMessageByteBuffer, IPAddress address, int port)
{

using var tcpClient = new TcpClient();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
*/

using System;
using Microsoft.AspNetCore.Http.Features;
using Monai.Deploy.InformaticsGateway.Api.Rest;
using Monai.Deploy.InformaticsGateway.Repositories;
using Monai.Deploy.InformaticsGateway.Services.Common;
Expand Down
27 changes: 13 additions & 14 deletions src/InformaticsGateway/Test/Services/HealthLevel7/MllpClientTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using FellowOakDicom;
using HL7.Dotnetcore;
using Microsoft.Extensions.Logging;
using Monai.Deploy.InformaticsGateway.Configuration;
Expand Down Expand Up @@ -54,12 +53,12 @@ public MllpClientTest()
[Fact(DisplayName = "Constructor")]
public void Constructor()
{
Assert.Throws<ArgumentNullException>(() => new MllpClient(null, null, null, null));
Assert.Throws<ArgumentNullException>(() => new MllpClient(_tcpClient.Object, null, null, null));
Assert.Throws<ArgumentNullException>(() => new MllpClient(_tcpClient.Object, _config, null, null));
Assert.Throws<ArgumentNullException>(() => new MllpClient(_tcpClient.Object, _config, _mIIpExtract.Object, null));
Assert.Throws<ArgumentNullException>(() => new MllpClient(null, null, null));
Assert.Throws<ArgumentNullException>(() => new MllpClient(_tcpClient.Object, null, null));
Assert.Throws<ArgumentNullException>(() => new MllpClient(_tcpClient.Object, _config, null));
Assert.Throws<ArgumentNullException>(() => new MllpClient(_tcpClient.Object, _config, null));

new MllpClient(_tcpClient.Object, _config, _mIIpExtract.Object, _logger.Object);
new MllpClient(_tcpClient.Object, _config, _logger.Object);
}

[Fact(DisplayName = "ReceiveData - records exception thrown by network stream")]
Expand All @@ -70,7 +69,7 @@ public async Task ReceiveData_ExceptionReadingStream()
.ThrowsAsync(new Exception("error"));

_tcpClient.Setup(p => p.GetStream()).Returns(stream.Object);
var client = new MllpClient(_tcpClient.Object, _config, _mIIpExtract.Object, _logger.Object);
var client = new MllpClient(_tcpClient.Object, _config, _logger.Object);

var action = new Func<IMllpClient, MllpClientResult, Task>(async (client, results) =>
{
Expand All @@ -93,7 +92,7 @@ public async Task ReceiveData_ZeroByte()
.ReturnsAsync(0);

_tcpClient.Setup(p => p.GetStream()).Returns(stream.Object);
var client = new MllpClient(_tcpClient.Object, _config, _mIIpExtract.Object, _logger.Object);
var client = new MllpClient(_tcpClient.Object, _config, _logger.Object);

var action = new Func<IMllpClient, MllpClientResult, Task>(async (client, results) =>
{
Expand Down Expand Up @@ -128,7 +127,7 @@ public async Task ReceiveData_InvalidMessage()
});

_tcpClient.Setup(p => p.GetStream()).Returns(stream.Object);
var client = new MllpClient(_tcpClient.Object, _config, _mIIpExtract.Object, _logger.Object);
var client = new MllpClient(_tcpClient.Object, _config, _logger.Object);

var action = new Func<IMllpClient, MllpClientResult, Task>(async (client, results) =>
{
Expand Down Expand Up @@ -169,7 +168,7 @@ public async Task ReceiveData_DisabledAck()
});

_tcpClient.Setup(p => p.GetStream()).Returns(stream.Object);
var client = new MllpClient(_tcpClient.Object, _config, _mIIpExtract.Object, _logger.Object);
var client = new MllpClient(_tcpClient.Object, _config, _logger.Object);

var action = new Func<IMllpClient, MllpClientResult, Task>(async (client, results) =>
{
Expand Down Expand Up @@ -210,7 +209,7 @@ public async Task ReceiveData_NeverSendAck()
});

_tcpClient.Setup(p => p.GetStream()).Returns(stream.Object);
var client = new MllpClient(_tcpClient.Object, _config, _mIIpExtract.Object, _logger.Object);
var client = new MllpClient(_tcpClient.Object, _config, _logger.Object);

var action = new Func<IMllpClient, MllpClientResult, Task>(async (client, results) =>
{
Expand Down Expand Up @@ -251,7 +250,7 @@ public async Task ReceiveData_ExceptionSendingAck()
});

_tcpClient.Setup(p => p.GetStream()).Returns(stream.Object);
var client = new MllpClient(_tcpClient.Object, _config, _mIIpExtract.Object, _logger.Object);
var client = new MllpClient(_tcpClient.Object, _config, _logger.Object);

var action = new Func<IMllpClient, MllpClientResult, Task>(async (client, results) =>
{
Expand Down Expand Up @@ -291,7 +290,7 @@ public async Task ReceiveData_CompleteWorkflow()
});

_tcpClient.Setup(p => p.GetStream()).Returns(stream.Object);
var client = new MllpClient(_tcpClient.Object, _config, _mIIpExtract.Object, _logger.Object);
var client = new MllpClient(_tcpClient.Object, _config, _logger.Object);

var action = new Func<IMllpClient, MllpClientResult, Task>(async (client, results) =>
{
Expand Down Expand Up @@ -337,7 +336,7 @@ public async Task ReceiveData_CompleteWorkflow_WithMultipleMessages()
});

_tcpClient.Setup(p => p.GetStream()).Returns(stream.Object);
var client = new MllpClient(_tcpClient.Object, _config, _mIIpExtract.Object, _logger.Object);
var client = new MllpClient(_tcpClient.Object, _config, _logger.Object);

var action = new Func<IMllpClient, MllpClientResult, Task>(async (client, results) =>
{
Expand Down
Loading

0 comments on commit a6dce3a

Please sign in to comment.