/*******************************************************************************
* 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.web.notification;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.Date;
import java.util.Vector;
import javax.servlet.ServletContext;
import org.opennms.core.resource.Vault;
import org.opennms.core.utils.ThreadCategory;
import org.opennms.web.element.NetworkElementFactory;
import org.opennms.web.filter.Filter;
import org.opennms.web.notification.filter.NodeFilter;
/**
* Encapsulates all querying functionality for notices
*
* @author <A HREF="mailto:larry@opennms.org">Lawrence Karnowski </A>
* @author <A HREF="http://www.opennms.org/">OpenNMS </A>
* @author <A HREF="mailto:larry@opennms.org">Lawrence Karnowski </A>
* @author <A HREF="http://www.opennms.org/">OpenNMS </A>
* @version $Id: $
* @since 1.8.1
*/
public class NoticeFactory {
/** Private constructor so this class cannot be instantiated. */
private NoticeFactory() {
}
/**
* Count the number of notices for a given acknowledgement type.
*
* @param ackType a {@link org.opennms.web.notification.AcknowledgeType} object.
* @param filters an array of org$opennms$web$filter$Filter objects.
* @return a int.
* @throws java.sql.SQLException if any.
*/
public static int getNoticeCount(AcknowledgeType ackType, Filter[] filters) throws SQLException {
if (ackType == null || filters == null) {
throw new IllegalArgumentException("Cannot take null parameters.");
}
int noticeCount = 0;
Connection conn = Vault.getDbConnection();
try {
StringBuffer select = new StringBuffer("SELECT COUNT(NOTIFYID) AS NOTICECOUNT FROM NOTIFICATIONS WHERE");
select.append(ackType.getAcknowledgeTypeClause());
for (Filter filter : filters) {
select.append(" AND");
select.append(filter.getParamSql());
}
PreparedStatement stmt = conn.prepareStatement(select.toString());
int parameterIndex = 1;
for (Filter filter : filters) {
parameterIndex += filter.bindParam(stmt, parameterIndex);
}
ResultSet rs = stmt.executeQuery();
if (rs.next()) {
noticeCount = rs.getInt("NOTICECOUNT");
}
rs.close();
stmt.close();
} finally {
Vault.releaseDbConnection(conn);
}
return noticeCount;
}
/**
* Return a specific notice.
*
* @param noticeId a int.
* @return a {@link org.opennms.web.notification.Notification} object.
* @throws java.sql.SQLException if any.
*/
public static Notification getNotice(int noticeId, ServletContext servletContext) throws SQLException {
Notification notice = null;
Connection conn = Vault.getDbConnection();
try {
PreparedStatement stmt = conn.prepareStatement("SELECT * FROM NOTIFICATION WHERE NOTIFYID=?");
stmt.setInt(1, noticeId);
ResultSet rs = stmt.executeQuery();
Notification[] notices = rs2Notices(rs, servletContext);
// what do I do if this actually returns more than one service?
if (notices.length > 0) {
notice = notices[0];
}
rs.close();
stmt.close();
} finally {
Vault.releaseDbConnection(conn);
}
return notice;
}
/**
* This method determines the log status of an event associated with a
* notification
*
* @param eventId
* the unique id of the event from the notice
* @return true if the event is display, false if log only
*/
public static boolean canDisplayEvent(int eventId) {
boolean display = false;
Connection connection = null;
try {
connection = Vault.getDbConnection();
PreparedStatement statement = connection.prepareStatement("SELECT eventDisplay FROM events WHERE eventid=?");
statement.setInt(1, eventId);
ResultSet results = statement.executeQuery();
results.next();
String status = results.getString(1);
if (status.equals("Y")) {
display = true;
}
statement.close();
results.close();
} catch (SQLException e) {
ThreadCategory.getInstance(NoticeFactory.class.getName()).error("Error getting event display status: " + e.getMessage(), e);
} finally {
if (connection != null) {
try {
Vault.releaseDbConnection(connection);
} catch (SQLException e) {
}
}
}
return display;
}
/**
* Return all unacknowledged notices sorted by id.
*
* @return an array of {@link org.opennms.web.notification.Notification} objects.
* @throws java.sql.SQLException if any.
*/
public static Notification[] getNotices(ServletContext servletContext) throws SQLException {
return (NoticeFactory.getNotices(SortStyle.ID, AcknowledgeType.UNACKNOWLEDGED, servletContext));
}
/**
* Return all unacknowledged or acknowledged notices sorted by id.
*
* @param ackType a {@link org.opennms.web.notification.AcknowledgeType} object.
* @return an array of {@link org.opennms.web.notification.Notification} objects.
* @throws java.sql.SQLException if any.
*/
public static Notification[] getNotices(AcknowledgeType ackType, ServletContext servletContext) throws SQLException {
return (NoticeFactory.getNotices(SortStyle.ID, ackType, servletContext));
}
/**
* Return all unacknowledged notices sorted by the given sort style.
*
* @param sortStyle a {@link org.opennms.web.notification.SortStyle} object.
* @return an array of {@link org.opennms.web.notification.Notification} objects.
* @throws java.sql.SQLException if any.
*/
public static Notification[] getNotices(SortStyle sortStyle, ServletContext servletContext) throws SQLException {
return (NoticeFactory.getNotices(sortStyle, AcknowledgeType.UNACKNOWLEDGED, servletContext));
}
/**
* Return all notices (optionally only unacknowledged notices) sorted by the
* given sort style.
*
* @deprecated Replaced by
* {@link " #getNotices(SortStyle,AcknowledgeType) getNotices( SortStyle, AcknowledgeType )"}
* @param sortStyle a {@link org.opennms.web.notification.SortStyle} object.
* @param includeAcknowledged a boolean.
* @return an array of {@link org.opennms.web.notification.Notification} objects.
* @throws java.sql.SQLException if any.
*/
public static Notification[] getNotices(SortStyle sortStyle, boolean includeAcknowledged, ServletContext servletContext) throws SQLException {
AcknowledgeType ackType = (includeAcknowledged) ? AcknowledgeType.BOTH : AcknowledgeType.UNACKNOWLEDGED;
return (NoticeFactory.getNotices(sortStyle, ackType, servletContext));
}
/**
* Return all notices (optionally only unacknowledged notices) sorted by the
* given sort style.
*
* @param sortStyle a {@link org.opennms.web.notification.SortStyle} object.
* @param ackType a {@link org.opennms.web.notification.AcknowledgeType} object.
* @return an array of {@link org.opennms.web.notification.Notification} objects.
* @throws java.sql.SQLException if any.
*/
public static Notification[] getNotices(SortStyle sortStyle, AcknowledgeType ackType, ServletContext servletContext) throws SQLException {
return (NoticeFactory.getNotices(sortStyle, ackType, new org.opennms.web.filter.Filter[0], servletContext));
}
/**
* Return all notices (optionally only unacknowledged notices) sorted by the
* given sort style.
*
* @param sortStyle a {@link org.opennms.web.notification.SortStyle} object.
* @param ackType a {@link org.opennms.web.notification.AcknowledgeType} object.
* @param filters an array of org$opennms$web$filter$Filter objects.
* @return an array of {@link org.opennms.web.notification.Notification} objects.
* @throws java.sql.SQLException if any.
*/
public static Notification[] getNotices(SortStyle sortStyle, AcknowledgeType ackType, org.opennms.web.filter.Filter[] filters, ServletContext servletContext) throws SQLException {
return (NoticeFactory.getNotices(sortStyle, ackType, filters, -1, -1, servletContext));
}
/**
* Return all notices (optionally only unacknowledged notices) sorted by the
* given sort style.
*
* <p>
* <strong>Note: </strong> This limit/offset code is <em>Postgres
* specific!</em>
* Per <a href="mailto:shaneo@opennms.org">Shane </a>, this is okay for now
* until we can come up with an Oracle alternative too.
* </p>
*
* @param limit
* if -1 or zero, no limit or offset is used
* @param offset
* if -1, no limit or offset if used
* @param sortStyle a {@link org.opennms.web.notification.SortStyle} object.
* @param ackType a {@link org.opennms.web.notification.AcknowledgeType} object.
* @param filters an array of org$opennms$web$filter$Filter objects.
* @return an array of {@link org.opennms.web.notification.Notification} objects.
* @throws java.sql.SQLException if any.
*/
public static Notification[] getNotices(SortStyle sortStyle, AcknowledgeType ackType, org.opennms.web.filter.Filter[] filters, int limit, int offset, ServletContext servletContext) throws SQLException {
if (sortStyle == null || ackType == null || filters == null) {
throw new IllegalArgumentException("Cannot take null parameters.");
}
boolean useLimits = false;
if (limit > 0 && offset > -1) {
useLimits = true;
}
Notification[] notices = null;
Connection conn = Vault.getDbConnection();
try {
StringBuffer select = new StringBuffer("SELECT * FROM NOTIFICATIONS WHERE");
select.append(ackType.getAcknowledgeTypeClause());
for (Filter filter : filters) {
select.append(" AND");
select.append(filter.getParamSql());
}
select.append(sortStyle.getOrderByClause());
if (useLimits) {
select.append(" LIMIT ?");
//select.append(limit);
select.append(" OFFSET ?");
//select.append(offset);
}
PreparedStatement stmt = conn.prepareStatement(select.toString());
int parameterIndex = 1;
for (Filter filter : filters) {
parameterIndex += filter.bindParam(stmt, parameterIndex);
}
if (useLimits) {
stmt.setInt(parameterIndex++, limit);
stmt.setInt(parameterIndex, offset);
}
ResultSet rs = stmt.executeQuery();
// PreparedStatement ps = conn.prepareStatement(select.toString());
notices = rs2Notices(rs, servletContext);
rs.close();
stmt.close();
} finally {
Vault.releaseDbConnection(conn);
}
return notices;
}
/**
* Return all unacknowledged notices sorted by time for the given node.
*
* @param nodeId a int.
* @return an array of {@link org.opennms.web.notification.Notification} objects.
* @throws java.sql.SQLException if any.
*/
public static Notification[] getNoticesForNode(int nodeId, ServletContext servletContext) throws SQLException {
return (getNoticesForNode(nodeId, SortStyle.ID, AcknowledgeType.UNACKNOWLEDGED, servletContext));
}
/**
* Return all notices (optionally only unacknowledged notices) sorted by id
* for the given node.
*
* @deprecated Replaced by
* {@link " #getNoticesForNode(int,SortStyle,AcknowledgeType) getNoticesForNode( int, SortStyle, AcknowledgeType )"}
* @param nodeId a int.
* @param includeAcknowledged a boolean.
* @return an array of {@link org.opennms.web.notification.Notification} objects.
* @throws java.sql.SQLException if any.
*/
public static Notification[] getNoticesForNode(int nodeId, boolean includeAcknowledged, ServletContext servletContext) throws SQLException {
AcknowledgeType ackType = (includeAcknowledged) ? AcknowledgeType.BOTH : AcknowledgeType.UNACKNOWLEDGED;
return (getNoticesForNode(nodeId, SortStyle.ID, ackType, servletContext));
}
/**
* Return all notices (optionally only unacknowledged notices) sorted by
* given sort style for the given node.
*
* @param nodeId a int.
* @param sortStyle a {@link org.opennms.web.notification.SortStyle} object.
* @param ackType a {@link org.opennms.web.notification.AcknowledgeType} object.
* @return an array of {@link org.opennms.web.notification.Notification} objects.
* @throws java.sql.SQLException if any.
*/
public static Notification[] getNoticesForNode(int nodeId, SortStyle sortStyle, AcknowledgeType ackType, ServletContext servletContext) throws SQLException {
if (sortStyle == null || ackType == null) {
throw new IllegalArgumentException("Cannot take null parameters.");
}
org.opennms.web.filter.Filter[] filters = new org.opennms.web.filter.Filter[] { new NodeFilter(nodeId) };
return (NoticeFactory.getNotices(sortStyle, ackType, filters, servletContext));
}
/**
* Return all unacknowledged notices for the given interface.
*
* @param nodeId a int.
* @param ipAddress a {@link java.lang.String} object.
* @return an array of {@link org.opennms.web.notification.Notification} objects.
* @throws java.sql.SQLException if any.
*/
public static Notification[] getNoticesForInterface(int nodeId, String ipAddress, ServletContext servletContext) throws SQLException {
return (getNoticesForInterface(nodeId, ipAddress, false, servletContext));
}
/**
* Return all notices (optionally only unacknowledged notices) sorted by id
* for the given interface.
*
* @param nodeId a int.
* @param ipAddress a {@link java.lang.String} object.
* @param includeAcknowledged a boolean.
* @return an array of {@link org.opennms.web.notification.Notification} objects.
* @throws java.sql.SQLException if any.
*/
public static Notification[] getNoticesForInterface(int nodeId, String ipAddress, boolean includeAcknowledged, ServletContext servletContext) throws SQLException {
if (ipAddress == null) {
throw new IllegalArgumentException("Cannot take null parameters.");
}
Notification[] notices = null;
Connection conn = Vault.getDbConnection();
try {
StringBuffer select = new StringBuffer("SELECT * FROM NOTIFICATIONS WHERE NODEID=? AND INTERFACEID=?");
if (!includeAcknowledged) {
select.append(" AND RESPONDTIME IS NULL");
}
select.append(" ORDER BY NOTIFYID DESC");
PreparedStatement stmt = conn.prepareStatement(select.toString());
stmt.setInt(1, nodeId);
stmt.setString(2, ipAddress);
ResultSet rs = stmt.executeQuery();
notices = rs2Notices(rs, servletContext);
rs.close();
stmt.close();
} finally {
Vault.releaseDbConnection(conn);
}
return notices;
}
/**
* Return all unacknowledged notices sorted by time for that have the given
* IP address, regardless of what node they belong to.
*
* @param ipAddress a {@link java.lang.String} object.
* @return an array of {@link org.opennms.web.notification.Notification} objects.
* @throws java.sql.SQLException if any.
*/
public static Notification[] getNoticesForInterface(String ipAddress, ServletContext servletContext) throws SQLException {
return (getNoticesForInterface(ipAddress, false, servletContext));
}
/**
* Return all notices (optionally only unacknowledged notices) sorted by id
* that have the given IP address, regardless of what node they belong to.
*
* @param ipAddress a {@link java.lang.String} object.
* @param includeAcknowledged a boolean.
* @return an array of {@link org.opennms.web.notification.Notification} objects.
* @throws java.sql.SQLException if any.
*/
public static Notification[] getNoticesForInterface(String ipAddress, boolean includeAcknowledged, ServletContext servletContext) throws SQLException {
if (ipAddress == null) {
throw new IllegalArgumentException("Cannot take null parameters.");
}
Notification[] notices = null;
Connection conn = Vault.getDbConnection();
try {
StringBuffer select = new StringBuffer("SELECT * FROM NOTIFICATIONS WHERE INTERFACEID=?");
if (!includeAcknowledged) {
select.append(" AND RESPONDTIME IS NULL");
}
select.append(" ORDER BY NOTIFYID DESC");
PreparedStatement stmt = conn.prepareStatement(select.toString());
stmt.setString(1, ipAddress);
ResultSet rs = stmt.executeQuery();
notices = rs2Notices(rs, servletContext);
rs.close();
stmt.close();
} finally {
Vault.releaseDbConnection(conn);
}
return notices;
}
/**
* Return all unacknowledged notices sorted by time for the given service.
*
* @param nodeId a int.
* @param ipAddress a {@link java.lang.String} object.
* @param serviceId a int.
* @return an array of {@link org.opennms.web.notification.Notification} objects.
* @throws java.sql.SQLException if any.
*/
public static Notification[] getNoticesForService(int nodeId, String ipAddress, int serviceId, ServletContext servletContext) throws SQLException {
return (getNoticesForService(nodeId, ipAddress, serviceId, false, servletContext));
}
/**
* Return all notices (optionally only unacknowledged notices) sorted by
* time for the given service.
*
* @param nodeId a int.
* @param ipAddress a {@link java.lang.String} object.
* @param serviceId a int.
* @param includeAcknowledged a boolean.
* @return an array of {@link org.opennms.web.notification.Notification} objects.
* @throws java.sql.SQLException if any.
*/
public static Notification[] getNoticesForService(int nodeId, String ipAddress, int serviceId, boolean includeAcknowledged, ServletContext servletContext) throws SQLException {
if (ipAddress == null) {
throw new IllegalArgumentException("Cannot take null parameters.");
}
Notification[] notices = null;
Connection conn = Vault.getDbConnection();
try {
StringBuffer select = new StringBuffer("SELECT * FROM NOTIFICATIONS WHERE NODEID=? AND INTERFACEID=? AND SERVICEID=?");
if (!includeAcknowledged) {
select.append(" AND RESPONDTIME IS NULL");
}
select.append(" ORDER BY NOTIFYID DESC");
PreparedStatement stmt = conn.prepareStatement(select.toString());
stmt.setInt(1, nodeId);
stmt.setString(2, ipAddress);
stmt.setInt(3, serviceId);
ResultSet rs = stmt.executeQuery();
notices = rs2Notices(rs, servletContext);
rs.close();
stmt.close();
} finally {
Vault.releaseDbConnection(conn);
}
return notices;
}
/**
* Return all unacknowledged notices sorted by time for the given service
* type, regardless of what node or interface they belong to.
*
* @param serviceId a int.
* @return an array of {@link org.opennms.web.notification.Notification} objects.
* @throws java.sql.SQLException if any.
*/
public static Notification[] getNoticesForService(int serviceId, ServletContext servletContext) throws SQLException {
return (getNoticesForService(serviceId, false, servletContext));
}
/**
* Return all notices (optionally only unacknowledged notices) sorted by id
* for the given service type, regardless of what node or interface they
* belong to.
*
* @param serviceId a int.
* @param includeAcknowledged a boolean.
* @return an array of {@link org.opennms.web.notification.Notification} objects.
* @throws java.sql.SQLException if any.
*/
public static Notification[] getNoticesForService(int serviceId, boolean includeAcknowledged, ServletContext servletContext) throws SQLException {
Notification[] notices = null;
Connection conn = Vault.getDbConnection();
try {
StringBuffer select = new StringBuffer("SELECT * FROM NOTIFICATION WHERE SERVICEID=?");
if (!includeAcknowledged) {
select.append(" AND RESPONDTIME IS NULL");
}
select.append(" ORDER BY NOTIFIYID DESC");
PreparedStatement stmt = conn.prepareStatement(select.toString());
stmt.setInt(1, serviceId);
ResultSet rs = stmt.executeQuery();
notices = rs2Notices(rs, servletContext);
rs.close();
stmt.close();
} finally {
Vault.releaseDbConnection(conn);
}
return notices;
}
/**
* Acknowledge a list of notices with the given username
*
* @param notices an array of {@link org.opennms.web.notification.Notification} objects.
* @param user a {@link java.lang.String} object.
* @throws java.sql.SQLException if any.
*/
public static void acknowledge(Notification[] notices, String user) throws SQLException {
acknowledge(notices, user, new Date());
}
/**
* Acknowledge a list of notices with the given username and the given time.
*
* @param notices an array of {@link org.opennms.web.notification.Notification} objects.
* @param user a {@link java.lang.String} object.
* @param time a java$util$Date object.
* @throws java.sql.SQLException if any.
*/
public static void acknowledge(Notification[] notices, String user, Date time) throws SQLException {
if (notices == null) {
throw new IllegalArgumentException("Cannot take null parameters.");
}
int[] ids = new int[notices.length];
for (int i = 0; i < ids.length; i++) {
ids[i] = notices[i].getId();
}
acknowledge(ids, user, time);
}
/**
* Acknowledge a list of notices with the given username and the current
* time.
*
* @param noticeIds an array of int.
* @param user a {@link java.lang.String} object.
* @throws java.sql.SQLException if any.
*/
public static void acknowledge(int[] noticeIds, String user) throws SQLException {
acknowledge(noticeIds, user, new Date());
}
/**
* Acknowledge a list of notices with the given username and the given time.
*
* @param noticeIds an array of int.
* @param user a {@link java.lang.String} object.
* @param time a java$util$Date object.
* @throws java.sql.SQLException if any.
*/
public static void acknowledge(int[] noticeIds, String user, Date time) throws SQLException {
if (noticeIds == null || user == null || time == null) {
throw new IllegalArgumentException("Cannot take null parameters.");
}
if (noticeIds.length > 0) {
StringBuffer update = new StringBuffer("UPDATE NOTIFICATIONS SET RESPONDTIME=?, ANSWEREDBY=?");
update.append(" WHERE NOTIFYID IN (");
update.append(noticeIds[0]);
for (int i = 1; i < noticeIds.length; i++) {
update.append(",");
update.append(noticeIds[i]);
}
update.append(")");
update.append(" AND RESPONDTIME IS NULL");
Connection conn = Vault.getDbConnection();
try {
PreparedStatement stmt = conn.prepareStatement(update.toString());
stmt.setTimestamp(1, new Timestamp(time.getTime()));
stmt.setString(2, user);
stmt.executeUpdate();
stmt.close();
} finally {
Vault.releaseDbConnection(conn);
}
}
}
/**
* Convenience method for translating a <code>java.sql.ResultSet</code>
* containing notice information into an array of <code>Notification</code>
* objects.
*
* @param rs a {@link java.sql.ResultSet} object.
* @return an array of {@link org.opennms.web.notification.Notification} objects.
* @throws java.sql.SQLException if any.
*/
// FIXME: Don't use the single variable "element" for different objects. - dj@opennms.org
protected static Notification[] rs2Notices(ResultSet rs, ServletContext servletContext) throws SQLException {
Notification[] notices = null;
Vector<Notification> vector = new Vector<Notification>();
while (rs.next()) {
Notification notice = new Notification();
Object element = new Integer(rs.getInt("notifyid"));
notice.m_notifyID = ((Integer) element).intValue();
element = rs.getTimestamp("pagetime");
if (element != null) {
notice.m_timeSent = ((Timestamp) element).getTime();
}
element = rs.getTimestamp("respondtime");
if (element != null) {
notice.m_timeReply = ((Timestamp) element).getTime();
}
element = rs.getString("textmsg");
notice.m_txtMsg = (String) element;
element = rs.getString("numericmsg");
notice.m_numMsg = (String) element;
element = rs.getString("answeredby");
notice.m_responder = (String) element;
element = new Integer(rs.getInt("nodeid"));
notice.m_nodeID = ((Integer) element).intValue();
element = rs.getString("interfaceid");
notice.m_interfaceID = (String) element;
element = new Integer(rs.getInt("eventid"));
notice.m_eventId = ((Integer) element).intValue();
element = new Integer(rs.getInt("serviceid"));
if (element != null) {
notice.m_serviceId = ((Integer) element).intValue();
element = NetworkElementFactory.getInstance(servletContext).getServiceNameFromId(notice.m_serviceId);
notice.m_serviceName = (String) element;
}
vector.addElement(notice);
}
notices = new Notification[vector.size()];
for (int i = 0; i < notices.length; i++) {
notices[i] = vector.elementAt(i);
}
return notices;
}
}