package org.ovirt.engine.core.bll;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.ovirt.engine.core.bll.context.CommandContext;
import org.ovirt.engine.core.common.action.LockProperties;
import org.ovirt.engine.core.common.action.LockProperties.Scope;
import org.ovirt.engine.core.common.action.VdsActionParameters;
import org.ovirt.engine.core.common.businessentities.VdsSpmIdMap;
import org.ovirt.engine.core.common.config.Config;
import org.ovirt.engine.core.common.config.ConfigValues;
import org.ovirt.engine.core.common.errors.EngineError;
import org.ovirt.engine.core.common.errors.EngineFault;
import org.ovirt.engine.core.common.errors.EngineMessage;
import org.ovirt.engine.core.common.locks.LockingGroup;
import org.ovirt.engine.core.common.utils.Pair;
import org.ovirt.engine.core.compat.Guid;
@InternalCommandAttribute
@ValidateSupportsTransaction
public class AddVdsSpmIdCommand<T extends VdsActionParameters> extends VdsCommand<T> {
/**
* Constructor for command creation when compensation is applied on startup
*/
public AddVdsSpmIdCommand(Guid commandId) {
super(commandId);
}
public AddVdsSpmIdCommand(T parameters, CommandContext cmdContext) {
super(parameters, cmdContext);
}
@Override
protected LockProperties applyLockProperties(LockProperties lockProperties) {
return lockProperties.withScope(Scope.Execution).withWait(true);
}
@Override
protected boolean validate() {
return true;
}
@Override
protected void executeCommand() {
List<VdsSpmIdMap> vdsSpmIdMapList = vdsSpmIdMapDao.getAll(getDcId());
if (vdsSpmIdMapList.size() >= Config.<Integer> getValue(ConfigValues.MaxNumberOfHostsInStoragePool)) {
buildFaultResult();
return;
}
insertSpmIdToDb(vdsSpmIdMapList);
setSucceeded(true);
}
protected void insertSpmIdToDb(List<VdsSpmIdMap> vdsSpmIdMapList) {
int selectedId = 1;
List<Integer> list = vdsSpmIdMapList.stream().map(VdsSpmIdMap::getVdsSpmId).sorted().collect(Collectors.toList());
for (int id : list) {
if (selectedId == id) {
selectedId++;
} else {
break;
}
}
VdsSpmIdMap newMap = new VdsSpmIdMap(getDcId(), getVdsId(), selectedId);
vdsSpmIdMapDao.save(newMap);
if (getParameters().isCompensationEnabled()) {
getCompensationContext().snapshotNewEntity(newMap);
getCompensationContext().stateChanged();
}
}
/**
* Gets the dc id from cluster if DC was removed and cluster is attached to a new DC
*/
private Guid getDcId() {
final Guid hostDcId = getVds().getStoragePoolId();
return hostDcId.equals(Guid.Empty)
? getCluster().getStoragePoolId()
: hostDcId;
}
private void buildFaultResult() {
EngineFault fault = new EngineFault();
fault.setError(EngineError.ReachedMaxNumberOfHostsInDC);
fault.setMessage(Backend.getInstance()
.getVdsErrorsTranslator()
.translateErrorTextSingle(fault.getError().toString()));
getReturnValue().setFault(fault);
}
@Override
protected Map<String, Pair<String, String>> getExclusiveLocks() {
return Collections.singletonMap(getVds().getStoragePoolId().toString(),
LockMessagesMatchUtil.makeLockingPair(LockingGroup.REGISTER_VDS, EngineMessage.ACTION_TYPE_FAILED_OBJECT_LOCKED));
}
}