/** * Copyright 2014 Comcast Cable Communications Management, LLC * * This file is part of CATS. * * CATS 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. * * CATS 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 CATS. If not, see <http://www.gnu.org/licenses/>. */ package com.comcast.cats.reboot.service; import java.util.Date; import java.util.List; import javax.ejb.Stateless; import javax.persistence.EntityManager; import javax.persistence.NoResultException; import javax.persistence.PersistenceContext; import javax.persistence.Query; import javax.persistence.TypedQuery; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.comcast.cats.reboot.RebootDetectionCategory; import com.comcast.cats.reboot.RebootDetectionStatus; import com.comcast.cats.reboot.RebootHostStatus; import com.comcast.cats.reboot.model.Host; import com.comcast.cats.reboot.model.DetectionInfo; /** * This class manages the persistence operations surrounding reboot detection. * * @author cfrede001 * */ @Stateless public class RebootDetectionService { public static int MAX_REBOOT_DETECTION_RESULTS = 200; protected static Logger logger = LoggerFactory.getLogger( RebootDetectionService.class ); @PersistenceContext( name = "reboot-detection-pu" ) protected EntityManager em; public List< Host > getHosts( RebootHostStatus status ) { List< Host > responseList = null; logger.trace( "getHosts()" ); try { TypedQuery< Host > query = em.createQuery( "SELECT h FROM Host h WHERE h.status = :status", Host.class ); query.setParameter( "status", status ); responseList = query.getResultList(); } catch ( NoResultException e ) { logger.warn( "No Hosts Found: {}", e ); } return responseList; } public List< Host > getEnabledHosts() { return getHosts( RebootHostStatus.ENABLED ); } public List< DetectionInfo > getDetectionInfo( String mac ) { return getDetectionInfo( mac, 0, MAX_REBOOT_DETECTION_RESULTS ); } public List< DetectionInfo > getDetectionInfo( String mac, Integer offset, Integer count ) { List< DetectionInfo > detections = null; try { TypedQuery< DetectionInfo > query = em .createNamedQuery( "DetectionInfo.FindByHostMac", DetectionInfo.class ); query.setParameter( "macAddress", mac ); query.setFirstResult( offset ); query.setMaxResults( count ); detections = query.getResultList(); } catch ( NoResultException e ) {} return detections; } /** * Retrieve the current RebootDetectionCount for a given host. * * @param mac * @return */ public Integer getRebootDetectionCount( String mac ) { try { Query query = em.createNamedQuery( "DetectionInfo.CountByHostMac" ); query.setParameter( "macAddress", mac ); query.setMaxResults( 1 ); Long count = ( Long ) query.getSingleResult(); return count.intValue(); } catch ( NoResultException e ) {} return -1; } public void delete( DetectionInfo detection ) { em.remove( detection ); } public DetectionInfo getLastDetectionInfo( String mac ) { DetectionInfo detection = null; try { Query query = em.createNamedQuery( "DetectionInfo.FindByHostMac" ); query.setParameter( "macAddress", mac ); query.setMaxResults( 1 ); detection = ( DetectionInfo ) query.getSingleResult(); } catch ( NoResultException e ) {} return detection; } public void processUptime( Host host, Long uptime, RebootDetectionStatus status ) { DetectionInfo info = new DetectionInfo(); info.setCategory( RebootDetectionCategory.SNMP ); info.setHost( host ); info.setExecutionDate( new Date() ); // Problem with request, what is the status. Long lastUptime = host.getUptime(); if ( uptime < 0 ) { // Use incoming status that code reflect potential errors. info.setStatus( status ); /* * Host uptime should not be set, since it must reflect the last * valid value. */ } else if ( uptime <= lastUptime ) { info.setStatus( RebootDetectionStatus.REBOOT_DETECTED ); host.setLastModified( new Date() ); host.setUptime( uptime ); } else { /* * If uptime is > than previous uptime then it was a successful * request. */ host.setLastModified( new Date() ); host.setUptime( uptime ); info.setStatus( RebootDetectionStatus.SUCCESSFUL_REQUEST ); } info.setUpTime( uptime ); logger.trace( "Updating the Host" ); process( host, info ); } public void process( Host host, DetectionInfo info ) { logger.trace( "process({}, {})", host, info ); info.setHost( host ); // Reboot has been detected, save to database. if ( info.getStatus() == RebootDetectionStatus.REBOOT_DETECTED ) { logger.trace( "Save Reboot[{}]", info.toString() ); } else { // Find the most current RebootDetection Information. DetectionInfo last = getLastDetectionInfo( host.getMacAddress() ); if ( last != null && last.getStatus().equals( info.getStatus() ) ) { logger.trace( "Delete last[{}]", last.toString() ); delete( last ); } // Always save the most recent detection information. logger.trace( "Save Info[{}]", info.toString() ); } update( host ); em.persist( info ); } public void delete( String mac ) { Host h = getHostByMac( mac ); if ( h != null ) { em.remove( h ); } } public Host update( Host h ) { return em.merge( h ); } /** * Handle host information based on the provided information. * * @param mac * @param ip * @param ecm * @param status * @return */ public Host saveOrUpdate( String mac, String ip, String ecm, RebootHostStatus status ) { Host host = getHostByMac( mac ); if ( host == null ) { host = new Host( mac, ip, ecm, status ); em.persist( host ); } else { host.setIpAddress( ip ); host.setEcm( ecm ); host.setStatus( status ); // Update are host entry. em.merge( host ); } return host; } /** * Retrieve the host by a given mac address. * * @param mac * @return */ public Host getHostByMac( String mac ) { Host host = null; try { Query query = em.createNamedQuery( "Host.FindByMac" ); query.setParameter( "macAddress", mac ); host = ( Host ) query.getSingleResult(); } catch ( NoResultException e ) {} return host; } }