<commit_before>/*******************************************************************************
 * This file is part of OpenNMS(R).
 *
 * Copyright (C) 2011-2012 The OpenNMS Group, Inc.
 * OpenNMS(R) is Copyright (C) 1999-2012 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 <<EMAIL>>
 *     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:<EMAIL>"><NAME></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) {
        e.getServiceType().getName(); // To avoid potential LazyInitializationException when dealing with NorthboundAlarm
        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;
    }
    <commit_msg>Add an extra NPE on AlarmPersisterImpl to make AlarmdTest and AlarmsPafeTest happy.<commit_after>/*******************************************************************************
 * This file is part of OpenNMS(R).
 *
 * Copyright (C) 2011-2012 The OpenNMS Group, Inc.
 * OpenNMS(R) is Copyright (C) 1999-2012 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 <<EMAIL>>
 *     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:<EMAIL>"><NAME></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) {
        if (e.getServiceType() != null) {
            e.getServiceType().getName(); // To avoid potential LazyInitializationException when dealing with NorthboundAlarm
        }
        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;
    }
    
{'fraction_non_alphanumeric': 0.12735849056603774, 'fraction_numerical': 0.0022461814914645105, 'mean_word_length': 2.2641129032258065, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 6, 'xml': 4}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6747729', 'n_tokens_mistral': 5056, 'n_tokens_neox': 4998, 'n_words': 1054}