2013-06-24 13:41:48 +02:00
|
|
|
|
/* Copyright (c) Citrix Systems Inc.
|
|
|
|
|
* All rights reserved.
|
|
|
|
|
*
|
|
|
|
|
* Redistribution and use in source and binary forms,
|
|
|
|
|
* with or without modification, are permitted provided
|
|
|
|
|
* that the following conditions are met:
|
|
|
|
|
*
|
|
|
|
|
* * Redistributions of source code must retain the above
|
|
|
|
|
* copyright notice, this list of conditions and the
|
|
|
|
|
* following disclaimer.
|
|
|
|
|
* * Redistributions in binary form must reproduce the above
|
|
|
|
|
* copyright notice, this list of conditions and the
|
|
|
|
|
* following disclaimer in the documentation and/or other
|
|
|
|
|
* materials provided with the distribution.
|
|
|
|
|
*
|
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
|
|
|
|
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
|
|
|
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
|
|
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
|
|
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
|
|
|
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
|
|
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
|
|
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
|
|
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
|
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
|
|
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
|
|
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
|
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
|
|
|
* SUCH DAMAGE.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
using System;
|
|
|
|
|
using System.Timers;
|
|
|
|
|
using XenAdmin.Actions;
|
2013-08-05 18:41:46 +02:00
|
|
|
|
using XenAdmin.Alerts;
|
2013-06-24 13:41:48 +02:00
|
|
|
|
using XenAdmin.Core;
|
|
|
|
|
using XenAdmin.Network;
|
|
|
|
|
using XenAPI;
|
|
|
|
|
using XenAdmin.Dialogs;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace XenAdmin
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// A custom Timer that checks at regular intervals if any server licenses have expired. Also contains logic
|
|
|
|
|
/// for testing license state on connection as to whether we should warn about a soon to expire license.
|
|
|
|
|
/// </summary>
|
|
|
|
|
class LicenseTimer : System.Timers.Timer
|
|
|
|
|
{
|
|
|
|
|
private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
|
|
|
|
|
|
|
|
|
private static readonly TimeSpan EXPIRED_REMINDER_FREQUENCY = new TimeSpan(0, 0, 30, 0); // How frequently to remind user when a license has expired
|
|
|
|
|
private static readonly TimeSpan CONNECTION_WARN_THRESHOLD = new TimeSpan(29, 0, 0, 0); // When to start warning on connection
|
|
|
|
|
private static readonly TimeSpan RUNNING_WARN_FREQUENCY = new TimeSpan(1, 0, 0, 0); // How frequently to remind when XC is running
|
|
|
|
|
|
|
|
|
|
private static DateTime lastPeriodicLicenseWarning;
|
|
|
|
|
private readonly LicenseManagerLauncher licenseManagerLauncher;
|
|
|
|
|
|
|
|
|
|
public LicenseTimer(LicenseManagerLauncher licenseManagerLauncher)
|
|
|
|
|
{
|
|
|
|
|
Elapsed += new ElapsedEventHandler(licenseTimerElapsed);
|
|
|
|
|
AutoReset = true;
|
|
|
|
|
Interval = EXPIRED_REMINDER_FREQUENCY.TotalMilliseconds;
|
|
|
|
|
lastPeriodicLicenseWarning = DateTime.UtcNow;
|
|
|
|
|
this.licenseManagerLauncher = licenseManagerLauncher;
|
|
|
|
|
Start();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2013-10-15 18:15:21 +02:00
|
|
|
|
/// Call this to check the server licenses when a connection has been made or on periodic check.
|
2013-06-24 13:41:48 +02:00
|
|
|
|
/// If a license has expired, the user is warned.
|
2013-10-15 18:15:21 +02:00
|
|
|
|
/// The logic for the periodic license warning check: only shows the less than 30 day warnings once every day XC is running.
|
2013-06-24 13:41:48 +02:00
|
|
|
|
/// </summary>
|
2013-10-15 18:15:21 +02:00
|
|
|
|
/// <param name="connection">The connection to check licenses on</param>
|
|
|
|
|
/// <param name="periodicCheck">Whehter it is a periodic check</param>
|
|
|
|
|
internal bool CheckActiveServerLicense(IXenConnection connection, bool periodicCheck)
|
2013-06-24 13:41:48 +02:00
|
|
|
|
{
|
2016-01-26 17:30:24 +01:00
|
|
|
|
// don't popup the license manager dialog if host is ClearwaterOrGreater and the feature is disabled
|
2016-01-28 22:43:15 +01:00
|
|
|
|
bool popupLicenseMgr = !(Helpers.ClearwaterOrGreater(connection) && HiddenFeatures.LicenseNagHidden);
|
2016-01-26 17:30:24 +01:00
|
|
|
|
|
|
|
|
|
// If the host is Dundee or greater, then the license alerts are generated by the server, so XenCenter shouldn't create any license alerts
|
|
|
|
|
bool createAlert = !Helpers.DundeeOrGreater(connection);
|
|
|
|
|
|
|
|
|
|
if (!popupLicenseMgr && !createAlert)
|
2013-10-15 18:15:21 +02:00
|
|
|
|
return false;
|
|
|
|
|
|
2013-06-24 13:41:48 +02:00
|
|
|
|
DateTime now = DateTime.UtcNow - connection.ServerTimeOffset;
|
|
|
|
|
foreach (Host host in connection.Cache.Hosts)
|
|
|
|
|
{
|
|
|
|
|
if (host.IsXCP)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
DateTime expiryDate = host.LicenseExpiryUTC;
|
|
|
|
|
TimeSpan timeToExpiry = expiryDate.Subtract(now);
|
|
|
|
|
|
|
|
|
|
if (expiryDate < now)
|
|
|
|
|
{
|
2013-10-15 18:15:21 +02:00
|
|
|
|
// License has expired. Pop up the License Manager.
|
2016-01-26 17:30:24 +01:00
|
|
|
|
Program.Invoke(Program.MainWindow, () => showLicenseSummaryExpired(host, now, expiryDate, createAlert, popupLicenseMgr));
|
2013-10-15 18:15:21 +02:00
|
|
|
|
return true;
|
2013-06-24 13:41:48 +02:00
|
|
|
|
}
|
2013-10-15 18:15:21 +02:00
|
|
|
|
if (timeToExpiry < CONNECTION_WARN_THRESHOLD &&
|
|
|
|
|
(!periodicCheck || DateTime.UtcNow.Subtract(lastPeriodicLicenseWarning) > RUNNING_WARN_FREQUENCY))
|
2013-06-24 13:41:48 +02:00
|
|
|
|
{
|
2013-10-15 18:15:21 +02:00
|
|
|
|
// If the license is sufficiently close to expiry date, show the warning
|
|
|
|
|
// If it's a periodic check, only warn if XC has been open for one day
|
|
|
|
|
if (periodicCheck)
|
|
|
|
|
lastPeriodicLicenseWarning = DateTime.UtcNow;
|
2016-01-26 17:30:24 +01:00
|
|
|
|
Program.Invoke(Program.MainWindow, () => showLicenseSummaryWarning(Helpers.GetName(host), now, expiryDate, createAlert, popupLicenseMgr));
|
2013-10-15 18:15:21 +02:00
|
|
|
|
return true;
|
|
|
|
|
}
|
2013-06-24 13:41:48 +02:00
|
|
|
|
}
|
2013-10-15 18:15:21 +02:00
|
|
|
|
return false;
|
2013-06-24 13:41:48 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Check to see if any licenses have expired as the timer periodically elapses.
|
|
|
|
|
/// </summary>
|
|
|
|
|
private void licenseTimerElapsed(object sender, ElapsedEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
if (licenseManagerLauncher.LicenceDialogIsShowing)
|
|
|
|
|
return;
|
|
|
|
|
foreach (IXenConnection xc in ConnectionsManager.XenConnectionsCopy)
|
|
|
|
|
{
|
2013-10-15 18:15:21 +02:00
|
|
|
|
if (CheckActiveServerLicense(xc, true))
|
2013-06-24 13:41:48 +02:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Shows the license summary dialog to the user as their license will soon expire.
|
|
|
|
|
/// </summary>
|
2016-01-26 17:30:24 +01:00
|
|
|
|
private void showLicenseSummaryWarning(String hostname, DateTime now, DateTime expiryDate, bool createAlert, bool popupLicenseMgr)
|
2013-06-24 13:41:48 +02:00
|
|
|
|
{
|
|
|
|
|
Program.AssertOnEventThread();
|
|
|
|
|
|
2013-08-05 18:41:46 +02:00
|
|
|
|
log.InfoFormat("Server {0} is within 30 days of expiry ({1}). Show License Summary if needed",
|
|
|
|
|
hostname,
|
|
|
|
|
HelpersGUI.DateTimeToString(expiryDate, Messages.DATEFORMAT_DMY_HMS, true));
|
|
|
|
|
|
2016-01-26 17:30:24 +01:00
|
|
|
|
if (createAlert)
|
|
|
|
|
{
|
|
|
|
|
var alert = new LicenseAlert(hostname, now, expiryDate) { LicenseManagerLauncher = licenseManagerLauncher };
|
|
|
|
|
Alert.AddAlert(alert);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!popupLicenseMgr)
|
|
|
|
|
return;
|
2013-06-24 13:41:48 +02:00
|
|
|
|
|
|
|
|
|
if (Program.RunInAutomatedTestMode)
|
2016-01-26 17:30:24 +01:00
|
|
|
|
log.Debug("In automated test mode: quashing license expiry warning");
|
2013-06-24 13:41:48 +02:00
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
licenseManagerLauncher.Parent = Program.MainWindow;
|
|
|
|
|
licenseManagerLauncher.LaunchIfRequired(true, ConnectionsManager.XenConnections);
|
2013-08-05 18:41:46 +02:00
|
|
|
|
}
|
2013-06-24 13:41:48 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Shows the license summary dialog to the user as their license has expired.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="host"></param>
|
2014-05-12 16:40:05 +02:00
|
|
|
|
/// <param name="now"></param>
|
2013-06-24 13:41:48 +02:00
|
|
|
|
/// <param name="expiryDate">Should be expressed in local time.</param>
|
2016-01-26 17:30:24 +01:00
|
|
|
|
private void showLicenseSummaryExpired(Host host, DateTime now, DateTime expiryDate, bool createAlert, bool popupLicenseMgr)
|
2013-06-24 13:41:48 +02:00
|
|
|
|
{
|
|
|
|
|
Program.AssertOnEventThread();
|
|
|
|
|
|
2014-05-12 16:40:05 +02:00
|
|
|
|
log.InfoFormat("Server {0} has expired ({1}). Show License Summary if needed",
|
|
|
|
|
host.Name,
|
|
|
|
|
HelpersGUI.DateTimeToString(expiryDate, Messages.DATEFORMAT_DMY_HMS, true));
|
|
|
|
|
|
2016-01-26 17:30:24 +01:00
|
|
|
|
if (createAlert)
|
|
|
|
|
{
|
|
|
|
|
var alert = new LicenseAlert(host.Name, now, expiryDate) { LicenseManagerLauncher = licenseManagerLauncher };
|
|
|
|
|
Alert.AddAlert(alert);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!popupLicenseMgr)
|
|
|
|
|
return;
|
2014-05-12 16:40:05 +02:00
|
|
|
|
|
2013-06-24 13:41:48 +02:00
|
|
|
|
if (Program.RunInAutomatedTestMode)
|
2016-01-26 17:30:24 +01:00
|
|
|
|
log.Debug("In automated test mode: quashing license expiry warning");
|
2013-06-24 13:41:48 +02:00
|
|
|
|
else
|
|
|
|
|
licenseManagerLauncher.LaunchIfRequired(true, ConnectionsManager.XenConnections);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|