package org.ovirt.engine.core.bll.storage.domain; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; import javax.inject.Inject; import org.ovirt.engine.core.bll.LockMessagesMatchUtil; import org.ovirt.engine.core.bll.context.CommandContext; import org.ovirt.engine.core.common.action.LockProperties; import org.ovirt.engine.core.common.action.StorageDomainManagementParameter; import org.ovirt.engine.core.common.businessentities.storage.LUNs; 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.common.vdscommands.GetVGInfoVDSCommandParameters; import org.ovirt.engine.core.common.vdscommands.VDSCommandType; import org.ovirt.engine.core.common.vdscommands.VDSReturnValue; import org.ovirt.engine.core.compat.Guid; import org.ovirt.engine.core.dao.LunDao; import org.ovirt.engine.core.dao.StorageDomainStaticDao; import org.ovirt.engine.core.utils.transaction.TransactionSupport; public class AddExistingBlockStorageDomainCommand<T extends StorageDomainManagementParameter> extends AddStorageDomainCommon<T> { @Inject private BlockStorageDomainHelper blockStorageDomainHelper; @Inject private LunDao lunDao; @Inject private StorageDomainStaticDao storageDomainStaticDao; /** * Constructor for command creation when compensation is applied on startup */ public AddExistingBlockStorageDomainCommand(Guid commandId) { super(commandId); } public AddExistingBlockStorageDomainCommand(T parameters, CommandContext commandContext) { super(parameters, commandContext); } @Override protected void executeCommand() { updateStaticDataDefaults(); // Add StorageDomain object to DB and update statistics addStorageDomainInDb(); updateStorageDomainDynamicFromIrs(); // Add relevant LUNs to DB List<LUNs> luns = getLUNsFromVgInfo(getStorageDomain().getStorage()); saveLUNsInDB(luns); updateMetadataDevices(); setSucceeded(true); } protected void updateMetadataDevices() { if (getStorageDomain().getVgMetadataDevice() == null || getStorageDomain().getFirstMetadataDevice() == null) { blockStorageDomainHelper.fillMetadataDevicesInfo(getStorageDomain().getStorageStaticData(), getVds().getId()); storageDomainStaticDao.update(getStorageDomain().getStorageStaticData()); } } @Override protected boolean canAddDomain() { if (storageDomainStaticDao.get(getStorageDomain().getId()) != null) { return failValidation(EngineMessage.ACTION_TYPE_FAILED_STORAGE_DOMAIN_ALREADY_EXIST); } List<LUNs> lunsOnStorage = getLUNsFromVgInfo(getStorageDomain().getStorage()); if (lunsOnStorage.isEmpty()) { return failValidation(EngineMessage.ACTION_TYPE_FAILED_PROBLEM_WITH_CANDIDATE_INFO); } Set<String> allLunIds = getAllLuns().stream().map(LUNs::getId).collect(Collectors.toSet()); if (lunsOnStorage.stream().map(LUNs::getId).anyMatch(allLunIds::contains)) { log.info("There are existing luns in the system which are part of VG id '{}'", getStorageDomain().getStorage()); return failValidation(EngineMessage.ACTION_TYPE_FAILED_IMPORT_STORAGE_DOMAIN_EXTERNAL_LUN_DISK_EXIST); } return true; } protected List<LUNs> getAllLuns() { return lunDao.getAll(); } @Override protected LockProperties applyLockProperties(LockProperties lockProperties) { return lockProperties.withScope(LockProperties.Scope.Execution); } @Override protected Map<String, Pair<String, String>> getExclusiveLocks() { if (getParameters().getStorageDomainId() != null) { return Collections.singletonMap(getParameters().getStorageDomainId().toString(), LockMessagesMatchUtil.makeLockingPair(LockingGroup.STORAGE, EngineMessage.ACTION_TYPE_FAILED_OBJECT_LOCKED)); } return null; } protected List<LUNs> getLUNsFromVgInfo(String vgId) { List<LUNs> luns = new ArrayList<>(); VDSReturnValue returnValue; try { returnValue = runVdsCommand(VDSCommandType.GetVGInfo, new GetVGInfoVDSCommandParameters(getParameters().getVdsId(), vgId)); } catch (RuntimeException e) { log.error("Could not get info for VG ID '{}': {}", vgId, e.getMessage()); log.debug("Exception", e); return luns; } luns.addAll((ArrayList<LUNs>) returnValue.getReturnValue()); return luns; } protected void saveLUNsInDB(final List<LUNs> luns) { TransactionSupport.executeInNewTransaction(() -> { for (LUNs lun : luns) { lunHelper.proceedLUNInDb(lun, getStorageDomain().getStorageType(), getStorageDomain().getStorage()); } return null; }); } }