/* * NOTE: This copyright doesnot cover user programs that use HQ program services * by normal system calls through the application program interfaces provided as * part of the Hyperic Plug-in Development Kit or the Hyperic Client Development * Kit - this is merely considered normal use of the program, and doesnot fall * under the heading of "derived work". Copyright (C) [2004-2008], Hyperic, Inc. * This file is part of HQ. HQ is free software; you can redistribute it and/or * modify it under the terms version 2 of the GNU General Public License as * published by the Free Software Foundation. This program 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 this program; if not, write * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA * 02111-1307 USA. */ package org.hyperic.hq.events.server.session; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.hibernate.Query; import org.hibernate.SessionFactory; import org.hibernate.type.IntegerType; import org.hyperic.hq.dao.HibernateDAO; import org.hyperic.hq.events.shared.RegisteredTriggerValue; import org.hyperic.util.timer.StopWatch; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; @Repository public class TriggerDAO extends HibernateDAO<RegisteredTrigger> implements TriggerDAOInterface { private final Log log = LogFactory.getLog(TriggerDAO.class); @Autowired public TriggerDAO(SessionFactory sessionFactory) { super(RegisteredTrigger.class, sessionFactory); } public RegisteredTrigger create(RegisteredTriggerValue createInfo) { RegisteredTrigger res = new RegisteredTrigger(createInfo); save(res); // Set the new ID just in case someone wants to use it createInfo.setId(res.getId()); return res; } public RegisteredTrigger findById(Integer id) { return (RegisteredTrigger) super.findById(id); } public RegisteredTrigger get(Integer id) { return (RegisteredTrigger) super.get(id); } /** * Find all the registered triggers associated with the alert definition. * * @param id The alert definition id. * @return The list of associated registered triggers. */ @SuppressWarnings("unchecked") public List<RegisteredTrigger> findByAlertDefinitionId(Integer id) { String sql = "from RegisteredTrigger rt where rt.alertDefinition.id = :defId"; return getSession().createQuery(sql).setParameter("defId", id).list(); } /** * Find all the registered trigger ids associated with the alert definition ids. * * @param alertDefIds The alert definition ids. * @return {@link Map} of alert definition id {@link Integer} * to {@link List} of trigger id {@link Integer} */ @SuppressWarnings("unchecked") public Map<Integer,List<Integer>> findTriggerIdsByAlertDefinitionIds(List<Integer> alertDefIds) { if (alertDefIds.isEmpty()) { return new HashMap<Integer,List<Integer>>(0,1); } final boolean debug = log.isDebugEnabled(); StopWatch watch = new StopWatch(); final String sql = new StringBuilder() .append("SELECT T.ALERT_DEFINITION_ID AS ALERT_DEF_ID, ") .append("T.ID AS TRIGGER_ID ") .append("FROM EAM_REGISTERED_TRIGGER T ") .append("WHERE T.ALERT_DEFINITION_ID IN (:alertDefIds) ") .toString(); Query query = getSession().createSQLQuery(sql) .addScalar("ALERT_DEF_ID", new IntegerType()) .addScalar("TRIGGER_ID", new IntegerType()); List<Object[]> triggers = new ArrayList<Object[]>(alertDefIds.size()); int batchSize = 1000; if (debug) watch.markTimeBegin("createQuery.list"); for (int i=0; i<alertDefIds.size(); i+=batchSize) { int end = Math.min(i+batchSize, alertDefIds.size()); List<Integer> list = alertDefIds.subList(i, end); query.setParameterList("alertDefIds", list, new IntegerType()); triggers.addAll(query.list()); } if (debug) watch.markTimeEnd("createQuery.list"); Map<Integer,List<Integer>> alertDefTriggerMap = new HashMap<Integer,List<Integer>>(alertDefIds.size()); if (debug) watch.markTimeBegin("buildMap"); for (Object[] o : triggers) { Integer alertDefId = (Integer) o[0]; Integer triggerId = (Integer) o[1]; List<Integer> trigList = alertDefTriggerMap.get(alertDefId); if (trigList == null) { trigList = new ArrayList<Integer>(); alertDefTriggerMap.put(alertDefId, trigList); } trigList.add(triggerId); } if (debug) { watch.markTimeEnd("buildMap"); log.debug("findTriggerIdsByAlertDefinitionIds: " + watch + ", alert definition ids size=" + alertDefIds.size() + ", trigger ids size=" + triggers.size() + ", map size=" + alertDefTriggerMap.size()); } return alertDefTriggerMap; } @SuppressWarnings("unchecked") public Set<RegisteredTrigger> findAllEnabledTriggers() { final boolean debug = log.isDebugEnabled(); StopWatch watch = new StopWatch(); // For performance optimization, we want to fetch each trigger's alert // def as well as the alert def's alert definition state and conditions // in a single query (as they will be used to create // AlertConditionEvaluators when creating trigger impls). This query // guarantees that when we do trigger.getAlertDefinition().getConditions(), // the database is not hit again String hql = new StringBuilder(256) .append("from AlertDefinition ad ") .append("join fetch ad.alertDefinitionState ") .append("join fetch ad.conditionsBag c ") .append("join fetch c.trigger ") .append("where ad.enabled = '1'") .append("and ad.deleted = '0' ") .toString(); if (debug) watch.markTimeBegin("createQuery.list"); List<AlertDefinition> alertDefs = getSession().createQuery(hql).list(); if (debug) watch.markTimeEnd("createQuery.list"); Set<RegisteredTrigger> triggers = new LinkedHashSet<RegisteredTrigger>(); if (debug) watch.markTimeBegin("addTriggers"); for(AlertDefinition definition : alertDefs) { for(AlertCondition condition: definition.getConditionsBag()) { triggers.add(condition.getTrigger()); } } if (debug) { watch.markTimeEnd("addTriggers"); log.debug("findAllEnabledTriggers: " + watch); } return triggers; } }