blob: 12de3040d8f4298beaa84ff20be0b1cab13f48ea [file] [log] [blame]
/*
* Copyright (C) 2011 The University of Manchester
*
* See the file "LICENSE" for license terms.
*/
package org.taverna.server.master.usage;
import static org.apache.commons.logging.LogFactory.getLog;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.annotation.PreDestroy;
import javax.xml.bind.JAXBException;
import org.apache.commons.logging.Log;
import org.ogf.usage.JobUsageRecord;
import org.springframework.beans.factory.annotation.Required;
import org.taverna.server.master.api.ManagementModel;
import org.taverna.server.master.utils.Contextualizer;
import org.taverna.server.master.utils.JDOSupport;
/**
* A simple state-aware writer of usage records. It just appends them, one by
* one, to the file whose name is stored in the state.
*
* @author Donal Fellows
*/
public class UsageRecordRecorder extends JDOSupport<UsageRecord> {
private Log log = getLog("Taverna.Server.Webapp");
public UsageRecordRecorder() {
super(UsageRecord.class);
}
private String logFile = null;
private boolean disableDB = false;
private ManagementModel state;
private Contextualizer contextualizer;
private String logDestination;
private PrintWriter writer;
private Object lock = new Object();
private UsageRecordRecorder self;
/**
* @param state
* the state to set
*/
@Required
public void setState(ManagementModel state) {
this.state = state;
}
@Required
public void setSelf(UsageRecordRecorder self) {
this.self = self;
}
public void setLogFile(String logFile) {
this.logFile = (logFile == null || logFile.equals("none")) ? null : logFile;
}
public void setDisableDB(String disable) {
disableDB = "yes".equalsIgnoreCase(disable);
}
/**
* @param contextualizer
* the system's contextualizer, used to allow making the UR dump
* file be placed relative to the webapp.
*/
@Required
public void setContextualizer(Contextualizer contextualizer) {
this.contextualizer = contextualizer;
}
/**
* Accept a usage record for recording.
*
* @param usageRecord
* The serialized usage record to record.
*/
public void storeUsageRecord(String usageRecord) {
String logfile = state.getUsageRecordLogFile();
if (logfile == null)
logfile = this.logFile;
if (logfile != null) {
logfile = contextualizer.contextualize(logfile);
synchronized (lock) {
if (!logfile.equals(logDestination)) {
if (writer != null) {
writer.close();
writer = null;
}
try {
writer = new PrintWriter(new FileWriter(logfile));
logDestination = logfile;
} catch (IOException e) {
log.warn("failed to open usage record log file", e);
}
}
if (writer != null) {
writer.println(usageRecord);
writer.flush();
}
}
}
if (!disableDB)
saveURtoDB(usageRecord);
}
/**
* How to save a usage record to the database.
*
* @param usageRecord
* The serialized usage record to save.
*/
protected void saveURtoDB(String usageRecord) {
UsageRecord ur;
try {
ur = new UsageRecord(usageRecord);
} catch (JAXBException e) {
log.warn("failed to deserialize usage record", e);
return;
}
try {
self.saveURtoDB(ur);
} catch (RuntimeException e) {
log.warn("failed to save UR to database", e);
}
}
@WithinSingleTransaction
public void saveURtoDB(UsageRecord ur) {
persist(ur);
}
@WithinSingleTransaction
public List<JobUsageRecord> getUsageRecords() {
@SuppressWarnings("unchecked")
Collection<String> urs = (Collection<String>) namedQuery("allByDate")
.execute();
List<JobUsageRecord> result = new ArrayList<>();
for (String ur : urs)
try {
result.add(JobUsageRecord.unmarshal(ur));
} catch (JAXBException e) {
log.warn("failed to unmarshal UR", e);
}
return result;
}
@PreDestroy
public void close() {
if (writer != null)
writer.close();
}
}