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:
@@ -460,15 +460,11 @@ public class AmqpMessageDispatcherServiceIntegrationTest extends AbstractAmqpSer
|
||||
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) {
|
||||
final Rollout rollout = testdataFactory.createRolloutByVariables(UUID.randomUUID().toString(), "", 1,
|
||||
filterQuery, ds, "50", "5", ActionType.FORCED, weight, false);
|
||||
rolloutManagement.start(rollout.getId());
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
return rollout;
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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.RolloutGroupConditions;
|
||||
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.Pageable;
|
||||
import org.springframework.data.domain.Slice;
|
||||
@@ -48,37 +47,7 @@ import org.springframework.util.concurrent.ListenableFuture;
|
||||
public interface RolloutManagement {
|
||||
|
||||
/**
|
||||
* Process rollout based on its current {@link Rollout#getStatus()}.
|
||||
*
|
||||
* 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.
|
||||
* Counts all {@link Rollout}s in the repository that are not marked as deleted.
|
||||
*
|
||||
* @return number of roll outs
|
||||
*/
|
||||
@@ -267,6 +236,14 @@ public interface RolloutManagement {
|
||||
Slice<Rollout> findByFiltersWithDetailedStatus(@NotNull Pageable pageable, @NotEmpty String searchText,
|
||||
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.
|
||||
*
|
||||
|
||||
@@ -157,40 +157,14 @@ public interface RolloutGroup extends NamedEntity {
|
||||
* The condition to evaluate if an group is success state.
|
||||
*/
|
||||
enum RolloutGroupSuccessCondition {
|
||||
THRESHOLD("thresholdRolloutGroupSuccessCondition");
|
||||
|
||||
private final String beanName;
|
||||
|
||||
RolloutGroupSuccessCondition(final String beanName) {
|
||||
this.beanName = beanName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the beanName
|
||||
*/
|
||||
public String getBeanName() {
|
||||
return beanName;
|
||||
}
|
||||
THRESHOLD
|
||||
}
|
||||
|
||||
/**
|
||||
* The condition to evaluate if an group is in error state.
|
||||
*/
|
||||
enum RolloutGroupErrorCondition {
|
||||
THRESHOLD("thresholdRolloutGroupErrorCondition");
|
||||
|
||||
private final String beanName;
|
||||
|
||||
RolloutGroupErrorCondition(final String beanName) {
|
||||
this.beanName = beanName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the beanName
|
||||
*/
|
||||
public String getBeanName() {
|
||||
return beanName;
|
||||
}
|
||||
THRESHOLD
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -198,20 +172,7 @@ public interface RolloutGroup extends NamedEntity {
|
||||
* hit.
|
||||
*/
|
||||
enum RolloutGroupErrorAction {
|
||||
PAUSE("pauseRolloutGroupAction");
|
||||
|
||||
private final String beanName;
|
||||
|
||||
RolloutGroupErrorAction(final String beanName) {
|
||||
this.beanName = beanName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the beanName
|
||||
*/
|
||||
public String getBeanName() {
|
||||
return beanName;
|
||||
}
|
||||
PAUSE
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -219,19 +180,6 @@ public interface RolloutGroup extends NamedEntity {
|
||||
* is hit.
|
||||
*/
|
||||
enum RolloutGroupSuccessAction {
|
||||
NEXTGROUP("startNextRolloutGroupAction");
|
||||
|
||||
private final String beanName;
|
||||
|
||||
RolloutGroupSuccessAction(final String beanName) {
|
||||
this.beanName = beanName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the beanName
|
||||
*/
|
||||
public String getBeanName() {
|
||||
return beanName;
|
||||
}
|
||||
NEXTGROUP
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.JpaRolloutGroup;
|
||||
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.RolloutGroupConditionEvaluator;
|
||||
import org.eclipse.hawkbit.repository.jpa.rollout.condition.EvaluatorNotConfiguredException;
|
||||
import org.eclipse.hawkbit.repository.jpa.rollout.condition.RolloutGroupEvaluationManager;
|
||||
import org.eclipse.hawkbit.repository.jpa.utils.DeploymentHelper;
|
||||
import org.eclipse.hawkbit.repository.jpa.utils.QuotaHelper;
|
||||
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.slf4j.Logger;
|
||||
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.Slice;
|
||||
import org.springframework.data.domain.Sort;
|
||||
@@ -105,8 +103,9 @@ public class JpaRolloutExecutor implements RolloutExecutor {
|
||||
private final EventPublisherHolder eventPublisherHolder;
|
||||
private final PlatformTransactionManager txManager;
|
||||
private final RolloutApprovalStrategy rolloutApprovalStrategy;
|
||||
private final ApplicationContext context;
|
||||
|
||||
private final RolloutGroupEvaluationManager evaluationManager;
|
||||
private final RolloutManagement rolloutManagement;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
@@ -117,7 +116,8 @@ public class JpaRolloutExecutor implements RolloutExecutor {
|
||||
final RolloutGroupManagement rolloutGroupManagement, final QuotaManagement quotaManagement,
|
||||
final DeploymentManagement deploymentManagement, final TargetManagement targetManagement,
|
||||
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.entityManager = entityManager;
|
||||
this.rolloutRepository = rolloutRepository;
|
||||
@@ -132,7 +132,8 @@ public class JpaRolloutExecutor implements RolloutExecutor {
|
||||
this.eventPublisherHolder = eventPublisherHolder;
|
||||
this.txManager = txManager;
|
||||
this.rolloutApprovalStrategy = rolloutApprovalStrategy;
|
||||
this.context = context;
|
||||
this.evaluationManager = evaluationManager;
|
||||
this.rolloutManagement = rolloutManagement;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -285,7 +286,7 @@ public class JpaRolloutExecutor implements RolloutExecutor {
|
||||
LOGGER.debug(
|
||||
"handleReadyRollout called for rollout {} with autostart beyond define time. Switch to STARTING",
|
||||
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) {
|
||||
try {
|
||||
context.getBean(rolloutGroup.getErrorAction().getBeanName(), RolloutGroupActionEvaluator.class)
|
||||
.eval(rollout, rolloutGroup, rolloutGroup.getErrorActionExp());
|
||||
} catch (final BeansException e) {
|
||||
LOGGER.error("Something bad happend when accessing the error action bean {}",
|
||||
rolloutGroup.getErrorAction().getBeanName(), e);
|
||||
evaluationManager.getErrorActionEvaluator(rolloutGroup.getErrorAction()).exec(rollout, rolloutGroup);
|
||||
} catch (final EvaluatorNotConfiguredException e) {
|
||||
LOGGER.error("Something bad happened when accessing the error action bean {}",
|
||||
rolloutGroup.getErrorAction().name(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -443,11 +443,10 @@ public class JpaRolloutExecutor implements RolloutExecutor {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
return context.getBean(errorCondition.getBeanName(), RolloutGroupConditionEvaluator.class).eval(rollout,
|
||||
rolloutGroup, rolloutGroup.getErrorConditionExp());
|
||||
} catch (final BeansException e) {
|
||||
LOGGER.error("Something bad happend when accessing the error condition bean {}",
|
||||
errorCondition.getBeanName(), e);
|
||||
return evaluationManager.getErrorConditionEvaluator(errorCondition).eval(rollout, rolloutGroup,
|
||||
rolloutGroup.getErrorConditionExp());
|
||||
} catch (final EvaluatorNotConfiguredException e) {
|
||||
LOGGER.error("Something bad happened when accessing the error condition bean {}", errorCondition.name(), e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -456,9 +455,8 @@ public class JpaRolloutExecutor implements RolloutExecutor {
|
||||
final RolloutGroupSuccessCondition finishCondition) {
|
||||
LOGGER.trace("Checking finish condition {} on rolloutgroup {}", finishCondition, rolloutGroup);
|
||||
try {
|
||||
final boolean isFinished = context
|
||||
.getBean(finishCondition.getBeanName(), RolloutGroupConditionEvaluator.class)
|
||||
.eval(rollout, rolloutGroup, rolloutGroup.getSuccessConditionExp());
|
||||
final boolean isFinished = evaluationManager.getSuccessConditionEvaluator(finishCondition).eval(rollout,
|
||||
rolloutGroup, rolloutGroup.getSuccessConditionExp());
|
||||
if (isFinished) {
|
||||
LOGGER.debug("Rolloutgroup {} is finished, starting next group", rolloutGroup);
|
||||
executeRolloutGroupSuccessAction(rollout, rolloutGroup);
|
||||
@@ -466,16 +464,15 @@ public class JpaRolloutExecutor implements RolloutExecutor {
|
||||
LOGGER.debug("Rolloutgroup {} is still running", rolloutGroup);
|
||||
}
|
||||
return isFinished;
|
||||
} catch (final BeansException e) {
|
||||
LOGGER.error("Something bad happend when accessing the finish condition bean {}",
|
||||
finishCondition.getBeanName(), e);
|
||||
} catch (final EvaluatorNotConfiguredException e) {
|
||||
LOGGER.error("Something bad happened when accessing the finish condition or success action bean {}",
|
||||
finishCondition.name(), e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void executeRolloutGroupSuccessAction(final Rollout rollout, final RolloutGroup rolloutGroup) {
|
||||
context.getBean(rolloutGroup.getSuccessAction().getBeanName(), RolloutGroupActionEvaluator.class).eval(rollout,
|
||||
rolloutGroup, rolloutGroup.getSuccessActionExp());
|
||||
evaluationManager.getSuccessActionEvaluator(rolloutGroup.getSuccessAction()).exec(rollout, rolloutGroup);
|
||||
}
|
||||
|
||||
private void startFirstRolloutGroup(final Rollout rollout) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -16,9 +16,7 @@ import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -28,7 +26,6 @@ import javax.validation.ValidationException;
|
||||
import org.eclipse.hawkbit.repository.DistributionSetManagement;
|
||||
import org.eclipse.hawkbit.repository.QuotaManagement;
|
||||
import org.eclipse.hawkbit.repository.RolloutApprovalStrategy;
|
||||
import org.eclipse.hawkbit.repository.RolloutExecutor;
|
||||
import org.eclipse.hawkbit.repository.RolloutFields;
|
||||
import org.eclipse.hawkbit.repository.RolloutHelper;
|
||||
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.rsql.RSQLUtility;
|
||||
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.WeightValidationHelper;
|
||||
import org.eclipse.hawkbit.repository.model.BaseEntity;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetType;
|
||||
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.rsql.VirtualPropertyReplacer;
|
||||
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.LoggerFactory;
|
||||
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.Direction;
|
||||
import org.springframework.data.jpa.domain.Specification;
|
||||
import org.springframework.integration.support.locks.LockRegistry;
|
||||
import org.springframework.orm.jpa.vendor.Database;
|
||||
import org.springframework.retry.annotation.Backoff;
|
||||
import org.springframework.retry.annotation.Retryable;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
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.util.CollectionUtils;
|
||||
import org.springframework.util.concurrent.ListenableFuture;
|
||||
@@ -137,35 +127,26 @@ public class JpaRolloutManagement implements RolloutManagement {
|
||||
private final TargetManagement targetManagement;
|
||||
private final DistributionSetManagement distributionSetManagement;
|
||||
private final VirtualPropertyReplacer virtualPropertyReplacer;
|
||||
private final PlatformTransactionManager txManager;
|
||||
private final TenantAware tenantAware;
|
||||
private final LockRegistry lockRegistry;
|
||||
private final RolloutApprovalStrategy rolloutApprovalStrategy;
|
||||
private final TenantConfigurationManagement tenantConfigurationManagement;
|
||||
private final SystemSecurityContext systemSecurityContext;
|
||||
private final RolloutExecutor rolloutExecutor;
|
||||
private final EventPublisherHolder eventPublisherHolder;
|
||||
private final Database database;
|
||||
|
||||
public JpaRolloutManagement(final TargetManagement targetManagement,
|
||||
final DistributionSetManagement distributionSetManagement, final EventPublisherHolder eventPublisherHolder,
|
||||
final VirtualPropertyReplacer virtualPropertyReplacer, final PlatformTransactionManager txManager,
|
||||
final TenantAware tenantAware, final LockRegistry lockRegistry, final Database database,
|
||||
final VirtualPropertyReplacer virtualPropertyReplacer, final Database database,
|
||||
final RolloutApprovalStrategy rolloutApprovalStrategy,
|
||||
final TenantConfigurationManagement tenantConfigurationManagement,
|
||||
final SystemSecurityContext systemSecurityContext, final RolloutExecutor rolloutExecutor) {
|
||||
final SystemSecurityContext systemSecurityContext) {
|
||||
this.targetManagement = targetManagement;
|
||||
this.distributionSetManagement = distributionSetManagement;
|
||||
this.virtualPropertyReplacer = virtualPropertyReplacer;
|
||||
this.txManager = txManager;
|
||||
this.tenantAware = tenantAware;
|
||||
this.lockRegistry = lockRegistry;
|
||||
this.rolloutApprovalStrategy = rolloutApprovalStrategy;
|
||||
this.tenantConfigurationManagement = tenantConfigurationManagement;
|
||||
this.systemSecurityContext = systemSecurityContext;
|
||||
this.eventPublisherHolder = eventPublisherHolder;
|
||||
this.database = database;
|
||||
this.rolloutExecutor = rolloutExecutor;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -435,43 +416,10 @@ public class JpaRolloutManagement implements RolloutManagement {
|
||||
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) {
|
||||
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
|
||||
@Transactional
|
||||
@Retryable(include = {
|
||||
@@ -517,6 +465,11 @@ public class JpaRolloutManagement implements RolloutManagement {
|
||||
return findAll;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Long> findActiveRollouts() {
|
||||
return rolloutRepository.findByStatusIn(ACTIVE_ROLLOUTS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Rollout> getByName(final String rolloutName) {
|
||||
return rolloutRepository.findByName(rolloutName);
|
||||
@@ -649,11 +602,6 @@ public class JpaRolloutManagement implements RolloutManagement {
|
||||
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
|
||||
@Transactional
|
||||
public void cancelRolloutsForDistributionSet(final DistributionSet set) {
|
||||
@@ -778,7 +726,7 @@ public class JpaRolloutManagement implements RolloutManagement {
|
||||
.filter(g -> RolloutGroupStatus.RUNNING.equals(g.getStatus())).findFirst()
|
||||
.orElseThrow(() -> new RolloutIllegalStateException("No group is running"));
|
||||
|
||||
startNextRolloutGroupAction.eval(rollout, latestRunning, latestRunning.getSuccessActionExp());
|
||||
startNextRolloutGroupAction.exec(rollout, latestRunning);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ import org.eclipse.hawkbit.repository.RepositoryProperties;
|
||||
import org.eclipse.hawkbit.repository.RolloutApprovalStrategy;
|
||||
import org.eclipse.hawkbit.repository.RolloutExecutor;
|
||||
import org.eclipse.hawkbit.repository.RolloutGroupManagement;
|
||||
import org.eclipse.hawkbit.repository.RolloutHandler;
|
||||
import org.eclipse.hawkbit.repository.RolloutManagement;
|
||||
import org.eclipse.hawkbit.repository.RolloutStatusCache;
|
||||
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.rollout.RolloutScheduler;
|
||||
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.ThresholdRolloutGroupErrorCondition;
|
||||
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.DistributionSetType;
|
||||
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.Target;
|
||||
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.JpaProperties;
|
||||
import org.springframework.boot.autoconfigure.transaction.TransactionManagerCustomizers;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.EnableAspectJAutoProxy;
|
||||
@@ -195,6 +199,16 @@ public class RepositoryApplicationConfiguration extends JpaBaseConfiguration {
|
||||
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
|
||||
@ConditionalOnMissingBean
|
||||
SystemManagementCacheKeyGenerator systemManagementCacheKeyGenerator() {
|
||||
@@ -660,6 +674,14 @@ public class RepositoryApplicationConfiguration extends JpaBaseConfiguration {
|
||||
return new JpaSoftwareModuleTypeManagement(distributionSetTypeRepository, softwareModuleTypeRepository,
|
||||
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
|
||||
@ConditionalOnMissingBean
|
||||
@@ -670,25 +692,25 @@ public class RepositoryApplicationConfiguration extends JpaBaseConfiguration {
|
||||
final RolloutGroupManagement rolloutGroupManagement, final QuotaManagement quotaManagement,
|
||||
final DeploymentManagement deploymentManagement, final TargetManagement targetManagement,
|
||||
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,
|
||||
rolloutGroupRepository, afterCommit, tenantAware, rolloutGroupManagement, quotaManagement,
|
||||
deploymentManagement, targetManagement, eventPublisherHolder, txManager, rolloutApprovalStrategy,
|
||||
context);
|
||||
evaluationManager, rolloutManagement);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
RolloutManagement rolloutManagement(final TargetManagement targetManagement,
|
||||
final DistributionSetManagement distributionSetManagement, final EventPublisherHolder eventPublisherHolder,
|
||||
final VirtualPropertyReplacer virtualPropertyReplacer, final PlatformTransactionManager txManager,
|
||||
final TenantAware tenantAware, final LockRegistry lockRegistry, final JpaProperties properties,
|
||||
final VirtualPropertyReplacer virtualPropertyReplacer, final JpaProperties properties,
|
||||
final RolloutApprovalStrategy rolloutApprovalStrategy,
|
||||
final TenantConfigurationManagement tenantConfigurationManagement,
|
||||
final SystemSecurityContext systemSecurityContext, final RolloutExecutor rolloutExecutor) {
|
||||
final SystemSecurityContext systemSecurityContext) {
|
||||
return new JpaRolloutManagement(targetManagement, distributionSetManagement, eventPublisherHolder,
|
||||
virtualPropertyReplacer, txManager, tenantAware, lockRegistry, properties.getDatabase(),
|
||||
rolloutApprovalStrategy, tenantConfigurationManagement, systemSecurityContext, rolloutExecutor);
|
||||
virtualPropertyReplacer, properties.getDatabase(), rolloutApprovalStrategy,
|
||||
tenantConfigurationManagement, systemSecurityContext);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -913,7 +935,7 @@ public class RepositoryApplicationConfiguration extends JpaBaseConfiguration {
|
||||
*
|
||||
* @param systemManagement
|
||||
* to find all tenants
|
||||
* @param rolloutManagement
|
||||
* @param rolloutHandler
|
||||
* to run the rollout handler
|
||||
* @param systemSecurityContext
|
||||
* to run as system
|
||||
@@ -924,8 +946,8 @@ public class RepositoryApplicationConfiguration extends JpaBaseConfiguration {
|
||||
@Profile("!test")
|
||||
@ConditionalOnProperty(prefix = "hawkbit.rollout.scheduler", name = "enabled", matchIfMissing = true)
|
||||
RolloutScheduler rolloutScheduler(final TenantAware tenantAware, final SystemManagement systemManagement,
|
||||
final RolloutManagement rolloutManagement, final SystemSecurityContext systemSecurityContext) {
|
||||
return new RolloutScheduler(systemManagement, rolloutManagement, systemSecurityContext);
|
||||
final RolloutHandler rolloutHandler, final SystemSecurityContext systemSecurityContext) {
|
||||
return new RolloutScheduler(systemManagement, rolloutHandler, systemSecurityContext);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*/
|
||||
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.security.SystemSecurityContext;
|
||||
import org.slf4j.Logger;
|
||||
@@ -16,8 +16,8 @@ import org.slf4j.LoggerFactory;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
|
||||
/**
|
||||
* Scheduler to schedule the {@link RolloutManagement#handleRollouts()}. The
|
||||
* delay between the checks be be configured using the property from
|
||||
* Scheduler to schedule the {@link RolloutHandler#handleAll()}. The
|
||||
* delay between the checks be configured using the property from
|
||||
* {#PROP_SCHEDULER_DELAY_PLACEHOLDER}.
|
||||
*/
|
||||
public class RolloutScheduler {
|
||||
@@ -28,7 +28,7 @@ public class RolloutScheduler {
|
||||
|
||||
private final SystemManagement systemManagement;
|
||||
|
||||
private final RolloutManagement rolloutManagement;
|
||||
private final RolloutHandler rolloutHandler;
|
||||
|
||||
private final SystemSecurityContext systemSecurityContext;
|
||||
|
||||
@@ -37,22 +37,22 @@ public class RolloutScheduler {
|
||||
*
|
||||
* @param systemManagement
|
||||
* to find all tenants
|
||||
* @param rolloutManagement
|
||||
* @param rolloutHandler
|
||||
* to run the rollout handler
|
||||
* @param systemSecurityContext
|
||||
* to run as system
|
||||
*/
|
||||
public RolloutScheduler(final SystemManagement systemManagement, final RolloutManagement rolloutManagement,
|
||||
public RolloutScheduler(final SystemManagement systemManagement, final RolloutHandler rolloutHandler,
|
||||
final SystemSecurityContext systemSecurityContext) {
|
||||
this.systemManagement = systemManagement;
|
||||
this.rolloutManagement = rolloutManagement;
|
||||
this.rolloutHandler = rolloutHandler;
|
||||
this.systemSecurityContext = systemSecurityContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Scheduler method called by the spring-async mechanism. Retrieves all
|
||||
* tenants from the {@link SystemManagement#findTenants()} and runs for each
|
||||
* tenant the {@link RolloutManagement#handleRollouts()} in the
|
||||
* tenants from the {@link SystemManagement#findTenants} and runs for each
|
||||
* tenant the {@link RolloutHandler#handleAll()} in the
|
||||
* {@link SystemSecurityContext}.
|
||||
*/
|
||||
@Scheduled(initialDelayString = PROP_SCHEDULER_DELAY_PLACEHOLDER, fixedDelayString = PROP_SCHEDULER_DELAY_PLACEHOLDER)
|
||||
@@ -63,13 +63,13 @@ public class RolloutScheduler {
|
||||
// permission to query and create entities.
|
||||
systemSecurityContext.runAsSystem(() -> {
|
||||
// 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.
|
||||
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=355458. So
|
||||
// iterate through all tenants and execute the rollout check for
|
||||
// each tenant seperately.
|
||||
|
||||
systemManagement.forEachTenant(tenant -> rolloutManagement.handleRollouts());
|
||||
systemManagement.forEachTenant(tenant -> rolloutHandler.handleAll());
|
||||
|
||||
return null;
|
||||
});
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,7 @@ import org.eclipse.hawkbit.security.SystemSecurityContext;
|
||||
* Error action evaluator which pauses the whole {@link Rollout} and sets the
|
||||
* current {@link RolloutGroup} to error.
|
||||
*/
|
||||
public class PauseRolloutGroupAction implements RolloutGroupActionEvaluator {
|
||||
public class PauseRolloutGroupAction implements RolloutGroupActionEvaluator<RolloutGroup.RolloutGroupErrorAction> {
|
||||
|
||||
private final RolloutManagement rolloutManagement;
|
||||
|
||||
@@ -36,12 +36,12 @@ public class PauseRolloutGroupAction implements RolloutGroupActionEvaluator {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean verifyExpression(final String expression) {
|
||||
return true;
|
||||
public RolloutGroup.RolloutGroupErrorAction getAction() {
|
||||
return RolloutGroup.RolloutGroupErrorAction.PAUSE;
|
||||
}
|
||||
|
||||
@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;
|
||||
|
||||
systemSecurityContext.runAsSystem(() -> {
|
||||
|
||||
@@ -12,11 +12,11 @@ import org.eclipse.hawkbit.repository.model.Rollout;
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -12,20 +12,11 @@ import org.eclipse.hawkbit.repository.model.Rollout;
|
||||
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 {
|
||||
public interface RolloutGroupConditionEvaluator<T> {
|
||||
|
||||
default boolean verifyExpression(final String expression) {
|
||||
// percentage value between 0 and 100
|
||||
try {
|
||||
final Integer value = Integer.valueOf(expression);
|
||||
return value >= 0 && value <= 100;
|
||||
} catch (final NumberFormatException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
T getCondition();
|
||||
|
||||
boolean eval(Rollout rollout, RolloutGroup rolloutGroup, final String expression);
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -23,7 +23,7 @@ import org.slf4j.LoggerFactory;
|
||||
/**
|
||||
* 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);
|
||||
|
||||
@@ -41,12 +41,12 @@ public class StartNextGroupRolloutGroupSuccessAction implements RolloutGroupActi
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean verifyExpression(final String expression) {
|
||||
return true;
|
||||
public RolloutGroup.RolloutGroupSuccessAction getAction() {
|
||||
return RolloutGroup.RolloutGroupSuccessAction.NEXTGROUP;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void eval(final Rollout rollout, final RolloutGroup rolloutGroup, final String expression) {
|
||||
public void exec(final Rollout rollout, final RolloutGroup rolloutGroup) {
|
||||
systemSecurityContext.runAsSystem(() -> {
|
||||
startNextGroup(rollout, rolloutGroup);
|
||||
return null;
|
||||
|
||||
@@ -18,9 +18,10 @@ import org.slf4j.Logger;
|
||||
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);
|
||||
|
||||
@@ -30,6 +31,11 @@ public class ThresholdRolloutGroupErrorCondition implements RolloutGroupConditio
|
||||
this.actionRepository = actionRepository;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RolloutGroup.RolloutGroupErrorCondition getCondition() {
|
||||
return RolloutGroup.RolloutGroupErrorCondition.THRESHOLD;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean eval(final Rollout rollout, final RolloutGroup rolloutGroup, final String expression) {
|
||||
final Long totalGroup = actionRepository.countByRolloutAndRolloutGroup((JpaRollout) rollout,
|
||||
|
||||
@@ -16,10 +16,11 @@ import org.slf4j.Logger;
|
||||
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.
|
||||
*/
|
||||
public class ThresholdRolloutGroupSuccessCondition implements RolloutGroupConditionEvaluator {
|
||||
public class ThresholdRolloutGroupSuccessCondition
|
||||
implements RolloutGroupConditionEvaluator<RolloutGroup.RolloutGroupSuccessCondition> {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(ThresholdRolloutGroupSuccessCondition.class);
|
||||
|
||||
private final ActionRepository actionRepository;
|
||||
@@ -28,6 +29,11 @@ public class ThresholdRolloutGroupSuccessCondition implements RolloutGroupCondit
|
||||
this.actionRepository = actionRepository;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RolloutGroup.RolloutGroupSuccessCondition getCondition() {
|
||||
return RolloutGroup.RolloutGroupSuccessCondition.THRESHOLD;
|
||||
}
|
||||
|
||||
@Override
|
||||
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(),
|
||||
rolloutGroup.getId(), completeActionStatus);
|
||||
try {
|
||||
final Integer threshold = Integer.valueOf(expression);
|
||||
final int threshold = Integer.parseInt(expression);
|
||||
// calculate threshold
|
||||
return ((float) finished / (float) totalGroup) >= ((float) threshold / 100F);
|
||||
|
||||
|
||||
@@ -8,9 +8,15 @@
|
||||
*/
|
||||
package org.eclipse.hawkbit.repository.jpa;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
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;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.awaitility.Awaitility;
|
||||
import org.awaitility.Duration;
|
||||
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.TestPropertySource;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
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;
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
|
||||
/**
|
||||
* 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
|
||||
// parallel
|
||||
new Thread(() -> systemSecurityContext.runAsSystemAsTenant(() -> {
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
return 0;
|
||||
}, tenant)).start();
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ class DistributionSetInvalidationManagementTest extends AbstractJpaIntegrationTe
|
||||
assertDistributionSetInvalidationCount(distributionSetInvalidationCount, 1, 0, 0);
|
||||
|
||||
distributionSetInvalidationManagement.invalidateDistributionSet(distributionSetInvalidation);
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
assertThat(targetFilterQueryManagement.get(invalidationTestData.getTargetFilterQuery().getId()).get()
|
||||
.getAutoAssignDistributionSet()).isNull();
|
||||
@@ -87,7 +87,7 @@ class DistributionSetInvalidationManagementTest extends AbstractJpaIntegrationTe
|
||||
assertDistributionSetInvalidationCount(distributionSetInvalidationCount, 1, 0, 1);
|
||||
|
||||
distributionSetInvalidationManagement.invalidateDistributionSet(distributionSetInvalidation);
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
assertThat(targetFilterQueryManagement.get(invalidationTestData.getTargetFilterQuery().getId()).get()
|
||||
.getAutoAssignDistributionSet()).isNull();
|
||||
@@ -119,7 +119,7 @@ class DistributionSetInvalidationManagementTest extends AbstractJpaIntegrationTe
|
||||
assertDistributionSetInvalidationCount(distributionSetInvalidationCount, 1, 5, 1);
|
||||
|
||||
distributionSetInvalidationManagement.invalidateDistributionSet(distributionSetInvalidation);
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
assertThat(targetFilterQueryManagement.get(invalidationTestData.getTargetFilterQuery().getId()).get()
|
||||
.getAutoAssignDistributionSet()).isNull();
|
||||
|
||||
@@ -92,7 +92,7 @@ class RolloutGroupManagementTest extends AbstractJpaIntegrationTest {
|
||||
.getContent();
|
||||
final RolloutGroup rolloutGroup = rolloutGroups.get(0);
|
||||
rolloutManagement.pauseRollout(rollout.getId());
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
final List<Target> targets = rolloutGroupManagement.findTargetsOfRolloutGroup(PAGE, rolloutGroup.getId())
|
||||
.getContent();
|
||||
Target targetCancelled = targets.get(0);
|
||||
@@ -195,7 +195,7 @@ class RolloutGroupManagementTest extends AbstractJpaIntegrationTest {
|
||||
final Rollout rollout = testdataFactory.createRollout();
|
||||
final List<RolloutGroup> rolloutGroups = rolloutGroupManagement.findByRollout(PAGE, rollout.getId())
|
||||
.getContent();
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
// check query when no actions exist
|
||||
final List<TargetWithActionStatus> targetsWithActionStatus = rolloutGroupManagement
|
||||
@@ -208,7 +208,7 @@ class RolloutGroupManagementTest extends AbstractJpaIntegrationTest {
|
||||
assertTargetNotNullAndActionStatusNullAndActionStatusCode(targetsWithActionStatus, null);
|
||||
|
||||
rolloutManagement.start(rollout.getId());
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
// check query when no action status code exist
|
||||
final List<Action> scheduledActions = findActionsByRolloutAndStatus(rollout, Status.SCHEDULED);
|
||||
|
||||
@@ -126,7 +126,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
||||
final Rollout rollout = testdataFactory.createRolloutByVariables("rolloutNotCancelRunningAction", "description",
|
||||
1, "name==*", knownDistributionSet, "50", "5");
|
||||
rolloutManagement.start(rollout.getId());
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
// verify that manually created action is still running and action
|
||||
// created from rollout is finished
|
||||
@@ -163,7 +163,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
||||
final Rollout rollout = testdataFactory.createRolloutByVariables("rolloutNotCancelRunningAction", "description",
|
||||
1, "name==*", knownDistributionSet, "50", "5", confirmationRequired);
|
||||
rolloutManagement.start(rollout.getId());
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
// verify that manually created action is still running and action
|
||||
// created from rollout is finished
|
||||
@@ -201,7 +201,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
||||
final Rollout rollout = testdataFactory.createRolloutByVariables("rolloutNotCancelRunningAction",
|
||||
"description", 1, "name==*", secondDistributionSet, "50", "5");
|
||||
rolloutManagement.start(rollout.getId());
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
// verify that manually created action is canceled and action
|
||||
// created from rollout is running
|
||||
@@ -333,7 +333,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
||||
|
||||
// check running rollouts again, now the finish condition should be hit
|
||||
// and should start the next group
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
// verify that now the first and the second group are in running state
|
||||
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")
|
||||
private void checkSecondGroupStatusIsRunning(final Rollout createdRollout) {
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
final List<RolloutGroup> runningRolloutGroups = rolloutGroupManagement
|
||||
.findByRollout(new OffsetBasedPageRequest(0, 10, Sort.by(Direction.ASC, "id")), createdRollout.getId())
|
||||
.getContent();
|
||||
@@ -428,7 +428,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
||||
|
||||
@Step("Check the status of the rollout groups and the rollout")
|
||||
private void verifyRolloutAndAllGroupsAreFinished(final Rollout createdRollout) {
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
final List<RolloutGroup> runningRolloutGroups = rolloutGroupManagement
|
||||
.findByRollout(PAGE, createdRollout.getId()).getContent();
|
||||
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
|
||||
// and should execute the error action
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
final Rollout rollout = reloadRollout(createdRollout);
|
||||
// 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
|
||||
// and should execute the error action
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
final Rollout rollout = reloadRollout(createdRollout);
|
||||
// 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);
|
||||
|
||||
// checking rollouts again
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
// next group should be running again after resuming the rollout
|
||||
final List<RolloutGroup> resumedGroups = rolloutGroupManagement
|
||||
@@ -557,7 +557,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
||||
// calculate the rest of the groups and finish them
|
||||
for (int groupsLeft = amountGroups - 1; groupsLeft >= 1; groupsLeft--) {
|
||||
// next check and start next group
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
// finish running actions, 2 actions should be finished
|
||||
assertThat(changeStatusForAllRunningActions(createdRollout, Status.FINISHED)).isEqualTo(2);
|
||||
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
|
||||
// so can go to FINISHED state of the rollout
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
// verify all groups are in finished state
|
||||
rolloutGroupManagement
|
||||
@@ -598,7 +598,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
||||
rolloutManagement.start(createdRollout.getId());
|
||||
|
||||
// Run here, because scheduler is disabled during tests
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
// 6 targets are ready and 2 are running
|
||||
validationMap = createInitStatusMap();
|
||||
@@ -607,7 +607,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
||||
validateRolloutActionStatus(createdRollout.getId(), validationMap);
|
||||
|
||||
changeStatusForAllRunningActions(createdRollout, Status.FINISHED);
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
// 4 targets are ready, 2 are finished and 2 are running
|
||||
validationMap = createInitStatusMap();
|
||||
validationMap.put(TotalTargetCountStatus.Status.SCHEDULED, 4L);
|
||||
@@ -616,7 +616,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
||||
validateRolloutActionStatus(createdRollout.getId(), validationMap);
|
||||
|
||||
changeStatusForAllRunningActions(createdRollout, Status.FINISHED);
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
// 2 targets are ready, 4 are finished and 2 are running
|
||||
validationMap = createInitStatusMap();
|
||||
validationMap.put(TotalTargetCountStatus.Status.SCHEDULED, 2L);
|
||||
@@ -625,7 +625,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
||||
validateRolloutActionStatus(createdRollout.getId(), validationMap);
|
||||
|
||||
changeStatusForAllRunningActions(createdRollout, Status.FINISHED);
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
// 0 targets are ready, 6 are finished and 2 are running
|
||||
validationMap = createInitStatusMap();
|
||||
validationMap.put(TotalTargetCountStatus.Status.FINISHED, 6L);
|
||||
@@ -633,7 +633,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
||||
validateRolloutActionStatus(createdRollout.getId(), validationMap);
|
||||
|
||||
changeStatusForAllRunningActions(createdRollout, Status.FINISHED);
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
// 0 targets are ready, 8 are finished and 0 are running
|
||||
validationMap = createInitStatusMap();
|
||||
validationMap.put(TotalTargetCountStatus.Status.FINISHED, 8L);
|
||||
@@ -662,7 +662,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
||||
rolloutManagement.start(createdRollout.getId());
|
||||
|
||||
// Run here, because scheduler is disabled during tests
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
// 6 targets are ready and 2 are running
|
||||
validationMap = createInitStatusMap();
|
||||
@@ -671,7 +671,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
||||
validateRolloutActionStatus(createdRollout.getId(), validationMap);
|
||||
|
||||
changeStatusForAllRunningActions(createdRollout, Status.DOWNLOADED);
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
// 4 targets are ready, 2 are finished(with DOWNLOADED action status)
|
||||
// and 2 are running
|
||||
validationMap = createInitStatusMap();
|
||||
@@ -681,7 +681,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
||||
validateRolloutActionStatus(createdRollout.getId(), validationMap);
|
||||
|
||||
changeStatusForAllRunningActions(createdRollout, Status.DOWNLOADED);
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
// 2 targets are ready, 4 are finished(with DOWNLOADED action status)
|
||||
// and 2 are running
|
||||
validationMap = createInitStatusMap();
|
||||
@@ -691,7 +691,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
||||
validateRolloutActionStatus(createdRollout.getId(), validationMap);
|
||||
|
||||
changeStatusForAllRunningActions(createdRollout, Status.DOWNLOADED);
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
// 0 targets are ready, 6 are finished(with DOWNLOADED action status)
|
||||
// and 2 are running
|
||||
validationMap = createInitStatusMap();
|
||||
@@ -700,7 +700,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
||||
validateRolloutActionStatus(createdRollout.getId(), validationMap);
|
||||
|
||||
changeStatusForAllRunningActions(createdRollout, Status.FINISHED);
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
// 0 targets are ready, 6 are finished(with DOWNLOADED action status), 2
|
||||
// are finished and 0 are running
|
||||
validationMap = createInitStatusMap();
|
||||
@@ -730,7 +730,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
||||
rolloutManagement.start(createdRollout.getId());
|
||||
|
||||
// Run here, because scheduler is disabled during tests
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
// 6 targets are ready and 2 are running
|
||||
validationMap = createInitStatusMap();
|
||||
@@ -739,7 +739,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
||||
validateRolloutActionStatus(createdRollout.getId(), validationMap);
|
||||
|
||||
changeStatusForAllRunningActions(createdRollout, Status.ERROR);
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
// 6 targets are ready and 2 are error
|
||||
validationMap = createInitStatusMap();
|
||||
validationMap.put(TotalTargetCountStatus.Status.SCHEDULED, 6L);
|
||||
@@ -761,7 +761,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
||||
successCondition, errorCondition);
|
||||
|
||||
changeStatusForAllRunningActions(createdRollout, Status.FINISHED);
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
// round(9/4)=2 targets finished (Group 1)
|
||||
// round(7/3)=2 targets running (Group 3)
|
||||
@@ -853,7 +853,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
||||
final Rollout rolloutTwo = testdataFactory.createRolloutByVariables("rolloutTwo",
|
||||
"This is the description for rollout two", 1, "controllerId==rollout-*", dsForRolloutTwo, "50", "80");
|
||||
changeStatusForAllRunningActions(rolloutOne, Status.FINISHED);
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
// Verify that 5 targets are finished, 5 are running and 5 are ready.
|
||||
Map<TotalTargetCountStatus.Status, Long> expectedTargetCountStatus = createInitStatusMap();
|
||||
expectedTargetCountStatus.put(TotalTargetCountStatus.Status.RUNNING, 5L);
|
||||
@@ -864,7 +864,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
||||
rolloutManagement.start(rolloutTwo.getId());
|
||||
|
||||
// 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
|
||||
// cancelled.
|
||||
@@ -892,13 +892,13 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
||||
rolloutOne = reloadRollout(rolloutOne);
|
||||
changeStatusForRunningActions(rolloutOne, Status.ERROR, 2);
|
||||
changeStatusForRunningActions(rolloutOne, Status.FINISHED, 3);
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
changeStatusForRunningActions(rolloutOne, Status.ERROR, 2);
|
||||
changeStatusForRunningActions(rolloutOne, Status.FINISHED, 3);
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
changeStatusForRunningActions(rolloutOne, Status.ERROR, 2);
|
||||
changeStatusForRunningActions(rolloutOne, Status.FINISHED, 3);
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
// 9 targets are finished and 6 have error
|
||||
Map<TotalTargetCountStatus.Status, Long> expectedTargetCountStatus = createInitStatusMap();
|
||||
@@ -917,7 +917,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
||||
rolloutManagement.start(rolloutTwo.getId());
|
||||
|
||||
// Run here, because scheduler is disabled during tests
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
rolloutTwo = reloadRollout(rolloutTwo);
|
||||
// 6 error targets are now running
|
||||
@@ -950,7 +950,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
||||
rolloutOne = reloadRollout(rolloutOne);
|
||||
changeStatusForRunningActions(rolloutOne, Status.ERROR, 2);
|
||||
changeStatusForRunningActions(rolloutOne, Status.FINISHED, 3);
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
// verify: 40% error but 60% finished -> should move to next group
|
||||
final List<RolloutGroup> rolloutGroups = rolloutGroupManagement.findByRollout(PAGE, rolloutOne.getId())
|
||||
.getContent();
|
||||
@@ -976,7 +976,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
||||
rolloutOne = reloadRollout(rolloutOne);
|
||||
changeStatusForRunningActions(rolloutOne, Status.ERROR, 2);
|
||||
changeStatusForRunningActions(rolloutOne, Status.FINISHED, 3);
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
// verify: 40% error and 60% finished -> should not move to next group
|
||||
// because successCondition 80%
|
||||
final List<RolloutGroup> rolloutGruops = rolloutGroupManagement.findByRollout(PAGE, rolloutOne.getId())
|
||||
@@ -1002,7 +1002,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
||||
rolloutOne = reloadRollout(rolloutOne);
|
||||
changeStatusForRunningActions(rolloutOne, Status.ERROR, 2);
|
||||
changeStatusForRunningActions(rolloutOne, Status.FINISHED, 3);
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
// verify: 40% error -> should pause because errorCondition is 20%
|
||||
rolloutOne = reloadRollout(rolloutOne);
|
||||
assertThat(rolloutOne.getStatus()).isEqualTo(RolloutStatus.PAUSED);
|
||||
@@ -1019,39 +1019,39 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
||||
final Rollout rolloutA = createTestRolloutWithTargetsAndDistributionSet(amountTargetsForRollout, amountGroups,
|
||||
successCondition, errorCondition, "RolloutA", "RolloutA");
|
||||
rolloutManagement.start(rolloutA.getId());
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
final int amountTargetsForRollout2 = 10;
|
||||
final int amountGroups2 = 2;
|
||||
final Rollout rolloutB = createTestRolloutWithTargetsAndDistributionSet(amountTargetsForRollout2, amountGroups2,
|
||||
successCondition, errorCondition, "RolloutB", "RolloutB");
|
||||
rolloutManagement.start(rolloutB.getId());
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
changeStatusForAllRunningActions(rolloutB, Status.FINISHED);
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
final int amountTargetsForRollout3 = 10;
|
||||
final int amountGroups3 = 2;
|
||||
final Rollout rolloutC = createTestRolloutWithTargetsAndDistributionSet(amountTargetsForRollout3, amountGroups3,
|
||||
successCondition, errorCondition, "RolloutC", "RolloutC");
|
||||
rolloutManagement.start(rolloutC.getId());
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
changeStatusForAllRunningActions(rolloutC, Status.ERROR);
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
final int amountTargetsForRollout4 = 15;
|
||||
final int amountGroups4 = 3;
|
||||
final Rollout rolloutD = createTestRolloutWithTargetsAndDistributionSet(amountTargetsForRollout4, amountGroups4,
|
||||
successCondition, errorCondition, "RolloutD", "RolloutD");
|
||||
rolloutManagement.start(rolloutD.getId());
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
changeStatusForRunningActions(rolloutD, Status.ERROR, 1);
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
changeStatusForAllRunningActions(rolloutD, Status.FINISHED);
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
final Slice<Rollout> rolloutPage = rolloutManagement
|
||||
.findAllWithDetailedStatus(new OffsetBasedPageRequest(0, 100, Sort.by(Direction.ASC, "name")), false);
|
||||
@@ -1181,10 +1181,10 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
||||
rolloutManagement.start(myRollout.getId());
|
||||
|
||||
// Run here, because scheduler is disabled during tests
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
changeStatusForRunningActions(myRollout, Status.FINISHED, 2);
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
myRollout = reloadRollout(myRollout);
|
||||
|
||||
float percent = rolloutGroupManagement
|
||||
@@ -1194,7 +1194,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
||||
assertThat(percent).isEqualTo(40);
|
||||
|
||||
changeStatusForRunningActions(myRollout, Status.FINISHED, 3);
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
percent = rolloutGroupManagement
|
||||
.getWithDetailedStatus(
|
||||
@@ -1204,7 +1204,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
||||
|
||||
changeStatusForRunningActions(myRollout, Status.FINISHED, 4);
|
||||
changeStatusForAllRunningActions(myRollout, Status.ERROR);
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
percent = rolloutGroupManagement
|
||||
.getWithDetailedStatus(
|
||||
@@ -1233,7 +1233,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
||||
rolloutManagement.start(myRollout.getId());
|
||||
|
||||
// Run here, because scheduler is disabled during tests
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
final Condition<String> targetBelongsInRollout = new Condition<>(s -> s.startsWith(rolloutName),
|
||||
"Target belongs into rollout");
|
||||
@@ -1336,7 +1336,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
||||
rolloutManagement.start(myRolloutId);
|
||||
|
||||
// Run here, because scheduler is disabled during tests
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
awaitRunningState(myRolloutId);
|
||||
|
||||
@@ -1365,7 +1365,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
||||
|
||||
assertThat(myRollout.getStatus()).isEqualTo(RolloutStatus.READY);
|
||||
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
final Long myRolloutId = myRollout.getId();
|
||||
myRollout = getRollout(myRolloutId);
|
||||
@@ -1374,7 +1374,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
||||
rolloutManagement.start(myRolloutId);
|
||||
|
||||
// Run here, because scheduler is disabled during tests
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
awaitRunningState(myRolloutId);
|
||||
|
||||
@@ -1487,7 +1487,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
||||
final Long myRolloutId = myRollout.getId();
|
||||
rolloutManagement
|
||||
.update(entityFactory.rollout().update(myRolloutId).startAt(System.currentTimeMillis() + 60000));
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
// rollout should not have been started
|
||||
myRollout = getRollout(myRolloutId);
|
||||
@@ -1495,13 +1495,13 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
||||
|
||||
// schedule to now
|
||||
rolloutManagement.update(entityFactory.rollout().update(myRolloutId).startAt(System.currentTimeMillis()));
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
myRollout = getRollout(myRolloutId);
|
||||
assertThat(myRollout.getStatus()).isEqualTo(RolloutStatus.STARTING);
|
||||
|
||||
// Run here, because scheduler is disabled during tests
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
awaitRunningState(myRolloutId);
|
||||
|
||||
@@ -1562,7 +1562,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
||||
TimeUnit.SECONDS.sleep(1);
|
||||
testdataFactory.createTargets(10, rolloutName + "-notIn-", rolloutName);
|
||||
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
myRollout = getRollout(myRollout.getId());
|
||||
assertThat(myRollout.getStatus()).isEqualTo(RolloutStatus.READY);
|
||||
@@ -1613,7 +1613,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
||||
});
|
||||
|
||||
// first handle iteration will put rollout in ready state
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
assertThat(getRollout(rolloutId)).satisfies(rollout -> {
|
||||
assertThat(rollout.getStatus()).isEqualTo(RolloutStatus.READY);
|
||||
@@ -1629,7 +1629,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
||||
|
||||
// start rollout
|
||||
rolloutManagement.start(rolloutId);
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
// verify rollout started. Check groups are in right state.
|
||||
// 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
|
||||
forceQuitAllActionsOfRolloutGroup(rolloutGroupIds.get(0));
|
||||
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
assertRolloutGroup(rolloutGroupIds.get(0), RolloutGroupStatus.FINISHED, true, amountTargetsInGroup1,
|
||||
Status.CANCELED);
|
||||
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
|
||||
// confirmation is not required for this group
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
assertRolloutGroup(rolloutGroupIds.get(0), RolloutGroupStatus.FINISHED, true, amountTargetsInGroup1,
|
||||
Status.CANCELED);
|
||||
assertRolloutGroup(rolloutGroupIds.get(1), RolloutGroupStatus.RUNNING, false, amountTargetsInGroup2,
|
||||
@@ -1855,7 +1855,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
||||
|
||||
// test
|
||||
rolloutManagement.delete(createdRollout.getId());
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
// verify
|
||||
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
|
||||
// has been started
|
||||
rolloutManagement.start(createdRollout.getId());
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
// verify we have running actions
|
||||
assertThat(actionRepository.findByRolloutIdAndStatus(PAGE, createdRollout.getId(), Status.RUNNING)
|
||||
@@ -1897,7 +1897,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
||||
|
||||
// test
|
||||
rolloutManagement.delete(createdRollout.getId());
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
// verify
|
||||
final JpaRollout deletedRollout = rolloutRepository.findById(createdRollout.getId()).get();
|
||||
@@ -1941,11 +1941,11 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
||||
|
||||
Rollout rolloutRunning = rolloutManagement.create(rolloutRunningCreate, 1, false, conditions);
|
||||
// Let the executor handle created Rollout
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
// start the rollout, so it has active running actions and a group which
|
||||
// has been started
|
||||
rolloutManagement.start(rolloutRunning.getId());
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
rolloutRunning = reloadRollout(rolloutRunning);
|
||||
|
||||
final String prefixRolloutReady = randomString + "2";
|
||||
@@ -1953,7 +1953,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
||||
.name(prefixRolloutReady + "-testRollout").targetFilterQuery("name==" + randomString + "*").set(testDs);
|
||||
Rollout rolloutReady = rolloutManagement.create(rolloutReadyCreate, 1, false, conditions);
|
||||
// Let the executor handle created Rollout
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
rolloutReady = reloadRollout(rolloutReady);
|
||||
|
||||
final List<Rollout> rolloutsOrderedByStatus = rolloutManagement
|
||||
@@ -2017,7 +2017,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
||||
.createSimpleTestRolloutWithTargetsAndDistributionSet(amountOfTargets, 2, amountOfTargets,
|
||||
"80", "50", null, weight).getId();
|
||||
rolloutManagement.start(rolloutId);
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
final List<Action> actions = deploymentManagement.findActionsAll(PAGE).getContent();
|
||||
assertThat(actions) //
|
||||
.hasSize(amountOfTargets) //
|
||||
@@ -2034,7 +2034,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
||||
|
||||
enableMultiAssignments();
|
||||
rolloutManagement.start(rolloutId);
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
final List<Action> actions = deploymentManagement.findActionsAll(PAGE).getContent();
|
||||
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);
|
||||
|
||||
// Let the executor handle created Rollout
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
final Rollout testRollout = reloadRollout(createdRollout);
|
||||
final List<RolloutGroup> rolloutGroups = rolloutGroupManagement
|
||||
@@ -2175,8 +2175,6 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private Rollout createTestRolloutWithTargetsAndDistributionSet(final int amountTargetsForRollout,
|
||||
final int groupSize, final String successCondition, final String errorCondition, final String rolloutName,
|
||||
final String targetPrefixName) {
|
||||
@@ -2300,7 +2298,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
||||
.withMessageContaining(errorMessage);
|
||||
|
||||
// Run here, because scheduler is disabled during tests
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
final Rollout rollout = reloadRollout(createdRollout);
|
||||
|
||||
rolloutManagement.pauseRollout(rollout.getId());
|
||||
|
||||
@@ -142,7 +142,7 @@ public class RepositoryEntityEventTest extends AbstractJpaIntegrationTest {
|
||||
"controllerId==" + targetPrefixName + "-*", distributionSet, successCondition, errorCondition);
|
||||
|
||||
rolloutManagement.delete(createdRollout.getId());
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
final RolloutDeletedEvent rolloutDeletedEvent = eventListener.waitForEvent(RolloutDeletedEvent.class);
|
||||
assertThat(rolloutDeletedEvent).isNotNull();
|
||||
|
||||
@@ -39,6 +39,7 @@ import org.eclipse.hawkbit.repository.EntityFactory;
|
||||
import org.eclipse.hawkbit.repository.QuotaManagement;
|
||||
import org.eclipse.hawkbit.repository.RepositoryConstants;
|
||||
import org.eclipse.hawkbit.repository.RolloutGroupManagement;
|
||||
import org.eclipse.hawkbit.repository.RolloutHandler;
|
||||
import org.eclipse.hawkbit.repository.RolloutManagement;
|
||||
import org.eclipse.hawkbit.repository.SoftwareModuleManagement;
|
||||
import org.eclipse.hawkbit.repository.SoftwareModuleTypeManagement;
|
||||
@@ -181,6 +182,9 @@ public abstract class AbstractIntegrationTest {
|
||||
@Autowired
|
||||
protected RolloutManagement rolloutManagement;
|
||||
|
||||
@Autowired
|
||||
protected RolloutHandler rolloutHandler;
|
||||
|
||||
@Autowired
|
||||
protected RolloutGroupManagement rolloutGroupManagement;
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ import org.eclipse.hawkbit.repository.DistributionSetTagManagement;
|
||||
import org.eclipse.hawkbit.repository.DistributionSetTypeManagement;
|
||||
import org.eclipse.hawkbit.repository.EntityFactory;
|
||||
import org.eclipse.hawkbit.repository.QuotaManagement;
|
||||
import org.eclipse.hawkbit.repository.RolloutHandler;
|
||||
import org.eclipse.hawkbit.repository.RolloutManagement;
|
||||
import org.eclipse.hawkbit.repository.SoftwareModuleManagement;
|
||||
import org.eclipse.hawkbit.repository.SoftwareModuleTypeManagement;
|
||||
@@ -177,6 +178,9 @@ public class TestdataFactory {
|
||||
@Autowired
|
||||
private RolloutManagement rolloutManagement;
|
||||
|
||||
@Autowired
|
||||
private RolloutHandler rolloutHandler;
|
||||
|
||||
@Autowired
|
||||
private QuotaManagement quotaManagement;
|
||||
|
||||
@@ -1202,7 +1206,7 @@ public class TestdataFactory {
|
||||
groupSize, confirmationRequired, conditions);
|
||||
|
||||
// Run here, because Scheduler is disabled during tests
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
return rolloutManagement.get(rollout.getId()).get();
|
||||
}
|
||||
@@ -1253,7 +1257,7 @@ public class TestdataFactory {
|
||||
rolloutManagement.start(rollout.getId());
|
||||
|
||||
// Run here, because scheduler is disabled during tests
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
return reloadRollout(rollout);
|
||||
}
|
||||
@@ -1350,9 +1354,9 @@ public class TestdataFactory {
|
||||
public Rollout createSoftDeletedRollout(final String prefix) {
|
||||
final Rollout newRollout = createRollout(prefix);
|
||||
rolloutManagement.start(newRollout.getId());
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
rolloutManagement.delete(newRollout.getId());
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
return newRollout;
|
||||
}
|
||||
|
||||
|
||||
@@ -207,7 +207,7 @@ class MgmtActionResourceTest extends AbstractManagementApiIntegrationTest {
|
||||
final Rollout rollout = testdataFactory.createRolloutByVariables("TestRollout", "TestDesc", 1,
|
||||
"name==" + target1.getName(), ds, "50", "5");
|
||||
rolloutManagement.start(rollout.getId());
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
final String rsqlRolloutName = "rollout.name==" + rollout.getName();
|
||||
final String rsqlRolloutId = "rollout.id==" + rollout.getId();
|
||||
|
||||
@@ -301,9 +301,9 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest {
|
||||
4, false, new RolloutGroupConditionBuilder().withDefaults()
|
||||
.successCondition(RolloutGroupSuccessCondition.THRESHOLD, "100").build());
|
||||
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
rolloutManagement.start(rollout.getId());
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
// request the list of rollouts with full representation
|
||||
mvc.perform(get("/rest/v1/rollouts?representation=full").accept(MediaType.APPLICATION_JSON))
|
||||
@@ -458,7 +458,7 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest {
|
||||
|
||||
@Step
|
||||
private void retrieveAndVerifyRolloutInRunning(final Rollout rollout) throws Exception {
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
mvc.perform(get("/rest/v1/rollouts/" + rollout.getId()).accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||
@@ -494,7 +494,7 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest {
|
||||
|
||||
@Step
|
||||
private void retrieveAndVerifyRolloutInReady(final Rollout rollout) throws Exception {
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
mvc.perform(get("/rest/v1/rollouts/" + rollout.getId()).accept(MediaType.APPLICATION_JSON))
|
||||
.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);
|
||||
|
||||
// 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())
|
||||
.andExpect(status().isOk()).andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
|
||||
@@ -598,7 +598,7 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest {
|
||||
startAt, forcetime);
|
||||
|
||||
// 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?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);
|
||||
|
||||
// Run here, because Scheduler is disabled during tests
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
retrieveAndCompareRolloutsContent(dsA, "/rest/v1/rollouts", false);
|
||||
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);
|
||||
|
||||
// Run here, because Scheduler is disabled during tests
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
mvc.perform(get("/rest/v1/rollouts?limit=1").accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||
@@ -707,7 +707,7 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest {
|
||||
.andExpect(jsonPath("status", equalTo("starting")));
|
||||
|
||||
// Run here, because scheduler is disabled during tests
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
// check rollout is in running state
|
||||
mvc.perform(get("/rest/v1/rollouts/{rolloutId}", rollout.getId()).accept(MediaType.APPLICATION_JSON))
|
||||
@@ -733,7 +733,7 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest {
|
||||
.andExpect(status().isOk());
|
||||
|
||||
// Run here, because scheduler is disabled during tests
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
// pausing rollout
|
||||
mvc.perform(post("/rest/v1/rollouts/{rolloutId}/pause", rollout.getId())).andDo(MockMvcResultPrinter.print())
|
||||
@@ -763,7 +763,7 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest {
|
||||
.andExpect(status().isOk());
|
||||
|
||||
// Run here, because scheduler is disabled during tests
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
// pausing rollout
|
||||
mvc.perform(post("/rest/v1/rollouts/{rolloutId}/pause", rollout.getId())).andDo(MockMvcResultPrinter.print())
|
||||
@@ -797,7 +797,7 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest {
|
||||
.andExpect(status().isOk());
|
||||
|
||||
// Run here, because scheduler is disabled during tests
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
// starting rollout - already started should lead into bad request
|
||||
mvc.perform(post("/rest/v1/rollouts/{rolloutId}/start", rollout.getId())).andDo(MockMvcResultPrinter.print())
|
||||
@@ -838,7 +838,7 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest {
|
||||
.andExpect(status().isOk());
|
||||
|
||||
// Run here, because scheduler is disabled during tests
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
// retrieve rollout groups from created rollout - 2 groups exists
|
||||
// (amountTargets / groupSize = 2)
|
||||
@@ -891,7 +891,7 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest {
|
||||
final RolloutGroup firstGroup, final RolloutGroup secondGroup, final boolean confirmationFlowEnabled,
|
||||
final boolean confirmationRequired) throws Exception {
|
||||
rolloutManagement.start(rollout.getId());
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
mvc.perform(get("/rest/v1/rollouts/{rolloutId}/deploygroups/{groupId}", rollout.getId(), firstGroup.getId())
|
||||
.accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||
.andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
|
||||
@@ -923,7 +923,7 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest {
|
||||
@Step
|
||||
private void retrieveAndVerifyRolloutGroupInReady(final Rollout rollout, final RolloutGroup firstGroup)
|
||||
throws Exception {
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
mvc.perform(get("/rest/v1/rollouts/{rolloutId}/deploygroups/{groupId}", rollout.getId(), firstGroup.getId())
|
||||
.accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||
.andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
|
||||
@@ -1034,7 +1034,7 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest {
|
||||
rolloutManagement.start(rollout.getId());
|
||||
|
||||
// Run here, because scheduler is disabled during tests
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
final RolloutGroup firstGroup = rolloutGroupManagement
|
||||
.findByRollout(PageRequest.of(0, 1, Direction.ASC, "id"), rollout.getId()).getContent().get(0);
|
||||
@@ -1064,7 +1064,7 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest {
|
||||
.andExpect(status().isOk());
|
||||
|
||||
// Run here, because scheduler is disabled during tests
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
// check if running
|
||||
awaitRunningState(rollout.getId());
|
||||
@@ -1280,7 +1280,7 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest {
|
||||
.successCondition(RolloutGroupSuccessCondition.THRESHOLD, "100").build());
|
||||
|
||||
// Run here, because Scheduler is disabled during tests
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
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*");
|
||||
rolloutManagement.start(rollout.getId());
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
mvc.perform(post("/rest/v1/rollouts/{rolloutId}/triggerNextGroup", rollout.getId()))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||
@@ -1318,7 +1318,7 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest {
|
||||
triggerNextGroupAndExpect(rollout, status().isBadRequest());
|
||||
|
||||
// READY state
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
triggerNextGroupAndExpect(rollout, status().isBadRequest());
|
||||
|
||||
// STARTING state
|
||||
@@ -1326,7 +1326,7 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest {
|
||||
triggerNextGroupAndExpect(rollout, status().isBadRequest());
|
||||
|
||||
// RUNNING state
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
triggerNextGroupAndExpect(rollout, status().isOk());
|
||||
|
||||
// PAUSED state
|
||||
@@ -1341,7 +1341,7 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest {
|
||||
|
||||
// FINISHED state
|
||||
setTargetsStatus(targets, Status.FINISHED);
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
triggerNextGroupAndExpect(rollout, status().isBadRequest());
|
||||
|
||||
}
|
||||
|
||||
@@ -2118,7 +2118,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest {
|
||||
final Rollout rollout = testdataFactory.createRolloutByVariables("My Rollout", "My Rollout Description", 1,
|
||||
"name==trg*", ds, "50", "5");
|
||||
rolloutManagement.start(rollout.getId());
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
// get all actions for the first target
|
||||
final Target target = targets.get(0);
|
||||
|
||||
@@ -196,7 +196,7 @@ public abstract class AbstractApiRestDocumentation extends AbstractRestIntegrati
|
||||
|
||||
// start the rollout and handle it
|
||||
rolloutManagement.start(rollout.getId());
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
updatedTargets = Collections.singletonList(savedTarget);
|
||||
|
||||
|
||||
@@ -416,7 +416,7 @@ public class RolloutResourceDocumentationTest extends AbstractApiRestDocumentati
|
||||
rolloutManagement.start(rollout.getId());
|
||||
|
||||
// Run here, because scheduler is disabled during tests
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
mockMvc.perform(post(MgmtRestConstants.ROLLOUT_V1_REQUEST_MAPPING + "/{rolloutId}/pause", rollout.getId())
|
||||
.accept(MediaTypes.HAL_JSON_VALUE)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||
@@ -431,7 +431,7 @@ public class RolloutResourceDocumentationTest extends AbstractApiRestDocumentati
|
||||
rolloutManagement.start(rollout.getId());
|
||||
|
||||
// Run here, because scheduler is disabled during tests
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
rolloutManagement.pauseRollout(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());
|
||||
|
||||
// Run here, because scheduler is disabled during tests
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
mockMvc.perform(
|
||||
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());
|
||||
|
||||
// Run here, because Scheduler is disabled during tests
|
||||
rolloutManagement.handleRollouts();
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
return rolloutManagement
|
||||
.update(entityFactory.rollout().update(rollout.getId()).startAt(System.currentTimeMillis() + 1000).description("exampleDescription"));
|
||||
|
||||
Reference in New Issue
Block a user