/******************************************************************************* * 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.mock; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; import org.opennms.core.utils.ThreadCategory; import org.opennms.netmgt.model.events.EventListener; import org.opennms.netmgt.xml.event.Event; import org.opennms.test.mock.MockUtil; /** * Anticipates outages based on events * @author <a href="mailto:brozow@opennms.org">Matt Brozowski</a> */ public class OutageAnticipator implements EventListener { private final MockDatabase m_db; private int m_expectedOpenCount; private int m_expectedOutageCount; private final Map<EventWrapper, List<Outage>> m_pendingOpens = new HashMap<EventWrapper, List<Outage>>(); private final Map<EventWrapper, List<Outage>> m_pendingCloses = new HashMap<EventWrapper, List<Outage>>(); private final Set<Outage> m_expectedOutages = new HashSet<Outage>(); public OutageAnticipator(MockDatabase db) { m_db = db; reset(); } /** * */ public synchronized void reset() { m_expectedOpenCount = m_db.countOpenOutages(); m_expectedOutageCount = m_db.countOutages(); m_expectedOutages.clear(); m_expectedOutages.addAll(m_db.getOutages()); } /** * @param element * @param lostService */ public synchronized void anticipateOutageOpened(MockElement element, final Event lostService) { MockVisitor outageCounter = new MockVisitorAdapter() { public void visitService(MockService svc) { if (!m_db.hasOpenOutage(svc) || anticipatesClose(svc)) { m_expectedOpenCount++; m_expectedOutageCount++; Outage outage = new Outage(svc); MockUtil.println("Anticipating outage open: "+outage); addToOutageList(m_pendingOpens, lostService, outage); } } }; element.visit(outageCounter); } /** * @param svc * @return */ protected synchronized boolean anticipatesClose(MockService svc) { return anticipates(m_pendingCloses, svc); } private synchronized boolean anticipates(Map<EventWrapper, List<Outage>> pending, MockService svc) { for (List<Outage> outageList : pending.values()) { for (Outage outage : outageList) { if (outage.isForService(svc)) { return true; } } } return false; } /** * @param outageMap * @param outageEvent * @param svc */ protected synchronized void addToOutageList(Map<EventWrapper, List<Outage>> outageMap, Event outageEvent, Outage outage) { EventWrapper w = new EventWrapper(outageEvent); List<Outage> list = outageMap.get(w); if (list == null) { list = new LinkedList<Outage>(); outageMap.put(w, list); } list.add(outage); } protected synchronized void removeFromOutageList(Map<EventWrapper, List<Outage>> outageMap, Event outageEvent, Outage outage) { EventWrapper w = new EventWrapper(outageEvent); List<Outage> list = outageMap.get(w); if (list == null) { return; } list.remove(outage); } public synchronized void deanticipateOutageClosed(MockElement element, final Event regainService) { MockVisitor outageCounter = new MockVisitorAdapter() { public void visitService(MockService svc) { if (anticipatesClose(svc)) { // Decrease the open ones.. leave the total the same m_expectedOpenCount++; for (Outage outage : m_db.getOpenOutages(svc)) { MockUtil.println("Deanticipating outage closed: "+outage); removeFromOutageList(m_pendingCloses, regainService, outage); } } } }; element.visit(outageCounter); } public synchronized void anticipateOutageClosed(MockElement element, final Event regainService) { MockVisitor outageCounter = new MockVisitorAdapter() { public void visitService(MockService svc) { if ((m_db.hasOpenOutage(svc) || anticipatesOpen(svc)) && !anticipatesClose(svc)) { // Decrease the open ones.. leave the total the same m_expectedOpenCount--; for (Outage outage : m_db.getOpenOutages(svc)) { MockUtil.println("Anticipating outage closed: "+outage); addToOutageList(m_pendingCloses, regainService, outage); } } } }; element.visit(outageCounter); } /** * @param svc * @return */ protected boolean anticipatesOpen(MockService svc) { return anticipates(m_pendingOpens, svc); } public int getExpectedOpens() { return m_expectedOpenCount; } public int getActualOpens() { return m_db.countOpenOutages(); } public int getExpectedOutages() { return m_expectedOutageCount; } public int getActualOutages() { return m_db.countOutages(); } public synchronized boolean checkAnticipated() { int openCount = m_db.countOpenOutages(); int outageCount = m_db.countOutages(); if (openCount != m_expectedOpenCount || outageCount != m_expectedOutageCount) { return false; } if (m_pendingOpens.size() != 0 || m_pendingCloses.size() != 0) { return false; } Set<Outage> currentOutages = new HashSet<Outage>(m_db.getOutages()); if (!m_expectedOutages.equals(currentOutages)) { for (Outage expectedOutage : m_expectedOutages) { if (currentOutages.contains(expectedOutage)) { currentOutages.remove(expectedOutage); } else { log().warn("Expected outage " + expectedOutage.toDetailedString() + " not in current Set"); } } for (Outage unexpectedOutage : currentOutages) { log().warn("Unexpected outage "+unexpectedOutage.toDetailedString()+" in database"); } return false; } return true; } /* (non-Javadoc) * @see org.opennms.netmgt.eventd.EventListener#getName() */ public String getName() { return "OutageAnticipator"; } /* (non-Javadoc) * @see org.opennms.netmgt.eventd.EventListener#onEvent(org.opennms.netmgt.xml.event.Event) */ public synchronized void onEvent(Event e) { for (Outage outage : getOutageList(m_pendingOpens, e)) { outage.setLostEvent(e.getDbid(), MockEventUtil.convertEventTimeIntoTimestamp(e.getTime())); m_expectedOutages.add(outage); } clearOutageList(m_pendingOpens, e); for (Outage outage : getOutageList(m_pendingCloses, e)) { closeExpectedOutages(e, outage); } clearOutageList(m_pendingCloses, e); } private synchronized void closeExpectedOutages(Event e, Outage pendingOutage) { for (Outage outage : m_expectedOutages) { if (pendingOutage.equals(outage)) { outage.setRegainedEvent(e.getDbid(), MockEventUtil.convertEventTimeIntoTimestamp(e.getTime())); } } } /** * @param pending * @param e */ private synchronized void clearOutageList(Map<EventWrapper, List<Outage>> pending, Event e) { pending.remove(new EventWrapper(e)); } /** * @param pending * @param e * @return */ private synchronized List<Outage> getOutageList(Map<EventWrapper, List<Outage>> pending, Event e) { EventWrapper w = new EventWrapper(e); if (pending.containsKey(w)) { return pending.get(w); } return new ArrayList<Outage>(0); } /** * @param ipAddr * @param nodeId * @param nodeId2 */ public void anticipateReparent(String ipAddr, int nodeId, int nodeId2) { } private ThreadCategory log() { return ThreadCategory.getInstance(OutageAnticipator.class); } }