/* * NOTE: This copyright does *not* 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 does *not* fall under the heading of * "derived work". * * Copyright (C) [2004-2009], 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.appdef.server.session; import java.sql.SQLException; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.hibernate.HibernateException; import org.hibernate.Query; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.criterion.Order; import org.hibernate.criterion.Restrictions; import org.hyperic.hibernate.PageInfo; import org.hyperic.hq.appdef.Agent; import org.hyperic.hq.appdef.AgentType; import org.hyperic.hq.common.shared.ServerConfigManager; import org.hyperic.hq.dao.HibernateDAO; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.orm.hibernate3.HibernateCallback; import org.springframework.orm.hibernate3.HibernateTemplate; import org.springframework.stereotype.Repository; @Repository public class AgentDAO extends HibernateDAO<Agent> { private static final Log log = LogFactory.getLog(AgentDAO.class); private static final String LIMIT_A_TO_CURRENT_AGENTS = "a.version >= :serverVersion "; private static final String LIMIT_A_TO_OLD_AGENTS = "a.version < :serverVersion "; private final Map<String, Integer> agentTokenToId = new HashMap<String, Integer>(); private final ServerConfigManager serverConfigManager; @Autowired public AgentDAO(SessionFactory f, ServerConfigManager serverConfigManager) { super(Agent.class, f); this.serverConfigManager = serverConfigManager; } @SuppressWarnings("unchecked") @PostConstruct public void preloadQueryCache() { new HibernateTemplate(sessionFactory, true).execute(new HibernateCallback() { public Object doInHibernate(Session session) throws HibernateException, SQLException { List<String> tokens = session.createQuery("select agentToken from Agent").list(); log.info("preloading Agent.findByAgentToken cache"); for(String token : tokens) { //HQ-2575 Preload findByAgentToken query cache to minimize DB connections when multiple agents //send measurement reports to a restarted server findByAgentToken(token, session); } // pre-fetch platforms bag to optimize ReportProcessor.handleMeasurementData log.info("preloading Agent.platforms bag"); String hql = "from Agent a left outer join fetch a.platforms"; session.createQuery(hql).list(); return null; } }); } @PreDestroy public void cleanup() { synchronized (agentTokenToId) { agentTokenToId.clear(); } } public Agent create(AgentType type, String address, Integer port, boolean unidirectional, String authToken, String agentToken, String version) { Agent ag = new Agent(type, address, port, unidirectional, authToken, agentToken, version); save(ag); return ag; } @Override @SuppressWarnings("unchecked") public List<Agent> findAll() { return getSession().createCriteria(Agent.class).addOrder(Order.asc("address")).addOrder( Order.asc("port")).list(); } @SuppressWarnings("unchecked") public List<Agent> findByIP(String ip) { String hql = "from Agent where address=:address"; return getSession().createQuery(hql) .setString("address", ip) .setCacheable(true) .setCacheRegion("Agent.findByIP") .list(); } public int countUsed() { return ((Number) getSession().createQuery( "select count(distinct a) from Platform p " + "join p.agent a").uniqueResult()) .intValue(); } public Agent findByIpAndPort(String address, int port) { String sql = "from Agent where address=? and port=?"; return (Agent) getSession().createQuery(sql).setString(0, address).setInteger(1, port) .uniqueResult(); } private Agent findByAgentToken(String token, Session session) { Integer agentId = null; synchronized (agentTokenToId) { agentId = agentTokenToId.get(token); } Agent rtn = (agentId != null) ? get(agentId) : null; if (rtn == null) { rtn = (Agent) session.createCriteria(Agent.class) .add(Restrictions.eq("agentToken", token)) .uniqueResult(); if (rtn != null) { agentId = rtn.getId(); synchronized (agentTokenToId) { agentTokenToId.put(token, rtn.getId()); } } } return rtn; } public Agent findByAgentToken(String token) { return findByAgentToken(token, getSession()); } @SuppressWarnings("unchecked") public List<Agent> findAgents(PageInfo pInfo) { final AgentSortField sort = (AgentSortField) pInfo.getSort(); final StringBuilder sql = new StringBuilder() .append("select distinct a from Platform p ") .append(" JOIN p.agent a") .append(" JOIN p.resource r") .append(" WHERE r.resourceType is not null") .append(" ORDER BY ").append(sort.getSortString("a")) .append((pInfo.isAscending() ? "" : " DESC")); // Secondary sort by CTime if (!sort.equals(AgentSortField.CTIME)) { sql.append(", ").append(AgentSortField.CTIME.getSortString("a")).append(" DESC"); } final Query q = getSession().createQuery(sql.toString()); return pInfo.pageResults(q).list(); } @SuppressWarnings("unchecked") public List<Agent> findOldAgents() { String sql = "from Agent a where " + LIMIT_A_TO_OLD_AGENTS; final Query query = getSession().createQuery(sql); query.setParameter("serverVersion", serverConfigManager.getServerMajorVersion()); return query.list(); } /** * Returns the agent's installation path * @param agentToken */ public String getAgentInstallationPath(String agentToken) { final StringBuilder sql = new StringBuilder() .append("select distinct s from Server s ") .append(" JOIN s.platform p") .append(" JOIN p.agent a") .append(" WHERE a.agentToken='" + agentToken + "' and s.description like '%Hyperic%Agent%'"); final Query q = getSession().createQuery(sql.toString()); try{ return ((Server)q.uniqueResult()).getInstallPath(); }catch (Exception e) { } return null; } /** * Get a list of all agents in the system, whose version is older than server's version and * which are actually used (e. have platforms) */ @SuppressWarnings("unchecked") public List<Agent> findOldAgentsUsed() { final String sql = new StringBuilder(150) .append("from Agent a where ") .append(LIMIT_A_TO_OLD_AGENTS) .append("and exists (select 1 from Platform p where p.agent.id = a.id)") .toString(); final Query query = getSession().createQuery(sql); query.setParameter("serverVersion", serverConfigManager.getServerMajorVersion()); return query.list(); } /** * Get a list of all agents in the system, whose version is equal to or newer than server's version and * which are actually used (e. have platforms) */ @SuppressWarnings("unchecked") public List<Agent> findUpToDateAgentsUsed() { final String sql = new StringBuilder(150) .append("from Agent a where ") .append(LIMIT_A_TO_CURRENT_AGENTS) .append("and exists (select 1 from Platform p where p.agent.id = a.id)") .toString(); final Query query = getSession().createQuery(sql); query.setParameter("serverVersion", serverConfigManager.getServerMajorVersion()); return query.list(); } /** * * @return number of agents, whose version is older than that of the server */ public long getNumOldAgents() { final String sql = "select count(a) from Agent a where " + LIMIT_A_TO_OLD_AGENTS; final Query query = getSession().createQuery(sql); query.setParameter("serverVersion", serverConfigManager.getServerMajorVersion()); return ((Number) query.uniqueResult()).longValue(); } public long getNumVersionUpToDateAgents() { final String sql = new StringBuilder(150) .append("select count(a) from Agent a where ") .append(LIMIT_A_TO_CURRENT_AGENTS) .append("and exists (select 1 from Platform p where p.agent.id = a.id)") .toString(); final Query query = getSession().createQuery(sql); query.setParameter("serverVersion", serverConfigManager.getServerMajorVersion()); return ((Number) query.uniqueResult()).longValue(); } /** * * @param agent * @return true if agent's version is older than that of the server */ public boolean isAgentOld(Agent agent) { String serverVersion = serverConfigManager.getServerMajorVersion(); return agent.getVersion().compareTo(serverVersion) < 0; } }