Add REST method for update rollout (#1749)
* adds PUT method for updating name and description of a rollout * restrict RolloutUpdate to changing only name and description * small refactoring Signed-off-by: Marinov Avgustin <Avgustin.Marinov@bosch.com>
This commit is contained in:
@@ -9,18 +9,122 @@
|
||||
*/
|
||||
package org.eclipse.hawkbit.repository.jpa.builder;
|
||||
|
||||
import jakarta.validation.constraints.Max;
|
||||
import jakarta.validation.constraints.Min;
|
||||
import org.eclipse.hawkbit.repository.DistributionSetManagement;
|
||||
import org.eclipse.hawkbit.repository.builder.AbstractRolloutUpdateCreate;
|
||||
import org.eclipse.hawkbit.repository.ValidString;
|
||||
import org.eclipse.hawkbit.repository.builder.AbstractNamedEntityBuilder;
|
||||
import org.eclipse.hawkbit.repository.builder.RolloutCreate;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaRollout;
|
||||
import org.eclipse.hawkbit.repository.model.Action;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public class JpaRolloutCreate extends AbstractNamedEntityBuilder<RolloutCreate> implements RolloutCreate {
|
||||
|
||||
public class JpaRolloutCreate extends AbstractRolloutUpdateCreate<RolloutCreate> implements RolloutCreate {
|
||||
private final DistributionSetManagement distributionSetManagement;
|
||||
|
||||
protected Long distributionSetId;
|
||||
@ValidString
|
||||
protected String targetFilterQuery;
|
||||
protected Action.ActionType actionType;
|
||||
protected Long forcedTime;
|
||||
protected Long startAt;
|
||||
@Min(Action.WEIGHT_MIN)
|
||||
@Max(Action.WEIGHT_MAX)
|
||||
protected Integer weight;
|
||||
|
||||
private boolean dynamic;
|
||||
|
||||
JpaRolloutCreate(final DistributionSetManagement distributionSetManagement) {
|
||||
this.distributionSetManagement = distributionSetManagement;
|
||||
}
|
||||
/**
|
||||
* {@link DistributionSet} of rollout
|
||||
*
|
||||
* @param distributionSetId ID of the distributionSetId
|
||||
* @return this builder
|
||||
*/
|
||||
public RolloutCreate distributionSetId(final long distributionSetId) {
|
||||
this.distributionSetId = distributionSetId;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter of the rollout
|
||||
*
|
||||
* @param targetFilterQuery query
|
||||
* @return this builder
|
||||
*/
|
||||
public RolloutCreate targetFilterQuery(final String targetFilterQuery) {
|
||||
this.targetFilterQuery = StringUtils.trimWhitespace(targetFilterQuery);
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* {@link Action.ActionType} used for {@link Action}s
|
||||
*
|
||||
* @param actionType type
|
||||
* @return this builder
|
||||
*/
|
||||
public RolloutCreate actionType(final Action.ActionType actionType) {
|
||||
this.actionType = actionType;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* forcedTime used for {@link Action}s
|
||||
*
|
||||
* @param forcedTime time
|
||||
* @return this builder
|
||||
*/
|
||||
public RolloutCreate forcedTime(final Long forcedTime) {
|
||||
this.forcedTime = forcedTime;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* weight used for {@link Action}s
|
||||
*
|
||||
* @param weight weight
|
||||
* @return this builder
|
||||
*/
|
||||
public RolloutCreate weight(final Integer weight) {
|
||||
this.weight = weight;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set start of the Rollout
|
||||
*
|
||||
* @param startAt start time point
|
||||
* @return this builder
|
||||
*/
|
||||
public RolloutCreate startAt(final Long startAt) {
|
||||
this.startAt = startAt;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Optional<Long> getDistributionSetId() {
|
||||
return Optional.ofNullable(distributionSetId);
|
||||
}
|
||||
|
||||
public Optional<Action.ActionType> getActionType() {
|
||||
return Optional.ofNullable(actionType);
|
||||
}
|
||||
|
||||
public Optional<Long> getForcedTime() {
|
||||
return Optional.ofNullable(forcedTime);
|
||||
}
|
||||
|
||||
public Optional<Integer> getWeight() {
|
||||
return Optional.ofNullable(weight);
|
||||
}
|
||||
|
||||
public Optional<Long> getStartAt() {
|
||||
return Optional.ofNullable(startAt);
|
||||
}
|
||||
|
||||
public RolloutCreate dynamic(final boolean dynamic) {
|
||||
this.dynamic = dynamic;
|
||||
@@ -33,7 +137,7 @@ public class JpaRolloutCreate extends AbstractRolloutUpdateCreate<RolloutCreate>
|
||||
|
||||
rollout.setName(name);
|
||||
rollout.setDescription(description);
|
||||
rollout.setDistributionSet(distributionSetManagement.getValidAndComplete(set));
|
||||
rollout.setDistributionSet(distributionSetManagement.getValidAndComplete(distributionSetId));
|
||||
rollout.setTargetFilterQuery(targetFilterQuery);
|
||||
rollout.setStartAt(startAt);
|
||||
rollout.setWeight(weight);
|
||||
@@ -49,4 +153,4 @@ public class JpaRolloutCreate extends AbstractRolloutUpdateCreate<RolloutCreate>
|
||||
|
||||
return rollout;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -58,7 +58,6 @@ import org.eclipse.hawkbit.repository.jpa.repository.RolloutRepository;
|
||||
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.DistributionSet;
|
||||
@@ -523,24 +522,9 @@ public class JpaRolloutManagement implements RolloutManagement {
|
||||
final JpaRollout rollout = getRolloutAndThrowExceptionIfNotFound(update.getId());
|
||||
|
||||
checkIfDeleted(update.getId(), rollout.getStatus());
|
||||
|
||||
update.getName().ifPresent(rollout::setName);
|
||||
update.getDescription().ifPresent(rollout::setDescription);
|
||||
update.getActionType().ifPresent(rollout::setActionType);
|
||||
update.getForcedTime().ifPresent(rollout::setForcedTime);
|
||||
update.getWeight().ifPresent(rollout::setWeight);
|
||||
// resetting back to manual start is done by setting start at time to
|
||||
// null
|
||||
rollout.setStartAt(update.getStartAt().orElse(null));
|
||||
update.getSet().ifPresent(setId -> {
|
||||
final DistributionSet set = distributionSetManagement.getValidAndComplete(setId);
|
||||
rollout.setDistributionSet(set);
|
||||
});
|
||||
if (rolloutApprovalStrategy.isApprovalNeeded(rollout)) {
|
||||
rollout.setStatus(RolloutStatus.WAITING_FOR_APPROVAL);
|
||||
rollout.setApprovalDecidedBy(null);
|
||||
rollout.setApprovalRemark(null);
|
||||
}
|
||||
|
||||
return rolloutRepository.save(rollout);
|
||||
}
|
||||
|
||||
|
||||
@@ -45,9 +45,8 @@ public class RolloutEventTest extends AbstractRemoteEntityEventTest<Rollout> {
|
||||
.type("os").modules(Collections.singletonList(module.getId())));
|
||||
|
||||
return rolloutManagement.create(
|
||||
entityFactory.rollout().create().name("exampleRollout").targetFilterQuery("controllerId==*").set(ds), 5,
|
||||
entityFactory.rollout().create().name("exampleRollout").targetFilterQuery("controllerId==*").distributionSetId(ds), 5,
|
||||
false, new RolloutGroupConditionBuilder().withDefaults()
|
||||
.successCondition(RolloutGroupSuccessCondition.THRESHOLD, "10").build());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -85,11 +85,10 @@ public class RolloutGroupEventTest extends AbstractRemoteEntityEventTest<Rollout
|
||||
.type("os").modules(Collections.singletonList(module.getId())));
|
||||
|
||||
final Rollout entity = rolloutManagement.create(
|
||||
entityFactory.rollout().create().name("exampleRollout").targetFilterQuery("controllerId==*").set(ds), 5,
|
||||
entityFactory.rollout().create().name("exampleRollout").targetFilterQuery("controllerId==*").distributionSetId(ds), 5,
|
||||
false, new RolloutGroupConditionBuilder().withDefaults()
|
||||
.successCondition(RolloutGroupSuccessCondition.THRESHOLD, "10").build());
|
||||
|
||||
return rolloutGroupManagement.findByRollout(PAGE, entity.getId()).getContent().get(0);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -119,7 +119,7 @@ public class ConcurrentDistributionSetInvalidationTest extends AbstractJpaIntegr
|
||||
|
||||
return rolloutManagement.create(entityFactory.rollout().create()
|
||||
.name("verifyInvalidateDistributionSetWithLargeRolloutThrowsException").description("desc")
|
||||
.targetFilterQuery("name==*").set(distributionSet).actionType(ActionType.FORCED),
|
||||
.targetFilterQuery("name==*").distributionSetId(distributionSet).actionType(ActionType.FORCED),
|
||||
quotaManagement.getMaxRolloutGroupsPerRollout(), false, conditions);
|
||||
}
|
||||
|
||||
|
||||
@@ -58,7 +58,6 @@ import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
|
||||
import org.eclipse.hawkbit.repository.exception.EntityReadOnlyException;
|
||||
import org.eclipse.hawkbit.repository.exception.IncompleteDistributionSetException;
|
||||
import org.eclipse.hawkbit.repository.exception.InvalidDistributionSetException;
|
||||
import org.eclipse.hawkbit.repository.exception.MultiAssignmentIsNotEnabledException;
|
||||
import org.eclipse.hawkbit.repository.exception.RolloutIllegalStateException;
|
||||
import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaAction;
|
||||
@@ -1408,7 +1407,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
||||
.errorAction(RolloutGroupErrorAction.PAUSE, null).build();
|
||||
|
||||
final RolloutCreate rollout = entityFactory.rollout().create().name(rolloutName).description(rolloutName)
|
||||
.targetFilterQuery("controllerId==" + targetPrefixName + "-*").set(distributionSet);
|
||||
.targetFilterQuery("controllerId==" + targetPrefixName + "-*").distributionSetId(distributionSet);
|
||||
|
||||
assertThatExceptionOfType(AssignmentQuotaExceededException.class)
|
||||
.isThrownBy(() -> rolloutManagement.create(rollout, amountGroups, false, conditions));
|
||||
@@ -1436,7 +1435,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
||||
// group1 exceeds the quota
|
||||
assertThatExceptionOfType(AssignmentQuotaExceededException.class).isThrownBy(() -> rolloutManagement.create(
|
||||
entityFactory.rollout().create().name(rolloutName).description(rolloutName)
|
||||
.targetFilterQuery("controllerId==" + rolloutName + "-*").set(distributionSet),
|
||||
.targetFilterQuery("controllerId==" + rolloutName + "-*").distributionSetId(distributionSet),
|
||||
Arrays.asList(group1, group2), conditions));
|
||||
|
||||
// create group definitions
|
||||
@@ -1448,7 +1447,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
||||
// group4 exceeds the quota
|
||||
assertThatExceptionOfType(AssignmentQuotaExceededException.class).isThrownBy(() -> rolloutManagement.create(
|
||||
entityFactory.rollout().create().name(rolloutName).description(rolloutName)
|
||||
.targetFilterQuery("controllerId==" + rolloutName + "-*").set(distributionSet),
|
||||
.targetFilterQuery("controllerId==" + rolloutName + "-*").distributionSetId(distributionSet),
|
||||
Arrays.asList(group3, group4), conditions));
|
||||
|
||||
// create group definitions
|
||||
@@ -1462,15 +1461,14 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
||||
// should work fine
|
||||
assertThat(rolloutManagement.create(
|
||||
entityFactory.rollout().create().name(rolloutName).description(rolloutName)
|
||||
.targetFilterQuery("controllerId==" + rolloutName + "-*").set(distributionSet),
|
||||
.targetFilterQuery("controllerId==" + rolloutName + "-*").distributionSetId(distributionSet),
|
||||
Arrays.asList(group5, group6, group7), conditions)).isNotNull();
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Verify the creation and the automatic start of a rollout.")
|
||||
void createAndAutoStartRollout() {
|
||||
|
||||
@Description("Verify the update of a rollout")
|
||||
void updateRollout() {
|
||||
final int amountTargetsForRollout = 50;
|
||||
final int amountGroups = 5;
|
||||
final String successCondition = "50";
|
||||
@@ -1487,31 +1485,13 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
||||
// schedule rollout auto start into the future
|
||||
final Long myRolloutId = myRollout.getId();
|
||||
rolloutManagement
|
||||
.update(entityFactory.rollout().update(myRolloutId).startAt(System.currentTimeMillis() + 60000));
|
||||
.update(entityFactory.rollout().update(myRolloutId).name("newName").description("newDesc"));
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
// rollout should not have been started
|
||||
myRollout = getRollout(myRolloutId);
|
||||
assertThat(myRollout.getStatus()).isEqualTo(RolloutStatus.READY);
|
||||
|
||||
// schedule to now
|
||||
rolloutManagement.update(entityFactory.rollout().update(myRolloutId).startAt(System.currentTimeMillis()));
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
myRollout = getRollout(myRolloutId);
|
||||
assertThat(myRollout.getStatus()).isEqualTo(RolloutStatus.STARTING);
|
||||
|
||||
// Run here, because scheduler is disabled during tests
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
awaitRunningState(myRolloutId);
|
||||
|
||||
myRollout = getRollout(myRolloutId);
|
||||
assertThat(myRollout.getStatus()).isEqualTo(RolloutStatus.RUNNING);
|
||||
final Map<TotalTargetCountStatus.Status, Long> expectedTargetCountStatus = createInitStatusMap();
|
||||
expectedTargetCountStatus.put(TotalTargetCountStatus.Status.RUNNING, 10L);
|
||||
expectedTargetCountStatus.put(TotalTargetCountStatus.Status.SCHEDULED, 40L);
|
||||
validateRolloutActionStatus(myRolloutId, expectedTargetCountStatus);
|
||||
assertThat(myRollout.getName()).isEqualTo("newName");
|
||||
assertThat(myRollout.getDescription()).isEqualTo("newDesc");
|
||||
}
|
||||
|
||||
private Rollout reloadRollout(final Rollout r) {
|
||||
@@ -1766,7 +1746,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
||||
.errorCondition(RolloutGroupErrorCondition.THRESHOLD, errorCondition)
|
||||
.errorAction(RolloutGroupErrorAction.PAUSE, null).build();
|
||||
final RolloutCreate rolloutToCreate = entityFactory.rollout().create().name(rolloutName)
|
||||
.description("some description").targetFilterQuery("id==" + rolloutName + "-*").set(distributionSet);
|
||||
.description("some description").targetFilterQuery("id==" + rolloutName + "-*").distributionSetId(distributionSet);
|
||||
|
||||
Rollout myRollout = rolloutManagement.create(rolloutToCreate, amountGroups, false, conditions);
|
||||
myRollout = getRollout(myRollout.getId());
|
||||
@@ -1942,7 +1922,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
||||
final String prefixRolloutRunning = randomString + "1";
|
||||
final RolloutCreate rolloutRunningCreate = entityFactory.rollout().create()
|
||||
.name(prefixRolloutRunning + "-testRollout").targetFilterQuery("name==" + randomString + "*")
|
||||
.set(testDs);
|
||||
.distributionSetId(testDs);
|
||||
|
||||
Rollout rolloutRunning = rolloutManagement.create(rolloutRunningCreate, 1, false, conditions);
|
||||
// Let the executor handle created Rollout
|
||||
@@ -1955,7 +1935,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
||||
|
||||
final String prefixRolloutReady = randomString + "2";
|
||||
final RolloutCreate rolloutReadyCreate = entityFactory.rollout().create()
|
||||
.name(prefixRolloutReady + "-testRollout").targetFilterQuery("name==" + randomString + "*").set(testDs);
|
||||
.name(prefixRolloutReady + "-testRollout").targetFilterQuery("name==" + randomString + "*").distributionSetId(testDs);
|
||||
Rollout rolloutReady = rolloutManagement.create(rolloutReadyCreate, 1, false, conditions);
|
||||
// Let the executor handle created Rollout
|
||||
rolloutHandler.handleAll();
|
||||
@@ -2066,34 +2046,6 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
||||
"desc", 2, "name==*", distributionSet, "50", "80"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Verifies that an exception is thrown when trying to update a rollout with an invalidated distribution set.")
|
||||
void updateRolloutWithInvalidDistributionSet() {
|
||||
final DistributionSet distributionSet = testdataFactory.createDistributionSet();
|
||||
testdataFactory.createTarget();
|
||||
final Rollout rollout = testdataFactory.createRolloutByVariables("updateRolloutWithInvalidDistributionSet",
|
||||
"desc", 2, "name==*", distributionSet, "50", "80");
|
||||
final DistributionSet invalidDistributionSet = testdataFactory.createAndInvalidateDistributionSet();
|
||||
|
||||
assertThatExceptionOfType(InvalidDistributionSetException.class)
|
||||
.as("Invalid distributionSet should throw an exception").isThrownBy(() -> rolloutManagement
|
||||
.update(entityFactory.rollout().update(rollout.getId()).set(invalidDistributionSet.getId())));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Verifies that an exception is thrown when trying to update a rollout with an incomplete distribution set.")
|
||||
void updateRolloutWithIncompleteDistributionSet() {
|
||||
final DistributionSet distributionSet = testdataFactory.createDistributionSet();
|
||||
testdataFactory.createTarget();
|
||||
final Rollout rollout = testdataFactory.createRolloutByVariables("updateRolloutWithIncompleteDistributionSet",
|
||||
"desc", 2, "name==*", distributionSet, "50", "80");
|
||||
final DistributionSet incompleteDistributionSet = testdataFactory.createIncompleteDistributionSet();
|
||||
|
||||
assertThatExceptionOfType(IncompleteDistributionSetException.class)
|
||||
.as("Incomplete distributionSet should throw an exception").isThrownBy(() -> rolloutManagement.update(
|
||||
entityFactory.rollout().update(rollout.getId()).set(incompleteDistributionSet.getId())));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Verify the that only compatible targets are part of a Rollout.")
|
||||
void createAndStartRolloutWithTargetTypes() {
|
||||
@@ -2114,7 +2066,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
||||
|
||||
final RolloutGroupConditions conditions = new RolloutGroupConditionBuilder().withDefaults().build();
|
||||
final RolloutCreate rolloutToCreate = entityFactory.rollout().create().name(rolloutName)
|
||||
.targetFilterQuery("name==*").set(testDs);
|
||||
.targetFilterQuery("name==*").distributionSetId(testDs);
|
||||
|
||||
final Rollout createdRollout = rolloutManagement.create(rolloutToCreate, 1, false, conditions);
|
||||
|
||||
@@ -2156,7 +2108,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
|
||||
|
||||
return entityFactory.rollout().create().name(rolloutName)
|
||||
.description("This is a test description for the rollout")
|
||||
.targetFilterQuery("controllerId==" + rolloutName + "-*").set(distributionSet);
|
||||
.targetFilterQuery("controllerId==" + rolloutName + "-*").distributionSetId(distributionSet);
|
||||
}
|
||||
|
||||
private void validateRolloutGroupActionStatus(final RolloutGroup rolloutGroup,
|
||||
|
||||
@@ -98,9 +98,9 @@ public class RSQLRolloutGroupFieldTest extends AbstractJpaIntegrationTest {
|
||||
private Rollout createRollout(final String name, final int amountGroups, final long distributionSetId,
|
||||
final String targetFilterQuery) {
|
||||
return rolloutManagement.create(
|
||||
entityFactory.rollout().create().set(distributionSetManagement.get(distributionSetId).get()).name(name)
|
||||
entityFactory.rollout().create().distributionSetId(distributionSetManagement.get(distributionSetId).get()).name(name)
|
||||
.targetFilterQuery(targetFilterQuery),
|
||||
amountGroups, false, new RolloutGroupConditionBuilder().withDefaults()
|
||||
.successCondition(RolloutGroupSuccessCondition.THRESHOLD, "100").build());
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user