<commit_before>package org.ovirt.engine.core.bll;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.ovirt.engine.core.bll.job.ExecutionHandler;
import org.ovirt.engine.core.bll.network.cluster.NetworkClusterHelper;
import org.ovirt.engine.core.bll.utils.PermissionSubject;
import org.ovirt.engine.core.common.VdcObjectType;
import org.ovirt.engine.core.common.action.MaintenanceNumberOfVdssParameters;
import org.ovirt.engine.core.common.action.MaintenanceVdsParameters;
import org.ovirt.engine.core.common.action.VdcActionType;
import org.ovirt.engine.core.common.action.VdcReturnValueBase;
import org.ovirt.engine.core.common.businessentities.MigrationSupport;
import org.ovirt.engine.core.common.businessentities.VDS;
import org.ovirt.engine.core.common.businessentities.VDSGroup;
import org.ovirt.engine.core.common.businessentities.VDSStatus;
import org.ovirt.engine.core.common.businessentities.VM;
import org.ovirt.engine.core.common.businessentities.VdsSpmStatus;
import org.ovirt.engine.core.common.businessentities.network.Network;
import org.ovirt.engine.core.common.locks.LockingGroup;
import org.ovirt.engine.core.common.utils.Pair;
import org.ovirt.engine.core.common.vdscommands.SetVdsStatusVDSCommandParameters;
import org.ovirt.engine.core.common.vdscommands.VDSCommandType;
import org.ovirt.engine.core.compat.Guid;
import org.ovirt.engine.core.dal.VdcBllMessages;
import org.ovirt.engine.core.dal.dbbroker.DbFacade;

@InternalCommandAttribute
@NonTransactiveCommandAttribute
public class MaintenanceNumberOfVdssCommand<T extends MaintenanceNumberOfVdssParameters> extends CommandBase<T> {
    private static final long serialVersionUID = -5691756067222085075L;
    private final HashMap<Guid, VDS> vdssToMaintenance = new HashMap<Guid, VDS>();
    private ArrayList<Guid> _vdsGroupIds;
    private final List<PermissionSubject> inspectedEntitiesMap;
    private Map<String, Pair<String, String>> sharedLockMap;

    public MaintenanceNumberOfVdssCommand(T parameters) {
        super(parameters);
        Iterable<Guid> vdsIdList = getParameters().getVdsIdList();
        inspectedEntitiesMap = new ArrayList<PermissionSubject>();
        for (Guid g : vdsIdList) {
            inspectedEntitiesMap.add(new PermissionSubject(g,
                    VdcObjectType.VDS,
                    getActionType().getActionGroup()));
        }
    }

    private void MoveVdssToGoingToMaintenanceMode() {
        List<VDS> spms = new ArrayList<VDS>();
        for (VDS vds : vdssToMaintenance.values()) {
            if (vds.getSpmStatus() != VdsSpmStatus.SPM) {
                setVdsStatusToPrepareForMaintaice(vds);
            } else {
                spms.add(vds);
            }
        }
        for (VDS vds : spms) {
            setVdsStatusToPrepareForMaintaice(vds);
        }
        freeLock();
    }

    private void setVdsStatusToPrepareForMaintaice(VDS vds) {
        if (vds.getStatus() != VDSStatus.PreparingForMaintenance && vds.getStatus() != VDSStatus.NonResponsive
                && vds.getStatus() != VDSStatus.Down) {
            runVdsCommand(VDSCommandType.SetVdsStatus,
                    new SetVdsStatusVDSCommandParameters(vds.getId(), VDSStatus.PreparingForMaintenance));
        }
    }

    private void MigrateAllVdss() {
        for (Guid vdsId : getParameters().getVdsIdList()) {
            // ParametersCurrentUser = CurrentUser
            MaintenanceVdsParameters tempVar = new MaintenanceVdsParameters(vdsId, getParameters().getIsInternal());
            tempVar.setSessionId(getParameters().getSessionId());
            tempVar.setCorrelationId(getParameters().getCorrelationId());
            VdcReturnValueBase result =
                    Backend.getInstance().runInternalAction(VdcActionType.MaintenanceVds,
                            tempVar,
                            ExecutionHandler.createInternalJobContext());
            if (!result.getCanDoAction()) {
                getReturnValue().getCanDoActionMessages().addAll(result.getCanDoActionMessages());
                getReturnValue().setCanDoAction(false);
            }
        }
    }

    @Override
    protected void setActionMessageParameters() {
        addCanDoActionMessage(VdcBllMessages.VAR__TYPE__HOST);
        addCanDoActionMessage(VdcBllMessages.VAR__ACTION__MAINTENANCE);
    }

    @Override
    protected void executeCommand() {
        MoveVdssToGoingToMaintenanceMode();
        MigrateAllVdss();
        // set network to operational / non-operational
        for (Guid id : _vdsGroupIds) {
            List<Network> networks = DbFacade.getInstance().getNetworkDao().getAllForCluster(id);
            for (Network net : networks) {
                NetworkClusterHelper.setStatus(id, net);
            }
        }
        setSucceeded(true);
    }

    @Override
    protected boolean canDoAction() {
        boolean result = true;
        _vdsGroupIds = new ArrayList<Guid>();
        Set<Guid> vdsWithRunningVMs = new HashSet<Guid>();
        List<String> hostNotRespondingList = new ArrayList<String>();
        List<String> hostsWithNonMigratableVms = new ArrayList<String>();
        List<String> nonMigratableVms = new ArrayList<String>();

        for (Guid vdsId : getParameters().getVdsIdList()) {
            VDS vds = DbFacade.getInstance().getVdsDao().get(vdsId);
            if (vds == null) {
                log.error(String.format("ResourceManager::vdsMaintenance could not find vds_id = '%1$s'", vdsId));
                addCanDoActionMessage(VdcBllMessages.VDS_INVALID_SERVER_ID);
                result = false;
                continue;
            }
            if (!vdssToMaintenance.containsKey(vdsId)) {
                vdssToMaintenance.put(vdsId, vds);
                if (vds.getSpmStatus() == VdsSpmStatus.SPM) {
                    addSharedLockEntry(vds);
                }
            }
        }
        result = result && acquireLockInternal();
        if (result) {
            // check if one of the target vdss is spm, if so check that there are no
            // tasks running
            for (Guid vdsId : getParameters().getVdsIdList()) {
                VDS vds = vdssToMaintenance.get(vdsId);
                if (vds != null) {
                    List<VM> vms = getVmDAO().getAllRunningForVds(vdsId);
                    if (vms.size() > 0) {
                        vdsWithRunningVMs.add(vdsId);
                    }
                    _vdsGroupIds.add(vds.getVdsGroupId());
                    List<String> nonMigratableVmDescriptionsToFrontEnd = new ArrayList<String>();
                    for (VM vm : vms) {
                        if (vm.getMigrationSupport() != MigrationSupport.MIGRATABLE) {
                            nonMigratableVmDescriptionsToFrontEnd.add(vm.getName());
                        }
                    }

                    if (nonMigratableVmDescriptionsToFrontEnd.size() > 0) {
                        hostsWithNonMigratableVms.add(vds.getName());
                        nonMigratableVms.addAll(nonMigratableVmDescriptionsToFrontEnd);

                        // The non migratable VM names will be comma separated
                        log.error(String.format("VDS %1$s contains non migratable VMs", vdsId));
                        result = false;

                    } else if (vds.getStatus() == VDSStatus.Maintenance) {
                        addCanDoActionMessage(VdcBllMessages.VDS_CANNOT_MAINTENANCE_VDS_IS_IN_MAINTENANCE);
                        result = false;
                    } else if (vds.getSpmStatus() == VdsSpmStatus.Contending) {
                        addCanDoActionMessage(VdcBllMessages.VDS_CANNOT_MAINTENANCE_SPM_CONTENDING);
                        result = false;
                    } else if (vds.getStatus() == VDSStatus.NonResponsive && vds.getVmCount() > 0) {
                        result = false;
                        hostNotRespondingList.add(vds.getName());
                    } else if (vds.getStatus() == VDSStatus.NonResponsive && vds.getSpmStatus() != VdsSpmStatus.None) {
                        result = false;
                        addCanDoActionMessage(VdcBllMessages.VDS_CANNOT_MAINTENANCE_VDS_IS_NOT_RESPONDING_AND_IS_SPM);
                    } else if (vds.getSpmStatus() == VdsSpmStatus.SPM && vds.getStatus() == VDSStatus.Up &&
                            getAsyncTaskDao().getAsyncTaskIdsByStoragePoolId(vds.getStoragePoolId()).size() > 0) {
                        addCanDoActionMessage(VdcBllMessages.VDS_CANNOT_MAINTENANCE_SPM_WITH_RUNNING_TASKS);
                        result = false;
                    }
                }
            }

            // If one of the host is non responsive with running VM's, add a CanDoAction message.
            handleNonResponsiveHosts(hostNotRespondingList);

            // If one of the vms is non migratable, add a CanDoAction message.
            handleNonMigratableVms(hostsWithNonMigratableVms, nonMigratableVms);<commit_msg>core:we are fencing a host when putting it in...<commit_after>package org.ovirt.engine.core.bll;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.ovirt.engine.core.bll.job.ExecutionHandler;
import org.ovirt.engine.core.bll.network.cluster.NetworkClusterHelper;
import org.ovirt.engine.core.bll.utils.PermissionSubject;
import org.ovirt.engine.core.common.VdcObjectType;
import org.ovirt.engine.core.common.action.MaintenanceNumberOfVdssParameters;
import org.ovirt.engine.core.common.action.MaintenanceVdsParameters;
import org.ovirt.engine.core.common.action.VdcActionType;
import org.ovirt.engine.core.common.action.VdcReturnValueBase;
import org.ovirt.engine.core.common.businessentities.MigrationSupport;
import org.ovirt.engine.core.common.businessentities.VDS;
import org.ovirt.engine.core.common.businessentities.VDSGroup;
import org.ovirt.engine.core.common.businessentities.VDSStatus;
import org.ovirt.engine.core.common.businessentities.VM;
import org.ovirt.engine.core.common.businessentities.VdsSpmStatus;
import org.ovirt.engine.core.common.businessentities.network.Network;
import org.ovirt.engine.core.common.locks.LockingGroup;
import org.ovirt.engine.core.common.utils.Pair;
import org.ovirt.engine.core.common.vdscommands.SetVdsStatusVDSCommandParameters;
import org.ovirt.engine.core.common.vdscommands.VDSCommandType;
import org.ovirt.engine.core.compat.Guid;
import org.ovirt.engine.core.dal.VdcBllMessages;
import org.ovirt.engine.core.dal.dbbroker.DbFacade;

@InternalCommandAttribute
@NonTransactiveCommandAttribute
public class MaintenanceNumberOfVdssCommand<T extends MaintenanceNumberOfVdssParameters> extends CommandBase<T> {
    private static final long serialVersionUID = -5691756067222085075L;
    private final HashMap<Guid, VDS> vdssToMaintenance = new HashMap<Guid, VDS>();
    private ArrayList<Guid> _vdsGroupIds;
    private final List<PermissionSubject> inspectedEntitiesMap;
    private Map<String, Pair<String, String>> sharedLockMap;

    public MaintenanceNumberOfVdssCommand(T parameters) {
        super(parameters);
        Iterable<Guid> vdsIdList = getParameters().getVdsIdList();
        inspectedEntitiesMap = new ArrayList<PermissionSubject>();
        for (Guid g : vdsIdList) {
            inspectedEntitiesMap.add(new PermissionSubject(g,
                    VdcObjectType.VDS,
                    getActionType().getActionGroup()));
        }
    }

    private void MoveVdssToGoingToMaintenanceMode() {
        List<VDS> spms = new ArrayList<VDS>();
        for (VDS vds : vdssToMaintenance.values()) {
            if (vds.getSpmStatus() != VdsSpmStatus.SPM) {
                setVdsStatusToPrepareForMaintaice(vds);
            } else {
                spms.add(vds);
            }
        }
        for (VDS vds : spms) {
            setVdsStatusToPrepareForMaintaice(vds);
        }
        freeLock();
    }

    private void setVdsStatusToPrepareForMaintaice(VDS vds) {
        if (vds.getStatus() != VDSStatus.PreparingForMaintenance && vds.getStatus() != VDSStatus.NonResponsive
                && vds.getStatus() != VDSStatus.Down) {
            runVdsCommand(VDSCommandType.SetVdsStatus,
                    new SetVdsStatusVDSCommandParameters(vds.getId(), VDSStatus.PreparingForMaintenance));
        }
    }

    private void MigrateAllVdss() {
        for (Guid vdsId : getParameters().getVdsIdList()) {
            // ParametersCurrentUser = CurrentUser
            MaintenanceVdsParameters tempVar = new MaintenanceVdsParameters(vdsId, getParameters().getIsInternal());
            tempVar.setSessionId(getParameters().getSessionId());
            tempVar.setCorrelationId(getParameters().getCorrelationId());
            VdcReturnValueBase result =
                    Backend.getInstance().runInternalAction(VdcActionType.MaintenanceVds,
                            tempVar,
                            ExecutionHandler.createInternalJobContext());
            if (!result.getCanDoAction()) {
                getReturnValue().getCanDoActionMessages().addAll(result.getCanDoActionMessages());
                getReturnValue().setCanDoAction(false);
            }
        }
    }

    @Override
    protected void setActionMessageParameters() {
        addCanDoActionMessage(VdcBllMessages.VAR__TYPE__HOST);
        addCanDoActionMessage(VdcBllMessages.VAR__ACTION__MAINTENANCE);
    }

    @Override
    protected void executeCommand() {
        MoveVdssToGoingToMaintenanceMode();
        MigrateAllVdss();
        // set network to operational / non-operational
        for (Guid id : _vdsGroupIds) {
            List<Network> networks = DbFacade.getInstance().getNetworkDao().getAllForCluster(id);
            for (Network net : networks) {
                NetworkClusterHelper.setStatus(id, net);
            }
        }
        setSucceeded(true);
    }

    @Override
    protected boolean canDoAction() {
        boolean result = true;
        _vdsGroupIds = new ArrayList<Guid>();
        Set<Guid> vdsWithRunningVMs = new HashSet<Guid>();
        List<String> hostNotRespondingList = new ArrayList<String>();
        List<String> hostsWithNonMigratableVms = new ArrayList<String>();
        List<String> nonMigratableVms = new ArrayList<String>();

        for (Guid vdsId : getParameters().getVdsIdList()) {
            VDS vds = DbFacade.getInstance().getVdsDao().get(vdsId);
            if (vds == null) {
                log.error(String.format("ResourceManager::vdsMaintenance could not find vds_id = '%1$s'", vdsId));
                addCanDoActionMessage(VdcBllMessages.VDS_INVALID_SERVER_ID);
                result = false;
                continue;
            }
            if (!vdssToMaintenance.containsKey(vdsId)) {
                vdssToMaintenance.put(vdsId, vds);
                if (vds.getSpmStatus() == VdsSpmStatus.SPM) {
                    addSharedLockEntry(vds);
                }
            }
        }
        result = result && acquireLockInternal();
        if (result) {
            // check if one of the target vdss is spm, if so check that there are no
            // tasks running
            for (Guid vdsId : getParameters().getVdsIdList()) {
                VDS vds = vdssToMaintenance.get(vdsId);
                if (vds != null) {
                    List<VM> vms = getVmDAO().getAllRunningForVds(vdsId);
                    if ((vds.getStatus() != VDSStatus.Maintenance) && (vds.getStatus() != VDSStatus.NonResponsive)
                            && (vds.getStatus() != VDSStatus.Up) && (vds.getStatus() != VDSStatus.Error)
                            && (vds.getStatus() != VDSStatus.PreparingForMaintenance)
                            && (vds.getStatus() != VDSStatus.Down)) {
                        result = false;
                        addCanDoActionMessage(VdcBllMessages.VDS_CANNOT_MAINTENANCE_VDS_IS_NOT_OPERATIONAL.toString());
                    }
                    else {
                        if (vms.size() > 0) {
                            vdsWithRunningVMs.add(vdsId);
                        }
                        _vdsGroupIds.add(vds.getVdsGroupId());
                        List<String> nonMigratableVmDescriptionsToFrontEnd = new ArrayList<String>();
                        for (VM vm : vms) {
                            if (vm.getMigrationSupport() != MigrationSupport.MIGRATABLE) {
                                nonMigratableVmDescriptionsToFrontEnd.add(vm.getName());
                            }
                        }

                        if (nonMigratableVmDescriptionsToFrontEnd.size() > 0) {
                            hostsWithNonMigratableVms.add(vds.getName());
                            nonMigratableVms.addAll(nonMigratableVmDescriptionsToFrontEnd);

                            // The non migratable VM names will be comma separated
                            log.error(String.format("VDS %1$s contains non migratable VMs", vdsId));
                            result = false;

                        } else if (vds.getStatus() == VDSStatus.Maintenance) {
                            addCanDoActionMessage(VdcBllMessages.VDS_CANNOT_MAINTENANCE_VDS_IS_IN_MAINTENANCE);
                            result = false;
                        } else if (vds.getSpmStatus() == VdsSpmStatus.Contending) {
                            addCanDoActionMessage(VdcBllMessages.VDS_CANNOT_MAINTENANCE_SPM_CONTENDING);
                            result = false;
                        } else if (vds.getStatus() == VDSStatus.NonResponsive && vds.getVmCount() > 0) {
                            result = false;
                            hostNotRespondingList.add(vds.getName());
                        } else if (vds.getStatus() == VDSStatus.NonResponsive
                                && vds.getSpmStatus() != VdsSpmStatus.None) {
                            result = false;
                            addCanDoActionMessage(VdcBllMessages.VDS_CANNOT_MAINTENANCE_VDS_IS_NOT_RESPONDING_AND_IS_SPM);
                        } else if (vds.getSpmStatus() == VdsSpmStatus.SPM && vds.getStatus() == VDSStatus.Up &&
                                getAsyncTaskDao().getAsyncTaskIdsByStoragePoolId(vds.getStoragePoolId()).size() > 0) {
                            addCanDoActionMessage(VdcBllMessages.VDS_CANNOT_MAINTENANCE_SPM_WITH_RUNNING_TASKS);
                            result = false;
                        }
                    }
                }
            }

            // If one of the host is non responsive with running VM's, add a CanDoAction message.
            handleNonResponsiveHosts(hostNotRespondingList);

            // If one of the vms is non migratable, add a CanDoAction message.
            handleNonMigratableVms(hostsWithNonMigratableVms, nonMigratableVms);
{'fraction_non_alphanumeric': 0.0963533480037724, 'fraction_numerical': 0.0026197212616577595, 'mean_word_length': 2.2688816578181195, 'pattern_counts': {'":': 0, '<': 53, '<?xml version=': 0, '>': 61, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 3, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2282876', 'n_tokens_mistral': 5588, 'n_tokens_neox': 5461, 'n_words': 850}