package org.ovirt.engine.core.bll.storage.disk.image;
import static java.util.Objects.requireNonNull;
import java.util.Collections;
import java.util.Date;
import java.util.Map;
import javax.inject.Inject;
import org.ovirt.engine.core.bll.LockMessagesMatchUtil;
import org.ovirt.engine.core.common.businessentities.storage.ImageTransfer;
import org.ovirt.engine.core.common.errors.EngineMessage;
import org.ovirt.engine.core.common.locks.LockingGroup;
import org.ovirt.engine.core.compat.Guid;
import org.ovirt.engine.core.dao.ImageTransferDao;
import org.ovirt.engine.core.utils.lock.EngineLock;
import org.ovirt.engine.core.utils.lock.LockManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ImageTransferUpdater {
private static final Logger log = LoggerFactory.getLogger(ImageTransferUpdater.class);
private final ImageTransferDao imageTransferDao;
private final LockManager lockManager;
@Inject
ImageTransferUpdater(ImageTransferDao imageTransferDao, LockManager lockManager) {
this.imageTransferDao = requireNonNull(imageTransferDao);
this.lockManager = requireNonNull(lockManager);
}
public ImageTransfer updateEntity(ImageTransfer updates, Guid commandId, boolean clearResourceId) {
// TODO this lock might not be enough; analyze possible concurrent calls
EngineLock lock = getEntityUpdateLock(commandId);
try {
lockManager.acquireLockWait(lock);
ImageTransfer entity = imageTransferDao.get(commandId);
if (entity == null) {
log.error("Attempt to update non-existent ImageTransfer entity");
return null;
}
entity.setLastUpdated(new Date());
if (updates != null) {
if (updates.getId() != null) {
entity.setId(updates.getId());
}
if (updates.getPhase() != null) {
String disk = entity.getDiskId() != null
? String.format(" (image %s)", entity.getDiskId().toString()) : "";
String message = entity.getMessage() != null
? String.format(" (message: '%s')", entity.getMessage()) : "";
log.info("Updating image transfer {}{} phase to {}{}",
commandId,
disk,
updates.getPhase(),
message);
entity.setPhase(updates.getPhase());
}
if (updates.getMessage() != null) {
entity.setMessage(updates.getMessage());
}
if (updates.getVdsId() != null) {
entity.setVdsId(updates.getVdsId());
}
if (updates.getDiskId() != null) {
entity.setDiskId(updates.getDiskId());
}
if (updates.getImagedTicketId() != null || clearResourceId) {
entity.setImagedTicketId(updates.getImagedTicketId());
}
if (updates.getProxyUri() != null) {
entity.setProxyUri(updates.getProxyUri());
}
if (updates.getSignedTicket() != null) {
entity.setSignedTicket(updates.getSignedTicket());
}
if (updates.getBytesSent() != null) {
entity.setBytesSent(updates.getBytesSent());
}
if (updates.getBytesTotal() != null) {
entity.setBytesTotal(updates.getBytesTotal());
}
}
imageTransferDao.update(entity);
return entity;
} finally {
lockManager.releaseLock(lock);
}
}
private EngineLock getEntityUpdateLock(Guid commandId) {
Map<String, org.ovirt.engine.core.common.utils.Pair<String, String>> lockMap =
Collections.singletonMap(commandId.toString(),
LockMessagesMatchUtil.makeLockingPair(
LockingGroup.DISK,
EngineMessage.ACTION_TYPE_FAILED_OBJECT_LOCKED));
return new EngineLock(lockMap);
}
}