/* 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.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Xml;
using CookComputing.XmlRpc;
using XenAdmin.Core;
using XenAPI;
namespace XenAdmin.Actions.HostActions
{
public static class LicensingHelper
{
#region Send license data to activation server
///
/// Send license information to the activation server after assigning or releasing a paid license.
/// This task will run on a separate thread.
///
/// Pass in a Dictionary containing the hosts and their previous license data
/// Pass in the current license edition
public static void SendLicenseEditionData(Dictionary hosts, string currentEdition)
{
// Supply the state information required by the task.
SendLicenseDataHelper sendLicenseDataHelper = new SendLicenseDataHelper(hosts, "apply_license", currentEdition, true);
// start a separate thread
Thread thread = new Thread(new ThreadStart(sendLicenseDataHelper.ThreadProc));
thread.Name = "Process licensing data for assigning or releasing a license";
thread.IsBackground = true;
thread.Start();
}
///
/// Send license information to the activation server after activating a free license.
/// In this case both previous and current editions are "free"
/// This task will run on a separate thread.
///
/// Pass in a Dictionary containing the hosts and their previous license data
public static void SendActivationData(Dictionary hosts)
{
// Supply the state information required by the task.
SendLicenseDataHelper sendLicenseDataHelper = new SendLicenseDataHelper(hosts, "activation", XenAPI.Host.GetEditionText(XenAPI.Host.Edition.Free), true);
// start a separate thread
Thread thread = new Thread(new ThreadStart(sendLicenseDataHelper.ThreadProc));
thread.Name = "Process licensing data for activating a free license)";
thread.IsBackground = true;
thread.Start();
}
public struct LicenseDataStruct
{
public string Edition;
public string ExpiryDate;
public LicenseDataStruct(string edition, string expiryDate)
{
Edition = edition;
ExpiryDate = expiryDate;
}
public LicenseDataStruct(XenAPI.Host host)
{
if (Helpers.MidnightRideOrGreater(host))
{
Edition = host.edition;
}
else
{
Edition = host.license_params.ContainsKey("sku_type") ? host.license_params["sku_type"] : "";
}
ExpiryDate = host.license_params.ContainsKey("expiry") ? host.license_params["expiry"] : "";
}
}
private class SendLicenseDataHelper
{
public Dictionary Hosts;
public string LicensingAction;
public string CurrentEdition;
public bool IncludeSKU;
public SendLicenseDataHelper(Dictionary hosts, string licensingAction, string currentEdition, bool includeSKU)
{
Hosts = hosts;
LicensingAction = licensingAction;
CurrentEdition = currentEdition;
IncludeSKU = includeSKU;
}
public void ThreadProc()
{
string licensingData;
try
{
// build the xml
using (MemoryStream ms = new MemoryStream())
{
Encoding Utf8 = new UTF8Encoding(false);
XmlWriterSettings settings = new XmlWriterSettings();
settings.OmitXmlDeclaration = true;
settings.Encoding = Utf8;
XmlWriter writer = XmlWriter.Create(ms, settings);
writer.WriteStartDocument();
writer.WriteStartElement(LicensingAction);
foreach (XenAPI.Host host in Hosts.Keys)
{
ProduceXmlForHost(host, Hosts[host], writer);
}
writer.WriteEndElement();
writer.WriteEndDocument();
writer.Close();
licensingData = Utf8.GetString(ms.ToArray());
}
// send the xml
ActivationProxy proxy = XmlRpcProxyGen.Create();
proxy.Url = string.Format(InvisibleMessages.ACTIVATION_URL, InvisibleMessages.ACTIVATION_SERVER);
proxy.Timeout = 30 * 1000;
proxy.UseIndentation = false;
proxy.UserAgent = Session.UserAgent;
proxy.KeepAlive = true;
proxy.Proxy = Session.Proxy;
// response is the transaction id of this call to the activation service
string response = proxy.process_reactivation_request(licensingData);
}
catch (Exception)
{
}
}
private void ProduceXmlForHost(XenAPI.Host host, LicenseDataStruct previousLicenseData, XmlWriter writer)
{
// wait for host to be updated
for (int i = 0; i < 100 &&
Helper.AreEqual2(host.license_params["expiry"], previousLicenseData.ExpiryDate) &&
Helper.AreEqual2(host.edition, previousLicenseData.Edition); i++)
{
Thread.Sleep(100);
}
writer.WriteStartElement("host");
writer.WriteAttributeString("uuid", host.uuid);
foreach (KeyValuePair kvp in host.software_version)
{
writer.WriteStartElement("software_version_element");
writer.WriteAttributeString("key", kvp.Key);
writer.WriteAttributeString("value", kvp.Value);
writer.WriteEndElement();
}
// edition information
if (IncludeSKU)
{
string newEdition;
if (String.IsNullOrEmpty(CurrentEdition))
{
if (Helpers.MidnightRideOrGreater(host))
{
newEdition = host.edition;
}
else
{
newEdition = host.license_params.ContainsKey("sku_type") ? host.license_params["sku_type"] : "";
}
}
else
{
newEdition = CurrentEdition;
}
writer.WriteStartElement("SKU");
writer.WriteAttributeString("from", previousLicenseData.Edition);
writer.WriteAttributeString("to", newEdition);
writer.WriteEndElement();
}
// license expiry information
writer.WriteStartElement("license_expiry_date");
writer.WriteAttributeString("from", previousLicenseData.ExpiryDate);
writer.WriteAttributeString("to", host.license_params["expiry"]);
writer.WriteEndElement();
writer.WriteEndElement();
}
}
#endregion
}
}