/******************************************************************************* * This file is part of OpenNMS(R). * * Copyright (C) 2009-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.alarmd; import org.opennms.core.utils.ThreadCategory; import org.opennms.netmgt.dao.AlarmDao; import org.opennms.netmgt.dao.EventDao; import org.opennms.netmgt.model.OnmsAlarm; import org.opennms.netmgt.model.OnmsEvent; import org.opennms.netmgt.model.OnmsSeverity; import org.opennms.netmgt.xml.event.Event; import org.opennms.netmgt.xml.event.UpdateField; import org.springframework.util.Assert; /** * Singleton to persist OnmsAlarms. * * @author <a href="mailto:david@opennms.org">David Hustace</a> * @version $Id: $ */ public class AlarmPersisterImpl implements AlarmPersister { private AlarmDao m_alarmDao; private EventDao m_eventDao; /** {@inheritDoc} * @return */ public OnmsAlarm persist(Event event) { if (!checkEventSanityAndDoWeProcess(event)) { return null; } log().debug("process: " + event.getUei() + " nodeid: " + event.getNodeid() + " ipaddr: " + event.getInterface() + " serviceid: " + event.getService()); return addOrReduceEventAsAlarm(event); } private OnmsAlarm addOrReduceEventAsAlarm(Event event) { //TODO: Understand why we use Assert Assert.notNull(event, "Incoming event was null, aborting"); Assert.isTrue(event.getDbid() > 0, "Incoming event has an illegal dbid (" + event.getDbid() + "), aborting"); //for some reason when we get here the event from the DB doesn't have the LogMsg (in my tests anyway) OnmsEvent e = m_eventDao.get(event.getDbid()); Assert.notNull(e, "Event was deleted before we could retrieve it and create an alarm."); String reductionKey = event.getAlarmData().getReductionKey(); log().debug("addOrReduceEventAsAlarm: looking for existing reduction key: "+reductionKey); OnmsAlarm alarm = m_alarmDao.findByReductionKey(reductionKey); if (alarm == null) { log().debug("addOrReduceEventAsAlarm: reductionKey:"+reductionKey+" not found, instantiating new alarm"); alarm = createNewAlarm(e, event); //FIXME: this should be a cascaded save m_alarmDao.save(alarm); m_eventDao.saveOrUpdate(e); } else { log().debug("addOrReduceEventAsAlarm: reductionKey:"+reductionKey+" found, reducing event to existing alarm: "+alarm.getIpAddr()); reduceEvent(e, alarm, event); m_alarmDao.update(alarm); m_eventDao.update(e); if (event.getAlarmData().isAutoClean()) { m_eventDao.deletePreviousEventsForAlarm(alarm.getId(), e); } } return alarm; } private static void reduceEvent(OnmsEvent e, OnmsAlarm alarm, Event event) { //Always set these alarm.setLastEvent(e); alarm.setLastEventTime(e.getEventTime()); alarm.setCounter(alarm.getCounter() + 1); if (!event.getAlarmData().hasUpdateFields()) { //We always set these even if there are not update fields specified alarm.setLogMsg(e.getEventLogMsg()); alarm.setEventParms(e.getEventParms()); } else { for (UpdateField field : event.getAlarmData().getUpdateFieldList()) { //Always set these, unless specified not to, in order to maintain current behavior if (field.getFieldName().equalsIgnoreCase("LogMsg") && field.isUpdateOnReduction() == false) { continue; } else { alarm.setLogMsg(e.getEventLogMsg()); } if (field.getFieldName().equalsIgnoreCase("Parms") && field.isUpdateOnReduction() == false) { continue; } else { alarm.setEventParms(e.getEventParms()); } //Set these others if (field.isUpdateOnReduction()) { if (field.getFieldName().toLowerCase().startsWith("distpoller")) { alarm.setDistPoller(e.getDistPoller()); } else if (field.getFieldName().toLowerCase().startsWith("ipaddr")) { alarm.setIpAddr(e.getIpAddr()); } else if (field.getFieldName().toLowerCase().startsWith("mouseover")) { alarm.setMouseOverText(e.getEventMouseOverText()); } else if (field.getFieldName().toLowerCase().startsWith("operinstruct")) { alarm.setOperInstruct(e.getEventOperInstruct()); } else if (field.getFieldName().equalsIgnoreCase("severity")) { alarm.setSeverity(OnmsSeverity.valueOf(e.getSeverityLabel())); } else if (field.getFieldName().toLowerCase().contains("descr")) { alarm.setDescription(e.getEventDescr()); alarm.setSeverity(OnmsSeverity.valueOf(e.getSeverityLabel())); } else { log().warn("reduceEvent: The specified field: "+field.getFieldName()+", is not supported."); } /* This doesn't work because the properties are not consistent from OnmsEvent to OnmsAlarm try { final BeanWrapper ew = PropertyAccessorFactory.forBeanPropertyAccess(e); final BeanWrapper aw = PropertyAccessorFactory.forBeanPropertyAccess(alarm); aw.setPropertyValue(field.getFieldName(), ew.getPropertyValue(field.getFieldName())); } catch (BeansException be) { System.out.println(be); log().error("reduceEvent:", be); continue; } */ } } } e.setAlarm(alarm); } private static OnmsAlarm createNewAlarm(OnmsEvent e, Event event) { OnmsAlarm alarm; alarm = new OnmsAlarm(); alarm.setAlarmType(event.getAlarmData().getAlarmType()); alarm.setClearKey(event.getAlarmData().getClearKey()); alarm.setCounter(1); alarm.setDescription(e.getEventDescr()); alarm.setDistPoller(e.getDistPoller()); alarm.setEventParms(e.getEventParms()); alarm.setFirstEventTime(e.getEventTime()); alarm.setIfIndex(e.getIfIndex()); alarm.setIpAddr(e.getIpAddr()); alarm.setLastEventTime(e.getEventTime()); alarm.setLastEvent(e); alarm.setLogMsg(e.getEventLogMsg()); alarm.setMouseOverText(e.getEventMouseOverText()); alarm.setNode(e.getNode()); alarm.setOperInstruct(e.getEventOperInstruct()); alarm.setReductionKey(event.getAlarmData().getReductionKey()); alarm.setServiceType(e.getServiceType()); alarm.setSeverity(OnmsSeverity.get(e.getEventSeverity())); //TODO: what to do? alarm.setSuppressedUntil(e.getEventTime()); //TODO: fix UI to not require this be set alarm.setSuppressedTime(e.getEventTime()); //TODO: Fix UI to not require this be set //alarm.setTTicketId(e.getEventTTicket()); //alarm.setTTicketState(TroubleTicketState.CANCEL_FAILED); //FIXME alarm.setUei(e.getEventUei()); e.setAlarm(alarm); return alarm; } private static boolean checkEventSanityAndDoWeProcess(final Event event) { Assert.notNull(event, "event argument must not be null"); //Events that are marked donotpersist have a dbid of 0 //Assert.isTrue(event.getDbid() > 0, "event does not have a dbid");//TODO: figure out what happens when this exception is thrown if (event.getLogmsg() != null && event.getLogmsg().getDest() != null && "donotpersist".equals(event.getLogmsg().getDest())) { log().debug("checkEventSanity" + ": uei '" + event.getUei() + "' marked as 'donotpersist'; not processing event."); return false; } if (event.getAlarmData() == null) { log().debug("checkEventSanity" + ": uei '" + event.getUei() + "' has no alarm data; not processing event."); return false; } return true; } private static ThreadCategory log() { return ThreadCategory.getInstance(AlarmPersisterImpl.class); } /** * <p>setAlarmDao</p> * * @param alarmDao a {@link org.opennms.netmgt.dao.AlarmDao} object. */ public void setAlarmDao(AlarmDao alarmDao) { m_alarmDao = alarmDao; } /** * <p>getAlarmDao</p> * * @return a {@link org.opennms.netmgt.dao.AlarmDao} object. */ public AlarmDao getAlarmDao() { return m_alarmDao; } /** * <p>setEventDao</p> * * @param eventDao a {@link org.opennms.netmgt.dao.EventDao} object. */ public void setEventDao(EventDao eventDao) { m_eventDao = eventDao; } /** * <p>getEventDao</p> * * @return a {@link org.opennms.netmgt.dao.EventDao} object. */ public EventDao getEventDao() { return m_eventDao; } }