/*
 * The contents of this file are subject to the terms
 * of the Common Development and Distribution License
 * (the License).  You may not use this file except in
 * compliance with the License.
 *
 * You can obtain a copy of the license at
 * https://glassfish.dev.java.net/public/CDDLv1.0.html or
 * glassfish/bootstrap/legal/CDDLv1.0.txt.
 * See the License for the specific language governing
 * permissions and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL
 * Header Notice in each file and include the License file
 * at glassfish/bootstrap/legal/CDDLv1.0.txt.
 * If applicable, add the following below the CDDL Header,
 * with the fields enclosed by brackets [] replaced by
 * you own identifying information:
 * "Portions Copyrighted [year] [name of copyright owner]"
 *
 * Copyright (c) Ericsson AB, 2004-2007. All rights reserved.
 */
package com.ericsson.ssa.config;

import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;

import java.util.Enumeration;
import java.util.logging.Level;

// inserted by hockey (automatic)
import java.util.logging.Logger;
import java.util.prefs.Preferences;


/**
 *
 * @author John Doe
 * @author erafope
 * @reviewed ejoelbi 2007-jan-17
 * @reviewed ehswolm 2007-feb-23
 */
public class ConfigManager extends RuntimeConfig {
    private static Logger logger = Logger.getLogger("SipContainer");
    private static Preferences userPreferences = Preferences.userRoot()
                                                            .node(Constants.TM_PREFERENCES_NODE);
    private static Preferences timerPreferences = Preferences.userRoot()
                                                             .node(Constants.TM_TIMER_PREFERENCES_NODE);
    private static Preferences systemPreferences = Preferences.systemRoot()
                                                              .node(com.ericsson.ssa.config.Constants.TM_PREFERENCES_NODE);

    /* config paramaters */
    private int m_HostNumber = Constants.UNINITIALIZED_INT;
    private String m_LanAddress = null;
    private String m_EnumTopDomain = null;
    private String m_DnsServerList = null;
    private int m_ProxyPoolSize = Constants.UNINITIALIZED_INT;
    private int m_ProxyRetries = Constants.UNINITIALIZED_INT;
    private int m_ProxySocketTimeout = Constants.UNINITIALIZED_INT;
    private int m_ProxyConnectionTimeout = Constants.UNINITIALIZED_INT;
    private boolean m_OverloadRegulation = false;
    private int m_SampleRate = Constants.UNINITIALIZED_INT;
    private int m_NumberOfSamples = Constants.UNINITIALIZED_INT;
    private int m_HttpThreshold = Constants.UNINITIALIZED_INT;
    private int m_IrThreshold = Constants.UNINITIALIZED_INT;
    private int m_SrThreshold = Constants.UNINITIALIZED_INT;
    private int m_MmThreshold = Constants.UNINITIALIZED_INT;
    private boolean m_CpuAlarmEnabled = true;
    private int m_CpuAlarmThreshold = Constants.UNINITIALIZED_INT;
    private int m_SipLinkTimeout = Constants.UNINITIALIZED_INT; // ms
    private int m_SipLinkTimeoutRetries = Constants.UNINITIALIZED_INT; // iterations
    private int m_SipLinkMaxQueueLen = Constants.UNINITIALIZED_INT;
    private int m_SipLinkAliveTimeout = Constants.UNINITIALIZED_INT;
    private boolean m_Eas503DisabledFetched = false;
    private boolean m_Eas503Disabled = true;
    private boolean m_ErrorResponseEnabledFetched = false;
    private boolean m_ErrorResponseEnabled = true;

    /**
     * Get a parameter value from preferences. The value returned is non-null if
     * the provided defaultValue is.
     *
     *
     * @param parameterName
     * @param isSystemProperty
     * @param defaultValue
     * @return
     */
    private String getStringParameter(String parameterName,
        boolean isSystemProperty, String defaultValue) {
        String value;

        if (isSystemProperty) {
            value = systemPreferences.get(parameterName, Constants.EMPTY_STRING);
        } else {
            value = userPreferences.get(parameterName, Constants.EMPTY_STRING);
        }

        if (value.equalsIgnoreCase(Constants.EMPTY_STRING) &&
                (defaultValue != null)) {
            logger.log(Level.INFO,
                "parameter <" + parameterName + ">: using default value: '" +
                defaultValue + "'");

            return defaultValue;
        } else if (value.equalsIgnoreCase(Constants.EMPTY_STRING) &&
                (defaultValue == null)) {
            logger.log(Level.WARNING,
                "parameter <" + parameterName +
                ">: no value specified and no default available, using empty string.");

            return Constants.EMPTY_STRING;
        } else if ((defaultValue != null) && value.equals(defaultValue)) {
            logger.log(Level.INFO,
                "parameter <" + parameterName + ">: using specified value: '" +
                value + "' (which is also the default value)");

            return value;
        } else if (defaultValue == null) {
            logger.log(Level.INFO,
                "parameter <" + parameterName + ">: using specified value: '" +
                value + "'");

            return value;
        } else {
            logger.log(Level.INFO,
                "parameter <" + parameterName +
                ">: using non-default value: '" + value + "'");

            return value;
        }
    }

    private int getIntParameter(String parameterName, boolean isSystemProperty,
        int defaultValue) {
        if (isSystemProperty) {
            return getIntParameter(systemPreferences, parameterName,
                defaultValue);
        }

        return getIntParameter(userPreferences, parameterName, defaultValue);
    }

    private int getIntParameter(Preferences prefnode, String parameterName,
        int defaultValue) {
        int value = prefnode.getInt(parameterName, Constants.UNINITIALIZED_INT);

        if ((value == Constants.UNINITIALIZED_INT) &&
                (defaultValue > Constants.UNINITIALIZED_INT)) {
            logger.log(Level.INFO,
                "parameter <" + parameterName + ">: using default value: " +
                defaultValue);

            return defaultValue;
        } else if ((value == Constants.UNINITIALIZED_INT) &&
                (defaultValue == Constants.UNINITIALIZED_INT)) {
            logger.log(Level.WARNING,
                "parameter <" + parameterName +
                ">: no value specified and no default available. Using " +
                Constants.UNINITIALIZED_INT);

            return Constants.UNINITIALIZED_INT;
        } else if ((defaultValue != Constants.UNINITIALIZED_INT) &&
                (value == defaultValue)) {
            logger.log(Level.INFO,
                "parameter <" + parameterName + ">: using specified value: " +
                value + " (which is also the default value)");

            return value;
        } else if (defaultValue == Constants.UNINITIALIZED_INT) {
            logger.log(Level.INFO,
                "parameter <" + parameterName + ">: using specified value: " +
                value);

            return value;
        } else {
            logger.log(Level.INFO,
                "parameter <" + parameterName + ">: using non-default value: " +
                value);

            return value;
        }
    }

    private boolean getBooleanParameter(String parameterName,
        boolean isSystemProperty, String defaultString) {
        boolean defaultValue = Boolean.valueOf(defaultString);
        String value;

        if (isSystemProperty) {
            value = systemPreferences.get(parameterName, Constants.EMPTY_STRING);
        } else {
            value = userPreferences.get(parameterName, Constants.EMPTY_STRING);
        }

        boolean result;

        if (value.equalsIgnoreCase("true")) {
            result = true;
            logger.log(Level.INFO,
                "parameter <" + parameterName + ">: using specified value: " +
                result + ((result != defaultValue) ? "" : " (same as default)"));
        } else if (value.equalsIgnoreCase("false")) {
            result = false;
            logger.log(Level.INFO,
                "parameter <" + parameterName + ">: using specified value: " +
                result + ((result != defaultValue) ? "" : " (same as default)"));
        } else if (value.equals(Constants.EMPTY_STRING)) {
            result = defaultValue;
            logger.log(Level.INFO,
                "parameter <" + parameterName + ">: using default value: " +
                defaultValue);
        } else {
            logger.log(Level.WARNING,
                "parameter <" + parameterName + ">: illegal value specified: " +
                value + ", assumed to mean: false, using: false");
            result = false;
        }

        return result;
    }

    @Override
    public boolean getDefaultTCPTransport() {
        return getBooleanParameter(com.ericsson.ssa.container.mbeans.Constants.DEFAULT_TCP_TRANSPORT,
            false, String.valueOf(Constants.DEFAULT_TCP_TRANSPORT));
    }

    @Override
    public int getThreadPoolSize() {
        return getIntParameter(com.ericsson.ssa.container.mbeans.Constants.THREAD_POOL_SIZE,
            false, Constants.THREADPOOL_SIZE_DEFAULT);
    }

    @Override
    public String getJMXDefaultHost() {
        return getLanAddress();
    }

    @Override
    public int getJMXDefaultPort() {
        return getIntParameter(com.ericsson.ssa.container.mbeans.Constants.JMX_DEFAULT_PORT,
            false, Constants.JMX_DEFAULT_PORT_DEFAULT);
    }

    @Override
    public boolean getErrorResponseEnabled() {
        if (m_ErrorResponseEnabledFetched) {
            return m_ErrorResponseEnabled;
        }

        m_ErrorResponseEnabled = getBooleanParameter(com.ericsson.ssa.container.mbeans.Constants.ERROR_RESPONSE_ENABLED,
                false, String.valueOf(Constants.ERROR_RESPONSE_ENABLED_DEFAULT));
        m_ErrorResponseEnabledFetched = true;

        return m_ErrorResponseEnabled;
    }

    /**
     * Provide the host number on the internal LAN on TSP/Linux. This number will
     * be non-zero on a properly configured TSP/Linux system, and it can be used
     * to uniquely identify a traffic processor within the cluster. On other
     * platforms 0 will be returned.
     */
    @Override
    public int getHostNumber() {
        if (m_HostNumber != Constants.UNINITIALIZED_INT) {
            return m_HostNumber;
        }

        String key = com.ericsson.ssa.container.mbeans.Constants.HOST_NUMBER;
        String hn = System.getProperty(key);

        if ((hn == null) || (hn.trim().length() == 0)) {
            m_HostNumber = 0;
        } else {
            m_HostNumber = Integer.parseInt(hn);
        }

        logger.log(Level.INFO,
            "parameter <HostNumber>: using value " + m_HostNumber);

        return m_HostNumber;
    }

    /**
     * getLanAddress() tries to find a configured IPv4 address of a physical
     * network interface. Some heuristics will be applied so that on TSP/Linux
     * one of the internal LAN addresses will most likely be returned. <br>
     * getLanAddress() always returns a correctly formatted dotted-decimal IP
     * address string; in the event of a machine with no configured IP addresses
     * it will return "0.0.0.0". <br>
     *
     * @return java.lang.String
     * @author erarafo
     */
    @Override
    public String getLanAddress() {
        if (m_LanAddress != null) {
            return m_LanAddress;
        }

        String lanAddress = "";
        String preferedPrefix = "172."; // TSP/Linux internal LAN address prefix,
                                        // preferred

        String avoidedPrefix = "127."; // Loopback interface, to be avoided
        String avoidedInterfacenamePrefix = "i4dd"; // VIP addresses, to be
                                                    // avoided

        String me = "getLanAddress(): ";

        if (logger.isLoggable(Level.FINE)) {
            logger.log(Level.FINE,
                me +
                "try to find a configured IP address of a physical network interface");
        }

        int score = 0;
        int newscore;
        Enumeration<NetworkInterface> nifs = null;

        try {
            nifs = NetworkInterface.getNetworkInterfaces();
        } catch (SocketException se) {
            logger.log(Level.SEVERE,
                me +
                "SocketException when trying to get our network interfaces", se);
        }

        if (nifs != null) {
            while (nifs.hasMoreElements()) {
                NetworkInterface nif = nifs.nextElement();
                String ifName = nif.getName();

                if (logger.isLoggable(Level.FINE)) {
                    logger.log(Level.FINE, me + "found interface: " + ifName);
                }

                int addrCount = 0;

                for (Enumeration<InetAddress> addrs = nif.getInetAddresses();
                        addrs.hasMoreElements();) {
                    InetAddress addr = addrs.nextElement();
                    addrCount++;

                    if (logger.isLoggable(Level.FINE)) {
                        logger.log(Level.FINE,
                            me + "found address " + addr + " for interface " +
                            ifName);
                    }

                    String addrString = addr.getHostAddress();

                    if (addrString.startsWith(preferedPrefix)) {
                        newscore = 40; // 40: preferred address

                        if (score < newscore) {
                            lanAddress = addrString;
                            score = newscore;

                            if (logger.isLoggable(Level.FINE)) {
                                logger.log(Level.FINE,
                                    me + "score: " + newscore +
                                    ", best so far");
                            }
                        } else {
                            if (logger.isLoggable(Level.FINE)) {
                                logger.log(Level.FINE,
                                    me + "score: " + newscore + ", ignored");
                            }
                        }
                    } else if (addrString.startsWith(avoidedPrefix)) {
                        newscore = 10; // 10: avoid this address if possible

                        if (score < newscore) {
                            lanAddress = addrString;
                            score = newscore;

                            if (logger.isLoggable(Level.FINE)) {
                                logger.log(Level.FINE,
                                    me + "score: " + newscore +
                                    ", best so far");
                            }
                        } else {
                            if (logger.isLoggable(Level.FINE)) {
                                logger.log(Level.FINE,
                                    me + "score: " + newscore + ", ignored");
                            }
                        }
                    } else if (ifName.startsWith(avoidedInterfacenamePrefix)) {
                        newscore = 20; // 20: avoid this address if possible

                        if (score < newscore) {
                            lanAddress = addrString;
                            score = newscore;

                            if (logger.isLoggable(Level.FINE)) {
                                logger.log(Level.FINE,
                                    me + "score: " + newscore +
                                    ", best so far");
                            }
                        } else {
                            if (logger.isLoggable(Level.FINE)) {
                                logger.log(Level.FINE,
                                    me + "score: " + newscore + ", ignored");
                            }
                        }
                    } else if (addrString.indexOf(":") >= 0) {
                        newscore = 25; // score 25 for IPv6 address

                        if (score < newscore) {
                            lanAddress = addrString;
                            score = newscore;

                            if (logger.isLoggable(Level.FINE)) {
                                logger.log(Level.FINE,
                                    me + "score: " + newscore +
                                    ", best so far");
                            }
                        } else {
                            if (logger.isLoggable(Level.FINE)) {
                                logger.log(Level.FINE,
                                    me + "score: " + newscore + ", ignored");
                            }
                        }
                    } else {
                        newscore = 30; // 30: neither preferred nor avoided

                        if (score < newscore) {
                            lanAddress = addrString;
                            score = newscore;

                            if (logger.isLoggable(Level.FINE)) {
                                logger.log(Level.FINE,
                                    me + "score: " + newscore +
                                    ", best so far");
                            }
                        } else {
                            if (logger.isLoggable(Level.FINE)) {
                                logger.log(Level.FINE,
                                    me + "score: " + newscore + ", ignored");
                            }
                        }
                    }
                }

                if (addrCount < 1) {
                    if (logger.isLoggable(Level.INFO)) {
                        logger.log(Level.INFO,
                            me +
                            "found no configured IP addresses for interface " +
                            ifName);
                    }
                } else if (addrCount > 1) {
                    if (logger.isLoggable(Level.INFO)) {
                        logger.log(Level.INFO,
                            me + "found " + addrCount +
                            " configured IP addresses for interface " + ifName);
                    }
                }
            }
        }

        if (lanAddress == null) {
            logger.log(Level.SEVERE,
                me +
                "no interface with a configured IP address found, using 0.0.0.0");
            lanAddress = Constants.BIND_TO_ANY;
        } else if (score < 30) {
            logger.log(Level.WARNING,
                me + "only found unsuitable IP addresses; using " + lanAddress +
                " in lack of better");
        }

        if (logger.isLoggable(Level.INFO)) {
            logger.log(Level.INFO,
                "parameter <LanAddress>: using " +
                ((score > 30) ? "preferred " : "") + "value '" + lanAddress +
                "'");
        }

        m_LanAddress = lanAddress;

        return lanAddress;
    }

    @Override
    public boolean getApplicationDispatcherLoopInternal() {
        return getBooleanParameter(com.ericsson.ssa.container.mbeans.Constants.APP_DISPATCHER_LOOP_INTERNAL,
            false,
            String.valueOf(Constants.APP_DISPATCHER_LOOP_INTERNAL_DEFAULT));
    }

    public String getEnumTopDomain() {
        if (m_EnumTopDomain != null) {
            return m_EnumTopDomain;
        }

        String parmName = com.ericsson.ssa.container.mbeans.Constants.ENUM_TOPDOMAIN;
        String defaultValue = String.valueOf(Constants.ENUM_TOPDOMAIN_DEFAULT);

        m_EnumTopDomain = getStringParameter(parmName, false, defaultValue);

        return m_EnumTopDomain;
    }

    public int getDnsCacheSize() {
        return getIntParameter(com.ericsson.ssa.container.mbeans.Constants.DNS_CACHE_SIZE,
            false, Constants.DNS_CACHE_SIZE_DEFAULT);
    }

    public String getDnsServerList() {
        if (m_DnsServerList != null) {
            return m_DnsServerList;
        }

        m_DnsServerList = getStringParameter(com.ericsson.ssa.container.mbeans.Constants.DNS_SERVER_LIST,
                false, null);

        return m_DnsServerList;
    }

    public int getProxyPoolSize() {
        if (m_ProxyPoolSize != Constants.UNINITIALIZED_INT) {
            return m_ProxyPoolSize;
        }

        m_ProxyPoolSize = getIntParameter(com.ericsson.ssa.container.mbeans.Constants.PROXY_POOL_SIZE,
                false, Constants.DEFAULT_PROXY_POOL_SIZE);

        return m_ProxyPoolSize;
    }

    public int getProxyRetries() {
        if (m_ProxyRetries != Constants.UNINITIALIZED_INT) {
            return m_ProxyRetries;
        }

        m_ProxyRetries = getIntParameter(com.ericsson.ssa.container.mbeans.Constants.PROXY_RETRIES,
                false, Constants.DEFAULT_PROXY_RETRIES);

        return m_ProxyRetries;
    }

    public int getProxySocketTimeout() {
        if (m_ProxySocketTimeout != Constants.UNINITIALIZED_INT) {
            return m_ProxySocketTimeout;
        }

        m_ProxySocketTimeout = getIntParameter(com.ericsson.ssa.container.mbeans.Constants.PROXY_SOCKET_TIMEOUT,
                false, Constants.DEFAULT_PROXY_SOCKET_TIMEOUT);

        return m_ProxySocketTimeout;
    }

    public int getProxyConnectionTimeout() {
        if (m_ProxyConnectionTimeout != Constants.UNINITIALIZED_INT) {
            return m_ProxyConnectionTimeout;
        }

        m_ProxyConnectionTimeout = getIntParameter(com.ericsson.ssa.container.mbeans.Constants.PROXY_CONNECTION_TIMEOUT,
                false, Constants.DEFAULT_PROXY_CONNECTION_TIMEOUT);

        return m_ProxyConnectionTimeout;
    }

    public int getTimerT1() {
        return getIntParameter(timerPreferences,
            com.ericsson.ssa.container.mbeans.Constants.TIMER_T1,
            Constants.TIMER_T1_DEFAULT);
    }

    public int getTimerT2() {
        return getIntParameter(timerPreferences,
            com.ericsson.ssa.container.mbeans.Constants.TIMER_T2,
            Constants.TIMER_T2_DEFAULT);
    }

    public int getTimerT4() {
        return getIntParameter(timerPreferences,
            com.ericsson.ssa.container.mbeans.Constants.TIMER_T4,
            Constants.TIMER_T4_DEFAULT);
    }

    /*
     * (non-Javadoc)
     *
     * @see com.ericsson.ssa.config.RuntimeConfig#getOverloadRegulation()
     */
    @Override
    public boolean getOverloadRegulation() {
        return getBooleanParameter(com.ericsson.ssa.container.mbeans.Constants.OVERLOAD_REGULATION,
            false, String.valueOf(Constants.OVERLOAD_REGULATION));
    }

    /*
     * (non-Javadoc)
     *
     * @see com.ericsson.ssa.config.RuntimeConfig#getSampleRate()
     */
    @Override
    public int getSampleRate() {
        if (m_SampleRate != Constants.UNINITIALIZED_INT) {
            return m_SampleRate;
        }

        m_SampleRate = getIntParameter(com.ericsson.ssa.container.mbeans.Constants.SAMPLE_RATE,
                false, Constants.SAMPLE_RATE);

        return m_SampleRate;
    }

    /*
     * (non-Javadoc)
     *
     * @see com.ericsson.ssa.config.RuntimeConfig#getNumberOfSamples()
     */
    @Override
    public int getNumberOfSamples() {
        if (m_NumberOfSamples != Constants.UNINITIALIZED_INT) {
            return m_NumberOfSamples;
        }

        m_NumberOfSamples = getIntParameter(com.ericsson.ssa.container.mbeans.Constants.NUMBER_OF_SAMPLES,
                false, Constants.NUMBER_OF_SAMPLES);

        return m_NumberOfSamples;
    }

    /*
     * (non-Javadoc)
     *
     * @see com.ericsson.ssa.config.RuntimeConfig#getHttpThreshold()
     */
    @Override
    public int getHttpThreshold() {
        if (m_HttpThreshold != Constants.UNINITIALIZED_INT) {
            return m_HttpThreshold;
        }

        m_HttpThreshold = getIntParameter(com.ericsson.ssa.container.mbeans.Constants.HTTP_THRESHOLD,
                false, Constants.HTTP_THRESHOLD);

        return m_HttpThreshold;
    }

    /*
     * (non-Javadoc)
     *
     * @see com.ericsson.ssa.config.RuntimeConfig#getIrThreshold()
     */
    @Override
    public int getIrThreshold() {
        if (m_IrThreshold != Constants.UNINITIALIZED_INT) {
            return m_IrThreshold;
        }

        m_IrThreshold = getIntParameter(com.ericsson.ssa.container.mbeans.Constants.IR_THRESHOLD,
                false, Constants.IR_THRESHOLD);

        return m_IrThreshold;
    }

    /*
     * (non-Javadoc)
     *
     * @see com.ericsson.ssa.config.RuntimeConfig#getSrThreshold()
     */
    @Override
    public int getSrThreshold() {
        if (m_SrThreshold != Constants.UNINITIALIZED_INT) {
            return m_SrThreshold;
        }

        m_SrThreshold = getIntParameter(com.ericsson.ssa.container.mbeans.Constants.SR_THRESHOLD,
                false, Constants.SR_THRESHOLD);

        return m_SrThreshold;
    }

    /*
     * (non-Javadoc)
     *
     * @see com.ericsson.ssa.config.RuntimeConfig#getMmThreshold()
     */
    @Override
    public int getMmThreshold() {
        if (m_MmThreshold != Constants.UNINITIALIZED_INT) {
            return m_MmThreshold;
        }

        m_MmThreshold = getIntParameter(com.ericsson.ssa.container.mbeans.Constants.MM_THRESHOLD,
                false, Constants.MM_THRESHOLD);

        return m_MmThreshold;
    }

    /*
     * (non-Javadoc)
     *
     * @see com.ericsson.ssa.config.RuntimeConfig#getCpuAlarmEnabled()
     */
    @Override
    public boolean getCpuAlarmEnabled() {
        return getBooleanParameter(com.ericsson.ssa.container.mbeans.Constants.CPU_ALARM_ENABLED,
            false, String.valueOf(Constants.CPU_OVERLOAD_ENABLED));
    }

    /*
     * (non-Javadoc)
     *
     * @see com.ericsson.ssa.config.RuntimeConfig#getCpuAlaramThreshold()
     */
    @Override
    public int getCpuAlaramThreshold() {
        if (m_CpuAlarmThreshold != Constants.UNINITIALIZED_INT) {
            return m_CpuAlarmThreshold;
        } else {
            m_CpuAlarmThreshold = getIntParameter(com.ericsson.ssa.container.mbeans.Constants.CPU_ALARM_THRESHOLD,
                    false, Constants.CPU_ALARM_THRESHOLD);

            return m_CpuAlarmThreshold;
        }
    }

    /*
     * (non-Javadoc)
     *
     * @see com.ericsson.ssa.config.RuntimeConfig#getSipLinkMaxQueueLength()
     */
    @Override
    public int getSipLinkMaxQueueLength() {
        if (m_SipLinkMaxQueueLen == Constants.UNINITIALIZED_INT) {
            m_SipLinkMaxQueueLen = getIntParameter(com.ericsson.ssa.container.mbeans.Constants.SIP_LINK_MAX_QUEUE_LENGTH,
                    false, Constants.SIP_LINK_MAX_QUEUE_LENGTH);
        }

        return m_SipLinkMaxQueueLen;
    }

    /*
     * (non-Javadoc)
     *
     * @see com.ericsson.ssa.config.RuntimeConfig#getSipLinkAliveTimeout()
     */
    @Override
    public int getSipLinkAliveTimeout() {
        if (m_SipLinkAliveTimeout == Constants.UNINITIALIZED_INT) {
            m_SipLinkAliveTimeout = getIntParameter(com.ericsson.ssa.container.mbeans.Constants.SIP_LINK_ALIVE_TIMEOUT,
                    false, Constants.SIP_LINK_ALIVE_TIMEOUT);
        }

        return m_SipLinkAliveTimeout;
    }

    /*
     * (non-Javadoc)
     *
     * @see com.ericsson.ssa.config.RuntimeConfig#getSipLinkTimeout()
     */
    @Override
    public int getSipLinkTimeout() {
        if (m_SipLinkTimeout == Constants.UNINITIALIZED_INT) {
            m_SipLinkTimeout = getIntParameter(com.ericsson.ssa.container.mbeans.Constants.SIP_LINK_TIMEOUT,
                    false, Constants.SIP_LINK_TIMEOUT);
        }

        return m_SipLinkTimeout;
    }

    /*
     * (non-Javadoc)
     *
     * @see com.ericsson.ssa.config.RuntimeConfig#getSipLinkTimeoutRetries()
     */
    @Override
    public int getSipLinkTimeoutRetries() {
        if (m_SipLinkTimeoutRetries == Constants.UNINITIALIZED_INT) {
            m_SipLinkTimeoutRetries = getIntParameter(com.ericsson.ssa.container.mbeans.Constants.SIP_LINK_TIMEOUT_RETRIES,
                    false, Constants.SIP_LINK_TIMEOUT_RETRIES);
        }

        return m_SipLinkTimeoutRetries;
    }

    @Override
    public boolean getEas503Disabled() {
        if (m_Eas503DisabledFetched) {
            return m_Eas503Disabled;
        } else {
            m_Eas503Disabled = getBooleanParameter(com.ericsson.ssa.container.mbeans.Constants.EAS_503_DISABLED,
                    false, String.valueOf(Constants.EAS_503_DISABLED_DEFAULT));
            m_Eas503DisabledFetched = true;

            return m_Eas503Disabled;
        }
    }

    @Override
    public void uninitialize() {
        if (_logger.isLoggable(Level.FINE)) {
            _logger.log(Level.FINE,
                "Uninitialize parameters that can be changed in runtime in order to read again.");
        }

        m_OverloadRegulation = false;
        m_SampleRate = Constants.UNINITIALIZED_INT;
        m_NumberOfSamples = Constants.UNINITIALIZED_INT;
        m_HttpThreshold = Constants.UNINITIALIZED_INT;
        m_IrThreshold = Constants.UNINITIALIZED_INT;
        m_SrThreshold = Constants.UNINITIALIZED_INT;
        m_MmThreshold = Constants.UNINITIALIZED_INT;
    }
}
