package com.rayo.server;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import com.rayo.server.cdr.CdrErrorHandler;
import com.rayo.server.cdr.CdrListener;
import com.rayo.server.cdr.CdrStorageStrategy;
import com.rayo.core.cdr.Cdr;
import com.voxeo.logging.Loggerf;
import com.voxeo.moho.Call;
public class CdrManager {
private static final Loggerf logger = Loggerf.getLogger(CdrManager.class);
private CdrErrorHandler errorHandler;
private List<CdrStorageStrategy> storageStrategies = new ArrayList<CdrStorageStrategy>();
private Map<String, Cdr> cdrs = new ConcurrentHashMap<String, Cdr>();
private List<CdrListener> listeners = new ArrayList<CdrListener>();
private Comparator<Cdr> comparator = new Comparator<Cdr>() {
public int compare(Cdr cdr1, Cdr cdr2) {
// Note this comparator will show active cdrs from the most recent cdr to the oldest cdr
return (int)(cdr2.getStartTime() - cdr1.getStartTime());
};
};
public Cdr create(Call call) {
if (logger.isDebugEnabled()) {
logger.debug("Creating CDR for call id [%s]", call.getId());
}
Cdr cdr = new Cdr();
cdr.setStartTime(System.currentTimeMillis());
cdr.setCallId(call.getId());
if (call.getInvitor() != null && call.getInvitor().getURI() != null) {
cdr.setFrom(call.getInvitor().getURI().toString());
}
if (call.getInvitee() != null && call.getInvitee().getURI() != null) {
cdr.setTo(call.getInvitee().getURI().toString());
}
cdrs.put(call.getId(),cdr);
return cdr;
}
public void end(Call call) {
Cdr cdr = cdrs.get(call.getId());
if (cdr == null) {
logger.error("Could not find CDR for call id %s", call.getId());
return;
}
cdr.setEndTime(System.currentTimeMillis());
if (call.getCallState() != null) {
cdr.setState(call.getCallState().toString());
}
}
public void append(String callId, String element) {
if (callId == null) {
logger.error("Received null call id from element %s", element);
return;
}
Cdr cdr = cdrs.get(callId);
if (cdr == null) {
logger.error("Could not find CDR for call id %s", callId);
return;
}
cdr.add(element);
for (CdrListener listener: listeners) {
listener.elementAdded(callId, element);
}
}
public void store(String callId) {
Cdr cdr = cdrs.get(callId);
if (cdr == null) {
logger.error("Could not find CDR for call id %s", callId);
return;
}
if (logger.isDebugEnabled()) {
logger.debug("Storing CDR record for call id [%s]", callId);
}
for(CdrStorageStrategy storageStrategy: storageStrategies) {
try {
storageStrategy.store(cdr);
} catch (Exception e) {
errorHandler.handleException(e);
}
}
if (logger.isDebugEnabled()) {
logger.debug("Removing CDR record from memory for call id [%s]", callId);
}
cdrs.remove(callId);
}
public void setErrorHandler(CdrErrorHandler errorHandler) {
this.errorHandler = errorHandler;
}
public void setStorageStrategies(List<CdrStorageStrategy> strategies) {
this.storageStrategies = strategies;
}
public List<Cdr> getActiveCdrs() {
if (logger.isDebugEnabled()) {
logger.debug("Retrieving list of active CDRs [%s]", cdrs.keySet().toString());
}
return sort(cdrs.values());
}
private List<Cdr> sort(Collection<Cdr> values) {
List<Cdr> cdrs = new ArrayList<Cdr>(values);
Collections.sort(cdrs, comparator);
return cdrs;
}
public Cdr getCdr(String callId) {
return cdrs.get(callId);
}
public void reset() {
cdrs.clear();
}
public void removeAllStorageStrategies() {
storageStrategies.clear();
}
public void setSpiStorageStrategies(List<CdrStorageStrategy> spiStorageStrategies) {
// These are SPI storage strategies that the user has provided.
// We just copy them to the standard storage strategies list
if (spiStorageStrategies != null) {
storageStrategies.addAll(spiStorageStrategies);
}
}
public void addCdrListener(CdrListener listener) {
listeners.add(listener);
}
public void removeCdrListener(CdrListener listener) {
listeners.remove(listener);
}
public List<CdrListener> getCdrListeners() {
return new ArrayList<CdrListener>(listeners);
}
}