Daniel Erez has uploaded a new change for review. Change subject: core: introduce GetUnregisteredLUNs query ......................................................................
core: introduce GetUnregisteredLUNs query Change-Id: I71cad5562f8d7dcb39c5a99b7daea28ccb4a00cf Signed-off-by: Daniel Erez <de...@redhat.com> --- A backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/storage/GetUnregisteredBlockStorageDomainsQuery.java A backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/queries/GetUnregisteredBlockStorageDomainsParameters.java M backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/queries/VdcQueryType.java 3 files changed, 291 insertions(+), 0 deletions(-) git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/72/29172/1 diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/storage/GetUnregisteredBlockStorageDomainsQuery.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/storage/GetUnregisteredBlockStorageDomainsQuery.java new file mode 100644 index 0000000..e386e8c --- /dev/null +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/storage/GetUnregisteredBlockStorageDomainsQuery.java @@ -0,0 +1,238 @@ +package org.ovirt.engine.core.bll.storage; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.collections.functors.EqualPredicate; +import org.apache.commons.lang.StringUtils; +import org.ovirt.engine.core.bll.Backend; +import org.ovirt.engine.core.bll.QueriesCommandBase; +import org.ovirt.engine.core.common.action.StorageServerConnectionParametersBase; +import org.ovirt.engine.core.common.action.VdcActionType; +import org.ovirt.engine.core.common.action.VdcReturnValueBase; +import org.ovirt.engine.core.common.businessentities.Entities; +import org.ovirt.engine.core.common.businessentities.LUNs; +import org.ovirt.engine.core.common.businessentities.SANState; +import org.ovirt.engine.core.common.businessentities.StorageDomain; +import org.ovirt.engine.core.common.businessentities.StorageDomainStatic; +import org.ovirt.engine.core.common.businessentities.StorageServerConnections; +import org.ovirt.engine.core.common.businessentities.StorageType; +import org.ovirt.engine.core.common.interfaces.VDSBrokerFrontend; +import org.ovirt.engine.core.common.queries.GetDeviceListQueryParameters; +import org.ovirt.engine.core.common.queries.GetUnregisteredBlockStorageDomainsParameters; +import org.ovirt.engine.core.common.queries.VdcQueryReturnValue; +import org.ovirt.engine.core.common.queries.VdcQueryType; +import org.ovirt.engine.core.common.utils.Pair; +import org.ovirt.engine.core.common.vdscommands.GetVGInfoVDSCommandParameters; +import org.ovirt.engine.core.common.vdscommands.HSMGetStorageDomainInfoVDSCommandParameters; +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.utils.linq.LinqUtils; +import org.ovirt.engine.core.utils.linq.Predicate; + +public class GetUnregisteredBlockStorageDomainsQuery<P extends GetUnregisteredBlockStorageDomainsParameters> extends QueriesCommandBase<P> { + public GetUnregisteredBlockStorageDomainsQuery(P parameters) { + super(parameters); + } + + private List<StorageServerConnections> connectedTargets; + private List<StorageDomain> storageDomains; + + @Override + protected void executeQueryCommand() { + try { + // iSCSI protocol requires targets connection (as opposed to FCP) + if (getParameters().getStorageType() == StorageType.ISCSI) { + connectedTargets = connectTargets(); + } + + // Fetch LUNs from GetDeviceList and filter-out irrelevant ones + List<LUNs> luns = getDeviceList(); + luns = filterLUNsByTargets(luns, connectedTargets); + luns = filterLUNsThatBelongToExistingStorageDomains(luns); + + // Retrieve storage domains by VG-IDs extracted from the LUNs + List<String> vgIDs = getVolumeGroupIdsByLUNs(luns); + storageDomains = getStorageDomainsByVolumeGroupIds(vgIDs); + } catch (RuntimeException e) { + log.errorFormat("Failed to retrieve storage domains by connections info. Exception message: {0}", e.getMessage()); + getQueryReturnValue().setSucceeded(false); + return; + } + + Pair<List<StorageDomain>, List<StorageServerConnections>> returnValue = new Pair<>(storageDomains, connectedTargets); + getQueryReturnValue().setReturnValue(returnValue); + } + + /** + * Connect to the targets (StorageServerConnections) specified in the parameters. + * + * @return A list of targets that's been successfully connected. + */ + private List<StorageServerConnections> connectTargets() { + List<StorageServerConnections> connectedTargets = new ArrayList<>(); + + for (StorageServerConnections storageConnection : getParameters().getStorageServerConnections()) { + VdcReturnValueBase returnValue = getBackend().runInternalAction( + VdcActionType.ConnectStorageToVds, + new StorageServerConnectionParametersBase(storageConnection, getParameters().getVdsId())); + if (returnValue.getSucceeded()) { + connectedTargets.add(storageConnection); + } + } + + if (connectedTargets.isEmpty()) { + Set<String> targetIQNs = + Entities.connectionsByIQN(getParameters().getStorageServerConnections()).keySet(); + + throw new RuntimeException(String.format("Couldn't connect to the specified targets: {0}.", + StringUtils.join(targetIQNs, ", "))); + } + + return connectedTargets; + } + + /** + * Get devices (LUNs) that are visible by the host. + * + * @return the list of LUNs. + */ + private List<LUNs> getDeviceList() { + List<LUNs> luns = new ArrayList<>(); + VdcQueryReturnValue returnValue = getBackend().runInternalQuery(VdcQueryType.GetDeviceList, + new GetDeviceListQueryParameters(getParameters().getVdsId(), getParameters().getStorageType())); + + if (returnValue.getSucceeded()) { + luns.addAll((List<LUNs>) returnValue.getReturnValue()); + } else { + throw new RuntimeException(returnValue.getExceptionString()); + } + + return luns; + } + + /** + * Filter out LUNs that aren't part of the specified targets. + * + * @param luns the LUNs list + * @param targets the targets list + * + * @return the relevant LUNs list + */ + private List<LUNs> filterLUNsByTargets(List<LUNs> luns, final List<StorageServerConnections> targets) { + // Targets should be null only when using StorageType.FCP + if (targets == null) { + return luns; + } + + // For iSCSI domains, filter LUNs by the specified targets + final Set<String> targetIQNs = Entities.connectionsByIQN(targets).keySet(); + return LinqUtils.filter(luns, new Predicate<LUNs>() { + @Override + public boolean eval(LUNs lun) { + for (StorageServerConnections connection : lun.getLunConnections()) { + if (CollectionUtils.exists(targetIQNs, new EqualPredicate(connection.getiqn()))) { + return true; + } + } + return false; + } + }); + } + + /** + * Filter out LUNs that are already a part of storage domains exist in the system. + * + * @param luns the LUNs list + * + * @return the relevant LUNs list + */ + private List<LUNs> filterLUNsThatBelongToExistingStorageDomains(List<LUNs> luns) { + List<StorageDomain> existingStorageDomains = getDbFacade().getStorageDomainDao().getAll(); + final List<Guid> existingStorageDomainIDs = Entities.getIds(existingStorageDomains); + + return LinqUtils.filter(luns, new Predicate<LUNs>() { + @Override + public boolean eval(LUNs lun) { + return !existingStorageDomainIDs.contains(lun.getStorageDomainId()); + } + }); + } + + /** + * Retrieve the volume group ID associated with each LUN in the specified list. + * + * @param luns the LUNs list + * + * @return volume group IDs + */ + private List<String> getVolumeGroupIdsByLUNs(List<LUNs> luns) { + Set<String> vgSet = new HashSet<>(); + for (LUNs lun : luns) { + if (!lun.getvolume_group_id().isEmpty()) { + vgSet.add(lun.getvolume_group_id()); + } + } + + return new ArrayList<>(vgSet); + } + + /** + * Create StorageDomain objects according to the specified VG-IDs list. + * + * @param vgIDs the VG-IDs list + * + * @return storage domains list + */ + private List<StorageDomain> getStorageDomainsByVolumeGroupIds(List<String> vgIDs) { + List<StorageDomain> storageDomains = new ArrayList<>(); + for (String vgID : vgIDs) { + VDSReturnValue returnValue = getVdsBroker().RunVdsCommand(VDSCommandType.GetVGInfo, + new GetVGInfoVDSCommandParameters(getParameters().getVdsId(), vgID)); + if (returnValue.getSucceeded()) { + ArrayList<LUNs> luns = (ArrayList<LUNs>) returnValue.getReturnValue(); + + // Get storage domain ID by a representative LUN + LUNs lun = luns.get(0); + Guid storageDomainId = lun.getStorageDomainId(); + + // Get storage domain using GetStorageDomainInfo + StorageDomain storageDomain = getStorageDomainByVgName(storageDomainId); + storageDomains.add(storageDomain); + } else { + throw new RuntimeException(returnValue.getVdsError().getMessage()); + } + } + return storageDomains; + } + + /** + * Retrieve a storage domain using a specified storage domain ID. + * + * @param storageDomainId the domain's ID + * @return the storage domain + */ + private StorageDomain getStorageDomainByVgName(Guid storageDomainId) { + VDSReturnValue returnValue = getVdsBroker().RunVdsCommand(VDSCommandType.HSMGetStorageDomainInfo, + new HSMGetStorageDomainInfoVDSCommandParameters(getParameters().getVdsId(), storageDomainId)); + if (returnValue.getSucceeded()) { + Pair<StorageDomainStatic, SANState> result = (Pair<StorageDomainStatic, SANState>) returnValue.getReturnValue(); + StorageDomainStatic storageDomainStatic = result.getFirst(); + + StorageDomain storageDomain = new StorageDomain(); + storageDomain.setStorageStaticData(storageDomainStatic); + + return storageDomain; + } else { + throw new RuntimeException(returnValue.getVdsError().getMessage()); + } + } + + private VDSBrokerFrontend getVdsBroker() { + return Backend.getInstance().getResourceManager(); + } +} diff --git a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/queries/GetUnregisteredBlockStorageDomainsParameters.java b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/queries/GetUnregisteredBlockStorageDomainsParameters.java new file mode 100644 index 0000000..e4fe453 --- /dev/null +++ b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/queries/GetUnregisteredBlockStorageDomainsParameters.java @@ -0,0 +1,52 @@ +package org.ovirt.engine.core.common.queries; + +import java.util.List; + +import org.ovirt.engine.core.common.businessentities.StorageServerConnections; +import org.ovirt.engine.core.common.businessentities.StorageType; +import org.ovirt.engine.core.compat.Guid; + +public class GetUnregisteredBlockStorageDomainsParameters extends VdcQueryParametersBase { + private static final long serialVersionUID = 6989522172841845637L; + + private Guid vdsId; + private StorageType storageType; + private List<StorageServerConnections> storageServerConnections; + + public GetUnregisteredBlockStorageDomainsParameters() { + } + + public GetUnregisteredBlockStorageDomainsParameters(Guid vdsId, StorageType storageType) { + this(vdsId, storageType, null); + } + + public GetUnregisteredBlockStorageDomainsParameters(Guid vdsId, StorageType storageType, List<StorageServerConnections> storageServerConnections) { + this.vdsId = vdsId; + this.storageType = storageType; + this.storageServerConnections = storageServerConnections; + } + + public Guid getVdsId() { + return vdsId; + } + + public void setVdsId(Guid vdsId) { + this.vdsId = vdsId; + } + + public StorageType getStorageType() { + return storageType; + } + + public void setStorageType(StorageType storageType) { + this.storageType = storageType; + } + + public List<StorageServerConnections> getStorageServerConnections() { + return storageServerConnections; + } + + public void setStorageServerConnections(List<StorageServerConnections> storageServerConnections) { + this.storageServerConnections = storageServerConnections; + } +} diff --git a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/queries/VdcQueryType.java b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/queries/VdcQueryType.java index d937ef6..bfe81da 100644 --- a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/queries/VdcQueryType.java +++ b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/queries/VdcQueryType.java @@ -249,6 +249,7 @@ GetConnectionsByDataCenterAndStorageType, GetStorageDomainsByStoragePoolId(VdcQueryAuthType.User), GetStorageDomainsByImageId, + GetUnregisteredBlockStorageDomains, GetVgList, GetDeviceList, DiscoverSendTargets, -- To view, visit http://gerrit.ovirt.org/29172 To unsubscribe, visit http://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I71cad5562f8d7dcb39c5a99b7daea28ccb4a00cf Gerrit-PatchSet: 1 Gerrit-Project: ovirt-engine Gerrit-Branch: master Gerrit-Owner: Daniel Erez <de...@redhat.com> _______________________________________________ Engine-patches mailing list Engine-patches@ovirt.org http://lists.ovirt.org/mailman/listinfo/engine-patches