/******************************************************************************* * This file is part of OpenNMS(R). * * Copyright (C) 2010-2011 The OpenNMS Group, Inc. * OpenNMS(R) is Copyright (C) 1999-2011 The OpenNMS Group, Inc. * * OpenNMS(R) is a registered trademark of The OpenNMS Group, Inc. * * OpenNMS(R) is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published * by the Free Software Foundation, either version 3 of the License, * or (at your option) any later version. * * OpenNMS(R) is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with OpenNMS(R). If not, see: * http://www.gnu.org/licenses/ * * For more information contact: * OpenNMS(R) Licensing <license@opennms.org> * http://www.opennms.org/ * http://www.opennms.com/ *******************************************************************************/ package org.opennms.web.category; import java.io.IOException; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Timestamp; import java.util.Calendar; import java.util.Collections; import java.util.Date; import java.util.GregorianCalendar; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Set; import java.util.TreeMap; import org.exolab.castor.xml.MarshalException; import org.exolab.castor.xml.ValidationException; import org.opennms.core.resource.Vault; import org.opennms.core.utils.DBUtils; import org.opennms.core.utils.LogUtils; import org.opennms.core.utils.ThreadCategory; import org.opennms.netmgt.config.CatFactory; import org.opennms.netmgt.config.CategoryFactory; /** * <p>CategoryModel class.</p> * * @author ranger * @version $Id: $ */ public class CategoryModel extends Object { /** The name of the category that includes all services and nodes. */ public static final String OVERALL_AVAILABILITY_CATEGORY = "Overall Service Availability"; /** The singleton instance of this class. */ private static CategoryModel m_instance; /** * Return the <code>CategoryModel</code>. * * @return a {@link org.opennms.web.category.CategoryModel} object. * @throws java.io.IOException if any. * @throws org.exolab.castor.xml.MarshalException if any. * @throws org.exolab.castor.xml.ValidationException if any. */ public synchronized static CategoryModel getInstance() throws IOException, MarshalException, ValidationException { if (CategoryModel.m_instance == null) { CategoryModel.m_instance = new CategoryModel(); } return (CategoryModel.m_instance ); } /** A mapping of category names to category instances. */ private HashMap<String, Category> m_categoryMap = new HashMap<String, Category>(); /** A reference to the CategoryFactory to get to category definitions. */ private CatFactory m_factory = null; /** The Log4J category for logging status and debug messages. */ private ThreadCategory m_log = org.opennms.core.utils.ThreadCategory.getInstance("RTC"); /** * Create the instance of the CategoryModel. */ private CategoryModel() throws IOException, MarshalException, ValidationException { CategoryFactory.init(); m_factory = CategoryFactory.getInstance(); m_log.debug("The CategoryModel object was created"); } /** * Return the <code>Category</code> instance for the given category name. * Return null if there is no match for the given name. * * @param categoryName a {@link java.lang.String} object. * @return a {@link org.opennms.web.category.Category} object. */ public Category getCategory(String categoryName) { if (categoryName == null) { throw new IllegalArgumentException("Cannot take null parameters."); } return (Category) m_categoryMap.get(categoryName); } /** * Return a mapping of category names to instances. * * @return a {@link java.util.Map} object. */ public Map<String, Category> getCategoryMap() { return Collections.unmodifiableMap(new HashMap<String, Category>(m_categoryMap)); } /** * Look up the category definition and return the category's normal * threshold. * * @param categoryName a {@link java.lang.String} object. * @return a double. */ public double getCategoryNormalThreshold(String categoryName) { if (categoryName == null) { throw new IllegalArgumentException("Cannot take null parameters."); } return m_factory.getNormal(categoryName); } /** * Look up the category definition and return the category's warning * threshold. * * @param categoryName a {@link java.lang.String} object. * @return a double. */ public double getCategoryWarningThreshold(String categoryName) { if (categoryName == null) { throw new IllegalArgumentException("Cannot take null parameters."); } return m_factory.getWarning(categoryName); } /** * Look up the category definition and return the category's description. * * @param categoryName a {@link java.lang.String} object. * @return a {@link java.lang.String} object. */ public String getCategoryComment(final String categoryName) { if (categoryName == null) { throw new IllegalArgumentException("Cannot take null parameters."); } String comment = null; m_factory.getReadLock().lock(); try { org.opennms.netmgt.config.categories.Category category = m_factory.getCategory(categoryName); if (category != null) { comment = category.getComment(); } } finally { m_factory.getReadLock().unlock(); } return comment; } /** * Update a category with new values. * * @param rtcCategory a {@link org.opennms.netmgt.xml.rtc.Category} object. */ public void updateCategory(final org.opennms.netmgt.xml.rtc.Category rtcCategory) { if (rtcCategory == null) { throw new IllegalArgumentException("Cannot take null parameters."); } final String categoryName = rtcCategory.getCatlabel(); m_factory.getWriteLock().lock(); try { org.opennms.netmgt.config.categories.Category categoryDef = m_factory.getCategory(categoryName); org.opennms.web.category.Category category = new org.opennms.web.category.Category(categoryDef, rtcCategory, new Date()); synchronized (m_categoryMap) { m_categoryMap.put(categoryName, category); } } finally { m_factory.getWriteLock().unlock(); } m_log.debug(categoryName + " was updated"); } /** * Return the availability percentage for all managed services on the given * node for the last 24 hours. If there are no managed services on this * node, then a value of -1 is returned. * * @param nodeId a int. * @return a double. * @throws java.sql.SQLException if any. */ public double getNodeAvailability(int nodeId) throws SQLException { Calendar cal = new GregorianCalendar(); Date now = cal.getTime(); cal.add(Calendar.DATE, -1); Date yesterday = cal.getTime(); return getNodeAvailability(nodeId, yesterday, now); } /** * Return the availability percentage for all managed services on the given * node from the given start time until the given end time. If there are no * managed services on this node, then a value of -1 is returned. * * @param nodeId a int. * @param start a {@link java.util.Date} object. * @param end a {@link java.util.Date} object. * @return a double. * @throws java.sql.SQLException if any. */ public double getNodeAvailability(int nodeId, Date start, Date end) throws SQLException { if (start == null || end == null) { throw new IllegalArgumentException("Cannot take null parameters."); } if (end.before(start)) { throw new IllegalArgumentException("Cannot have an end time before the start time."); } if (end.equals(start)) { throw new IllegalArgumentException("Cannot have an end time equal to the start time."); } double avail = -1; final DBUtils d = new DBUtils(getClass()); try { Connection conn = Vault.getDbConnection(); d.watch(conn); PreparedStatement stmt = conn.prepareStatement("select getManagePercentAvailNodeWindow(?, ?, ?) as avail"); d.watch(stmt); stmt.setInt(1, nodeId); // yes, these are supposed to be backwards, the end time first stmt.setTimestamp(2, new Timestamp(end.getTime())); stmt.setTimestamp(3, new Timestamp(start.getTime())); ResultSet rs = stmt.executeQuery(); d.watch(rs); if (rs.next()) { avail = rs.getDouble("avail"); } } catch (final SQLException e) { LogUtils.warnf(this, e, "Failed to get node availability for nodeId %d", nodeId); } finally { d.cleanUp(); } return avail; } /** * Return the availability percentage for all managed services on the given * nodes for the last 24 hours. If there are no managed services on these * nodes, then a value of -1 is returned. * * @param nodeIds a {@link java.util.Set} object. * @return a {@link java.util.Map} object. * @throws java.sql.SQLException if any. */ public Map<Integer, Double> getNodeAvailability(Set<Integer> nodeIds) throws SQLException { Calendar cal = new GregorianCalendar(); Date now = cal.getTime(); cal.add(Calendar.DATE, -1); Date yesterday = cal.getTime(); return getNodeAvailability(nodeIds, yesterday, now); } /** * Return the availability percentage for all managed services on the given * nodes from the given start time until the given end time. If there are no * managed services on these nodes, then a value of -1 is returned. * * @param nodeIds a {@link java.util.Set} object. * @param start a {@link java.util.Date} object. * @param end a {@link java.util.Date} object. * @return a {@link java.util.Map} object. * @throws java.sql.SQLException if any. */ public Map<Integer, Double> getNodeAvailability(Set<Integer> nodeIds, Date start, Date end) throws SQLException { if(nodeIds==null || nodeIds.size()==0){ throw new IllegalArgumentException("Cannot take nodeIds null or with length 0."); } if (start == null || end == null) { throw new IllegalArgumentException("Cannot take null parameters."); } if (end.before(start)) { throw new IllegalArgumentException("Cannot have an end time before the start time."); } if (end.equals(start)) { throw new IllegalArgumentException("Cannot have an end time equal to the start time."); } double avail = -1; int nodeid = 0; Map<Integer, Double> retMap = new TreeMap<Integer, Double>(); final DBUtils d = new DBUtils(getClass()); try { Connection conn = Vault.getDbConnection(); d.watch(conn); StringBuffer sb = new StringBuffer("select nodeid, getManagePercentAvailNodeWindow(nodeid, ?, ?) from node where nodeid in ("); Iterator<Integer> it = nodeIds.iterator(); while (it.hasNext()){ sb.append(it.next()); if (it.hasNext()) { sb.append(", "); } } sb.append(")"); PreparedStatement stmt = conn.prepareStatement(sb.toString()); d.watch(stmt); // yes, these are supposed to be backwards, the end time first stmt.setTimestamp(1, new Timestamp(end.getTime())); stmt.setTimestamp(2, new Timestamp(start.getTime())); ResultSet rs = stmt.executeQuery(); d.watch(rs); while (rs.next()) { nodeid = rs.getInt(1); avail = rs.getDouble(2); retMap.put(new Integer(nodeid), new Double(avail)); } } catch (final SQLException e) { LogUtils.warnf(this, e, "Failed to get node availability for nodeIds %s", nodeIds); } finally { d.cleanUp(); } return Collections.unmodifiableMap(retMap); } /** * Return the availability percentage for all managed services on the given * interface for the last 24 hours. If there are no managed services on this * interface, then a value of -1 is returned. * * @param nodeId a int. * @param ipAddr a {@link java.lang.String} object. * @return a double. * @throws java.sql.SQLException if any. */ public double getInterfaceAvailability(int nodeId, String ipAddr) throws SQLException { if (ipAddr == null) { throw new IllegalArgumentException("Cannot take null parameters."); } Calendar cal = new GregorianCalendar(); Date now = cal.getTime(); cal.add(Calendar.DATE, -1); Date yesterday = cal.getTime(); return getInterfaceAvailability(nodeId, ipAddr, yesterday, now); } /** * Return the availability percentage for all managed services on the given * interface from the given start time until the given end time. If there * are no managed services on this interface, then a value of -1 is * returned. * * @param nodeId a int. * @param ipAddr a {@link java.lang.String} object. * @param start a {@link java.util.Date} object. * @param end a {@link java.util.Date} object. * @return a double. * @throws java.sql.SQLException if any. */ public double getInterfaceAvailability(int nodeId, String ipAddr, Date start, Date end) throws SQLException { if (ipAddr == null || start == null || end == null) { throw new IllegalArgumentException("Cannot take null parameters."); } if (end.before(start)) { throw new IllegalArgumentException("Cannot have an end time before the start time."); } if (end.equals(start)) { throw new IllegalArgumentException("Cannot have an end time equal to the start time."); } double avail = -1; final DBUtils d = new DBUtils(getClass()); try { Connection conn = Vault.getDbConnection(); d.watch(conn); PreparedStatement stmt = conn.prepareStatement("select getManagePercentAvailIntfWindow(?, ?, ?, ?) as avail"); d.watch(stmt); stmt.setInt(1, nodeId); stmt.setString(2, ipAddr); // yes, these are supposed to be backwards, the end time first stmt.setTimestamp(3, new Timestamp(end.getTime())); stmt.setTimestamp(4, new Timestamp(start.getTime())); ResultSet rs = stmt.executeQuery(); d.watch(rs); if (rs.next()) { avail = rs.getDouble("avail"); } } catch (final SQLException e) { LogUtils.warnf(this, e, "Failed to get interface availability for nodeId %d, interface %s", nodeId, ipAddr); } finally { d.cleanUp(); } return avail; } /** * Return the availability percentage for a managed service for the last 24 * hours. If the service is not managed, then a value of -1 is returned. * * @param nodeId a int. * @param ipAddr a {@link java.lang.String} object. * @param serviceId a int. * @return a double. * @throws java.sql.SQLException if any. */ public double getServiceAvailability(int nodeId, String ipAddr, int serviceId) throws SQLException { if (ipAddr == null) { throw new IllegalArgumentException("Cannot take null parameters."); } Calendar cal = new GregorianCalendar(); Date now = cal.getTime(); cal.add(Calendar.DATE, -1); Date yesterday = cal.getTime(); return getServiceAvailability(nodeId, ipAddr, serviceId, yesterday, now); } /** * Return the availability percentage for a managed service from the given * start time until the given end time. If the service is not managed, then * a value of -1 is returned. * * @param nodeId a int. * @param ipAddr a {@link java.lang.String} object. * @param serviceId a int. * @param start a {@link java.util.Date} object. * @param end a {@link java.util.Date} object. * @return a double. * @throws java.sql.SQLException if any. */ public double getServiceAvailability(int nodeId, String ipAddr, int serviceId, Date start, Date end) throws SQLException { if (ipAddr == null || start == null || end == null) { throw new IllegalArgumentException("Cannot take null parameters."); } if (end.before(start)) { throw new IllegalArgumentException("Cannot have an end time before the start time."); } if (end.equals(start)) { throw new IllegalArgumentException("Cannot have an end time equal to the start time."); } double avail = -1; final DBUtils d = new DBUtils(getClass()); try { Connection conn = Vault.getDbConnection(); d.watch(conn); PreparedStatement stmt = conn.prepareStatement("select getPercentAvailabilityInWindow(?, ?, ?, ?, ?) as avail from ifservices, ipinterface where ifservices.ipaddr = ipinterface.ipaddr and ifservices.nodeid = ipinterface.nodeid and ipinterface.ismanaged='M' and ifservices.nodeid=? and ifservices.ipaddr=? and serviceid=?"); d.watch(stmt); stmt.setInt(1, nodeId); stmt.setString(2, ipAddr); stmt.setInt(3, serviceId); // yes, these are supposed to be backwards, the end time first stmt.setTimestamp(4, new Timestamp(end.getTime())); stmt.setTimestamp(5, new Timestamp(start.getTime())); stmt.setInt(6, nodeId); stmt.setString(7, ipAddr); stmt.setInt(8, serviceId); ResultSet rs = stmt.executeQuery(); d.watch(rs); if (rs.next()) { avail = rs.getDouble("avail"); } } catch (final SQLException e) { LogUtils.warnf(this, e, "Failed to get service availability for nodeId %d, interface %s, serviceId %d", nodeId, ipAddr, serviceId); } finally { d.cleanUp(); } return avail; } }