package org.infosec.ismp.eventd.processor; import java.sql.PreparedStatement; import java.sql.SQLException; import java.sql.Timestamp; import java.sql.Types; import java.text.ParseException; import javax.sql.DataSource; import org.infosec.ismp.eventd.EventdServiceManager; import org.infosec.ismp.model.event.Event; import org.infosec.ismp.model.event.EventConstants; import org.infosec.ismp.util.ThreadCategory; import org.springframework.beans.factory.InitializingBean; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.util.Assert; /** * EventWriter loads the information in each 'Event' into the database. * * While loading mutiple values of the same element into a single DB column, the * mutiple values are delimited by MULTIPLE_VAL_DELIM. * * When an element and its attribute are loaded into a single DB column, the * value and the attribute are separated by a DB_ATTRIB_DELIM. * * When using delimiters to append values, if the values already have the * delimiter, the delimiter in the value is escaped as in URLs. * * Values for the ' <parms>' block are loaded with each parm name and parm value * delimited with the NAME_VAL_DELIM. * * @see org.opennms.netmgt.model.events.Constants#MULTIPLE_VAL_DELIM * @see org.opennms.netmgt.model.events.Constants#DB_ATTRIB_DELIM * @see org.opennms.netmgt.model.events.Constants#NAME_VAL_DELIM * * @author <A HREF="mailto:david@opennms.org">David Hustace </A> * @author Sowmya Nataraj </A> * @author <A HREF="http://www.opennms.org">OpenNMS.org </A> * * Changes: * * - Alarm persisting added (many moons ago) * - Alarm persisting now removes oldest events by default. Use "auto-clean" attribute * in eventconf files. */ public abstract class AbstractJdbcPersister implements InitializingBean, EventProcessor { // Field sizes in the events table protected static final int EVENT_UEI_FIELD_SIZE = 256; protected static final int EVENT_HOST_FIELD_SIZE = 256; protected static final int EVENT_INTERFACE_FIELD_SIZE = 16; protected static final int EVENT_DPNAME_FIELD_SIZE = 12; protected static final int EVENT_SNMPHOST_FIELD_SIZE = 256; protected static final int EVENT_SNMP_FIELD_SIZE = 256; protected static final int EVENT_DESCR_FIELD_SIZE = 4000; protected static final int EVENT_LOGGRP_FIELD_SIZE = 32; protected static final int EVENT_LOGMSG_FIELD_SIZE = 256; protected static final int EVENT_PATHOUTAGE_FIELD_SIZE = 1024; protected static final int EVENT_CORRELATION_FIELD_SIZE = 1024; protected static final int EVENT_OPERINSTRUCT_FIELD_SIZE = 1024; protected static final int EVENT_AUTOACTION_FIELD_SIZE = 256; protected static final int EVENT_OPERACTION_FIELD_SIZE = 256; protected static final int EVENT_OPERACTION_MENU_FIELD_SIZE = 64; // protected static final int EVENT_NOTIFICATION_FIELD_SIZE = 128; protected static final int EVENT_TTICKET_FIELD_SIZE = 128; protected static final int EVENT_FORWARD_FIELD_SIZE = 256; protected static final int EVENT_MOUSEOVERTEXT_FIELD_SIZE = 64; protected static final int EVENT_ACKUSER_FIELD_SIZE = 256; protected static final int EVENT_SOURCE_FIELD_SIZE = 128; protected static final int EVENT_X733_ALARMTYPE_SIZE = 31; /** * The character to put in if the log or display is to be set to yes */ protected static final char MSG_YES = 'Y'; /** * The character to put in if the log or display is to be set to no */ protected static final char MSG_NO = 'N'; private EventdServiceManager m_eventdServiceManager; private DataSource m_dataSource; private String m_getNextIdString; public AbstractJdbcPersister() { } /** * Sets the statement up for a String value. * * @param stmt * The statement to add the value to. * @param ndx * The ndx for the value. * @param value * The value to add to the statement. * * @exception java.sql.SQLException * Thrown if there is an error adding the value to the * statement. */ protected void set(PreparedStatement stmt, int ndx, String value) throws SQLException { if (value == null || value.length() == 0) { stmt.setNull(ndx, Types.VARCHAR); } else { stmt.setString(ndx, value); } } /** * Sets the statement up for an integer type. If the integer type is less * than zero, then it is set to null! * * @param stmt * The statement to add the value to. * @param ndx * The ndx for the value. * @param value * The value to add to the statement. * * @exception java.sql.SQLException * Thrown if there is an error adding the value to the * statement. */ protected void set(PreparedStatement stmt, int ndx, int value) throws SQLException { if (value < 0) { stmt.setNull(ndx, Types.INTEGER); } else { stmt.setInt(ndx, value); } } /** * Sets the statement up for a timestamp type. * * @param stmt * The statement to add the value to. * @param ndx * The ndx for the value. * @param value * The value to add to the statement. * * @exception java.sql.SQLException * Thrown if there is an error adding the value to the * statement. */ protected void set(PreparedStatement stmt, int ndx, Timestamp value) throws SQLException { if (value == null) { stmt.setNull(ndx, Types.TIMESTAMP); } else { stmt.setTimestamp(ndx, value); } } /** * Sets the statement up for a character value. * * @param stmt * The statement to add the value to. * @param ndx * The ndx for the value. * @param value * The value to add to the statement. * * @exception java.sql.SQLException * Thrown if there is an error adding the value to the * statement. */ protected void set(PreparedStatement stmt, int ndx, char value) throws SQLException { stmt.setString(ndx, String.valueOf(value)); } /** * This method is used to convert the service name into a service id. It * first looks up the information from a service map of Eventd and if no * match is found, by performing a lookup in the database. If the conversion * is successful then the corresponding integer identifier will be returned * to the caller. * * @param name * The name of the service * * @return The integer identifier for the service name. * * @exception java.sql.SQLException * Thrown if there is an error accessing the stored data or * the SQL text is malformed. This will also be thrown if the * result cannot be obtained. * * @see EventdConstants#SQL_DB_SVCNAME_TO_SVCID * */ protected int getServiceID(String name) throws SQLException { return m_eventdServiceManager.getServiceId(name); } /** * @param event * @param log * @return */ protected Timestamp getEventTime(Event event) { try { return new Timestamp(EventConstants.parseToDate(event.getTime()) .getTime()); } catch (ParseException e) { log().warn( "Failed to convert time " + event.getTime() + " to timestamp,setting current time instead. exception : " + e, e); return new Timestamp(System.currentTimeMillis()); } } protected int getNextId() throws SQLException { return new JdbcTemplate(getDataSource()) .queryForInt(getGetNextIdString()); } protected ThreadCategory log() { return ThreadCategory.getInstance(getClass()); } @Override public void afterPropertiesSet() throws SQLException { Assert.state(m_eventdServiceManager != null, "property eventdServiceManager must be set"); Assert.state(m_dataSource != null, "property dataSource must be set"); Assert.state(m_getNextIdString != null, "property getNextIdString must be set"); } public EventdServiceManager getEventdServiceManager() { return m_eventdServiceManager; } public void setEventdServiceManager( EventdServiceManager eventdServiceManager) { m_eventdServiceManager = eventdServiceManager; } public DataSource getDataSource() { return m_dataSource; } public void setDataSource(DataSource dataSource) { m_dataSource = dataSource; } public String getGetNextIdString() { return m_getNextIdString; } public void setGetNextIdString(String getNextIdString) { m_getNextIdString = getNextIdString; } protected boolean checkEventSanityAndDoWeProcess(Event event, String logPrefix) { Assert.notNull(event, "event argument must not be null"); return true; } }