Initial Commit
This commit is contained in:
commit
600d8fa5ec
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
/bin/
|
||||
/obj/
|
||||
23
DicomMigratorApp.csproj
Normal file
23
DicomMigratorApp.csproj
Normal file
@ -0,0 +1,23 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="fo-dicom" Version="5.1.3" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="8.0.2" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="8.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
|
||||
<PackageReference Include="System.Data.SqlClient" Version="4.8.6" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="8.0.0" />
|
||||
<PackageReference Include="MySql.Data" Version="9.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
176
Program.cs
Normal file
176
Program.cs
Normal file
@ -0,0 +1,176 @@
|
||||
using System;
|
||||
using MySql.Data.MySqlClient;
|
||||
using FellowOakDicom;
|
||||
using FellowOakDicom.Network;
|
||||
using FellowOakDicom.Network.Client;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace DicomMigratorApp
|
||||
{
|
||||
class Program
|
||||
{
|
||||
private static IConfiguration Configuration;
|
||||
private static ILogger<Program> _logger;
|
||||
|
||||
private static string connectionString;
|
||||
private static string targetIP;
|
||||
private static string senderAET;
|
||||
private static string targetAET;
|
||||
private static string folderLocation;
|
||||
private static int targetPort;
|
||||
|
||||
static async Task Main(string[] args)
|
||||
{
|
||||
var serviceProvider = new ServiceCollection()
|
||||
.AddLogging(config =>
|
||||
{
|
||||
config.AddConsole();
|
||||
config.SetMinimumLevel(LogLevel.Information);
|
||||
})
|
||||
.BuildServiceProvider();
|
||||
|
||||
_logger = serviceProvider.GetService<ILoggerFactory>()
|
||||
.CreateLogger<Program>();
|
||||
|
||||
_logger.LogInformation("Application started");
|
||||
|
||||
connectionString = "Server=127.0.0.1;Port=3306;Database=dms_db;User Id=root;Password=Rootmatrix23@;";
|
||||
targetIP = "127.0.0.1";
|
||||
senderAET = "MYAE";
|
||||
targetAET = "ORTHANC";
|
||||
folderLocation = "D:\\dicom_imags\\";
|
||||
var targetPortStr = "4242";
|
||||
|
||||
if (!int.TryParse(targetPortStr, out targetPort))
|
||||
{
|
||||
_logger.LogError("TargetServer__Port environment variable is not a valid integer.");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var migrationStudy = await GetMigrationStudy(connectionString);
|
||||
if (migrationStudy == null)
|
||||
{
|
||||
_logger.LogInformation("No studies found for migration.");
|
||||
return;
|
||||
}
|
||||
|
||||
_logger.LogInformation($"Retrieved studyDetails for Migration");
|
||||
|
||||
try
|
||||
{
|
||||
await MigrateStudy(migrationStudy.StudyInstanceUID, folderLocation + migrationStudy.StudyInstanceUID);
|
||||
await UpdateSourceCFind(connectionString, migrationStudy.StudyInstanceUID, "MIGRATION_COMPLETE");
|
||||
}
|
||||
catch (DicomAssociationRejectedException ex)
|
||||
{
|
||||
_logger.LogError(ex, $"Association rejected for studyInstanceUID {migrationStudy.StudyInstanceUID}");
|
||||
await UpdateSourceCFind(connectionString, migrationStudy.StudyInstanceUID, "MIGRATION_ERRORED");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, $"An error occurred while retrieving or saving studyInstanceUID {migrationStudy.StudyInstanceUID}");
|
||||
await UpdateSourceCFind(connectionString, migrationStudy.StudyInstanceUID, "MIGRATION_ERRORED");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "An error occurred in the main processing loop");
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task<SourceStudy> GetMigrationStudy(string connectionString)
|
||||
{
|
||||
var qrStudy = new SourceStudy();
|
||||
|
||||
try
|
||||
{
|
||||
using (var connection = new MySqlConnection(connectionString))
|
||||
{
|
||||
_logger.LogInformation("Opening a connection to the database");
|
||||
await connection.OpenAsync();
|
||||
_logger.LogInformation("Database connection established");
|
||||
var command = new MySqlCommand("SELECT study_instance_uid,patient_id,status FROM source_cfind WHERE status='QR_COMPLETE' LIMIT 1", connection);
|
||||
var reader = await command.ExecuteReaderAsync();
|
||||
|
||||
while (await reader.ReadAsync())
|
||||
{
|
||||
qrStudy = new SourceStudy
|
||||
{
|
||||
StudyInstanceUID = reader.IsDBNull(0) ? null : reader.GetString(0),
|
||||
PatientID = reader.IsDBNull(1) ? null : reader.GetString(1),
|
||||
Status = reader.IsDBNull(2) ? null : reader.GetString(2)
|
||||
};
|
||||
}
|
||||
|
||||
reader.Close();
|
||||
}
|
||||
if (qrStudy.StudyInstanceUID != null)
|
||||
{
|
||||
_logger.LogInformation("Picked study to be migrated from the database");
|
||||
await UpdateSourceCFind(connectionString, qrStudy.StudyInstanceUID, "MIGRATION_INPROGRESS");
|
||||
}
|
||||
else
|
||||
{
|
||||
qrStudy = null;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error retrieving study to be migrated from the database");
|
||||
}
|
||||
|
||||
return qrStudy;
|
||||
}
|
||||
|
||||
private static async Task UpdateSourceCFind(string connectionString, string study_instance_uid, string updateStatus)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var connection = new MySqlConnection(connectionString))
|
||||
{
|
||||
await connection.OpenAsync();
|
||||
var command = new MySqlCommand("UPDATE source_cfind SET status = @Status WHERE study_instance_uid = @StudyInstanceUID", connection);
|
||||
|
||||
command.Parameters.AddWithValue("@StudyInstanceUID", study_instance_uid);
|
||||
command.Parameters.AddWithValue("@Status", updateStatus);
|
||||
|
||||
await command.ExecuteNonQueryAsync();
|
||||
_logger.LogInformation($"Updated source C-FIND record for study instance uid {study_instance_uid}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, $"Error updating source study record for study {study_instance_uid}");
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task MigrateStudy(string studyInstanceUID, string folderPath)
|
||||
{
|
||||
var client = DicomClientFactory.Create(targetIP, targetPort, false, senderAET, targetAET);
|
||||
|
||||
var files = System.IO.Directory.GetFiles(folderPath, "*");
|
||||
foreach (var file in files)
|
||||
{
|
||||
var dicomFile = await DicomFile.OpenAsync(file);
|
||||
await client.AddRequestAsync(new DicomCStoreRequest(dicomFile));
|
||||
}
|
||||
|
||||
await client.SendAsync();
|
||||
|
||||
_logger.LogInformation($"Migrated studyInstanceUID {studyInstanceUID} to target AET {targetAET}");
|
||||
}
|
||||
}
|
||||
|
||||
class SourceStudy
|
||||
{
|
||||
public string PatientID { get; set; }
|
||||
public string StudyInstanceUID { get; set; }
|
||||
public string Status { get; set; }
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user