// // 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); } } } }