shnakkydoodle.measuring.provider.MetricsProviderSQLServer.java Source code

Java tutorial

Introduction

Here is the source code for shnakkydoodle.measuring.provider.MetricsProviderSQLServer.java

Source

/*
 * Author Stephen Booysen
 *
 * Copyright (c) 2012 Stephen Booysen, Inc. All Rights Reserved.
 *
 * This software is the confidential and proprietary information of
 * Stephen Booysen. ("Confidential Information"). You shall not
 * disclose such Confidential Information and shall use it only in
 * accordance with the terms of the license agreement you entered into
 * with Stephen Booysen
 *
 * Stephen Booysen MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
 * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
 * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
 * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
 * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
 */
package shnakkydoodle.measuring.provider;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Types;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.apache.commons.dbutils.DbUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import shnakkydoodle.logging.LoggingManager;
import shnakkydoodle.measuring.common.AlarmComparisonOperator;
import shnakkydoodle.measuring.common.AlarmHistoryItem;
import shnakkydoodle.measuring.common.AlarmMetricAlarm;
import shnakkydoodle.measuring.common.AlarmState;
import shnakkydoodle.measuring.common.DayOfWeek;
import shnakkydoodle.measuring.common.IMetricProvider;
import shnakkydoodle.measuring.common.MetricAlarmEvent;
import shnakkydoodle.measuring.common.MetricData;
import shnakkydoodle.measuring.common.MetricEventSource;
import shnakkydoodle.measuring.common.MetricSLA;
import shnakkydoodle.measuring.common.MetricSLAExclusionTime;
import shnakkydoodle.measuring.common.MetricSLAResult;
import shnakkydoodle.measuring.common.MetricSLAState;
import shnakkydoodle.measuring.common.MetricSlaAlarmStatus;
import shnakkydoodle.measuring.common.MetricStatistic;
import shnakkydoodle.measuring.common.MetricUnit;

/**
 * @Author Stephen Booysen
 * 
 */
public class MetricsProviderSQLServer implements IMetricProvider {

    // region Private Members

    // The logging manager we are using
    private LoggingManager loggingManager;

    // The event source
    private MetricEventSource eventSource = new MetricEventSource();

    /**
     * The sql host
     */
    private String host;

    /**
     * The sql username
     */
    private String username;

    /**
     * The sql password
     */
    private String password;

    /**
     * Get all scripts to be run to create logging db tables with procs and
     * constraints Execute each scripts
     */
    private void ProcessConfigFile() {

        try {
            InputStream in = getClass()
                    .getResourceAsStream("shnakkydoodle/measuring/provider/resources/config.xml");

            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder dBuilder;
            dBuilder = dbFactory.newDocumentBuilder();
            Document doc = dBuilder.parse(in);
            doc.getDocumentElement().normalize();

            NodeList nList = doc.getElementsByTagName("resourcepath");

            for (int temp = 0; temp < nList.getLength(); temp++) {

                Node nNode = nList.item(temp);

                if (nNode.getNodeType() == Node.ELEMENT_NODE) {

                    Element eElement = (Element) nNode;
                    String resourcePath = eElement.getTextContent();

                    // Read in script and execute
                    if (ReadExecuteScript(resourcePath)) {
                        System.out.println("Successfully created: " + resourcePath);
                    } else {
                        System.err.println("Failed on creating: " + resourcePath);
                    }
                }
            }

        } catch (ParserConfigurationException e) {
            System.err.println(e.getClass().getName() + ": " + e.getMessage());
            e.printStackTrace();
        } catch (SAXException e) {
            System.err.println(e.getClass().getName() + ": " + e.getMessage());
            e.printStackTrace();
        } catch (IOException e) {
            System.err.println(e.getClass().getName() + ": " + e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * Create database and tables
     * 
     * @param resourcePath
     */
    private boolean ReadExecuteScript(String resourcePath) {
        boolean flag = false;

        try {
            InputStream in = getClass().getResourceAsStream(resourcePath);
            BufferedReader input = new BufferedReader(new InputStreamReader(in));
            StringBuilder content = new StringBuilder();

            String line;
            line = input.readLine();

            while (line != null) {
                content.append(line + "\n");
                line = input.readLine();
            }
            input.close();

            if (content.length() > 0) {
                Connection conn = null;
                Statement stmt = null;

                Class.forName("net.sourceforge.jtds.jdbc.Driver");
                conn = DriverManager
                        .getConnection(this.host + ";user=" + this.username + ";password=" + this.password);

                stmt = conn.createStatement();
                stmt.executeUpdate(content.toString());

                flag = true;

                stmt.close();
                conn.close();
            } else {
                System.err.println("No database metrics create tables script.");
            }
        } catch (IOException e) {
            System.err.println(e.getClass().getName() + ": " + e.getMessage());
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            System.err.println(e.getClass().getName() + ": " + e.getMessage());
            e.printStackTrace();
        } catch (SQLException e) {
            System.err.println(e.getClass().getName() + ": " + e.getMessage());
            e.printStackTrace();
        } catch (Exception e) {
            System.err.println(e.getClass().getName() + ": " + e.getMessage());
            e.printStackTrace();
        }

        return flag;
    }

    /**
     * Check if LoggingData table exists
     * 
     * @return
     */
    private boolean CheckIfDatabaseTablesExists() {
        Connection conn = null;
        boolean flag = false;

        try {
            Class.forName("net.sourceforge.jtds.jdbc.Driver");
            conn = DriverManager.getConnection(this.host + ";user=" + this.username + ";password=" + this.password);

            DatabaseMetaData meta = conn.getMetaData();
            ResultSet res = meta.getTables(null, null, null, new String[] { "TABLE" });

            while (res.next()) {

                if (res.getString("TABLE_TYPE").equalsIgnoreCase("TABLE")) {
                    if (res.getString("TABLE_NAME").equalsIgnoreCase("MetricData")) {
                        flag = true;
                        break;
                    }
                }
            }
            res.close();
            conn.close();

        } catch (ClassNotFoundException e) {
            System.err.println(e.getClass().getName() + ": " + e.getMessage());
            e.printStackTrace();
        } catch (SQLException e) {
            System.err.println(e.getClass().getName() + ": " + e.getMessage());
            e.printStackTrace();
        }

        return flag;
    }

    /**
     * Test if a metric has caused an alarm
     * 
     * @param metricData
     */
    private void evaluateMetricAlarm(MetricData metricData) {

        ArrayList<AlarmMetricAlarm> alarms = this.getMetricAlarmByMetricNamespace(metricData.getMetricNamespace(),
                metricData.getMetricName());

        // evaluate the alarms
        for (AlarmMetricAlarm alarm : alarms) {

            if (metricData.getMetricNamespace().equalsIgnoreCase(alarm.getMetricNamespace())
                    && metricData.getMetricName().equalsIgnoreCase(alarm.getMetricName())) {

                if (alarm.getComparisonOperator() == AlarmComparisonOperator.GreaterThanOrEqualToThreshold
                        && metricData.getValue() >= alarm.getThreshold()) {
                    setAlarmState(alarm.getAlarmName(), "Metric value greater or equal to threshold",
                            metricData.getValue().toString(), AlarmState.ALARM);
                } else if (alarm.getComparisonOperator() == AlarmComparisonOperator.GreaterThanThreshold
                        && metricData.getValue() > alarm.getThreshold()) {
                    setAlarmState(alarm.getAlarmName(), "Metric value greater than threshold",
                            metricData.getValue().toString(), AlarmState.ALARM);
                } else if (alarm.getComparisonOperator() == AlarmComparisonOperator.LessThanOrEqualToThreshold
                        && metricData.getValue() <= alarm.getThreshold()) {
                    setAlarmState(alarm.getAlarmName(), "Metric value less than or equal threshold",
                            metricData.getValue().toString(), AlarmState.ALARM);
                } else if (alarm.getComparisonOperator() == AlarmComparisonOperator.LessThanThreshold
                        && metricData.getValue() < alarm.getThreshold()) {
                    setAlarmState(alarm.getAlarmName(), "Metric value less than threshold",
                            metricData.getValue().toString(), AlarmState.ALARM);
                } else {
                    setAlarmState(alarm.getAlarmName(), "Metric value less than threshold",
                            metricData.getValue().toString(), AlarmState.OK);
                }
            }
        }
    }

    /**
     * Initialise - check if db, tables exist and create tables if does not exist
     */
    private void initialise() {

        if (!CheckIfDatabaseTablesExists()) {
            ProcessConfigFile();
        }
    }

    // endregion

    // region Public Members

    /**
     * Constructor
     * 
     * @param host
     * @param username
     * @param password
     */
    public MetricsProviderSQLServer(String host, String username, String password) {
        this.host = host;
        this.username = username;
        this.password = password;

        initialise();
    }

    /**
     * Constructor
     * 
     * @param host
     * @param username
     * @param password
     */
    public MetricsProviderSQLServer(String host, String username, String password, LoggingManager loggingManager) {
        this.host = host;
        this.username = username;
        this.password = password;
        this.loggingManager = loggingManager;

        initialise();
    }

    /**
     * Add a metric alarm
     * 
     * @param alarmName
     * @param alarmDescription
     * @param comparisonOperator
     * @param metricNamespace
     * @param metricName
     * @param satistic
     * @param threshold
     * @param unit
     * @return lastId
     */
    @Override
    public Integer addMetricAlarm(String alarmName, String alarmDescription,
            AlarmComparisonOperator comparisonOperator, String metricNamespace, String metricName,
            MetricStatistic statistic, Double threshold, MetricUnit unit) {
        Integer lastId = 0;
        Connection conn = null;
        CallableStatement stmt = null;

        try {
            Class.forName("net.sourceforge.jtds.jdbc.Driver");
            conn = DriverManager.getConnection(this.host + ";user=" + this.username + ";password=" + this.password);

            // create new alarm
            stmt = conn.prepareCall("uspMetricAlarm_Insert(?,?,?,?,?,?,?,?,?,?,?,?)");
            stmt.setInt(1, comparisonOperator.getValue());
            stmt.setInt(2, statistic.getValue());
            stmt.setInt(3, unit.getValue());
            stmt.setString(4, alarmName);
            stmt.setString(5, alarmDescription);
            stmt.setString(6, metricNamespace);
            stmt.setString(7, metricName);
            stmt.setDouble(8, threshold);
            stmt.setString(9, null);
            stmt.setString(10, null);
            stmt.setInt(11, AlarmState.OK.getValue());
            stmt.registerOutParameter(12, Types.INTEGER);
            stmt.execute();

            lastId = stmt.getInt(12);
        } catch (SQLException e) {
            this.loggingManager.LogError("Error : " + e.getClass().getName(), e.getMessage());
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            this.loggingManager.LogError("Error : " + e.getClass().getName(), e.getMessage());
            e.printStackTrace();
        } finally {
            DbUtils.closeQuietly(stmt);
            DbUtils.closeQuietly(conn);
        }

        return lastId;
    }

    /**
     * Add metric alarm history item
     * 
     * @param alarmMetricAlarmId
     * @param stateReason
     * @param stateReasonData
     * @param alarmState
     */
    @Override
    public void addMetricAlarmHistory(Integer alarmMetricAlarmId, String stateReason, String stateReasonData,
            AlarmState alarmState) {
        Connection conn = null;
        CallableStatement stmt = null;

        try {
            Class.forName("net.sourceforge.jtds.jdbc.Driver");
            conn = DriverManager.getConnection(this.host + ";user=" + this.username + ";password=" + this.password);

            // create new MetricAlarmHistoryItem
            stmt = conn.prepareCall("uspMetricAlarmHistoryItem_Insert(?,?,?,?)");
            stmt.setInt(1, alarmMetricAlarmId);
            stmt.setString(2, stateReason);
            stmt.setString(3, stateReasonData);
            stmt.setInt(4, alarmState.getValue());
            stmt.execute();
        } catch (SQLException e) {
            this.loggingManager.LogError("Error : " + e.getClass().getName(), e.getMessage());
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            this.loggingManager.LogError("Error : " + e.getClass().getName(), e.getMessage());
            e.printStackTrace();
        } finally {
            DbUtils.closeQuietly(stmt);
            DbUtils.closeQuietly(conn);
        }
    }

    /**
     * Add metric data
     * 
     * @param metricNamespace
     * @param metricName
     * @param unit
     * @param value
     * @data the extra data field
     */
    @Override
    public void addMetricData(String metricNamespace, String metricName, MetricUnit unit, Double value,
            String data) {
        Connection conn = null;
        CallableStatement stmt = null;

        try {
            Class.forName("net.sourceforge.jtds.jdbc.Driver");
            conn = DriverManager.getConnection(this.host + ";user=" + this.username + ";password=" + this.password);

            // create new metric data
            stmt = conn.prepareCall("uspMetricData_Insert(?,?,?,?,?)");
            stmt.setString(1, metricNamespace);
            stmt.setString(2, metricName);
            stmt.setInt(3, unit.getValue());
            stmt.setDouble(4, value);
            stmt.setString(5, data);
            stmt.execute();

            // Create a data item
            MetricData dataitem = new MetricData();
            dataitem.setMetricName(metricName);
            dataitem.setMetricNamespace(metricNamespace);
            dataitem.setUnit(unit);
            dataitem.setValue(value);
            dataitem.setData(data);

            // Evaluate for alarms
            evaluateMetricAlarm(dataitem);

        } catch (SQLException e) {
            this.loggingManager.LogError("Error : " + e.getClass().getName(), e.getMessage());
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            this.loggingManager.LogError("Error : " + e.getClass().getName(), e.getMessage());
            e.printStackTrace();
        } finally {
            DbUtils.closeQuietly(stmt);
            DbUtils.closeQuietly(conn);
        }
    }

    /**
     * Add metric sla
     * 
     * @param metricAlarmId
     * @param slaName
     * @param slaDescription
     * @param percentage
     * @param lastId
     */
    @Override
    public Integer addMetricSla(Integer metricAlarmId, String slaName, String slaDescription, Double percentage) {
        Connection conn = null;
        CallableStatement stmt = null;
        Integer lastId = 0;

        try {
            Class.forName("net.sourceforge.jtds.jdbc.Driver");
            conn = DriverManager.getConnection(this.host + ";user=" + this.username + ";password=" + this.password);

            // create new sla
            stmt = conn.prepareCall("uspMetricSla_Insert(?,?,?,?,?)");
            stmt.setInt(1, metricAlarmId);
            stmt.setString(2, slaName);
            stmt.setString(3, slaDescription);
            stmt.setDouble(4, percentage);
            stmt.registerOutParameter(5, Types.INTEGER);
            stmt.execute();

            lastId = stmt.getInt(5);
        } catch (SQLException e) {
            this.loggingManager.LogError("Error : " + e.getClass().getName(), e.getMessage());
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            this.loggingManager.LogError("Error : " + e.getClass().getName(), e.getMessage());
            e.printStackTrace();
        } finally {
            DbUtils.closeQuietly(stmt);
            DbUtils.closeQuietly(conn);
        }

        return lastId;
    }

    /**
     * Add MetricSLAExclusionTime
     * 
     * @param metricSlaId
     * @param dayOfWeek
     * @param startTime
     * @param endTime
     */
    @Override
    public void addMetricSlaExclusionTime(Integer metricSlaId, DayOfWeek dayOfWeek, String startTime,
            String endTime) {
        Connection conn = null;
        CallableStatement stmt = null;

        try {
            Class.forName("net.sourceforge.jtds.jdbc.Driver");
            conn = DriverManager.getConnection(this.host + ";user=" + this.username + ";password=" + this.password);

            // create new MetricSLAExclusionTime
            stmt = conn.prepareCall("uspMetricSlaExclusionTime_Insert(?,?,?,?)");
            stmt.setInt(1, metricSlaId);
            stmt.setInt(2, dayOfWeek.getValue());
            stmt.setString(3, startTime);
            stmt.setString(4, endTime);
            stmt.execute();
        } catch (SQLException e) {
            this.loggingManager.LogError("Error : " + e.getClass().getName(), e.getMessage());
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            this.loggingManager.LogError("Error : " + e.getClass().getName(), e.getMessage());
            e.printStackTrace();
        } finally {
            DbUtils.closeQuietly(stmt);
            DbUtils.closeQuietly(conn);
        }
    }

    /**
     * Add MetricSlaAlarmState
     * 
     * @param metricSlaId
     * @param alarmStateId
     */
    @Override
    public void addMetricSlaAlarmStatus(Integer metricSlaId, Integer alarmStateId) {
        Connection conn = null;
        CallableStatement stmt = null;

        try {
            Class.forName("net.sourceforge.jtds.jdbc.Driver");
            conn = DriverManager.getConnection(this.host + ";user=" + this.username + ";password=" + this.password);

            // create new MetricSlaAlarmStatus
            stmt = conn.prepareCall("uspMetricSlaAlarmStatus_Insert(?,?)");
            stmt.setInt(1, metricSlaId);
            stmt.setInt(2, alarmStateId);
            stmt.execute();
        } catch (SQLException e) {
            this.loggingManager.LogError("Error : " + e.getClass().getName(), e.getMessage());
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            this.loggingManager.LogError("Error : " + e.getClass().getName(), e.getMessage());
            e.printStackTrace();
        } finally {
            DbUtils.closeQuietly(stmt);
            DbUtils.closeQuietly(conn);
        }
    }

    /**
     * Register a metric event listener
     * 
     * @param listener
     * @return
     */
    @Override
    public void addMetricEventListener(MetricAlarmEvent listener) {
        this.eventSource.addMetricEventListener(listener);
    }

    /**
     * Delete alarm by id
     * 
     * @param metricAlarmId
     * @rowsDeleted
     */
    @Override
    public Integer deleteAlarm(Integer metricAlarmId) {
        Connection conn = null;
        CallableStatement stmt = null;
        Integer rowsDeleted = 0;

        try {
            Class.forName("net.sourceforge.jtds.jdbc.Driver");
            conn = DriverManager.getConnection(this.host + ";user=" + this.username + ";password=" + this.password);

            // delete alarm
            stmt = conn.prepareCall("uspMetricAlarm_Delete(?)");
            stmt.setInt(1, metricAlarmId);
            rowsDeleted = stmt.executeUpdate();
        } catch (SQLException e) {
            this.loggingManager.LogError("Error : " + e.getClass().getName(), e.getMessage());
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            this.loggingManager.LogError("Error : " + e.getClass().getName(), e.getMessage());
            e.printStackTrace();
        } finally {
            DbUtils.closeQuietly(stmt);
            DbUtils.closeQuietly(conn);
        }

        return rowsDeleted;
    }

    /**
     * Delete alarms history items for an alarm
     * 
     * @param metricAlarmId
     * @return rowsDeleted
     */
    @Override
    public Integer deleteAlarmHistoryItems(Integer metricAlarmId) {

        Connection conn = null;
        CallableStatement stmt = null;
        Integer rowsDeleted = 0;

        try {
            Class.forName("net.sourceforge.jtds.jdbc.Driver");
            conn = DriverManager.getConnection(this.host + ";user=" + this.username + ";password=" + this.password);

            // delete alarm history
            stmt = conn.prepareCall("uspMetricAlarmHistoryItem_Delete(?)");
            stmt.setInt(1, metricAlarmId);
            rowsDeleted = stmt.executeUpdate();
        } catch (SQLException e) {
            this.loggingManager.LogError("Error : " + e.getClass().getName(), e.getMessage());
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            this.loggingManager.LogError("Error : " + e.getClass().getName(), e.getMessage());
            e.printStackTrace();
        } finally {
            DbUtils.closeQuietly(stmt);
            DbUtils.closeQuietly(conn);
        }

        return rowsDeleted;
    }

    @Override
    public void deleteMaintenanceAlarmHistory(String metricNamespace, String metricName, Date endDate) {
        // TODO Auto-generated method stub

    }

    /**
     * Delete metric data by Metric namespace and metric name (if metric name = null
     * then delete all records for metric namespace
     * 
     * @param metricNamespace
     * @param metricName
     */
    @Override
    public void deleteMetricData(String metricNamespace, String metricName) {
        Connection conn = null;
        CallableStatement stmt = null;

        try {
            Class.forName("net.sourceforge.jtds.jdbc.Driver");
            conn = DriverManager.getConnection(this.host + ";user=" + this.username + ";password=" + this.password);

            // Delete metric data
            stmt = conn.prepareCall("uspMetricData_Delete(?,?,?,?)");
            stmt.setString(1, metricNamespace);
            stmt.setString(2, metricName);
            stmt.setString(3, null);
            stmt.setString(4, null);

            stmt.execute();
        } catch (SQLException e) {
            this.loggingManager.LogError("Error : " + e.getClass().getName(), e.getMessage());
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            this.loggingManager.LogError("Error : " + e.getClass().getName(), e.getMessage());
            e.printStackTrace();
        } finally {
            DbUtils.closeQuietly(stmt);
            DbUtils.closeQuietly(conn);
        }
    }

    /**
     * Delete Metric data - maintenance cleanup function
     * 
     * @param metricNamespace
     * @param startDate
     * @param endDate
     */
    @Override
    public void deleteMetricData(String metricNamespace, Date startDate, Date endDate) {
        Connection conn = null;
        CallableStatement stmt = null;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        try {
            Class.forName("net.sourceforge.jtds.jdbc.Driver");
            conn = DriverManager.getConnection(this.host + ";user=" + this.username + ";password=" + this.password);

            // Delete metric data
            stmt = conn.prepareCall("uspMetricData_Delete(?,?,?,?)");
            stmt.setString(1, metricNamespace);
            stmt.setNull(2, Types.NULL);

            if (startDate != null)
                stmt.setString(3, sdf.format(startDate));
            else
                stmt.setString(3, null);

            if (endDate != null)
                stmt.setString(4, sdf.format(endDate));
            else
                stmt.setString(4, null);

            stmt.execute();
        } catch (SQLException e) {
            this.loggingManager.LogError("Error : " + e.getClass().getName(), e.getMessage());
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            this.loggingManager.LogError("Error : " + e.getClass().getName(), e.getMessage());
            e.printStackTrace();
        } finally {
            DbUtils.closeQuietly(stmt);
            DbUtils.closeQuietly(conn);
        }
    }

    /**
     * Delete metric sla
     * 
     * @param metricSlaId
     * @return rowsDeleted
     */
    public Integer deleteMetricSla(Integer metricSlaId) {

        Connection conn = null;
        CallableStatement stmt = null;
        Integer rowsDeleted = 0;

        try {
            Class.forName("net.sourceforge.jtds.jdbc.Driver");
            conn = DriverManager.getConnection(this.host + ";user=" + this.username + ";password=" + this.password);

            // delete metric sla
            stmt = conn.prepareCall("uspMetricSla_Delete(?)");
            stmt.setInt(1, metricSlaId);
            rowsDeleted = stmt.executeUpdate();

        } catch (SQLException e) {
            this.loggingManager.LogError("Error : " + e.getClass().getName(), e.getMessage());
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            this.loggingManager.LogError("Error : " + e.getClass().getName(), e.getMessage());
            e.printStackTrace();
        } finally {
            DbUtils.closeQuietly(stmt);
            DbUtils.closeQuietly(conn);
        }

        return rowsDeleted;
    }

    /**
     * Delete metric sla alarm status's
     * 
     * @param metricSlaId
     */
    public void deleteMetricSlaAlarmStatus(Integer metricSlaId) {
        Connection conn = null;
        CallableStatement stmt = null;

        try {
            Class.forName("net.sourceforge.jtds.jdbc.Driver");
            conn = DriverManager.getConnection(this.host + ";user=" + this.username + ";password=" + this.password);

            // Delete metric sla exclusion time
            stmt = conn.prepareCall("uspMetricSlaAlarmStatus_Delete(?)");
            stmt.setInt(1, metricSlaId);

            stmt.execute();
        } catch (SQLException e) {
            this.loggingManager.LogError("Error : " + e.getClass().getName(), e.getMessage());
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            this.loggingManager.LogError("Error : " + e.getClass().getName(), e.getMessage());
            e.printStackTrace();
        } finally {
            DbUtils.closeQuietly(stmt);
            DbUtils.closeQuietly(conn);
        }
    }

    /**
     * Delete metric sla exclusion times
     * 
     * @param metricSlaId
     * @return rowsDeleted
     */
    public Integer deleteMetricSlaExclusionTimes(Integer metricSlaId) {
        Connection conn = null;
        CallableStatement stmt = null;
        Integer rowsDeleted = 0;

        try {
            Class.forName("net.sourceforge.jtds.jdbc.Driver");
            conn = DriverManager.getConnection(this.host + ";user=" + this.username + ";password=" + this.password);

            // Delete metric sla exclusion time
            stmt = conn.prepareCall("uspMetricSlaExclusionTime_Delete(?)");
            stmt.setInt(1, metricSlaId);

            rowsDeleted = stmt.executeUpdate();
        } catch (SQLException e) {
            this.loggingManager.LogError("Error : " + e.getClass().getName(), e.getMessage());
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            this.loggingManager.LogError("Error : " + e.getClass().getName(), e.getMessage());
            e.printStackTrace();
        } finally {
            DbUtils.closeQuietly(stmt);
            DbUtils.closeQuietly(conn);
        }

        return rowsDeleted;
    }

    /**
     * Get the history for a MetricAlarm by an alarm name and dates
     * 
     * @param alarmName
     * @param startDate
     * @param endDate
     */
    @Override
    public ArrayList<AlarmHistoryItem> getMetricAlarmHistory(String alarmName, Date startDate, Date endDate) {
        ArrayList<AlarmHistoryItem> alarmHistoryItems = new ArrayList<AlarmHistoryItem>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        Connection conn = null;
        CallableStatement stmt = null;
        ResultSet rs = null;

        try {
            Class.forName("net.sourceforge.jtds.jdbc.Driver");
            conn = DriverManager.getConnection(this.host + ";user=" + this.username + ";password=" + this.password);

            stmt = conn.prepareCall("uspMetricAlarmHistoryItem_GetByAlarmName(?,?,?)");
            stmt.setString(1, alarmName);

            if (startDate != null)
                stmt.setString(2, sdf.format(startDate));
            else
                stmt.setString(2, null);

            if (endDate != null)
                stmt.setString(3, sdf.format(endDate));
            else
                stmt.setString(3, null);

            rs = stmt.executeQuery();

            while (rs.next()) {
                AlarmState alarmState = AlarmState.NONE;
                AlarmMetricAlarm alarmMetricAlarm = new AlarmMetricAlarm();
                alarmMetricAlarm = getMetricAlarm(rs.getInt("MetricAlarmId"), null);

                AlarmHistoryItem alarmHistoryItem = new AlarmHistoryItem();
                alarmHistoryItem.setAlarmHistoryItemId(rs.getInt("MetricAlarmHistoryItemId"));
                alarmHistoryItem.setAlarmMetricAlarm(alarmMetricAlarm);
                alarmHistoryItem.setStateReason(rs.getString("StateReason"));
                alarmHistoryItem.setStateReasonData(rs.getString("StateReasonData"));
                alarmHistoryItem.setAlarmState(alarmState.findByValue(rs.getInt("AlarmStateId")));
                alarmHistoryItem.setTimestamp(sdf.parse(rs.getString("DateCreated")));

                alarmHistoryItems.add(alarmHistoryItem);
            }
        } catch (SQLException e) {
            this.loggingManager.LogError("Error : " + e.getClass().getName(), e.getMessage());
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            this.loggingManager.LogError("Error : " + e.getClass().getName(), e.getMessage());
            e.printStackTrace();
        } catch (ParseException e) {
            this.loggingManager.LogError("Error : " + e.getClass().getName(), e.getMessage());
            e.printStackTrace();
        } finally {
            DbUtils.closeQuietly(rs);
            DbUtils.closeQuietly(stmt);
            DbUtils.closeQuietly(conn);
        }
        return alarmHistoryItems;
    }

    /**
     * Retrieve all the alarm history for a current metric
     * 
     * @param metricNamespace
     * @param metricName
     */
    @Override
    public ArrayList<AlarmHistoryItem> getAlarmHistoryForMetric(String metricNamespace, String metricName) {
        ArrayList<AlarmHistoryItem> retAlarmHistoryItems = new ArrayList<AlarmHistoryItem>();

        ArrayList<AlarmMetricAlarm> alarmsForMetric = getMetricAlarmByMetricNamespace(metricNamespace, metricName);
        for (AlarmMetricAlarm alarmForMetric : alarmsForMetric) {
            ArrayList<AlarmHistoryItem> alarmHistoryItems = getMetricAlarmHistory(alarmForMetric.getAlarmName(),
                    null, null);
            for (AlarmHistoryItem alarmHistoryItem : alarmHistoryItems) {
                retAlarmHistoryItems.add(alarmHistoryItem);
            }
        }
        return retAlarmHistoryItems;
    }

    /**
     * Get AlarmMetricAlarm by alarm name or metricnamespace and/or metricname
     * 
     * @param alarmName
     * @param metricNamespace
     * @param metricName
     * @return
     */
    @Override
    public ArrayList<AlarmMetricAlarm> getMetricAlarmByMetricNamespace(String metricNamespace, String metricName) {
        ArrayList<AlarmMetricAlarm> alarmMetricAlarmList = new ArrayList<AlarmMetricAlarm>();

        Connection conn = null;
        CallableStatement stmt = null;
        ResultSet rs = null;

        try {
            Class.forName("net.sourceforge.jtds.jdbc.Driver");
            conn = DriverManager.getConnection(this.host + ";user=" + this.username + ";password=" + this.password);

            stmt = conn.prepareCall("uspMetricAlarm_GetByMetricNamespace(?,?)");

            stmt.setString(1, metricNamespace);
            stmt.setString(2, metricName);

            rs = stmt.executeQuery();

            while (rs.next()) {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                AlarmComparisonOperator alarmComparisonOperator = AlarmComparisonOperator.None;
                MetricStatistic metricStatistic = MetricStatistic.None;
                MetricUnit metricUnit = MetricUnit.None;
                AlarmState alarmState = AlarmState.NONE;

                AlarmMetricAlarm metricAlarm = new AlarmMetricAlarm();
                metricAlarm.setAlarmMetricAlarmId(rs.getInt("MetricAlarmId"));
                metricAlarm.setComparisonOperator(
                        alarmComparisonOperator.findByValue(rs.getInt("AlarmComparisonOperatorId")));
                metricAlarm.setMetricSatistic(metricStatistic.findByValue(rs.getInt("MetricStatisticId")));
                metricAlarm.setMetricUnit(metricUnit.findByValue(rs.getInt("MetricUnitId")));
                metricAlarm.setAlarmName(rs.getString("Name"));
                metricAlarm.setAlarmDescription(rs.getString("Description"));
                metricAlarm.setMetricNamespace(rs.getString("MetricNamespace"));
                metricAlarm.setMetricName(rs.getString("MetricName"));
                metricAlarm.setThreshold(rs.getDouble("Threshold"));
                metricAlarm.setStateReason(rs.getString("StateReason"));
                metricAlarm.setStateReasonData(rs.getString("StateReasonData"));
                metricAlarm.setStateValue(alarmState.findByValue(rs.getInt("AlarmStateId")));
                metricAlarm.setDateModified(sdf.parse(rs.getString("DateModified")));
                metricAlarm.setDateCreated(sdf.parse(rs.getString("DateCreated")));
                alarmMetricAlarmList.add(metricAlarm);
            }
        } catch (SQLException e) {
            this.loggingManager.LogError("Error : " + e.getClass().getName(), e.getMessage());
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            this.loggingManager.LogError("Error : " + e.getClass().getName(), e.getMessage());
            e.printStackTrace();
        } catch (ParseException e) {
            this.loggingManager.LogError("Error : " + e.getClass().getName(), e.getMessage());
            e.printStackTrace();
        } finally {
            DbUtils.closeQuietly(rs);
            DbUtils.closeQuietly(stmt);
            DbUtils.closeQuietly(conn);
        }
        return alarmMetricAlarmList;
    }

    /**
     * Get AlarmMetricAlarm by alarm id
     * 
     * @param alarmMetricAlarmId
     * @param alarmName
     * @return AlarmMetricAlarm
     */
    @Override
    public AlarmMetricAlarm getMetricAlarm(Integer alarmMetricAlarmId, String alarmName) {
        Connection conn = null;
        CallableStatement stmt = null;
        ResultSet rs = null;

        AlarmMetricAlarm alarmMetricAlarm = null;
        AlarmComparisonOperator alarmComparisonOperator = AlarmComparisonOperator.None;
        MetricStatistic metricStatistic = MetricStatistic.None;
        MetricUnit metricUnit = MetricUnit.None;
        AlarmState alarmState = AlarmState.NONE;

        try {
            Class.forName("net.sourceforge.jtds.jdbc.Driver");
            conn = DriverManager.getConnection(this.host + ";user=" + this.username + ";password=" + this.password);

            stmt = conn.prepareCall("uspMetricAlarm_Get(?,?)");

            if (alarmMetricAlarmId == null)
                stmt.setNull(1, Types.NULL);
            else
                stmt.setInt(1, alarmMetricAlarmId);

            stmt.setString(2, alarmName);

            rs = stmt.executeQuery();

            while (rs.next()) {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

                alarmMetricAlarm = new AlarmMetricAlarm();
                alarmMetricAlarm.setAlarmMetricAlarmId(rs.getInt("MetricAlarmId"));
                alarmMetricAlarm.setComparisonOperator(
                        alarmComparisonOperator.findByValue(rs.getInt("AlarmComparisonOperatorId")));
                alarmMetricAlarm.setMetricSatistic(metricStatistic.findByValue(rs.getInt("MetricStatisticId")));
                alarmMetricAlarm.setMetricUnit(metricUnit.findByValue(rs.getInt("MetricUnitId")));
                alarmMetricAlarm.setAlarmName(rs.getString("Name"));
                alarmMetricAlarm.setAlarmDescription(rs.getString("Description"));
                alarmMetricAlarm.setMetricNamespace(rs.getString("MetricNamespace"));
                alarmMetricAlarm.setMetricName(rs.getString("MetricName"));
                alarmMetricAlarm.setThreshold(rs.getDouble("Threshold"));
                alarmMetricAlarm.setStateReason(rs.getString("StateReason"));
                alarmMetricAlarm.setStateReasonData(rs.getString("StateReasonData"));
                alarmMetricAlarm.setStateValue(alarmState.findByValue(rs.getInt("AlarmStateId")));
                alarmMetricAlarm.setDateModified(sdf.parse(rs.getString("DateModified")));
                alarmMetricAlarm.setDateCreated(sdf.parse(rs.getString("DateCreated")));
            }
        } catch (SQLException e) {
            this.loggingManager.LogError("Error : " + e.getClass().getName(), e.getMessage());
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            this.loggingManager.LogError("Error : " + e.getClass().getName(), e.getMessage());
            e.printStackTrace();
        } catch (ParseException e) {
            this.loggingManager.LogError("Error : " + e.getClass().getName(), e.getMessage());
            e.printStackTrace();
        } finally {
            DbUtils.closeQuietly(rs);
            DbUtils.closeQuietly(stmt);
            DbUtils.closeQuietly(conn);
        }

        return alarmMetricAlarm;
    }

    /**
     * Gets statistics for the specified metric
     * 
     * @param metricNamespace
     * @param metricName
     * @param startDate
     * @param endDate
     * @return all the statics for a metric
     */
    @Override
    public HashMap<MetricStatistic, Double> getMetricStatistics(String metricNamespace, String metricName,
            Date startDate, Date endDate) {
        // set up our stats
        Double sum = 0.00;
        Double max = Double.MIN_VALUE;
        Double min = Double.MAX_VALUE;
        Double cnt = 0.00;

        ArrayList<MetricData> data = getMetricData(metricNamespace, metricName, startDate, endDate);

        if (data != null) {
            for (MetricData dataitem : data) {
                sum = sum + dataitem.getValue();
                if (dataitem.getValue() >= max) {
                    max = dataitem.getValue();
                }
                if (dataitem.getValue() <= min) {
                    min = dataitem.getValue();
                }
                cnt++;
            }
        }

        HashMap<MetricStatistic, Double> metricStatistics = new HashMap<MetricStatistic, Double>();

        metricStatistics.put(MetricStatistic.Average, cnt);
        if (cnt > 0) {
            metricStatistics.put(MetricStatistic.Average, sum / cnt);
        }
        metricStatistics.put(MetricStatistic.Maximum, max);
        metricStatistics.put(MetricStatistic.Minumim, min);
        metricStatistics.put(MetricStatistic.Sum, sum);

        return metricStatistics;
    }

    /**
     * Returns a list of all distinct metric namespaces
     * 
     * @return a list of metrics
     */
    @Override
    public ArrayList<HashMap<String, String>> getMetrics() {
        return getMetrics(null);
    }

    /**
     * List all the metrics for a namespace
     * 
     * @param metricNamespace
     * @return ArrayList<HashMap<String, String>>
     */
    @Override
    public ArrayList<HashMap<String, String>> getMetrics(String metricNamespace) {
        Connection conn = null;
        CallableStatement stmt = null;
        ResultSet rs = null;

        ArrayList<HashMap<String, String>> retData = new ArrayList<HashMap<String, String>>();

        try {
            Class.forName("net.sourceforge.jtds.jdbc.Driver");
            conn = DriverManager.getConnection(this.host + ";user=" + this.username + ";password=" + this.password);

            stmt = conn.prepareCall("uspMetricData_GetMetrics(?)");
            stmt.setString(1, metricNamespace);
            rs = stmt.executeQuery();

            while (rs.next()) {
                // Create a new container
                HashMap<String, String> metricNameContainer = new HashMap<String, String>();

                metricNameContainer.put("metricnamespace", rs.getString("MetricNamespace"));
                metricNameContainer.put("metricname", rs.getString("MetricName"));

                // Add the name
                retData.add(metricNameContainer);
            }
        } catch (SQLException e) {
            this.loggingManager.LogError("Error : " + e.getClass().getName(), e.getMessage());
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            this.loggingManager.LogError("Error : " + e.getClass().getName(), e.getMessage());
            e.printStackTrace();
        } finally {
            DbUtils.closeQuietly(rs);
            DbUtils.closeQuietly(stmt);
            DbUtils.closeQuietly(conn);
        }
        return retData;
    }

    /**
     * Get metric data object by id
     * 
     * @param metricDataId
     * @return MetricData
     */
    @Override
    public MetricData getMetricData(Integer metricDataId) {
        Connection conn = null;
        CallableStatement stmt = null;
        ResultSet rs = null;

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        MetricData dataitem = null;
        MetricUnit metricUnit = MetricUnit.None;

        try {
            Class.forName("net.sourceforge.jtds.jdbc.Driver");
            conn = DriverManager.getConnection(this.host + ";user=" + this.username + ";password=" + this.password);

            stmt = conn.prepareCall("dbo.uspMetricData_Get(?)");
            stmt.setInt(1, metricDataId);

            rs = stmt.executeQuery();

            while (rs.next()) {
                dataitem = new MetricData();
                dataitem.setMetricId(rs.getInt("MetricDataId"));
                dataitem.setUnit(metricUnit.findByValue(rs.getInt("MetricUnitId")));
                dataitem.setMetricNamespace(rs.getString("MetricNamespace"));
                dataitem.setMetricName(rs.getString("MetricName"));
                dataitem.setValue(rs.getDouble("Value"));
                dataitem.setData(rs.getString("Data"));
                dataitem.setTimestamp(sdf.parse(rs.getString("DateCreated")));
            }
        } catch (SQLException e) {
            this.loggingManager.LogError("Error : " + e.getClass().getName(), e.getMessage());
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            this.loggingManager.LogError("Error : " + e.getClass().getName(), e.getMessage());
            e.printStackTrace();
        } catch (ParseException e) {
            this.loggingManager.LogError("Error : " + e.getClass().getName(), e.getMessage());
            e.printStackTrace();
        } finally {
            DbUtils.closeQuietly(rs);
            DbUtils.closeQuietly(stmt);
            DbUtils.closeQuietly(conn);
        }

        return dataitem;
    }

    /**
     * Gets metric data
     * 
     * @param metricNamespace
     * @param metricName
     * @param startDate
     * @param endDate
     * @return ArrayList<MetricData>
     */
    @Override
    public ArrayList<MetricData> getMetricData(String metricNamespace, String metricName, Date startDate,
            Date endDate) {
        Connection conn = null;
        CallableStatement stmt = null;
        ResultSet rs = null;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        // create a container for the data
        ArrayList<MetricData> data = new ArrayList<MetricData>();

        try {
            Class.forName("net.sourceforge.jtds.jdbc.Driver");
            conn = DriverManager.getConnection(this.host + ";user=" + this.username + ";password=" + this.password);

            stmt = conn.prepareCall("uspMetricData_GetMetricData(?,?,?,?)");
            stmt.setString(1, metricNamespace);
            stmt.setString(2, metricName);

            if (startDate != null)
                stmt.setString(3, sdf.format(startDate));
            else
                stmt.setString(3, null);

            if (endDate != null)
                stmt.setString(4, sdf.format(endDate));
            else
                stmt.setString(4, null);

            rs = stmt.executeQuery();

            while (rs.next()) {

                MetricUnit metricUnit = MetricUnit.None;

                MetricData dataitem = new MetricData();
                dataitem.setMetricId(rs.getInt("MetricDataId"));
                dataitem.setUnit(metricUnit.findByValue(rs.getInt("MetricUnitId")));
                dataitem.setMetricNamespace(rs.getString("MetricNamespace"));
                dataitem.setMetricName(rs.getString("MetricName"));
                dataitem.setValue(rs.getDouble("Value"));
                dataitem.setData(rs.getString("Data"));
                dataitem.setTimestamp(sdf.parse(rs.getString("DateCreated")));
                data.add(dataitem);
            }
        } catch (SQLException e) {
            this.loggingManager.LogError("Error : " + e.getClass().getName(), e.getMessage());
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            this.loggingManager.LogError("Error : " + e.getClass().getName(), e.getMessage());
            e.printStackTrace();
        } catch (ParseException e) {
            this.loggingManager.LogError("Error : " + e.getClass().getName(), e.getMessage());
            e.printStackTrace();
        } finally {
            DbUtils.closeQuietly(rs);
            DbUtils.closeQuietly(stmt);
            DbUtils.closeQuietly(conn);
        }

        return data;
    }

    /**
     * List all metric sla's or by metric alarmid
     * 
     * @param metricAlarmId
     * 
     * @return ArrayList<MetricSLA>
     */
    @Override
    public ArrayList<MetricSLA> getMetricSlas(Integer metricAlarmId) {
        Connection conn = null;
        CallableStatement stmt = null;
        ResultSet rs = null;

        // create a container for the data
        ArrayList<MetricSLA> metricSlaList = new ArrayList<MetricSLA>();

        try {
            Class.forName("net.sourceforge.jtds.jdbc.Driver");
            conn = DriverManager.getConnection(this.host + ";user=" + this.username + ";password=" + this.password);

            stmt = conn.prepareCall("uspMetricSla_GetByMetricAlarmId(?)");

            if (metricAlarmId == null)
                stmt.setNull(1, Types.NULL);
            else
                stmt.setInt(1, metricAlarmId);

            rs = stmt.executeQuery();

            while (rs.next()) {
                AlarmMetricAlarm alarmMetricAlarm = new AlarmMetricAlarm();
                alarmMetricAlarm = getMetricAlarm(rs.getInt("MetricAlarmId"), null);

                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

                MetricSLA dataitem = new MetricSLA();
                dataitem.setMetricSLAId(rs.getInt("MetricSlaId"));
                dataitem.setAlarmMetricAlarm(alarmMetricAlarm);
                dataitem.setSLAName(rs.getString("Name"));
                dataitem.setSLADescription(rs.getString("Description"));
                dataitem.setPercentage(rs.getDouble("Percentage"));
                dataitem.setDateModified(sdf.parse(rs.getString("DateModified")));
                dataitem.setDateCreated(sdf.parse(rs.getString("DateCreated")));
                metricSlaList.add(dataitem);
            }
        } catch (SQLException e) {
            this.loggingManager.LogError("Error : " + e.getClass().getName(), e.getMessage());
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            this.loggingManager.LogError("Error : " + e.getClass().getName(), e.getMessage());
            e.printStackTrace();
        } catch (ParseException e) {
            this.loggingManager.LogError("Error : " + e.getClass().getName(), e.getMessage());
            e.printStackTrace();
        } finally {
            DbUtils.closeQuietly(rs);
            DbUtils.closeQuietly(stmt);
            DbUtils.closeQuietly(conn);
        }

        return metricSlaList;
    }

    /**
     * Get metric sla by MetricSlaId/Sla Name
     * 
     * @param metricSlaId
     * @param slaName
     * @return MetricSLA
     */
    @Override
    public MetricSLA getMetricSla(Integer metricSlaId, String slaName) {
        Connection conn = null;
        CallableStatement stmt = null;
        ResultSet rs = null;

        // create a container for the data
        MetricSLA dataitem = null;

        try {
            Class.forName("net.sourceforge.jtds.jdbc.Driver");
            conn = DriverManager.getConnection(this.host + ";user=" + this.username + ";password=" + this.password);

            stmt = conn.prepareCall("uspMetricSla_Get(?,?)");

            if (metricSlaId == null)
                stmt.setNull(1, Types.NULL);
            else
                stmt.setInt(1, metricSlaId);

            if (slaName == null)
                stmt.setNull(2, Types.NULL);
            else
                stmt.setString(2, slaName);

            rs = stmt.executeQuery();

            while (rs.next()) {
                AlarmMetricAlarm alarmMetricAlarm = new AlarmMetricAlarm();
                alarmMetricAlarm = getMetricAlarm(rs.getInt("MetricAlarmId"), null);

                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                dataitem = new MetricSLA();
                dataitem.setMetricSLAId(rs.getInt("MetricSlaId"));
                dataitem.setAlarmMetricAlarm(alarmMetricAlarm);
                dataitem.setSLAName(rs.getString("Name"));
                dataitem.setSLADescription(rs.getString("Description"));
                dataitem.setPercentage(rs.getDouble("Percentage"));
                dataitem.setDateModified(sdf.parse(rs.getString("DateModified")));
                dataitem.setDateCreated(sdf.parse(rs.getString("DateCreated")));
            }
        } catch (SQLException e) {
            this.loggingManager.LogError("Error : " + e.getClass().getName(), e.getMessage());
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            this.loggingManager.LogError("Error : " + e.getClass().getName(), e.getMessage());
            e.printStackTrace();
        } catch (ParseException e) {
            this.loggingManager.LogError("Error : " + e.getClass().getName(), e.getMessage());
            e.printStackTrace();
        } finally {
            DbUtils.closeQuietly(rs);
            DbUtils.closeQuietly(stmt);
            DbUtils.closeQuietly(conn);
        }

        return dataitem;
    }

    /**
     * Get list of MetricSlaAlarmStatus(es) by MetricSlaId
     * 
     * @param metricSlaId
     * @param startDate
     * @param endDate
     * @return ArrayList<MetricSlaAlarmStatus>
     */
    @Override
    public ArrayList<MetricSlaAlarmStatus> getMetricSlaAlarmStatus(Integer metricSlaId, Date startDate,
            Date endDate) {
        Connection conn = null;
        CallableStatement stmt = null;
        ResultSet rs = null;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        AlarmState alarmState = AlarmState.NONE;

        // create a container for the data
        ArrayList<MetricSlaAlarmStatus> metricSlaAlarmStatusList = new ArrayList<MetricSlaAlarmStatus>();

        try {
            Class.forName("net.sourceforge.jtds.jdbc.Driver");
            conn = DriverManager.getConnection(this.host + ";user=" + this.username + ";password=" + this.password);

            stmt = conn.prepareCall("uspMetricSlaAlarmStatus_GetBySlaId(?,?,?)");
            stmt.setInt(1, metricSlaId);

            if (startDate != null)
                stmt.setString(2, sdf.format(startDate));
            else
                stmt.setString(2, null);

            if (endDate != null)
                stmt.setString(3, sdf.format(endDate));
            else
                stmt.setString(3, null);

            rs = stmt.executeQuery();

            while (rs.next()) {
                MetricSLA metricSla = new MetricSLA();
                metricSla = getMetricSla(rs.getInt("MetricSlaId"), null);

                MetricSlaAlarmStatus dataitem = new MetricSlaAlarmStatus();
                dataitem.setMetricSlaAlarmStatusId(rs.getInt("MetricSlaAlarmStatusId"));
                dataitem.setMetricSLA(metricSla);
                dataitem.setAlarmState(alarmState.findByValue(rs.getInt("AlarmStateId")));
                dataitem.setTimestamp(sdf.parse(rs.getString("DateCreated")));

                metricSlaAlarmStatusList.add(dataitem);
            }
        } catch (SQLException e) {
            this.loggingManager.LogError("Error : " + e.getClass().getName(), e.getMessage());
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            this.loggingManager.LogError("Error : " + e.getClass().getName(), e.getMessage());
            e.printStackTrace();
        } catch (ParseException e) {
            this.loggingManager.LogError("Error : " + e.getClass().getName(), e.getMessage());
            e.printStackTrace();
        } finally {
            DbUtils.closeQuietly(rs);
            DbUtils.closeQuietly(stmt);
            DbUtils.closeQuietly(conn);
        }

        return metricSlaAlarmStatusList;
    }

    /**
     * Get metric sla result
     * 
     * @param metricSlaId
     * @param startDate
     * @param endDate
     * @return MetricSLAResult
     */
    @Override
    public MetricSLAResult getMetricSlaResult(Integer metricSlaId, Date startDate, Date endDate) {
        MetricSLAResult metricSlaResult = new MetricSLAResult();

        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            Date date = new Date();
            Double actualPercentage = null;

            MetricSLAState metricSlaState = MetricSLAState.NO_DATA;

            MetricSLA metricSla = new MetricSLA();
            metricSla = this.getMetricSla(metricSlaId, null);

            // Get alarm status history for this sla
            ArrayList<MetricSlaAlarmStatus> metricSlaAlarmStatusList = new ArrayList<MetricSlaAlarmStatus>();
            metricSlaAlarmStatusList = this.getMetricSlaAlarmStatus(metricSlaId, startDate, endDate);

            if (metricSlaAlarmStatusList.size() > 0) {
                Double totalAlarmCount = 0.0;

                for (MetricSlaAlarmStatus m : metricSlaAlarmStatusList) {
                    // Get total count of when alarm been raised
                    if (m.getAlarmState().equals(AlarmState.OK)) {
                        totalAlarmCount += 1;
                    }
                }

                // Calculate sla percentage
                Double metricSlaAlarmStatusCount = (double) metricSlaAlarmStatusList.size();
                actualPercentage = totalAlarmCount / metricSlaAlarmStatusCount * 100.0;

                if (actualPercentage >= metricSla.getPercentage()) {
                    metricSlaState = MetricSLAState.IN_SLA;
                } else {
                    metricSlaState = MetricSLAState.OUT_SLA;
                }

            } else {
                metricSlaState = MetricSLAState.NO_DATA;
                actualPercentage = 0.0;
            }

            metricSlaResult.setMetricSLA(metricSla);
            metricSlaResult.setMetricSLAState(metricSlaState);
            metricSlaResult.setStartDate(sdf.parse(sdf.format(date)));
            metricSlaResult.setStartDate(startDate);
            metricSlaResult.setEndDate(endDate);
            metricSlaResult.setSlaPercentage(actualPercentage);

        } catch (ParseException e) {
            this.loggingManager.LogError("Error : " + e.getClass().getName(), e.getMessage());
            e.printStackTrace();
        }
        return metricSlaResult;
    }

    /**
     * Get list of MetricSLAExclusionTime(s) by MetricSlaId
     * 
     * @param metricSlaId
     * @return ArrayList<MetricSLAExclusionTime>
     */
    @Override
    public ArrayList<MetricSLAExclusionTime> getMetricSlaExclusionTime(Integer metricSlaId) {
        Connection conn = null;
        CallableStatement stmt = null;
        ResultSet rs = null;

        // create a container for the data
        ArrayList<MetricSLAExclusionTime> metricSLAExclusionTimeList = new ArrayList<MetricSLAExclusionTime>();

        try {
            Class.forName("net.sourceforge.jtds.jdbc.Driver");
            conn = DriverManager.getConnection(this.host + ";user=" + this.username + ";password=" + this.password);

            stmt = conn.prepareCall("uspMetricSlaExclusionTime_GetBySlaId(?)");
            stmt.setInt(1, metricSlaId);

            rs = stmt.executeQuery();

            while (rs.next()) {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                DayOfWeek dayOfWeek = DayOfWeek.Monday;

                MetricSLA metricSla = new MetricSLA();
                metricSla = getMetricSla(rs.getInt("MetricSlaId"), null);

                MetricSLAExclusionTime dataitem = new MetricSLAExclusionTime();
                dataitem.setMetricSLAExclusionTimeId(rs.getInt("MetricSLAExclusionTimeId"));
                dataitem.setMetricSla(metricSla);
                dataitem.setDayOfWeek(dayOfWeek.findByValue(rs.getInt("DayOfWeekId")));
                dataitem.setStartTime(rs.getString("StartTime"));
                dataitem.setEndTime(rs.getString("EndTime"));
                dataitem.setTimestamp(sdf.parse(rs.getString("DateCreated")));

                metricSLAExclusionTimeList.add(dataitem);
            }
        } catch (SQLException e) {
            this.loggingManager.LogError("Error : " + e.getClass().getName(), e.getMessage());
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            this.loggingManager.LogError("Error : " + e.getClass().getName(), e.getMessage());
            e.printStackTrace();
        } catch (ParseException e) {
            this.loggingManager.LogError("Error : " + e.getClass().getName(), e.getMessage());
            e.printStackTrace();
        } finally {
            DbUtils.closeQuietly(rs);
            DbUtils.closeQuietly(stmt);
            DbUtils.closeQuietly(conn);
        }

        return metricSLAExclusionTimeList;
    }

    /**
     * Set an alarm state
     * 
     * @param alarmName
     * @param stateReason
     * @param stateReasonData
     * @param stateValue
     */
    @Override
    public void setAlarmState(String alarmName, String stateReason, String stateReasonData, AlarmState alarmState) {

        // Get metric alarm by Alarm name
        AlarmMetricAlarm metricAlarm = getMetricAlarm(null, alarmName);

        if (metricAlarm != null) {
            // store the current state
            AlarmState current = metricAlarm.getStateValue();

            // Update object
            metricAlarm.setStateReason(stateReason);
            metricAlarm.setStateReasonData(stateReasonData);

            // Update alarm statereason, statereasonData and alarmstate
            updateMetricAlarm(metricAlarm.getAlarmMetricAlarmId(), metricAlarm.getAlarmName(),
                    metricAlarm.getAlarmDescription(), metricAlarm.getComparisonOperator(),
                    metricAlarm.getMetricNamespace(), metricAlarm.getMetricName(), metricAlarm.getMetricSatistic(),
                    metricAlarm.getThreshold(), metricAlarm.getMetricUnit(), metricAlarm.getStateReason(),
                    metricAlarm.getStateReasonData(), alarmState);

            // Add alarm history item
            addMetricAlarmHistory(metricAlarm.getAlarmMetricAlarmId(), metricAlarm.getStateReason(),
                    metricAlarm.getStateReasonData(), metricAlarm.getStateValue());

            // determine the new state. If it has changed, raise the
            // alarm
            AlarmState newvalue = alarmState;
            if (!current.equals(newvalue)) {
                this.eventSource.raiseMetricAlarm(metricAlarm);
            }
        }
    }

    @Override
    public void setLoggingManager(LoggingManager loggingManager) {
        this.loggingManager = loggingManager;
    }

    /**
     * Update a metric alarm
     * 
     * @param metricAlarmId
     * @param alarmName
     * @param alarmDescription
     * @param comparisonOperator
     * @param metricNamespace
     * @param metricName
     * @param statistic
     * @param threshold
     * @param unit
     * @param stateReason
     * @param stateReasonData
     * @param alarmState
     * @return rowsUpdated
     */
    @Override
    public Integer updateMetricAlarm(Integer metricAlarmId, String alarmName, String alarmDescription,
            AlarmComparisonOperator comparisonOperator, String metricNamespace, String metricName,
            MetricStatistic statistic, Double threshold, MetricUnit unit, String stateReason,
            String stateReasonData, AlarmState alarmState) {
        Connection conn = null;
        CallableStatement stmt = null;
        Integer rowsUpdated = 0;

        try {
            Class.forName("net.sourceforge.jtds.jdbc.Driver");
            conn = DriverManager.getConnection(this.host + ";user=" + this.username + ";password=" + this.password);

            // create new alarm
            stmt = conn.prepareCall("uspMetricAlarm_Update(?,?,?,?,?,?,?,?,?,?,?,?)");
            stmt.setInt(1, metricAlarmId);
            stmt.setInt(2, comparisonOperator.getValue());
            stmt.setInt(3, statistic.getValue());
            stmt.setInt(4, unit.getValue());
            stmt.setString(5, alarmName);
            stmt.setString(6, alarmDescription);
            stmt.setString(7, metricNamespace);
            stmt.setString(8, metricName);
            stmt.setDouble(9, threshold);
            stmt.setString(10, stateReason);
            stmt.setString(11, stateReasonData);
            stmt.setInt(12, alarmState.getValue());
            rowsUpdated = stmt.executeUpdate();
        } catch (SQLException e) {
            this.loggingManager.LogError("Error : " + e.getClass().getName(), e.getMessage());
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            this.loggingManager.LogError("Error : " + e.getClass().getName(), e.getMessage());
            e.printStackTrace();
        } finally {
            DbUtils.closeQuietly(stmt);
            DbUtils.closeQuietly(conn);
        }

        return rowsUpdated;
    }

    /**
     * Update metric sla
     * 
     * @param metricSlaId
     * @param metricAlarmId
     * @param slaName
     * @param slaDescription
     * @param percentage
     * @return rowsUpdated
     */
    @Override
    public Integer updateMetricSla(Integer metricSlaId, Integer metricAlarmId, String slaName,
            String slaDescription, Double percentage) {
        Connection conn = null;
        CallableStatement stmt = null;
        Integer rowsUpdated = 0;

        try {
            Class.forName("net.sourceforge.jtds.jdbc.Driver");
            conn = DriverManager.getConnection(this.host + ";user=" + this.username + ";password=" + this.password);

            // Update sla
            stmt = conn.prepareCall("uspMetricSla_Update(?,?,?,?,?,?)");
            stmt.setInt(1, metricSlaId);
            stmt.setInt(2, metricAlarmId);
            stmt.setString(3, slaName);
            stmt.setString(4, slaDescription);
            stmt.setDouble(5, percentage);
            rowsUpdated = stmt.executeUpdate();
        } catch (SQLException e) {
            this.loggingManager.LogError("Error : " + e.getClass().getName(), e.getMessage());
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            this.loggingManager.LogError("Error : " + e.getClass().getName(), e.getMessage());
            e.printStackTrace();
        } finally {
            DbUtils.closeQuietly(stmt);
            DbUtils.closeQuietly(conn);
        }

        return rowsUpdated;
    }

    // endregion
}