/******************************************************************************* * This file is part of OpenNMS(R). * * Copyright (C) 2010-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.features.poller.remote.gwt.server; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import java.util.Date; import java.util.Properties; import java.util.Set; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.opennms.core.test.MockLogAppender; import org.opennms.core.test.OpenNMSJUnit4ClassRunner; import org.opennms.core.utils.BeanUtils; import org.opennms.features.poller.remote.gwt.client.ApplicationDetails; import org.opennms.features.poller.remote.gwt.client.ApplicationInfo; import org.opennms.features.poller.remote.gwt.client.LocationMonitorState; import org.opennms.features.poller.remote.gwt.client.Status; import org.opennms.features.poller.remote.gwt.client.StatusDetails; import org.opennms.features.poller.remote.gwt.client.location.LocationDetails; import org.opennms.features.poller.remote.gwt.client.location.LocationInfo; import org.opennms.features.poller.remote.gwt.client.utils.Interval; import org.opennms.features.poller.remote.gwt.client.utils.IntervalUtils; import org.opennms.netmgt.dao.ApplicationDao; import org.opennms.netmgt.dao.DistPollerDao; import org.opennms.netmgt.dao.IpInterfaceDao; import org.opennms.netmgt.dao.MonitoredServiceDao; import org.opennms.netmgt.dao.NodeDao; import org.opennms.netmgt.dao.ServiceTypeDao; import org.opennms.netmgt.dao.db.JUnitConfigurationEnvironment; import org.opennms.netmgt.dao.db.JUnitTemporaryDatabase; import org.opennms.netmgt.dao.db.TemporaryDatabase; import org.opennms.netmgt.dao.db.TemporaryDatabaseAware; import org.opennms.netmgt.dao.hibernate.LocationMonitorDaoHibernate; import org.opennms.netmgt.filter.FilterDaoFactory; import org.opennms.netmgt.model.OnmsApplication; import org.opennms.netmgt.model.OnmsDistPoller; import org.opennms.netmgt.model.OnmsIpInterface; import org.opennms.netmgt.model.OnmsLocationMonitor; import org.opennms.netmgt.model.OnmsMonitoredService; import org.opennms.netmgt.model.OnmsNode; import org.opennms.netmgt.model.OnmsServiceType; import org.opennms.netmgt.model.PollStatus; import org.opennms.netmgt.model.OnmsLocationMonitor.MonitorStatus; import org.opennms.netmgt.poller.remote.PollerBackEnd; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.transaction.annotation.Transactional; @RunWith(OpenNMSJUnit4ClassRunner.class) @ContextConfiguration(locations = { "classpath:META-INF/opennms/mockEventIpcManager.xml", "classpath:/META-INF/opennms/applicationContext-dao.xml", "classpath*:/META-INF/opennms/component-dao.xml", "classpath:/META-INF/opennms/applicationContext-daemon.xml", "file:src/main/webapp/WEB-INF/applicationContext-remote-poller.xml", "classpath:/locationDataServiceTest.xml" }) @JUnitConfigurationEnvironment @JUnitTemporaryDatabase @Transactional public class LocationDataServiceTest implements TemporaryDatabaseAware<TemporaryDatabase>, InitializingBean { @Autowired private LocationDataService m_locationDataService; @Autowired private LocationMonitorDaoHibernate m_locationMonitorDao; @Autowired private ApplicationDao m_applicationDao; @Autowired private MonitoredServiceDao m_monitoredServiceDao; @Autowired private IpInterfaceDao m_ipInterfaceDao; @Autowired private DistPollerDao m_distPollerDao; @Autowired private NodeDao m_nodeDao; @Autowired private ServiceTypeDao m_serviceTypeDao; @Autowired private PollerBackEnd m_pollerBackEnd; private OnmsLocationMonitor m_rduMonitor1; private OnmsLocationMonitor m_rduMonitor2; private OnmsMonitoredService m_localhostHttpService; private OnmsMonitoredService m_googleHttpService; // private Date m_pollingEnd = getMidnight(); private Date m_pollingEnd = new Date(); private Date m_pollingStart = new Date(m_pollingEnd.getTime() - (1000 * 60 * 60 * 24)); @Override public void afterPropertiesSet() throws Exception { BeanUtils.assertAutowiring(this); } @Before public void setUp() throws Exception { Properties p = new Properties(); p.setProperty("log4j.logger.org.hibernate", "INFO"); p.setProperty("log4j.logger.org.hibernate.SQL", "DEBUG"); MockLogAppender.setupLogging(p); OnmsApplication app = new OnmsApplication(); app.setName("TestApp1"); m_applicationDao.saveOrUpdate(app); OnmsDistPoller dp = new OnmsDistPoller("localhost", "127.0.0.1"); m_distPollerDao.saveOrUpdate(dp); OnmsNode localhostNode = new OnmsNode(dp); localhostNode.setLabel("localhost"); m_nodeDao.saveOrUpdate(localhostNode); OnmsNode googleNode = new OnmsNode(dp); googleNode.setLabel("google"); m_nodeDao.saveOrUpdate(googleNode); OnmsIpInterface localhostIpInterface = new OnmsIpInterface("127.0.0.1", localhostNode); m_ipInterfaceDao.saveOrUpdate(localhostIpInterface); OnmsIpInterface googleIpInterface = new OnmsIpInterface("66.249.80.104", googleNode); m_ipInterfaceDao.saveOrUpdate(googleIpInterface); OnmsServiceType httpServiceType = new OnmsServiceType("HTTP"); m_serviceTypeDao.saveOrUpdate(httpServiceType); m_localhostHttpService = createService(app, localhostIpInterface, httpServiceType); m_googleHttpService = createService(app, googleIpInterface, httpServiceType); m_rduMonitor1 = new OnmsLocationMonitor(); m_rduMonitor1.setDefinitionName("RDU"); m_rduMonitor1.setLastCheckInTime(m_pollingEnd); m_rduMonitor1.setStatus(MonitorStatus.STARTED); m_locationMonitorDao.saveOrUpdate(m_rduMonitor1); m_rduMonitor2 = new OnmsLocationMonitor(); m_rduMonitor2.setDefinitionName("RDU"); m_rduMonitor2.setLastCheckInTime(m_pollingEnd); m_rduMonitor2.setStatus(MonitorStatus.STARTED); m_locationMonitorDao.saveOrUpdate(m_rduMonitor2); m_applicationDao.flush(); m_distPollerDao.flush(); m_nodeDao.flush(); m_ipInterfaceDao.flush(); m_serviceTypeDao.flush(); m_monitoredServiceDao.flush(); m_locationMonitorDao.flush(); OnmsApplication onmsApp = m_applicationDao.findByName("TestApp1"); assertTrue(onmsApp.equals(app)); assertEquals("Count of applications associated with services is wrong", 1, m_localhostHttpService.getApplications().size()); assertEquals("Count of applications associated with services is wrong", 1, m_googleHttpService.getApplications().size()); assertEquals("Count of services associated with application is wrong", 2, app.getMonitoredServices().size()); m_pollingEnd = new Date(); m_pollingStart = new Date(m_pollingEnd.getTime() - (1000 * 60 * 60 * 24)); } private long days(int numDays) { return 86400000 * numDays; } private long hours(int numHours) { return 3600000 * numHours; } @SuppressWarnings("unused") private long minutes(int numMinutes) { return 60000 * numMinutes; } private long now() { return System.currentTimeMillis(); } private OnmsMonitoredService createService(OnmsApplication app, OnmsIpInterface localhostIpInterface, OnmsServiceType httpServiceType) { OnmsMonitoredService service = new OnmsMonitoredService(); service.addApplication(app); app.addMonitoredService(service); service.setIpInterface(localhostIpInterface); service.setLastFail(m_pollingEnd); service.setLastGood(m_pollingEnd); service.setNotify("N"); service.setServiceType(httpServiceType); service.setStatus("A"); service.setSource("P"); m_monitoredServiceDao.saveOrUpdate(service); m_applicationDao.saveOrUpdate(app); return service; } @Test public void testLocationInfo() throws Exception { m_pollerBackEnd.reportResult(m_rduMonitor1.getId(), m_localhostHttpService.getId(), getAvailable(new Date(now() - days(20) - hours(3)))); m_pollerBackEnd.reportResult(m_rduMonitor1.getId(), m_localhostHttpService.getId(), getDown(new Date(now() - days(20) - hours(2)))); m_pollerBackEnd.reportResult(m_rduMonitor1.getId(), m_localhostHttpService.getId(), getAvailable(new Date(now() - days(20) - hours(1)))); m_pollerBackEnd.reportResult(m_rduMonitor1.getId(), m_googleHttpService.getId(), getDown(new Date(now() - days(20) - hours(4)))); LocationInfo li = m_locationDataService.getLocationInfo("RDU"); assertEquals("RDU", li.getName()); // Down because one of the services is down. assertEquals(Status.DOWN, li.getStatusDetails().getStatus()); } @Test public void testLocationDetails() throws Exception { m_pollerBackEnd.reportResult(m_rduMonitor1.getId(), m_localhostHttpService.getId(), getAvailable(new Date(now() - days(20) - hours(3)))); m_pollerBackEnd.reportResult(m_rduMonitor1.getId(), m_localhostHttpService.getId(), getDown(new Date(now() - days(20) - hours(2)))); m_pollerBackEnd.reportResult(m_rduMonitor1.getId(), m_localhostHttpService.getId(), getAvailable(new Date(now() - days(20) - hours(1)))); m_pollerBackEnd.reportResult(m_rduMonitor1.getId(), m_googleHttpService.getId(), getDown(new Date(now() - days(20) - hours(4)))); LocationDetails ld = m_locationDataService.getLocationDetails("RDU"); assertEquals(Status.UNKNOWN, ld.getApplicationState().getStatusDetails().getStatus()); assertEquals(Status.DOWN, ld.getLocationMonitorState().getStatusDetails().getStatus()); } @Test public void testLocationMonitorState() throws Exception { m_pollerBackEnd.reportResult(m_rduMonitor1.getId(), m_localhostHttpService.getId(), getAvailable(new Date(now() - days(20) - hours(3)))); m_pollerBackEnd.reportResult(m_rduMonitor1.getId(), m_localhostHttpService.getId(), getDown(new Date(now() - days(20) - hours(2)))); m_pollerBackEnd.reportResult(m_rduMonitor1.getId(), m_localhostHttpService.getId(), getAvailable(new Date(now() - days(20) - hours(1)))); m_pollerBackEnd.reportResult(m_rduMonitor1.getId(), m_googleHttpService.getId(), getDown(new Date(now() - days(20) - hours(4)))); LocationDetails ld = m_locationDataService.getLocationDetails("RDU"); LocationMonitorState lms = ld.getLocationMonitorState(); assertEquals(Status.DOWN, lms.getStatusDetails().getStatus()); assertEquals(2, lms.getServices().size()); assertEquals(1, lms.getServicesDown().size()); assertEquals(1, lms.getMonitorsWithServicesDown().size()); assertEquals(2, lms.getMonitorsStarted()); assertEquals(0, lms.getMonitorsStopped()); assertEquals(0, lms.getMonitorsDisconnected()); } @Test public void testApplicationInfo() throws Exception { m_pollerBackEnd.reportResult(m_rduMonitor1.getId(), m_localhostHttpService.getId(), getAvailable(new Date(now() - hours(3)))); m_pollerBackEnd.reportResult(m_rduMonitor1.getId(), m_localhostHttpService.getId(), getDown(new Date(now() - hours(2)))); m_pollerBackEnd.reportResult(m_rduMonitor1.getId(), m_localhostHttpService.getId(), getAvailable(new Date(now() - hours(1)))); m_pollerBackEnd.reportResult(m_rduMonitor1.getId(), m_googleHttpService.getId(), getDown(new Date(now() - hours(4)))); ApplicationInfo ai = m_locationDataService.getApplicationInfo("TestApp1"); assertEquals("TestApp1", ai.getName()); assertEquals(Status.DOWN, ai.getStatusDetails().getStatus()); } @Test public void testApplicationDetailsFullyAvailableOneMonitor() throws Exception { m_pollerBackEnd.reportResult(m_rduMonitor1.getId(), m_localhostHttpService.getId(), getAvailable(m_pollingStart)); m_pollerBackEnd.reportResult(m_rduMonitor1.getId(), m_googleHttpService.getId(), getAvailable(m_pollingStart)); ApplicationDetails ad = m_locationDataService.getApplicationDetails("TestApp1"); assertEquals("TestApp1", ad.getApplicationName()); assertEquals(Double.valueOf(100), ad.getAvailability()); assertEquals(StatusDetails.up(), ad.getStatusDetails()); } @Test public void testApplicationDetailsHalfAvailableOneMonitor() throws Exception { // first, everything's up m_pollerBackEnd.reportResult(m_rduMonitor1.getId(), m_localhostHttpService.getId(), getAvailable(m_pollingStart)); m_pollerBackEnd.reportResult(m_rduMonitor1.getId(), m_googleHttpService.getId(), getAvailable(m_pollingStart)); // bring it down for 12 hours m_pollerBackEnd.reportResult(m_rduMonitor1.getId(), m_googleHttpService.getId(), getDown(new Date(m_pollingStart.getTime() + (1000 * 60 * 60 * 6)))); // bring it back up m_pollerBackEnd.reportResult(m_rduMonitor1.getId(), m_googleHttpService.getId(), getAvailable(new Date(m_pollingStart.getTime() + (1000 * 60 * 60 * 18)))); ApplicationDetails ad = m_locationDataService.getApplicationDetails("TestApp1"); assertEquals("TestApp1", ad.getApplicationName()); assertEquals(Double.valueOf(50), ad.getAvailability()); assertEquals("currently available", StatusDetails.up(), ad.getStatusDetails()); } @Test public void testApplicationDetailsDownOneMonitor() throws Exception { m_pollerBackEnd.reportResult(m_rduMonitor1.getId(), m_localhostHttpService.getId(), getDown(m_pollingStart)); m_pollerBackEnd.reportResult(m_rduMonitor1.getId(), m_googleHttpService.getId(), getDown(m_pollingStart)); ApplicationDetails ad = m_locationDataService.getApplicationDetails("TestApp1"); assertEquals("TestApp1", ad.getApplicationName()); assertEquals(Double.valueOf(0), ad.getAvailability()); assertEquals("down for 24 hours", StatusDetails.down("foo"), ad.getStatusDetails()); } @Test public void testApplicationDetailsTwoMonitorsMarginal() throws Exception { // first, everything's up m_pollerBackEnd.reportResult(m_rduMonitor1.getId(), m_localhostHttpService.getId(), getAvailable(m_pollingStart)); m_pollerBackEnd.reportResult(m_rduMonitor2.getId(), m_localhostHttpService.getId(), getAvailable(m_pollingStart)); m_pollerBackEnd.reportResult(m_rduMonitor1.getId(), m_googleHttpService.getId(), getAvailable(m_pollingStart)); m_pollerBackEnd.reportResult(m_rduMonitor2.getId(), m_googleHttpService.getId(), getAvailable(m_pollingStart)); // bring one down for 12 hours m_pollerBackEnd.reportResult(m_rduMonitor1.getId(), m_googleHttpService.getId(), getDown(new Date(m_pollingStart.getTime() + (1000 * 60 * 60 * 6)))); // and back up m_pollerBackEnd.reportResult(m_rduMonitor1.getId(), m_googleHttpService.getId(), getAvailable(new Date(m_pollingStart.getTime() + (1000 * 60 * 60 * 18)))); ApplicationDetails ad = m_locationDataService.getApplicationDetails("TestApp1"); assertEquals("TestApp1", ad.getApplicationName()); assertEquals(Double.valueOf(100), ad.getAvailability()); assertEquals("currently available", StatusDetails.up(), ad.getStatusDetails()); } @Test public void testApplicationDetailsTwoMonitorsOutageContainedInOther() throws Exception { // first, everything's up m_pollerBackEnd.reportResult(m_rduMonitor1.getId(), m_localhostHttpService.getId(), getAvailable(m_pollingStart)); m_pollerBackEnd.reportResult(m_rduMonitor2.getId(), m_localhostHttpService.getId(), getAvailable(m_pollingStart)); m_pollerBackEnd.reportResult(m_rduMonitor1.getId(), m_googleHttpService.getId(), getAvailable(m_pollingStart)); m_pollerBackEnd.reportResult(m_rduMonitor2.getId(), m_googleHttpService.getId(), getAvailable(m_pollingStart)); // bring one down for 12 hours m_pollerBackEnd.reportResult(m_rduMonitor1.getId(), m_googleHttpService.getId(), getDown(new Date(m_pollingStart.getTime() + (1000 * 60 * 60 * 6)))); // and back up m_pollerBackEnd.reportResult(m_rduMonitor1.getId(), m_googleHttpService.getId(), getAvailable(new Date(m_pollingStart.getTime() + (1000 * 60 * 60 * 18)))); // bring the other down for 4 hours, overlapping m_pollerBackEnd.reportResult(m_rduMonitor2.getId(), m_googleHttpService.getId(), getDown(new Date(m_pollingStart.getTime() + (1000 * 60 * 60 * 6)))); // and back up m_pollerBackEnd.reportResult(m_rduMonitor2.getId(), m_googleHttpService.getId(), getAvailable(new Date(m_pollingStart.getTime() + (1000 * 60 * 60 * 10)))); ApplicationDetails ad = m_locationDataService.getApplicationDetails("TestApp1"); assertEquals("TestApp1", ad.getApplicationName()); assertEquals(Double.valueOf(20D/24D*100), ad.getAvailability()); assertEquals("currently available", StatusDetails.up(), ad.getStatusDetails()); } @Test public void testApplicationDetailsTwoMonitorsOutagesOverlap() throws Exception { // first, everything's up m_pollerBackEnd.reportResult(m_rduMonitor1.getId(), m_localhostHttpService.getId(), getAvailable(m_pollingStart)); m_pollerBackEnd.reportResult(m_rduMonitor2.getId(), m_localhostHttpService.getId(), getAvailable(m_pollingStart)); m_pollerBackEnd.reportResult(m_rduMonitor1.getId(), m_googleHttpService.getId(), getAvailable(m_pollingStart)); m_pollerBackEnd.reportResult(m_rduMonitor2.getId(), m_googleHttpService.getId(), getAvailable(m_pollingStart)); // bring one down for 12 hours m_pollerBackEnd.reportResult(m_rduMonitor1.getId(), m_googleHttpService.getId(), getDown(new Date(m_pollingStart.getTime() + (1000 * 60 * 60 * 6)))); // and back up m_pollerBackEnd.reportResult(m_rduMonitor1.getId(), m_googleHttpService.getId(), getAvailable(new Date(m_pollingStart.getTime() + (1000 * 60 * 60 * 18)))); // bring the other down for 12 hours, overlapping by 8 m_pollerBackEnd.reportResult(m_rduMonitor2.getId(), m_googleHttpService.getId(), getDown(new Date(m_pollingStart.getTime() + (1000 * 60 * 60 * 10)))); // and back up m_pollerBackEnd.reportResult(m_rduMonitor2.getId(), m_googleHttpService.getId(), getAvailable(new Date(m_pollingStart.getTime() + (1000 * 60 * 60 * 22)))); ApplicationDetails ad = m_locationDataService.getApplicationDetails("TestApp1"); assertEquals("TestApp1", ad.getApplicationName()); assertEquals(Double.valueOf(16D/24D*100), ad.getAvailability()); assertEquals("currently available", StatusDetails.up(), ad.getStatusDetails()); final String detailString = ad.getDetailsAsString(); System.err.println(detailString); assertTrue(detailString.contains("")); } @Test public void testIntervalManipulation() { Set<Interval> intervals = IntervalUtils.getIntervalSet(); intervals.add(new Interval(0, 1000)); intervals.add(new Interval(1200, 2000)); Set<Interval> inverted = IntervalUtils.invert(new Date(0), new Date(3000), intervals); Set<Interval> invertedMatch = IntervalUtils.getIntervalSet(); invertedMatch.add(new Interval(1000, 1200)); invertedMatch.add(new Interval(2000, 3000)); assertEquals(invertedMatch, inverted); intervals = IntervalUtils.getIntervalSet(); intervals.add(new Interval(100, 1000)); intervals.add(new Interval(1500, 2000)); inverted = IntervalUtils.invert(new Date(0), new Date(2000), intervals); invertedMatch = IntervalUtils.getIntervalSet(); invertedMatch.add(new Interval(0, 100)); invertedMatch.add(new Interval(1000, 1500)); assertEquals(invertedMatch, inverted); intervals = IntervalUtils.getIntervalSet(); intervals.add(new Interval(0, 1500)); intervals.add(new Interval(1000, 3000)); intervals.add(new Interval(4000, 5000)); Set<Interval> normalized = IntervalUtils.normalize(intervals); Set<Interval> normalizedMatch = IntervalUtils.getIntervalSet(); normalizedMatch.add(new Interval(0, 3000)); normalizedMatch.add(new Interval(4000, 5000)); assertEquals(normalizedMatch, normalized); intervals = IntervalUtils.getIntervalSet(); intervals.add(new Interval(0, 1500)); intervals.add(new Interval(1000, 3000)); intervals.add(new Interval(4000, 5000)); intervals.add(new Interval(2000, 4500)); intervals.add(new Interval(3500, 4400)); intervals.add(new Interval(2800, 5600)); normalized = IntervalUtils.normalize(intervals); normalizedMatch = IntervalUtils.getIntervalSet(); normalizedMatch.add(new Interval(0, 5600)); assertEquals(normalizedMatch, normalized); } private PollStatus getDown(final Date date) { final PollStatus ps = PollStatus.down("butt itches"); ps.setTimestamp(date); return ps; } private PollStatus getAvailable(final Date date) { final PollStatus ps = PollStatus.available(); ps.setTimestamp(date); return ps; } public void setTemporaryDatabase(TemporaryDatabase database) { FilterDaoFactory.setInstance(null); } }