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

Reply via email to