package org.ovirt.engine.core.bll.tasks;
import java.io.Serializable;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.inject.Inject;
import javax.inject.Singleton;
import javax.transaction.Transaction;
import org.apache.commons.collections.CollectionUtils;
import org.ovirt.engine.core.common.businessentities.CommandAssociatedEntity;
import org.ovirt.engine.core.common.businessentities.CommandEntity;
import org.ovirt.engine.core.compat.CommandStatus;
import org.ovirt.engine.core.compat.DateTime;
import org.ovirt.engine.core.compat.Guid;
import org.ovirt.engine.core.dao.CommandEntityDao;
import org.ovirt.engine.core.utils.transaction.TransactionSupport;
@Singleton
public class CommandsCacheImpl implements CommandsCache {
private Map<Guid, CommandEntity> commandMap;
private volatile boolean cacheInitialized;
private Object LOCK = new Object();
@Inject
private CommandEntityDao commandEntityDao;
public CommandsCacheImpl() {
commandMap = new HashMap<>();
}
private void initializeCache() {
if (!cacheInitialized) {
synchronized(LOCK) {
if (!cacheInitialized) {
List<CommandEntity> cmdEntities = commandEntityDao.getAll();
for (CommandEntity cmdEntity : cmdEntities) {
commandMap.put(cmdEntity.getId(), cmdEntity);
}
cacheInitialized = true;
}
}
}
}
@Override
public Set<Guid> keySet() {
initializeCache();
return commandMap.keySet();
}
@Override
public CommandEntity get(Guid commandId) {
initializeCache();
return commandMap.get(commandId);
}
@Override
public void remove(final Guid commandId) {
commandMap.remove(commandId);
commandEntityDao.remove(commandId);
}
@Override
public void put(final CommandEntity cmdEntity) {
commandMap.put(cmdEntity.getId(), cmdEntity);
saveOrUpdateWithoutTransaction(cmdEntity);
}
@Override
public void removeAllCommandsBeforeDate(DateTime cutoff) {
commandEntityDao.removeAllBeforeDate(cutoff);
cacheInitialized = false;
initializeCache();
}
@Override
public void updateCommandStatus(Guid commandId, CommandStatus status) {
final CommandEntity cmdEntity = get(commandId);
if (cmdEntity != null) {
cmdEntity.setCommandStatus(status);
saveOrUpdateWithoutTransaction(cmdEntity);
}
}
@Override
public void updateCommandData(Guid commandId, Map<String, Serializable> data) {
final CommandEntity cmdEntity = get(commandId);
if (cmdEntity != null) {
cmdEntity.setData(data);
saveOrUpdateWithoutTransaction(cmdEntity);
}
}
@Override
public void updateCommandExecuted(final Guid commandId) {
CommandEntity cmdEntity = get(commandId);
if (cmdEntity != null) {
cmdEntity.setExecuted(true);
commandEntityDao.updateExecuted(commandId);
}
}
public void saveOrUpdateWithoutTransaction(CommandEntity cmdEntity) {
Transaction transaction = TransactionSupport.suspend();
try {
commandEntityDao.saveOrUpdate(cmdEntity);
} finally {
if (transaction != null) {
TransactionSupport.resume(transaction);
}
}
}
@Override
public void updateCallbackNotified(final Guid commandId) {
CommandEntity cmdEntity = get(commandId);
if (cmdEntity != null) {
cmdEntity.setCallbackNotified(true);
commandEntityDao.updateNotified(commandId);
}
}
@Override
public void persistCommandAssociatedEntities(Collection<CommandAssociatedEntity> cmdAssociatedEntities) {
if (CollectionUtils.isEmpty(cmdAssociatedEntities)) {
return;
}
Transaction transaction = TransactionSupport.suspend();
try {
commandEntityDao.insertCommandAssociatedEntities(cmdAssociatedEntities);
} finally {
if (transaction != null) {
TransactionSupport.resume(transaction);
}
}
}
@Override
public List<CommandAssociatedEntity> getCommandAssociatedEntities(Guid cmdId) {
return commandEntityDao.getAllCommandAssociatedEntities(cmdId);
}
@Override
public List<Guid> getCommandIdsByEntityId(Guid entityId) {
return commandEntityDao.getCommandIdsByEntity(entityId);
}
@Override
public List<CommandEntity> getChildCmdsByParentCmdId(Guid cmdId) {
return commandEntityDao.getCmdEntitiesByParentCmdId(cmdId);
}
}