This repository has been archived by the owner on Apr 26, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Yannick Börner
committed
Mar 24, 2021
1 parent
63929b5
commit 8cdbe23
Showing
13 changed files
with
1,045 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
name: .NET | ||
|
||
on: | ||
push: | ||
branches: [ develop ] | ||
pull_request: | ||
branches: [ develop ] | ||
|
||
jobs: | ||
build: | ||
|
||
runs-on: ubuntu-latest | ||
|
||
steps: | ||
- uses: actions/checkout@v2 | ||
- name: Setup .NET | ||
uses: actions/setup-dotnet@v1 | ||
with: | ||
dotnet-version: 5.0.x | ||
- name: Restore dependencies | ||
run: dotnet restore | ||
- name: Build | ||
run: dotnet build --no-restore | ||
- name: Test | ||
run: dotnet test --no-build --verbosity normal |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
using HL7.Dotnetcore; | ||
using Microsoft.Extensions.Configuration; | ||
using Microsoft.VisualStudio.TestTools.UnitTesting; | ||
using System; | ||
using System.IO; | ||
using static Healex.HL7v2Anonymizer.ReplacementOptions; | ||
|
||
namespace Healex.HL7v2Anonymizer.Tests | ||
{ | ||
[TestClass] | ||
public class AnonymizerTests | ||
{ | ||
[TestMethod] | ||
[DeploymentItem("Healex.HL7v2Anonymizer.Tests/TestData", "TestData")] | ||
public void AnonymizerTestAdt() | ||
{ | ||
TestAnonymization(File.ReadAllText(@"./TestData/TestAdt1.hl7")); | ||
} | ||
|
||
[TestMethod] | ||
[DeploymentItem("Healex.HL7v2Anonymizer.Tests/TestData", "TestData")] | ||
public void AnonymizerTestOru() | ||
{ | ||
TestAnonymization(File.ReadAllText(@"./TestData/TestOru1.hl7")); | ||
} | ||
|
||
public void TestAnonymization(string messageContent) | ||
{ | ||
var message = new Message(messageContent); | ||
|
||
// Setup | ||
var replacementOptions = getReplacementOptions(); | ||
message.ParseMessage(); | ||
|
||
// Method under test | ||
var anonymizer = new Anonymizer(replacementOptions); | ||
anonymizer.Anonymize(message); | ||
|
||
// Assert | ||
foreach (SegmentReplacement segment in replacementOptions.Segments) | ||
{ | ||
foreach (Replacement replacement in segment.Replacements) | ||
{ | ||
try | ||
{ | ||
Assert.AreEqual(message.GetValue(replacement.Path), replacement.Value); | ||
} | ||
catch (HL7Exception) | ||
{ | ||
// Throws if segment is not present | ||
continue; | ||
} | ||
} | ||
} | ||
|
||
// Output for manual inspection | ||
var messageAsString = message.SerializeMessage(true); | ||
Console.WriteLine(messageAsString); | ||
} | ||
|
||
private static ReplacementOptions getReplacementOptions() | ||
{ | ||
var builder = new ConfigurationBuilder() | ||
.SetBasePath(Directory.GetCurrentDirectory()) | ||
.AddJsonFile("appsettings.json", optional: false); | ||
|
||
IConfiguration config = builder.Build(); | ||
|
||
var replacementOptions = config.GetSection("ReplacementOptions").Get<ReplacementOptions>(); | ||
return replacementOptions; | ||
} | ||
} | ||
} |
35 changes: 35 additions & 0 deletions
35
Healex.HL7v2Anonymizer.Tests/Healex.HL7v2Anonymizer.Tests.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>net5.0</TargetFramework> | ||
|
||
<IsPackable>false</IsPackable> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<Content Include="..\Healex.HL7v2Anonymizer\appsettings.json" Link="appsettings.json" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="5.0.0" /> | ||
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="5.0.0" /> | ||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.7.1" /> | ||
<PackageReference Include="MSTest.TestAdapter" Version="2.1.1" /> | ||
<PackageReference Include="MSTest.TestFramework" Version="2.1.1" /> | ||
<PackageReference Include="coverlet.collector" Version="1.3.0" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\Healex.HL7v2Anonymizer\Healex.HL7v2Anonymizer.csproj" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<None Update="TestData\TestAdt1.hl7"> | ||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> | ||
</None> | ||
<None Update="TestData\TestOru1.hl7"> | ||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> | ||
</None> | ||
</ItemGroup> | ||
|
||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
MSH|^~\&|NES|NINTENDO|TESTSYSTEM|TESTFACILITY|20010101000000||ADT^A04|Q123456789T123456789X123456|P|2.3 | ||
EVN|A04|20010101000000|||^KOOPA^BOWSER^^^^^^^CURRENT | ||
PID|1||123456789^^^^MR||BROS^MARIO^^^^||19850101000000|M|||123 FAKE STREET^MARIO LUIGI BROS PLACE^TOADSTOOL KINGDOM^NES^A1B2C3^JP^HOME^^1234|1234|(555)555-0123^HOME^JP:1234567^^1^555^5550123~(555)555-0124^HOME^JP:1234568^^1^555^5550124|||S|MSH|12345678|||||||0|||||N | ||
NK1|1|PEACH^PRINCESS^^^^|SO|ANOTHER CASTLE^^TOADSTOOL KINGDOM^NES^^JP|(123)555-1234|(123)555-2345|NOK||||||||||||| | ||
NK1|2|TOADSTOOL^PRINCESS^^^^|SO|YET ANOTHER CASTLE^^TOADSTOOL KINGDOM^NES^^JP|(123)555-3456|(123)555-4567|EMC||||||||||||| | ||
PV1|1|O|ABCD^EFGH^|||^^|123456^DINO^YOSHI^^^^^^MSRM^CURRENT^^^NEIGHBOURHOOD DR NBR^|^DOG^DUCKHUNT^^^^^^^CURRENT||CRD|||||||123456^DINO^YOSHI^^^^^^MSRM^CURRENT^^^NEIGHBOURHOOD DR NBR^|AO|0123456789|1|||||||||||||||||||MSH||A|||20010101000000 | ||
IN1|1|PAR^PARENT||||LUIGI | ||
IN1|2|FRI^FRIEND||||PRINCESS |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
MSH|^~\&|LCS|LCA|LIS|TEST9999|199807311532||ORU^R01|3629|P|2.2 | ||
PID|2|2161348462|20809880170|1614614|20809880170^TESTPAT||19760924|M|||^^^^ | ||
ORC|NW|8642753100012^LIS|20809880170^LCS||||||19980727000000|||HAVILAND | ||
OBR|1|8642753100012^LIS|20809880170^LCS|008342^UPPER RESPIRATORY | ||
OBX|1|ST|008342^UPPER RESPIRATORY CULTURE^L||FINALREPORT|||||N|F||| 19980729160500|BN | ||
ORC|NW|8642753100012^LIS|20809880170^LCS||||||19980727000000|||HAVILAND | ||
OBR|2|8642753100012^LIS|20809880170^LCS|997602^.^L|||19980727175800||||G||| | ||
OBX|2|CE|997231^RESULT 1^L||M415|||||N|F|||19980729160500|BN | ||
NTE|1|L|MORAXELLA (BRANHAMELLA) CATARRHALIS | ||
NTE|2|L| HEAVY GROWTH | ||
NTE|3|L| BETA LACTAMASE POSITIVE | ||
OBX|3|CE|997232^RESULT 2^L||MR105|||||N|F|||19980729160500|BN | ||
NTE|1|L|ROUTINE RESPIRATORY FLORA |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
|
||
Microsoft Visual Studio Solution File, Format Version 12.00 | ||
# Visual Studio Version 16 | ||
VisualStudioVersion = 16.0.31005.135 | ||
MinimumVisualStudioVersion = 10.0.40219.1 | ||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Healex.HL7v2Anonymizer", "Healex.HL7v2Anonymizer\Healex.HL7v2Anonymizer.csproj", "{9A79221A-7684-4BD6-9721-199934853893}" | ||
EndProject | ||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Healex.HL7v2Anonymizer.Tests", "Healex.HL7v2Anonymizer.Tests\Healex.HL7v2Anonymizer.Tests.csproj", "{2B44D800-3F01-4288-AFD1-1DF7D956B661}" | ||
EndProject | ||
Global | ||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||
Debug|Any CPU = Debug|Any CPU | ||
Release|Any CPU = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||
{9A79221A-7684-4BD6-9721-199934853893}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
{9A79221A-7684-4BD6-9721-199934853893}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
{9A79221A-7684-4BD6-9721-199934853893}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
{9A79221A-7684-4BD6-9721-199934853893}.Release|Any CPU.Build.0 = Release|Any CPU | ||
{2B44D800-3F01-4288-AFD1-1DF7D956B661}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
{2B44D800-3F01-4288-AFD1-1DF7D956B661}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
{2B44D800-3F01-4288-AFD1-1DF7D956B661}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
{2B44D800-3F01-4288-AFD1-1DF7D956B661}.Release|Any CPU.Build.0 = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(SolutionProperties) = preSolution | ||
HideSolutionNode = FALSE | ||
EndGlobalSection | ||
GlobalSection(ExtensibilityGlobals) = postSolution | ||
SolutionGuid = {971ACC78-6922-482C-8AC1-693787A35B0B} | ||
EndGlobalSection | ||
EndGlobal |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
using HL7.Dotnetcore; | ||
using System; | ||
using static Healex.HL7v2Anonymizer.ReplacementOptions; | ||
|
||
namespace Healex.HL7v2Anonymizer | ||
{ | ||
public class Anonymizer | ||
{ | ||
private ReplacementOptions _replacementOptions; | ||
|
||
public Anonymizer(ReplacementOptions replacementOptions) | ||
{ | ||
_replacementOptions = replacementOptions; | ||
} | ||
|
||
public bool Anonymize(Message message) | ||
{ | ||
var isSuccess = true; | ||
foreach (SegmentReplacement segmentReplacement in _replacementOptions.Segments) | ||
{ | ||
var segments = message.Segments(segmentReplacement.Segment); | ||
foreach (Segment segment in segments) | ||
{ | ||
// Create new temporary message for each repeating segment | ||
// because we can't set values in all repeating segments at once | ||
// We use references so this overwrites the original segments | ||
var tempMessage = new Message(); | ||
tempMessage.AddNewSegment(segment); | ||
|
||
foreach (Replacement replacement in segmentReplacement.Replacements) | ||
{ | ||
tryReplaceValue(replacement, tempMessage); | ||
} | ||
} | ||
} | ||
return isSuccess; | ||
} | ||
|
||
private bool tryReplaceValue(Replacement replacement, Message message) | ||
{ | ||
try | ||
{ | ||
message.SetValue(replacement.Path, replacement.Value); | ||
} | ||
catch (HL7Exception) | ||
{ | ||
// Throws if segment is not present | ||
} | ||
catch (Exception e) | ||
{ | ||
Console.WriteLine(e.Message); | ||
return false; | ||
} | ||
return true; | ||
} | ||
} | ||
|
||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<OutputType>Exe</OutputType> | ||
<TargetFramework>net5.0</TargetFramework> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="HL7-dotnetcore" Version="2.20.0" /> | ||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="5.0.0" /> | ||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="5.0.0" /> | ||
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="5.0.0" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<None Update="appsettings.json"> | ||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> | ||
</None> | ||
</ItemGroup> | ||
|
||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
using HL7.Dotnetcore; | ||
using Microsoft.Extensions.Configuration; | ||
using System; | ||
using System.IO; | ||
|
||
namespace Healex.HL7v2Anonymizer | ||
{ | ||
class Program | ||
{ | ||
static void Main(string[] args) | ||
{ | ||
waitForInput(); | ||
} | ||
|
||
private static void waitForInput() | ||
{ | ||
Console.WriteLine("Welcome to the Healex HL7v2 anonymizer!"); | ||
Console.WriteLine("---------------------------------------------------------------------------------------"); | ||
Console.WriteLine("WARNING: THIS APPLICATION OVERWRITES THE ORIGINAL v2 MESSAGES. BACKUP YOUR FILES FIRST!"); | ||
Console.WriteLine("---------------------------------------------------------------------------------------"); | ||
Console.WriteLine("Enter the directory to your v2 messages and press enter:"); | ||
var directory = Console.ReadLine(); | ||
Console.WriteLine(); | ||
tryAnonymizeMessages(directory); | ||
Console.WriteLine(); | ||
waitForInput(); | ||
} | ||
|
||
private static void tryAnonymizeMessages(string directory) | ||
{ | ||
var pathsToV2Messages = getPathsToV2Messages(directory); | ||
var anonymizer = new Anonymizer(getReplacementOptions()); | ||
|
||
if (pathsToV2Messages is not null) | ||
{ | ||
if (pathsToV2Messages.Length == 0) | ||
Console.WriteLine($"=> No v2 messages found in {directory}"); | ||
|
||
foreach (string path in pathsToV2Messages) | ||
{ | ||
var message = readAndParseMessage(path); | ||
var success = anonymizer.Anonymize(message); | ||
serializeAndWriteMessageOrLogError(success, message, path); | ||
} | ||
} | ||
} | ||
|
||
private static void serializeAndWriteMessageOrLogError(bool success, Message message, string path) | ||
{ | ||
if (success) | ||
{ | ||
Console.WriteLine($"=> Anonymization successful: {path}"); | ||
var serializedMessage = message.SerializeMessage(true); | ||
File.WriteAllText(path, serializedMessage); | ||
} | ||
else | ||
{ | ||
Console.WriteLine($"=> Anonymization fail: {path}"); | ||
} | ||
} | ||
|
||
private static string[] getPathsToV2Messages(string directory) | ||
{ | ||
try | ||
{ | ||
var v2Messages = Directory.GetFiles(directory, "*.hl7"); | ||
return v2Messages; | ||
} | ||
catch (Exception e) | ||
{ | ||
Console.WriteLine(e.Message); | ||
return null; | ||
} | ||
} | ||
|
||
private static Message readAndParseMessage(string path) | ||
{ | ||
try | ||
{ | ||
var message = new Message(File.ReadAllText(path)); | ||
message.ParseMessage(); | ||
return message; | ||
} catch (Exception e) | ||
{ | ||
Console.Write(e.Message); | ||
return null; | ||
} | ||
} | ||
|
||
private static ReplacementOptions getReplacementOptions() | ||
{ | ||
var builder = new ConfigurationBuilder() | ||
.SetBasePath(Directory.GetCurrentDirectory()) | ||
.AddJsonFile("appsettings.json", optional: false); | ||
|
||
IConfiguration config = builder.Build(); | ||
|
||
var replacementOptions = config.GetSection("ReplacementOptions").Get<ReplacementOptions>(); | ||
return replacementOptions; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
namespace Healex.HL7v2Anonymizer | ||
{ | ||
public class ReplacementOptions | ||
{ | ||
public SegmentReplacement[] Segments { get; set; } | ||
|
||
public class SegmentReplacement | ||
{ | ||
public string Segment { get; set; } | ||
public Replacement[] Replacements { get; set; } | ||
} | ||
|
||
public class Replacement | ||
{ | ||
public string Path { get; set; } | ||
public string Value { get; set; } | ||
} | ||
} | ||
} |
Oops, something went wrong.