diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
old mode 100644
new mode 100755
index ca6a5527c..51a009a7b
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -183,11 +183,11 @@ jobs:
ports:
- 27017:27017
steps:
- - name: Set up JDK 11
+ - name: Set up JDK 17
uses: actions/setup-java@v3
with:
distribution: zulu
- java-version: '11'
+ java-version: '17'
- uses: actions/setup-dotnet@v3
with:
diff --git a/src/Api/Hl7ApplicationConfigEntity.cs b/src/Api/Hl7ApplicationConfigEntity.cs
index aefa605cf..3cc3160d9 100755
--- a/src/Api/Hl7ApplicationConfigEntity.cs
+++ b/src/Api/Hl7ApplicationConfigEntity.cs
@@ -26,7 +26,7 @@
namespace Monai.Deploy.InformaticsGateway.Api
{
- public class Hl7ApplicationConfigEntity : MongoDBEntityBase
+ public sealed class Hl7ApplicationConfigEntity : MongoDBEntityBase
{
///
/// Gets or sets the name of a Hl7 application entity.
@@ -60,6 +60,8 @@ public class Hl7ApplicationConfigEntity : MongoDBEntityBase
///
public List PlugInAssemblies { get; set; } = default!;
+ public DateTime LastModified { get; set; } = DateTime.UtcNow;
+
public IEnumerable Validate()
{
var errors = new List();
@@ -114,7 +116,7 @@ public override string ToString()
}
//string key, string value
- public class StringKeyValuePair : IKeyValuePair
+ public sealed class StringKeyValuePair : IKeyValuePair, IEquatable
{
[Key]
public string Key { get; set; } = string.Empty;
@@ -136,7 +138,7 @@ public static List FromDictionary(Dictionary
}
- public class DataKeyValuePair : IKeyValuePair
+ public sealed class DataKeyValuePair : IKeyValuePair, IEquatable
{
[Key]
public string Key { get; set; } = string.Empty;
diff --git a/src/InformaticsGateway/Services/HealthLevel7/IMllpClient.cs b/src/Api/Mllp/IMllpClient.cs
old mode 100644
new mode 100755
similarity index 88%
rename from src/InformaticsGateway/Services/HealthLevel7/IMllpClient.cs
rename to src/Api/Mllp/IMllpClient.cs
index 8e38ac846..e8c631c32
--- a/src/InformaticsGateway/Services/HealthLevel7/IMllpClient.cs
+++ b/src/Api/Mllp/IMllpClient.cs
@@ -18,9 +18,9 @@
using System.Threading;
using System.Threading.Tasks;
-namespace Monai.Deploy.InformaticsGateway.Services.HealthLevel7
+namespace Monai.Deploy.InformaticsGateway.Api.Mllp
{
- internal interface IMllpClient : IDisposable
+ public interface IMllpClient : IDisposable
{
Guid ClientId { get; }
@@ -28,4 +28,4 @@ internal interface IMllpClient : IDisposable
Task Start(Func onDisconnect, CancellationToken cancellationToken);
}
-}
\ No newline at end of file
+}
diff --git a/src/InformaticsGateway/Services/HealthLevel7/IMllpExtract.cs b/src/Api/Mllp/IMllpExtract.cs
similarity index 78%
rename from src/InformaticsGateway/Services/HealthLevel7/IMllpExtract.cs
rename to src/Api/Mllp/IMllpExtract.cs
index 8fd8bbf37..2c82fee46 100755
--- a/src/InformaticsGateway/Services/HealthLevel7/IMllpExtract.cs
+++ b/src/Api/Mllp/IMllpExtract.cs
@@ -19,10 +19,12 @@
using HL7.Dotnetcore;
using Monai.Deploy.InformaticsGateway.Api.Storage;
-namespace Monai.Deploy.InformaticsGateway.Services.HealthLevel7
+namespace Monai.Deploy.InformaticsGateway.Api.Mllp
{
- internal interface IMllpExtract
+ public interface IMllpExtract
{
- Task ExtractInfo(Hl7FileStorageMetadata meta, Message message);
+ Task ExtractInfo(Hl7FileStorageMetadata meta, Message message, Hl7ApplicationConfigEntity configItem);
+
+ Task GetConfigItem(Message message);
}
}
diff --git a/src/InformaticsGateway/Services/HealthLevel7/IMllpService.cs b/src/Api/Mllp/IMllpService.cs
similarity index 92%
rename from src/InformaticsGateway/Services/HealthLevel7/IMllpService.cs
rename to src/Api/Mllp/IMllpService.cs
index 6272464b2..d12e1fd28 100755
--- a/src/InformaticsGateway/Services/HealthLevel7/IMllpService.cs
+++ b/src/Api/Mllp/IMllpService.cs
@@ -18,7 +18,7 @@
using System.Threading;
using System.Threading.Tasks;
-namespace Monai.Deploy.InformaticsGateway.Services.HealthLevel7
+namespace Monai.Deploy.InformaticsGateway.Api.Mllp
{
public interface IMllpService
{
diff --git a/src/InformaticsGateway/Services/HealthLevel7/MllpClientResult.cs b/src/Api/Mllp/MllpClientResult.cs
similarity index 91%
rename from src/InformaticsGateway/Services/HealthLevel7/MllpClientResult.cs
rename to src/Api/Mllp/MllpClientResult.cs
index 401875804..36db3b65f 100755
--- a/src/InformaticsGateway/Services/HealthLevel7/MllpClientResult.cs
+++ b/src/Api/Mllp/MllpClientResult.cs
@@ -18,9 +18,9 @@
using System.Collections.Generic;
using HL7.Dotnetcore;
-namespace Monai.Deploy.InformaticsGateway.Services.HealthLevel7
+namespace Monai.Deploy.InformaticsGateway.Api.Mllp
{
- internal class MllpClientResult
+ public class MllpClientResult
{
public IList Messages { get; }
public AggregateException? AggregateException { get; }
diff --git a/src/Api/Monai.Deploy.InformaticsGateway.Api.csproj b/src/Api/Monai.Deploy.InformaticsGateway.Api.csproj
index f4b8450b0..181306f97 100755
--- a/src/Api/Monai.Deploy.InformaticsGateway.Api.csproj
+++ b/src/Api/Monai.Deploy.InformaticsGateway.Api.csproj
@@ -53,6 +53,7 @@
+
diff --git a/src/Api/PlugIns/IInputHL7DataPlugIn.cs b/src/Api/PlugIns/IInputHL7DataPlugIn.cs
new file mode 100755
index 000000000..b44d0f736
--- /dev/null
+++ b/src/Api/PlugIns/IInputHL7DataPlugIn.cs
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+
+using System.Threading.Tasks;
+using HL7.Dotnetcore;
+using Monai.Deploy.InformaticsGateway.Api.Storage;
+
+namespace Monai.Deploy.InformaticsGateway.Api.PlugIns
+{
+ ///
+ /// IInputDataPlugIn enables lightweight data processing over incoming data received from supported data ingestion
+ /// services.
+ /// Refer to for additional details.
+ ///
+ public interface IInputHL7DataPlugIn
+ {
+ string Name { get; }
+
+ Task<(Message hl7Message, FileStorageMetadata fileMetadata)> ExecuteAsync(Message hl7File, FileStorageMetadata fileMetadata);
+ }
+
+}
diff --git a/src/Api/PlugIns/IInputHL7DataPlugInEngine.cs b/src/Api/PlugIns/IInputHL7DataPlugInEngine.cs
new file mode 100755
index 000000000..dc34b976d
--- /dev/null
+++ b/src/Api/PlugIns/IInputHL7DataPlugInEngine.cs
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using HL7.Dotnetcore;
+using Monai.Deploy.InformaticsGateway.Api.Storage;
+
+namespace Monai.Deploy.InformaticsGateway.Api.PlugIns
+{
+ ///
+ /// IInputDataPlugInEngine processes incoming data receivied from various supported services through
+ /// a list of plug-ins based on .
+ /// Rules:
+ ///
+ /// - SCP: A list of plug-ins can be configured with each AET, and each plug-in is executed in the order stored, enabling piping of the incoming data before each file is uploaded to the storage service.
+ /// - Incoming data is processed one file at a time and SHALL not wait for the entire study to arrive.
+ /// - Plug-ins MUST be lightweight and not hinder the upload process.
+ /// - Plug-ins SHALL not accumulate files in memory or storage for bulk processing.
+ ///
+ ///
+ public interface IInputHL7DataPlugInEngine
+ {
+ void Configure(IReadOnlyList pluginAssemblies);
+
+ Task> ExecutePlugInsAsync(Message hl7File, FileStorageMetadata fileMetadata, Hl7ApplicationConfigEntity configItem);
+ }
+}
diff --git a/src/Api/Test/packages.lock.json b/src/Api/Test/packages.lock.json
index c3b2fbbdd..903cc6b49 100755
--- a/src/Api/Test/packages.lock.json
+++ b/src/Api/Test/packages.lock.json
@@ -94,6 +94,11 @@
"System.Threading.Channels": "6.0.0"
}
},
+ "HL7-dotnetcore": {
+ "type": "Transitive",
+ "resolved": "2.36.0",
+ "contentHash": "N1HLMeIqYuY+4O69ItgZJoDBnnpNkK5N2pClceTJ2nFJxsP48iCsA4iz3tm43Yszi4r/vaThoc3UoLBfGP3vKw=="
+ },
"Macross.Json.Extensions": {
"type": "Transitive",
"resolved": "3.0.0",
@@ -1277,6 +1282,7 @@
"monai.deploy.informaticsgateway.api": {
"type": "Project",
"dependencies": {
+ "HL7-dotnetcore": "[2.36.0, )",
"Macross.Json.Extensions": "[3.0.0, )",
"Microsoft.EntityFrameworkCore.Abstractions": "[6.0.25, )",
"Monai.Deploy.InformaticsGateway.Common": "[1.0.0, )",
diff --git a/src/Api/packages.lock.json b/src/Api/packages.lock.json
index 2f0038d42..1a4adf62a 100755
--- a/src/Api/packages.lock.json
+++ b/src/Api/packages.lock.json
@@ -21,6 +21,12 @@
"System.Threading.Channels": "6.0.0"
}
},
+ "HL7-dotnetcore": {
+ "type": "Direct",
+ "requested": "[2.36.0, )",
+ "resolved": "2.36.0",
+ "contentHash": "N1HLMeIqYuY+4O69ItgZJoDBnnpNkK5N2pClceTJ2nFJxsP48iCsA4iz3tm43Yszi4r/vaThoc3UoLBfGP3vKw=="
+ },
"Macross.Json.Extensions": {
"type": "Direct",
"requested": "[3.0.0, )",
diff --git a/src/CLI/Test/packages.lock.json b/src/CLI/Test/packages.lock.json
index 7ae5d5d97..dbdd6f20e 100755
--- a/src/CLI/Test/packages.lock.json
+++ b/src/CLI/Test/packages.lock.json
@@ -137,6 +137,11 @@
"System.Threading.Channels": "6.0.0"
}
},
+ "HL7-dotnetcore": {
+ "type": "Transitive",
+ "resolved": "2.36.0",
+ "contentHash": "N1HLMeIqYuY+4O69ItgZJoDBnnpNkK5N2pClceTJ2nFJxsP48iCsA4iz3tm43Yszi4r/vaThoc3UoLBfGP3vKw=="
+ },
"Macross.Json.Extensions": {
"type": "Transitive",
"resolved": "3.0.0",
@@ -1560,6 +1565,7 @@
"monai.deploy.informaticsgateway.api": {
"type": "Project",
"dependencies": {
+ "HL7-dotnetcore": "[2.36.0, )",
"Macross.Json.Extensions": "[3.0.0, )",
"Microsoft.EntityFrameworkCore.Abstractions": "[6.0.25, )",
"Monai.Deploy.InformaticsGateway.Common": "[1.0.0, )",
diff --git a/src/CLI/packages.lock.json b/src/CLI/packages.lock.json
index 75418ec51..22c1f3e80 100755
--- a/src/CLI/packages.lock.json
+++ b/src/CLI/packages.lock.json
@@ -93,6 +93,11 @@
"System.Threading.Channels": "6.0.0"
}
},
+ "HL7-dotnetcore": {
+ "type": "Transitive",
+ "resolved": "2.36.0",
+ "contentHash": "N1HLMeIqYuY+4O69ItgZJoDBnnpNkK5N2pClceTJ2nFJxsP48iCsA4iz3tm43Yszi4r/vaThoc3UoLBfGP3vKw=="
+ },
"Macross.Json.Extensions": {
"type": "Transitive",
"resolved": "3.0.0",
@@ -541,6 +546,7 @@
"monai.deploy.informaticsgateway.api": {
"type": "Project",
"dependencies": {
+ "HL7-dotnetcore": "[2.36.0, )",
"Macross.Json.Extensions": "[3.0.0, )",
"Microsoft.EntityFrameworkCore.Abstractions": "[6.0.25, )",
"Monai.Deploy.InformaticsGateway.Common": "[1.0.0, )",
diff --git a/src/Client/Test/packages.lock.json b/src/Client/Test/packages.lock.json
index 49b143571..2bbd6ee7a 100755
--- a/src/Client/Test/packages.lock.json
+++ b/src/Client/Test/packages.lock.json
@@ -1826,6 +1826,7 @@
"monai.deploy.informaticsgateway.api": {
"type": "Project",
"dependencies": {
+ "HL7-dotnetcore": "[2.36.0, )",
"Macross.Json.Extensions": "[3.0.0, )",
"Microsoft.EntityFrameworkCore.Abstractions": "[6.0.25, )",
"Monai.Deploy.InformaticsGateway.Common": "[1.0.0, )",
diff --git a/src/Client/packages.lock.json b/src/Client/packages.lock.json
index d3be0afb3..2a3e704e0 100755
--- a/src/Client/packages.lock.json
+++ b/src/Client/packages.lock.json
@@ -43,6 +43,11 @@
"System.Threading.Channels": "6.0.0"
}
},
+ "HL7-dotnetcore": {
+ "type": "Transitive",
+ "resolved": "2.36.0",
+ "contentHash": "N1HLMeIqYuY+4O69ItgZJoDBnnpNkK5N2pClceTJ2nFJxsP48iCsA4iz3tm43Yszi4r/vaThoc3UoLBfGP3vKw=="
+ },
"Macross.Json.Extensions": {
"type": "Transitive",
"resolved": "3.0.0",
@@ -274,6 +279,7 @@
"monai.deploy.informaticsgateway.api": {
"type": "Project",
"dependencies": {
+ "HL7-dotnetcore": "[2.36.0, )",
"Macross.Json.Extensions": "[3.0.0, )",
"Microsoft.EntityFrameworkCore.Abstractions": "[6.0.25, )",
"Monai.Deploy.InformaticsGateway.Common": "[1.0.0, )",
diff --git a/src/Configuration/Test/packages.lock.json b/src/Configuration/Test/packages.lock.json
index 9265712dc..02e67b1eb 100755
--- a/src/Configuration/Test/packages.lock.json
+++ b/src/Configuration/Test/packages.lock.json
@@ -102,6 +102,11 @@
"System.Threading.Channels": "6.0.0"
}
},
+ "HL7-dotnetcore": {
+ "type": "Transitive",
+ "resolved": "2.36.0",
+ "contentHash": "N1HLMeIqYuY+4O69ItgZJoDBnnpNkK5N2pClceTJ2nFJxsP48iCsA4iz3tm43Yszi4r/vaThoc3UoLBfGP3vKw=="
+ },
"Macross.Json.Extensions": {
"type": "Transitive",
"resolved": "3.0.0",
@@ -1290,6 +1295,7 @@
"monai.deploy.informaticsgateway.api": {
"type": "Project",
"dependencies": {
+ "HL7-dotnetcore": "[2.36.0, )",
"Macross.Json.Extensions": "[3.0.0, )",
"Microsoft.EntityFrameworkCore.Abstractions": "[6.0.25, )",
"Monai.Deploy.InformaticsGateway.Common": "[1.0.0, )",
diff --git a/src/Configuration/packages.lock.json b/src/Configuration/packages.lock.json
index 5af67fda9..2b5691080 100755
--- a/src/Configuration/packages.lock.json
+++ b/src/Configuration/packages.lock.json
@@ -43,6 +43,11 @@
"System.Threading.Channels": "6.0.0"
}
},
+ "HL7-dotnetcore": {
+ "type": "Transitive",
+ "resolved": "2.36.0",
+ "contentHash": "N1HLMeIqYuY+4O69ItgZJoDBnnpNkK5N2pClceTJ2nFJxsP48iCsA4iz3tm43Yszi4r/vaThoc3UoLBfGP3vKw=="
+ },
"Macross.Json.Extensions": {
"type": "Transitive",
"resolved": "3.0.0",
@@ -274,6 +279,7 @@
"monai.deploy.informaticsgateway.api": {
"type": "Project",
"dependencies": {
+ "HL7-dotnetcore": "[2.36.0, )",
"Macross.Json.Extensions": "[3.0.0, )",
"Microsoft.EntityFrameworkCore.Abstractions": "[6.0.25, )",
"Monai.Deploy.InformaticsGateway.Common": "[1.0.0, )",
diff --git a/src/Database/Api/Test/packages.lock.json b/src/Database/Api/Test/packages.lock.json
index 93a1cc3a7..65aff269f 100755
--- a/src/Database/Api/Test/packages.lock.json
+++ b/src/Database/Api/Test/packages.lock.json
@@ -76,6 +76,11 @@
"System.Threading.Channels": "6.0.0"
}
},
+ "HL7-dotnetcore": {
+ "type": "Transitive",
+ "resolved": "2.36.0",
+ "contentHash": "N1HLMeIqYuY+4O69ItgZJoDBnnpNkK5N2pClceTJ2nFJxsP48iCsA4iz3tm43Yszi4r/vaThoc3UoLBfGP3vKw=="
+ },
"Macross.Json.Extensions": {
"type": "Transitive",
"resolved": "3.0.0",
@@ -1264,6 +1269,7 @@
"monai.deploy.informaticsgateway.api": {
"type": "Project",
"dependencies": {
+ "HL7-dotnetcore": "[2.36.0, )",
"Macross.Json.Extensions": "[3.0.0, )",
"Microsoft.EntityFrameworkCore.Abstractions": "[6.0.25, )",
"Monai.Deploy.InformaticsGateway.Common": "[1.0.0, )",
diff --git a/src/Database/Api/packages.lock.json b/src/Database/Api/packages.lock.json
index f86d76521..53e07aa40 100755
--- a/src/Database/Api/packages.lock.json
+++ b/src/Database/Api/packages.lock.json
@@ -49,6 +49,11 @@
"System.Threading.Channels": "6.0.0"
}
},
+ "HL7-dotnetcore": {
+ "type": "Transitive",
+ "resolved": "2.36.0",
+ "contentHash": "N1HLMeIqYuY+4O69ItgZJoDBnnpNkK5N2pClceTJ2nFJxsP48iCsA4iz3tm43Yszi4r/vaThoc3UoLBfGP3vKw=="
+ },
"Macross.Json.Extensions": {
"type": "Transitive",
"resolved": "3.0.0",
@@ -280,6 +285,7 @@
"monai.deploy.informaticsgateway.api": {
"type": "Project",
"dependencies": {
+ "HL7-dotnetcore": "[2.36.0, )",
"Macross.Json.Extensions": "[3.0.0, )",
"Microsoft.EntityFrameworkCore.Abstractions": "[6.0.25, )",
"Monai.Deploy.InformaticsGateway.Common": "[1.0.0, )",
diff --git a/src/Database/DatabaseMigrationManager.cs b/src/Database/DatabaseMigrationManager.cs
old mode 100644
new mode 100755
index da35c17a4..72acb2cd8
--- a/src/Database/DatabaseMigrationManager.cs
+++ b/src/Database/DatabaseMigrationManager.cs
@@ -61,7 +61,7 @@ private static Type[] FindMatchingTypesFromAssemblies(Assembly[] assemblies)
var matchingTypes = new List();
foreach (var assembly in assemblies)
{
- var types = assembly.ExportedTypes.Where(p => p.IsAssignableFrom(typeof(IDatabaseMigrationManager)));
+ var types = assembly.ExportedTypes.Where(p => p.IsAssignableFrom(typeof(IDatabaseMigrationManager)) && p.Name != nameof(IDatabaseMigrationManager));
if (types.Any())
{
matchingTypes.AddRange(types);
diff --git a/src/Database/EntityFramework/Migrations/20231204113501_Hl7DEstinationAndConfig.cs b/src/Database/EntityFramework/Migrations/20231204113501_Hl7DEstinationAndConfig.cs
index 7dbf72215..d23d89c28 100755
--- a/src/Database/EntityFramework/Migrations/20231204113501_Hl7DEstinationAndConfig.cs
+++ b/src/Database/EntityFramework/Migrations/20231204113501_Hl7DEstinationAndConfig.cs
@@ -1,4 +1,4 @@
-using System;
+
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
diff --git a/src/Database/EntityFramework/Migrations/20231207154732_Hl7Plugins.Designer.cs b/src/Database/EntityFramework/Migrations/20231207154732_Hl7Plugins.Designer.cs
new file mode 100755
index 000000000..256eb5527
--- /dev/null
+++ b/src/Database/EntityFramework/Migrations/20231207154732_Hl7Plugins.Designer.cs
@@ -0,0 +1,508 @@
+//
+using System;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using Monai.Deploy.InformaticsGateway.Database.EntityFramework;
+
+#nullable disable
+
+namespace Monai.Deploy.InformaticsGateway.Database.Migrations
+{
+ [DbContext(typeof(InformaticsGatewayContext))]
+ [Migration("20231207154732_Hl7Plugins")]
+ partial class Hl7Plugins
+ {
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder.HasAnnotation("ProductVersion", "6.0.25");
+
+ modelBuilder.Entity("Monai.Deploy.InformaticsGateway.Api.Hl7ApplicationConfigEntity", b =>
+ {
+ b.Property("Name")
+ .HasColumnType("TEXT")
+ .HasColumnOrder(0);
+
+ b.Property("DataLink")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("DataMapping")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("DateTimeCreated")
+ .HasColumnType("TEXT");
+
+ b.Property("LastModified")
+ .HasColumnType("TEXT");
+
+ b.Property("PlugInAssemblies")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("SendingId")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.HasKey("Name");
+
+ b.HasIndex(new[] { "Name" }, "idx_hl7_name")
+ .IsUnique();
+
+ b.ToTable("Hl7ApplicationConfig");
+ });
+
+ modelBuilder.Entity("Monai.Deploy.InformaticsGateway.Api.Models.DestinationApplicationEntity", b =>
+ {
+ b.Property("Name")
+ .HasColumnType("TEXT");
+
+ b.Property("AeTitle")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("CreatedBy")
+ .HasColumnType("TEXT");
+
+ b.Property("DateTimeCreated")
+ .HasColumnType("TEXT");
+
+ b.Property("DateTimeUpdated")
+ .HasColumnType("TEXT");
+
+ b.Property("HostIp")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("Port")
+ .HasColumnType("INTEGER");
+
+ b.Property("UpdatedBy")
+ .HasColumnType("TEXT");
+
+ b.HasKey("Name");
+
+ b.HasIndex(new[] { "Name" }, "idx_destination_name")
+ .IsUnique();
+
+ b.HasIndex(new[] { "Name", "AeTitle", "HostIp", "Port" }, "idx_source_all")
+ .IsUnique();
+
+ b.ToTable("DestinationApplicationEntities");
+ });
+
+ modelBuilder.Entity("Monai.Deploy.InformaticsGateway.Api.Models.DicomAssociationInfo", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("TEXT");
+
+ b.Property("CalledAeTitle")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("CallingAeTitle")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("CorrelationId")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("DateTimeCreated")
+ .HasColumnType("TEXT");
+
+ b.Property("DateTimeDisconnected")
+ .HasColumnType("TEXT");
+
+ b.Property("Duration")
+ .HasColumnType("TEXT");
+
+ b.Property("Errors")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("FileCount")
+ .HasColumnType("INTEGER");
+
+ b.Property("PayloadIds")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("RemoteHost")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("RemotePort")
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.ToTable("DicomAssociationHistories");
+ });
+
+ modelBuilder.Entity("Monai.Deploy.InformaticsGateway.Api.Models.ExternalAppDetails", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("TEXT");
+
+ b.Property("CorrelationId")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("DateTimeCreated")
+ .HasColumnType("TEXT");
+
+ b.Property("DestinationFolder")
+ .HasColumnType("TEXT");
+
+ b.Property("ExportTaskID")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("PatientId")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("PatientIdOutBound")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("StudyInstanceUid")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("StudyInstanceUidOutBound")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("WorkflowInstanceId")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.ToTable("ExternalAppDetails");
+ });
+
+ modelBuilder.Entity("Monai.Deploy.InformaticsGateway.Api.Models.HL7DestinationEntity", b =>
+ {
+ b.Property("Name")
+ .HasColumnType("TEXT");
+
+ b.Property("AeTitle")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("CreatedBy")
+ .HasColumnType("TEXT");
+
+ b.Property("DateTimeCreated")
+ .HasColumnType("TEXT");
+
+ b.Property("DateTimeUpdated")
+ .HasColumnType("TEXT");
+
+ b.Property("HostIp")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("Port")
+ .HasColumnType("INTEGER");
+
+ b.Property("UpdatedBy")
+ .HasColumnType("TEXT");
+
+ b.HasKey("Name");
+
+ b.HasIndex(new[] { "Name" }, "idx_destination_name")
+ .IsUnique()
+ .HasDatabaseName("idx_destination_name1");
+
+ b.HasIndex(new[] { "Name", "AeTitle", "HostIp", "Port" }, "idx_source_all")
+ .IsUnique()
+ .HasDatabaseName("idx_source_all1");
+
+ b.ToTable("HL7DestinationEntities");
+ });
+
+ modelBuilder.Entity("Monai.Deploy.InformaticsGateway.Api.Models.MonaiApplicationEntity", b =>
+ {
+ b.Property("Name")
+ .HasColumnType("TEXT")
+ .HasColumnOrder(0);
+
+ b.Property("AeTitle")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("AllowedSopClasses")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("CreatedBy")
+ .HasColumnType("TEXT");
+
+ b.Property("DateTimeCreated")
+ .HasColumnType("TEXT");
+
+ b.Property("DateTimeUpdated")
+ .HasColumnType("TEXT");
+
+ b.Property("Grouping")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("IgnoredSopClasses")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("PlugInAssemblies")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("Timeout")
+ .HasColumnType("INTEGER");
+
+ b.Property("UpdatedBy")
+ .HasColumnType("TEXT");
+
+ b.Property("Workflows")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.HasKey("Name");
+
+ b.HasIndex(new[] { "Name" }, "idx_monaiae_name")
+ .IsUnique();
+
+ b.ToTable("MonaiApplicationEntities");
+ });
+
+ modelBuilder.Entity("Monai.Deploy.InformaticsGateway.Api.Rest.InferenceRequest", b =>
+ {
+ b.Property("InferenceRequestId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("TEXT");
+
+ b.Property("CreatedBy")
+ .HasColumnType("TEXT");
+
+ b.Property("DateTimeCreated")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("InputMetadata")
+ .HasColumnType("TEXT");
+
+ b.Property("InputResources")
+ .HasColumnType("TEXT");
+
+ b.Property("OutputResources")
+ .HasColumnType("TEXT");
+
+ b.Property("Priority")
+ .HasColumnType("INTEGER");
+
+ b.Property("State")
+ .HasColumnType("INTEGER");
+
+ b.Property("Status")
+ .HasColumnType("INTEGER");
+
+ b.Property("TransactionId")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("TryCount")
+ .HasColumnType("INTEGER");
+
+ b.HasKey("InferenceRequestId");
+
+ b.HasIndex(new[] { "InferenceRequestId" }, "idx_inferencerequest_inferencerequestid")
+ .IsUnique();
+
+ b.HasIndex(new[] { "State" }, "idx_inferencerequest_state");
+
+ b.HasIndex(new[] { "TransactionId" }, "idx_inferencerequest_transactionid")
+ .IsUnique();
+
+ b.ToTable("InferenceRequests");
+ });
+
+ modelBuilder.Entity("Monai.Deploy.InformaticsGateway.Api.SourceApplicationEntity", b =>
+ {
+ b.Property("Name")
+ .HasColumnType("TEXT");
+
+ b.Property("AeTitle")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("CreatedBy")
+ .HasColumnType("TEXT");
+
+ b.Property("DateTimeCreated")
+ .HasColumnType("TEXT");
+
+ b.Property("DateTimeUpdated")
+ .HasColumnType("TEXT");
+
+ b.Property("HostIp")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("UpdatedBy")
+ .HasColumnType("TEXT");
+
+ b.HasKey("Name");
+
+ b.HasIndex(new[] { "Name", "AeTitle", "HostIp" }, "idx_source_all")
+ .IsUnique()
+ .HasDatabaseName("idx_source_all2");
+
+ b.HasIndex(new[] { "Name" }, "idx_source_name")
+ .IsUnique();
+
+ b.ToTable("SourceApplicationEntities");
+ });
+
+ modelBuilder.Entity("Monai.Deploy.InformaticsGateway.Api.Storage.Payload", b =>
+ {
+ b.Property("PayloadId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("TEXT");
+
+ b.Property("CorrelationId")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("DataOrigins")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("DataTrigger")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("DateTimeCreated")
+ .HasColumnType("TEXT");
+
+ b.Property("DestinationFolder")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("Files")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("Key")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("MachineName")
+ .HasColumnType("TEXT");
+
+ b.Property("RetryCount")
+ .HasColumnType("INTEGER");
+
+ b.Property("State")
+ .HasColumnType("INTEGER");
+
+ b.Property("TaskId")
+ .HasColumnType("TEXT");
+
+ b.Property("Timeout")
+ .HasColumnType("INTEGER");
+
+ b.Property("WorkflowInstanceId")
+ .HasColumnType("TEXT");
+
+ b.HasKey("PayloadId");
+
+ b.HasIndex(new[] { "CorrelationId", "PayloadId" }, "idx_payload_ids")
+ .IsUnique();
+
+ b.HasIndex(new[] { "State" }, "idx_payload_state");
+
+ b.ToTable("Payloads");
+ });
+
+ modelBuilder.Entity("Monai.Deploy.InformaticsGateway.Api.VirtualApplicationEntity", b =>
+ {
+ b.Property("Name")
+ .HasColumnType("TEXT")
+ .HasColumnOrder(0);
+
+ b.Property("CreatedBy")
+ .HasColumnType("TEXT");
+
+ b.Property("DateTimeCreated")
+ .HasColumnType("TEXT");
+
+ b.Property("DateTimeUpdated")
+ .HasColumnType("TEXT");
+
+ b.Property("PlugInAssemblies")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("UpdatedBy")
+ .HasColumnType("TEXT");
+
+ b.Property("VirtualAeTitle")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("Workflows")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.HasKey("Name");
+
+ b.HasIndex(new[] { "Name" }, "idx_virtualae_name")
+ .IsUnique();
+
+ b.ToTable("VirtualApplicationEntities");
+ });
+
+ modelBuilder.Entity("Monai.Deploy.InformaticsGateway.Database.Api.StorageMetadataWrapper", b =>
+ {
+ b.Property("CorrelationId")
+ .HasColumnType("TEXT");
+
+ b.Property("Identity")
+ .HasColumnType("TEXT");
+
+ b.Property("DateTimeCreated")
+ .HasColumnType("TEXT");
+
+ b.Property("IsUploaded")
+ .HasColumnType("INTEGER");
+
+ b.Property("TypeName")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("Value")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.HasKey("CorrelationId", "Identity");
+
+ b.HasIndex(new[] { "CorrelationId" }, "idx_storagemetadata_correlation");
+
+ b.HasIndex(new[] { "CorrelationId", "Identity" }, "idx_storagemetadata_ids");
+
+ b.HasIndex(new[] { "IsUploaded" }, "idx_storagemetadata_uploaded");
+
+ b.ToTable("StorageMetadataWrapperEntities");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/src/Database/EntityFramework/Migrations/20231207154732_Hl7Plugins.cs b/src/Database/EntityFramework/Migrations/20231207154732_Hl7Plugins.cs
new file mode 100755
index 000000000..c86631267
--- /dev/null
+++ b/src/Database/EntityFramework/Migrations/20231207154732_Hl7Plugins.cs
@@ -0,0 +1,27 @@
+
+using Microsoft.EntityFrameworkCore.Migrations;
+
+#nullable disable
+
+namespace Monai.Deploy.InformaticsGateway.Database.Migrations
+{
+ public partial class Hl7Plugins : Migration
+ {
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.AddColumn(
+ name: "LastModified",
+ table: "Hl7ApplicationConfig",
+ type: "TEXT",
+ nullable: false,
+ defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified));
+ }
+
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropColumn(
+ name: "LastModified",
+ table: "Hl7ApplicationConfig");
+ }
+ }
+}
diff --git a/src/Database/EntityFramework/Migrations/InformaticsGatewayContextModelSnapshot.cs b/src/Database/EntityFramework/Migrations/InformaticsGatewayContextModelSnapshot.cs
index cec0093f1..8eb10b0df 100755
--- a/src/Database/EntityFramework/Migrations/InformaticsGatewayContextModelSnapshot.cs
+++ b/src/Database/EntityFramework/Migrations/InformaticsGatewayContextModelSnapshot.cs
@@ -34,6 +34,9 @@ protected override void BuildModel(ModelBuilder modelBuilder)
b.Property("DateTimeCreated")
.HasColumnType("TEXT");
+ b.Property("LastModified")
+ .HasColumnType("TEXT");
+
b.Property("PlugInAssemblies")
.IsRequired()
.HasColumnType("TEXT");
diff --git a/src/Database/EntityFramework/Repositories/Hl7ApplicationConfigRepository.cs b/src/Database/EntityFramework/Repositories/Hl7ApplicationConfigRepository.cs
old mode 100644
new mode 100755
index 7f6711ab4..898181503
--- a/src/Database/EntityFramework/Repositories/Hl7ApplicationConfigRepository.cs
+++ b/src/Database/EntityFramework/Repositories/Hl7ApplicationConfigRepository.cs
@@ -63,11 +63,7 @@ public Task DeleteAsync(string id, CancellationToken
{
return _retryPolicy.ExecuteAsync(async () =>
{
- var entity = await GetByIdAsync(id).ConfigureAwait(false);
- if (entity is null)
- {
- throw new DatabaseException("Failed to delete entity.");
- }
+ var entity = await GetByIdAsync(id).ConfigureAwait(false) ?? throw new DatabaseException("Failed to delete entity.");
var result = _dataset.Remove(entity);
await _informaticsGatewayContext.SaveChangesAsync(cancellationToken).ConfigureAwait(false);
return result.Entity;
diff --git a/src/Database/EntityFramework/Test/packages.lock.json b/src/Database/EntityFramework/Test/packages.lock.json
index 40ce6d70b..95ac88e42 100755
--- a/src/Database/EntityFramework/Test/packages.lock.json
+++ b/src/Database/EntityFramework/Test/packages.lock.json
@@ -102,6 +102,11 @@
"System.Threading.Channels": "6.0.0"
}
},
+ "HL7-dotnetcore": {
+ "type": "Transitive",
+ "resolved": "2.36.0",
+ "contentHash": "N1HLMeIqYuY+4O69ItgZJoDBnnpNkK5N2pClceTJ2nFJxsP48iCsA4iz3tm43Yszi4r/vaThoc3UoLBfGP3vKw=="
+ },
"Macross.Json.Extensions": {
"type": "Transitive",
"resolved": "3.0.0",
@@ -1468,6 +1473,7 @@
"monai.deploy.informaticsgateway.api": {
"type": "Project",
"dependencies": {
+ "HL7-dotnetcore": "[2.36.0, )",
"Macross.Json.Extensions": "[3.0.0, )",
"Microsoft.EntityFrameworkCore.Abstractions": "[6.0.25, )",
"Monai.Deploy.InformaticsGateway.Common": "[1.0.0, )",
diff --git a/src/Database/EntityFramework/packages.lock.json b/src/Database/EntityFramework/packages.lock.json
index c80430fab..91f7b6eac 100755
--- a/src/Database/EntityFramework/packages.lock.json
+++ b/src/Database/EntityFramework/packages.lock.json
@@ -110,6 +110,11 @@
"System.Threading.Channels": "6.0.0"
}
},
+ "HL7-dotnetcore": {
+ "type": "Transitive",
+ "resolved": "2.36.0",
+ "contentHash": "N1HLMeIqYuY+4O69ItgZJoDBnnpNkK5N2pClceTJ2nFJxsP48iCsA4iz3tm43Yszi4r/vaThoc3UoLBfGP3vKw=="
+ },
"Humanizer.Core": {
"type": "Transitive",
"resolved": "2.8.26",
@@ -472,6 +477,7 @@
"monai.deploy.informaticsgateway.api": {
"type": "Project",
"dependencies": {
+ "HL7-dotnetcore": "[2.36.0, )",
"Macross.Json.Extensions": "[3.0.0, )",
"Microsoft.EntityFrameworkCore.Abstractions": "[6.0.25, )",
"Monai.Deploy.InformaticsGateway.Common": "[1.0.0, )",
diff --git a/src/Database/MongoDB/Integration.Test/packages.lock.json b/src/Database/MongoDB/Integration.Test/packages.lock.json
index 8ad2d5e4f..c0cbcf5cf 100755
--- a/src/Database/MongoDB/Integration.Test/packages.lock.json
+++ b/src/Database/MongoDB/Integration.Test/packages.lock.json
@@ -110,6 +110,11 @@
"System.Threading.Channels": "6.0.0"
}
},
+ "HL7-dotnetcore": {
+ "type": "Transitive",
+ "resolved": "2.36.0",
+ "contentHash": "N1HLMeIqYuY+4O69ItgZJoDBnnpNkK5N2pClceTJ2nFJxsP48iCsA4iz3tm43Yszi4r/vaThoc3UoLBfGP3vKw=="
+ },
"Macross.Json.Extensions": {
"type": "Transitive",
"resolved": "3.0.0",
@@ -1395,6 +1400,7 @@
"monai.deploy.informaticsgateway.api": {
"type": "Project",
"dependencies": {
+ "HL7-dotnetcore": "[2.36.0, )",
"Macross.Json.Extensions": "[3.0.0, )",
"Microsoft.EntityFrameworkCore.Abstractions": "[6.0.25, )",
"Monai.Deploy.InformaticsGateway.Common": "[1.0.0, )",
diff --git a/src/Database/MongoDB/Repositories/HL7DestinationEntityRepository.cs b/src/Database/MongoDB/Repositories/HL7DestinationEntityRepository.cs
old mode 100644
new mode 100755
index 37676d848..feb428f09
--- a/src/Database/MongoDB/Repositories/HL7DestinationEntityRepository.cs
+++ b/src/Database/MongoDB/Repositories/HL7DestinationEntityRepository.cs
@@ -53,7 +53,10 @@ public HL7DestinationEntityRepository(
_scope = serviceScopeFactory.CreateScope();
_retryPolicy = Policy.Handle().WaitAndRetryAsync(
options.Value.Retries.RetryDelays,
- (exception, timespan, count, context) => _logger.DatabaseErrorRetry(timespan, count, exception));
+ (exception, timespan, count, context) =>
+ {
+ _logger.DatabaseErrorRetry(timespan, count, exception);
+ });
var mongoDbClient = _scope.ServiceProvider.GetRequiredService();
var mongoDatabase = mongoDbClient.GetDatabase(mongoDbOptions.Value.DatabaseName);
diff --git a/src/Database/MongoDB/Repositories/Hl7ApplicationConfigRepository.cs b/src/Database/MongoDB/Repositories/Hl7ApplicationConfigRepository.cs
index b7a35ce5e..8b23cf257 100755
--- a/src/Database/MongoDB/Repositories/Hl7ApplicationConfigRepository.cs
+++ b/src/Database/MongoDB/Repositories/Hl7ApplicationConfigRepository.cs
@@ -49,7 +49,10 @@ public Hl7ApplicationConfigRepository(IServiceScopeFactory serviceScopeFactory,
_scope = serviceScopeFactory.CreateScope();
_retryPolicy = Policy.Handle().WaitAndRetryAsync(
options.Value.Retries.RetryDelays,
- (exception, timespan, count, context) => _logger.DatabaseErrorRetry(timespan, count, exception));
+ (exception, timespan, count, context) =>
+ {
+ _logger.DatabaseErrorRetry(timespan, count, exception);
+ });
var mongoDbClient = _scope.ServiceProvider.GetRequiredService();
var mongoDatabase = mongoDbClient.GetDatabase(options.Value.DatabaseName);
diff --git a/src/Database/MongoDB/packages.lock.json b/src/Database/MongoDB/packages.lock.json
index b248f4c03..cd453a7c0 100755
--- a/src/Database/MongoDB/packages.lock.json
+++ b/src/Database/MongoDB/packages.lock.json
@@ -69,6 +69,11 @@
"System.Threading.Channels": "6.0.0"
}
},
+ "HL7-dotnetcore": {
+ "type": "Transitive",
+ "resolved": "2.36.0",
+ "contentHash": "N1HLMeIqYuY+4O69ItgZJoDBnnpNkK5N2pClceTJ2nFJxsP48iCsA4iz3tm43Yszi4r/vaThoc3UoLBfGP3vKw=="
+ },
"Macross.Json.Extensions": {
"type": "Transitive",
"resolved": "3.0.0",
@@ -373,6 +378,7 @@
"monai.deploy.informaticsgateway.api": {
"type": "Project",
"dependencies": {
+ "HL7-dotnetcore": "[2.36.0, )",
"Macross.Json.Extensions": "[3.0.0, )",
"Microsoft.EntityFrameworkCore.Abstractions": "[6.0.25, )",
"Monai.Deploy.InformaticsGateway.Common": "[1.0.0, )",
diff --git a/src/Database/packages.lock.json b/src/Database/packages.lock.json
index 9fa7405f1..af4bbeb2a 100755
--- a/src/Database/packages.lock.json
+++ b/src/Database/packages.lock.json
@@ -94,6 +94,11 @@
"System.Threading.Channels": "6.0.0"
}
},
+ "HL7-dotnetcore": {
+ "type": "Transitive",
+ "resolved": "2.36.0",
+ "contentHash": "N1HLMeIqYuY+4O69ItgZJoDBnnpNkK5N2pClceTJ2nFJxsP48iCsA4iz3tm43Yszi4r/vaThoc3UoLBfGP3vKw=="
+ },
"Humanizer.Core": {
"type": "Transitive",
"resolved": "2.8.26",
@@ -609,6 +614,7 @@
"monai.deploy.informaticsgateway.api": {
"type": "Project",
"dependencies": {
+ "HL7-dotnetcore": "[2.36.0, )",
"Macross.Json.Extensions": "[3.0.0, )",
"Microsoft.EntityFrameworkCore.Abstractions": "[6.0.25, )",
"Monai.Deploy.InformaticsGateway.Common": "[1.0.0, )",
diff --git a/src/InformaticsGateway/Logging/Log.800.Hl7Service.cs b/src/InformaticsGateway/Logging/Log.800.Hl7Service.cs
index a3235b8a0..9e6de4683 100755
--- a/src/InformaticsGateway/Logging/Log.800.Hl7Service.cs
+++ b/src/InformaticsGateway/Logging/Log.800.Hl7Service.cs
@@ -101,5 +101,12 @@ public static partial class Log
[LoggerMessage(EventId = 826, Level = LogLevel.Debug, Message = "HL7 meassage sent received {ack}")]
public static partial void Hl7MessageSent(this ILogger logger, string ack);
+
+ [LoggerMessage(EventId = 827, Level = LogLevel.Warning, Message = "HL7 plugin loading exceptions")]
+ public static partial void HL7PluginLoadingExceptions(this ILogger logger, Exception ex);
+
+ [LoggerMessage(EventId = 828, Level = LogLevel.Information, Message = "HL7 message recieved. {message}")]
+ public static partial void Hl7MessageReceieved(this ILogger logger, string message);
+
}
}
diff --git a/src/InformaticsGateway/Program.cs b/src/InformaticsGateway/Program.cs
index 9586ee88c..be43e4ade 100755
--- a/src/InformaticsGateway/Program.cs
+++ b/src/InformaticsGateway/Program.cs
@@ -25,6 +25,7 @@
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
+using Monai.Deploy.InformaticsGateway.Api.Mllp;
using Monai.Deploy.InformaticsGateway.Api.PlugIns;
using Monai.Deploy.InformaticsGateway.Common;
using Monai.Deploy.InformaticsGateway.Configuration;
@@ -35,7 +36,6 @@
using Monai.Deploy.InformaticsGateway.Services.DicomWeb;
using Monai.Deploy.InformaticsGateway.Services.Export;
using Monai.Deploy.InformaticsGateway.Services.Fhir;
-using Monai.Deploy.InformaticsGateway.Services.HealthLevel7;
using Monai.Deploy.InformaticsGateway.Services.Http;
using Monai.Deploy.InformaticsGateway.Services.Scp;
using Monai.Deploy.InformaticsGateway.Services.Scu;
@@ -116,8 +116,10 @@ internal static IHostBuilder CreateHostBuilder(string[] args) =>
services.AddScoped();
services.AddScoped();
services.AddScoped();
+ services.AddScoped();
services.AddScoped, InputDataPlugInEngineFactory>();
services.AddScoped, OutputDataPlugInEngineFactory>();
+ services.AddScoped, InputHL7DataPlugInEngineFactory>();
services.AddMonaiDeployStorageService(hostContext.Configuration!.GetSection("InformaticsGateway:storage:serviceAssemblyName").Value, Monai.Deploy.Storage.HealthCheckOptions.ServiceHealthCheck);
@@ -152,7 +154,6 @@ internal static IHostBuilder CreateHostBuilder(string[] args) =>
.AddHttpClient("fhir", configure => configure.Timeout = timeout)
.SetHandlerLifetime(timeout);
-#pragma warning disable CS8603 // Possible null reference return.
services.AddHostedService();
services.AddHostedService();
services.AddHostedService();
@@ -164,7 +165,6 @@ internal static IHostBuilder CreateHostBuilder(string[] args) =>
services.AddHostedService();
services.AddHostedService();
services.AddHostedService();
-#pragma warning restore CS8603 // Possible null reference return.
})
.ConfigureWebHostDefaults(webBuilder =>
diff --git a/src/InformaticsGateway/Services/Common/IInputDataPluginEngineFactory.cs b/src/InformaticsGateway/Services/Common/IInputDataPluginEngineFactory.cs
old mode 100644
new mode 100755
index 4f122da6f..880eaef95
--- a/src/InformaticsGateway/Services/Common/IInputDataPluginEngineFactory.cs
+++ b/src/InformaticsGateway/Services/Common/IInputDataPluginEngineFactory.cs
@@ -125,4 +125,11 @@ public OutputDataPlugInEngineFactory(IFileSystem fileSystem, ILogger
+ {
+ public InputHL7DataPlugInEngineFactory(IFileSystem fileSystem, ILogger> logger) : base(fileSystem, logger)
+ {
+ }
+ }
}
diff --git a/src/InformaticsGateway/Services/Common/InputHL7DataPlugInEngine.cs b/src/InformaticsGateway/Services/Common/InputHL7DataPlugInEngine.cs
new file mode 100755
index 000000000..a4abac3f0
--- /dev/null
+++ b/src/InformaticsGateway/Services/Common/InputHL7DataPlugInEngine.cs
@@ -0,0 +1,92 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using HL7.Dotnetcore;
+using Microsoft.Extensions.Logging;
+using Monai.Deploy.InformaticsGateway.Api;
+using Monai.Deploy.InformaticsGateway.Api.PlugIns;
+using Monai.Deploy.InformaticsGateway.Api.Storage;
+using Monai.Deploy.InformaticsGateway.Common;
+using Monai.Deploy.InformaticsGateway.Logging;
+
+namespace Monai.Deploy.InformaticsGateway.Services.Common
+{
+ public class InputHL7DataPlugInEngine : IInputHL7DataPlugInEngine
+ {
+ private readonly IServiceProvider _serviceProvider;
+ private readonly ILogger _logger;
+ private IReadOnlyList? _plugsins;
+
+ public InputHL7DataPlugInEngine(IServiceProvider serviceProvider, ILogger logger)
+ {
+ _serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider));
+ _logger = logger ?? throw new ArgumentNullException(nameof(logger));
+ }
+
+ public void Configure(IReadOnlyList pluginAssemblies)
+ {
+ _plugsins = LoadPlugIns(_serviceProvider, pluginAssemblies);
+ }
+
+ public async Task> ExecutePlugInsAsync(Message hl7File, FileStorageMetadata fileMetadata, Hl7ApplicationConfigEntity? configItem)
+ {
+ if (_plugsins == null)
+ {
+ throw new PlugInInitializationException("InputHL7DataPlugInEngine not configured, please call Configure() first.");
+ }
+
+ foreach (var plugin in _plugsins)
+ {
+ if (configItem is not null && configItem.PlugInAssemblies.Exists(a => a.StartsWith(plugin.ToString()!)))
+ {
+ _logger.ExecutingInputDataPlugIn(plugin.Name);
+ (hl7File, fileMetadata) = await plugin.ExecuteAsync(hl7File, fileMetadata).ConfigureAwait(false);
+ }
+ }
+
+ return new Tuple(hl7File, fileMetadata);
+ }
+
+ private IReadOnlyList LoadPlugIns(IServiceProvider serviceProvider, IReadOnlyList pluginAssemblies)
+ {
+ var exceptions = new List();
+ var list = new List();
+ foreach (var plugin in pluginAssemblies)
+ {
+ try
+ {
+ _logger.AddingInputDataPlugIn(plugin);
+ list.Add(typeof(IInputHL7DataPlugIn).CreateInstance(serviceProvider, typeString: plugin));
+ }
+ catch (Exception ex)
+ {
+ exceptions.Add(new PlugInLoadingException($"Error loading plug-in '{plugin}'.", ex));
+ }
+ }
+
+ if (exceptions.Any())
+ {
+ throw new AggregateException("Error loading plug-in(s).", exceptions);
+ }
+
+ return list;
+ }
+ }
+}
diff --git a/src/InformaticsGateway/Services/Common/OutputDataPluginEngine.cs b/src/InformaticsGateway/Services/Common/OutputDataPluginEngine.cs
index ecbf77a93..a497862dc 100755
--- a/src/InformaticsGateway/Services/Common/OutputDataPluginEngine.cs
+++ b/src/InformaticsGateway/Services/Common/OutputDataPluginEngine.cs
@@ -61,7 +61,7 @@ public async Task ExecutePlugInsAsync(ExportRequestDat
(dicomFile, exportRequestDataMessage) = await plugin.ExecuteAsync(dicomFile, exportRequestDataMessage).ConfigureAwait(false);
}
using var ms = new MemoryStream();
- await dicomFile.SaveAsync(ms);
+ await dicomFile.SaveAsync(ms).ConfigureAwait(false);
exportRequestDataMessage.SetData(ms.ToArray());
return exportRequestDataMessage;
diff --git a/src/InformaticsGateway/Services/Export/ExportServiceBase.cs b/src/InformaticsGateway/Services/Export/ExportServiceBase.cs
index 935f87817..b6f73b1c6 100755
--- a/src/InformaticsGateway/Services/Export/ExportServiceBase.cs
+++ b/src/InformaticsGateway/Services/Export/ExportServiceBase.cs
@@ -138,7 +138,6 @@ public async Task StopAsync(CancellationToken cancellationToken)
await Task.Delay(250).ConfigureAwait(false);
#pragma warning restore CA2016 // Forward the 'CancellationToken' parameter to methods
_cancellationTokenSource.Dispose();
- return;
}
private void SetupPolling()
@@ -147,7 +146,7 @@ private void SetupPolling()
_logger.ExportEventSubscription(ServiceName, RoutingKey);
}
- protected async Task OnMessageReceivedCallback(MessageReceivedEventArgs eventArgs)
+ protected virtual async Task OnMessageReceivedCallback(MessageReceivedEventArgs eventArgs)
{
using var loggerScope = _logger.BeginScope(new Messaging.Common.LoggingDataDictionary {
{ "ThreadId", Environment.CurrentManagedThreadId },
diff --git a/src/InformaticsGateway/Services/Export/Hl7ExportService.cs b/src/InformaticsGateway/Services/Export/Hl7ExportService.cs
index 16ed9a345..0e39217d1 100755
--- a/src/InformaticsGateway/Services/Export/Hl7ExportService.cs
+++ b/src/InformaticsGateway/Services/Export/Hl7ExportService.cs
@@ -28,7 +28,7 @@
using Monai.Deploy.InformaticsGateway.Configuration;
using Monai.Deploy.InformaticsGateway.Database.Api.Repositories;
using Monai.Deploy.InformaticsGateway.Logging;
-using Monai.Deploy.InformaticsGateway.Services.HealthLevel7;
+using Monai.Deploy.InformaticsGateway.Api.Mllp;
using Monai.Deploy.Messaging.Common;
using Polly;
@@ -159,5 +159,6 @@ protected override Task ExecuteOutputDataEngineCallbac
{
return Task.FromResult(exportDataRequest);
}
+
}
}
diff --git a/src/InformaticsGateway/Services/HealthLevel7/IMllpClientFactory.cs b/src/InformaticsGateway/Services/HealthLevel7/IMllpClientFactory.cs
index fe2c1b8a5..3640227a2 100755
--- a/src/InformaticsGateway/Services/HealthLevel7/IMllpClientFactory.cs
+++ b/src/InformaticsGateway/Services/HealthLevel7/IMllpClientFactory.cs
@@ -18,7 +18,7 @@
using Monai.Deploy.InformaticsGateway.Configuration;
using Monai.Deploy.InformaticsGateway.Services.Common;
-namespace Monai.Deploy.InformaticsGateway.Services.HealthLevel7
+namespace Monai.Deploy.InformaticsGateway.Api.Mllp
{
internal interface IMllpClientFactory
{
diff --git a/src/InformaticsGateway/Services/HealthLevel7/MllpClient.cs b/src/InformaticsGateway/Services/HealthLevel7/MllpClient.cs
index b3c87372b..520043b0d 100755
--- a/src/InformaticsGateway/Services/HealthLevel7/MllpClient.cs
+++ b/src/InformaticsGateway/Services/HealthLevel7/MllpClient.cs
@@ -23,12 +23,12 @@
using Ardalis.GuardClauses;
using HL7.Dotnetcore;
using Microsoft.Extensions.Logging;
-using Monai.Deploy.InformaticsGateway.Api;
using Monai.Deploy.InformaticsGateway.Configuration;
using Monai.Deploy.InformaticsGateway.Logging;
using Monai.Deploy.InformaticsGateway.Services.Common;
+using Monai.Deploy.InformaticsGateway.Services.HealthLevel7;
-namespace Monai.Deploy.InformaticsGateway.Services.HealthLevel7
+namespace Monai.Deploy.InformaticsGateway.Api.Mllp
{
internal sealed class MllpClient : IMllpClient
{
diff --git a/src/InformaticsGateway/Services/HealthLevel7/MllpExtract.cs b/src/InformaticsGateway/Services/HealthLevel7/MllpExtract.cs
index d27e7a71e..e579db251 100755
--- a/src/InformaticsGateway/Services/HealthLevel7/MllpExtract.cs
+++ b/src/InformaticsGateway/Services/HealthLevel7/MllpExtract.cs
@@ -22,15 +22,14 @@
using FellowOakDicom;
using HL7.Dotnetcore;
using Microsoft.Extensions.Logging;
-using Monai.Deploy.InformaticsGateway.Api;
using Monai.Deploy.InformaticsGateway.Api.Models;
using Monai.Deploy.InformaticsGateway.Api.Storage;
using Monai.Deploy.InformaticsGateway.Database.Api.Repositories;
using Monai.Deploy.InformaticsGateway.Logging;
-namespace Monai.Deploy.InformaticsGateway.Services.HealthLevel7
+namespace Monai.Deploy.InformaticsGateway.Api.Mllp
{
- internal sealed class MllpExtract : IMllpExtract
+ public sealed class MllpExtract : IMllpExtract
{
private readonly ILogger _logger;
private readonly IHl7ApplicationConfigRepository _hl7ApplicationConfigRepository;
@@ -44,25 +43,10 @@ public MllpExtract(IHl7ApplicationConfigRepository hl7ApplicationConfigRepositor
}
- public async Task ExtractInfo(Hl7FileStorageMetadata meta, Message message)
+ public async Task ExtractInfo(Hl7FileStorageMetadata meta, Message message, Hl7ApplicationConfigEntity configItem)
{
try
{
- // load the config
- var config = await _hl7ApplicationConfigRepository.GetAllAsync().ConfigureAwait(false);
- if (config == null)
- {
- _logger.Hl7NoConfig();
- return message;
- }
- _logger.Hl7ConfigLoaded($"Config: {config}");
- // get config for vendorId
- var configItem = GetConfig(config, message);
- if (configItem == null)
- {
- _logger.Hl7NoMatchingConfig(message.HL7Message);
- return message;
- }
// extract data for the given fields
// Use Id to get record from Db
var details = await GetExtAppDetails(configItem, message).ConfigureAwait(false);
@@ -94,6 +78,26 @@ public async Task ExtractInfo(Hl7FileStorageMetadata meta, Message mess
return message;
}
+ public async Task GetConfigItem(Message message)
+ {
+ // load the config
+ var config = await _hl7ApplicationConfigRepository.GetAllAsync().ConfigureAwait(false);
+ if (config == null)
+ {
+ _logger.Hl7NoConfig();
+ return null;
+ }
+ _logger.Hl7ConfigLoaded($"Config: {config}");
+ // get config for vendorId
+ var configItem = GetConfig(config, message);
+ if (configItem == null)
+ {
+ _logger.Hl7NoMatchingConfig(message.HL7Message);
+ return null;
+ }
+ return configItem;
+ }
+
private async Task GetExtAppDetails(Hl7ApplicationConfigEntity hl7ApplicationConfigEntity, Message message)
{
var tagId = message.GetValue(hl7ApplicationConfigEntity.DataLink.Key);
@@ -101,9 +105,9 @@ public async Task ExtractInfo(Hl7FileStorageMetadata meta, Message mess
switch (type)
{
case DataLinkType.PatientId:
- return await _externalAppDetailsRepository.GetByPatientIdOutboundAsync(tagId, new CancellationToken()).ConfigureAwait(false); ;
+ return await _externalAppDetailsRepository.GetByPatientIdOutboundAsync(tagId, new CancellationToken()).ConfigureAwait(false);
case DataLinkType.StudyInstanceUid:
- return await _externalAppDetailsRepository.GetByStudyIdOutboundAsync(tagId, new CancellationToken()).ConfigureAwait(false); ;
+ return await _externalAppDetailsRepository.GetByStudyIdOutboundAsync(tagId, new CancellationToken()).ConfigureAwait(false);
default:
break;
}
@@ -115,6 +119,7 @@ public async Task 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;
diff --git a/src/InformaticsGateway/Services/HealthLevel7/MllpService.cs b/src/InformaticsGateway/Services/HealthLevel7/MllpService.cs
index 8a4a99cd4..b105b58ec 100755
--- a/src/InformaticsGateway/Services/HealthLevel7/MllpService.cs
+++ b/src/InformaticsGateway/Services/HealthLevel7/MllpService.cs
@@ -18,6 +18,7 @@
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO.Abstractions;
+using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
@@ -29,17 +30,20 @@
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
+using Monai.Deploy.InformaticsGateway.Api.PlugIns;
using Monai.Deploy.InformaticsGateway.Api.Rest;
using Monai.Deploy.InformaticsGateway.Api.Storage;
using Monai.Deploy.InformaticsGateway.Common;
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.Connectors;
+using Monai.Deploy.InformaticsGateway.Services.HealthLevel7;
using Monai.Deploy.InformaticsGateway.Services.Storage;
using Monai.Deploy.Messaging.Events;
-namespace Monai.Deploy.InformaticsGateway.Services.HealthLevel7
+namespace Monai.Deploy.InformaticsGateway.Api.Mllp
{
internal sealed class MllpService : IMllpService, IHostedService, IDisposable, IMonaiService
{
@@ -56,6 +60,9 @@ internal sealed class MllpService : IMllpService, IHostedService, IDisposable, I
private readonly IStorageInfoProvider _storageInfoProvider;
private readonly ConcurrentDictionary _activeTasks;
private readonly IMllpExtract _mIIpExtract;
+ private readonly IInputHL7DataPlugInEngine _inputHL7DataPlugInEngine;
+ private readonly IHl7ApplicationConfigRepository _hl7ApplicationConfigRepository;
+ private DateTime _lastConfigRead = new(2000, 1, 1, 0, 0, 0, DateTimeKind.Utc);
public int ActiveConnections
{
@@ -91,6 +98,8 @@ public MllpService(IServiceScopeFactory serviceScopeFactory,
_storageInfoProvider = serviceScope.ServiceProvider.GetService() ?? throw new ServiceNotFoundException(nameof(IStorageInfoProvider));
_mIIpExtract = serviceScope.ServiceProvider.GetService() ?? throw new ServiceNotFoundException(nameof(IMllpExtract));
_activeTasks = new ConcurrentDictionary();
+ _inputHL7DataPlugInEngine = serviceScope.ServiceProvider.GetService() ?? throw new ServiceNotFoundException(nameof(IInputHL7DataPlugInEngine));
+ _hl7ApplicationConfigRepository = serviceScope.ServiceProvider.GetService() ?? throw new ServiceNotFoundException(nameof(IHl7ApplicationConfigRepository));
}
public Task StartAsync(CancellationToken cancellationToken)
@@ -170,12 +179,21 @@ private async Task OnDisconnect(IMllpClient client, MllpClientResult result)
Guard.Against.Null(client, nameof(client));
Guard.Against.Null(result, nameof(result));
+ await ConfigurePlugInEngine().ConfigureAwait(false);
+
try
{
foreach (var message in result.Messages)
{
+ var newMessage = message;
var hl7Filemetadata = new Hl7FileStorageMetadata(client.ClientId.ToString(), DataService.HL7, client.ClientIp);
- var newMessage = await _mIIpExtract.ExtractInfo(hl7Filemetadata, message).ConfigureAwait(false);
+ var configItem = await _mIIpExtract.GetConfigItem(message).ConfigureAwait(false);
+ if (configItem is not null)
+ {
+ await _inputHL7DataPlugInEngine.ExecutePlugInsAsync(message, hl7Filemetadata, configItem).ConfigureAwait(false);
+ newMessage = await _mIIpExtract.ExtractInfo(hl7Filemetadata, message, configItem).ConfigureAwait(false);
+ }
+
await hl7Filemetadata.SetDataStream(newMessage.HL7Message, _configuration.Value.Storage.TemporaryDataStorage, _fileSystem, _configuration.Value.Storage.LocalTemporaryStoragePath).ConfigureAwait(false);
var payloadId = await _payloadAssembler.Queue(client.ClientId.ToString(), hl7Filemetadata, new DataOrigin { DataService = DataService.HL7, Source = client.ClientIp, Destination = FileStorageMetadata.IpAddress() }).ConfigureAwait(false);
hl7Filemetadata.PayloadId ??= payloadId.ToString();
@@ -194,6 +212,31 @@ private async Task OnDisconnect(IMllpClient client, MllpClientResult result)
}
}
+ private async Task ConfigurePlugInEngine()
+ {
+ var configs = await _hl7ApplicationConfigRepository.GetAllAsync().ConfigureAwait(false);
+ if (configs is not null && configs.Any() && configs.Max(c => c.LastModified) > _lastConfigRead)
+ {
+ var pluginAssemblies = new List();
+ foreach (var config in configs.Where(p => p.PlugInAssemblies?.Count > 0))
+ {
+ try
+ {
+ pluginAssemblies.AddRange(config.PlugInAssemblies.Where(p => pluginAssemblies.Contains(p) is false));
+ }
+ catch (Exception ex)
+ {
+ _logger.HL7PluginLoadingExceptions(ex);
+ }
+ }
+ if (pluginAssemblies.Any())
+ {
+ _inputHL7DataPlugInEngine.Configure(pluginAssemblies);
+ }
+ }
+ _lastConfigRead = DateTime.UtcNow;
+ }
+
private void WaitUntilAvailable(int maximumNumberOfConnections)
{
var count = 0;
diff --git a/src/InformaticsGateway/Services/Http/Startup.cs b/src/InformaticsGateway/Services/Http/Startup.cs
index dfc6dc5e1..6f0779ebd 100755
--- a/src/InformaticsGateway/Services/Http/Startup.cs
+++ b/src/InformaticsGateway/Services/Http/Startup.cs
@@ -44,10 +44,8 @@ public Startup(IConfiguration configuration)
public IConfiguration Configuration { get; }
-#pragma warning disable CA1822 // Mark members as static
public void ConfigureServices(IServiceCollection services)
-#pragma warning restore CA1822 // Mark members as static
{
services.AddHttpContextAccessor();
services.AddControllers(opts =>
diff --git a/src/InformaticsGateway/Services/Scp/ApplicationEntityHandler.cs b/src/InformaticsGateway/Services/Scp/ApplicationEntityHandler.cs
index 411657c86..4946bc6ac 100755
--- a/src/InformaticsGateway/Services/Scp/ApplicationEntityHandler.cs
+++ b/src/InformaticsGateway/Services/Scp/ApplicationEntityHandler.cs
@@ -112,7 +112,7 @@ public async Task HandleInstanceAsync(DicomCStoreRequest request, string
_logger.InstanceIgnoredWIthMatchingSopClassUid(request.SOPClassUID.UID);
return string.Empty;
}
- ExternalAppDetails? storedDetails = null;
+ ExternalAppDetails? storedDetails;
diff --git a/src/InformaticsGateway/Test/Plug-ins/TestInputHL7DataPlugs.cs b/src/InformaticsGateway/Test/Plug-ins/TestInputHL7DataPlugs.cs
new file mode 100755
index 000000000..c24e93270
--- /dev/null
+++ b/src/InformaticsGateway/Test/Plug-ins/TestInputHL7DataPlugs.cs
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+using System.Reflection;
+using HL7.Dotnetcore;
+using Monai.Deploy.InformaticsGateway.Api.PlugIns;
+using Monai.Deploy.InformaticsGateway.Api.Storage;
+
+namespace Monai.Deploy.InformaticsGateway.Test.PlugIns
+{
+ [PlugInName("TestInputHL7DataPlugInAddWorkflow")]
+ public class TestInputHL7DataPlugInAddWorkflow : IInputHL7DataPlugIn
+ {
+ public static readonly string TestString = "HOSPITAL changed!";
+
+ public string Name => GetType().GetCustomAttribute()?.Name ?? GetType().Name;
+
+ public Task<(Message hl7Message, FileStorageMetadata fileMetadata)> ExecuteAsync(Message hl7File, FileStorageMetadata fileMetadata)
+ {
+ hl7File.SetValue("MSH.3", TestString);
+ fileMetadata.Workflows.Add(TestString);
+ return Task.FromResult((hl7File, fileMetadata));
+ }
+ }
+}
diff --git a/src/InformaticsGateway/Test/Services/Common/InputHL7DataPlugInEngineFactoryTest.cs b/src/InformaticsGateway/Test/Services/Common/InputHL7DataPlugInEngineFactoryTest.cs
new file mode 100755
index 000000000..47a56a735
--- /dev/null
+++ b/src/InformaticsGateway/Test/Services/Common/InputHL7DataPlugInEngineFactoryTest.cs
@@ -0,0 +1,69 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.IO.Abstractions;
+using System.Linq;
+using System.Reflection;
+using System.Text.Json;
+using Microsoft.Extensions.Logging;
+using Monai.Deploy.InformaticsGateway.Api.PlugIns;
+using Monai.Deploy.InformaticsGateway.Common;
+using Monai.Deploy.InformaticsGateway.Services.Common;
+using Monai.Deploy.InformaticsGateway.SharedTest;
+using Monai.Deploy.InformaticsGateway.Test.PlugIns;
+using Moq;
+using Xunit;
+using Xunit.Abstractions;
+namespace Monai.Deploy.InformaticsGateway.Test.Services.Common
+{
+ public class InputHL7DataPlugInEngineFactoryTest
+ {
+ private readonly Mock> _logger;
+ private readonly FileSystem _fileSystem;
+ private readonly ITestOutputHelper _output;
+
+ public InputHL7DataPlugInEngineFactoryTest(ITestOutputHelper output)
+ {
+ _logger = new Mock>();
+ _fileSystem = new FileSystem();
+ _output = output;
+
+ _logger.Setup(p => p.IsEnabled(It.IsAny())).Returns(true);
+ }
+
+ [Fact]
+ public void RegisteredPlugIns_WhenCalled_ReturnsListOfPlugIns()
+ {
+ var factory = new InputHL7DataPlugInEngineFactory(_fileSystem, _logger.Object);
+ var result = factory.RegisteredPlugIns().OrderBy(p => p.Value).ToArray();
+
+ _output.WriteLine($"result now = {JsonSerializer.Serialize(result)}");
+
+ Assert.Collection(result,
+ p => VerifyPlugIn(p, typeof(TestInputHL7DataPlugInAddWorkflow)));
+
+ _logger.VerifyLogging($"{typeof(IInputHL7DataPlugIn).Name} data plug-in found {typeof(TestInputHL7DataPlugInAddWorkflow).GetCustomAttribute()?.Name}: {typeof(TestInputHL7DataPlugInAddWorkflow).GetShortTypeAssemblyName()}.", LogLevel.Information, Times.Once());
+ }
+
+ private void VerifyPlugIn(KeyValuePair values, Type type)
+ {
+ Assert.Equal(values.Key, type.GetCustomAttribute()?.Name);
+ Assert.Equal(values.Value, type.GetShortTypeAssemblyName());
+ }
+ }
+}
diff --git a/src/InformaticsGateway/Test/Services/Common/InputHL7DataPlugInEngineTest.cs b/src/InformaticsGateway/Test/Services/Common/InputHL7DataPlugInEngineTest.cs
new file mode 100755
index 000000000..295322227
--- /dev/null
+++ b/src/InformaticsGateway/Test/Services/Common/InputHL7DataPlugInEngineTest.cs
@@ -0,0 +1,145 @@
+/*
+ * 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.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
+using Monai.Deploy.InformaticsGateway.Api;
+using Monai.Deploy.InformaticsGateway.Api.Storage;
+using Monai.Deploy.InformaticsGateway.Common;
+using Monai.Deploy.InformaticsGateway.Services.Common;
+using Monai.Deploy.InformaticsGateway.Test.PlugIns;
+using Monai.Deploy.Messaging.Events;
+using Moq;
+using Xunit;
+
+namespace Monai.Deploy.InformaticsGateway.Test.Services.Common
+{
+ public class InputHL7DataPlugInEngineTest
+ {
+ private readonly Mock> _logger;
+ private readonly Mock _serviceScopeFactory;
+ private readonly Mock _serviceScope;
+ private readonly ServiceProvider _serviceProvider;
+
+ private const string SampleMessage = "MSH|^~\\&|MD|MD HOSPITAL|MD Test|MONAI Deploy|202207130000|SECURITY|MD^A01^ADT_A01|MSG00001|P|2.8||||\r\n";
+
+ public InputHL7DataPlugInEngineTest()
+ {
+ _logger = new Mock>();
+ _serviceScopeFactory = new Mock();
+ _serviceScope = new Mock();
+
+ var services = new ServiceCollection();
+ services.AddScoped(p => _logger.Object);
+
+ _serviceProvider = services.BuildServiceProvider();
+ _serviceScopeFactory.Setup(p => p.CreateScope()).Returns(_serviceScope.Object);
+ _serviceScope.Setup(p => p.ServiceProvider).Returns(_serviceProvider);
+
+ _logger.Setup(p => p.IsEnabled(It.IsAny())).Returns(true);
+ }
+
+ [Fact]
+ public void GivenAnInputHL7DataPlugInEngine_WhenInitialized_ExpectParametersToBeValidated()
+ {
+ Assert.Throws(() => new InputHL7DataPlugInEngine(null, null));
+ Assert.Throws(() => new InputHL7DataPlugInEngine(_serviceProvider, null));
+
+ _ = new InputHL7DataPlugInEngine(_serviceProvider, _logger.Object);
+ }
+
+
+ [Fact]
+ public void GivenAnInputHL7DataPlugInEngine_WhenConfigureIsCalledWithBogusAssemblies_ThrowsException()
+ {
+ var pluginEngine = new InputHL7DataPlugInEngine(_serviceProvider, _logger.Object);
+ var assemblies = new List() { "SomeBogusAssemblye" };
+
+ var exceptions = Assert.Throws(() => pluginEngine.Configure(assemblies));
+
+ Assert.Single(exceptions.InnerExceptions);
+ Assert.True(exceptions.InnerException is PlugInLoadingException);
+ Assert.Contains("Error loading plug-in 'SomeBogusAssemblye'", exceptions.InnerException.Message);
+ }
+
+ [Fact]
+ public void GivenAnInputHL7DataPlugInEngine_WhenConfigureIsCalledWithAValidAssembly_ExpectNoExceptions()
+ {
+ var pluginEngine = new InputHL7DataPlugInEngine(_serviceProvider, _logger.Object);
+ var assemblies = new List() { typeof(TestInputHL7DataPlugInAddWorkflow).AssemblyQualifiedName };
+
+ pluginEngine.Configure(assemblies);
+ Assert.NotNull(pluginEngine);
+ }
+
+ [Fact]
+ public async Task GivenAnInputHL7DataPlugInEngine_WhenExecutePlugInsIsCalledWithoutConfigure_ThrowsException()
+ {
+ var pluginEngine = new InputHL7DataPlugInEngine(_serviceProvider, _logger.Object);
+ var assemblies = new List() { typeof(TestInputHL7DataPlugInAddWorkflow).AssemblyQualifiedName };
+
+ var dicomInfo = new DicomFileStorageMetadata(
+ Guid.NewGuid().ToString(),
+ Guid.NewGuid().ToString(),
+ "StudyInstanceUID",
+ "SeriesInstanceUID",
+ "SOPInstanceUID",
+ DataService.DicomWeb,
+ "calling",
+ "called");
+
+ var message = new HL7.Dotnetcore.Message(SampleMessage);
+ message.ParseMessage();
+
+ await Assert.ThrowsAsync(async () => await pluginEngine.ExecutePlugInsAsync(message, dicomInfo, null));
+ }
+
+ [Fact]
+ public async Task GivenAnInputHL7DataPlugInEngine_WhenExecutePlugInsIsCalled_ExpectDataIsProcessedByPlugInAsync()
+ {
+ var pluginEngine = new InputHL7DataPlugInEngine(_serviceProvider, _logger.Object);
+ var assemblies = new List()
+ {
+ typeof(TestInputHL7DataPlugInAddWorkflow).AssemblyQualifiedName,
+ };
+
+ pluginEngine.Configure(assemblies);
+
+ var dicomInfo = new DicomFileStorageMetadata(
+ Guid.NewGuid().ToString(),
+ Guid.NewGuid().ToString(),
+ "StudyInstanceUID",
+ "SeriesInstanceUID",
+ "SOPInstanceUID",
+ DataService.DicomWeb,
+ "calling",
+ "called");
+
+ var message = new HL7.Dotnetcore.Message(SampleMessage);
+ message.ParseMessage();
+ var configItem = new Hl7ApplicationConfigEntity { PlugInAssemblies = new List { { "Monai.Deploy.InformaticsGateway.Test.PlugIns.TestInputHL7DataPlugInAddWorkflow" } } };
+
+ var (Hl7Message, resultDicomInfo) = await pluginEngine.ExecutePlugInsAsync(message, dicomInfo, configItem);
+
+ Assert.Equal(Hl7Message, message);
+ Assert.Equal(resultDicomInfo, dicomInfo);
+ Assert.Equal(Hl7Message.GetValue("MSH.3"), TestInputHL7DataPlugInAddWorkflow.TestString);
+ }
+ }
+}
diff --git a/src/InformaticsGateway/Test/Services/Export/ExportHl7ServiceTests.cs b/src/InformaticsGateway/Test/Services/Export/ExportHl7ServiceTests.cs
index 216709cbf..0897a68a2 100755
--- a/src/InformaticsGateway/Test/Services/Export/ExportHl7ServiceTests.cs
+++ b/src/InformaticsGateway/Test/Services/Export/ExportHl7ServiceTests.cs
@@ -27,6 +27,7 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
+using Monai.Deploy.InformaticsGateway.Api.Mllp;
using Monai.Deploy.InformaticsGateway.Api.Models;
using Monai.Deploy.InformaticsGateway.Api.PlugIns;
using Monai.Deploy.InformaticsGateway.Common;
diff --git a/src/InformaticsGateway/Test/Services/HealthLevel7/MllPExtractTests.cs b/src/InformaticsGateway/Test/Services/HealthLevel7/MllPExtractTests.cs
index d8809e333..0d9aa2541 100755
--- a/src/InformaticsGateway/Test/Services/HealthLevel7/MllPExtractTests.cs
+++ b/src/InformaticsGateway/Test/Services/HealthLevel7/MllPExtractTests.cs
@@ -16,7 +16,6 @@
*/
-using Monai.Deploy.InformaticsGateway.Services.HealthLevel7;
using System.Threading;
using Moq;
using Xunit;
@@ -26,6 +25,7 @@
using System.Collections.Generic;
using HL7.Dotnetcore;
using Monai.Deploy.InformaticsGateway.Database.Api.Repositories;
+using Monai.Deploy.InformaticsGateway.Api.Mllp;
using Monai.Deploy.InformaticsGateway.Api.Storage;
using System.Threading.Tasks;
using Monai.Deploy.InformaticsGateway.Api.Models;
@@ -117,7 +117,8 @@ public async Task Should_Set_MetaData_On_Hl7FileStorageMetadata_Object()
var meatData = new Hl7FileStorageMetadata { Id = "metaId", File = new StorageObjectMetadata("txt") };
- await _sut.ExtractInfo(meatData, message);
+ var configItem = await _sut.GetConfigItem(message);
+ await _sut.ExtractInfo(meatData, message, configItem);
Assert.Equal("WorkflowInstanceId2", meatData.WorkflowInstanceId);
Assert.Equal("ExportTaskID2", meatData.TaskId);
@@ -166,8 +167,8 @@ public async Task Should_Set_Original_Patient_And_Study_Uid()
var meatData = new Hl7FileStorageMetadata { Id = "metaId", File = new StorageObjectMetadata("txt") };
-
- message = await _sut.ExtractInfo(meatData, message);
+ var configItem = await _sut.GetConfigItem(message);
+ message = await _sut.ExtractInfo(meatData, message, configItem);
Assert.Equal("PatentID", message.GetValue("OBR.3"));
Assert.Equal("PatentID", message.GetValue("PID.2"));
diff --git a/src/InformaticsGateway/Test/Services/HealthLevel7/MllpClientTest.cs b/src/InformaticsGateway/Test/Services/HealthLevel7/MllpClientTest.cs
index 033efea81..de8b363cd 100755
--- a/src/InformaticsGateway/Test/Services/HealthLevel7/MllpClientTest.cs
+++ b/src/InformaticsGateway/Test/Services/HealthLevel7/MllpClientTest.cs
@@ -22,6 +22,7 @@
using System.Threading.Tasks;
using HL7.Dotnetcore;
using Microsoft.Extensions.Logging;
+using Monai.Deploy.InformaticsGateway.Api.Mllp;
using Monai.Deploy.InformaticsGateway.Configuration;
using Monai.Deploy.InformaticsGateway.Services.Common;
using Monai.Deploy.InformaticsGateway.Services.HealthLevel7;
diff --git a/src/InformaticsGateway/Test/Services/HealthLevel7/MllpServiceTest.cs b/src/InformaticsGateway/Test/Services/HealthLevel7/MllpServiceTest.cs
index 52757d6d0..1f2119bc6 100755
--- a/src/InformaticsGateway/Test/Services/HealthLevel7/MllpServiceTest.cs
+++ b/src/InformaticsGateway/Test/Services/HealthLevel7/MllpServiceTest.cs
@@ -29,13 +29,16 @@
using Monai.Deploy.InformaticsGateway.Configuration;
using Monai.Deploy.InformaticsGateway.Services.Common;
using Monai.Deploy.InformaticsGateway.Services.Connectors;
-using Monai.Deploy.InformaticsGateway.Services.HealthLevel7;
+using Monai.Deploy.InformaticsGateway.Api.Mllp;
using Monai.Deploy.InformaticsGateway.Services.Storage;
using Monai.Deploy.InformaticsGateway.SharedTest;
using Monai.Deploy.Messaging.Events;
using Moq;
using xRetry;
using Xunit;
+using Monai.Deploy.InformaticsGateway.Api;
+using Monai.Deploy.InformaticsGateway.Api.PlugIns;
+using Monai.Deploy.InformaticsGateway.Database.Api.Repositories;
namespace Monai.Deploy.InformaticsGateway.Test.Services.HealthLevel7
{
@@ -57,6 +60,8 @@ public class MllpServiceTest
private readonly IServiceProvider _serviceProvider;
private readonly Mock _storageInfoProvider;
private readonly Mock _mIIpExtract = new Mock();
+ private readonly Mock _hl7DataPlugInEngine = new Mock();
+ private readonly Mock _hl7ApplicationConfigRepository = new Mock();
public MllpServiceTest()
{
@@ -87,6 +92,8 @@ public MllpServiceTest()
services.AddScoped(p => _fileSystem.Object);
services.AddScoped(p => _storageInfoProvider.Object);
services.AddScoped(p => _mIIpExtract.Object);
+ services.AddScoped(p => _hl7DataPlugInEngine.Object);
+ services.AddScoped(p => _hl7ApplicationConfigRepository.Object);
_serviceProvider = services.BuildServiceProvider();
_serviceScopeFactory.Setup(p => p.CreateScope()).Returns(_serviceScope.Object);
@@ -276,8 +283,9 @@ public async Task GivenATcpClientWithHl7Messages_WhenDisconnected_ExpectMessageT
{
var checkEvent = new ManualResetEventSlim();
var client = new Mock();
- _mIIpExtract.Setup(e => e.ExtractInfo(It.IsAny(), It.IsAny()))
- .ReturnsAsync((Hl7FileStorageMetadata meta, Message Msg) => Msg);
+ _mIIpExtract.Setup(e => e.ExtractInfo(It.IsAny(), It.IsAny(), It.IsAny()))
+ .ReturnsAsync((Hl7FileStorageMetadata meta, Message Msg, Hl7ApplicationConfigEntity configItem) => Msg);
+
_mllpClientFactory.Setup(p => p.CreateClient(It.IsAny(), It.IsAny(), It.IsAny>()))
.Returns(() =>
{
@@ -319,8 +327,11 @@ public async Task GivenATcpClientWithHl7Messages_WhenDisconnected_ExpectMessageT
var checkEvent = new ManualResetEventSlim();
var client = new Mock();
- _mIIpExtract.Setup(e => e.ExtractInfo(It.IsAny(), It.IsAny()))
- .ReturnsAsync((Hl7FileStorageMetadata meta, Message Msg) => Msg);
+ _mIIpExtract.Setup(e => e.ExtractInfo(It.IsAny(), It.IsAny(), It.IsAny()))
+ .ReturnsAsync((Hl7FileStorageMetadata meta, Message Msg, Hl7ApplicationConfigEntity configItem) => Msg);
+
+ _mIIpExtract.Setup(e => e.GetConfigItem(It.IsAny()))
+ .ReturnsAsync((Message Msg) => new Hl7ApplicationConfigEntity());
_mllpClientFactory.Setup(p => p.CreateClient(It.IsAny(), It.IsAny(), It.IsAny>()))
.Returns(() =>
@@ -353,7 +364,7 @@ public async Task GivenATcpClientWithHl7Messages_WhenDisconnected_ExpectMessageT
Assert.True(checkEvent.Wait(3000));
await Task.Delay(500).ConfigureAwait(false);
- _mIIpExtract.Verify(p => p.ExtractInfo(It.IsAny(), It.IsAny()), Times.Exactly(3));
+ _mIIpExtract.Verify(p => p.ExtractInfo(It.IsAny(), It.IsAny(), It.IsAny()), Times.Exactly(3));
}
}
}
diff --git a/src/InformaticsGateway/Test/packages.lock.json b/src/InformaticsGateway/Test/packages.lock.json
index 5820049ac..0cbb69366 100755
--- a/src/InformaticsGateway/Test/packages.lock.json
+++ b/src/InformaticsGateway/Test/packages.lock.json
@@ -2085,6 +2085,7 @@
"monai.deploy.informaticsgateway.api": {
"type": "Project",
"dependencies": {
+ "HL7-dotnetcore": "[2.36.0, )",
"Macross.Json.Extensions": "[3.0.0, )",
"Microsoft.EntityFrameworkCore.Abstractions": "[6.0.25, )",
"Monai.Deploy.InformaticsGateway.Common": "[1.0.0, )",
diff --git a/src/InformaticsGateway/packages.lock.json b/src/InformaticsGateway/packages.lock.json
index 630572169..1778d145c 100755
--- a/src/InformaticsGateway/packages.lock.json
+++ b/src/InformaticsGateway/packages.lock.json
@@ -1695,6 +1695,7 @@
"monai.deploy.informaticsgateway.api": {
"type": "Project",
"dependencies": {
+ "HL7-dotnetcore": "[2.36.0, )",
"Macross.Json.Extensions": "[3.0.0, )",
"Microsoft.EntityFrameworkCore.Abstractions": "[6.0.25, )",
"Monai.Deploy.InformaticsGateway.Common": "[1.0.0, )",
diff --git a/src/Plug-ins/RemoteAppExecution/Test/packages.lock.json b/src/Plug-ins/RemoteAppExecution/Test/packages.lock.json
index 4d70f5c72..ac62dee73 100755
--- a/src/Plug-ins/RemoteAppExecution/Test/packages.lock.json
+++ b/src/Plug-ins/RemoteAppExecution/Test/packages.lock.json
@@ -149,6 +149,11 @@
"System.Threading.Channels": "6.0.0"
}
},
+ "HL7-dotnetcore": {
+ "type": "Transitive",
+ "resolved": "2.36.0",
+ "contentHash": "N1HLMeIqYuY+4O69ItgZJoDBnnpNkK5N2pClceTJ2nFJxsP48iCsA4iz3tm43Yszi4r/vaThoc3UoLBfGP3vKw=="
+ },
"Macross.Json.Extensions": {
"type": "Transitive",
"resolved": "3.0.0",
@@ -1595,6 +1600,7 @@
"monai.deploy.informaticsgateway.api": {
"type": "Project",
"dependencies": {
+ "HL7-dotnetcore": "[2.36.0, )",
"Macross.Json.Extensions": "[3.0.0, )",
"Microsoft.EntityFrameworkCore.Abstractions": "[6.0.25, )",
"Monai.Deploy.InformaticsGateway.Common": "[1.0.0, )",
diff --git a/src/Plug-ins/RemoteAppExecution/packages.lock.json b/src/Plug-ins/RemoteAppExecution/packages.lock.json
index 5c4215fea..a171e527a 100755
--- a/src/Plug-ins/RemoteAppExecution/packages.lock.json
+++ b/src/Plug-ins/RemoteAppExecution/packages.lock.json
@@ -169,6 +169,11 @@
"System.Threading.Channels": "6.0.0"
}
},
+ "HL7-dotnetcore": {
+ "type": "Transitive",
+ "resolved": "2.36.0",
+ "contentHash": "N1HLMeIqYuY+4O69ItgZJoDBnnpNkK5N2pClceTJ2nFJxsP48iCsA4iz3tm43Yszi4r/vaThoc3UoLBfGP3vKw=="
+ },
"Humanizer.Core": {
"type": "Transitive",
"resolved": "2.8.26",
@@ -589,6 +594,7 @@
"monai.deploy.informaticsgateway.api": {
"type": "Project",
"dependencies": {
+ "HL7-dotnetcore": "[2.36.0, )",
"Macross.Json.Extensions": "[3.0.0, )",
"Microsoft.EntityFrameworkCore.Abstractions": "[6.0.25, )",
"Monai.Deploy.InformaticsGateway.Common": "[1.0.0, )",
diff --git a/tests/Integration.Test/StepDefinitions/RemoteAppExecutionPlugInsStepDefinitions.cs b/tests/Integration.Test/StepDefinitions/RemoteAppExecutionPlugInsStepDefinitions.cs
index 2e126327b..55e7137cf 100755
--- a/tests/Integration.Test/StepDefinitions/RemoteAppExecutionPlugInsStepDefinitions.cs
+++ b/tests/Integration.Test/StepDefinitions/RemoteAppExecutionPlugInsStepDefinitions.cs
@@ -25,7 +25,6 @@
using Monai.Deploy.InformaticsGateway.Configuration;
using Monai.Deploy.InformaticsGateway.Integration.Test.Common;
using Monai.Deploy.InformaticsGateway.Integration.Test.Drivers;
-//using Monai.Deploy.InformaticsGateway.PlugIns.Pseudonymisation;
using Monai.Deploy.InformaticsGateway.PlugIns.RemoteAppExecution;
using Monai.Deploy.Messaging.Events;
using Monai.Deploy.Messaging.Messages;
diff --git a/tests/Integration.Test/appsettings.json b/tests/Integration.Test/appsettings.json
index e16ccb4b4..8e3d304b6 100755
--- a/tests/Integration.Test/appsettings.json
+++ b/tests/Integration.Test/appsettings.json
@@ -5,6 +5,25 @@
"plugins": {
"remoteApp": {
"ReplaceTags": "AccessionNumber, StudyDescription, SeriesDescription, PatientAddress, PatientAge, PatientName"
+ },
+ "Pseudonymise": {
+ "ConnectionString": "mongodb://root:rootpassword@localhost:27017",
+ "DatabaseName": "InformaticsGateway",
+ "EncriptionClientTimeoutSeconds": "900",
+ "ExpiresAfterDays": "1",
+ "ExternalAppTaskInboundKeepTags": "0020 000E, 0020 0010, 0020 00013, 0008 0018, 0020 000E",
+ "ImportantTags": "0010 0020, 0008 0018, 0008 0016, 0020 000D, 0020 000E, 0020 0010,0008 1155, 0008 0014, 0008 0050, 0008 0080, 0008 0081, 0008 0090, 0008 0092, 0008 0094, 0008 1010, 0008 1030, 0008 103E, 0008 1040, 0008 1048,0008 1050, 0008 1060, 0008 1070, 0008 1080, 0008 2111, 0010 0010, 0010 0030, 0010 0030, 0010 0032, 0010 0040, 0010 1000, 0010 1001, 0010 1001, 0010 1010, 0010 1020, 0010 1030, 0010 1090, 0010 2160, 0010 2180, 0010 21B0, 0010 4000, 0018 1000, 0018 1030, 0020 0052, 0020 0200, 0020 4000, 0040 0275, 0040 A124, 0040 A730, 0088 0140, 3006 0024, 3006 00C2",
+ "SecurityProfile": "\t\t\t\t0010,0020;K;;;;;;;;;;\r\n\t\t\t\t0008,0018;C;;;;;;;;;;\r\n\t\t\t\t0008,0016;K;;;;;;;;;;\r\n\t\t\t\t0020,000D;K;;;;;;;;;;\r\n\t\t\t\t0020,000E;C;;;;;;;;;;\r\n\t\t\t\t0020,0010;C;;;;;;;;;;\r\n\t\t\t\t0008,1155;C;;;;;;;;;;\r\n\t\t\t\t0008,0014;X;;;;;;;;;;\r\n\t\t\t\t0008,0050;K;;;;;;;;;;\r\n\t\t\t\t0008,0080;X;;;;;;;;;;\r\n\t\t\t\t0008,0081;X;;;;;;;;;;\r\n\t\t\t\t0008,0090;X;;;;;;;;;;\r\n\t\t\t\t0008,0092;X;;;;;;;;;;\r\n\t\t\t\t0008,0094;X;;;;;;;;;;\r\n\t\t\t\t0008,1010;X;;;;;;;;;;\r\n\t\t\t\t0008,1030;X;;;;;;;;;;\r\n\t\t\t\t0008,103E;X;;;;;;;;;;\r\n\t\t\t\t0008,1040;X;;;;;;;;;;\r\n\t\t\t\t0008,1048;X;;;;;;;;;;\r\n\t\t\t\t0008,1050;X;;;;;;;;;;\r\n\t\t\t\t0008,1060;X;;;;;;;;;;\r\n\t\t\t\t0008,1070;X;;;;;;;;;;\r\n\t\t\t\t0008,1080;X;;;;;;;;;;\r\n\t\t\t\t0008,2111;X;;;;;;;;;;\r\n\t\t\t\t0010,0010;X;;;;;;;;;;\r\n\t\t\t\t0010,0030;X;;;;;;;;;;\r\n\t\t\t\t0010,0030;X;;;;;;;;;;\r\n\t\t\t\t0010,0032;X;;;;;;;;;;\r\n\t\t\t\t0010,0040;X;;;;;;;;;;\r\n\t\t\t\t0010,1000;X;;;;;;;;;;\r\n\t\t\t\t0010,1001;X;;;;;;;;;;\r\n\t\t\t\t0010,1001;X;;;;;;;;;;\r\n\t\t\t\t0010,1010;X;;;;;;;;;;\r\n\t\t\t\t0010,1020;X;;;;;;;;;;\r\n\t\t\t\t0010,1030;X;;;;;;;;;;\r\n\t\t\t\t0010,1090;X;;;;;;;;;;\r\n\t\t\t\t0010,2160;X;;;;;;;;;;\r\n\t\t\t\t0010,2180;X;;;;;;;;;;\r\n\t\t\t\t0010,21B0;X;;;;;;;;;;\r\n\t\t\t\t0010,4000;X;;;;;;;;;;\r\n\t\t\t\t\r\n\t\t\t\t0018,1000;X;;;;;;;;;;\r\n\t\t\t\t0018,1030;X;;;;;;;;;;\r\n\t\t\t\t0020,0052;X;;;;;;;;;;\r\n\t\t\t\t0020,0200;X;;;;;;;;;;\r\n\t\t\t\t0020,4000;X;;;;;;;;;;\r\n\t\t\t\t0040,0275;X;;;;;;;;;;\r\n\t\t\t\t0040,A124;X;;;;;;;;;;\r\n\t\t\t\t0040,A730;X;;;;;;;;;;\r\n\t\t\t\t0088,0140;X;;;;;;;;;;\r\n\t\t\t\t3006,0024;X;;;;;;;;;;\r\n\t\t\t\t3006,00C2;X;;;;;;;;;;\r\n\t\t\t\t",
+ "KMS": {
+ "KeyVaultNamespace": "InformaticsGateway.KeyVault",
+ "AWS": {
+ "accessKeyId": "",
+ "arnKey": "",
+ "roleArnToAssume": "",
+ "region": "eu-west-2",
+ "secretAccessKey": ""
+ }
+ }
}
},
"ConnectionStrings": {
diff --git a/tests/Integration.Test/packages.lock.json b/tests/Integration.Test/packages.lock.json
index c3b9e5483..9a208b6ce 100755
--- a/tests/Integration.Test/packages.lock.json
+++ b/tests/Integration.Test/packages.lock.json
@@ -226,6 +226,16 @@
"resolved": "2.5.0",
"contentHash": "+Gp9vuC2431yPyKB15YrOTxCuEAErBQUTIs6CquumX1F073UaPHGW0VE/XVJLMh9W4sXdz3TBkcHdFWZrRn2Hw=="
},
+ "AnswerDicomTools": {
+ "type": "Transitive",
+ "resolved": "0.1.1-rc0089",
+ "contentHash": "DgDBjo708kHmr0lUdUrYaRLjmaICrJMBh6w/Vd0E/r2SJ0DDiQuxMABJzIwXwrVFSzrrwpqPqWBQMTCY++9uPQ==",
+ "dependencies": {
+ "Microsoft.Extensions.Configuration": "6.0.1",
+ "MongoDB.Driver": "2.21.0",
+ "fo-dicom": "5.1.1"
+ }
+ },
"Ardalis.GuardClauses": {
"type": "Transitive",
"resolved": "4.1.1",
@@ -413,6 +423,15 @@
"Microsoft.Extensions.Primitives": "6.0.0"
}
},
+ "Microsoft.Extensions.Configuration.CommandLine": {
+ "type": "Transitive",
+ "resolved": "6.0.0",
+ "contentHash": "3nL1qCkZ1Oxx14ZTzgo4MmlO7tso7F+TtMZAY2jUAtTLyAcDp+EDjk3RqafoKiNaePyPvvlleEcBxh3b2Hzl1g==",
+ "dependencies": {
+ "Microsoft.Extensions.Configuration": "6.0.0",
+ "Microsoft.Extensions.Configuration.Abstractions": "6.0.0"
+ }
+ },
"Microsoft.Extensions.Configuration.FileExtensions": {
"type": "Transitive",
"resolved": "6.0.0",
@@ -425,6 +444,17 @@
"Microsoft.Extensions.Primitives": "6.0.0"
}
},
+ "Microsoft.Extensions.Configuration.UserSecrets": {
+ "type": "Transitive",
+ "resolved": "6.0.1",
+ "contentHash": "Fy8yr4V6obi7ZxvKYI1i85jqtwMq8tqyxQVZpRSkgeA8enqy/KvBIMdcuNdznlxQMZa72mvbHqb7vbg4Pyx95w==",
+ "dependencies": {
+ "Microsoft.Extensions.Configuration.Abstractions": "6.0.0",
+ "Microsoft.Extensions.Configuration.Json": "6.0.0",
+ "Microsoft.Extensions.FileProviders.Abstractions": "6.0.0",
+ "Microsoft.Extensions.FileProviders.Physical": "6.0.0"
+ }
+ },
"Microsoft.Extensions.DependencyInjection": {
"type": "Transitive",
"resolved": "6.0.1",
@@ -500,6 +530,34 @@
"resolved": "6.0.0",
"contentHash": "ip8jnL1aPiaPeKINCqaTEbvBFDmVx9dXQEBZ2HOBRXPD1eabGNqP/bKlsIcp7U2lGxiXd5xIhoFcmY8nM4Hdiw=="
},
+ "Microsoft.Extensions.Hosting": {
+ "type": "Transitive",
+ "resolved": "6.0.1",
+ "contentHash": "hbmizc9KPWOacLU8Z8YMaBG6KWdZFppczYV/KwnPGU/8xebWxQxdDeJmLOgg968prb7g2oQgnp6JVLX6lgby8g==",
+ "dependencies": {
+ "Microsoft.Extensions.Configuration": "6.0.0",
+ "Microsoft.Extensions.Configuration.Abstractions": "6.0.0",
+ "Microsoft.Extensions.Configuration.Binder": "6.0.0",
+ "Microsoft.Extensions.Configuration.CommandLine": "6.0.0",
+ "Microsoft.Extensions.Configuration.EnvironmentVariables": "6.0.1",
+ "Microsoft.Extensions.Configuration.FileExtensions": "6.0.0",
+ "Microsoft.Extensions.Configuration.Json": "6.0.0",
+ "Microsoft.Extensions.Configuration.UserSecrets": "6.0.1",
+ "Microsoft.Extensions.DependencyInjection": "6.0.0",
+ "Microsoft.Extensions.DependencyInjection.Abstractions": "6.0.0",
+ "Microsoft.Extensions.FileProviders.Abstractions": "6.0.0",
+ "Microsoft.Extensions.FileProviders.Physical": "6.0.0",
+ "Microsoft.Extensions.Hosting.Abstractions": "6.0.0",
+ "Microsoft.Extensions.Logging": "6.0.0",
+ "Microsoft.Extensions.Logging.Abstractions": "6.0.0",
+ "Microsoft.Extensions.Logging.Configuration": "6.0.0",
+ "Microsoft.Extensions.Logging.Console": "6.0.0",
+ "Microsoft.Extensions.Logging.Debug": "6.0.0",
+ "Microsoft.Extensions.Logging.EventLog": "6.0.0",
+ "Microsoft.Extensions.Logging.EventSource": "6.0.0",
+ "Microsoft.Extensions.Options": "6.0.0"
+ }
+ },
"Microsoft.Extensions.Hosting.Abstractions": {
"type": "Transitive",
"resolved": "6.0.0",
@@ -542,6 +600,55 @@
"Microsoft.Extensions.Options.ConfigurationExtensions": "6.0.0"
}
},
+ "Microsoft.Extensions.Logging.Console": {
+ "type": "Transitive",
+ "resolved": "6.0.0",
+ "contentHash": "gsqKzOEdsvq28QiXFxagmn1oRB9GeI5GgYCkoybZtQA0IUb7QPwf1WmN3AwJeNIsadTvIFQCiVK0OVIgKfOBGg==",
+ "dependencies": {
+ "Microsoft.Extensions.DependencyInjection.Abstractions": "6.0.0",
+ "Microsoft.Extensions.Logging": "6.0.0",
+ "Microsoft.Extensions.Logging.Abstractions": "6.0.0",
+ "Microsoft.Extensions.Logging.Configuration": "6.0.0",
+ "Microsoft.Extensions.Options": "6.0.0",
+ "System.Text.Json": "6.0.0"
+ }
+ },
+ "Microsoft.Extensions.Logging.Debug": {
+ "type": "Transitive",
+ "resolved": "6.0.0",
+ "contentHash": "M9g/JixseSZATJE9tcMn9uzoD4+DbSglivFqVx8YkRJ7VVPmnvCEbOZ0AAaxsL1EKyI4cz07DXOOJExxNsUOHw==",
+ "dependencies": {
+ "Microsoft.Extensions.DependencyInjection.Abstractions": "6.0.0",
+ "Microsoft.Extensions.Logging": "6.0.0",
+ "Microsoft.Extensions.Logging.Abstractions": "6.0.0"
+ }
+ },
+ "Microsoft.Extensions.Logging.EventLog": {
+ "type": "Transitive",
+ "resolved": "6.0.0",
+ "contentHash": "rlo0RxlMd0WtLG3CHI0qOTp6fFn7MvQjlrCjucA31RqmiMFCZkF8CHNbe8O7tbBIyyoLGWB1he9CbaA5iyHthg==",
+ "dependencies": {
+ "Microsoft.Extensions.DependencyInjection.Abstractions": "6.0.0",
+ "Microsoft.Extensions.Logging": "6.0.0",
+ "Microsoft.Extensions.Logging.Abstractions": "6.0.0",
+ "Microsoft.Extensions.Options": "6.0.0",
+ "System.Diagnostics.EventLog": "6.0.0"
+ }
+ },
+ "Microsoft.Extensions.Logging.EventSource": {
+ "type": "Transitive",
+ "resolved": "6.0.0",
+ "contentHash": "BeDyyqt7nkm/nr+Gdk+L8n1tUT/u33VkbXAOesgYSNsxDM9hJ1NOBGoZfj9rCbeD2+9myElI6JOVVFmnzgeWQA==",
+ "dependencies": {
+ "Microsoft.Extensions.DependencyInjection.Abstractions": "6.0.0",
+ "Microsoft.Extensions.Logging": "6.0.0",
+ "Microsoft.Extensions.Logging.Abstractions": "6.0.0",
+ "Microsoft.Extensions.Options": "6.0.0",
+ "Microsoft.Extensions.Primitives": "6.0.0",
+ "System.Runtime.CompilerServices.Unsafe": "6.0.0",
+ "System.Text.Json": "6.0.0"
+ }
+ },
"Microsoft.Extensions.Options": {
"type": "Transitive",
"resolved": "6.0.0",
@@ -1941,6 +2048,25 @@
"resolved": "0.6.2",
"contentHash": "jPao/LdUNLUz8rn3H1D8W7wQbZsRZM0iayvWI4xGejJg3XJHT56gcmYdgmCGPdJF1UEBqUjucCRrFB+4HbJsbw=="
},
+ "monai-deploy-informatics-gateway-pseudonymisation": {
+ "type": "Project",
+ "dependencies": {
+ "AnswerDicomTools": "[0.1.1-rc0089, )",
+ "Ardalis.GuardClauses": "[4.1.1, )",
+ "HL7-dotnetcore": "[2.36.0, )",
+ "Microsoft.EntityFrameworkCore": "[6.0.25, )",
+ "Microsoft.EntityFrameworkCore.Relational": "[6.0.25, )",
+ "Microsoft.EntityFrameworkCore.Sqlite": "[6.0.25, )",
+ "Microsoft.Extensions.Configuration": "[6.0.1, )",
+ "Microsoft.Extensions.Configuration.FileExtensions": "[6.0.0, )",
+ "Microsoft.Extensions.Configuration.Json": "[6.0.0, )",
+ "Microsoft.Extensions.Hosting": "[6.0.1, )",
+ "MongoDB.Driver": "[2.21.0, )",
+ "NLog": "[5.2.4, )",
+ "Polly": "[7.2.4, )",
+ "fo-dicom": "[5.1.1, )"
+ }
+ },
"monai.deploy.informaticsgateway": {
"type": "Project",
"dependencies": {
@@ -1964,6 +2090,7 @@
"monai.deploy.informaticsgateway.api": {
"type": "Project",
"dependencies": {
+ "HL7-dotnetcore": "[2.36.0, )",
"Macross.Json.Extensions": "[3.0.0, )",
"Microsoft.EntityFrameworkCore.Abstractions": "[6.0.25, )",
"Monai.Deploy.InformaticsGateway.Common": "[1.0.0, )",