package org.subethamail.core.admin;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import javax.ejb.Schedule;
import javax.ejb.Singleton;
import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.inject.Inject;
import javax.inject.Named;
import lombok.extern.java.Log;
import org.subethamail.core.util.SubEtha;
import org.subethamail.core.util.SubEthaEntityManager;
import org.subethamail.entity.Mail;
import org.subethamail.entity.Subscription;
import org.subethamail.entity.SubscriptionHold;
import com.caucho.resources.ScheduledTask;
/**
* Performs cleanup operations by pruning (old) held messages and subscriptions.
*
* This is scheduled (by a {@link ScheduledTask}) daily.
*
* @author Jeff Schnitzer
* @author Scott Hernandez
*/
@Named("cleanup")
@Singleton
@TransactionAttribute(TransactionAttributeType.REQUIRED)
@Stateless
@Log
public class CleanupBean
{
/** Keep held subscriptions around for 30 days */
public static final long MAX_HELD_SUB_AGE_MILLIS = 1000L * 60L * 60L * 24L * 30L;
/** Keep held messages around for 7 days */
public static final long MAX_HELD_MSG_AGE_MILLIS = 1000L * 60L * 60L * 24L * 7L;
private static volatile boolean isRunning = false;
/** */
@Inject @SubEtha SubEthaEntityManager em;
/**
* Cleans up held {@link Subscription}s and {@link Mail}
**/
@Schedule(minute="*/15", hour="*")
public void cleanup()
{
log.log(Level.FINE,"Starting cleanup");
log.log(Level.FINE,"em is {0}", this.em);
try
{
if(!isRunning)
{
isRunning = true;
this.cleanupHeldSubscriptions();
this.cleanupHeldMail();
}
else
{
log.warning("Attempted to start cleanup while one is already running; skipping cleanup.");
}
}
finally
{
isRunning = false;
}
}
/**
* Purges old subscription holds.
*/
protected void cleanupHeldSubscriptions()
{
Date cutoff = new Date(System.currentTimeMillis() - MAX_HELD_SUB_AGE_MILLIS);
log.log(Level.FINE,"Purging held subscriptions older than {0}", cutoff);
int count = 0;
List<SubscriptionHold> holds = this.em.findHeldSubscriptionsOlderThan(cutoff);
for (SubscriptionHold hold: holds)
{
log.log(Level.FINE,"Deleting obsolete hold: {0}", hold);
this.em.remove(hold);
count++;
}
if (count > 0)
log.log(Level.INFO,"{0} obsolete subscription holds removed with cutoff: {1}", new Object[]{count, cutoff});
}
/**
* Purges old held messages.
*/
protected void cleanupHeldMail()
{
Date cutoff = new Date(System.currentTimeMillis() - MAX_HELD_MSG_AGE_MILLIS);
log.log(Level.FINE,"Purging held mail older than {0}", cutoff);
int count = 0;
List<Mail> holds = this.em.findHeldMailOlderThan(cutoff);
for (Mail hold: holds)
{
log.log(Level.FINE,"Deleting obsolete hold: {0}", hold);
this.em.remove(hold);
count++;
}
if (count > 0)
log.log(Level.INFO,"{0} obsolete message holds removed", count);
}
}