<commit_before>package io.cattle.platform.servicediscovery.upgrade.impl;

import static io.cattle.platform.core.model.tables.ServiceExposeMapTable.*;

import io.cattle.platform.activity.ActivityLog;
import io.cattle.platform.activity.ActivityService;
import io.cattle.platform.core.addon.InServiceUpgradeStrategy;
import io.cattle.platform.core.addon.RollingRestartStrategy;
import io.cattle.platform.core.addon.ServiceRestart;
import io.cattle.platform.core.addon.ServiceUpgradeStrategy;
import io.cattle.platform.core.addon.ToServiceUpgradeStrategy;
import io.cattle.platform.core.constants.CommonStatesConstants;
import io.cattle.platform.core.constants.HealthcheckConstants;
import io.cattle.platform.core.constants.InstanceConstants;
import io.cattle.platform.core.constants.ServiceConstants;
import io.cattle.platform.core.model.Instance;
import io.cattle.platform.core.model.Service;
import io.cattle.platform.core.model.ServiceExposeMap;
import io.cattle.platform.engine.process.ExitReason;
import io.cattle.platform.engine.process.impl.ProcessCancelException;
import io.cattle.platform.engine.process.impl.ProcessExecutionExitException;
import io.cattle.platform.json.JsonMapper;
import io.cattle.platform.lock.LockCallbackNoReturn;
import io.cattle.platform.lock.LockManager;
import io.cattle.platform.object.ObjectManager;
import io.cattle.platform.object.process.ObjectProcessManager;
import io.cattle.platform.object.resource.ResourceMonitor;
import io.cattle.platform.object.resource.ResourcePredicate;
import io.cattle.platform.object.util.DataAccessor;
import io.cattle.platform.process.common.util.ProcessUtils;
import io.cattle.platform.servicediscovery.api.dao.ServiceExposeMapDao;
import io.cattle.platform.servicediscovery.deployment.DeploymentManager;
import io.cattle.platform.servicediscovery.deployment.impl.lock.ServiceLock;
import io.cattle.platform.servicediscovery.service.ServiceDiscoveryService;
import io.cattle.platform.servicediscovery.upgrade.UpgradeManager;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.inject.Inject;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;

public class UpgradeManagerImpl implements UpgradeManager {

    private enum Type {
        ToUpgrade,
        ToCleanup,
        UpgradedUnmanaged,
    }

    @Inject
    ServiceExposeMapDao exposeMapDao;

    @Inject
    ObjectManager objectManager;

    @Inject
    DeploymentManager deploymentMgr;

    @Inject
    LockManager lockManager;

    @Inject
    ObjectProcessManager objectProcessMgr;

    @Inject
    ResourceMonitor resourceMntr;

    @Inject
    ServiceDiscoveryService serviceDiscoveryService;

    @Inject
    JsonMapper jsonMapper;

    @Inject
    ActivityService activityService;

    private static final long SLEEP = 1000L;

    protected void setUpgrade(ServiceExposeMap map, boolean upgrade) {
        if (upgrade) {
            map.setUpgrade(true);
            map.setManaged(false);
        } else {
            map.setUpgrade(false);
            map.setManaged(true);
        }
        objectManager.persist(map);
    }

    public boolean doInServiceUpgrade(Service service, InServiceUpgradeStrategy strategy, boolean isUpgrade, String currentProcess) {
        long batchSize = strategy.getBatchSize();
        boolean startFirst = strategy.getStartFirst();

        Map<String, List<Instance>> deploymentUnitInstancesToUpgrade = formDeploymentUnitsForUpgrade(service,
                Type.ToUpgrade, isUpgrade, strategy);

        Map<String, List<Instance>> deploymentUnitInstancesUpgradedUnmanaged = formDeploymentUnitsForUpgrade(
                service,
                Type.UpgradedUnmanaged, isUpgrade, strategy);

        Map<String, List<Instance>> deploymentUnitInstancesToCleanup = formDeploymentUnitsForUpgrade(service,
                Type.ToCleanup, isUpgrade, strategy);

        // upgrade deployment units
        upgradeDeploymentUnits(service, deploymentUnitInstancesToUpgrade, deploymentUnitInstancesUpgradedUnmanaged,
                deploymentUnitInstancesToCleanup,
                batchSize, startFirst, preseveDeploymentUnit(service, strategy), isUpgrade, currentProcess, strategy);

        // check if empty
        if (deploymentUnitInstancesToUpgrade.isEmpty()) {
            deploymentMgr.activate(service);
            return true;
        }
        return false;
    }

    protected boolean preseveDeploymentUnit(Service service, InServiceUpgradeStrategy strategy) {
        boolean isServiceIndexDUStrategy = StringUtils.equalsIgnoreCase(
                ServiceConstants.SERVICE_INDEX_DU_STRATEGY,
                DataAccessor.fieldString(service, ServiceConstants.FIELD_SERVICE_INDEX_STRATEGY));
        return isServiceIndexDUStrategy || !strategy.isFullUpgrade();
    }

    protected void upgradeDeploymentUnits(final Service service,
            final Map<String, List<Instance>> deploymentUnitInstancesToUpgrade,
            final Map<String, List<Instance>> deploymentUnitInstancesUpgradedUnmanaged,
            final Map<String, List<Instance>> deploymentUnitInstancesToCleanup,
            final long batchSize,
            final boolean startFirst, final boolean preseveDeploymentUnit, final boolean isUpgrade,
            final String currentProcess, final InServiceUpgradeStrategy strategy) {
        // hold the lock so service.reconcile triggered by config.update
        // (in turn triggered by instance.remove) won't interfere
        lockManager.lock(new ServiceLock(service), new LockCallbackNoReturn() {
            @Override
            public void doWithLockNoResult() {
                // wait for healthy only for upgrade
                // should be skipped for rollback
                if (isUpgrade) {
                    deploymentMgr.activate(service);
                    waitForHealthyState(service, currentProcess, strategy);
                }
                // mark for upgrade
                markForUpgrade(batchSize);

                if (startFirst) {<commit_msg>Ensure stop before proceeding with upgrade<commit_after>package io.cattle.platform.servicediscovery.upgrade.impl;

import static io.cattle.platform.core.model.tables.ServiceExposeMapTable.*;

import io.cattle.platform.activity.ActivityLog;
import io.cattle.platform.activity.ActivityService;
import io.cattle.platform.core.addon.InServiceUpgradeStrategy;
import io.cattle.platform.core.addon.RollingRestartStrategy;
import io.cattle.platform.core.addon.ServiceRestart;
import io.cattle.platform.core.addon.ServiceUpgradeStrategy;
import io.cattle.platform.core.addon.ToServiceUpgradeStrategy;
import io.cattle.platform.core.constants.CommonStatesConstants;
import io.cattle.platform.core.constants.HealthcheckConstants;
import io.cattle.platform.core.constants.InstanceConstants;
import io.cattle.platform.core.constants.ServiceConstants;
import io.cattle.platform.core.model.Instance;
import io.cattle.platform.core.model.Service;
import io.cattle.platform.core.model.ServiceExposeMap;
import io.cattle.platform.engine.process.ExitReason;
import io.cattle.platform.engine.process.impl.ProcessCancelException;
import io.cattle.platform.engine.process.impl.ProcessExecutionExitException;
import io.cattle.platform.json.JsonMapper;
import io.cattle.platform.lock.LockCallbackNoReturn;
import io.cattle.platform.lock.LockManager;
import io.cattle.platform.object.ObjectManager;
import io.cattle.platform.object.process.ObjectProcessManager;
import io.cattle.platform.object.resource.ResourceMonitor;
import io.cattle.platform.object.resource.ResourcePredicate;
import io.cattle.platform.object.util.DataAccessor;
import io.cattle.platform.process.common.util.ProcessUtils;
import io.cattle.platform.servicediscovery.api.dao.ServiceExposeMapDao;
import io.cattle.platform.servicediscovery.deployment.DeploymentManager;
import io.cattle.platform.servicediscovery.deployment.impl.lock.ServiceLock;
import io.cattle.platform.servicediscovery.service.ServiceDiscoveryService;
import io.cattle.platform.servicediscovery.upgrade.UpgradeManager;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.inject.Inject;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;

public class UpgradeManagerImpl implements UpgradeManager {

    private enum Type {
        ToUpgrade,
        ToCleanup,
        UpgradedUnmanaged,
    }

    @Inject
    ServiceExposeMapDao exposeMapDao;

    @Inject
    ObjectManager objectManager;

    @Inject
    DeploymentManager deploymentMgr;

    @Inject
    LockManager lockManager;

    @Inject
    ObjectProcessManager objectProcessMgr;

    @Inject
    ResourceMonitor resourceMntr;

    @Inject
    ServiceDiscoveryService serviceDiscoveryService;

    @Inject
    JsonMapper jsonMapper;

    @Inject
    ActivityService activityService;

    private static final long SLEEP = 1000L;

    protected void setUpgrade(ServiceExposeMap map, boolean upgrade) {
        if (upgrade) {
            map.setUpgrade(true);
            map.setManaged(false);
        } else {
            map.setUpgrade(false);
            map.setManaged(true);
        }
        objectManager.persist(map);
    }

    public boolean doInServiceUpgrade(Service service, InServiceUpgradeStrategy strategy, boolean isUpgrade, String currentProcess) {
        long batchSize = strategy.getBatchSize();
        boolean startFirst = strategy.getStartFirst();

        Map<String, List<Instance>> deploymentUnitInstancesToUpgrade = formDeploymentUnitsForUpgrade(service,
                Type.ToUpgrade, isUpgrade, strategy);

        Map<String, List<Instance>> deploymentUnitInstancesUpgradedUnmanaged = formDeploymentUnitsForUpgrade(
                service,
                Type.UpgradedUnmanaged, isUpgrade, strategy);

        Map<String, List<Instance>> deploymentUnitInstancesToCleanup = formDeploymentUnitsForUpgrade(service,
                Type.ToCleanup, isUpgrade, strategy);

        // upgrade deployment units
        upgradeDeploymentUnits(service, deploymentUnitInstancesToUpgrade, deploymentUnitInstancesUpgradedUnmanaged,
                deploymentUnitInstancesToCleanup,
                batchSize, startFirst, preseveDeploymentUnit(service, strategy), isUpgrade, currentProcess, strategy);

        // check if empty
        if (deploymentUnitInstancesToUpgrade.isEmpty()) {
            deploymentMgr.activate(service);
            return true;
        }
        return false;
    }

    protected boolean preseveDeploymentUnit(Service service, InServiceUpgradeStrategy strategy) {
        boolean isServiceIndexDUStrategy = StringUtils.equalsIgnoreCase(
                ServiceConstants.SERVICE_INDEX_DU_STRATEGY,
                DataAccessor.fieldString(service, ServiceConstants.FIELD_SERVICE_INDEX_STRATEGY));
        return isServiceIndexDUStrategy || !strategy.isFullUpgrade();
    }

    protected void upgradeDeploymentUnits(final Service service,
            final Map<String, List<Instance>> deploymentUnitInstancesToUpgrade,
            final Map<String, List<Instance>> deploymentUnitInstancesUpgradedUnmanaged,
            final Map<String, List<Instance>> deploymentUnitInstancesToCleanup,
            final long batchSize,
            final boolean startFirst, final boolean preseveDeploymentUnit, final boolean isUpgrade,
            final String currentProcess, final InServiceUpgradeStrategy strategy) {
        // hold the lock so service.reconcile triggered by config.update
        // (in turn triggered by instance.remove) won't interfere
        lockManager.lock(new ServiceLock(service), new LockCallbackNoReturn() {
            @Override
            public void doWithLockNoResult() {
                // make sure that all instances that were meant to be stopped
                // by the previous batch upgrade, are stopped before proceeding
                stopInstances(service, deploymentUnitInstancesToCleanup);
                // wait for healthy only for upgrade
                // should be skipped for rollback
                if (isUpgrade) {
                    deploymentMgr.activate(service);
                    waitForHealthyState(service, currentProcess, strategy);
                }
                // mark for upgrade
                markForUpgrade(batchSize);

                if (startFirst) {
{'fraction_non_alphanumeric': 0.0771563073485997, 'fraction_numerical': 0.0009574722731987553, 'mean_word_length': 3.561135371179039, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '425990', 'n_tokens_mistral': 3349, 'n_tokens_neox': 3298, 'n_words': 629}