/******************************************************************************* * This file is part of OpenNMS(R). * * Copyright (C) 2006-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.netmgt.linkd; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Timestamp; import java.text.ParseException; import java.util.Date; import org.opennms.core.utils.DBUtils; import org.opennms.core.utils.LogUtils; import org.opennms.netmgt.EventConstants; import org.opennms.netmgt.config.DataSourceFactory; /** * * @author <a href="mailto:antonio@opennms.it">Antonio Russo</a> */ public final class DbDataLinkInterfaceEntry { /** * The character returned if the entry is active */ public static final char STATUS_ACTIVE = 'A'; /** * The character returned if the entry is not active * means last polled */ public static final char STATUS_NOT_POLLED = 'N'; /** * It stats that node is deleted * The character returned if the node is deleted */ public static final char STATUS_DELETED = 'D'; /** * The character returned if the entry type is unset/unknown. */ public static final char STATUS_UNKNOWN = 'K'; /** * The node identifier */ int m_nodeId; /** * SNMP index of interface connected to the link on the node, * is "-1" if it doesn't support SNMP */ int m_ifindex; /** * Unique integer identifier for parent linking node */ int m_nodeparentid; /** * SNMP interface index on the parent node. */ int m_parentifindex; /** * The Status of * this information */ char m_status = STATUS_UNKNOWN; /** * The Time when * this information was learned */ Timestamp m_lastPollTime; /** * the sql statement to load data from database */ private static final String SQL_LOAD_DATALINKINTERFACE = "SELECT nodeparentid,parentIfIndex,status,lastpolltime FROM datalinkinterface WHERE nodeid = ? AND ifindex = ? "; /** * True if this recored was loaded from the database. * False if it's new. */ private boolean m_fromDb; /** * The bit map used to determine which elements have * changed since the record was created. */ private int m_changed; // Mask fields // private static final int CHANGED_PARENTNODEID = 1 << 0; private static final int CHANGED_PARENTIFINDEX = 1 << 1; private static final int CHANGED_STATUS = 1 << 2; private static final int CHANGED_POLLTIME = 1 << 3; /** * Inserts the new row into the DataLinkInterface table * of the OpenNMS database. * * @param c The connection to the database. * * @throws java.sql.SQLException Thrown if an error occurs * with the connection */ private void insert(Connection c) throws SQLException { if (m_fromDb) throw new IllegalStateException("The data link interface record already exists in the database"); // first extract the next node identifier // String queryString = "INSERT INTO DataLinkInterface (nodeid,ifindex,nodeparentid,parentIfIndex,status,lastpolltime) VALUES (?,?,?,?,?,?)"; // create the Prepared statment and then // start setting the result values // PreparedStatement stmt; final DBUtils d = new DBUtils(getClass()); try { stmt = c.prepareStatement(queryString); d.watch(stmt); queryString = null; int ndx = 1; stmt.setInt(ndx++, m_nodeId); stmt.setInt(ndx++, m_ifindex); stmt.setInt(ndx++, m_nodeparentid); stmt.setInt(ndx++, m_parentifindex); stmt.setString(ndx++, new String(new char[] { m_status })); stmt.setTimestamp(ndx++, m_lastPollTime); // Run the insert // //int rc = stmt.executeUpdate(); } finally { d.cleanUp(); } // clear the mask and mark as backed // by the database // m_fromDb = true; m_changed = 0; } /** * Updates an existing record in the OpenNMS DataLinkInterface table. * * @param c The connection used for the update. * * @throws java.sql.SQLException Thrown if an error occurs * with the connection */ private void update(Connection c) throws SQLException { if (!m_fromDb) throw new IllegalStateException( "The record does not exists in the database"); // first extract the next node identifier // StringBuffer sqlText = new StringBuffer("UPDATE DataLinkInterface SET "); char comma = ' '; if ((m_changed & CHANGED_PARENTNODEID) == CHANGED_PARENTNODEID) { sqlText.append(comma).append("nodeparentid = ?"); comma = ','; } if ((m_changed & CHANGED_PARENTIFINDEX) == CHANGED_PARENTIFINDEX) { sqlText.append(comma).append("parentIfIndex = ?"); comma = ','; } if ((m_changed & CHANGED_STATUS) == CHANGED_STATUS) { sqlText.append(comma).append("status = ?"); comma = ','; } if ((m_changed & CHANGED_POLLTIME) == CHANGED_POLLTIME) { sqlText.append(comma).append("lastpolltime = ?"); comma = ','; } sqlText.append(" WHERE nodeid = ? AND ifindex = ? "); // create the Prepared statment and then // start setting the result values // PreparedStatement stmt; final DBUtils d = new DBUtils(getClass()); try { stmt = c.prepareStatement(sqlText.toString()); d.watch(stmt); int ndx = 1; if ((m_changed & CHANGED_PARENTNODEID) == CHANGED_PARENTNODEID) stmt.setInt(ndx++, m_nodeparentid); if ((m_changed & CHANGED_PARENTIFINDEX) == CHANGED_PARENTIFINDEX) stmt.setInt(ndx++, m_parentifindex); if ((m_changed & CHANGED_STATUS) == CHANGED_STATUS) stmt.setString(ndx++, new String(new char[] { m_status })); if ((m_changed & CHANGED_POLLTIME) == CHANGED_POLLTIME) { stmt.setTimestamp(ndx++, m_lastPollTime); } stmt.setInt(ndx++, m_nodeId); stmt.setInt(ndx++, m_ifindex); // Run the insert // //int rc = stmt.executeUpdate(); } finally { d.cleanUp(); } // clear the mask and mark as backed // by the database // m_changed = 0; } /** * Load the current interface from the database. If the interface * was modified, the modifications are lost. The nodeid * and ifindex must be set prior to this call. * * @param c The connection used to load the data. * * @throws java.sql.SQLException Thrown if an error occurs * with the connection */ private boolean load(Connection c) throws SQLException { if (!m_fromDb) throw new IllegalStateException( "The record does not exists in the database"); PreparedStatement stmt = null; ResultSet rset; final DBUtils d = new DBUtils(getClass()); try { stmt = c.prepareStatement(SQL_LOAD_DATALINKINTERFACE); d.watch(stmt); stmt.setInt(1, m_nodeId); stmt.setInt(2, m_ifindex); rset = stmt.executeQuery(); d.watch(rset); if (!rset.next()) { LogUtils.debugf(this, "DataLinkInterfaceEntry.load: no result found"); return false; } // extract the values. // int ndx = 1; // get the mac address // m_nodeparentid = rset.getInt(ndx++); if (rset.wasNull()) m_nodeparentid = -1; // get the source node ifindex // m_parentifindex = rset.getInt(ndx++); if (rset.wasNull()) m_ifindex = -1; // the entry status // String str = rset.getString(ndx++); if (str != null && !rset.wasNull()) m_status = str.charAt(0); else m_status = STATUS_UNKNOWN; m_lastPollTime = rset.getTimestamp(ndx++); } finally { d.cleanUp(); } // clear the mask and mark as backed // by the database // LogUtils.debugf(this, "DataInterfaceEntry.load: result found"); m_changed = 0; return true; } DbDataLinkInterfaceEntry(int nodeId, int ifindex, boolean exists) { m_nodeId = nodeId; m_ifindex = ifindex; m_fromDb = exists; m_nodeparentid = -1; m_parentifindex = -1; } DbDataLinkInterfaceEntry(int nodeId, boolean exists) { m_nodeId = nodeId; m_ifindex = -1; m_fromDb = exists; m_nodeparentid = -1; m_parentifindex = -1; } static DbDataLinkInterfaceEntry create(int nodeid, int ifindex) { return new DbDataLinkInterfaceEntry(nodeid, ifindex, false); } static DbDataLinkInterfaceEntry create(int nodeid) { return new DbDataLinkInterfaceEntry(nodeid,false); } /** * <p>get_nodeId</p> * * @return a int. */ public int get_nodeId() { return m_nodeId; } /** * <p>get_ifindex</p> * * @return a int. */ public int get_ifindex() { return m_ifindex; } /** * <p>get_nodeparentid</p> * * @return a int. */ public int get_nodeparentid() { return m_nodeparentid; } void set_nodeparentid(int nodeparentid) { m_nodeparentid = nodeparentid; m_changed |= CHANGED_PARENTNODEID; } boolean hasNodeParentIdChanged() { if ((m_changed & CHANGED_PARENTNODEID) == CHANGED_PARENTNODEID) return true; else return false; } boolean updateNodeParentId(int nodeparentid) { if (nodeparentid != m_nodeparentid) { set_nodeparentid(nodeparentid); return true; } else return false; } /** * <p>get_parentifindex</p> * * @return a int. */ public int get_parentifindex() { return m_parentifindex; } void set_parentifindex(int parentifindex) { m_parentifindex = parentifindex; m_changed |= CHANGED_PARENTIFINDEX; } boolean hasParentIfIndexChanged() { if ((m_changed & CHANGED_PARENTIFINDEX) == CHANGED_PARENTIFINDEX) return true; else return false; } boolean updateParentIfIndex(int parentifindex) { if (parentifindex != m_parentifindex) { set_parentifindex(parentifindex); return true; } else return false; } /** * <p>get_status</p> * * @return a char. */ public char get_status() { return m_status; } void set_status(char status) { if (status == STATUS_ACTIVE || status == STATUS_NOT_POLLED || status == STATUS_DELETED) m_status = status; m_changed |= CHANGED_STATUS; } boolean hasStatusChanged() { if ((m_changed & CHANGED_STATUS) == CHANGED_STATUS) return true; else return false; } boolean updateStatus(char status) { if (status != m_status) { set_status(status); return true; } else return false; } /** * @return */ Timestamp get_lastpolltime() { return m_lastPollTime; } /** * Gets the last poll time of the record */ String getLastPollTimeString() { String result = null; if (m_lastPollTime != null) { result = m_lastPollTime.toString(); } return result; } /** * Sets the last poll time. * * @param time The last poll time. * */ void set_lastpolltime(String time) throws ParseException { if (time == null) { m_lastPollTime = null; } else { Date tmpDate = EventConstants.parseToDate(time); m_lastPollTime = new Timestamp(tmpDate.getTime()); } m_changed |= CHANGED_POLLTIME; } /** * Sets the last poll time. * * @param time The last poll time. * */ void set_lastpolltime(Date time) { m_lastPollTime = new Timestamp(time.getTime()); m_changed |= CHANGED_POLLTIME; } /** * Sets the last poll time. * * @param time The last poll time. * */ void set_lastpolltime(Timestamp time) { m_lastPollTime = time; m_changed |= CHANGED_POLLTIME; } /** * Updates the interface information in the configured database. If the * interface does not exist the a new row in the table is created. If the * element already exists then it's current row is updated as * needed based upon the current changes to the node. */ void store() throws SQLException { if (m_changed != 0 || m_fromDb == false) { Connection db = null; try { db = DataSourceFactory.getInstance().getConnection(); store(db); if (db.getAutoCommit() == false) db.commit(); } finally { try { if (db != null) db.close(); } catch (SQLException e) { LogUtils.warnf(this, e, "Exception closing JDBC connection"); } } } return; } /** * Updates the interface information in the configured database. If the * atinterface does not exist the a new row in the table is created. If the * element already exists then it's current row is updated as * needed based upon the current changes to the node. * * @param db The database connection used to write the record. */ void store(Connection db) throws SQLException { if (m_changed != 0 || m_fromDb == false) { if (m_fromDb) update(db); else insert(db); } } /** * Retreives a current record from the database based upon the * key fields of <em>nodeID</em> and <em>ifindex</em>. If the * record cannot be found then a null reference is returnd. * * @param nid The node id key * @param ifindex The interface snmp index * * @return The loaded entry or null if one could not be found. * */ static DbDataLinkInterfaceEntry get(int nid, int ifindex) throws SQLException { Connection db = null; try { db = DataSourceFactory.getInstance().getConnection(); return get(db, nid, ifindex); } finally { try { if (db != null) db.close(); } catch (SQLException e) { LogUtils.warnf(DbDataLinkInterfaceEntry.class, e, "Exception closing JDBC connection"); } } } /** * Retreives a current record from the database based upon the * key fields of <em>nodeID</em> and <em>ifindex</em>. If the * record cannot be found then a null reference is returnd. * * @param db The databse connection used to load the entry. * @param nid The node id key * @param ifindex The interface snmp index * * @return The loaded entry or null if one could not be found. * */ static DbDataLinkInterfaceEntry get(Connection db, int nid, int ifindex) throws SQLException { DbDataLinkInterfaceEntry entry = new DbDataLinkInterfaceEntry(nid, ifindex,true); if (!entry.load(db)) entry = null; return entry; } /** * Retreives a current record from the database based upon the * key field of <em>nodeID</em>. If the * record cannot be found then a null reference is returnd. * * @param nid The node id key * * @return The loaded entry or null if one could not be found. * */ static DbDataLinkInterfaceEntry get(int nid) throws SQLException { Connection db = null; try { db = DataSourceFactory.getInstance().getConnection(); return get(db, nid); } finally { try { if (db != null) db.close(); } catch (SQLException e) { LogUtils.warnf(DbDataLinkInterfaceEntry.class, e, "Exception closing JDBC connection"); } } } /** * Retreives a current record from the database based upon the * key fields of <em>nodeID</em>. If the * record cannot be found then a null reference is returnd. * * @param db The databse connection used to load the entry. * @param nid The node id key * * @return The loaded entry or null if one could not be found. * */ static DbDataLinkInterfaceEntry get(Connection db, int nid) throws SQLException { DbDataLinkInterfaceEntry entry = new DbDataLinkInterfaceEntry(nid,true); if (!entry.load(db)) entry = null; return entry; } /** * <p>toString</p> * * @return a {@link java.lang.String} object. */ public String toString() { String sep = System.getProperty("line.separator"); StringBuffer buf = new StringBuffer(); buf.append("from db = ").append(m_fromDb).append(sep); buf.append("node id = ").append(m_nodeId).append(sep); buf.append("ifindex = ").append(m_ifindex).append(sep); buf.append("node parent id = ").append(m_nodeparentid).append(sep); buf.append("parent interface ifindex = ").append(m_parentifindex).append(sep); buf.append("status = ").append(m_status).append(sep); buf.append("last poll time = ").append(m_lastPollTime).append(sep); return buf.toString(); } }