Initial Commit
This commit is contained in:
356
TomcatServer/RegistrationServer/RegistrationService.cs
Normal file
356
TomcatServer/RegistrationServer/RegistrationService.cs
Normal file
@@ -0,0 +1,356 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.ServiceProcess;
|
||||
using System.Text;
|
||||
using Pluto.Registration;
|
||||
using System.Reflection;
|
||||
using Yaulw.Thread;
|
||||
|
||||
namespace RegistrationServer
|
||||
{
|
||||
public partial class RegistrationService : ServiceBase
|
||||
{
|
||||
|
||||
#region Internal Consts
|
||||
|
||||
// Threshold used to determine if system just rebooted, and service just
|
||||
// started. We need to wait a little because we need to make sure the Database Server is up
|
||||
internal const int NUMBER_OF_MINUTES_SERVICE_UP_THRESHOLD = 5;
|
||||
internal const int NUMBER_OF_MINUTES_SYSTEM_UP_THRESHOLD = 10;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Internal Statics
|
||||
|
||||
/// <summary>
|
||||
/// Service Start Time
|
||||
/// </summary>
|
||||
internal static DateTime ServiceStartDT = DateTime.MinValue;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Members
|
||||
|
||||
/// <summary>
|
||||
/// Check if this is the first time the network got enabled
|
||||
/// </summary>
|
||||
private bool FirstTimeNetworkConnected = true;
|
||||
|
||||
/// <summary>
|
||||
/// Was the Channel Activated?
|
||||
/// </summary>
|
||||
private bool ROHasBeenActivated = false;
|
||||
|
||||
/// <summary>
|
||||
/// Did a System Reboot just occur?
|
||||
/// </summary>
|
||||
private bool SystemJustStarted_SoUseServiceThreshold = false;
|
||||
private bool ServiceUpTimeReached = false;
|
||||
private bool SystemThresholdNotReached = true;
|
||||
|
||||
/// <summary>
|
||||
/// Is the Logger Setup?
|
||||
/// </summary>
|
||||
private bool LoggerIsSetup = false;
|
||||
|
||||
/// <summary>
|
||||
/// Our Connectivity Timer Thread
|
||||
/// </summary>
|
||||
private SingleThreadTimer connectivityTimer = null;
|
||||
|
||||
/// <summary>
|
||||
/// If for some reason the network goes down, we should re-initialize
|
||||
/// everything as if nothing happened
|
||||
/// </summary>
|
||||
private bool NetworkOutageDetected = false;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Construction
|
||||
|
||||
/// <summary>
|
||||
/// Singleton Instance of the Service
|
||||
/// </summary>
|
||||
internal static RegistrationService s_RegistrationService = null;
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
public RegistrationService()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
// Log to the Application System Log
|
||||
this.EventLog.Log = "Application";
|
||||
s_RegistrationService = this;
|
||||
|
||||
// Handle all unexpected errors
|
||||
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unhandled Domain Exception
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
|
||||
{
|
||||
Exception ex = (Exception)e.ExceptionObject;
|
||||
String msg = "UnhandledException Occured: " + ex.Message + "\n\n" + ex.InnerException.Message;
|
||||
AppLogError(msg);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Windows Event Logging
|
||||
|
||||
internal static void AppLogError(string errMsg)
|
||||
{
|
||||
s_RegistrationService.EventLog.WriteEntry(errMsg, EventLogEntryType.Error);
|
||||
if (Registration.Logger != null)
|
||||
Registration.Logger.Error(errMsg);
|
||||
}
|
||||
|
||||
internal static void AppLogInfo(string infoMsg)
|
||||
{
|
||||
s_RegistrationService.EventLog.WriteEntry(infoMsg, EventLogEntryType.Information);
|
||||
if (Registration.Logger != null)
|
||||
Registration.Logger.Info(infoMsg);
|
||||
}
|
||||
|
||||
internal static void AppLogWarning(string warnMsg)
|
||||
{
|
||||
s_RegistrationService.EventLog.WriteEntry(warnMsg, EventLogEntryType.Warning);
|
||||
if (Registration.Logger != null)
|
||||
Registration.Logger.Info(warnMsg);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
// usefull for debugging Service in visual studio
|
||||
#if DEBUG
|
||||
internal void DebugStart(string[] args)
|
||||
{
|
||||
DEBUGGING_ONLY.DEBUGSTEP_INTO();
|
||||
OnStart(args);
|
||||
}
|
||||
#endif
|
||||
|
||||
#region System / Service Up Time
|
||||
|
||||
/// <summary>
|
||||
/// Get Service UpTime
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private TimeSpan GetServiceUpTime()
|
||||
{
|
||||
return (DateTime.Now - ServiceStartDT);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// For Service Handling, see if the system has been up long enough
|
||||
/// Once it becomes true, it will always return true
|
||||
/// </summary>
|
||||
private bool HasServiceBeenUpLongEnough()
|
||||
{
|
||||
if (!ServiceUpTimeReached)
|
||||
ServiceUpTimeReached = GetServiceUpTime().TotalMinutes >= NUMBER_OF_MINUTES_SERVICE_UP_THRESHOLD;
|
||||
return ServiceUpTimeReached;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// For Error Handling, see if the system has been up till this threshold
|
||||
/// Once it becomes false, will always return false
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private bool IsSystemBeenUpWithinMaxThreshold()
|
||||
{
|
||||
if (SystemThresholdNotReached)
|
||||
SystemThresholdNotReached = (Yaulw.Installer.Common.GetSystemUpTime().TotalMinutes <= NUMBER_OF_MINUTES_SYSTEM_UP_THRESHOLD);
|
||||
return SystemThresholdNotReached;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Service Start-Up
|
||||
/// </summary>
|
||||
/// <param name="args"></param>
|
||||
protected override void OnStart(string[] args)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Service Started
|
||||
// System just started, so make sure that service is timing out a little to make
|
||||
// sure everything is up and running
|
||||
SystemJustStarted_SoUseServiceThreshold = IsSystemBeenUpWithinMaxThreshold();
|
||||
AppLogInfo(String.Format("MSLMobile Gateway Service started up at: {0}. System Reboot detected: {1}", DateTime.Now.ToLongTimeString(), SystemJustStarted_SoUseServiceThreshold));
|
||||
ServiceStartDT = DateTime.Now;
|
||||
|
||||
// Internet / Network Connectivity Timer
|
||||
// * Ran into issues when computer is rebooted, we need certain things working before the service can start,
|
||||
// * therefore decided to put DataStore Read(), AutoUpdate, RO Connection into a Connection Timer,
|
||||
// that keeps checking every 10 seconds if we have network connectivity * Enables / Disables RO Channels as needed, just in case *
|
||||
AppLogInfo("MSLMobile Gateway Service starting connectivity timer.");
|
||||
connectivityTimer = new SingleThreadTimer(ConnectivityHandler, (uint)TimeSpan.FromSeconds(10).TotalMilliseconds, true);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
AppLogError(String.Format("Service OnStart() Error thrown. Fatal. Can't continue: {0}", e.Message));
|
||||
this.Stop();
|
||||
}
|
||||
}
|
||||
|
||||
#region Private Connectivity Timed Thread (runs every 10 Seconds)
|
||||
|
||||
/// <summary>
|
||||
/// Single Threaded Connectivity Handler (Handles Auto-Update, ReadInDataStore(), and RO Channels)
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void ConnectivityHandler(object sender, Yaulw.Thread.SingleThreadTimer.STElapsedEventArgs e)
|
||||
{
|
||||
// System just started, we won't do anyting in here until our
|
||||
// Service Startup 'NUMBER_OF_MINUTES_SERVICE_UP_THRESHOLD' timeout of is reached
|
||||
if (SystemJustStarted_SoUseServiceThreshold && !HasServiceBeenUpLongEnough())
|
||||
return;
|
||||
|
||||
// Check Connectivity,
|
||||
// ~withouth basic networking being up there is nothing really to do here
|
||||
bool bHasConnection = Yaulw.Net.IPHostHelper.HasConnection();
|
||||
if (!bHasConnection)
|
||||
{
|
||||
DeactivateChannelIfActivated(true);
|
||||
return;
|
||||
}
|
||||
|
||||
// Always set up the Logger First (Needed for all subsequent DB Calls)
|
||||
if (!LoggerIsSetup)
|
||||
{
|
||||
AppLogInfo("Setting up Logger");
|
||||
Registration.Setup_Logger();
|
||||
LoggerIsSetup = true;
|
||||
}
|
||||
|
||||
// * Check to Make sure the System has been up long enough *
|
||||
// Calling VerifyConnectivity() requires SQL Server to be up
|
||||
// and running and hence, we can't do it right at service start when the
|
||||
// server just rebooted, we wait 5 of service uptime to make sure after a server reboot,
|
||||
// that the services needed are up
|
||||
if (FirstTimeNetworkConnected)
|
||||
{
|
||||
AppLogInfo("System has been up long enough. Starting Initialization.");
|
||||
|
||||
// Make sure we can connect to the Database
|
||||
try
|
||||
{
|
||||
if (!DataAccessLayer.VerifyConnectivity())
|
||||
{
|
||||
AppLogError("Cannot verify SQL Server Credentials upon initialization. Service must be stopped.");
|
||||
this.Stop();
|
||||
}
|
||||
else
|
||||
{
|
||||
AppLogInfo("Success. SQL Server Credentials could connect upon initialization.");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
AppLogError(String.Format("Cannot verify SQL Server Credentials upon initialization '{0}'. Service must be stopped.", ex.Message));
|
||||
this.Stop();
|
||||
}
|
||||
FirstTimeNetworkConnected = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// We have a valid SQL Server Connection, hence we can continue
|
||||
if (!FirstTimeNetworkConnected)
|
||||
{
|
||||
// If Network disconnection occured, we should try to re-read in everything,
|
||||
// to make sure we are doing the best we can
|
||||
if (NetworkOutageDetected)
|
||||
{
|
||||
AppLogInfo("Network Outage Detected - Trying to retry connecting to SQL Server");
|
||||
// Make sure we can connect to the Database
|
||||
try
|
||||
{
|
||||
if (!DataAccessLayer.VerifyConnectivity())
|
||||
AppLogError("Cannot verify SQL Server Credentials after Network Outage.");
|
||||
else
|
||||
AppLogInfo("Success. SQL Server Credentials could connect after Networ Outage.");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
AppLogError(String.Format("Cannot verify SQL Server Credentials after Network Outage '{0}'.", ex.Message));
|
||||
}
|
||||
}
|
||||
|
||||
// Activate the RO Channel
|
||||
ActivateChannelIfNotActivated();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private RO Channel Helpers
|
||||
|
||||
/// <summary>
|
||||
/// Activate all Channel
|
||||
/// </summary>
|
||||
private void ActivateChannelIfNotActivated()
|
||||
{
|
||||
if (!ROHasBeenActivated)
|
||||
{
|
||||
SetPort(Configuration.Port);
|
||||
ServerChannel.Activate();
|
||||
ROHasBeenActivated = true;
|
||||
AppLogInfo(String.Format("MSLMobile Gateway Service Channel Activated on Port:{0}.", Configuration.Port));
|
||||
NetworkOutageDetected = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deactivate RO Channel
|
||||
/// </summary>
|
||||
private void DeactivateChannelIfActivated(bool bNetworkOutage)
|
||||
{
|
||||
if (ROHasBeenActivated)
|
||||
{
|
||||
ServerChannel.Deactivate();
|
||||
ROHasBeenActivated = false;
|
||||
AppLogInfo("MSLMobile Gateway Service Channel Deactivated.");
|
||||
NetworkOutageDetected = bNetworkOutage;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
// usefull for debugging Service in visual studio
|
||||
#if DEBUG
|
||||
internal void DebugStop() { OnStop(); }
|
||||
#endif
|
||||
/// <summary>
|
||||
/// SCM OnStop() call-in
|
||||
/// </summary>
|
||||
protected override void OnStop()
|
||||
{
|
||||
try
|
||||
{
|
||||
// First stop the internal connectivity timer
|
||||
if (connectivityTimer != null)
|
||||
{
|
||||
AppLogInfo("MSLMobile Gateway Service connectivity timer stopped.");
|
||||
connectivityTimer.Stop();
|
||||
}
|
||||
|
||||
DeactivateChannelIfActivated(false);
|
||||
AppLogInfo("End DeactivateChannelIfActivated.");
|
||||
}
|
||||
catch (Exception) { /* ignore */ }
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user