git_bsmd/bsmd.hisnord/transmitter.cs

169 lines
6.8 KiB
C#

//
// Class: transmitter
// Current CLR: 4.0.30319.34209
// System: Microsoft Visual Studio 10.0
// Author: dani
// Created: 7/14/2015 7:39:29 AM
//
// Copyright (c) 2015 Informatikbüro Daniel Schick. All rights reserved.
using System;
using System.Diagnostics;
using System.IO;
using bsmd.database;
using log4net;
namespace bsmd.hisnord
{
public class transmitter
{
private static readonly ILog _log = LogManager.GetLogger(typeof(transmitter));
private static int? processId;
public static bool Transmit()
{
string rootDir = Properties.Settings.Default.TransmitterRoot;
if(processId.HasValue)
{
_log.InfoFormat("Transmitter process {0} still running, aborting call", processId);
return false;
}
try
{
ProcessStartInfo startInfo = new ProcessStartInfo(Path.Combine(rootDir, Properties.Settings.Default.Transmitter));
startInfo.WorkingDirectory = rootDir;
startInfo.RedirectStandardError = true;
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardInput = false;
startInfo.UseShellExecute = false;
using (Process transmitterProcess = new Process())
{
transmitterProcess.Exited += TransmitterProcess_Exited;
transmitterProcess.ErrorDataReceived += TransmitterProcess_ErrorDataReceived;
transmitterProcess.OutputDataReceived += TransmitterProcess_OutputDataReceived;
transmitterProcess.StartInfo = startInfo;
transmitterProcess.EnableRaisingEvents = true;
transmitterProcess.Start();
transmitterProcess.BeginErrorReadLine();
transmitterProcess.BeginOutputReadLine();
processId = transmitterProcess.Id;
// _log.DebugFormat("started {0}", transmitterProcess.ProcessName);
int timeout = Properties.Settings.Default.BatchTimeoutMins * 1000 * 60; // convert to ms
_log.DebugFormat($"starting transmitter, process ID: {processId}, timeout {timeout} ms.");
if (!transmitterProcess.WaitForExit((timeout == 0) ? int.MaxValue : timeout))
{
_log.Warn($"Transmitter {processId} not exited within {timeout} ms");
try
{
transmitterProcess.Kill();
_log.Warn($"Transmitter {processId} killed");
processId = null;
}
catch (Exception e)
{
_log.Warn($"Killing Transmitter {processId} failed: {e.Message}");
}
}
else
{
int exitCode = transmitterProcess.ExitCode;
if (exitCode != 0)
{
string errorText = "";
switch(exitCode)
{
case 1: errorText = "Schema violation"; break;
case 2:
case 3: errorText = "Element must not be null"; break;
case 1000: errorText = "Internal error"; break;
case 1001: errorText = "Access denied - Login"; break;
case 1004: errorText = "Access denied - Internal Configuration"; break;
case 1005: errorText = "Internal configuration error"; break;
case 2000: errorText = "File not found"; break;
}
_log.ErrorFormat("Transmitter returned code {0}: {1}", exitCode, errorText);
}
}
}
return true;
}
catch (Exception ex)
{
_log.Error($"Transmitter failed: {ex.Message}");
return false;
}
}
private static void TransmitterProcess_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
if(!e.Data.IsNullOrEmpty())
_log.Debug(e.Data);
}
private static void TransmitterProcess_ErrorDataReceived(object sender, DataReceivedEventArgs e)
{
// Output of STDERR. HIS-Nord seems to be using this for logging, so we do not flag as error.
if(!e.Data.IsNullOrEmpty())
_log.Debug(e.Data);
}
private static void TransmitterProcess_Exited(object sender, EventArgs e)
{
_log.Debug("Transmitter process exited");
processId = null;
}
public static void PurgeOldFiles(int maxAgeDays)
{
try
{
// "import_done" (= successfully received)
DirectoryInfo info = new DirectoryInfo(Path.Combine(Properties.Settings.Default.TransmitterRoot, Properties.Settings.Default.AnswerArchiveDir));
FileInfo[] files = info.GetFiles();
int cnt = 0;
foreach (FileInfo file in files)
{
if (file.CreationTime < DateTime.Now.AddDays(-maxAgeDays))
{
_log.Debug($"deleting {file.Name}");
file.Delete();
cnt++;
}
}
_log.Info($"deleted {cnt} files from {Properties.Settings.Default.AnswerArchiveDir}");
// "archive" (= successfully sent)
cnt = 0;
info = new DirectoryInfo(Path.Combine(Properties.Settings.Default.TransmitterRoot, Properties.Settings.Default.OutputArchiveDir));
files = info.GetFiles();
foreach (FileInfo file in files)
{
if (file.CreationTime < DateTime.Now.AddDays(-maxAgeDays))
{
_log.Debug($"deleting {file.Name}");
file.Delete();
cnt++;
}
}
_log.Info($"deleted {cnt} files from {Properties.Settings.Default.OutputArchiveDir}");
}
catch(Exception ex)
{
_log.ErrorFormat("Error trying to delete old files: {0}", ex.Message);
}
}
}
}