/******************************************************************************* * This file is part of OpenNMS(R). * * Copyright (C) 2008-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.web.rest; import java.util.Collections; import java.util.LinkedList; import java.util.List; import javax.persistence.Entity; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.UriInfo; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlElementWrapper; import javax.xml.bind.annotation.XmlRootElement; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.builder.ToStringBuilder; import org.opennms.core.criteria.Alias.JoinType; import org.opennms.core.criteria.Criteria; import org.opennms.core.criteria.CriteriaBuilder; import org.opennms.core.criteria.Fetch.FetchType; import org.opennms.core.utils.LogUtils; import org.opennms.netmgt.dao.stats.AlarmStatisticsService; import org.opennms.netmgt.model.OnmsAlarm; import org.opennms.netmgt.model.OnmsSeverity; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; import com.sun.jersey.spi.resource.PerRequest; /** * Basic Web Service using REST for NCS Components * * @author <a href="mailto:brozow@opennms.org">Matt Brozowski</a> */ @Component @PerRequest @Scope("prototype") @Path("stats/alarms") @Transactional public class AlarmStatsRestService extends AlarmRestServiceBase { private static final String[] EMPTY_STRING_ARRAY = new String[0]; @Autowired AlarmStatisticsService m_statisticsService; @Context UriInfo m_uriInfo; @GET @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) public AlarmStatistics getStats() { readLock(); try { return getStats(null); } finally { readUnlock(); } } @GET @Path("/by-severity") @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) public AlarmStatisticsBySeverity getStatsForEachSeverity(@QueryParam("severities") final String severitiesString) { readLock(); try { final AlarmStatisticsBySeverity stats = new AlarmStatisticsBySeverity(); String[] severities = StringUtils.split(severitiesString, ","); if (severities == null || severities.length == 0) { severities = OnmsSeverity.names().toArray(EMPTY_STRING_ARRAY); } for (final String severityName : severities) { final OnmsSeverity severity = OnmsSeverity.get(severityName); final AlarmStatistics stat = getStats(severity); stat.setSeverity(severity); stats.add(stat); } return stats; } finally { readUnlock(); } } protected AlarmStatistics getStats(final OnmsSeverity severity) { final AlarmStatistics stats = new AlarmStatistics(); final CriteriaBuilder builder = getCriteriaBuilder(m_uriInfo.getQueryParameters(), false); // note: this is just the *total count* criteria, so no ordering, and count everything builder.clearOrder(); builder.limit(null); builder.offset(0); if (severity != null) { builder.eq("severity", severity); } final Criteria criteria = builder.toCriteria(); LogUtils.debugf(this, "criteria = %s", criteria); final int count = m_statisticsService.getTotalCount(criteria); stats.setTotalCount(count); stats.setAcknowledgedCount(m_statisticsService.getAcknowledgedCount(criteria)); stats.setNewestAcknowledged(getNewestAcknowledged(severity)); stats.setNewestUnacknowledged(getNewestUnacknowledged(severity)); stats.setOldestAcknowledged(getOldestAcknowledged(severity)); stats.setOldestUnacknowledged(getOldestUnacknowledged(severity)); return stats; } protected OnmsAlarm getNewestAcknowledged(final OnmsSeverity severity) { final CriteriaBuilder builder = getCriteriaBuilder(severity); builder.orderBy("lastEventTime").desc(); builder.orderBy("id").desc(); builder.limit(1); final Criteria criteria = builder.toCriteria(); LogUtils.debugf(this, "getNewestAcknowledged(%s) criteria = %s", severity, criteria); return m_statisticsService.getAcknowledged(criteria); } private OnmsAlarm getNewestUnacknowledged(final OnmsSeverity severity) { final CriteriaBuilder builder = getCriteriaBuilder(severity); builder.orderBy("lastEventTime").desc(); builder.orderBy("id").desc(); builder.limit(1); final Criteria criteria = builder.toCriteria(); LogUtils.debugf(this, "getNewestUnacknowledged(%s) criteria = %s", severity, criteria); return m_statisticsService.getUnacknowledged(criteria); } protected OnmsAlarm getOldestAcknowledged(final OnmsSeverity severity) { final CriteriaBuilder builder = getCriteriaBuilder(severity); builder.orderBy("firstEventTime").asc(); builder.orderBy("id").asc(); builder.limit(1); final Criteria criteria = builder.toCriteria(); LogUtils.debugf(this, "getOldestAcknowledged(%s) criteria = %s", severity, criteria); return m_statisticsService.getAcknowledged(criteria); } private OnmsAlarm getOldestUnacknowledged(final OnmsSeverity severity) { final CriteriaBuilder builder = getCriteriaBuilder(severity); builder.orderBy("firstEventTime").asc(); builder.orderBy("id").asc(); builder.limit(1); final Criteria criteria = builder.toCriteria(); LogUtils.debugf(this, "getOldestUnacknowledged(%s) criteria = %s", severity, criteria); return m_statisticsService.getUnacknowledged(criteria); } protected CriteriaBuilder getCriteriaBuilder(final OnmsSeverity severity) { final CriteriaBuilder builder = new CriteriaBuilder(OnmsAlarm.class); if (severity != null) { builder.eq("severity", severity); } builder.fetch("firstEvent", FetchType.EAGER); builder.fetch("lastEvent", FetchType.EAGER); builder.alias("node", "node", JoinType.LEFT_JOIN); builder.alias("node.snmpInterfaces", "snmpInterface", JoinType.LEFT_JOIN); builder.alias("node.ipInterfaces", "ipInterface", JoinType.LEFT_JOIN); return builder; } @Entity @XmlRootElement(name = "severities") public static class AlarmStatisticsBySeverity { private List<AlarmStatistics> m_stats = new LinkedList<AlarmStatistics>(); @XmlElement(name="alarmStatistics") public List<AlarmStatistics> getStats() { return m_stats; } public void setStats(final List<AlarmStatistics> stats) { m_stats = stats; } public void add(final AlarmStatistics stats) { m_stats.add(stats); } @Override public String toString() { return new ToStringBuilder(this) .append("alarmStatistics", m_stats) .toString(); } } @Entity @XmlRootElement(name = "alarmStatistics") public static class AlarmStatistics { private int m_totalCount = 0; private int m_acknowledgedCount = 0; private OnmsSeverity m_severity = null; private OnmsAlarm m_newestAcknowledged; private OnmsAlarm m_newestUnacknowledged; private OnmsAlarm m_oldestAcknowledged; private OnmsAlarm m_oldestUnacknowledged; @Override public String toString() { return new ToStringBuilder(this) .append("totalCount", m_totalCount) .append("acknowledgedCount", m_acknowledgedCount) .append("unacknowledgedCount", getUnacknowledgedCount()) .append("newestAcknowledged", m_newestAcknowledged) .append("newestUnacknowledged", m_newestUnacknowledged) .append("oldestAcknowledged", m_oldestAcknowledged) .append("oldestUnacknowledged", m_oldestUnacknowledged) .toString(); } @XmlAttribute(name="totalCount") public int getTotalCount() { return m_totalCount; } public void setTotalCount(final int count) { m_totalCount = count; } @XmlAttribute(name="acknowledgedCount") public int getAcknowledgedCount() { return m_acknowledgedCount; } public void setAcknowledgedCount(final int count) { m_acknowledgedCount = count; } @XmlAttribute(name="unacknowledgedCount") public int getUnacknowledgedCount() { return m_totalCount - m_acknowledgedCount; } public void setUnacknowledgedCount(final int count) {} @XmlAttribute(name="severity") public OnmsSeverity getSeverity() { return m_severity; } public void setSeverity(final OnmsSeverity severity) { m_severity = severity; } @XmlElementWrapper(name="newestAcked") @XmlElement(name="alarm") public List<OnmsAlarm> getNewestAcknowledged() { return Collections.singletonList(m_newestAcknowledged); } public void setNewestAcknowledged(final OnmsAlarm alarm) { m_newestAcknowledged = alarm; } @XmlElementWrapper(name="newestUnacked") @XmlElement(name="alarm") public List<OnmsAlarm> getNewestUnacknowledged() { return Collections.singletonList(m_newestUnacknowledged); } public void setNewestUnacknowledged(final OnmsAlarm alarm) { m_newestUnacknowledged = alarm; } @XmlElementWrapper(name="oldestAcked") @XmlElement(name="alarm") public List<OnmsAlarm> getOldestAcknowledged() { return Collections.singletonList(m_oldestAcknowledged); } public void setOldestAcknowledged(final OnmsAlarm alarm) { m_oldestAcknowledged = alarm; } @XmlElementWrapper(name="oldestUnacked") @XmlElement(name="alarm") public List<OnmsAlarm> getOldestUnacknowledged() { return Collections.singletonList(m_oldestUnacknowledged); } public void setOldestUnacknowledged(final OnmsAlarm alarm) { m_oldestUnacknowledged = alarm; } } }