package org.ovirt.engine.core.bll;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.ovirt.engine.core.common.AuditLogType;
import org.ovirt.engine.core.common.VdcObjectType;
import org.ovirt.engine.core.common.action.ChangeVDSClusterParameters;
import org.ovirt.engine.core.common.action.VdcActionType;
import org.ovirt.engine.core.common.action.VdcReturnValueBase;
import org.ovirt.engine.core.common.businessentities.StorageType;
import org.ovirt.engine.core.common.businessentities.VDS;
import org.ovirt.engine.core.common.businessentities.VDSGroup;
import org.ovirt.engine.core.common.businessentities.VdsStatic;
import org.ovirt.engine.core.common.businessentities.storage_pool;
import org.ovirt.engine.core.compat.Guid;
import org.ovirt.engine.core.compat.TransactionScopeOption;
import org.ovirt.engine.core.dal.VdcBllMessages;
import org.ovirt.engine.core.dal.dbbroker.DbFacade;
import org.ovirt.engine.core.utils.ObjectIdentityChecker;
import org.ovirt.engine.core.utils.transaction.TransactionMethod;
import org.ovirt.engine.core.utils.transaction.TransactionSupport;
@NonTransactiveCommandAttribute(forceCompensation = true)
public class ChangeVDSClusterCommand<T extends ChangeVDSClusterParameters> extends VdsCommand<T> {
private storage_pool targetStoragePool;
/**
* Constructor for command creation when compensation is applied on startup
* @param commandId
*/
public ChangeVDSClusterCommand(Guid commandId) {
super(commandId);
}
public ChangeVDSClusterCommand(T params) {
super(params);
}
@Override
protected boolean canDoAction() {
VDS vds = getVds();
if (vds == null) {
addCanDoActionMessage(VdcBllMessages.VDS_INVALID_SERVER_ID);
return false;
}
if (!ObjectIdentityChecker.CanUpdateField(vds, "vds_group_id", vds.getstatus())) {
addCanDoActionMessage(VdcBllMessages.VDS_STATUS_NOT_VALID_FOR_UPDATE);
return false;
}
VDSGroup targetCluster = DbFacade.getInstance().getVdsGroupDAO().get(getParameters().getClusterId());
if (targetCluster == null) {
addCanDoActionMessage(VdcBllMessages.VDS_CLUSTER_IS_NOT_VALID);
return false;
}
targetStoragePool = DbFacade.getInstance().getStoragePoolDAO().getForVdsGroup(targetCluster.getID());
if (targetStoragePool != null && targetStoragePool.getstorage_pool_type() == StorageType.LOCALFS) {
if (!DbFacade.getInstance().getVdsStaticDAO().getAllForVdsGroup(getParameters().getClusterId()).isEmpty()) {
addCanDoActionMessage(VdcBllMessages.VDS_CANNOT_ADD_MORE_THEN_ONE_HOST_TO_LOCAL_STORAGE);
return false;
}
}
return true;
}
@Override
protected void executeCommand() {
VDSGroup sourceCluster = getVdsGroup();
final Guid targetClusterId = getParameters().getClusterId();
if (sourceCluster.getID().equals(targetClusterId)) {
setSucceeded(true);
return;
}
// save the new cluster id
TransactionSupport.executeInNewTransaction(new TransactionMethod<Void>() {
@Override
public Void runInTransaction() {
VdsStatic staticData = getVds().getStaticData();
getCompensationContext().snapshotEntity(staticData);
staticData.setvds_group_id(targetClusterId);
DbFacade.getInstance().getVdsStaticDAO().update(staticData);
getCompensationContext().stateChanged();
return null;
}
});
// handle spm
getParameters().setCompensationEnabled(true);
getParameters().setTransactionScopeOption(TransactionScopeOption.RequiresNew);
if (sourceCluster.getstorage_pool_id() != null) {
VdcReturnValueBase removeVdsSpmIdReturn = Backend.getInstance().runInternalAction(
VdcActionType.RemoveVdsSpmId, getParameters(), getCompensationContext());
if (!removeVdsSpmIdReturn.getSucceeded()) {
setSucceeded(false);
getReturnValue().setFault(removeVdsSpmIdReturn.getFault());
return;
}
}
if (targetStoragePool != null) {
VdcReturnValueBase addVdsSpmIdReturn = Backend.getInstance().runInternalAction(
VdcActionType.AddVdsSpmId, getParameters(), getCompensationContext());
if (!addVdsSpmIdReturn.getSucceeded()) {
setSucceeded(false);
getReturnValue().setFault(addVdsSpmIdReturn.getFault());
return;
}
}
setSucceeded(true);
}
@Override
public AuditLogType getAuditLogTypeValue() {
return getSucceeded() ? AuditLogType.USER_UPDATE_VDS : AuditLogType.USER_FAILED_UPDATE_VDS;
}
@Override
public Map<Guid, VdcObjectType> getPermissionCheckSubjects() {
Map<Guid, VdcObjectType> map = new HashMap<Guid, VdcObjectType>(2);
map.put(getParameters().getVdsId(), VdcObjectType.VDS);
map.put(getParameters().getClusterId(), VdcObjectType.VdsGroups);
Map<Guid, VdcObjectType> unmodifiableMap = Collections.unmodifiableMap(map);
return unmodifiableMap;
}
}