/** * Copyright (C) 2008-2010, Squale Project - http://www.squale.org * * This file is part of Squale. * * Squale is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of the * License, or any later version. * * Squale 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 Lesser General Public License * along with Squale. If not, see <http://www.gnu.org/licenses/>. */ /* * Created on 3 ao�t 06 * */ package org.squale.squalix.core.purge; import java.io.FileInputStream; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.squale.jraf.commons.exception.JrafDaoException; import org.squale.jraf.commons.exception.JrafPersistenceException; import org.squale.jraf.helper.PersistenceHelper; import org.squale.jraf.spi.persistence.ISession; import org.squale.squalecommon.daolayer.component.ApplicationDAOImpl; import org.squale.squalecommon.daolayer.component.AuditDAOImpl; import org.squale.squalecommon.daolayer.component.ProjectDAOImpl; import org.squale.squalecommon.daolayer.config.web.AbstractDisplayConfDAOImpl; import org.squale.squalecommon.enterpriselayer.businessobject.component.ApplicationBO; import org.squale.squalecommon.enterpriselayer.businessobject.component.AuditBO; import org.squale.squalecommon.enterpriselayer.businessobject.component.ProjectBO; import org.squale.squalix.core.CoreMessages; /** * Thread s�par�e de purge * @author M401540 */ public class Purge extends Thread { /** * Logger */ private static final Log LOGGER = LogFactory.getLog( Purge.class ); /** * Site */ private long mSiteId; /** * La liste des applications qui vont �tre audit�es en m�me temps que la purge. Pour �viter d'avoir des croisements * de session, on ne va pas purger les audits qui rattach� � une de ces applications */ private Set mForbiddenApplis = new HashSet(); /** * Fichier de configuration de la purge. */ private final String mPurgeConfigFile = "config/purge.xml"; /** * Analyseur de fichier de configuration de la purge d'audits. */ private final PurgeConfParser mPurgeConfParser = new PurgeConfParser(); /** * Constructeur * * @param pSiteId site de lancement * @param pRunningAudits les audits qui vont �tre lanc�s */ public Purge( long pSiteId, List pRunningAudits ) { mSiteId = pSiteId; configPurge(); setForbiddenApplis( pRunningAudits ); } /** * Lance le Thread de purge des applications et des audits */ public void run() { try { // ouvre une session Hibernate ISession session = PersistenceHelper.getPersistenceProvider().getSession(); // purge des audits supprim�s ou obsol�tes � supprimer purgeAudits( session ); // On va purger les configurations d'affichage qui ne servent plus // i.e. qui ne sont plus rattach�es ni � un audit, ni a un profil session.beginTransaction(); AbstractDisplayConfDAOImpl.getInstance().removeUnusedConf( session ); session.commitTransactionWithoutClose(); // Apr�s les audits, on va supprimer les projets... session.beginTransaction(); Collection projects = ProjectDAOImpl.getInstance().findWhereStatusAndSite( session, ProjectBO.DELETED, mSiteId ); Iterator it = projects.iterator(); LOGGER.info( CoreMessages.getString( "projects.todelete", new Object[] { new Integer( projects.size() ) } ) ); session.commitTransactionWithoutClose(); while ( it.hasNext() ) { ProjectBO p = (ProjectBO) it.next(); // supresion physique comme pour les audits // Commit un par un pour des raisons de perf session.beginTransaction(); ProjectDAOImpl.getInstance().remove( session, (Object) p ); session.commitTransactionWithoutClose(); } // maintenant que tous les audits sont supprim�s, on peut supprimer les applis... session.beginTransaction(); it = ApplicationDAOImpl.getInstance().findWhereStatus( session, ApplicationBO.DELETED ).iterator(); session.commitTransactionWithoutClose(); while ( it.hasNext() ) { ApplicationBO a = (ApplicationBO) it.next(); // du site if ( a.getServeurBO() == null || a.getServeurBO().getServeurId() == mSiteId ) { // supresion physique comme pour les audits // Commit un par un pour des raisons de perf session.beginTransaction(); ApplicationDAOImpl.getInstance().remove( session, (Object) a ); session.commitTransactionWithoutClose(); } } // ferme la session session.closeSession(); } catch ( JrafPersistenceException e ) { LOGGER.error( e, e ); } catch ( JrafDaoException e ) { LOGGER.error( e, e ); } } /** * Purge les audits supprim�s ou obsol�tes au regard de la fr�quence de purge de l'application. <br /> * Pour les audits de jalon, seuls les audits en �chec sont supprim�s. <br /> * Pour les audits de suivi, un minimum d'audits obsol�tes sont conserv�s pour historique (selon configuration). * <br /> * Un maximum donn� d'audits sont supprim�s (selon configuration). Pr�-condition : la liste des audits est tri�e par * date d�croissante. * * @param pSession session de persistence. * @throws JrafDaoException si exception de persistence. */ private void purgeAudits( ISession pSession ) throws JrafDaoException { int lNbAuditsDeleted = 0; // suppression des audits supprim�s qui n'appartiennent pas � une application // audit�e dans un thread parall�le Iterator it = AuditDAOImpl.getInstance().findDeleted( pSession, mSiteId, mForbiddenApplis ).iterator(); while ( it.hasNext() && lNbAuditsDeleted < mPurgeConfParser.getMaxAuditsToDelete().intValue() ) { AuditBO a = (AuditBO) it.next(); // Commit un par un pour des raisons de perf/charge purgeOneAudit( pSession, a ); lNbAuditsDeleted++; LOGGER.info( CoreMessages.getString( "purge.info.deleted", new Object[] { new Long( a.getId() ) } ) ); } // traitement des audits obsol�tes � supprimer List lAuditsList = AuditDAOImpl.getInstance().findObsoleteAuditsToDelete( pSession, mSiteId, mForbiddenApplis ); List lAuditsToDelete = new ArrayList(); List lTreatedApplicationsList = new ArrayList(); it = lAuditsList.iterator(); // les derniers audits obsol�tes de suivi d'une application sont conserv�s while ( it.hasNext() ) { Object[] lListItem = (Object[]) it.next(); AuditBO lAuditBO = (AuditBO) lListItem[0]; ApplicationBO lApplicationBO = (ApplicationBO) lListItem[1]; if ( !lTreatedApplicationsList.contains( new Long( lApplicationBO.getId() ) ) ) { // copie des audits obsol�tes de suivi � ne pas conserver Iterator it2 = lAuditsList.iterator(); int lNbAuditsKept = 0; while ( it2.hasNext() ) { Object[] lListItem2 = (Object[]) it2.next(); AuditBO lAuditBO2 = (AuditBO) lListItem2[0]; ApplicationBO lApplicationBO2 = (ApplicationBO) lListItem2[1]; if ( lApplicationBO.getId() == lApplicationBO2.getId() ) { if ( lAuditBO2.getType().equals( AuditBO.NORMAL ) && lNbAuditsKept < mPurgeConfParser.getMinObsoleteAuditsToKeep().intValue() ) { lNbAuditsKept++; } else { lAuditsToDelete.add( lAuditBO2 ); } } } // les audits de l'application ont �t� trait�s lTreatedApplicationsList.add( new Long( lApplicationBO.getId() ) ); } } // suppression des audits obsol�tes � supprimer (ordre chronologique) final int lNbAuditsToDelete = lAuditsToDelete.size(); int i = lNbAuditsToDelete - 1; while ( i >= 0 && lNbAuditsDeleted < mPurgeConfParser.getMaxAuditsToDelete().intValue() ) { AuditBO lAuditBO = (AuditBO) lAuditsToDelete.get( i ); purgeOneAudit( pSession, lAuditBO ); lNbAuditsDeleted++; i--; LOGGER.info( CoreMessages.getString( "purge.info.obsolete", new Object[] { new Long( lAuditBO.getId() ) } ) ); } } /** * Supprime un audit. * * @param pSession session de persistence. * @param pAuditBO audit � supprimer. * @throws JrafDaoException exception de persistence. */ private void purgeOneAudit( ISession pSession, AuditBO pAuditBO ) throws JrafDaoException { // supprime vraiment l'audit (et tous le reste avec le delete cascade) // en appelant la methode remove Object (et no AuditBO qui ne realise // que le delete logique pSession.beginTransaction(); AuditDAOImpl.getInstance().remove( pSession, (Object) pAuditBO ); pSession.commitTransactionWithoutClose(); } /** * Configure la purge. */ private void configPurge() { try { mPurgeConfParser.parse( new FileInputStream( mPurgeConfigFile ) ); // suppression de la contrainte de maximum d'audits if ( mPurgeConfParser.getMaxAuditsToDelete().intValue() < 0 ) { mPurgeConfParser.setMaxAuditsToDelete( new Integer( Integer.MAX_VALUE ) ); } } catch ( Exception e ) { // r�-initialisation de la configuration de purge mPurgeConfParser.setMinObsoleteAuditsToKeep( new Integer( 0 ) ); mPurgeConfParser.setMaxAuditsToDelete( new Integer( 0 ) ); LOGGER.error( CoreMessages.getString( "purge.config.error.1" ) ); LOGGER.error( CoreMessages.getString( "purge.config.error.2" ) ); } } /** * Cr�er l'ensemble des ids des applications audit�es en m�me temps que la purge * * @param pRunningAudits les audits qui peuvent �tre audit�s en m�me temps que la purge */ private void setForbiddenApplis( List pRunningAudits ) { try { // ouvre une session Hibernate ISession session = PersistenceHelper.getPersistenceProvider().getSession(); ApplicationBO curAppli; AuditBO curAudit; for ( int i = 0; i < pRunningAudits.size(); i++ ) { curAudit = (AuditBO) pRunningAudits.get( i ); curAppli = ApplicationDAOImpl.getInstance().loadByAuditId( session, new Long( curAudit.getId() ) ); // On ajoute son id au set mForbiddenApplis.add( new Long( curAppli.getId() ) ); } // ferme la session session.closeSession(); } catch ( JrafPersistenceException e ) { LOGGER.error( e, e ); } catch ( JrafDaoException e ) { LOGGER.error( e, e ); } } }