[#1548] Add support for dynamic rollouts (#1533)

* [#1548] Add support for dynamic rollouts

-- Current status --

Initial draft only !!!, to be improved

TODO:
 * evaluate the target count - if update group/rollout total count fails dynamic updates could (?), actually, contain more targets
 * is it needed to break handler on group creating?
 * if dynamic group schedulers occur to be heavy - maybe a handler per tenant will ensure that one tenant won't break all

*Concept for dynamic groups*:

Rollouts are static and dynamic.
Static rollouts consist of static groups only while dynamic rollouts have a number of static groups (first groups) and then an unlimited number of dynamic groups.

Group targets assignments:
* static groups include ALL matching targets created at the time the rollout was created, nevertheless they have active actions with bigger weight or not. Actions for the rollout and included targeets however are created at the start time.
* dynamic groups however are filled in when started and consider the action weight. The targets included in a dynamic group are:
  * matching (filter and distribution set compatible)
  * not included in this or following rollout static groups (if already included in any of the following rollouts - it's intended to be overridden)
  * not in active actions of any rollouts with equal or bigger weight

In general, when you create a rollout it contains all matching targets available at create time overriding any previous rollouts, actions, and so on. If the rollout is dynamic when its dynamic group becomes running it gets only matching targets that doesn't belong to static groups or have actions with great or equal weight

Signed-off-by: Marinov Avgustin <Avgustin.Marinov@bosch.com>

* [#1548] Add 1000 weight for actions, rollouts and auto assignments without weight

Signed-off-by: Marinov Avgustin <Avgustin.Marinov@bosch.com>

---------

Signed-off-by: Marinov Avgustin <Avgustin.Marinov@bosch.com>
This commit is contained in:
Avgustin Marinov
2024-01-18 11:37:01 +02:00
committed by GitHub
parent b98b224964
commit 7768e543fd
50 changed files with 1005 additions and 177 deletions

View File

@@ -513,4 +513,15 @@ public abstract class AbstractIntegrationTest {
.getConfigurationValue(TenantConfigurationKey.USER_CONFIRMATION_ENABLED, Boolean.class).getValue();
}
// ensure that next action will get current time millis AFTER got from the previous
protected void waitNextMillis() {
final long createTime = System.currentTimeMillis();
while (System.currentTimeMillis() == createTime) {
try {
Thread.sleep(1);
} catch (final InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
}

View File

@@ -287,7 +287,7 @@ public class TestdataFactory {
* for {@link SoftwareModule}s and {@link DistributionSet}s name,
* vendor and description.
* @param tags
* {@link DistributionSet#getTags()}
* DistributionSet tags
*
* @return {@link DistributionSet} entity.
*/
@@ -397,7 +397,7 @@ public class TestdataFactory {
* {@link SoftwareModule#getVersion()} extended by a random
* number.updat
* @param tags
* {@link DistributionSet#getTags()}
* DistributionSet tags
*
* @return {@link DistributionSet} entity.
*/
@@ -909,10 +909,13 @@ public class TestdataFactory {
}
public List<Target> createTargets(final String prefix, final int number) {
return createTargets(prefix, 0, number);
}
public List<Target> createTargets(final String prefix, final int offset, final int number) {
final List<TargetCreate> targets = Lists.newArrayListWithExpectedSize(number);
for (int i = 0; i < number; i++) {
targets.add(entityFactory.target().create().controllerId(prefix + i));
targets.add(entityFactory.target().create().controllerId(prefix + (offset + i)));
}
return createTargets(targets);
@@ -1192,6 +1195,21 @@ public class TestdataFactory {
successCondition, errorCondition, Action.ActionType.FORCED, null, confirmationRequired);
}
public Rollout createRolloutByVariables(final String rolloutName, final String rolloutDescription,
final int groupSize, final String filterQuery, final DistributionSet distributionSet,
final String successCondition, final String errorCondition, final boolean confirmationRequired,
final boolean dynamic) {
return createRolloutByVariables(rolloutName, rolloutDescription, groupSize, filterQuery, distributionSet,
successCondition, errorCondition, Action.ActionType.FORCED, null, confirmationRequired, dynamic);
}
public Rollout createRolloutByVariables(final String rolloutName, final String rolloutDescription,
final int groupSize, final String filterQuery, final DistributionSet distributionSet,
final String successCondition, final String errorCondition, final Action.ActionType actionType,
final Integer weight, final boolean confirmationRequired) {
return createRolloutByVariables(rolloutName, rolloutDescription, groupSize, filterQuery, distributionSet,
successCondition, errorCondition, actionType, weight, confirmationRequired, false);
}
/**
* Creates rollout based on given parameters.
*
@@ -1216,12 +1234,13 @@ public class TestdataFactory {
* @param confirmationRequired
* if the confirmation is required (considered with confirmation flow
* active)
* @param dynamic is dynamic
* @return created {@link Rollout}
*/
public Rollout createRolloutByVariables(final String rolloutName, final String rolloutDescription,
final int groupSize, final String filterQuery, final DistributionSet distributionSet,
final String successCondition, final String errorCondition, final Action.ActionType actionType,
final Integer weight, final boolean confirmationRequired) {
final Integer weight, final boolean confirmationRequired, final boolean dynamic) {
final RolloutGroupConditions conditions = new RolloutGroupConditionBuilder().withDefaults()
.successCondition(RolloutGroupSuccessCondition.THRESHOLD, successCondition)
.errorCondition(RolloutGroupErrorCondition.THRESHOLD, errorCondition)
@@ -1229,7 +1248,8 @@ public class TestdataFactory {
final Rollout rollout = rolloutManagement.create(
entityFactory.rollout().create().name(rolloutName).description(rolloutDescription)
.targetFilterQuery(filterQuery).set(distributionSet).actionType(actionType).weight(weight),
.targetFilterQuery(filterQuery).set(distributionSet).actionType(actionType).weight(weight)
.dynamic(dynamic),
groupSize, confirmationRequired, conditions);
// Run here, because Scheduler is disabled during tests
@@ -1300,7 +1320,7 @@ public class TestdataFactory {
* the amount of targets used for the rollout
* @param amountOtherTargets
* amount of other targets not included in the rollout
* @param groupSize
* @param amountGroups
* the size of the rollout group
* @param successCondition
* success condition