// Copyright (c) 2017 schick Informatik
// Description: Controls zur Statusanzeige auf dem Server
//
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows.Controls;
using System.Text.RegularExpressions;
using System.Globalization;
using log4net;
using bsmd.database;
using System.ServiceProcess;
using System.ComponentModel;
namespace ENI2.Controls
{
///
/// Interaction logic for ServerStatusControl.xaml
///
public partial class ServerStatusControl : UserControl
{
private readonly ObservableCollection entries = new ObservableCollection();
private readonly static Regex regex = new Regex(@"BSMD_(\d*)-(.*)-(\w*)");
private readonly static ILog _log = LogManager.GetLogger("ServerStatus");
private ProgressBar _updateProgressBar;
private TextBlock _updateTextBlock;
private bool _isUpdating = false;
private readonly static Dictionary coreIdVisitIdMap = new Dictionary();
public ServerStatusControl()
{
InitializeComponent();
this.dataGridStatus.ItemsSource = this.entries;
this.Loaded += ServerStatusControl_Loaded;
}
private void ServerStatusControl_Loaded(object sender, System.Windows.RoutedEventArgs e)
{
this.refreshButton_Click(null, null);
}
internal void Update(LockingServiceReference.ServerStatus serverStatus)
{
if (this._isUpdating) return;
_isUpdating = true;
int totalNum = serverStatus.IMPFiles.Length + serverStatus.READYFiles.Length + serverStatus.CORRUPTFiles.Length;
entries.Clear();
BackgroundWorker bgWorker = new BackgroundWorker();
bgWorker.DoWork += (o, e) =>
{
System.Windows.Application.Current.Dispatcher.Invoke(delegate {
this._updateProgressBar.Maximum = totalNum;
this._updateProgressBar.Value = 0;
});
int counter = 0;
// Die Dateien müssen in die Objekte
List tmpList = new List();
foreach (string filename in serverStatus.IMPFiles)
{
StatusEntry se = StatusEntry.Create(filename, "IMP");
tmpList.Add(se);
counter++;
System.Windows.Application.Current.Dispatcher.Invoke(delegate {
this._updateTextBlock.Text = string.Format(Properties.Resources.textUpdatingFile, counter, totalNum);
this._updateProgressBar.Value = counter;
});
}
foreach (string filename in serverStatus.READYFiles)
{
StatusEntry se = StatusEntry.Create(filename, "READY");
tmpList.Add(se);
counter++;
System.Windows.Application.Current.Dispatcher.Invoke(delegate {
this._updateTextBlock.Text = string.Format(Properties.Resources.textUpdatingFile, counter, totalNum);
this._updateProgressBar.Value = counter;
});
}
foreach (string filename in serverStatus.CORRUPTFiles)
{
StatusEntry se = StatusEntry.Create(filename, "CORRUPT");
tmpList.Add(se);
counter++;
System.Windows.Application.Current.Dispatcher.Invoke(delegate {
this._updateTextBlock.Text = string.Format(Properties.Resources.textUpdatingFile, counter, totalNum);
this._updateProgressBar.Value = counter;
});
}
tmpList.Sort();
System.Windows.Application.Current.Dispatcher.Invoke(delegate {
foreach (StatusEntry se in tmpList)
entries.Add(se);
});
};
bgWorker.RunWorkerCompleted += (o, e) =>
{
// Enumeration parsen und text ausgeben
ServiceControllerStatus transmitter = (ServiceControllerStatus)serverStatus.Transmitter;
this.labelStatusTransmitter.Content = transmitter.ToString();
this.busyIndicator.IsBusy = false;
_isUpdating = false;
};
this.busyIndicator.IsBusy = true;
bgWorker.RunWorkerAsync();
}
public class StatusEntry : IComparable
{
private static readonly Dictionary guidIdDict = new Dictionary();
public string Class { get; set; }
public DateTime Timestamp { get; set; }
public string Id { get; set; }
public string Status { get; set; }
public static StatusEntry Create(string filename, string status)
{
StatusEntry result = null;
if (regex.IsMatch(filename))
{
try
{
StatusEntry entry = new StatusEntry();
Match m = regex.Match(filename);
entry.Timestamp = DateTime.ParseExact(m.Groups[1].Value, "yyyyMMddHHmmss", CultureInfo.InvariantCulture);
string guidString = m.Groups[2].Value;
string idString = "";
if (!guidIdDict.ContainsKey(guidString))
{
if (Guid.TryParse(m.Groups[2].Value, out Guid coreId))
{
if (!coreIdVisitIdMap.ContainsKey(coreId))
{
MessageCore aCore = DBManager.Instance.GetMessageCoreById(coreId);
if (aCore != null)
{
coreIdVisitIdMap[coreId] = aCore.DisplayId;
idString = aCore.DisplayId;
}
}
else
{
idString = coreIdVisitIdMap[coreId];
}
}
guidIdDict[guidString] = idString;
}
entry.Id = guidIdDict[guidString];
entry.Class = m.Groups[3].Value;
entry.Status = status;
result = entry;
}
catch (Exception ex)
{
_log.WarnFormat("Problem reading status info: {0}", ex.Message);
}
}
return result;
}
public static void ClearIds() { guidIdDict.Clear(); }
public int CompareTo(object obj)
{
if(obj is StatusEntry entry)
return -(Timestamp.CompareTo(entry.Timestamp));
return 0;
}
}
private void refreshButton_Click(object sender, System.Windows.RoutedEventArgs e)
{
StatusEntry.ClearIds();
if (App.LockingServiceClient != null)
{
try
{
LockingServiceReference.ServerStatus serverStatus = App.LockingServiceClient.GetStatus();
if (serverStatus != null)
{
this.Update(serverStatus);
}
}
catch (Exception ex)
{
_log.DebugFormat("LockingService.GetStatus() threw an exception: {0}", ex.Message);
}
}
}
private void textUpdateProgress_Loaded(object sender, System.Windows.RoutedEventArgs e)
{
if (sender != null) this._updateTextBlock = sender as TextBlock;
}
private void progressBarUpdate_Loaded(object sender, System.Windows.RoutedEventArgs e)
{
if (sender != null) this._updateProgressBar = sender as ProgressBar;
}
}
}