commit 600d8fa5ecc505e2a435abb291f61d35570164f0 Author: shadab ahmed Date: Mon Jul 22 13:19:51 2024 +0530 Initial Commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0ff549a --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/bin/ +/obj/ \ No newline at end of file diff --git a/DicomMigratorApp.csproj b/DicomMigratorApp.csproj new file mode 100644 index 0000000..65b7216 --- /dev/null +++ b/DicomMigratorApp.csproj @@ -0,0 +1,23 @@ + + + + Exe + net6.0 + enable + enable + + + + + + + + + + + + + + + + diff --git a/Program.cs b/Program.cs new file mode 100644 index 0000000..c625fa2 --- /dev/null +++ b/Program.cs @@ -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 _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() + .CreateLogger(); + + _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 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; } + } +}