package org.ovirt.engine.core.bll.storage;

import java.util.ArrayList;
import java.util.List;

import org.ovirt.engine.core.common.action.StorageDomainManagementParameter;
import org.ovirt.engine.core.common.businessentities.LUNs;
import org.ovirt.engine.core.common.errors.VdcBllMessages;
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.utils.transaction.TransactionMethod;
import org.ovirt.engine.core.utils.transaction.TransactionSupport;

public class AddExistingBlockStorageDomainCommand<T extends StorageDomainManagementParameter> extends
        AddStorageDomainCommon<T> {

    /**
     * Constructor for command creation when compensation is applied on startup
     *
     * @param commandId
     */
    protected AddExistingBlockStorageDomainCommand(Guid commandId) {
        super(commandId);
    }

    public AddExistingBlockStorageDomainCommand(T parameters) {
        super(parameters);
    }

    @Override
    protected void executeCommand() {
        // Add StorageDomain object to DB and update statistics
        addStorageDomainInDb();
        updateStorageDomainDynamicFromIrs();

        // Add relevant LUNs to DB
        List<LUNs> luns = getLUNsFromVgInfo(getStorageDomain().getStorage());
        saveLUNsInDB(luns);

        setSucceeded(true);
    }

    @Override
    protected boolean canAddDomain() {
        if (getStorageDomainStaticDAO().get(getStorageDomain().getId()) != null) {
            return failCanDoAction(VdcBllMessages.ACTION_TYPE_FAILED_STORAGE_DOMAIN_ALREADY_EXIST);
        }
        return true;
    }

    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(new TransactionMethod<Void>() {
            @Override
            public Void runInTransaction() {
                for (LUNs lun : luns) {
                    proceedLUNInDb(lun, getStorageDomain().getStorageType(), getStorageDomain().getStorage());
                }
                return null;
            }
        });
    }

}

@@ -82,22 +82,189 @@
 va.util.
-List;%0A
+Collections;%0Aimport java.util.List;%0Aimport java.util.Map;%0A%0Aimport org.ovirt.engine.core.bll.LockMessagesMatchUtil;%0Aimport org.ovirt.engine.core.common.action.LockProperties;
 %0Aimport 
@@ -447,24 +447,128 @@
 llMessages;%0A
+import org.ovirt.engine.core.common.locks.LockingGroup;%0Aimport org.ovirt.engine.core.common.utils.Pair;%0A
 import org.o
@@ -2041,32 +2041,614 @@
 rn true;%0A    %7D%0A%0A
+    @Override%0A    protected LockProperties applyLockProperties(LockProperties lockProperties) %7B%0A        return lockProperties.withScope(LockProperties.Scope.Execution);%0A    %7D%0A%0A    @Override%0A    protected Map%3CString, Pair%3CString, String%3E%3E getExclusiveLocks() %7B%0A        if (getParameters().getStorageDomainId() != null) %7B%0A            return Collections.singletonMap(getParameters().getStorageDomainId().toString(),%0A                    LockMessagesMatchUtil.makeLockingPair(LockingGroup.STORAGE, VdcBllMessages.ACTION_TYPE_FAILED_OBJECT_LOCKED));%0A        %7D%0A        return null;%0A    %7D%0A%0A
     protected Li

Add lock when importing an exsiting block Storage Domain