/******************************************************************************* * 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.reporting.availability.svclayer; import static org.opennms.core.utils.InetAddressUtils.str; import java.beans.PropertyVetoException; import java.io.IOException; import java.lang.reflect.UndeclaredThrowableException; import java.net.InetAddress; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Timestamp; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.ListIterator; import org.exolab.castor.xml.MarshalException; import org.exolab.castor.xml.ValidationException; import org.opennms.core.utils.ThreadCategory; import org.opennms.netmgt.config.CatFactory; import org.opennms.netmgt.config.CategoryFactory; import org.opennms.netmgt.config.DataSourceFactory; import org.opennms.netmgt.filter.FilterDaoFactory; import org.opennms.reporting.availability.AvailabilityConstants; import org.opennms.reporting.datablock.Node; import org.opennms.reporting.datablock.Outage; import org.opennms.reporting.datablock.OutageSvcTimesList; /** * <p>LegacyAvailabilityDataService class.</p> */ public class LegacyAvailabilityDataService implements AvailabilityDataService { CatFactory m_catFactory; /** * Common Rule for the category group. */ private String m_commonRule; private Connection m_availConn; private final ThreadCategory log; private List<Node> m_nodes; private static final String LOG4J_CATEGORY = "OpenNMS.Report"; /** * <p>Constructor for LegacyAvailabilityDataService.</p> */ public LegacyAvailabilityDataService() { String oldPrefix = ThreadCategory.getPrefix(); ThreadCategory.setPrefix(LOG4J_CATEGORY); log = ThreadCategory.getInstance(LegacyAvailabilityDataService.class); log.debug("initialised DefaultAvailablityReportService"); ThreadCategory.setPrefix(oldPrefix); } /** {@inheritDoc} */ public List<Node> getNodes(org.opennms.netmgt.config.categories.Category category, long startTime, long endTime) throws AvailabilityDataServiceException { m_nodes = new ArrayList<Node>(); PreparedStatement ipInfoGetStmt = null; PreparedStatement servicesGetStmt = null; PreparedStatement outagesGetStmt = null; String categoryName = category.getLabel(); try { CategoryFactory.init(); m_catFactory = CategoryFactory.getInstance(); } catch (IOException e) { log.fatal("Initializing CategoryFactory", e); throw new AvailabilityDataServiceException("faild to init catFactory"); } catch (MarshalException e) { log.fatal("Initializing CategoryFactory", e); throw new AvailabilityDataServiceException("faild to init catFactory"); } catch (ValidationException e) { log.fatal("Initializing CategoryFactory", e); throw new AvailabilityDataServiceException("faild to init catFactory"); } m_catFactory.getReadLock().lock(); try { m_commonRule = m_catFactory.getEffectiveRule(categoryName); List<InetAddress> nodeIPs = FilterDaoFactory.getInstance().getActiveIPAddressList(m_commonRule); if (log.isDebugEnabled()) { log.debug("Number of IPs satisfying rule: " + nodeIPs.size()); } List<String> monitoredServices = new ArrayList<String>(category.getServiceCollection()); log.debug("categories in monitoredServices = " + monitoredServices.toString()); initialiseConnection(); // Prepare the statement to get service entries for each IP try { // Prepared statement to get node info for an IP ipInfoGetStmt = m_availConn.prepareStatement(AvailabilityConstants.DB_GET_INFO_FOR_IP); // Prepared statedment to get services info for an IP address servicesGetStmt = m_availConn.prepareStatement(AvailabilityConstants.DB_GET_SVC_ENTRIES); // Prepared statement to get outages entries outagesGetStmt = m_availConn.prepareStatement(AvailabilityConstants.DB_GET_OUTAGE_ENTRIES); } catch (SQLException e) { log.fatal("failed to setup prepared statement", e); throw new AvailabilityDataServiceException("failed to setup prepared statement"); } /* * For each of these IP addresses, get the details from the * ifServices and services tables. */ Iterator<InetAddress> ipIter = nodeIPs.iterator(); String ip = null; ResultSet ipRS = null; try { // Prepared statement to get node info for an IP ipInfoGetStmt = m_availConn.prepareStatement(AvailabilityConstants.DB_GET_INFO_FOR_IP); while (ipIter.hasNext()) { ip = str(ipIter.next()); log.debug("ecexuting " + AvailabilityConstants.DB_GET_INFO_FOR_IP + " for " + ip); // get node info for this ip ipInfoGetStmt.setString(1, ip); ipRS = ipInfoGetStmt.executeQuery(); // now handle all the results from this while (ipRS.next()) { int nodeid = ipRS.getInt(1); String nodeName = ipRS.getString(2); // get the services for this IP address ResultSet svcRS = null; servicesGetStmt.setLong(1, nodeid); servicesGetStmt.setString(2, ip); servicesGetStmt.setString(3, ip); servicesGetStmt.setLong(4, nodeid); svcRS = servicesGetStmt.executeQuery(); // create node objects for this nodeID/IP/service while (svcRS.next()) { // read data from the resultSet int svcid = svcRS.getInt(1); String svcname = svcRS.getString(2); /* * If the list is empty, we assume all services are * monitored. If it has any, we use it as a filter */ if (monitoredServices.isEmpty() || monitoredServices.contains(svcname)) { OutageSvcTimesList outageSvcTimesList = new OutageSvcTimesList(); getOutagesNodeIpSvc(nodeid, nodeName, ip, svcid, svcname, outageSvcTimesList, outagesGetStmt, startTime, endTime); } } } } } catch (SQLException e) { log.fatal("failed to execute prepared statement", e); throw new AvailabilityDataServiceException("failed to execute prepared statement"); } finally { try { if (ipRS != null) { ipRS.close(); } if (servicesGetStmt != null) { servicesGetStmt.close(); } if (ipInfoGetStmt != null) { ipInfoGetStmt.close(); } if (outagesGetStmt != null) { outagesGetStmt.close(); } if (m_availConn != null) { closeConnection(); } } catch (SQLException e) { log.fatal("failed to close ipInfo prepared statement", e); throw new AvailabilityDataServiceException("failed to close ipInfo prepared statement"); } } } finally { m_catFactory.getReadLock().unlock(); } return m_nodes; } /** * Get all outages for this nodeid/ipaddr/service combination and add it * to m_nodes. */ private void getOutagesNodeIpSvc(int nodeid, String nodeName, String ipaddr, int serviceid, String serviceName, OutageSvcTimesList outageSvcTimesList, PreparedStatement outagesGetStmt, long startTime,long endTime) throws SQLException { // Get outages for this node/ip/svc pair try { outagesGetStmt.setInt(1, nodeid); outagesGetStmt.setString(2, ipaddr); outagesGetStmt.setInt(3, serviceid); ResultSet rs = outagesGetStmt.executeQuery(); if (m_nodes != null && m_nodes.size() > 0) { ListIterator<Node> lstIter = m_nodes.listIterator(); boolean foundFlag = false; Node oldNode = null; while (lstIter.hasNext()) { oldNode = (Node) lstIter.next(); if (oldNode != null && oldNode.getNodeID() == nodeid) { foundFlag = true; break; } } if (!foundFlag) { Node newNode = new Node(nodeName, nodeid); newNode.addInterface(ipaddr, serviceName); m_nodes.add(newNode); } else { oldNode.addInterface(ipaddr, serviceName); } } else { Node newNode = new Node(nodeName, nodeid); newNode.addInterface(ipaddr, serviceName); if (m_nodes == null) { log.debug("NODES IS NULL"); } m_nodes.add(newNode); } while (rs.next()) { Timestamp lost = rs.getTimestamp(1); Timestamp regained = rs.getTimestamp(2); long losttime = lost.getTime(); long regainedtime = 0; if (regained != null) { regainedtime = regained.getTime(); } if (regainedtime > 0) { if (regainedtime <= startTime || losttime >= endTime) { continue; } } else { if (losttime >= endTime) { continue; } } Outage outage = new Outage(losttime, regainedtime); outageSvcTimesList.add(outage); addNode(nodeName, nodeid, ipaddr, serviceName, losttime, regainedtime); } if (rs != null) { rs.close(); } } catch (SQLException e) { log.fatal("SQL Error occured while getting the outages ", e); throw e; } } /** * This method adds a unique tuple to the list of nodes m_nodes. * * @param nodeName a {@link java.lang.String} object. * @param nodeid a int. * @param ipaddr a {@link java.lang.String} object. * @param serviceid a {@link java.lang.String} object. * @param losttime a long. * @param regainedtime a long. */ public void addNode(String nodeName, int nodeid, String ipaddr, String serviceid, long losttime, long regainedtime) { if (m_nodes == null) { log.debug("adding new arraylis"); m_nodes = new ArrayList<Node>(); } else { if (m_nodes.size() <= 0) { Node newNode = new Node(nodeName, nodeid); // if(log.isDebugEnabled()) // log.debug("Created the new node."); if (losttime > 0) { if (regainedtime > 0) { newNode.addInterface(ipaddr, serviceid, losttime, regainedtime); } else { newNode.addInterface(ipaddr, serviceid, losttime); } } else { newNode.addInterface(ipaddr, serviceid); } m_nodes.add(newNode); return; } else // look for the node with the nodeName { Node newNode = null; boolean foundFlag = false; ListIterator<Node> lstIter = m_nodes.listIterator(); while (lstIter.hasNext()) { newNode = lstIter.next(); if (newNode.getNodeID() == nodeid) { foundFlag = true; break; } } if (!foundFlag) { newNode = new Node(nodeName, nodeid); if (losttime > 0) { if (regainedtime > 0) { newNode.addInterface(ipaddr, serviceid, losttime, regainedtime); } else { newNode.addInterface(ipaddr, serviceid, losttime); } } else { newNode.addInterface(ipaddr, serviceid); } m_nodes.add(newNode); return; } else { if (losttime > 0) { if (regainedtime > 0) { newNode.addInterface(ipaddr, serviceid, losttime, regainedtime); } else { newNode.addInterface(ipaddr, serviceid, losttime); } } else { newNode.addInterface(ipaddr, serviceid); } return; } } } } /** * Initializes the database connection. */ private void initialiseConnection() throws AvailabilityDataServiceException { // // Initialize the DataCollectionConfigFactory // try { DataSourceFactory.init(); m_availConn = DataSourceFactory.getInstance().getConnection(); } catch (MarshalException e) { log.fatal( "initialize: Failed to load data collection configuration", e); throw new AvailabilityDataServiceException("failed to load data collection configuration"); } catch (ValidationException e) { log.fatal( "initialize: Failed to load data collection configuration", e); throw new AvailabilityDataServiceException("failed to load data collection configuration"); } catch (IOException e) { log.fatal( "initialize: Failed to load data collection configuration", e); throw new UndeclaredThrowableException(e); } catch (ClassNotFoundException e) { log.fatal("initialize: Failed loading database driver.", e); throw new AvailabilityDataServiceException("failed to load data collection configuration"); } catch (SQLException e) { log.fatal( "initialize: Failed getting connection to the database.", e); throw new AvailabilityDataServiceException("failed to load data collection configuration"); } catch (PropertyVetoException e) { log.fatal( "initialize: Failed getting connection to the database.", e); throw new AvailabilityDataServiceException("initialize: Failed getting connection to the database"); } } /** * Closes the database connection. */ private void closeConnection() { ThreadCategory log = ThreadCategory.getInstance(this.getClass()); if (m_availConn != null) { try { m_availConn.close(); m_availConn = null; } catch (Throwable t) { log.warn( "initialize: an exception occured while closing the " + "JDBC connection", t); } } } }