/* 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.Text;
using XenAPI;
using XenAdmin.Core;
namespace XenAdmin.Wlb
{
///
/// A Static class for describing and maintining the current state of the Wlb Server connection
///
public static class WlbServerState
{
///
/// The key string used to store the connection status in Pool's OtherConfig dictionary
///
private const string WLB_CONNECTION_STATUS = "WlbConnectionStatus";
///
/// The key string used to store the connection error message in the pool's OtherConfig dictionary
///
private const string WLB_CONNECTION_ERROR = "WlbConnectionError";
///
/// Public enumeration of the possible Wlb Conection states
///
public enum ServerState
{
Unknown = 0,
NotConfigured,
Enabled,
Disabled,
ConnectionError
}
///
/// object for locking SetState
///
private static Object _lockObject = new Object();
///
/// Public method for updating the Wlb Server state when there is no error (Failure).
/// This method clears any existing failure message for the connection
///
/// The pool who's Wlb connection state we are updating
/// The current state of the pool's Wlb Server State
public static void SetState(Pool pool, ServerState state)
{
SetState(pool.Connection.Session, pool, state, null);
}
///
/// Public method for updating the Wlb Server state. If the state is ConnectionFailure and
/// a Failure is supplied, it's message is stored in the OtherConfig
///
/// The pool who's Wlb connection state we are updating
/// The current state of the pool's Wlb Server State
/// The Failure (if any) describing the Connection Error
public static void SetState(Pool pool, ServerState state, Failure failure)
{
SetState(pool.Connection.Session, pool, state, failure);
}
///
/// Public method for updating the Wlb Server state when there is no error (Failure) and need specific seesion information.
/// This method clears any existing failure message for the connection
///
/// The User session use to do this operation
/// The pool who's Wlb connection state we are updating
/// The current state of the pool's Wlb Server State
public static void SetState(Session session, Pool pool, ServerState state)
{
SetState(session, pool, state, null);
}
///
/// Public method for updating the Wlb Server state. If the state is ConnectionFailure and
/// a Failure is supplied, it's message is stored in the OtherConfig
///
/// The User session use to do this operation
/// The pool who's Wlb connection state we are updating
/// The current state of the pool's Wlb Server State
/// The Failure (if any) describing the Connection Error
public static void SetState(Session session, Pool pool, ServerState state, Failure failure)
{
//only update the state if new value if different than current value
// this is to cut down on unneeded Pool_PropertiesChanged events
if (GetState(pool) != state)
{
// set a lock so we are setting state one at a time
lock (_lockObject)
{
Helpers.SetOtherConfig(session, pool, WLB_CONNECTION_STATUS, state.ToString());
if (null != failure && state == ServerState.ConnectionError)
{
string error = String.Empty;
if (failure.Message == FriendlyErrorNames.WLB_INTERNAL_ERROR)
{
error = Messages.ResourceManager.GetString("WLB_ERROR_" + failure.ErrorDescription[1]);
}
else
{
error = failure.Message;
}
Helpers.SetOtherConfig(session, pool, WLB_CONNECTION_ERROR, error);
}
else
{
Helpers.SetOtherConfig(session, pool, WLB_CONNECTION_ERROR, String.Empty);
}
}
}
}
///
/// Public method for retrieving the current state of a Pool's Wlb server connection
///
/// The pool who's Wlb connection state we are updating
/// ServerState enumeration representing the current Wlb server conection state
public static ServerState GetState(Pool pool)
{
if (null == Helpers.GetOtherConfig(pool) && !CheckForKnownState(pool))
{
return ServerState.NotConfigured;
}
else
{
if (!Helpers.GetOtherConfig(pool).ContainsKey(WLB_CONNECTION_STATUS))
{
return ServerState.NotConfigured;
}
else
{
return (ServerState)Enum.Parse(typeof(ServerState), Helpers.GetOtherConfig(pool)[WLB_CONNECTION_STATUS]);
}
}
}
///
/// Private method for determining (initializing) the state of the WlbConnectin when there is
/// nothing yet stored in OtherConfig
///
/// The pool who's Wlb connection state we are updating
/// Bool denoting whether we were able to ascertain the current server state
private static bool CheckForKnownState(Pool pool)
{
bool stateFound = false;
if (Helpers.WlbEnabled(pool.Connection))
{
SetState(pool, ServerState.Enabled);
stateFound = true;
}
else if (String.IsNullOrEmpty(pool.wlb_url))
{
SetState(pool, ServerState.NotConfigured);
stateFound = true;
}
return stateFound;
}
///
/// Public method for retrieving the Failure message string stored in OtherConfig for the pool
///
/// The pool who's Wlb connection state we are retrieving
/// A string containing the Failure message, or an empty string
public static string GetFailureMessage(Pool pool)
{
string message = String.Empty;
if (null != Helpers.GetOtherConfig(pool) && Helpers.GetOtherConfig(pool).ContainsKey(WLB_CONNECTION_ERROR))
{
message = Helpers.GetOtherConfig(pool)[WLB_CONNECTION_ERROR];
}
return message;
}
}
}