/* 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; } } }