Skip to content

Commit eb841e4

Browse files
authored
Merge pull request #505 from Project-MONAI/AI-357
Ai 357
2 parents 79c3e53 + 4a7a86f commit eb841e4

File tree

19 files changed

+128
-71
lines changed

19 files changed

+128
-71
lines changed

src/Api/Storage/Hl7FileStorageMetadata.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ namespace Monai.Deploy.InformaticsGateway.Api.Storage
2727
public sealed record Hl7FileStorageMetadata : FileStorageMetadata
2828
{
2929
public const string Hl7SubDirectoryName = "ehr";
30-
public const string FileExtension = ".txt";
30+
public const string FileExtension = ".hl7";
3131

3232
/// <inheritdoc/>
3333
[JsonIgnore]

src/InformaticsGateway/Logging/Log.5000.DataPlugins.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,5 +44,8 @@ public static partial class Log
4444

4545
[LoggerMessage(EventId = 5007, Level = LogLevel.Error, Message = "Error executing plug-in: {plugin}.")]
4646
public static partial void ErrorAddingOutputDataPlugIn(this ILogger logger, Exception d, string plugin);
47+
48+
[LoggerMessage(EventId = 5008, Level = LogLevel.Trace, Message = "Import plugin executed: {pluginName}. now: {fileMetadata}")]
49+
public static partial void InputDataPlugInEngineexecuted(this ILogger logger, string pluginName, string fileMetadata);
4750
}
4851
}

src/InformaticsGateway/Logging/Log.800.Hl7Service.cs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,14 +51,14 @@ public static partial class Log
5151
[LoggerMessage(EventId = 809, Level = LogLevel.Debug, Message = "Acknowledgment type={value}.")]
5252
public static partial void AcknowledgmentType(this ILogger logger, string value);
5353

54-
[LoggerMessage(EventId = 810, Level = LogLevel.Information, Message = "Acknowledgment sent: length={length}.")]
55-
public static partial void AcknowledgmentSent(this ILogger logger, int length);
54+
[LoggerMessage(EventId = 810, Level = LogLevel.Information, Message = "Acknowledgment sent message:{message} length:{length}.")]
55+
public static partial void AcknowledgmentSent(this ILogger logger, string message, int length);
5656

5757
[LoggerMessage(EventId = 811, Level = LogLevel.Debug, Message = "HL7 bytes received: {length}.")]
5858
public static partial void Hl7MessageBytesRead(this ILogger logger, int length);
5959

60-
[LoggerMessage(EventId = 812, Level = LogLevel.Debug, Message = "Parsing message with {length} bytes.")]
61-
public static partial void Hl7GenerateMessage(this ILogger logger, int length);
60+
[LoggerMessage(EventId = 812, Level = LogLevel.Debug, Message = "Parsing message with {length} bytes. {message}")]
61+
public static partial void Hl7GenerateMessage(this ILogger logger, int length, string message);
6262

6363
[LoggerMessage(EventId = 813, Level = LogLevel.Debug, Message = "Waiting for HL7 message.")]
6464
public static partial void HL7ReadingMessage(this ILogger logger);
@@ -105,5 +105,14 @@ public static partial class Log
105105
[LoggerMessage(EventId = 827, Level = LogLevel.Warning, Message = "HL7 plugin loading exceptions")]
106106
public static partial void HL7PluginLoadingExceptions(this ILogger logger, Exception ex);
107107

108+
[LoggerMessage(EventId = 828, Level = LogLevel.Information, Message = "HL7 message recieved. {message}")]
109+
public static partial void Hl7MessageReceieved(this ILogger logger, string message);
110+
111+
[LoggerMessage(EventId = 829, Level = LogLevel.Trace, Message = "HL7 config Not matching message Id {senderId} configId {configID}")]
112+
public static partial void Hl7NotMatchingConfig(this ILogger logger, string senderId, string configID);
113+
114+
[LoggerMessage(EventId = 830, Level = LogLevel.Error, Message = "Error generating HL7 acknowledgment. for message {message}")]
115+
public static partial void ErrorGeneratingHl7Acknowledgment(this ILogger logger, Exception ex, string message);
116+
108117
}
109118
}

src/InformaticsGateway/Program.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ private static NLog.Logger ConfigureNLog(string assemblyVersionNumber)
182182
ext.RegisterLayoutRenderer("servicename", logEvent => typeof(Program).Namespace);
183183
ext.RegisterLayoutRenderer("serviceversion", logEvent => assemblyVersionNumber);
184184
ext.RegisterLayoutRenderer("machinename", logEvent => Environment.MachineName);
185+
ext.RegisterLayoutRenderer("appname", logEvent => "MIG");
185186
})
186187
.LoadConfigurationFromAppSettings()
187188
.GetCurrentClassLogger();

src/InformaticsGateway/Services/Common/InputDataPluginEngine.cs

100644100755
Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
using System;
1818
using System.Collections.Generic;
1919
using System.Linq;
20+
using System.Text.Json;
2021
using System.Threading.Tasks;
2122
using FellowOakDicom;
2223
using Microsoft.Extensions.Logging;
@@ -31,7 +32,7 @@ internal class InputDataPlugInEngine : IInputDataPlugInEngine
3132
{
3233
private readonly IServiceProvider _serviceProvider;
3334
private readonly ILogger<InputDataPlugInEngine> _logger;
34-
private IReadOnlyList<IInputDataPlugIn>? _plugsins;
35+
private IReadOnlyList<IInputDataPlugIn>? _plugins;
3536

3637
public InputDataPlugInEngine(IServiceProvider serviceProvider, ILogger<InputDataPlugInEngine> logger)
3738
{
@@ -41,20 +42,22 @@ public InputDataPlugInEngine(IServiceProvider serviceProvider, ILogger<InputData
4142

4243
public void Configure(IReadOnlyList<string> pluginAssemblies)
4344
{
44-
_plugsins = LoadPlugIns(_serviceProvider, pluginAssemblies);
45+
_plugins = LoadPlugIns(_serviceProvider, pluginAssemblies);
4546
}
4647

4748
public async Task<Tuple<DicomFile, FileStorageMetadata>> ExecutePlugInsAsync(DicomFile dicomFile, FileStorageMetadata fileMetadata)
4849
{
49-
if (_plugsins == null)
50+
if (_plugins == null)
5051
{
5152
throw new PlugInInitializationException("InputDataPlugInEngine not configured, please call Configure() first.");
5253
}
5354

54-
foreach (var plugin in _plugsins)
55+
foreach (var plugin in _plugins)
5556
{
5657
_logger.ExecutingInputDataPlugIn(plugin.Name);
5758
(dicomFile, fileMetadata) = await plugin.ExecuteAsync(dicomFile, fileMetadata).ConfigureAwait(false);
59+
60+
_logger.InputDataPlugInEngineexecuted(plugin.Name, JsonSerializer.Serialize(fileMetadata));
5861
}
5962

6063
return new Tuple<DicomFile, FileStorageMetadata>(dicomFile, fileMetadata);

src/InformaticsGateway/Services/Common/InputHL7DataPlugInEngine.cs

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -47,20 +47,22 @@ public void Configure(IReadOnlyList<string> pluginAssemblies)
4747

4848
public async Task<Tuple<Message, FileStorageMetadata>> ExecutePlugInsAsync(Message hl7File, FileStorageMetadata fileMetadata, Hl7ApplicationConfigEntity? configItem)
4949
{
50-
if (_plugsins == null)
50+
if (configItem?.PlugInAssemblies is not null && configItem.PlugInAssemblies.Any())
5151
{
52-
throw new PlugInInitializationException("InputHL7DataPlugInEngine not configured, please call Configure() first.");
53-
}
52+
if (_plugsins == null)
53+
{
54+
throw new PlugInInitializationException("InputHL7DataPlugInEngine not configured, please call Configure() first.");
55+
}
5456

55-
foreach (var plugin in _plugsins)
56-
{
57-
if (configItem is not null && configItem.PlugInAssemblies.Exists(a => a.StartsWith(plugin.ToString()!)))
57+
foreach (var plugin in _plugsins)
5858
{
59-
_logger.ExecutingInputDataPlugIn(plugin.Name);
60-
(hl7File, fileMetadata) = await plugin.ExecuteAsync(hl7File, fileMetadata).ConfigureAwait(false);
59+
if (configItem is not null && configItem.PlugInAssemblies.Exists(a => a.StartsWith(plugin.ToString()!)))
60+
{
61+
_logger.ExecutingInputDataPlugIn(plugin.Name);
62+
(hl7File, fileMetadata) = await plugin.ExecuteAsync(hl7File, fileMetadata).ConfigureAwait(false);
63+
}
6164
}
6265
}
63-
6466
return new Tuple<Message, FileStorageMetadata>(hl7File, fileMetadata);
6567
}
6668

src/InformaticsGateway/Services/Connectors/PayloadAssembler.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ private async void OnTimedEvent(Object? source, System.Timers.ElapsedEventArgs e
144144
}
145145
foreach (var key in _payloads.Keys)
146146
{
147-
var payload = await _payloads[key].WithCancellation(_tokenSource.Token);
147+
var payload = await _payloads[key].WithCancellation(_tokenSource.Token).ConfigureAwait(false);
148148
using var loggerScope = _logger.BeginScope(new LoggingDataDictionary<string, object> { { "CorrelationId", payload.CorrelationId } });
149149

150150
_logger.BucketElapsedTime(key, payload.Timeout, payload.ElapsedTime().TotalSeconds, payload.Files.Count, payload.FilesUploaded, payload.FilesFailedToUpload);

src/InformaticsGateway/Services/Connectors/PayloadNotificationActionHandler.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
using System;
1818
using System.Linq;
19+
using System.Text.Json;
1920
using System.Threading;
2021
using System.Threading.Tasks;
2122
using System.Threading.Tasks.Dataflow;
@@ -169,6 +170,8 @@ private async Task SendArtifactRecievedEvent(Payload payload)
169170
};
170171
artifiactRecievedEvent.DataOrigins.AddRange(payload.DataOrigins);
171172

173+
_logger.LogTrace($"Adding files to ArtifactsReceivedEvent files {JsonSerializer.Serialize(payload)}");
174+
172175
artifiactRecievedEvent.Artifacts = payload.Files.Select(f => new Artifact { Type = f.DataOrigin.ArtifactType, Path = f.File.UploadPath }).ToList();
173176

174177
var message = new JsonMessage<ArtifactsReceivedEvent>(

src/InformaticsGateway/Services/Export/Hl7ExportService.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
using Monai.Deploy.InformaticsGateway.Api.Mllp;
3232
using Monai.Deploy.Messaging.Common;
3333
using Polly;
34+
using System.Linq;
3435

3536
namespace Monai.Deploy.InformaticsGateway.Services.Export
3637
{
@@ -119,7 +120,7 @@ private async Task ExecuteHl7Export(
119120
.ExecuteAsync(async () =>
120121
{
121122
await _mllpService.SendMllp(
122-
IPAddress.Parse(destination.HostIp),
123+
Dns.GetHostAddresses(destination.HostIp).First(),
123124
destination.Port, Encoding.UTF8.GetString(exportRequestData.FileContent),
124125
cancellationToken
125126
).ConfigureAwait(false);

src/InformaticsGateway/Services/HealthLevel7/MllpClient.cs

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -159,13 +159,31 @@ private async Task SendAcknowledgment(INetworkStream clientStream, Message messa
159159

160160
if (ShouldSendAcknowledgment(message))
161161
{
162-
var ackMessage = message.GetACK();
162+
Message ackMessage = message;
163+
try
164+
{
165+
ackMessage = message.GetACK(false);
166+
}
167+
catch (Exception ex)
168+
{
169+
_logger.ErrorGeneratingHl7Acknowledgment(ex, message.HL7Message);
170+
_exceptions.Add(ex);
171+
return;
172+
}
173+
174+
if (ackMessage is null)
175+
{
176+
var ex = new Exception("Error generating HL7 acknowledgment.");
177+
_logger.ErrorGeneratingHl7Acknowledgment(ex, message.HL7Message);
178+
_exceptions.Add(ex);
179+
return;
180+
}
163181
var ackData = new ReadOnlyMemory<byte>(ackMessage.GetMLLP());
164182
try
165183
{
166184
await clientStream.WriteAsync(ackData, cancellationToken).ConfigureAwait(false);
167185
await clientStream.FlushAsync(cancellationToken).ConfigureAwait(false);
168-
_logger.AcknowledgmentSent(ackData.Length);
186+
_logger.AcknowledgmentSent(ackMessage.HL7Message, ackData.Length);
169187
}
170188
catch (Exception ex)
171189
{
@@ -181,7 +199,7 @@ private bool ShouldSendAcknowledgment(Message message)
181199
try
182200
{
183201
var value = message.DefaultSegment(Resources.MessageHeaderSegment).Fields(Resources.AcceptAcknowledgementType);
184-
if (value is null)
202+
if (value is null || string.IsNullOrWhiteSpace(value.Value))
185203
{
186204
return true;
187205
}
@@ -211,9 +229,9 @@ private bool CreateMessage(int startIndex, int endIndex, ref string data, out Me
211229
try
212230
{
213231
var text = data.Substring(messageStartIndex, endIndex - messageStartIndex);
214-
_logger.Hl7GenerateMessage(text.Length);
232+
_logger.Hl7GenerateMessage(text.Length, text);
215233
message = new Message(text);
216-
message.ParseMessage();
234+
message.ParseMessage(false);
217235
data = data.Length > endIndex ? data.Substring(messageEndIndex) : string.Empty;
218236
return true;
219237
}

src/InformaticsGateway/Services/HealthLevel7/MllpExtract.cs

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
using System;
1919
using System.Collections.Generic;
20+
using System.Text.Json;
2021
using System.Threading;
2122
using System.Threading.Tasks;
2223
using FellowOakDicom;
@@ -29,19 +30,11 @@
2930

3031
namespace Monai.Deploy.InformaticsGateway.Api.Mllp
3132
{
32-
public sealed class MllpExtract : IMllpExtract
33+
public sealed class MllpExtract(IHl7ApplicationConfigRepository hl7ApplicationConfigRepository, IExternalAppDetailsRepository externalAppDetailsRepository, ILogger<MllpExtract> logger) : IMllpExtract
3334
{
34-
private readonly ILogger<MllpExtract> _logger;
35-
private readonly IHl7ApplicationConfigRepository _hl7ApplicationConfigRepository;
36-
private readonly IExternalAppDetailsRepository _externalAppDetailsRepository;
37-
38-
public MllpExtract(IHl7ApplicationConfigRepository hl7ApplicationConfigRepository, IExternalAppDetailsRepository externalAppDetailsRepository, ILogger<MllpExtract> logger)
39-
{
40-
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
41-
_hl7ApplicationConfigRepository = hl7ApplicationConfigRepository ?? throw new ArgumentNullException(nameof(hl7ApplicationConfigRepository));
42-
_externalAppDetailsRepository = externalAppDetailsRepository ?? throw new ArgumentNullException(nameof(externalAppDetailsRepository));
43-
}
44-
35+
private readonly ILogger<MllpExtract> _logger = logger ?? throw new ArgumentNullException(nameof(logger));
36+
private readonly IHl7ApplicationConfigRepository _hl7ApplicationConfigRepository = hl7ApplicationConfigRepository ?? throw new ArgumentNullException(nameof(hl7ApplicationConfigRepository));
37+
private readonly IExternalAppDetailsRepository _externalAppDetailsRepository = externalAppDetailsRepository ?? throw new ArgumentNullException(nameof(externalAppDetailsRepository));
4538

4639
public async Task<Message> ExtractInfo(Hl7FileStorageMetadata meta, Message message, Hl7ApplicationConfigEntity configItem)
4740
{
@@ -87,7 +80,7 @@ public async Task<Message> ExtractInfo(Hl7FileStorageMetadata meta, Message mess
8780
_logger.Hl7NoConfig();
8881
return null;
8982
}
90-
_logger.Hl7ConfigLoaded($"Config: {config}");
83+
_logger.Hl7ConfigLoaded($"Config: {JsonSerializer.Serialize(config)}");
9184
// get config for vendorId
9285
var configItem = GetConfig(config, message);
9386
if (configItem == null)
@@ -115,15 +108,20 @@ public async Task<Message> ExtractInfo(Hl7FileStorageMetadata meta, Message mess
115108
throw new Exception($"Invalid DataLinkType: {type}");
116109
}
117110

118-
internal static Hl7ApplicationConfigEntity? GetConfig(List<Hl7ApplicationConfigEntity> config, Message message)
111+
internal Hl7ApplicationConfigEntity? GetConfig(List<Hl7ApplicationConfigEntity> config, Message message)
119112
{
120113
foreach (var item in config)
121114
{
122-
var t = message.GetValue(item.SendingId.Key);
123-
if (item.SendingId.Value == message.GetValue(item.SendingId.Key))
115+
var sendingId = message.GetValue(item.SendingId.Key);
116+
if (item.SendingId.Value == sendingId)
124117
{
118+
_logger.Hl7FoundMatchingConfig(sendingId, JsonSerializer.Serialize(item));
125119
return item;
126120
}
121+
else
122+
{
123+
_logger.Hl7NotMatchingConfig(sendingId, item.SendingId.Value);
124+
}
127125
}
128126
return null;
129127
}
@@ -143,7 +141,7 @@ private Message RepopulateMessage(Hl7ApplicationConfigEntity config, ExternalApp
143141
{
144142
var newMess = message.HL7Message.Replace(oldvalue, details.PatientId);
145143
message = new Message(newMess);
146-
message.ParseMessage();
144+
message.ParseMessage(true);
147145
}
148146
}
149147
else if (tag == DicomTag.StudyInstanceUID)
@@ -155,7 +153,7 @@ private Message RepopulateMessage(Hl7ApplicationConfigEntity config, ExternalApp
155153
{
156154
var newMess = message.HL7Message.Replace(oldvalue, details.StudyInstanceUid);
157155
message = new Message(newMess);
158-
message.ParseMessage();
156+
message.ParseMessage(true);
159157
}
160158
}
161159
}

0 commit comments

Comments
 (0)