package net.sf.appstatus.batch;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import java.util.Vector;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import net.sf.appstatus.core.batch.IBatch;
import net.sf.appstatus.core.batch.IBatchManager;
import net.sf.appstatus.core.batch.IBatchProgressMonitor;
/**
* This implementation stores batch history and status in memory.
* <p>
* Can be used when batch is run within the same JVM as the console.
* <p>
* History is lost on restart.
*
* @author Nicolas Richeton
*
*/
public class InProcessBatchManager implements IBatchManager {
private static Logger logger = LoggerFactory.getLogger(InProcessBatchManager.class);
private List<IBatch> errorBatches = new Vector<IBatch>();
List<IBatch> finishedBatches = new Vector<IBatch>();
private int logInterval = 1000;
private long maxSize = 25;
List<IBatch> runningBatches = new Vector<IBatch>();
private int zombieInterval;
public IBatch addBatch(String name, String group, String uuid) {
// Add batch
IBatch b = new Batch(uuid, name, group);
((Batch) b).setZombieInterval(this.zombieInterval);
int currentPosition = runningBatches.indexOf(b);
if (currentPosition >= 0) {
// Reuse existing object (and keep monitor).
b = runningBatches.get(currentPosition);
} else {
// Add new batch
// initMonitor
getMonitor(b);
// runningBatches is not limited in size.
runningBatches.add(b);
}
return b;
}
protected void addTo(List<IBatch> l, IBatch b) {
// Ensure batch list does not exceed defined size
if (l.size() >= maxSize) {
l.remove(0);
}
l.add(b);
}
public void batchEnd(Batch batch) {
runningBatches.remove(batch);
addTo(finishedBatches, batch);
if (!batch.isSuccess()) {
addTo(errorBatches, batch);
}
}
public List<IBatch> getBatches(String group, String name) {
List<IBatch> result = new ArrayList<IBatch>();
for (IBatch b : runningBatches) {
if (StringUtils.equals(group, b.getGroup()) && StringUtils.equals(name, b.getName())) {
result.add(b);
}
}
for (IBatch b : finishedBatches) {
if (StringUtils.equals(group, b.getGroup()) && StringUtils.equals(name, b.getName())) {
result.add(b);
}
}
return result;
}
public Properties getConfiguration() {
return null;
}
public List<IBatch> getErrorBatches() {
return errorBatches;
}
public List<IBatch> getFinishedBatches() {
return finishedBatches;
}
public IBatchProgressMonitor getMonitor(IBatch batch) {
Batch b = (Batch) batch;
// If batch has no progress monitor, create one.
if (b.getProgressMonitor() == null) {
// Calling this method automatically call
// IBatch#setProgressMonitor()
InProcessBatchProgressMonitor pm = new InProcessBatchProgressMonitor(batch.getUuid(), batch, this);
pm.setWritingDelay(logInterval);
}
// Return current monitor.
return b.getProgressMonitor();
}
public List<IBatch> getRunningBatches() {
return runningBatches;
}
public void init() {
}
/*
* (non-Javadoc)
*
* @see net.sf.appstatus.core.batch.IBatchManager#removeAllBatches(int)
*/
public void removeAllBatches(int scope) {
if (finishedBatches == null || finishedBatches.size() == 0) {
// Nothing can be removed using scoped.
return;
}
ArrayList<IBatch> toRemove = new ArrayList<IBatch>();
switch (scope) {
case REMOVE_SUCCESS:
for (IBatch b : finishedBatches) {
if (b.isSuccess() && (b.getRejectedItemsId() == null || b.getRejectedItemsId().size() == 0)) {
toRemove.add(b);
}
}
break;
case REMOVE_OLD:
// Create reference date.
Calendar c = Calendar.getInstance();
c.add(Calendar.MONTH, -6);
Date thisIsOld = c.getTime();
for (IBatch b : finishedBatches) {
if (b.getLastUpdate().before(thisIsOld)) {
toRemove.add(b);
}
}
break;
}
// Remove all batches marked for deletion.
for (IBatch b : toRemove) {
removeBatch(b);
}
}
private void removeBatch(IBatch b) {
// Remove only finished jobs
if (!runningBatches.contains(b)) {
// remove from errorBatches
if (errorBatches.contains(b)) {
errorBatches.remove(b);
}
// Remove from finished batches.
if (finishedBatches.contains(b)) {
finishedBatches.remove(b);
}
}
}
/*
* (non-Javadoc)
*
* @see
* net.sf.appstatus.core.batch.IBatchManager#removeBatch(net.sf.appstatus
* .core.batch.IBatch)
*/
public void removeBatch(String uuid) {
Batch b = new Batch(uuid);
removeBatch(b);
}
public void setConfiguration(Properties configuration) {
try {
logInterval = Integer.parseInt(configuration.getProperty("batch.logInterval"));
} catch (NumberFormatException e) {
logInterval = 1000;
}
logger.info("Batch log interval: {}ms", logInterval);
try {
maxSize = Integer.parseInt(configuration.getProperty("batch.maxHistory"));
} catch (NumberFormatException e) {
maxSize = 25;
}
logger.info("Batch history size: {}", maxSize);
try {
zombieInterval = Integer.parseInt(configuration.getProperty("batch.zombieInterval"));
} catch (NumberFormatException e) {
zombieInterval = 1000 * 60 * 10;
}
logger.info("Zombie interval: {}", zombieInterval);
}
}