DicomMigratorApp/Program.cs
2024-07-24 00:27:44 +05:30

186 lines
7.3 KiB
C#

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;
using System.Threading;
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 int targetPort;
private static string db_status_to_pick;
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 = Environment.GetEnvironmentVariable("ConnectionStrings__DefaultConnection") ?? "Server=127.0.0.1;Port=3306;Database=dms_db;User Id=root;Password=Rootmatrix23@;";
targetIP = Environment.GetEnvironmentVariable("Dest__IP") ?? "127.0.0.1";
senderAET = Environment.GetEnvironmentVariable("Sender__AET") ?? "MYAE";
targetAET = Environment.GetEnvironmentVariable("Dest__AET") ?? "ORTHANC";
var targetPortStr = Environment.GetEnvironmentVariable("Dest__Port") ?? "4242";
db_status_to_pick = Environment.GetEnvironmentVariable("DB_STATUS") ?? "MIGRATION_QUEUE";
if (!int.TryParse(targetPortStr, out targetPort))
{
_logger.LogError("TargetServer__Port environment variable is not a valid integer.");
return;
}
while (true)
{
try
{
var imagePaths = await GetMigrationImages(connectionString,db_status_to_pick);
if (imagePaths == null || imagePaths.Count == 0)
{
await Task.Delay(5000);
continue;
}
foreach (var image in imagePaths)
{
try
{
await MigrateImage(image.Path);
await UpdateImagePathStatus(connectionString, image.Id, "MIGRATION_COMPLETE");
}
catch (DicomAssociationRejectedException ex)
{
_logger.LogError(ex, $"Association rejected for image path {image.Path}");
await UpdateImagePathStatus(connectionString, image.Id, "MIGRATION_ERRORED");
}
catch (Exception ex)
{
_logger.LogError(ex, $"An error occurred while migrating image path {image.Path}");
await UpdateImagePathStatus(connectionString, image.Id, "MIGRATION_ERRORED");
}
}
}
catch (MySqlException ex)
{
_logger.LogError(ex, "An error occurred while connecting to the database");
break;
}
catch (Exception ex)
{
_logger.LogError(ex, "An error occurred in the main processing loop");
break;
}
}
}
private static async Task<List<ImageRecord>> GetMigrationImages(string connectionString, string db_status_to_pick)
{
var imagePaths = new List<ImageRecord>();
try
{
using (var connection = new MySqlConnection(connectionString))
{
await connection.OpenAsync();
_logger.LogInformation("Database connection established");
var command = new MySqlCommand("SELECT id, image_path FROM priority_migration_image WHERE status=@Status order by priority LIMIT 10", connection);
command.Parameters.AddWithValue("@Status", db_status_to_pick);
var reader = await command.ExecuteReaderAsync();
while (await reader.ReadAsync())
{
imagePaths.Add(new ImageRecord
{
Id = reader.IsDBNull(0) ? 0 : reader.GetInt32(0),
Path = reader.IsDBNull(1) ? null : reader.GetString(1)
});
}
reader.Close();
}
_logger.LogInformation($"Retrieved {imagePaths.Count} image paths for migration");
}
catch (Exception ex)
{
_logger.LogError(ex, "Error retrieving image paths from the database");
throw; // Re-throw the exception to ensure it is caught by the outer try-catch block
}
return imagePaths;
}
private static async Task UpdateImagePathStatus(string connectionString, int imageId, string updateStatus)
{
try
{
using (var connection = new MySqlConnection(connectionString))
{
await connection.OpenAsync();
var command = new MySqlCommand("UPDATE priority_migration_image SET status = @Status WHERE id = @ImageId", connection);
command.Parameters.AddWithValue("@ImageId", imageId);
command.Parameters.AddWithValue("@Status", updateStatus);
await command.ExecuteNonQueryAsync();
_logger.LogInformation($"Updated image path record for image ID {imageId} with status {updateStatus}");
}
}
catch (Exception ex)
{
_logger.LogError(ex, $"Error updating image path record for image ID {imageId}");
throw; // Re-throw the exception to ensure it is caught by the outer try-catch block
}
}
private static async Task MigrateImage(string imagePath)
{
try
{
var client = DicomClientFactory.Create(targetIP, targetPort, false, senderAET, targetAET);
var dicomFile = await DicomFile.OpenAsync(imagePath);
await client.AddRequestAsync(new DicomCStoreRequest(dicomFile));
await client.SendAsync();
_logger.LogInformation($"Migrated image {imagePath} to target AET {targetAET}");
}
catch (Exception ex)
{
_logger.LogError(ex, $"Error migrating image {imagePath}");
throw; // Re-throw the exception to ensure it is caught by the outer try-catch block
}
}
}
class ImageRecord
{
public int Id { get; set; }
public string Path { get; set; }
}
}