/*
* RHQ Management Platform
* Copyright (C) 2005-2014 Red Hat, Inc.
* All rights reserved.
*
* This program 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 version 2 of the License.
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
package org.rhq.enterprise.server.purge;
import javax.annotation.Resource;
import javax.ejb.Stateless;
import javax.ejb.TransactionManagement;
import javax.ejb.TransactionManagementType;
import javax.sql.DataSource;
import javax.transaction.UserTransaction;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.rhq.enterprise.server.RHQConstants;
import org.rhq.enterprise.server.measurement.instrumentation.MeasurementMonitor;
/**
* A manager for purge. It's mostly used from the {@link org.rhq.enterprise.server.scheduler.jobs.DataPurgeJob}.<br>
* <br>
* Purge operations should happen in (relatively) small, transaction-bounded chunks. This is to avoid transaction
* timeouts as a single delete query might fully lock a table for quite some time, thus preventing data coming from
* agent reports from being inserted.
*
* @author Thomas Segismont
*/
@Stateless
@TransactionManagement(TransactionManagementType.BEAN)
public class PurgeManagerBean implements PurgeManagerLocal {
private static final Log LOG = LogFactory.getLog(PurgeManagerBean.class);
@Resource(name = "RHQ_DS", mappedName = RHQConstants.DATASOURCE_JNDI_NAME)
private DataSource dataSource;
@Resource
private UserTransaction userTransaction;
@Override
public int purgeAvailabilities(long oldest) {
AvailabilityPurge availabilityPurge = new AvailabilityPurge(dataSource, userTransaction, oldest);
long startTime = System.currentTimeMillis();
int deleted = availabilityPurge.execute();
MeasurementMonitor.getMBean().incrementPurgeTime(System.currentTimeMillis() - startTime);
MeasurementMonitor.getMBean().setPurgedAvailabilities(deleted);
return deleted;
}
@Override
public int purgeTraits(long oldest) {
MeasurementDataTraitPurge traitPurge = new MeasurementDataTraitPurge(dataSource, userTransaction, oldest);
long startTime = System.currentTimeMillis();
int deleted = traitPurge.execute();
MeasurementMonitor.getMBean().incrementPurgeTime(System.currentTimeMillis() - startTime);
MeasurementMonitor.getMBean().setPurgedMeasurementTraits(deleted);
return deleted;
}
@Override
public int purgeEventData(long deleteUpToTime) {
EventDataPurge eventDataPurge = new EventDataPurge(dataSource, userTransaction, deleteUpToTime);
long startTime = System.currentTimeMillis();
int deleted = eventDataPurge.execute();
MeasurementMonitor.getMBean().incrementPurgeTime(System.currentTimeMillis() - startTime);
MeasurementMonitor.getMBean().setPurgedEvents(deleted);
return deleted;
}
@Override
public int purgeCallTimeData(long deleteUpToTime) {
// NOTE: We do not purge unreferenced rows from RHQ_CALLTIME_DATA_KEY, because this can cause issues
// (see http://jira.jboss.com/jira/browse/JBNADM-1606). Once we limit the number of keys per
// resource at insertion time (see http://jira.jboss.com/jira/browse/JBNADM-2618), the key
// table will not require truncation.
CallTimeDataValuePurge callTimeDataValuePurge = new CallTimeDataValuePurge(dataSource, userTransaction,
deleteUpToTime);
long startTime = System.currentTimeMillis();
int deletedRowCount = callTimeDataValuePurge.execute();
MeasurementMonitor.getMBean().incrementPurgeTime(System.currentTimeMillis() - startTime);
MeasurementMonitor.getMBean().setPurgedCallTimeData(deletedRowCount);
return deletedRowCount;
}
@Override
public int deleteAlerts(long beginTime, long endTime) {
long totalTime = 0;
AlertConditionLogPurge conditionLogPurge = new AlertConditionLogPurge(dataSource, userTransaction, beginTime,
endTime);
long start = System.currentTimeMillis();
int conditionsDeleted = conditionLogPurge.execute();
long end = System.currentTimeMillis();
if (LOG.isDebugEnabled()) {
LOG.debug("Deleted [" + conditionsDeleted + "] alert condition logs in [" + (end - start) + "]ms");
}
totalTime += (end - start);
AlertNotificationLogPurge notificationLogPurge = new AlertNotificationLogPurge(dataSource, userTransaction,
beginTime, endTime);
start = System.currentTimeMillis();
int deletedNotifications = notificationLogPurge.execute();
end = System.currentTimeMillis();
if (LOG.isDebugEnabled()) {
LOG.debug("Deleted [" + deletedNotifications + "] alert notifications in [" + (end - start) + "]ms");
}
totalTime += (end - start);
AlertPurge alertPurge = new AlertPurge(dataSource, userTransaction, beginTime, endTime);
start = System.currentTimeMillis();
int deletedAlerts = alertPurge.execute();
end = System.currentTimeMillis();
if (LOG.isDebugEnabled()) {
LOG.debug("Deleted [" + deletedAlerts + "] alerts in [" + (end - start) + "]ms");
}
totalTime += (end - start);
MeasurementMonitor.getMBean().incrementPurgeTime(totalTime);
MeasurementMonitor.getMBean().setPurgedAlerts(deletedAlerts);
MeasurementMonitor.getMBean().setPurgedAlertConditions(conditionsDeleted);
MeasurementMonitor.getMBean().setPurgedAlertNotifications(deletedNotifications);
if (LOG.isDebugEnabled()) {
LOG.debug("Deleted [" + (deletedAlerts + conditionsDeleted + deletedNotifications) + "] "
+ "alert audit records in [" + (totalTime) + "]ms");
}
return deletedAlerts;
}
@Override
public void removeOutdatedOOBs(long cutoffTime) {
MeasurementOOBPurge measurementOOBPurge = new MeasurementOOBPurge(dataSource, userTransaction, cutoffTime);
int count = measurementOOBPurge.execute();
LOG.info("Removed [" + count + "] outdated OOBs");
}
@Override
public int purgeOrphanedBundleResourceDeploymentHistory() {
BundleResourceDeploymentHistoryPurge purge = new BundleResourceDeploymentHistoryPurge(dataSource,
userTransaction);
return purge.execute();
}
@Override
public int purgeOrphanedDriftFilesInDatabase(long purgeMillis) {
JPADriftFilePurge purge = new JPADriftFilePurge(dataSource, userTransaction, purgeMillis);
return purge.execute();
}
@Override
public int purgePartitionEvents(long deleteUpToTime) {
PartitionEventDetailsPurge detailsPurge = new PartitionEventDetailsPurge(dataSource, userTransaction,
deleteUpToTime);
detailsPurge.execute();
PartitionEventPurge eventPurge = new PartitionEventPurge(dataSource, userTransaction, deleteUpToTime);
return eventPurge.execute();
}
@Override
public int purgeResourceConfigHistory(long deleteUpToTime) {
int purged = 0;
purged += new ResourceConfigurationUpdatePurge(dataSource, userTransaction, deleteUpToTime).execute();
// ResourceConfigurationUpdateFromGroupPurge needs to be executed before GroupResourceConfigurationUpdatePurge
purged += new ResourceConfigurationUpdateFromGroupPurge(dataSource, userTransaction, deleteUpToTime).execute();
purged += new GroupResourceConfigurationUpdatePurge(dataSource, userTransaction, deleteUpToTime).execute();
return purged;
}
}