Fix circular rollout dependencies (#1337)

* Do some refactoring to fix dependencies between rollout management, executor and evaluator beans.
* Move rollout retrieving in same transaction as execution.
* Do some refactoring. Extend logging and exception handling.
* Remove unnecessary transactional and validation annotations.
* remove catching never thrown bean
* Fix new rollout handling API
This commit is contained in:
Michael Herdt
2023-04-03 09:13:00 +02:00
committed by GitHub
parent 17bf633df9
commit fbda9764b1
29 changed files with 537 additions and 352 deletions

View File

@@ -460,15 +460,11 @@ public class AmqpMessageDispatcherServiceIntegrationTest extends AbstractAmqpSer
return ds.getModules().stream().map(SoftwareModule::getId).collect(Collectors.toSet()); return ds.getModules().stream().map(SoftwareModule::getId).collect(Collectors.toSet());
} }
private Rollout createAndStartRollout(final DistributionSet ds, final String filterQuery) {
return createAndStartRollout(ds, filterQuery, null);
}
private Rollout createAndStartRollout(final DistributionSet ds, final String filterQuery, final Integer weight) { private Rollout createAndStartRollout(final DistributionSet ds, final String filterQuery, final Integer weight) {
final Rollout rollout = testdataFactory.createRolloutByVariables(UUID.randomUUID().toString(), "", 1, final Rollout rollout = testdataFactory.createRolloutByVariables(UUID.randomUUID().toString(), "", 1,
filterQuery, ds, "50", "5", ActionType.FORCED, weight, false); filterQuery, ds, "50", "5", ActionType.FORCED, weight, false);
rolloutManagement.start(rollout.getId()); rolloutManagement.start(rollout.getId());
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
return rollout; return rollout;
} }

View File

@@ -0,0 +1,52 @@
/**
* Copyright (c) 2023 Bosch.IO GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository;
import static org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions;
import org.eclipse.hawkbit.repository.model.Rollout;
import org.eclipse.hawkbit.repository.model.RolloutGroup;
import org.eclipse.hawkbit.repository.model.Target;
import org.springframework.security.access.prepost.PreAuthorize;
/**
* Represents the handler service for creating, deleting, and starting a Rollout
*/
@FunctionalInterface
public interface RolloutHandler {
/**
* Process rollout based on its current {@link Rollout#getStatus()}.
*
* For {@link Rollout.RolloutStatus#CREATING} that means creating the
* {@link RolloutGroup}s with {@link Target}s and when finished switch to
* {@link Rollout.RolloutStatus#READY}.
*
* For {@link Rollout.RolloutStatus#READY} that means switching to
* {@link Rollout.RolloutStatus#STARTING} if the {@link Rollout#getStartAt()} is
* set and time of calling this method is beyond this point in time. This auto
* start mechanism is optional. Call {@link RolloutManagement#start(long)} otherwise.
*
* For {@link Rollout.RolloutStatus#STARTING} that means starting the first
* {@link RolloutGroup}s in line and when finished switch to
* {@link Rollout.RolloutStatus#RUNNING}.
*
* For {@link Rollout.RolloutStatus#RUNNING} that means checking to activate
* further groups based on the defined thresholds. Switched to
* {@link Rollout.RolloutStatus#FINISHED} is all groups are finished.
*
* For {@link Rollout.RolloutStatus#DELETING} that means either soft delete in
* case rollout was already {@link Rollout.RolloutStatus#RUNNING} which results
* in status change {@link Rollout.RolloutStatus#DELETED} or hard delete from
* the persistence otherwise.
*
*/
@PreAuthorize(SpringEvalExpressions.IS_SYSTEM_CODE)
void handleAll();
}

View File

@@ -33,7 +33,6 @@ import org.eclipse.hawkbit.repository.model.RolloutGroup;
import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupStatus; import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupStatus;
import org.eclipse.hawkbit.repository.model.RolloutGroupConditions; import org.eclipse.hawkbit.repository.model.RolloutGroupConditions;
import org.eclipse.hawkbit.repository.model.RolloutGroupsValidation; import org.eclipse.hawkbit.repository.model.RolloutGroupsValidation;
import org.eclipse.hawkbit.repository.model.Target;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice; import org.springframework.data.domain.Slice;
@@ -48,37 +47,7 @@ import org.springframework.util.concurrent.ListenableFuture;
public interface RolloutManagement { public interface RolloutManagement {
/** /**
* Process rollout based on its current {@link Rollout#getStatus()}. * Counts all {@link Rollout}s in the repository that are not marked as deleted.
*
* For {@link RolloutStatus#CREATING} that means creating the
* {@link RolloutGroup}s with {@link Target}s and when finished switch to
* {@link RolloutStatus#READY}.
*
* For {@link RolloutStatus#READY} that means switching to
* {@link RolloutStatus#STARTING} if the {@link Rollout#getStartAt()} is set
* and time of calling this method is beyond this point in time. This auto
* start mechanism is optional. Call {@link #start(Long)} otherwise.
*
* For {@link RolloutStatus#STARTING} that means starting the first
* {@link RolloutGroup}s in line and when finished switch to
* {@link RolloutStatus#RUNNING}.
*
* For {@link RolloutStatus#RUNNING} that means checking to activate further
* groups based on the defined thresholds. Switched to
* {@link RolloutStatus#FINISHED} is all groups are finished.
*
* For {@link RolloutStatus#DELETING} that means either soft delete in case
* rollout was already {@link RolloutStatus#RUNNING} which results in status
* change {@link RolloutStatus#DELETED} or hard delete from the persistence
* otherwise.
*
*/
@PreAuthorize(SpringEvalExpressions.IS_SYSTEM_CODE)
void handleRollouts();
/**
* Counts all {@link Rollout}s in the repository that are not marked as
* deleted.
* *
* @return number of roll outs * @return number of roll outs
*/ */
@@ -267,6 +236,14 @@ public interface RolloutManagement {
Slice<Rollout> findByFiltersWithDetailedStatus(@NotNull Pageable pageable, @NotEmpty String searchText, Slice<Rollout> findByFiltersWithDetailedStatus(@NotNull Pageable pageable, @NotEmpty String searchText,
boolean deleted); boolean deleted);
/**
* Find rollouts which are still active and needs to be handled.
*
* @return a list of active rollouts
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ)
List<Long> findActiveRollouts();
/** /**
* Retrieves a specific rollout by its ID. * Retrieves a specific rollout by its ID.
* *

View File

@@ -157,40 +157,14 @@ public interface RolloutGroup extends NamedEntity {
* The condition to evaluate if an group is success state. * The condition to evaluate if an group is success state.
*/ */
enum RolloutGroupSuccessCondition { enum RolloutGroupSuccessCondition {
THRESHOLD("thresholdRolloutGroupSuccessCondition"); THRESHOLD
private final String beanName;
RolloutGroupSuccessCondition(final String beanName) {
this.beanName = beanName;
}
/**
* @return the beanName
*/
public String getBeanName() {
return beanName;
}
} }
/** /**
* The condition to evaluate if an group is in error state. * The condition to evaluate if an group is in error state.
*/ */
enum RolloutGroupErrorCondition { enum RolloutGroupErrorCondition {
THRESHOLD("thresholdRolloutGroupErrorCondition"); THRESHOLD
private final String beanName;
RolloutGroupErrorCondition(final String beanName) {
this.beanName = beanName;
}
/**
* @return the beanName
*/
public String getBeanName() {
return beanName;
}
} }
/** /**
@@ -198,20 +172,7 @@ public interface RolloutGroup extends NamedEntity {
* hit. * hit.
*/ */
enum RolloutGroupErrorAction { enum RolloutGroupErrorAction {
PAUSE("pauseRolloutGroupAction"); PAUSE
private final String beanName;
RolloutGroupErrorAction(final String beanName) {
this.beanName = beanName;
}
/**
* @return the beanName
*/
public String getBeanName() {
return beanName;
}
} }
/** /**
@@ -219,19 +180,6 @@ public interface RolloutGroup extends NamedEntity {
* is hit. * is hit.
*/ */
enum RolloutGroupSuccessAction { enum RolloutGroupSuccessAction {
NEXTGROUP("startNextRolloutGroupAction"); NEXTGROUP
private final String beanName;
RolloutGroupSuccessAction(final String beanName) {
this.beanName = beanName;
}
/**
* @return the beanName
*/
public String getBeanName() {
return beanName;
}
} }
} }

View File

@@ -34,8 +34,8 @@ import org.eclipse.hawkbit.repository.jpa.model.JpaAction;
import org.eclipse.hawkbit.repository.jpa.model.JpaRollout; import org.eclipse.hawkbit.repository.jpa.model.JpaRollout;
import org.eclipse.hawkbit.repository.jpa.model.JpaRolloutGroup; import org.eclipse.hawkbit.repository.jpa.model.JpaRolloutGroup;
import org.eclipse.hawkbit.repository.jpa.model.RolloutTargetGroup; import org.eclipse.hawkbit.repository.jpa.model.RolloutTargetGroup;
import org.eclipse.hawkbit.repository.jpa.rollout.condition.RolloutGroupActionEvaluator; import org.eclipse.hawkbit.repository.jpa.rollout.condition.EvaluatorNotConfiguredException;
import org.eclipse.hawkbit.repository.jpa.rollout.condition.RolloutGroupConditionEvaluator; import org.eclipse.hawkbit.repository.jpa.rollout.condition.RolloutGroupEvaluationManager;
import org.eclipse.hawkbit.repository.jpa.utils.DeploymentHelper; import org.eclipse.hawkbit.repository.jpa.utils.DeploymentHelper;
import org.eclipse.hawkbit.repository.jpa.utils.QuotaHelper; import org.eclipse.hawkbit.repository.jpa.utils.QuotaHelper;
import org.eclipse.hawkbit.repository.model.Action; import org.eclipse.hawkbit.repository.model.Action;
@@ -53,8 +53,6 @@ import org.eclipse.hawkbit.repository.model.helper.EventPublisherHolder;
import org.eclipse.hawkbit.tenancy.TenantAware; import org.eclipse.hawkbit.tenancy.TenantAware;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Slice; import org.springframework.data.domain.Slice;
import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort;
@@ -105,7 +103,8 @@ public class JpaRolloutExecutor implements RolloutExecutor {
private final EventPublisherHolder eventPublisherHolder; private final EventPublisherHolder eventPublisherHolder;
private final PlatformTransactionManager txManager; private final PlatformTransactionManager txManager;
private final RolloutApprovalStrategy rolloutApprovalStrategy; private final RolloutApprovalStrategy rolloutApprovalStrategy;
private final ApplicationContext context; private final RolloutGroupEvaluationManager evaluationManager;
private final RolloutManagement rolloutManagement;
/** /**
* Constructor * Constructor
@@ -117,7 +116,8 @@ public class JpaRolloutExecutor implements RolloutExecutor {
final RolloutGroupManagement rolloutGroupManagement, final QuotaManagement quotaManagement, final RolloutGroupManagement rolloutGroupManagement, final QuotaManagement quotaManagement,
final DeploymentManagement deploymentManagement, final TargetManagement targetManagement, final DeploymentManagement deploymentManagement, final TargetManagement targetManagement,
final EventPublisherHolder eventPublisherHolder, final PlatformTransactionManager txManager, final EventPublisherHolder eventPublisherHolder, final PlatformTransactionManager txManager,
final RolloutApprovalStrategy rolloutApprovalStrategy, final ApplicationContext context) { final RolloutApprovalStrategy rolloutApprovalStrategy,
final RolloutGroupEvaluationManager evaluationManager, final RolloutManagement rolloutManagement) {
this.rolloutTargetGroupRepository = rolloutTargetGroupRepository; this.rolloutTargetGroupRepository = rolloutTargetGroupRepository;
this.entityManager = entityManager; this.entityManager = entityManager;
this.rolloutRepository = rolloutRepository; this.rolloutRepository = rolloutRepository;
@@ -132,7 +132,8 @@ public class JpaRolloutExecutor implements RolloutExecutor {
this.eventPublisherHolder = eventPublisherHolder; this.eventPublisherHolder = eventPublisherHolder;
this.txManager = txManager; this.txManager = txManager;
this.rolloutApprovalStrategy = rolloutApprovalStrategy; this.rolloutApprovalStrategy = rolloutApprovalStrategy;
this.context = context; this.evaluationManager = evaluationManager;
this.rolloutManagement = rolloutManagement;
} }
@Override @Override
@@ -285,7 +286,7 @@ public class JpaRolloutExecutor implements RolloutExecutor {
LOGGER.debug( LOGGER.debug(
"handleReadyRollout called for rollout {} with autostart beyond define time. Switch to STARTING", "handleReadyRollout called for rollout {} with autostart beyond define time. Switch to STARTING",
rollout.getId()); rollout.getId());
context.getBean(RolloutManagement.class).start(rollout.getId()); rolloutManagement.start(rollout.getId());
} }
} }
@@ -417,11 +418,10 @@ public class JpaRolloutExecutor implements RolloutExecutor {
private void callErrorAction(final Rollout rollout, final RolloutGroup rolloutGroup) { private void callErrorAction(final Rollout rollout, final RolloutGroup rolloutGroup) {
try { try {
context.getBean(rolloutGroup.getErrorAction().getBeanName(), RolloutGroupActionEvaluator.class) evaluationManager.getErrorActionEvaluator(rolloutGroup.getErrorAction()).exec(rollout, rolloutGroup);
.eval(rollout, rolloutGroup, rolloutGroup.getErrorActionExp()); } catch (final EvaluatorNotConfiguredException e) {
} catch (final BeansException e) { LOGGER.error("Something bad happened when accessing the error action bean {}",
LOGGER.error("Something bad happend when accessing the error action bean {}", rolloutGroup.getErrorAction().name(), e);
rolloutGroup.getErrorAction().getBeanName(), e);
} }
} }
@@ -443,11 +443,10 @@ public class JpaRolloutExecutor implements RolloutExecutor {
return false; return false;
} }
try { try {
return context.getBean(errorCondition.getBeanName(), RolloutGroupConditionEvaluator.class).eval(rollout, return evaluationManager.getErrorConditionEvaluator(errorCondition).eval(rollout, rolloutGroup,
rolloutGroup, rolloutGroup.getErrorConditionExp()); rolloutGroup.getErrorConditionExp());
} catch (final BeansException e) { } catch (final EvaluatorNotConfiguredException e) {
LOGGER.error("Something bad happend when accessing the error condition bean {}", LOGGER.error("Something bad happened when accessing the error condition bean {}", errorCondition.name(), e);
errorCondition.getBeanName(), e);
return false; return false;
} }
} }
@@ -456,9 +455,8 @@ public class JpaRolloutExecutor implements RolloutExecutor {
final RolloutGroupSuccessCondition finishCondition) { final RolloutGroupSuccessCondition finishCondition) {
LOGGER.trace("Checking finish condition {} on rolloutgroup {}", finishCondition, rolloutGroup); LOGGER.trace("Checking finish condition {} on rolloutgroup {}", finishCondition, rolloutGroup);
try { try {
final boolean isFinished = context final boolean isFinished = evaluationManager.getSuccessConditionEvaluator(finishCondition).eval(rollout,
.getBean(finishCondition.getBeanName(), RolloutGroupConditionEvaluator.class) rolloutGroup, rolloutGroup.getSuccessConditionExp());
.eval(rollout, rolloutGroup, rolloutGroup.getSuccessConditionExp());
if (isFinished) { if (isFinished) {
LOGGER.debug("Rolloutgroup {} is finished, starting next group", rolloutGroup); LOGGER.debug("Rolloutgroup {} is finished, starting next group", rolloutGroup);
executeRolloutGroupSuccessAction(rollout, rolloutGroup); executeRolloutGroupSuccessAction(rollout, rolloutGroup);
@@ -466,16 +464,15 @@ public class JpaRolloutExecutor implements RolloutExecutor {
LOGGER.debug("Rolloutgroup {} is still running", rolloutGroup); LOGGER.debug("Rolloutgroup {} is still running", rolloutGroup);
} }
return isFinished; return isFinished;
} catch (final BeansException e) { } catch (final EvaluatorNotConfiguredException e) {
LOGGER.error("Something bad happend when accessing the finish condition bean {}", LOGGER.error("Something bad happened when accessing the finish condition or success action bean {}",
finishCondition.getBeanName(), e); finishCondition.name(), e);
return false; return false;
} }
} }
private void executeRolloutGroupSuccessAction(final Rollout rollout, final RolloutGroup rolloutGroup) { private void executeRolloutGroupSuccessAction(final Rollout rollout, final RolloutGroup rolloutGroup) {
context.getBean(rolloutGroup.getSuccessAction().getBeanName(), RolloutGroupActionEvaluator.class).eval(rollout, evaluationManager.getSuccessActionEvaluator(rolloutGroup.getSuccessAction()).exec(rollout, rolloutGroup);
rolloutGroup, rolloutGroup.getSuccessActionExp());
} }
private void startFirstRolloutGroup(final Rollout rollout) { private void startFirstRolloutGroup(final Rollout rollout) {

View File

@@ -0,0 +1,109 @@
/**
* Copyright (c) 2023 Bosch.IO GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.jpa;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.locks.Lock;
import org.eclipse.hawkbit.repository.RolloutExecutor;
import org.eclipse.hawkbit.repository.RolloutHandler;
import org.eclipse.hawkbit.repository.RolloutManagement;
import org.eclipse.hawkbit.repository.jpa.utils.DeploymentHelper;
import org.eclipse.hawkbit.repository.model.BaseEntity;
import org.eclipse.hawkbit.tenancy.TenantAware;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.integration.support.locks.LockRegistry;
import org.springframework.transaction.PlatformTransactionManager;
/**
* JPA implementation of {@link RolloutHandler}.
*/
public class JpaRolloutHandler implements RolloutHandler {
private static final Logger LOGGER = LoggerFactory.getLogger(JpaRolloutHandler.class);
private final TenantAware tenantAware;
private final RolloutManagement rolloutManagement;
private final RolloutExecutor rolloutExecutor;
private final LockRegistry lockRegistry;
private final PlatformTransactionManager txManager;
/**
* Constructor
*
* @param tenantAware
* the {@link TenantAware} bean holding the tenant information
* @param rolloutManagement
* to fetch rollout related information from the datasource
* @param rolloutExecutor
* to trigger executions for a specific rollout
* @param lockRegistry
* to lock processes
* @param txManager
* transaction manager interface
*/
public JpaRolloutHandler(final TenantAware tenantAware, final RolloutManagement rolloutManagement,
final RolloutExecutor rolloutExecutor, final LockRegistry lockRegistry,
final PlatformTransactionManager txManager) {
this.tenantAware = tenantAware;
this.rolloutManagement = rolloutManagement;
this.rolloutExecutor = rolloutExecutor;
this.lockRegistry = lockRegistry;
this.txManager = txManager;
}
@Override
public void handleAll() {
final List<Long> rollouts = rolloutManagement.findActiveRollouts();
if (rollouts.isEmpty()) {
return;
}
final String handlerId = createRolloutLockKey(tenantAware.getCurrentTenant());
final Lock lock = lockRegistry.obtain(handlerId);
if (!lock.tryLock()) {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Could not perform lock {}", lock);
}
return;
}
try {
LOGGER.trace("Trigger handling {} rollouts.", rollouts.size());
rollouts.forEach(rolloutId -> handleRolloutInNewTransaction(rolloutId, handlerId));
} finally {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Unlock lock {}", lock);
}
lock.unlock();
}
}
private static String createRolloutLockKey(final String tenant) {
return tenant + "-rollout";
}
private void handleRolloutInNewTransaction(final long rolloutId, final String handlerId) {
DeploymentHelper.runInNewTransaction(txManager, handlerId + "-" + rolloutId, status -> {
rolloutManagement.get(rolloutId).ifPresentOrElse(
rollout -> runInUserContext(rollout, () -> rolloutExecutor.execute(rollout)),
() -> LOGGER.error("Could not retrieve rollout with id {}. Will not continue with execution.",
rolloutId));
return 0L;
});
}
private void runInUserContext(final BaseEntity rollout, final Runnable handler) {
DeploymentHelper.runInNonSystemContext(handler, () -> Objects.requireNonNull(rollout.getCreatedBy()),
tenantAware);
}
}

View File

@@ -16,9 +16,7 @@ import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.locks.Lock;
import java.util.function.Function; import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@@ -28,7 +26,6 @@ import javax.validation.ValidationException;
import org.eclipse.hawkbit.repository.DistributionSetManagement; import org.eclipse.hawkbit.repository.DistributionSetManagement;
import org.eclipse.hawkbit.repository.QuotaManagement; import org.eclipse.hawkbit.repository.QuotaManagement;
import org.eclipse.hawkbit.repository.RolloutApprovalStrategy; import org.eclipse.hawkbit.repository.RolloutApprovalStrategy;
import org.eclipse.hawkbit.repository.RolloutExecutor;
import org.eclipse.hawkbit.repository.RolloutFields; import org.eclipse.hawkbit.repository.RolloutFields;
import org.eclipse.hawkbit.repository.RolloutHelper; import org.eclipse.hawkbit.repository.RolloutHelper;
import org.eclipse.hawkbit.repository.RolloutManagement; import org.eclipse.hawkbit.repository.RolloutManagement;
@@ -52,10 +49,8 @@ import org.eclipse.hawkbit.repository.jpa.model.JpaRollout_;
import org.eclipse.hawkbit.repository.jpa.rollout.condition.StartNextGroupRolloutGroupSuccessAction; import org.eclipse.hawkbit.repository.jpa.rollout.condition.StartNextGroupRolloutGroupSuccessAction;
import org.eclipse.hawkbit.repository.jpa.rsql.RSQLUtility; import org.eclipse.hawkbit.repository.jpa.rsql.RSQLUtility;
import org.eclipse.hawkbit.repository.jpa.specifications.RolloutSpecification; import org.eclipse.hawkbit.repository.jpa.specifications.RolloutSpecification;
import org.eclipse.hawkbit.repository.jpa.utils.DeploymentHelper;
import org.eclipse.hawkbit.repository.jpa.utils.QuotaHelper; import org.eclipse.hawkbit.repository.jpa.utils.QuotaHelper;
import org.eclipse.hawkbit.repository.jpa.utils.WeightValidationHelper; import org.eclipse.hawkbit.repository.jpa.utils.WeightValidationHelper;
import org.eclipse.hawkbit.repository.model.BaseEntity;
import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSetType; import org.eclipse.hawkbit.repository.model.DistributionSetType;
import org.eclipse.hawkbit.repository.model.Rollout; import org.eclipse.hawkbit.repository.model.Rollout;
@@ -70,8 +65,6 @@ import org.eclipse.hawkbit.repository.model.TotalTargetCountStatus;
import org.eclipse.hawkbit.repository.model.helper.EventPublisherHolder; import org.eclipse.hawkbit.repository.model.helper.EventPublisherHolder;
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer; import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
import org.eclipse.hawkbit.security.SystemSecurityContext; import org.eclipse.hawkbit.security.SystemSecurityContext;
import org.eclipse.hawkbit.tenancy.TenantAware;
import org.eclipse.hawkbit.utils.TenantConfigHelper;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@@ -82,14 +75,11 @@ import org.springframework.data.domain.Slice;
import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction; import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.jpa.domain.Specification; import org.springframework.data.jpa.domain.Specification;
import org.springframework.integration.support.locks.LockRegistry;
import org.springframework.orm.jpa.vendor.Database; import org.springframework.orm.jpa.vendor.Database;
import org.springframework.retry.annotation.Backoff; import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Retryable; import org.springframework.retry.annotation.Retryable;
import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult; import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import org.springframework.util.concurrent.ListenableFuture; import org.springframework.util.concurrent.ListenableFuture;
@@ -137,35 +127,26 @@ public class JpaRolloutManagement implements RolloutManagement {
private final TargetManagement targetManagement; private final TargetManagement targetManagement;
private final DistributionSetManagement distributionSetManagement; private final DistributionSetManagement distributionSetManagement;
private final VirtualPropertyReplacer virtualPropertyReplacer; private final VirtualPropertyReplacer virtualPropertyReplacer;
private final PlatformTransactionManager txManager;
private final TenantAware tenantAware;
private final LockRegistry lockRegistry;
private final RolloutApprovalStrategy rolloutApprovalStrategy; private final RolloutApprovalStrategy rolloutApprovalStrategy;
private final TenantConfigurationManagement tenantConfigurationManagement; private final TenantConfigurationManagement tenantConfigurationManagement;
private final SystemSecurityContext systemSecurityContext; private final SystemSecurityContext systemSecurityContext;
private final RolloutExecutor rolloutExecutor;
private final EventPublisherHolder eventPublisherHolder; private final EventPublisherHolder eventPublisherHolder;
private final Database database; private final Database database;
public JpaRolloutManagement(final TargetManagement targetManagement, public JpaRolloutManagement(final TargetManagement targetManagement,
final DistributionSetManagement distributionSetManagement, final EventPublisherHolder eventPublisherHolder, final DistributionSetManagement distributionSetManagement, final EventPublisherHolder eventPublisherHolder,
final VirtualPropertyReplacer virtualPropertyReplacer, final PlatformTransactionManager txManager, final VirtualPropertyReplacer virtualPropertyReplacer, final Database database,
final TenantAware tenantAware, final LockRegistry lockRegistry, final Database database,
final RolloutApprovalStrategy rolloutApprovalStrategy, final RolloutApprovalStrategy rolloutApprovalStrategy,
final TenantConfigurationManagement tenantConfigurationManagement, final TenantConfigurationManagement tenantConfigurationManagement,
final SystemSecurityContext systemSecurityContext, final RolloutExecutor rolloutExecutor) { final SystemSecurityContext systemSecurityContext) {
this.targetManagement = targetManagement; this.targetManagement = targetManagement;
this.distributionSetManagement = distributionSetManagement; this.distributionSetManagement = distributionSetManagement;
this.virtualPropertyReplacer = virtualPropertyReplacer; this.virtualPropertyReplacer = virtualPropertyReplacer;
this.txManager = txManager;
this.tenantAware = tenantAware;
this.lockRegistry = lockRegistry;
this.rolloutApprovalStrategy = rolloutApprovalStrategy; this.rolloutApprovalStrategy = rolloutApprovalStrategy;
this.tenantConfigurationManagement = tenantConfigurationManagement; this.tenantConfigurationManagement = tenantConfigurationManagement;
this.systemSecurityContext = systemSecurityContext; this.systemSecurityContext = systemSecurityContext;
this.eventPublisherHolder = eventPublisherHolder; this.eventPublisherHolder = eventPublisherHolder;
this.database = database; this.database = database;
this.rolloutExecutor = rolloutExecutor;
} }
@Override @Override
@@ -435,43 +416,10 @@ public class JpaRolloutManagement implements RolloutManagement {
rolloutRepository.save(rollout); rolloutRepository.save(rollout);
} }
@Override
// No transaction, will be created per handled rollout
@Transactional(propagation = Propagation.NEVER)
public void handleRollouts() {
final List<Long> rollouts = rolloutRepository.findByStatusIn(ACTIVE_ROLLOUTS);
if (rollouts.isEmpty()) {
return;
}
final String tenant = tenantAware.getCurrentTenant();
final String handlerId = createRolloutLockKey(tenant);
final Lock lock = lockRegistry.obtain(handlerId);
if (!lock.tryLock()) {
return;
}
try {
rollouts.forEach(rolloutId -> DeploymentHelper.runInNewTransaction(txManager, handlerId + "-" + rolloutId,
status -> handleRollout(rolloutId)));
} finally {
lock.unlock();
}
}
public static String createRolloutLockKey(final String tenant) { public static String createRolloutLockKey(final String tenant) {
return tenant + "-rollout"; return tenant + "-rollout";
} }
private long handleRollout(final long rolloutId) {
final JpaRollout rollout = rolloutRepository.findById(rolloutId)
.orElseThrow(() -> new EntityNotFoundException(Rollout.class, rolloutId));
runInUserContext(rollout, () -> rolloutExecutor.execute(rollout));
return 0;
}
@Override @Override
@Transactional @Transactional
@Retryable(include = { @Retryable(include = {
@@ -517,6 +465,11 @@ public class JpaRolloutManagement implements RolloutManagement {
return findAll; return findAll;
} }
@Override
public List<Long> findActiveRollouts() {
return rolloutRepository.findByStatusIn(ACTIVE_ROLLOUTS);
}
@Override @Override
public Optional<Rollout> getByName(final String rolloutName) { public Optional<Rollout> getByName(final String rolloutName) {
return rolloutRepository.findByName(rolloutName); return rolloutRepository.findByName(rolloutName);
@@ -649,11 +602,6 @@ public class JpaRolloutManagement implements RolloutManagement {
QuotaHelper.assertAssignmentQuota(requested, quota, Target.class, RolloutGroup.class); QuotaHelper.assertAssignmentQuota(requested, quota, Target.class, RolloutGroup.class);
} }
private void runInUserContext(final BaseEntity rollout, final Runnable handler) {
DeploymentHelper.runInNonSystemContext(handler, () -> Objects.requireNonNull(rollout.getCreatedBy()),
tenantAware);
}
@Override @Override
@Transactional @Transactional
public void cancelRolloutsForDistributionSet(final DistributionSet set) { public void cancelRolloutsForDistributionSet(final DistributionSet set) {
@@ -778,7 +726,7 @@ public class JpaRolloutManagement implements RolloutManagement {
.filter(g -> RolloutGroupStatus.RUNNING.equals(g.getStatus())).findFirst() .filter(g -> RolloutGroupStatus.RUNNING.equals(g.getStatus())).findFirst()
.orElseThrow(() -> new RolloutIllegalStateException("No group is running")); .orElseThrow(() -> new RolloutIllegalStateException("No group is running"));
startNextRolloutGroupAction.eval(rollout, latestRunning, latestRunning.getSuccessActionExp()); startNextRolloutGroupAction.exec(rollout, latestRunning);
} }
} }

View File

@@ -36,6 +36,7 @@ import org.eclipse.hawkbit.repository.RepositoryProperties;
import org.eclipse.hawkbit.repository.RolloutApprovalStrategy; import org.eclipse.hawkbit.repository.RolloutApprovalStrategy;
import org.eclipse.hawkbit.repository.RolloutExecutor; import org.eclipse.hawkbit.repository.RolloutExecutor;
import org.eclipse.hawkbit.repository.RolloutGroupManagement; import org.eclipse.hawkbit.repository.RolloutGroupManagement;
import org.eclipse.hawkbit.repository.RolloutHandler;
import org.eclipse.hawkbit.repository.RolloutManagement; import org.eclipse.hawkbit.repository.RolloutManagement;
import org.eclipse.hawkbit.repository.RolloutStatusCache; import org.eclipse.hawkbit.repository.RolloutStatusCache;
import org.eclipse.hawkbit.repository.SoftwareModuleManagement; import org.eclipse.hawkbit.repository.SoftwareModuleManagement;
@@ -84,6 +85,9 @@ import org.eclipse.hawkbit.repository.jpa.model.helper.SecurityTokenGeneratorHol
import org.eclipse.hawkbit.repository.jpa.model.helper.TenantAwareHolder; import org.eclipse.hawkbit.repository.jpa.model.helper.TenantAwareHolder;
import org.eclipse.hawkbit.repository.jpa.rollout.RolloutScheduler; import org.eclipse.hawkbit.repository.jpa.rollout.RolloutScheduler;
import org.eclipse.hawkbit.repository.jpa.rollout.condition.PauseRolloutGroupAction; import org.eclipse.hawkbit.repository.jpa.rollout.condition.PauseRolloutGroupAction;
import org.eclipse.hawkbit.repository.jpa.rollout.condition.RolloutGroupActionEvaluator;
import org.eclipse.hawkbit.repository.jpa.rollout.condition.RolloutGroupConditionEvaluator;
import org.eclipse.hawkbit.repository.jpa.rollout.condition.RolloutGroupEvaluationManager;
import org.eclipse.hawkbit.repository.jpa.rollout.condition.StartNextGroupRolloutGroupSuccessAction; import org.eclipse.hawkbit.repository.jpa.rollout.condition.StartNextGroupRolloutGroupSuccessAction;
import org.eclipse.hawkbit.repository.jpa.rollout.condition.ThresholdRolloutGroupErrorCondition; import org.eclipse.hawkbit.repository.jpa.rollout.condition.ThresholdRolloutGroupErrorCondition;
import org.eclipse.hawkbit.repository.jpa.rollout.condition.ThresholdRolloutGroupSuccessCondition; import org.eclipse.hawkbit.repository.jpa.rollout.condition.ThresholdRolloutGroupSuccessCondition;
@@ -92,6 +96,7 @@ import org.eclipse.hawkbit.repository.jpa.rsql.RsqlParserValidationOracle;
import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSetType; import org.eclipse.hawkbit.repository.model.DistributionSetType;
import org.eclipse.hawkbit.repository.model.Rollout; import org.eclipse.hawkbit.repository.model.Rollout;
import org.eclipse.hawkbit.repository.model.RolloutGroup;
import org.eclipse.hawkbit.repository.model.SoftwareModule; import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TargetFilterQuery; import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
@@ -119,7 +124,6 @@ import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration; import org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration;
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties; import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
import org.springframework.boot.autoconfigure.transaction.TransactionManagerCustomizers; import org.springframework.boot.autoconfigure.transaction.TransactionManagerCustomizers;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy; import org.springframework.context.annotation.EnableAspectJAutoProxy;
@@ -195,6 +199,16 @@ public class RepositoryApplicationConfiguration extends JpaBaseConfiguration {
return new ThresholdRolloutGroupSuccessCondition(actionRepository); return new ThresholdRolloutGroupSuccessCondition(actionRepository);
} }
@Bean
RolloutGroupEvaluationManager evaluationManager(
final List<RolloutGroupConditionEvaluator<RolloutGroup.RolloutGroupErrorCondition>> errorConditionEvaluators,
final List<RolloutGroupConditionEvaluator<RolloutGroup.RolloutGroupSuccessCondition>> successConditionEvaluators,
final List<RolloutGroupActionEvaluator<RolloutGroup.RolloutGroupErrorAction>> errorActionEvaluators,
final List<RolloutGroupActionEvaluator<RolloutGroup.RolloutGroupSuccessAction>> successActionEvaluators) {
return new RolloutGroupEvaluationManager(errorConditionEvaluators, successConditionEvaluators,
errorActionEvaluators, successActionEvaluators);
}
@Bean @Bean
@ConditionalOnMissingBean @ConditionalOnMissingBean
SystemManagementCacheKeyGenerator systemManagementCacheKeyGenerator() { SystemManagementCacheKeyGenerator systemManagementCacheKeyGenerator() {
@@ -661,6 +675,14 @@ public class RepositoryApplicationConfiguration extends JpaBaseConfiguration {
virtualPropertyReplacer, softwareModuleRepository, properties.getDatabase()); virtualPropertyReplacer, softwareModuleRepository, properties.getDatabase());
} }
@Bean
@ConditionalOnMissingBean
RolloutHandler rolloutHandler(final TenantAware tenantAware, final RolloutManagement rolloutManagement,
final RolloutExecutor rolloutExecutor, final LockRegistry lockRegistry,
final PlatformTransactionManager txManager) {
return new JpaRolloutHandler(tenantAware, rolloutManagement, rolloutExecutor, lockRegistry, txManager);
}
@Bean @Bean
@ConditionalOnMissingBean @ConditionalOnMissingBean
RolloutExecutor rolloutExecutor(final RolloutTargetGroupRepository rolloutTargetGroupRepository, RolloutExecutor rolloutExecutor(final RolloutTargetGroupRepository rolloutTargetGroupRepository,
@@ -670,25 +692,25 @@ public class RepositoryApplicationConfiguration extends JpaBaseConfiguration {
final RolloutGroupManagement rolloutGroupManagement, final QuotaManagement quotaManagement, final RolloutGroupManagement rolloutGroupManagement, final QuotaManagement quotaManagement,
final DeploymentManagement deploymentManagement, final TargetManagement targetManagement, final DeploymentManagement deploymentManagement, final TargetManagement targetManagement,
final EventPublisherHolder eventPublisherHolder, final PlatformTransactionManager txManager, final EventPublisherHolder eventPublisherHolder, final PlatformTransactionManager txManager,
final RolloutApprovalStrategy rolloutApprovalStrategy, final ApplicationContext context) { final RolloutApprovalStrategy rolloutApprovalStrategy,
final RolloutGroupEvaluationManager evaluationManager, final RolloutManagement rolloutManagement) {
return new JpaRolloutExecutor(rolloutTargetGroupRepository, entityManager, rolloutRepository, actionRepository, return new JpaRolloutExecutor(rolloutTargetGroupRepository, entityManager, rolloutRepository, actionRepository,
rolloutGroupRepository, afterCommit, tenantAware, rolloutGroupManagement, quotaManagement, rolloutGroupRepository, afterCommit, tenantAware, rolloutGroupManagement, quotaManagement,
deploymentManagement, targetManagement, eventPublisherHolder, txManager, rolloutApprovalStrategy, deploymentManagement, targetManagement, eventPublisherHolder, txManager, rolloutApprovalStrategy,
context); evaluationManager, rolloutManagement);
} }
@Bean @Bean
@ConditionalOnMissingBean @ConditionalOnMissingBean
RolloutManagement rolloutManagement(final TargetManagement targetManagement, RolloutManagement rolloutManagement(final TargetManagement targetManagement,
final DistributionSetManagement distributionSetManagement, final EventPublisherHolder eventPublisherHolder, final DistributionSetManagement distributionSetManagement, final EventPublisherHolder eventPublisherHolder,
final VirtualPropertyReplacer virtualPropertyReplacer, final PlatformTransactionManager txManager, final VirtualPropertyReplacer virtualPropertyReplacer, final JpaProperties properties,
final TenantAware tenantAware, final LockRegistry lockRegistry, final JpaProperties properties,
final RolloutApprovalStrategy rolloutApprovalStrategy, final RolloutApprovalStrategy rolloutApprovalStrategy,
final TenantConfigurationManagement tenantConfigurationManagement, final TenantConfigurationManagement tenantConfigurationManagement,
final SystemSecurityContext systemSecurityContext, final RolloutExecutor rolloutExecutor) { final SystemSecurityContext systemSecurityContext) {
return new JpaRolloutManagement(targetManagement, distributionSetManagement, eventPublisherHolder, return new JpaRolloutManagement(targetManagement, distributionSetManagement, eventPublisherHolder,
virtualPropertyReplacer, txManager, tenantAware, lockRegistry, properties.getDatabase(), virtualPropertyReplacer, properties.getDatabase(), rolloutApprovalStrategy,
rolloutApprovalStrategy, tenantConfigurationManagement, systemSecurityContext, rolloutExecutor); tenantConfigurationManagement, systemSecurityContext);
} }
/** /**
@@ -913,7 +935,7 @@ public class RepositoryApplicationConfiguration extends JpaBaseConfiguration {
* *
* @param systemManagement * @param systemManagement
* to find all tenants * to find all tenants
* @param rolloutManagement * @param rolloutHandler
* to run the rollout handler * to run the rollout handler
* @param systemSecurityContext * @param systemSecurityContext
* to run as system * to run as system
@@ -924,8 +946,8 @@ public class RepositoryApplicationConfiguration extends JpaBaseConfiguration {
@Profile("!test") @Profile("!test")
@ConditionalOnProperty(prefix = "hawkbit.rollout.scheduler", name = "enabled", matchIfMissing = true) @ConditionalOnProperty(prefix = "hawkbit.rollout.scheduler", name = "enabled", matchIfMissing = true)
RolloutScheduler rolloutScheduler(final TenantAware tenantAware, final SystemManagement systemManagement, RolloutScheduler rolloutScheduler(final TenantAware tenantAware, final SystemManagement systemManagement,
final RolloutManagement rolloutManagement, final SystemSecurityContext systemSecurityContext) { final RolloutHandler rolloutHandler, final SystemSecurityContext systemSecurityContext) {
return new RolloutScheduler(systemManagement, rolloutManagement, systemSecurityContext); return new RolloutScheduler(systemManagement, rolloutHandler, systemSecurityContext);
} }
/** /**

View File

@@ -8,7 +8,7 @@
*/ */
package org.eclipse.hawkbit.repository.jpa.rollout; package org.eclipse.hawkbit.repository.jpa.rollout;
import org.eclipse.hawkbit.repository.RolloutManagement; import org.eclipse.hawkbit.repository.RolloutHandler;
import org.eclipse.hawkbit.repository.SystemManagement; import org.eclipse.hawkbit.repository.SystemManagement;
import org.eclipse.hawkbit.security.SystemSecurityContext; import org.eclipse.hawkbit.security.SystemSecurityContext;
import org.slf4j.Logger; import org.slf4j.Logger;
@@ -16,8 +16,8 @@ import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled; import org.springframework.scheduling.annotation.Scheduled;
/** /**
* Scheduler to schedule the {@link RolloutManagement#handleRollouts()}. The * Scheduler to schedule the {@link RolloutHandler#handleAll()}. The
* delay between the checks be be configured using the property from * delay between the checks be configured using the property from
* {#PROP_SCHEDULER_DELAY_PLACEHOLDER}. * {#PROP_SCHEDULER_DELAY_PLACEHOLDER}.
*/ */
public class RolloutScheduler { public class RolloutScheduler {
@@ -28,7 +28,7 @@ public class RolloutScheduler {
private final SystemManagement systemManagement; private final SystemManagement systemManagement;
private final RolloutManagement rolloutManagement; private final RolloutHandler rolloutHandler;
private final SystemSecurityContext systemSecurityContext; private final SystemSecurityContext systemSecurityContext;
@@ -37,22 +37,22 @@ public class RolloutScheduler {
* *
* @param systemManagement * @param systemManagement
* to find all tenants * to find all tenants
* @param rolloutManagement * @param rolloutHandler
* to run the rollout handler * to run the rollout handler
* @param systemSecurityContext * @param systemSecurityContext
* to run as system * to run as system
*/ */
public RolloutScheduler(final SystemManagement systemManagement, final RolloutManagement rolloutManagement, public RolloutScheduler(final SystemManagement systemManagement, final RolloutHandler rolloutHandler,
final SystemSecurityContext systemSecurityContext) { final SystemSecurityContext systemSecurityContext) {
this.systemManagement = systemManagement; this.systemManagement = systemManagement;
this.rolloutManagement = rolloutManagement; this.rolloutHandler = rolloutHandler;
this.systemSecurityContext = systemSecurityContext; this.systemSecurityContext = systemSecurityContext;
} }
/** /**
* Scheduler method called by the spring-async mechanism. Retrieves all * Scheduler method called by the spring-async mechanism. Retrieves all
* tenants from the {@link SystemManagement#findTenants()} and runs for each * tenants from the {@link SystemManagement#findTenants} and runs for each
* tenant the {@link RolloutManagement#handleRollouts()} in the * tenant the {@link RolloutHandler#handleAll()} in the
* {@link SystemSecurityContext}. * {@link SystemSecurityContext}.
*/ */
@Scheduled(initialDelayString = PROP_SCHEDULER_DELAY_PLACEHOLDER, fixedDelayString = PROP_SCHEDULER_DELAY_PLACEHOLDER) @Scheduled(initialDelayString = PROP_SCHEDULER_DELAY_PLACEHOLDER, fixedDelayString = PROP_SCHEDULER_DELAY_PLACEHOLDER)
@@ -63,13 +63,13 @@ public class RolloutScheduler {
// permission to query and create entities. // permission to query and create entities.
systemSecurityContext.runAsSystem(() -> { systemSecurityContext.runAsSystem(() -> {
// workaround eclipselink that is currently not possible to // workaround eclipselink that is currently not possible to
// execute a query without multitenancy if MultiTenant // execute a query without multi-tenancy if MultiTenant
// annotation is used. // annotation is used.
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=355458. So // https://bugs.eclipse.org/bugs/show_bug.cgi?id=355458. So
// iterate through all tenants and execute the rollout check for // iterate through all tenants and execute the rollout check for
// each tenant seperately. // each tenant seperately.
systemManagement.forEachTenant(tenant -> rolloutManagement.handleRollouts()); systemManagement.forEachTenant(tenant -> rolloutHandler.handleAll());
return null; return null;
}); });

View File

@@ -0,0 +1,28 @@
/**
* Copyright (c) 2023 Bosch.IO GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.jpa.rollout.condition;
/**
* Exception indicating that a specific evaluator is missing in the application
* context.
*/
public class EvaluatorNotConfiguredException extends RuntimeException {
private static final String MESSAGE_FORMAT = "Cannot find any configured evaluator for action/condition '%s'. Please ensure to configure one in the application context to make use of it.";
/**
* Constructor
*
* @param s
* the action/condition to evaluate
*/
public EvaluatorNotConfiguredException(final String s) {
super(String.format(MESSAGE_FORMAT, s));
}
}

View File

@@ -20,7 +20,7 @@ import org.eclipse.hawkbit.security.SystemSecurityContext;
* Error action evaluator which pauses the whole {@link Rollout} and sets the * Error action evaluator which pauses the whole {@link Rollout} and sets the
* current {@link RolloutGroup} to error. * current {@link RolloutGroup} to error.
*/ */
public class PauseRolloutGroupAction implements RolloutGroupActionEvaluator { public class PauseRolloutGroupAction implements RolloutGroupActionEvaluator<RolloutGroup.RolloutGroupErrorAction> {
private final RolloutManagement rolloutManagement; private final RolloutManagement rolloutManagement;
@@ -36,12 +36,12 @@ public class PauseRolloutGroupAction implements RolloutGroupActionEvaluator {
} }
@Override @Override
public boolean verifyExpression(final String expression) { public RolloutGroup.RolloutGroupErrorAction getAction() {
return true; return RolloutGroup.RolloutGroupErrorAction.PAUSE;
} }
@Override @Override
public void eval(final Rollout rollout, final RolloutGroup rolloutG, final String expression) { public void exec(final Rollout rollout, final RolloutGroup rolloutG) {
final JpaRolloutGroup rolloutGroup = (JpaRolloutGroup) rolloutG; final JpaRolloutGroup rolloutGroup = (JpaRolloutGroup) rolloutG;
systemSecurityContext.runAsSystem(() -> { systemSecurityContext.runAsSystem(() -> {

View File

@@ -12,11 +12,11 @@ import org.eclipse.hawkbit.repository.model.Rollout;
import org.eclipse.hawkbit.repository.model.RolloutGroup; import org.eclipse.hawkbit.repository.model.RolloutGroup;
/** /**
* * Interface to define a specific execution for an action
*/ */
public interface RolloutGroupActionEvaluator { public interface RolloutGroupActionEvaluator<T> {
boolean verifyExpression(final String expression); T getAction();
void eval(Rollout rollout, RolloutGroup rolloutGroup, final String expression); void exec(Rollout rollout, RolloutGroup rolloutGroup);
} }

View File

@@ -12,20 +12,11 @@ import org.eclipse.hawkbit.repository.model.Rollout;
import org.eclipse.hawkbit.repository.model.RolloutGroup; import org.eclipse.hawkbit.repository.model.RolloutGroup;
/** /**
* Verifies {@link RolloutGroup#getErrorConditionExp()}. * Interface for evaluate conditions define for a {@link RolloutGroup} based on a given expression
*/ */
@FunctionalInterface public interface RolloutGroupConditionEvaluator<T> {
public interface RolloutGroupConditionEvaluator {
default boolean verifyExpression(final String expression) { T getCondition();
// percentage value between 0 and 100
try {
final Integer value = Integer.valueOf(expression);
return value >= 0 && value <= 100;
} catch (final NumberFormatException e) {
return false;
}
}
boolean eval(Rollout rollout, RolloutGroup rolloutGroup, final String expression); boolean eval(Rollout rollout, RolloutGroup rolloutGroup, final String expression);
} }

View File

@@ -0,0 +1,98 @@
/**
* Copyright (c) 2023 Bosch.IO GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.jpa.rollout.condition;
import java.util.List;
import org.eclipse.hawkbit.repository.model.RolloutGroup;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Manager class to collect all instances of
* {@link RolloutGroupConditionEvaluator} and
* {@link RolloutGroupActionEvaluator} for specific conditions and actions. The
* corresponding instance can be fetched by providing the action/condition.
*/
public class RolloutGroupEvaluationManager {
private static final Logger LOGGER = LoggerFactory.getLogger(RolloutGroupEvaluationManager.class);
private final List<RolloutGroupConditionEvaluator<RolloutGroup.RolloutGroupErrorCondition>> errorConditionEvaluators;
private final List<RolloutGroupConditionEvaluator<RolloutGroup.RolloutGroupSuccessCondition>> successConditionEvaluators;
private final List<RolloutGroupActionEvaluator<RolloutGroup.RolloutGroupErrorAction>> errorActionEvaluators;
private final List<RolloutGroupActionEvaluator<RolloutGroup.RolloutGroupSuccessAction>> successActionEvaluators;
/**
* Constructor
*
* @param errorConditionEvaluators
* evaluators for instances of {@link RolloutGroupConditionEvaluator}
* handling the {@link RolloutGroup.RolloutGroupErrorCondition}
* @param successConditionEvaluators
* evaluators for instances of {@link RolloutGroupConditionEvaluator}
* handling the {@link RolloutGroup.RolloutGroupSuccessCondition}
* @param errorActionEvaluators
* evaluators for instances of {@link RolloutGroupActionEvaluator}
* handling the {@link RolloutGroup.RolloutGroupErrorAction}
* @param successActionEvaluators
* evaluators for instances of {@link RolloutGroupActionEvaluator}
* handling the {@link RolloutGroup.RolloutGroupSuccessAction}
*/
public RolloutGroupEvaluationManager(
final List<RolloutGroupConditionEvaluator<RolloutGroup.RolloutGroupErrorCondition>> errorConditionEvaluators,
final List<RolloutGroupConditionEvaluator<RolloutGroup.RolloutGroupSuccessCondition>> successConditionEvaluators,
final List<RolloutGroupActionEvaluator<RolloutGroup.RolloutGroupErrorAction>> errorActionEvaluators,
final List<RolloutGroupActionEvaluator<RolloutGroup.RolloutGroupSuccessAction>> successActionEvaluators) {
this.errorConditionEvaluators = errorConditionEvaluators;
this.successConditionEvaluators = successConditionEvaluators;
this.errorActionEvaluators = errorActionEvaluators;
this.successActionEvaluators = successActionEvaluators;
}
public RolloutGroupActionEvaluator<RolloutGroup.RolloutGroupErrorAction> getErrorActionEvaluator(
final RolloutGroup.RolloutGroupErrorAction errorAction) {
return findFirstActionEvaluator(errorActionEvaluators, errorAction);
}
public RolloutGroupActionEvaluator<RolloutGroup.RolloutGroupSuccessAction> getSuccessActionEvaluator(
final RolloutGroup.RolloutGroupSuccessAction successAction) {
return findFirstActionEvaluator(successActionEvaluators, successAction);
}
public RolloutGroupConditionEvaluator<RolloutGroup.RolloutGroupErrorCondition> getErrorConditionEvaluator(
final RolloutGroup.RolloutGroupErrorCondition errorCondition) {
return findFirstConditionEvaluator(errorConditionEvaluators, errorCondition);
}
public RolloutGroupConditionEvaluator<RolloutGroup.RolloutGroupSuccessCondition> getSuccessConditionEvaluator(
final RolloutGroup.RolloutGroupSuccessCondition successCondition) {
return findFirstConditionEvaluator(successConditionEvaluators, successCondition);
}
private static <T extends Enum<T>> RolloutGroupActionEvaluator<T> findFirstActionEvaluator(
final List<RolloutGroupActionEvaluator<T>> evaluators, final T action) {
return evaluators.stream().filter(evaluator -> evaluator.getAction() == action).findFirst().orElseThrow(() -> {
LOGGER.warn("Could not find suitable evaluator for the '{}' action.", action.name());
throw new EvaluatorNotConfiguredException(action.name());
});
}
private static <T extends Enum<T>> RolloutGroupConditionEvaluator<T> findFirstConditionEvaluator(
final List<RolloutGroupConditionEvaluator<T>> evaluators, final T condition) {
return evaluators.stream().filter(evaluator -> evaluator.getCondition() == condition).findFirst()
.orElseThrow(() -> {
LOGGER.warn("Could not find suitable evaluator for the '{}' condition.", condition.name());
throw new EvaluatorNotConfiguredException(condition.name());
});
}
}

View File

@@ -23,7 +23,7 @@ import org.slf4j.LoggerFactory;
/** /**
* Success action which starts the next following {@link RolloutGroup}. * Success action which starts the next following {@link RolloutGroup}.
*/ */
public class StartNextGroupRolloutGroupSuccessAction implements RolloutGroupActionEvaluator { public class StartNextGroupRolloutGroupSuccessAction implements RolloutGroupActionEvaluator<RolloutGroup.RolloutGroupSuccessAction> {
private static final Logger logger = LoggerFactory.getLogger(StartNextGroupRolloutGroupSuccessAction.class); private static final Logger logger = LoggerFactory.getLogger(StartNextGroupRolloutGroupSuccessAction.class);
@@ -41,12 +41,12 @@ public class StartNextGroupRolloutGroupSuccessAction implements RolloutGroupActi
} }
@Override @Override
public boolean verifyExpression(final String expression) { public RolloutGroup.RolloutGroupSuccessAction getAction() {
return true; return RolloutGroup.RolloutGroupSuccessAction.NEXTGROUP;
} }
@Override @Override
public void eval(final Rollout rollout, final RolloutGroup rolloutGroup, final String expression) { public void exec(final Rollout rollout, final RolloutGroup rolloutGroup) {
systemSecurityContext.runAsSystem(() -> { systemSecurityContext.runAsSystem(() -> {
startNextGroup(rollout, rolloutGroup); startNextGroup(rollout, rolloutGroup);
return null; return null;

View File

@@ -18,9 +18,10 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
/** /**
* * Evaluates if the {@link RolloutGroup#getErrorConditionExp()} is reached.
*/ */
public class ThresholdRolloutGroupErrorCondition implements RolloutGroupConditionEvaluator { public class ThresholdRolloutGroupErrorCondition
implements RolloutGroupConditionEvaluator<RolloutGroup.RolloutGroupErrorCondition> {
private static final Logger LOGGER = LoggerFactory.getLogger(ThresholdRolloutGroupErrorCondition.class); private static final Logger LOGGER = LoggerFactory.getLogger(ThresholdRolloutGroupErrorCondition.class);
@@ -30,6 +31,11 @@ public class ThresholdRolloutGroupErrorCondition implements RolloutGroupConditio
this.actionRepository = actionRepository; this.actionRepository = actionRepository;
} }
@Override
public RolloutGroup.RolloutGroupErrorCondition getCondition() {
return RolloutGroup.RolloutGroupErrorCondition.THRESHOLD;
}
@Override @Override
public boolean eval(final Rollout rollout, final RolloutGroup rolloutGroup, final String expression) { public boolean eval(final Rollout rollout, final RolloutGroup rolloutGroup, final String expression) {
final Long totalGroup = actionRepository.countByRolloutAndRolloutGroup((JpaRollout) rollout, final Long totalGroup = actionRepository.countByRolloutAndRolloutGroup((JpaRollout) rollout,

View File

@@ -16,10 +16,11 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
/** /**
* Threshold to calculate if rollout group success condition is reached and the * Threshold to calculate if the {@link RolloutGroup#getSuccessConditionExp()} is reached and the
* next rollout group can get started. * next rollout group can get started.
*/ */
public class ThresholdRolloutGroupSuccessCondition implements RolloutGroupConditionEvaluator { public class ThresholdRolloutGroupSuccessCondition
implements RolloutGroupConditionEvaluator<RolloutGroup.RolloutGroupSuccessCondition> {
private static final Logger LOGGER = LoggerFactory.getLogger(ThresholdRolloutGroupSuccessCondition.class); private static final Logger LOGGER = LoggerFactory.getLogger(ThresholdRolloutGroupSuccessCondition.class);
private final ActionRepository actionRepository; private final ActionRepository actionRepository;
@@ -28,6 +29,11 @@ public class ThresholdRolloutGroupSuccessCondition implements RolloutGroupCondit
this.actionRepository = actionRepository; this.actionRepository = actionRepository;
} }
@Override
public RolloutGroup.RolloutGroupSuccessCondition getCondition() {
return RolloutGroup.RolloutGroupSuccessCondition.THRESHOLD;
}
@Override @Override
public boolean eval(final Rollout rollout, final RolloutGroup rolloutGroup, final String expression) { public boolean eval(final Rollout rollout, final RolloutGroup rolloutGroup, final String expression) {
@@ -44,7 +50,7 @@ public class ThresholdRolloutGroupSuccessCondition implements RolloutGroupCondit
final long finished = this.actionRepository.countByRolloutIdAndRolloutGroupIdAndStatus(rollout.getId(), final long finished = this.actionRepository.countByRolloutIdAndRolloutGroupIdAndStatus(rollout.getId(),
rolloutGroup.getId(), completeActionStatus); rolloutGroup.getId(), completeActionStatus);
try { try {
final Integer threshold = Integer.valueOf(expression); final int threshold = Integer.parseInt(expression);
// calculate threshold // calculate threshold
return ((float) finished / (float) totalGroup) >= ((float) threshold / 100F); return ((float) finished / (float) totalGroup) >= ((float) threshold / 100F);

View File

@@ -8,9 +8,15 @@
*/ */
package org.eclipse.hawkbit.repository.jpa; package org.eclipse.hawkbit.repository.jpa;
import io.qameta.allure.Description; import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import io.qameta.allure.Feature; import static org.mockito.AdditionalAnswers.delegatesTo;
import io.qameta.allure.Story; import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import java.util.Collections;
import java.util.concurrent.TimeUnit;
import org.awaitility.Awaitility; import org.awaitility.Awaitility;
import org.awaitility.Duration; import org.awaitility.Duration;
import org.eclipse.hawkbit.repository.exception.StopRolloutException; import org.eclipse.hawkbit.repository.exception.StopRolloutException;
@@ -32,14 +38,9 @@ import org.springframework.context.annotation.Primary;
import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.TestPropertySource;
import java.util.Collections; import io.qameta.allure.Description;
import java.util.concurrent.TimeUnit; import io.qameta.allure.Feature;
import io.qameta.allure.Story;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.mockito.AdditionalAnswers.delegatesTo;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
/** /**
* Test class testing the invalidation of a {@link DistributionSet} while the * Test class testing the invalidation of a {@link DistributionSet} while the
@@ -87,7 +88,7 @@ public class ConcurrentDistributionSetInvalidationTest extends AbstractJpaIntegr
// run in new Thread so that the invalidation can be executed in // run in new Thread so that the invalidation can be executed in
// parallel // parallel
new Thread(() -> systemSecurityContext.runAsSystemAsTenant(() -> { new Thread(() -> systemSecurityContext.runAsSystemAsTenant(() -> {
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
return 0; return 0;
}, tenant)).start(); }, tenant)).start();

View File

@@ -58,7 +58,7 @@ class DistributionSetInvalidationManagementTest extends AbstractJpaIntegrationTe
assertDistributionSetInvalidationCount(distributionSetInvalidationCount, 1, 0, 0); assertDistributionSetInvalidationCount(distributionSetInvalidationCount, 1, 0, 0);
distributionSetInvalidationManagement.invalidateDistributionSet(distributionSetInvalidation); distributionSetInvalidationManagement.invalidateDistributionSet(distributionSetInvalidation);
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
assertThat(targetFilterQueryManagement.get(invalidationTestData.getTargetFilterQuery().getId()).get() assertThat(targetFilterQueryManagement.get(invalidationTestData.getTargetFilterQuery().getId()).get()
.getAutoAssignDistributionSet()).isNull(); .getAutoAssignDistributionSet()).isNull();
@@ -87,7 +87,7 @@ class DistributionSetInvalidationManagementTest extends AbstractJpaIntegrationTe
assertDistributionSetInvalidationCount(distributionSetInvalidationCount, 1, 0, 1); assertDistributionSetInvalidationCount(distributionSetInvalidationCount, 1, 0, 1);
distributionSetInvalidationManagement.invalidateDistributionSet(distributionSetInvalidation); distributionSetInvalidationManagement.invalidateDistributionSet(distributionSetInvalidation);
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
assertThat(targetFilterQueryManagement.get(invalidationTestData.getTargetFilterQuery().getId()).get() assertThat(targetFilterQueryManagement.get(invalidationTestData.getTargetFilterQuery().getId()).get()
.getAutoAssignDistributionSet()).isNull(); .getAutoAssignDistributionSet()).isNull();
@@ -119,7 +119,7 @@ class DistributionSetInvalidationManagementTest extends AbstractJpaIntegrationTe
assertDistributionSetInvalidationCount(distributionSetInvalidationCount, 1, 5, 1); assertDistributionSetInvalidationCount(distributionSetInvalidationCount, 1, 5, 1);
distributionSetInvalidationManagement.invalidateDistributionSet(distributionSetInvalidation); distributionSetInvalidationManagement.invalidateDistributionSet(distributionSetInvalidation);
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
assertThat(targetFilterQueryManagement.get(invalidationTestData.getTargetFilterQuery().getId()).get() assertThat(targetFilterQueryManagement.get(invalidationTestData.getTargetFilterQuery().getId()).get()
.getAutoAssignDistributionSet()).isNull(); .getAutoAssignDistributionSet()).isNull();

View File

@@ -92,7 +92,7 @@ class RolloutGroupManagementTest extends AbstractJpaIntegrationTest {
.getContent(); .getContent();
final RolloutGroup rolloutGroup = rolloutGroups.get(0); final RolloutGroup rolloutGroup = rolloutGroups.get(0);
rolloutManagement.pauseRollout(rollout.getId()); rolloutManagement.pauseRollout(rollout.getId());
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
final List<Target> targets = rolloutGroupManagement.findTargetsOfRolloutGroup(PAGE, rolloutGroup.getId()) final List<Target> targets = rolloutGroupManagement.findTargetsOfRolloutGroup(PAGE, rolloutGroup.getId())
.getContent(); .getContent();
Target targetCancelled = targets.get(0); Target targetCancelled = targets.get(0);
@@ -195,7 +195,7 @@ class RolloutGroupManagementTest extends AbstractJpaIntegrationTest {
final Rollout rollout = testdataFactory.createRollout(); final Rollout rollout = testdataFactory.createRollout();
final List<RolloutGroup> rolloutGroups = rolloutGroupManagement.findByRollout(PAGE, rollout.getId()) final List<RolloutGroup> rolloutGroups = rolloutGroupManagement.findByRollout(PAGE, rollout.getId())
.getContent(); .getContent();
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
// check query when no actions exist // check query when no actions exist
final List<TargetWithActionStatus> targetsWithActionStatus = rolloutGroupManagement final List<TargetWithActionStatus> targetsWithActionStatus = rolloutGroupManagement
@@ -208,7 +208,7 @@ class RolloutGroupManagementTest extends AbstractJpaIntegrationTest {
assertTargetNotNullAndActionStatusNullAndActionStatusCode(targetsWithActionStatus, null); assertTargetNotNullAndActionStatusNullAndActionStatusCode(targetsWithActionStatus, null);
rolloutManagement.start(rollout.getId()); rolloutManagement.start(rollout.getId());
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
// check query when no action status code exist // check query when no action status code exist
final List<Action> scheduledActions = findActionsByRolloutAndStatus(rollout, Status.SCHEDULED); final List<Action> scheduledActions = findActionsByRolloutAndStatus(rollout, Status.SCHEDULED);

View File

@@ -126,7 +126,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
final Rollout rollout = testdataFactory.createRolloutByVariables("rolloutNotCancelRunningAction", "description", final Rollout rollout = testdataFactory.createRolloutByVariables("rolloutNotCancelRunningAction", "description",
1, "name==*", knownDistributionSet, "50", "5"); 1, "name==*", knownDistributionSet, "50", "5");
rolloutManagement.start(rollout.getId()); rolloutManagement.start(rollout.getId());
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
// verify that manually created action is still running and action // verify that manually created action is still running and action
// created from rollout is finished // created from rollout is finished
@@ -163,7 +163,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
final Rollout rollout = testdataFactory.createRolloutByVariables("rolloutNotCancelRunningAction", "description", final Rollout rollout = testdataFactory.createRolloutByVariables("rolloutNotCancelRunningAction", "description",
1, "name==*", knownDistributionSet, "50", "5", confirmationRequired); 1, "name==*", knownDistributionSet, "50", "5", confirmationRequired);
rolloutManagement.start(rollout.getId()); rolloutManagement.start(rollout.getId());
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
// verify that manually created action is still running and action // verify that manually created action is still running and action
// created from rollout is finished // created from rollout is finished
@@ -201,7 +201,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
final Rollout rollout = testdataFactory.createRolloutByVariables("rolloutNotCancelRunningAction", final Rollout rollout = testdataFactory.createRolloutByVariables("rolloutNotCancelRunningAction",
"description", 1, "name==*", secondDistributionSet, "50", "5"); "description", 1, "name==*", secondDistributionSet, "50", "5");
rolloutManagement.start(rollout.getId()); rolloutManagement.start(rollout.getId());
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
// verify that manually created action is canceled and action // verify that manually created action is canceled and action
// created from rollout is running // created from rollout is running
@@ -333,7 +333,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
// check running rollouts again, now the finish condition should be hit // check running rollouts again, now the finish condition should be hit
// and should start the next group // and should start the next group
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
// verify that now the first and the second group are in running state // verify that now the first and the second group are in running state
final List<RolloutGroup> runningRolloutGroups = rolloutGroupManagement final List<RolloutGroup> runningRolloutGroups = rolloutGroupManagement
@@ -395,7 +395,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
@Step("Check the status of the rollout groups, second group should be in running status") @Step("Check the status of the rollout groups, second group should be in running status")
private void checkSecondGroupStatusIsRunning(final Rollout createdRollout) { private void checkSecondGroupStatusIsRunning(final Rollout createdRollout) {
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
final List<RolloutGroup> runningRolloutGroups = rolloutGroupManagement final List<RolloutGroup> runningRolloutGroups = rolloutGroupManagement
.findByRollout(new OffsetBasedPageRequest(0, 10, Sort.by(Direction.ASC, "id")), createdRollout.getId()) .findByRollout(new OffsetBasedPageRequest(0, 10, Sort.by(Direction.ASC, "id")), createdRollout.getId())
.getContent(); .getContent();
@@ -428,7 +428,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
@Step("Check the status of the rollout groups and the rollout") @Step("Check the status of the rollout groups and the rollout")
private void verifyRolloutAndAllGroupsAreFinished(final Rollout createdRollout) { private void verifyRolloutAndAllGroupsAreFinished(final Rollout createdRollout) {
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
final List<RolloutGroup> runningRolloutGroups = rolloutGroupManagement final List<RolloutGroup> runningRolloutGroups = rolloutGroupManagement
.findByRollout(PAGE, createdRollout.getId()).getContent(); .findByRollout(PAGE, createdRollout.getId()).getContent();
assertThat(runningRolloutGroups.get(0).getStatus()).isEqualTo(RolloutGroupStatus.FINISHED); assertThat(runningRolloutGroups.get(0).getStatus()).isEqualTo(RolloutGroupStatus.FINISHED);
@@ -467,7 +467,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
// check running rollouts again, now the error condition should be hit // check running rollouts again, now the error condition should be hit
// and should execute the error action // and should execute the error action
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
final Rollout rollout = reloadRollout(createdRollout); final Rollout rollout = reloadRollout(createdRollout);
// the rollout itself should be in paused based on the error action // the rollout itself should be in paused based on the error action
@@ -510,7 +510,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
// check running rollouts again, now the error condition should be hit // check running rollouts again, now the error condition should be hit
// and should execute the error action // and should execute the error action
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
final Rollout rollout = reloadRollout(createdRollout); final Rollout rollout = reloadRollout(createdRollout);
// the rollout itself should be in paused based on the error action // the rollout itself should be in paused based on the error action
@@ -529,7 +529,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
assertThat(reloadRollout(createdRollout).getStatus()).isEqualTo(RolloutStatus.RUNNING); assertThat(reloadRollout(createdRollout).getStatus()).isEqualTo(RolloutStatus.RUNNING);
// checking rollouts again // checking rollouts again
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
// next group should be running again after resuming the rollout // next group should be running again after resuming the rollout
final List<RolloutGroup> resumedGroups = rolloutGroupManagement final List<RolloutGroup> resumedGroups = rolloutGroupManagement
@@ -557,7 +557,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
// calculate the rest of the groups and finish them // calculate the rest of the groups and finish them
for (int groupsLeft = amountGroups - 1; groupsLeft >= 1; groupsLeft--) { for (int groupsLeft = amountGroups - 1; groupsLeft >= 1; groupsLeft--) {
// next check and start next group // next check and start next group
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
// finish running actions, 2 actions should be finished // finish running actions, 2 actions should be finished
assertThat(changeStatusForAllRunningActions(createdRollout, Status.FINISHED)).isEqualTo(2); assertThat(changeStatusForAllRunningActions(createdRollout, Status.FINISHED)).isEqualTo(2);
assertThat(getRollout(createdRollout.getId()).getStatus()).isEqualTo(RolloutStatus.RUNNING); assertThat(getRollout(createdRollout.getId()).getStatus()).isEqualTo(RolloutStatus.RUNNING);
@@ -565,7 +565,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
} }
// check rollout to see that all actions and all groups are finished and // check rollout to see that all actions and all groups are finished and
// so can go to FINISHED state of the rollout // so can go to FINISHED state of the rollout
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
// verify all groups are in finished state // verify all groups are in finished state
rolloutGroupManagement rolloutGroupManagement
@@ -598,7 +598,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
rolloutManagement.start(createdRollout.getId()); rolloutManagement.start(createdRollout.getId());
// Run here, because scheduler is disabled during tests // Run here, because scheduler is disabled during tests
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
// 6 targets are ready and 2 are running // 6 targets are ready and 2 are running
validationMap = createInitStatusMap(); validationMap = createInitStatusMap();
@@ -607,7 +607,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
validateRolloutActionStatus(createdRollout.getId(), validationMap); validateRolloutActionStatus(createdRollout.getId(), validationMap);
changeStatusForAllRunningActions(createdRollout, Status.FINISHED); changeStatusForAllRunningActions(createdRollout, Status.FINISHED);
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
// 4 targets are ready, 2 are finished and 2 are running // 4 targets are ready, 2 are finished and 2 are running
validationMap = createInitStatusMap(); validationMap = createInitStatusMap();
validationMap.put(TotalTargetCountStatus.Status.SCHEDULED, 4L); validationMap.put(TotalTargetCountStatus.Status.SCHEDULED, 4L);
@@ -616,7 +616,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
validateRolloutActionStatus(createdRollout.getId(), validationMap); validateRolloutActionStatus(createdRollout.getId(), validationMap);
changeStatusForAllRunningActions(createdRollout, Status.FINISHED); changeStatusForAllRunningActions(createdRollout, Status.FINISHED);
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
// 2 targets are ready, 4 are finished and 2 are running // 2 targets are ready, 4 are finished and 2 are running
validationMap = createInitStatusMap(); validationMap = createInitStatusMap();
validationMap.put(TotalTargetCountStatus.Status.SCHEDULED, 2L); validationMap.put(TotalTargetCountStatus.Status.SCHEDULED, 2L);
@@ -625,7 +625,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
validateRolloutActionStatus(createdRollout.getId(), validationMap); validateRolloutActionStatus(createdRollout.getId(), validationMap);
changeStatusForAllRunningActions(createdRollout, Status.FINISHED); changeStatusForAllRunningActions(createdRollout, Status.FINISHED);
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
// 0 targets are ready, 6 are finished and 2 are running // 0 targets are ready, 6 are finished and 2 are running
validationMap = createInitStatusMap(); validationMap = createInitStatusMap();
validationMap.put(TotalTargetCountStatus.Status.FINISHED, 6L); validationMap.put(TotalTargetCountStatus.Status.FINISHED, 6L);
@@ -633,7 +633,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
validateRolloutActionStatus(createdRollout.getId(), validationMap); validateRolloutActionStatus(createdRollout.getId(), validationMap);
changeStatusForAllRunningActions(createdRollout, Status.FINISHED); changeStatusForAllRunningActions(createdRollout, Status.FINISHED);
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
// 0 targets are ready, 8 are finished and 0 are running // 0 targets are ready, 8 are finished and 0 are running
validationMap = createInitStatusMap(); validationMap = createInitStatusMap();
validationMap.put(TotalTargetCountStatus.Status.FINISHED, 8L); validationMap.put(TotalTargetCountStatus.Status.FINISHED, 8L);
@@ -662,7 +662,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
rolloutManagement.start(createdRollout.getId()); rolloutManagement.start(createdRollout.getId());
// Run here, because scheduler is disabled during tests // Run here, because scheduler is disabled during tests
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
// 6 targets are ready and 2 are running // 6 targets are ready and 2 are running
validationMap = createInitStatusMap(); validationMap = createInitStatusMap();
@@ -671,7 +671,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
validateRolloutActionStatus(createdRollout.getId(), validationMap); validateRolloutActionStatus(createdRollout.getId(), validationMap);
changeStatusForAllRunningActions(createdRollout, Status.DOWNLOADED); changeStatusForAllRunningActions(createdRollout, Status.DOWNLOADED);
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
// 4 targets are ready, 2 are finished(with DOWNLOADED action status) // 4 targets are ready, 2 are finished(with DOWNLOADED action status)
// and 2 are running // and 2 are running
validationMap = createInitStatusMap(); validationMap = createInitStatusMap();
@@ -681,7 +681,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
validateRolloutActionStatus(createdRollout.getId(), validationMap); validateRolloutActionStatus(createdRollout.getId(), validationMap);
changeStatusForAllRunningActions(createdRollout, Status.DOWNLOADED); changeStatusForAllRunningActions(createdRollout, Status.DOWNLOADED);
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
// 2 targets are ready, 4 are finished(with DOWNLOADED action status) // 2 targets are ready, 4 are finished(with DOWNLOADED action status)
// and 2 are running // and 2 are running
validationMap = createInitStatusMap(); validationMap = createInitStatusMap();
@@ -691,7 +691,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
validateRolloutActionStatus(createdRollout.getId(), validationMap); validateRolloutActionStatus(createdRollout.getId(), validationMap);
changeStatusForAllRunningActions(createdRollout, Status.DOWNLOADED); changeStatusForAllRunningActions(createdRollout, Status.DOWNLOADED);
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
// 0 targets are ready, 6 are finished(with DOWNLOADED action status) // 0 targets are ready, 6 are finished(with DOWNLOADED action status)
// and 2 are running // and 2 are running
validationMap = createInitStatusMap(); validationMap = createInitStatusMap();
@@ -700,7 +700,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
validateRolloutActionStatus(createdRollout.getId(), validationMap); validateRolloutActionStatus(createdRollout.getId(), validationMap);
changeStatusForAllRunningActions(createdRollout, Status.FINISHED); changeStatusForAllRunningActions(createdRollout, Status.FINISHED);
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
// 0 targets are ready, 6 are finished(with DOWNLOADED action status), 2 // 0 targets are ready, 6 are finished(with DOWNLOADED action status), 2
// are finished and 0 are running // are finished and 0 are running
validationMap = createInitStatusMap(); validationMap = createInitStatusMap();
@@ -730,7 +730,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
rolloutManagement.start(createdRollout.getId()); rolloutManagement.start(createdRollout.getId());
// Run here, because scheduler is disabled during tests // Run here, because scheduler is disabled during tests
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
// 6 targets are ready and 2 are running // 6 targets are ready and 2 are running
validationMap = createInitStatusMap(); validationMap = createInitStatusMap();
@@ -739,7 +739,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
validateRolloutActionStatus(createdRollout.getId(), validationMap); validateRolloutActionStatus(createdRollout.getId(), validationMap);
changeStatusForAllRunningActions(createdRollout, Status.ERROR); changeStatusForAllRunningActions(createdRollout, Status.ERROR);
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
// 6 targets are ready and 2 are error // 6 targets are ready and 2 are error
validationMap = createInitStatusMap(); validationMap = createInitStatusMap();
validationMap.put(TotalTargetCountStatus.Status.SCHEDULED, 6L); validationMap.put(TotalTargetCountStatus.Status.SCHEDULED, 6L);
@@ -761,7 +761,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
successCondition, errorCondition); successCondition, errorCondition);
changeStatusForAllRunningActions(createdRollout, Status.FINISHED); changeStatusForAllRunningActions(createdRollout, Status.FINISHED);
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
// round(9/4)=2 targets finished (Group 1) // round(9/4)=2 targets finished (Group 1)
// round(7/3)=2 targets running (Group 3) // round(7/3)=2 targets running (Group 3)
@@ -853,7 +853,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
final Rollout rolloutTwo = testdataFactory.createRolloutByVariables("rolloutTwo", final Rollout rolloutTwo = testdataFactory.createRolloutByVariables("rolloutTwo",
"This is the description for rollout two", 1, "controllerId==rollout-*", dsForRolloutTwo, "50", "80"); "This is the description for rollout two", 1, "controllerId==rollout-*", dsForRolloutTwo, "50", "80");
changeStatusForAllRunningActions(rolloutOne, Status.FINISHED); changeStatusForAllRunningActions(rolloutOne, Status.FINISHED);
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
// Verify that 5 targets are finished, 5 are running and 5 are ready. // Verify that 5 targets are finished, 5 are running and 5 are ready.
Map<TotalTargetCountStatus.Status, Long> expectedTargetCountStatus = createInitStatusMap(); Map<TotalTargetCountStatus.Status, Long> expectedTargetCountStatus = createInitStatusMap();
expectedTargetCountStatus.put(TotalTargetCountStatus.Status.RUNNING, 5L); expectedTargetCountStatus.put(TotalTargetCountStatus.Status.RUNNING, 5L);
@@ -864,7 +864,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
rolloutManagement.start(rolloutTwo.getId()); rolloutManagement.start(rolloutTwo.getId());
// Run here, because scheduler is disabled during tests // Run here, because scheduler is disabled during tests
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
// Verify that 5 targets are finished, 5 are still running and 5 are // Verify that 5 targets are finished, 5 are still running and 5 are
// cancelled. // cancelled.
@@ -892,13 +892,13 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
rolloutOne = reloadRollout(rolloutOne); rolloutOne = reloadRollout(rolloutOne);
changeStatusForRunningActions(rolloutOne, Status.ERROR, 2); changeStatusForRunningActions(rolloutOne, Status.ERROR, 2);
changeStatusForRunningActions(rolloutOne, Status.FINISHED, 3); changeStatusForRunningActions(rolloutOne, Status.FINISHED, 3);
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
changeStatusForRunningActions(rolloutOne, Status.ERROR, 2); changeStatusForRunningActions(rolloutOne, Status.ERROR, 2);
changeStatusForRunningActions(rolloutOne, Status.FINISHED, 3); changeStatusForRunningActions(rolloutOne, Status.FINISHED, 3);
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
changeStatusForRunningActions(rolloutOne, Status.ERROR, 2); changeStatusForRunningActions(rolloutOne, Status.ERROR, 2);
changeStatusForRunningActions(rolloutOne, Status.FINISHED, 3); changeStatusForRunningActions(rolloutOne, Status.FINISHED, 3);
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
// 9 targets are finished and 6 have error // 9 targets are finished and 6 have error
Map<TotalTargetCountStatus.Status, Long> expectedTargetCountStatus = createInitStatusMap(); Map<TotalTargetCountStatus.Status, Long> expectedTargetCountStatus = createInitStatusMap();
@@ -917,7 +917,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
rolloutManagement.start(rolloutTwo.getId()); rolloutManagement.start(rolloutTwo.getId());
// Run here, because scheduler is disabled during tests // Run here, because scheduler is disabled during tests
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
rolloutTwo = reloadRollout(rolloutTwo); rolloutTwo = reloadRollout(rolloutTwo);
// 6 error targets are now running // 6 error targets are now running
@@ -950,7 +950,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
rolloutOne = reloadRollout(rolloutOne); rolloutOne = reloadRollout(rolloutOne);
changeStatusForRunningActions(rolloutOne, Status.ERROR, 2); changeStatusForRunningActions(rolloutOne, Status.ERROR, 2);
changeStatusForRunningActions(rolloutOne, Status.FINISHED, 3); changeStatusForRunningActions(rolloutOne, Status.FINISHED, 3);
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
// verify: 40% error but 60% finished -> should move to next group // verify: 40% error but 60% finished -> should move to next group
final List<RolloutGroup> rolloutGroups = rolloutGroupManagement.findByRollout(PAGE, rolloutOne.getId()) final List<RolloutGroup> rolloutGroups = rolloutGroupManagement.findByRollout(PAGE, rolloutOne.getId())
.getContent(); .getContent();
@@ -976,7 +976,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
rolloutOne = reloadRollout(rolloutOne); rolloutOne = reloadRollout(rolloutOne);
changeStatusForRunningActions(rolloutOne, Status.ERROR, 2); changeStatusForRunningActions(rolloutOne, Status.ERROR, 2);
changeStatusForRunningActions(rolloutOne, Status.FINISHED, 3); changeStatusForRunningActions(rolloutOne, Status.FINISHED, 3);
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
// verify: 40% error and 60% finished -> should not move to next group // verify: 40% error and 60% finished -> should not move to next group
// because successCondition 80% // because successCondition 80%
final List<RolloutGroup> rolloutGruops = rolloutGroupManagement.findByRollout(PAGE, rolloutOne.getId()) final List<RolloutGroup> rolloutGruops = rolloutGroupManagement.findByRollout(PAGE, rolloutOne.getId())
@@ -1002,7 +1002,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
rolloutOne = reloadRollout(rolloutOne); rolloutOne = reloadRollout(rolloutOne);
changeStatusForRunningActions(rolloutOne, Status.ERROR, 2); changeStatusForRunningActions(rolloutOne, Status.ERROR, 2);
changeStatusForRunningActions(rolloutOne, Status.FINISHED, 3); changeStatusForRunningActions(rolloutOne, Status.FINISHED, 3);
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
// verify: 40% error -> should pause because errorCondition is 20% // verify: 40% error -> should pause because errorCondition is 20%
rolloutOne = reloadRollout(rolloutOne); rolloutOne = reloadRollout(rolloutOne);
assertThat(rolloutOne.getStatus()).isEqualTo(RolloutStatus.PAUSED); assertThat(rolloutOne.getStatus()).isEqualTo(RolloutStatus.PAUSED);
@@ -1019,39 +1019,39 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
final Rollout rolloutA = createTestRolloutWithTargetsAndDistributionSet(amountTargetsForRollout, amountGroups, final Rollout rolloutA = createTestRolloutWithTargetsAndDistributionSet(amountTargetsForRollout, amountGroups,
successCondition, errorCondition, "RolloutA", "RolloutA"); successCondition, errorCondition, "RolloutA", "RolloutA");
rolloutManagement.start(rolloutA.getId()); rolloutManagement.start(rolloutA.getId());
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
final int amountTargetsForRollout2 = 10; final int amountTargetsForRollout2 = 10;
final int amountGroups2 = 2; final int amountGroups2 = 2;
final Rollout rolloutB = createTestRolloutWithTargetsAndDistributionSet(amountTargetsForRollout2, amountGroups2, final Rollout rolloutB = createTestRolloutWithTargetsAndDistributionSet(amountTargetsForRollout2, amountGroups2,
successCondition, errorCondition, "RolloutB", "RolloutB"); successCondition, errorCondition, "RolloutB", "RolloutB");
rolloutManagement.start(rolloutB.getId()); rolloutManagement.start(rolloutB.getId());
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
changeStatusForAllRunningActions(rolloutB, Status.FINISHED); changeStatusForAllRunningActions(rolloutB, Status.FINISHED);
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
final int amountTargetsForRollout3 = 10; final int amountTargetsForRollout3 = 10;
final int amountGroups3 = 2; final int amountGroups3 = 2;
final Rollout rolloutC = createTestRolloutWithTargetsAndDistributionSet(amountTargetsForRollout3, amountGroups3, final Rollout rolloutC = createTestRolloutWithTargetsAndDistributionSet(amountTargetsForRollout3, amountGroups3,
successCondition, errorCondition, "RolloutC", "RolloutC"); successCondition, errorCondition, "RolloutC", "RolloutC");
rolloutManagement.start(rolloutC.getId()); rolloutManagement.start(rolloutC.getId());
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
changeStatusForAllRunningActions(rolloutC, Status.ERROR); changeStatusForAllRunningActions(rolloutC, Status.ERROR);
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
final int amountTargetsForRollout4 = 15; final int amountTargetsForRollout4 = 15;
final int amountGroups4 = 3; final int amountGroups4 = 3;
final Rollout rolloutD = createTestRolloutWithTargetsAndDistributionSet(amountTargetsForRollout4, amountGroups4, final Rollout rolloutD = createTestRolloutWithTargetsAndDistributionSet(amountTargetsForRollout4, amountGroups4,
successCondition, errorCondition, "RolloutD", "RolloutD"); successCondition, errorCondition, "RolloutD", "RolloutD");
rolloutManagement.start(rolloutD.getId()); rolloutManagement.start(rolloutD.getId());
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
changeStatusForRunningActions(rolloutD, Status.ERROR, 1); changeStatusForRunningActions(rolloutD, Status.ERROR, 1);
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
changeStatusForAllRunningActions(rolloutD, Status.FINISHED); changeStatusForAllRunningActions(rolloutD, Status.FINISHED);
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
final Slice<Rollout> rolloutPage = rolloutManagement final Slice<Rollout> rolloutPage = rolloutManagement
.findAllWithDetailedStatus(new OffsetBasedPageRequest(0, 100, Sort.by(Direction.ASC, "name")), false); .findAllWithDetailedStatus(new OffsetBasedPageRequest(0, 100, Sort.by(Direction.ASC, "name")), false);
@@ -1181,10 +1181,10 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
rolloutManagement.start(myRollout.getId()); rolloutManagement.start(myRollout.getId());
// Run here, because scheduler is disabled during tests // Run here, because scheduler is disabled during tests
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
changeStatusForRunningActions(myRollout, Status.FINISHED, 2); changeStatusForRunningActions(myRollout, Status.FINISHED, 2);
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
myRollout = reloadRollout(myRollout); myRollout = reloadRollout(myRollout);
float percent = rolloutGroupManagement float percent = rolloutGroupManagement
@@ -1194,7 +1194,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
assertThat(percent).isEqualTo(40); assertThat(percent).isEqualTo(40);
changeStatusForRunningActions(myRollout, Status.FINISHED, 3); changeStatusForRunningActions(myRollout, Status.FINISHED, 3);
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
percent = rolloutGroupManagement percent = rolloutGroupManagement
.getWithDetailedStatus( .getWithDetailedStatus(
@@ -1204,7 +1204,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
changeStatusForRunningActions(myRollout, Status.FINISHED, 4); changeStatusForRunningActions(myRollout, Status.FINISHED, 4);
changeStatusForAllRunningActions(myRollout, Status.ERROR); changeStatusForAllRunningActions(myRollout, Status.ERROR);
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
percent = rolloutGroupManagement percent = rolloutGroupManagement
.getWithDetailedStatus( .getWithDetailedStatus(
@@ -1233,7 +1233,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
rolloutManagement.start(myRollout.getId()); rolloutManagement.start(myRollout.getId());
// Run here, because scheduler is disabled during tests // Run here, because scheduler is disabled during tests
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
final Condition<String> targetBelongsInRollout = new Condition<>(s -> s.startsWith(rolloutName), final Condition<String> targetBelongsInRollout = new Condition<>(s -> s.startsWith(rolloutName),
"Target belongs into rollout"); "Target belongs into rollout");
@@ -1336,7 +1336,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
rolloutManagement.start(myRolloutId); rolloutManagement.start(myRolloutId);
// Run here, because scheduler is disabled during tests // Run here, because scheduler is disabled during tests
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
awaitRunningState(myRolloutId); awaitRunningState(myRolloutId);
@@ -1365,7 +1365,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
assertThat(myRollout.getStatus()).isEqualTo(RolloutStatus.READY); assertThat(myRollout.getStatus()).isEqualTo(RolloutStatus.READY);
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
final Long myRolloutId = myRollout.getId(); final Long myRolloutId = myRollout.getId();
myRollout = getRollout(myRolloutId); myRollout = getRollout(myRolloutId);
@@ -1374,7 +1374,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
rolloutManagement.start(myRolloutId); rolloutManagement.start(myRolloutId);
// Run here, because scheduler is disabled during tests // Run here, because scheduler is disabled during tests
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
awaitRunningState(myRolloutId); awaitRunningState(myRolloutId);
@@ -1487,7 +1487,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
final Long myRolloutId = myRollout.getId(); final Long myRolloutId = myRollout.getId();
rolloutManagement rolloutManagement
.update(entityFactory.rollout().update(myRolloutId).startAt(System.currentTimeMillis() + 60000)); .update(entityFactory.rollout().update(myRolloutId).startAt(System.currentTimeMillis() + 60000));
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
// rollout should not have been started // rollout should not have been started
myRollout = getRollout(myRolloutId); myRollout = getRollout(myRolloutId);
@@ -1495,13 +1495,13 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
// schedule to now // schedule to now
rolloutManagement.update(entityFactory.rollout().update(myRolloutId).startAt(System.currentTimeMillis())); rolloutManagement.update(entityFactory.rollout().update(myRolloutId).startAt(System.currentTimeMillis()));
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
myRollout = getRollout(myRolloutId); myRollout = getRollout(myRolloutId);
assertThat(myRollout.getStatus()).isEqualTo(RolloutStatus.STARTING); assertThat(myRollout.getStatus()).isEqualTo(RolloutStatus.STARTING);
// Run here, because scheduler is disabled during tests // Run here, because scheduler is disabled during tests
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
awaitRunningState(myRolloutId); awaitRunningState(myRolloutId);
@@ -1562,7 +1562,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
TimeUnit.SECONDS.sleep(1); TimeUnit.SECONDS.sleep(1);
testdataFactory.createTargets(10, rolloutName + "-notIn-", rolloutName); testdataFactory.createTargets(10, rolloutName + "-notIn-", rolloutName);
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
myRollout = getRollout(myRollout.getId()); myRollout = getRollout(myRollout.getId());
assertThat(myRollout.getStatus()).isEqualTo(RolloutStatus.READY); assertThat(myRollout.getStatus()).isEqualTo(RolloutStatus.READY);
@@ -1613,7 +1613,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
}); });
// first handle iteration will put rollout in ready state // first handle iteration will put rollout in ready state
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
assertThat(getRollout(rolloutId)).satisfies(rollout -> { assertThat(getRollout(rolloutId)).satisfies(rollout -> {
assertThat(rollout.getStatus()).isEqualTo(RolloutStatus.READY); assertThat(rollout.getStatus()).isEqualTo(RolloutStatus.READY);
@@ -1629,7 +1629,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
// start rollout // start rollout
rolloutManagement.start(rolloutId); rolloutManagement.start(rolloutId);
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
// verify rollout started. Check groups are in right state. // verify rollout started. Check groups are in right state.
// Group 1 should be in WFC state, since confirmation is required here. // Group 1 should be in WFC state, since confirmation is required here.
@@ -1641,7 +1641,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
// cancel execution of all action of group 1 to trigger second group // cancel execution of all action of group 1 to trigger second group
forceQuitAllActionsOfRolloutGroup(rolloutGroupIds.get(0)); forceQuitAllActionsOfRolloutGroup(rolloutGroupIds.get(0));
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
assertRolloutGroup(rolloutGroupIds.get(0), RolloutGroupStatus.FINISHED, true, amountTargetsInGroup1, assertRolloutGroup(rolloutGroupIds.get(0), RolloutGroupStatus.FINISHED, true, amountTargetsInGroup1,
Status.CANCELED); Status.CANCELED);
assertRolloutGroup(rolloutGroupIds.get(1), RolloutGroupStatus.SCHEDULED, false, amountTargetsInGroup2, assertRolloutGroup(rolloutGroupIds.get(1), RolloutGroupStatus.SCHEDULED, false, amountTargetsInGroup2,
@@ -1649,7 +1649,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
// verify actions of second rule are directly in RUNNING state, since // verify actions of second rule are directly in RUNNING state, since
// confirmation is not required for this group // confirmation is not required for this group
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
assertRolloutGroup(rolloutGroupIds.get(0), RolloutGroupStatus.FINISHED, true, amountTargetsInGroup1, assertRolloutGroup(rolloutGroupIds.get(0), RolloutGroupStatus.FINISHED, true, amountTargetsInGroup1,
Status.CANCELED); Status.CANCELED);
assertRolloutGroup(rolloutGroupIds.get(1), RolloutGroupStatus.RUNNING, false, amountTargetsInGroup2, assertRolloutGroup(rolloutGroupIds.get(1), RolloutGroupStatus.RUNNING, false, amountTargetsInGroup2,
@@ -1855,7 +1855,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
// test // test
rolloutManagement.delete(createdRollout.getId()); rolloutManagement.delete(createdRollout.getId());
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
// verify // verify
final Optional<JpaRollout> deletedRollout = rolloutRepository.findById(createdRollout.getId()); final Optional<JpaRollout> deletedRollout = rolloutRepository.findById(createdRollout.getId());
@@ -1889,7 +1889,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
// start the rollout, so it has active running actions and a group which // start the rollout, so it has active running actions and a group which
// has been started // has been started
rolloutManagement.start(createdRollout.getId()); rolloutManagement.start(createdRollout.getId());
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
// verify we have running actions // verify we have running actions
assertThat(actionRepository.findByRolloutIdAndStatus(PAGE, createdRollout.getId(), Status.RUNNING) assertThat(actionRepository.findByRolloutIdAndStatus(PAGE, createdRollout.getId(), Status.RUNNING)
@@ -1897,7 +1897,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
// test // test
rolloutManagement.delete(createdRollout.getId()); rolloutManagement.delete(createdRollout.getId());
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
// verify // verify
final JpaRollout deletedRollout = rolloutRepository.findById(createdRollout.getId()).get(); final JpaRollout deletedRollout = rolloutRepository.findById(createdRollout.getId()).get();
@@ -1941,11 +1941,11 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
Rollout rolloutRunning = rolloutManagement.create(rolloutRunningCreate, 1, false, conditions); Rollout rolloutRunning = rolloutManagement.create(rolloutRunningCreate, 1, false, conditions);
// Let the executor handle created Rollout // Let the executor handle created Rollout
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
// start the rollout, so it has active running actions and a group which // start the rollout, so it has active running actions and a group which
// has been started // has been started
rolloutManagement.start(rolloutRunning.getId()); rolloutManagement.start(rolloutRunning.getId());
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
rolloutRunning = reloadRollout(rolloutRunning); rolloutRunning = reloadRollout(rolloutRunning);
final String prefixRolloutReady = randomString + "2"; final String prefixRolloutReady = randomString + "2";
@@ -1953,7 +1953,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
.name(prefixRolloutReady + "-testRollout").targetFilterQuery("name==" + randomString + "*").set(testDs); .name(prefixRolloutReady + "-testRollout").targetFilterQuery("name==" + randomString + "*").set(testDs);
Rollout rolloutReady = rolloutManagement.create(rolloutReadyCreate, 1, false, conditions); Rollout rolloutReady = rolloutManagement.create(rolloutReadyCreate, 1, false, conditions);
// Let the executor handle created Rollout // Let the executor handle created Rollout
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
rolloutReady = reloadRollout(rolloutReady); rolloutReady = reloadRollout(rolloutReady);
final List<Rollout> rolloutsOrderedByStatus = rolloutManagement final List<Rollout> rolloutsOrderedByStatus = rolloutManagement
@@ -2017,7 +2017,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
.createSimpleTestRolloutWithTargetsAndDistributionSet(amountOfTargets, 2, amountOfTargets, .createSimpleTestRolloutWithTargetsAndDistributionSet(amountOfTargets, 2, amountOfTargets,
"80", "50", null, weight).getId(); "80", "50", null, weight).getId();
rolloutManagement.start(rolloutId); rolloutManagement.start(rolloutId);
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
final List<Action> actions = deploymentManagement.findActionsAll(PAGE).getContent(); final List<Action> actions = deploymentManagement.findActionsAll(PAGE).getContent();
assertThat(actions) // assertThat(actions) //
.hasSize(amountOfTargets) // .hasSize(amountOfTargets) //
@@ -2034,7 +2034,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
enableMultiAssignments(); enableMultiAssignments();
rolloutManagement.start(rolloutId); rolloutManagement.start(rolloutId);
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
final List<Action> actions = deploymentManagement.findActionsAll(PAGE).getContent(); final List<Action> actions = deploymentManagement.findActionsAll(PAGE).getContent();
assertThat(actions).hasSize(amountOfTargets).allMatch(action -> !action.getWeight().isPresent()); assertThat(actions).hasSize(amountOfTargets).allMatch(action -> !action.getWeight().isPresent());
} }
@@ -2114,7 +2114,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
final Rollout createdRollout = rolloutManagement.create(rolloutToCreate, 1, false, conditions); final Rollout createdRollout = rolloutManagement.create(rolloutToCreate, 1, false, conditions);
// Let the executor handle created Rollout // Let the executor handle created Rollout
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
final Rollout testRollout = reloadRollout(createdRollout); final Rollout testRollout = reloadRollout(createdRollout);
final List<RolloutGroup> rolloutGroups = rolloutGroupManagement final List<RolloutGroup> rolloutGroups = rolloutGroupManagement
@@ -2175,8 +2175,6 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
} }
} }
private Rollout createTestRolloutWithTargetsAndDistributionSet(final int amountTargetsForRollout, private Rollout createTestRolloutWithTargetsAndDistributionSet(final int amountTargetsForRollout,
final int groupSize, final String successCondition, final String errorCondition, final String rolloutName, final int groupSize, final String successCondition, final String errorCondition, final String rolloutName,
final String targetPrefixName) { final String targetPrefixName) {
@@ -2300,7 +2298,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
.withMessageContaining(errorMessage); .withMessageContaining(errorMessage);
// Run here, because scheduler is disabled during tests // Run here, because scheduler is disabled during tests
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
final Rollout rollout = reloadRollout(createdRollout); final Rollout rollout = reloadRollout(createdRollout);
rolloutManagement.pauseRollout(rollout.getId()); rolloutManagement.pauseRollout(rollout.getId());

View File

@@ -142,7 +142,7 @@ public class RepositoryEntityEventTest extends AbstractJpaIntegrationTest {
"controllerId==" + targetPrefixName + "-*", distributionSet, successCondition, errorCondition); "controllerId==" + targetPrefixName + "-*", distributionSet, successCondition, errorCondition);
rolloutManagement.delete(createdRollout.getId()); rolloutManagement.delete(createdRollout.getId());
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
final RolloutDeletedEvent rolloutDeletedEvent = eventListener.waitForEvent(RolloutDeletedEvent.class); final RolloutDeletedEvent rolloutDeletedEvent = eventListener.waitForEvent(RolloutDeletedEvent.class);
assertThat(rolloutDeletedEvent).isNotNull(); assertThat(rolloutDeletedEvent).isNotNull();

View File

@@ -39,6 +39,7 @@ import org.eclipse.hawkbit.repository.EntityFactory;
import org.eclipse.hawkbit.repository.QuotaManagement; import org.eclipse.hawkbit.repository.QuotaManagement;
import org.eclipse.hawkbit.repository.RepositoryConstants; import org.eclipse.hawkbit.repository.RepositoryConstants;
import org.eclipse.hawkbit.repository.RolloutGroupManagement; import org.eclipse.hawkbit.repository.RolloutGroupManagement;
import org.eclipse.hawkbit.repository.RolloutHandler;
import org.eclipse.hawkbit.repository.RolloutManagement; import org.eclipse.hawkbit.repository.RolloutManagement;
import org.eclipse.hawkbit.repository.SoftwareModuleManagement; import org.eclipse.hawkbit.repository.SoftwareModuleManagement;
import org.eclipse.hawkbit.repository.SoftwareModuleTypeManagement; import org.eclipse.hawkbit.repository.SoftwareModuleTypeManagement;
@@ -181,6 +182,9 @@ public abstract class AbstractIntegrationTest {
@Autowired @Autowired
protected RolloutManagement rolloutManagement; protected RolloutManagement rolloutManagement;
@Autowired
protected RolloutHandler rolloutHandler;
@Autowired @Autowired
protected RolloutGroupManagement rolloutGroupManagement; protected RolloutGroupManagement rolloutGroupManagement;

View File

@@ -36,6 +36,7 @@ import org.eclipse.hawkbit.repository.DistributionSetTagManagement;
import org.eclipse.hawkbit.repository.DistributionSetTypeManagement; import org.eclipse.hawkbit.repository.DistributionSetTypeManagement;
import org.eclipse.hawkbit.repository.EntityFactory; import org.eclipse.hawkbit.repository.EntityFactory;
import org.eclipse.hawkbit.repository.QuotaManagement; import org.eclipse.hawkbit.repository.QuotaManagement;
import org.eclipse.hawkbit.repository.RolloutHandler;
import org.eclipse.hawkbit.repository.RolloutManagement; import org.eclipse.hawkbit.repository.RolloutManagement;
import org.eclipse.hawkbit.repository.SoftwareModuleManagement; import org.eclipse.hawkbit.repository.SoftwareModuleManagement;
import org.eclipse.hawkbit.repository.SoftwareModuleTypeManagement; import org.eclipse.hawkbit.repository.SoftwareModuleTypeManagement;
@@ -177,6 +178,9 @@ public class TestdataFactory {
@Autowired @Autowired
private RolloutManagement rolloutManagement; private RolloutManagement rolloutManagement;
@Autowired
private RolloutHandler rolloutHandler;
@Autowired @Autowired
private QuotaManagement quotaManagement; private QuotaManagement quotaManagement;
@@ -1202,7 +1206,7 @@ public class TestdataFactory {
groupSize, confirmationRequired, conditions); groupSize, confirmationRequired, conditions);
// Run here, because Scheduler is disabled during tests // Run here, because Scheduler is disabled during tests
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
return rolloutManagement.get(rollout.getId()).get(); return rolloutManagement.get(rollout.getId()).get();
} }
@@ -1253,7 +1257,7 @@ public class TestdataFactory {
rolloutManagement.start(rollout.getId()); rolloutManagement.start(rollout.getId());
// Run here, because scheduler is disabled during tests // Run here, because scheduler is disabled during tests
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
return reloadRollout(rollout); return reloadRollout(rollout);
} }
@@ -1350,9 +1354,9 @@ public class TestdataFactory {
public Rollout createSoftDeletedRollout(final String prefix) { public Rollout createSoftDeletedRollout(final String prefix) {
final Rollout newRollout = createRollout(prefix); final Rollout newRollout = createRollout(prefix);
rolloutManagement.start(newRollout.getId()); rolloutManagement.start(newRollout.getId());
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
rolloutManagement.delete(newRollout.getId()); rolloutManagement.delete(newRollout.getId());
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
return newRollout; return newRollout;
} }

View File

@@ -207,7 +207,7 @@ class MgmtActionResourceTest extends AbstractManagementApiIntegrationTest {
final Rollout rollout = testdataFactory.createRolloutByVariables("TestRollout", "TestDesc", 1, final Rollout rollout = testdataFactory.createRolloutByVariables("TestRollout", "TestDesc", 1,
"name==" + target1.getName(), ds, "50", "5"); "name==" + target1.getName(), ds, "50", "5");
rolloutManagement.start(rollout.getId()); rolloutManagement.start(rollout.getId());
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
final String rsqlRolloutName = "rollout.name==" + rollout.getName(); final String rsqlRolloutName = "rollout.name==" + rollout.getName();
final String rsqlRolloutId = "rollout.id==" + rollout.getId(); final String rsqlRolloutId = "rollout.id==" + rollout.getId();

View File

@@ -301,9 +301,9 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest {
4, false, new RolloutGroupConditionBuilder().withDefaults() 4, false, new RolloutGroupConditionBuilder().withDefaults()
.successCondition(RolloutGroupSuccessCondition.THRESHOLD, "100").build()); .successCondition(RolloutGroupSuccessCondition.THRESHOLD, "100").build());
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
rolloutManagement.start(rollout.getId()); rolloutManagement.start(rollout.getId());
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
// request the list of rollouts with full representation // request the list of rollouts with full representation
mvc.perform(get("/rest/v1/rollouts?representation=full").accept(MediaType.APPLICATION_JSON)) mvc.perform(get("/rest/v1/rollouts?representation=full").accept(MediaType.APPLICATION_JSON))
@@ -458,7 +458,7 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest {
@Step @Step
private void retrieveAndVerifyRolloutInRunning(final Rollout rollout) throws Exception { private void retrieveAndVerifyRolloutInRunning(final Rollout rollout) throws Exception {
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
mvc.perform(get("/rest/v1/rollouts/" + rollout.getId()).accept(MediaType.APPLICATION_JSON)) mvc.perform(get("/rest/v1/rollouts/" + rollout.getId()).accept(MediaType.APPLICATION_JSON))
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
@@ -494,7 +494,7 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest {
@Step @Step
private void retrieveAndVerifyRolloutInReady(final Rollout rollout) throws Exception { private void retrieveAndVerifyRolloutInReady(final Rollout rollout) throws Exception {
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
mvc.perform(get("/rest/v1/rollouts/" + rollout.getId()).accept(MediaType.APPLICATION_JSON)) mvc.perform(get("/rest/v1/rollouts/" + rollout.getId()).accept(MediaType.APPLICATION_JSON))
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
@@ -556,7 +556,7 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest {
postRollout("rollout2", 5, dsA.getId(), "id==target-0001*", 10, Action.ActionType.FORCED); postRollout("rollout2", 5, dsA.getId(), "id==target-0001*", 10, Action.ActionType.FORCED);
// Run here, because Scheduler is disabled during tests // Run here, because Scheduler is disabled during tests
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
mvc.perform(get("/rest/v1/rollouts").accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) mvc.perform(get("/rest/v1/rollouts").accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print())
.andExpect(status().isOk()).andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(status().isOk()).andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
@@ -598,7 +598,7 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest {
startAt, forcetime); startAt, forcetime);
// Run here, because Scheduler is disabled during tests // Run here, because Scheduler is disabled during tests
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
retrieveAndCompareRolloutsContent(dsA, "/rest/v1/rollouts", false, true, startAt, forcetime); retrieveAndCompareRolloutsContent(dsA, "/rest/v1/rollouts", false, true, startAt, forcetime);
retrieveAndCompareRolloutsContent(dsA, "/rest/v1/rollouts?representation=full", true, true, startAt, forcetime); retrieveAndCompareRolloutsContent(dsA, "/rest/v1/rollouts?representation=full", true, true, startAt, forcetime);
@@ -616,7 +616,7 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest {
postRollout("rollout2", 5, dsA.getId(), "id==target-0001*", 10, Action.ActionType.FORCED); postRollout("rollout2", 5, dsA.getId(), "id==target-0001*", 10, Action.ActionType.FORCED);
// Run here, because Scheduler is disabled during tests // Run here, because Scheduler is disabled during tests
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
retrieveAndCompareRolloutsContent(dsA, "/rest/v1/rollouts", false); retrieveAndCompareRolloutsContent(dsA, "/rest/v1/rollouts", false);
retrieveAndCompareRolloutsContent(dsA, "/rest/v1/rollouts?representation=full", true); retrieveAndCompareRolloutsContent(dsA, "/rest/v1/rollouts?representation=full", true);
@@ -634,7 +634,7 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest {
postRollout("rollout2", 5, dsA.getId(), "id==target*", 20, Action.ActionType.FORCED); postRollout("rollout2", 5, dsA.getId(), "id==target*", 20, Action.ActionType.FORCED);
// Run here, because Scheduler is disabled during tests // Run here, because Scheduler is disabled during tests
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
mvc.perform(get("/rest/v1/rollouts?limit=1").accept(MediaType.APPLICATION_JSON)) mvc.perform(get("/rest/v1/rollouts?limit=1").accept(MediaType.APPLICATION_JSON))
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
@@ -707,7 +707,7 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest {
.andExpect(jsonPath("status", equalTo("starting"))); .andExpect(jsonPath("status", equalTo("starting")));
// Run here, because scheduler is disabled during tests // Run here, because scheduler is disabled during tests
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
// check rollout is in running state // check rollout is in running state
mvc.perform(get("/rest/v1/rollouts/{rolloutId}", rollout.getId()).accept(MediaType.APPLICATION_JSON)) mvc.perform(get("/rest/v1/rollouts/{rolloutId}", rollout.getId()).accept(MediaType.APPLICATION_JSON))
@@ -733,7 +733,7 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest {
.andExpect(status().isOk()); .andExpect(status().isOk());
// Run here, because scheduler is disabled during tests // Run here, because scheduler is disabled during tests
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
// pausing rollout // pausing rollout
mvc.perform(post("/rest/v1/rollouts/{rolloutId}/pause", rollout.getId())).andDo(MockMvcResultPrinter.print()) mvc.perform(post("/rest/v1/rollouts/{rolloutId}/pause", rollout.getId())).andDo(MockMvcResultPrinter.print())
@@ -763,7 +763,7 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest {
.andExpect(status().isOk()); .andExpect(status().isOk());
// Run here, because scheduler is disabled during tests // Run here, because scheduler is disabled during tests
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
// pausing rollout // pausing rollout
mvc.perform(post("/rest/v1/rollouts/{rolloutId}/pause", rollout.getId())).andDo(MockMvcResultPrinter.print()) mvc.perform(post("/rest/v1/rollouts/{rolloutId}/pause", rollout.getId())).andDo(MockMvcResultPrinter.print())
@@ -797,7 +797,7 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest {
.andExpect(status().isOk()); .andExpect(status().isOk());
// Run here, because scheduler is disabled during tests // Run here, because scheduler is disabled during tests
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
// starting rollout - already started should lead into bad request // starting rollout - already started should lead into bad request
mvc.perform(post("/rest/v1/rollouts/{rolloutId}/start", rollout.getId())).andDo(MockMvcResultPrinter.print()) mvc.perform(post("/rest/v1/rollouts/{rolloutId}/start", rollout.getId())).andDo(MockMvcResultPrinter.print())
@@ -838,7 +838,7 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest {
.andExpect(status().isOk()); .andExpect(status().isOk());
// Run here, because scheduler is disabled during tests // Run here, because scheduler is disabled during tests
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
// retrieve rollout groups from created rollout - 2 groups exists // retrieve rollout groups from created rollout - 2 groups exists
// (amountTargets / groupSize = 2) // (amountTargets / groupSize = 2)
@@ -891,7 +891,7 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest {
final RolloutGroup firstGroup, final RolloutGroup secondGroup, final boolean confirmationFlowEnabled, final RolloutGroup firstGroup, final RolloutGroup secondGroup, final boolean confirmationFlowEnabled,
final boolean confirmationRequired) throws Exception { final boolean confirmationRequired) throws Exception {
rolloutManagement.start(rollout.getId()); rolloutManagement.start(rollout.getId());
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
mvc.perform(get("/rest/v1/rollouts/{rolloutId}/deploygroups/{groupId}", rollout.getId(), firstGroup.getId()) mvc.perform(get("/rest/v1/rollouts/{rolloutId}/deploygroups/{groupId}", rollout.getId(), firstGroup.getId())
.accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
@@ -923,7 +923,7 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest {
@Step @Step
private void retrieveAndVerifyRolloutGroupInReady(final Rollout rollout, final RolloutGroup firstGroup) private void retrieveAndVerifyRolloutGroupInReady(final Rollout rollout, final RolloutGroup firstGroup)
throws Exception { throws Exception {
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
mvc.perform(get("/rest/v1/rollouts/{rolloutId}/deploygroups/{groupId}", rollout.getId(), firstGroup.getId()) mvc.perform(get("/rest/v1/rollouts/{rolloutId}/deploygroups/{groupId}", rollout.getId(), firstGroup.getId())
.accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
@@ -1034,7 +1034,7 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest {
rolloutManagement.start(rollout.getId()); rolloutManagement.start(rollout.getId());
// Run here, because scheduler is disabled during tests // Run here, because scheduler is disabled during tests
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
final RolloutGroup firstGroup = rolloutGroupManagement final RolloutGroup firstGroup = rolloutGroupManagement
.findByRollout(PageRequest.of(0, 1, Direction.ASC, "id"), rollout.getId()).getContent().get(0); .findByRollout(PageRequest.of(0, 1, Direction.ASC, "id"), rollout.getId()).getContent().get(0);
@@ -1064,7 +1064,7 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest {
.andExpect(status().isOk()); .andExpect(status().isOk());
// Run here, because scheduler is disabled during tests // Run here, because scheduler is disabled during tests
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
// check if running // check if running
awaitRunningState(rollout.getId()); awaitRunningState(rollout.getId());
@@ -1280,7 +1280,7 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest {
.successCondition(RolloutGroupSuccessCondition.THRESHOLD, "100").build()); .successCondition(RolloutGroupSuccessCondition.THRESHOLD, "100").build());
// Run here, because Scheduler is disabled during tests // Run here, because Scheduler is disabled during tests
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
return rolloutManagement.get(rollout.getId()).orElseThrow(NoSuchElementException::new); return rolloutManagement.get(rollout.getId()).orElseThrow(NoSuchElementException::new);
} }
@@ -1295,7 +1295,7 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest {
final Rollout rollout = createRollout("rollout1", 4, dsA.getId(), "controllerId==rollout*"); final Rollout rollout = createRollout("rollout1", 4, dsA.getId(), "controllerId==rollout*");
rolloutManagement.start(rollout.getId()); rolloutManagement.start(rollout.getId());
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
mvc.perform(post("/rest/v1/rollouts/{rolloutId}/triggerNextGroup", rollout.getId())) mvc.perform(post("/rest/v1/rollouts/{rolloutId}/triggerNextGroup", rollout.getId()))
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()); .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
@@ -1318,7 +1318,7 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest {
triggerNextGroupAndExpect(rollout, status().isBadRequest()); triggerNextGroupAndExpect(rollout, status().isBadRequest());
// READY state // READY state
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
triggerNextGroupAndExpect(rollout, status().isBadRequest()); triggerNextGroupAndExpect(rollout, status().isBadRequest());
// STARTING state // STARTING state
@@ -1326,7 +1326,7 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest {
triggerNextGroupAndExpect(rollout, status().isBadRequest()); triggerNextGroupAndExpect(rollout, status().isBadRequest());
// RUNNING state // RUNNING state
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
triggerNextGroupAndExpect(rollout, status().isOk()); triggerNextGroupAndExpect(rollout, status().isOk());
// PAUSED state // PAUSED state
@@ -1341,7 +1341,7 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest {
// FINISHED state // FINISHED state
setTargetsStatus(targets, Status.FINISHED); setTargetsStatus(targets, Status.FINISHED);
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
triggerNextGroupAndExpect(rollout, status().isBadRequest()); triggerNextGroupAndExpect(rollout, status().isBadRequest());
} }

View File

@@ -2118,7 +2118,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest {
final Rollout rollout = testdataFactory.createRolloutByVariables("My Rollout", "My Rollout Description", 1, final Rollout rollout = testdataFactory.createRolloutByVariables("My Rollout", "My Rollout Description", 1,
"name==trg*", ds, "50", "5"); "name==trg*", ds, "50", "5");
rolloutManagement.start(rollout.getId()); rolloutManagement.start(rollout.getId());
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
// get all actions for the first target // get all actions for the first target
final Target target = targets.get(0); final Target target = targets.get(0);

View File

@@ -196,7 +196,7 @@ public abstract class AbstractApiRestDocumentation extends AbstractRestIntegrati
// start the rollout and handle it // start the rollout and handle it
rolloutManagement.start(rollout.getId()); rolloutManagement.start(rollout.getId());
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
updatedTargets = Collections.singletonList(savedTarget); updatedTargets = Collections.singletonList(savedTarget);

View File

@@ -416,7 +416,7 @@ public class RolloutResourceDocumentationTest extends AbstractApiRestDocumentati
rolloutManagement.start(rollout.getId()); rolloutManagement.start(rollout.getId());
// Run here, because scheduler is disabled during tests // Run here, because scheduler is disabled during tests
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
mockMvc.perform(post(MgmtRestConstants.ROLLOUT_V1_REQUEST_MAPPING + "/{rolloutId}/pause", rollout.getId()) mockMvc.perform(post(MgmtRestConstants.ROLLOUT_V1_REQUEST_MAPPING + "/{rolloutId}/pause", rollout.getId())
.accept(MediaTypes.HAL_JSON_VALUE)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .accept(MediaTypes.HAL_JSON_VALUE)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
@@ -431,7 +431,7 @@ public class RolloutResourceDocumentationTest extends AbstractApiRestDocumentati
rolloutManagement.start(rollout.getId()); rolloutManagement.start(rollout.getId());
// Run here, because scheduler is disabled during tests // Run here, because scheduler is disabled during tests
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
rolloutManagement.pauseRollout(rollout.getId()); rolloutManagement.pauseRollout(rollout.getId());
mockMvc.perform(post(MgmtRestConstants.ROLLOUT_V1_REQUEST_MAPPING + "/{rolloutId}/resume", rollout.getId()) mockMvc.perform(post(MgmtRestConstants.ROLLOUT_V1_REQUEST_MAPPING + "/{rolloutId}/resume", rollout.getId())
@@ -471,7 +471,7 @@ public class RolloutResourceDocumentationTest extends AbstractApiRestDocumentati
rolloutManagement.start(rollout.getId()); rolloutManagement.start(rollout.getId());
// Run here, because scheduler is disabled during tests // Run here, because scheduler is disabled during tests
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
mockMvc.perform( mockMvc.perform(
post(MgmtRestConstants.ROLLOUT_V1_REQUEST_MAPPING + "/{rolloutId}/triggerNextGroup", rollout.getId()) post(MgmtRestConstants.ROLLOUT_V1_REQUEST_MAPPING + "/{rolloutId}/triggerNextGroup", rollout.getId())
@@ -692,7 +692,7 @@ public class RolloutResourceDocumentationTest extends AbstractApiRestDocumentati
.withDefaults().successCondition(RolloutGroupSuccessCondition.THRESHOLD, "10").build()); .withDefaults().successCondition(RolloutGroupSuccessCondition.THRESHOLD, "10").build());
// Run here, because Scheduler is disabled during tests // Run here, because Scheduler is disabled during tests
rolloutManagement.handleRollouts(); rolloutHandler.handleAll();
return rolloutManagement return rolloutManagement
.update(entityFactory.rollout().update(rollout.getId()).startAt(System.currentTimeMillis() + 1000).description("exampleDescription")); .update(entityFactory.rollout().update(rollout.getId()).startAt(System.currentTimeMillis() + 1000).description("exampleDescription"));