diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/builder/RolloutBuilder.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/builder/RolloutBuilder.java index 32b7a48cc..627998dfa 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/builder/RolloutBuilder.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/builder/RolloutBuilder.java @@ -13,13 +13,11 @@ import org.eclipse.hawkbit.repository.model.Rollout; /** * Builder for {@link Rollout}. - * */ public interface RolloutBuilder { /** - * @param id - * of the updatable entity + * @param id of the updatable entity * @return builder instance */ RolloutUpdate update(long id); @@ -28,5 +26,4 @@ public interface RolloutBuilder { * @return builder instance */ RolloutCreate create(); - -} +} \ No newline at end of file diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/builder/RolloutCreate.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/builder/RolloutCreate.java index a3f649e92..fb2b63a14 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/builder/RolloutCreate.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/builder/RolloutCreate.java @@ -28,11 +28,11 @@ import org.eclipse.hawkbit.repository.model.TargetFilterQuery; * */ public interface RolloutCreate { + /** * Set name * - * @param name - * for {@link Rollout#getName()} + * @param name for {@link Rollout#getName()} * @return updated builder instance */ RolloutCreate name(@Size(min = 1, max = NamedEntity.NAME_MAX_SIZE) @NotNull String name); @@ -40,8 +40,7 @@ public interface RolloutCreate { /** * Set description * - * @param description - * for {@link Rollout#getDescription()} + * @param description for {@link Rollout#getDescription()} * @return updated builder instance */ RolloutCreate description(@Size(max = NamedEntity.DESCRIPTION_MAX_SIZE) String description); @@ -49,28 +48,25 @@ public interface RolloutCreate { /** * Set the {@link DistributionSet} * - * @param set - * for {@link Rollout#getDistributionSet()} + * @param set for {@link Rollout#getDistributionSet()} * @return updated builder instance */ - default RolloutCreate set(final DistributionSet set) { - return set(Optional.ofNullable(set).map(DistributionSet::getId).orElse(null)); + default RolloutCreate distributionSetId(final DistributionSet set) { + return distributionSetId(Optional.ofNullable(set).map(DistributionSet::getId).orElse(null)); } /** * Set the id of the {@link DistributionSet} * - * @param setId - * for {@link Rollout#getDistributionSet()} + * @param distributionSetId for {@link Rollout#getDistributionSet()} * @return updated builder instance */ - RolloutCreate set(long setId); + RolloutCreate distributionSetId(long distributionSetId); /** * Set the {@link TargetFilterQuery} * - * @param targetFilterQuery - * for {@link Rollout#getTargetFilterQuery()} + * @param targetFilterQuery for {@link Rollout#getTargetFilterQuery()} * @return updated builder instance */ RolloutCreate targetFilterQuery( @@ -79,26 +75,23 @@ public interface RolloutCreate { /** * Set the {@link ActionType} * - * @param actionType - * for {@link Rollout#getActionType()} + * @param actionType for {@link Rollout#getActionType()} * @return updated builder instance */ RolloutCreate actionType(@NotNull ActionType actionType); /** - * Set the forcedTime of the resulting {@link Actions} + * Set the forcedTime of the resulting {@link org.eclipse.hawkbit.repository.model.Action}s * - * @param forcedTime - * for {@link Rollout#getForcedTime()} + * @param forcedTime for {@link Rollout#getForcedTime()} * @return updated builder instance */ RolloutCreate forcedTime(Long forcedTime); /** - * Set the weight of the resulting {@link Actions} + * Set the weight of the resulting {@link org.eclipse.hawkbit.repository.model.Action}s * - * @param weight - * for {@link Rollout#getWeight()} + * @param weight for {@link Rollout#getWeight()} * @return updated builder instance */ RolloutCreate weight(Integer weight); @@ -106,17 +99,15 @@ public interface RolloutCreate { /** * Set if the rollout shall be dynamic * - * @param dynamic - * for {@link Rollout#isDynamic()} + * @param dynamic for {@link Rollout#isDynamic()} * @return updated builder instance */ RolloutCreate dynamic(boolean dynamic); /** - * set start + * Set start at * - * @param startAt - * for {@link Rollout#getStartAt()} + * @param startAt for {@link Rollout#getStartAt()} * @return updated builder instance */ RolloutCreate startAt(Long startAt); @@ -125,4 +116,4 @@ public interface RolloutCreate { * @return peek on current state of {@link Rollout} in the builder */ Rollout build(); -} +} \ No newline at end of file diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/builder/RolloutUpdate.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/builder/RolloutUpdate.java index 8c9d47fe7..ff5ebb535 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/builder/RolloutUpdate.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/builder/RolloutUpdate.java @@ -26,8 +26,7 @@ public interface RolloutUpdate { /** * Set name of the {@link Rollout} * - * @param name - * for {@link Rollout#getName()} + * @param name for {@link Rollout#getName()} * @return updated builder instance */ RolloutUpdate name(@Size(min = 1, max = NamedEntity.NAME_MAX_SIZE) @NotNull String name); @@ -35,54 +34,8 @@ public interface RolloutUpdate { /** * Set description of the {@link Rollout} * - * @param description - * for {@link Rollout#getDescription()} + * @param description for {@link Rollout#getDescription()} * @return updated builder instance */ RolloutUpdate description(@Size(max = NamedEntity.DESCRIPTION_MAX_SIZE) String description); - - /** - * Set ID of {@link DistributionSet} of the {@link Rollout} - * - * @param setId - * for {@link Rollout#getDistributionSet()} - * @return updated builder instance - */ - RolloutUpdate set(long setId); - - /** - * Set action type of the {@link Rollout} - * - * @param actionType - * for {@link Rollout#getActionType()} - * @return updated builder instance - */ - RolloutUpdate actionType(@NotNull Action.ActionType actionType); - - /** - * Set forcedTime of the {@link Rollout} - * - * @param forcedTime - * for {@link Rollout#getForcedTime()} - * @return updated builder instance - */ - RolloutUpdate forcedTime(Long forcedTime); - - /** - * Set weight of {@link Action}s created by the {@link Rollout} - * - * @param weight - * for {@link Rollout#getWeight()} - * @return updated builder instance - */ - RolloutUpdate weight(Integer weight); - - /** - * Set start time of the {@link Rollout} - * - * @param startAt - * for {@link Rollout#getStartAt()} - * @return updated builder instance - */ - RolloutUpdate startAt(Long startAt); -} +} \ No newline at end of file diff --git a/hawkbit-repository/hawkbit-repository-core/src/main/java/org/eclipse/hawkbit/repository/builder/AbstractRolloutUpdateCreate.java b/hawkbit-repository/hawkbit-repository-core/src/main/java/org/eclipse/hawkbit/repository/builder/AbstractRolloutUpdateCreate.java deleted file mode 100644 index 766e91d2a..000000000 --- a/hawkbit-repository/hawkbit-repository-core/src/main/java/org/eclipse/hawkbit/repository/builder/AbstractRolloutUpdateCreate.java +++ /dev/null @@ -1,134 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.repository.builder; - -import java.util.Optional; - -import jakarta.validation.constraints.Max; -import jakarta.validation.constraints.Min; - -import org.eclipse.hawkbit.repository.ValidString; -import org.eclipse.hawkbit.repository.model.Action; -import org.eclipse.hawkbit.repository.model.Action.ActionType; -import org.eclipse.hawkbit.repository.model.DistributionSet; -import org.springframework.util.StringUtils; - -/** - * Create and update builder DTO. - * - * @param - * update or create builder interface - */ -public abstract class AbstractRolloutUpdateCreate extends AbstractNamedEntityBuilder { - protected Long set; - - @ValidString - protected String targetFilterQuery; - - protected ActionType actionType; - protected Long forcedTime; - protected Long startAt; - - @Min(Action.WEIGHT_MIN) - @Max(Action.WEIGHT_MAX) - protected Integer weight; - - /** - * {@link DistributionSet} of rollout - * - * @param set - * ID of the set - * @return this builder - */ - public T set(final long set) { - this.set = set; - return (T) this; - } - - /** - * Filter of the rollout - * - * @param targetFilterQuery - * query - * @return this builder - */ - public T targetFilterQuery(final String targetFilterQuery) { - this.targetFilterQuery = StringUtils.trimWhitespace(targetFilterQuery); - return (T) this; - } - - /** - * {@link ActionType} used for {@link Action}s - * - * @param actionType - * type - * @return this builder - */ - public T actionType(final ActionType actionType) { - this.actionType = actionType; - return (T) this; - } - - /** - * forcedTime used for {@link Action}s - * - * @param forcedTime - * time - * @return this builder - */ - public T forcedTime(final Long forcedTime) { - this.forcedTime = forcedTime; - return (T) this; - } - - /** - * weight used for {@link Action}s - * - * @param weight - * weight - * @return this builder - */ - public T weight(final Integer weight) { - this.weight = weight; - return (T) this; - } - - /** - * Set start of the Rollout - * - * @param startAt - * start time point - * @return this builder - */ - public T startAt(final Long startAt) { - this.startAt = startAt; - return (T) this; - } - - public Optional getSet() { - return Optional.ofNullable(set); - } - - public Optional getActionType() { - return Optional.ofNullable(actionType); - } - - public Optional getForcedTime() { - return Optional.ofNullable(forcedTime); - } - - public Optional getWeight() { - return Optional.ofNullable(weight); - } - - public Optional getStartAt() { - return Optional.ofNullable(startAt); - } -} diff --git a/hawkbit-repository/hawkbit-repository-core/src/main/java/org/eclipse/hawkbit/repository/builder/GenericRolloutUpdate.java b/hawkbit-repository/hawkbit-repository-core/src/main/java/org/eclipse/hawkbit/repository/builder/GenericRolloutUpdate.java index 3b2d32739..97cc631d7 100644 --- a/hawkbit-repository/hawkbit-repository-core/src/main/java/org/eclipse/hawkbit/repository/builder/GenericRolloutUpdate.java +++ b/hawkbit-repository/hawkbit-repository-core/src/main/java/org/eclipse/hawkbit/repository/builder/GenericRolloutUpdate.java @@ -12,7 +12,7 @@ package org.eclipse.hawkbit.repository.builder; /** * Update implementation. */ -public class GenericRolloutUpdate extends AbstractRolloutUpdateCreate implements RolloutUpdate { +public class GenericRolloutUpdate extends AbstractNamedEntityBuilder implements RolloutUpdate { public GenericRolloutUpdate(final Long id) { super.id = id; diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/builder/JpaRolloutCreate.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/builder/JpaRolloutCreate.java index 5ae8af95d..f686a95ee 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/builder/JpaRolloutCreate.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/builder/JpaRolloutCreate.java @@ -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 implements RolloutCreate { -public class JpaRolloutCreate extends AbstractRolloutUpdateCreate 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 getDistributionSetId() { + return Optional.ofNullable(distributionSetId); + } + + public Optional getActionType() { + return Optional.ofNullable(actionType); + } + + public Optional getForcedTime() { + return Optional.ofNullable(forcedTime); + } + + public Optional getWeight() { + return Optional.ofNullable(weight); + } + + public Optional getStartAt() { + return Optional.ofNullable(startAt); + } public RolloutCreate dynamic(final boolean dynamic) { this.dynamic = dynamic; @@ -33,7 +137,7 @@ public class JpaRolloutCreate extends AbstractRolloutUpdateCreate 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 return rollout; } -} +} \ No newline at end of file diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaRolloutManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaRolloutManagement.java index 9255e9443..e95839ba9 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaRolloutManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaRolloutManagement.java @@ -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); } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/event/remote/entity/RolloutEventTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/event/remote/entity/RolloutEventTest.java index 001142a61..2d9dde83b 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/event/remote/entity/RolloutEventTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/event/remote/entity/RolloutEventTest.java @@ -45,9 +45,8 @@ public class RolloutEventTest extends AbstractRemoteEntityEventTest { .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()); } - -} +} \ No newline at end of file diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/event/remote/entity/RolloutGroupEventTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/event/remote/entity/RolloutGroupEventTest.java index b5d33f931..db93d3bb6 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/event/remote/entity/RolloutGroupEventTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/event/remote/entity/RolloutGroupEventTest.java @@ -85,11 +85,10 @@ public class RolloutGroupEventTest extends AbstractRemoteEntityEventTest 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 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, diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RSQLRolloutGroupFieldTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RSQLRolloutGroupFieldTest.java index c6445ee4d..256d5aae3 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RSQLRolloutGroupFieldTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RSQLRolloutGroupFieldTest.java @@ -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()); } -} +} \ No newline at end of file diff --git a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/TestdataFactory.java b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/TestdataFactory.java index 475cda687..e747bc906 100644 --- a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/TestdataFactory.java +++ b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/TestdataFactory.java @@ -1246,7 +1246,7 @@ 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).distributionSetId(distributionSet).actionType(actionType).weight(weight) .dynamic(dynamic), groupSize, confirmationRequired, conditions); diff --git a/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/json/model/rollout/MgmtRolloutRestRequestBody.java b/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/json/model/rollout/MgmtRolloutRestRequestBodyPost.java similarity index 91% rename from hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/json/model/rollout/MgmtRolloutRestRequestBody.java rename to hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/json/model/rollout/MgmtRolloutRestRequestBodyPost.java index afc9e7442..d9f06bed8 100644 --- a/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/json/model/rollout/MgmtRolloutRestRequestBody.java +++ b/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/json/model/rollout/MgmtRolloutRestRequestBodyPost.java @@ -10,7 +10,6 @@ package org.eclipse.hawkbit.mgmt.json.model.rollout; import java.util.List; -import java.util.Optional; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; @@ -63,18 +62,18 @@ import com.fasterxml.jackson.annotation.JsonProperty; }, "startAt" : 1682408570791 }""") -public class MgmtRolloutRestRequestBody extends AbstractMgmtRolloutConditionsEntity { +public class MgmtRolloutRestRequestBodyPost extends AbstractMgmtRolloutConditionsEntity { @Schema(description = "Target filter query language expression", example = "id==targets-*") private String targetFilterQuery; - @Schema(description = "The ID of distributionset of this rollout", example = "6") + @Schema(description = "The ID of distribution set of this rollout", example = "6") private long distributionSetId; @Schema(description = "The amount of groups the rollout should split targets into", example = "5") private Integer amountGroups; - @Schema(description = "Forcetime in milliseconds", example = "1691065781929") + @Schema(description = "Force time in milliseconds", example = "1691065781929") private Long forcetime; @Schema(description = "Start at timestamp of Rollout", example = "1691065780929") diff --git a/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/json/model/rollout/MgmtRolloutRestRequestBodyPut.java b/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/json/model/rollout/MgmtRolloutRestRequestBodyPut.java new file mode 100644 index 000000000..90bf14f82 --- /dev/null +++ b/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/json/model/rollout/MgmtRolloutRestRequestBodyPut.java @@ -0,0 +1,43 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.hawkbit.mgmt.json.model.rollout; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; +import lombok.experimental.Accessors; +import org.eclipse.hawkbit.mgmt.json.model.MgmtNamedEntity; +import org.eclipse.hawkbit.mgmt.json.model.distributionset.MgmtActionType; +import org.eclipse.hawkbit.mgmt.json.model.rolloutgroup.MgmtRolloutGroup; + +import java.util.List; + +/** + * Model for request containing a rollout body e.g. in a POST request of + * creating a rollout via REST API. + */ +@Data +@Accessors(chain = true) +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@JsonInclude(Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(example = """ + { + "name" : "exampleRollout", + "description" : "Rollout for all named targets" + }""") +public class MgmtRolloutRestRequestBodyPut extends MgmtNamedEntity { +} \ No newline at end of file diff --git a/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtRolloutRestApi.java b/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtRolloutRestApi.java index 7e81c192a..27e0a4faf 100644 --- a/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtRolloutRestApi.java +++ b/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtRolloutRestApi.java @@ -17,7 +17,8 @@ import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; import org.eclipse.hawkbit.mgmt.json.model.PagedList; import org.eclipse.hawkbit.mgmt.json.model.rollout.MgmtRolloutResponseBody; -import org.eclipse.hawkbit.mgmt.json.model.rollout.MgmtRolloutRestRequestBody; +import org.eclipse.hawkbit.mgmt.json.model.rollout.MgmtRolloutRestRequestBodyPost; +import org.eclipse.hawkbit.mgmt.json.model.rollout.MgmtRolloutRestRequestBodyPut; import org.eclipse.hawkbit.mgmt.json.model.rolloutgroup.MgmtRolloutGroupResponseBody; import org.eclipse.hawkbit.mgmt.json.model.target.MgmtTarget; import org.eclipse.hawkbit.rest.json.model.ExceptionInfo; @@ -28,6 +29,8 @@ import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestParam; /** @@ -144,7 +147,7 @@ public interface MgmtRolloutRestApi { /** * Handles the POST request for creating rollout. * - * @param rolloutRequestBody + * @param rolloutCreateBody * the rollout body to be created. * @return In case rollout could successful created the ResponseEntity with * status code 201 with the successfully created rollout. In any @@ -161,7 +164,7 @@ public interface MgmtRolloutRestApi { content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))), @ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " + - "data volume restriction applies.", + "data volume restriction applies.", content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))), @ApiResponse(responseCode = "405", description = "The http request method is not allowed on the resource.", content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))), @@ -180,7 +183,50 @@ public interface MgmtRolloutRestApi { @PostMapping(value = MgmtRestConstants.ROLLOUT_V1_REQUEST_MAPPING, consumes = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }, produces = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) - ResponseEntity create(MgmtRolloutRestRequestBody rolloutRequestBody); + ResponseEntity create(MgmtRolloutRestRequestBodyPost rolloutCreateBody); + + /** + * Handles the POST request for creating rollout. + * + * @param rolloutUpdateBody + * the rollout body with details for update. + * @return In case rollout could successful updated the ResponseEntity with + * status code 200 with the successfully created rollout. In any + * failure the JsonResponseExceptionHandler is handling the + * response. + */ + @Operation(summary = "Update Rollout", description = "Handles the UPDATE request for a single " + + "Rollout. Required permission: UPDATE_ROLLOUT") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Successfully retrieved"), + @ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters", + content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))), + @ApiResponse(responseCode = "401", description = "The request requires user authentication.", + content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))), + @ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " + + "changed (i.e. read-only) or data volume restriction applies.", + content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))), + @ApiResponse(responseCode = "404", description = "Distribution Set not found.", + content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))), + @ApiResponse(responseCode = "405", description = "The http request method is not allowed on the resource.", + content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))), + @ApiResponse(responseCode = "406", description = "In case accept header is specified and not application/json.", + content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))), + @ApiResponse(responseCode = "409", description = "E.g. in case an entity is created or modified by another " + + "user in another request at the same time. You may retry your modification request.", + content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))), + @ApiResponse(responseCode = "415", description = "The request was attempt with a media-type which is not " + + "supported by the server for this resource.", + content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))), + @ApiResponse(responseCode = "429", description = "Too many requests. The server will refuse further " + + "attempts and the client has to wait another second.", + content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))) + }) + @PutMapping(value = MgmtRestConstants.ROLLOUT_V1_REQUEST_MAPPING + "/{rolloutId}", consumes = { + MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }, produces = { + MediaType.APPLICATION_JSON_VALUE, MediaTypes.HAL_JSON_VALUE }) + ResponseEntity update(@PathVariable("rolloutId") Long rolloutId, + @RequestBody MgmtRolloutRestRequestBodyPut rolloutUpdateBody); /** * Handles the request for approving a rollout. diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtRolloutMapper.java b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtRolloutMapper.java index 5783aabeb..5e9ecdaaa 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtRolloutMapper.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtRolloutMapper.java @@ -22,7 +22,8 @@ import org.eclipse.hawkbit.mgmt.json.model.rollout.MgmtRolloutCondition.Conditio import org.eclipse.hawkbit.mgmt.json.model.rollout.MgmtRolloutErrorAction; import org.eclipse.hawkbit.mgmt.json.model.rollout.MgmtRolloutErrorAction.ErrorAction; import org.eclipse.hawkbit.mgmt.json.model.rollout.MgmtRolloutResponseBody; -import org.eclipse.hawkbit.mgmt.json.model.rollout.MgmtRolloutRestRequestBody; +import org.eclipse.hawkbit.mgmt.json.model.rollout.MgmtRolloutRestRequestBodyPost; +import org.eclipse.hawkbit.mgmt.json.model.rollout.MgmtRolloutRestRequestBodyPut; import org.eclipse.hawkbit.mgmt.json.model.rollout.MgmtRolloutSuccessAction; import org.eclipse.hawkbit.mgmt.json.model.rollout.MgmtRolloutSuccessAction.SuccessAction; import org.eclipse.hawkbit.mgmt.json.model.rolloutgroup.MgmtRolloutGroup; @@ -33,6 +34,7 @@ import org.eclipse.hawkbit.mgmt.rest.api.MgmtRolloutRestApi; import org.eclipse.hawkbit.repository.EntityFactory; import org.eclipse.hawkbit.repository.builder.RolloutCreate; import org.eclipse.hawkbit.repository.builder.RolloutGroupCreate; +import org.eclipse.hawkbit.repository.builder.RolloutUpdate; import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.Rollout; import org.eclipse.hawkbit.repository.model.RolloutGroup; @@ -123,22 +125,30 @@ final class MgmtRolloutMapper { return body; } - static RolloutCreate fromRequest(final EntityFactory entityFactory, final MgmtRolloutRestRequestBody restRequest, + static RolloutCreate fromRequest(final EntityFactory entityFactory, final MgmtRolloutRestRequestBodyPost restRequest, final DistributionSet distributionSet) { - - return entityFactory.rollout().create().name(restRequest.getName()).description(restRequest.getDescription()) - .dynamic(restRequest.isDynamic()) - .set(distributionSet).targetFilterQuery(restRequest.getTargetFilterQuery()) + return entityFactory.rollout().create() + .name(restRequest.getName()) + .description(restRequest.getDescription()) + .distributionSetId(distributionSet) + .targetFilterQuery(restRequest.getTargetFilterQuery()) .actionType(MgmtRestModelMapper.convertActionType(restRequest.getType())) .forcedTime(restRequest.getForcetime()).startAt(restRequest.getStartAt()) - .weight(restRequest.getWeight()); + .weight(restRequest.getWeight()) + .dynamic(restRequest.isDynamic()); + } + + static RolloutUpdate fromRequest(final EntityFactory entityFactory, final MgmtRolloutRestRequestBodyPut restRequest, final long rolloutId) { + return entityFactory.rollout().update(rolloutId) + .name(restRequest.getName()) + .description(restRequest.getDescription()); } static RolloutCreate fromRetriedRollout(final EntityFactory entityFactory, final Rollout rollout) { return entityFactory.rollout().create() .name(rollout.getName().concat("_retry")) .description(rollout.getDescription()) - .set(rollout.getDistributionSet()) + .distributionSetId(rollout.getDistributionSet()) .targetFilterQuery("failedrollout==".concat(String.valueOf(rollout.getId()))) .actionType(rollout.getActionType()) .forcedTime(rollout.getForcedTime()) diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtRolloutResource.java b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtRolloutResource.java index a67ddac3a..cb8c47fa4 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtRolloutResource.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtRolloutResource.java @@ -19,7 +19,8 @@ import jakarta.validation.ValidationException; import lombok.extern.slf4j.Slf4j; import org.eclipse.hawkbit.mgmt.json.model.PagedList; import org.eclipse.hawkbit.mgmt.json.model.rollout.MgmtRolloutResponseBody; -import org.eclipse.hawkbit.mgmt.json.model.rollout.MgmtRolloutRestRequestBody; +import org.eclipse.hawkbit.mgmt.json.model.rollout.MgmtRolloutRestRequestBodyPost; +import org.eclipse.hawkbit.mgmt.json.model.rollout.MgmtRolloutRestRequestBodyPut; import org.eclipse.hawkbit.mgmt.json.model.rolloutgroup.MgmtRolloutGroup; import org.eclipse.hawkbit.mgmt.json.model.rolloutgroup.MgmtRolloutGroupResponseBody; import org.eclipse.hawkbit.mgmt.json.model.target.MgmtTarget; @@ -130,9 +131,8 @@ public class MgmtRolloutResource implements MgmtRolloutRestApi { @Override public ResponseEntity create( - @RequestBody final MgmtRolloutRestRequestBody rolloutRequestBody) { - - // first check the given RSQL query if it's well formed, otherwise and + @RequestBody final MgmtRolloutRestRequestBodyPost rolloutRequestBody) { + // first check the given RSQL query if it's well-formed, otherwise and // exception is thrown final String targetFilterQuery = rolloutRequestBody.getTargetFilterQuery(); if (targetFilterQuery == null) { @@ -170,9 +170,8 @@ public class MgmtRolloutResource implements MgmtRolloutRestApi { return ResponseEntity.status(HttpStatus.CREATED).body(MgmtRolloutMapper.toResponseRollout(rollout, true)); } - private Optional isConfirmationRequiredForGroup(final MgmtRolloutGroup group, - final MgmtRolloutRestRequestBody request) { + final MgmtRolloutRestRequestBodyPost request) { if (group.getConfirmationRequired() != null) { return Optional.of(group.getConfirmationRequired()); } else if (request.getConfirmationRequired() != null) { @@ -181,6 +180,15 @@ public class MgmtRolloutResource implements MgmtRolloutRestApi { return Optional.empty(); } + @Override + public ResponseEntity update( + @PathVariable("rolloutId") final Long rolloutId, + @RequestBody final MgmtRolloutRestRequestBodyPut rolloutUpdateBody) { + final Rollout updated = + rolloutManagement.update(MgmtRolloutMapper.fromRequest(entityFactory, rolloutUpdateBody, rolloutId)); + return ResponseEntity.ok(MgmtRolloutMapper.toResponseRollout(updated, true)); + } + @Override public ResponseEntity approve(@PathVariable("rolloutId") final Long rolloutId, final String remark) { rolloutManagement.approveOrDeny(rolloutId, Rollout.ApprovalDecision.APPROVED, remark); diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtRolloutResourceTest.java b/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtRolloutResourceTest.java index 9929dc9c8..74c9d96bc 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtRolloutResourceTest.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtRolloutResourceTest.java @@ -20,6 +20,7 @@ import static org.hamcrest.Matchers.hasSize; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -56,6 +57,7 @@ import org.eclipse.hawkbit.repository.test.util.SecurityContextSwitch; import org.eclipse.hawkbit.repository.test.util.WithUser; import org.eclipse.hawkbit.rest.util.JsonBuilder; import org.eclipse.hawkbit.rest.util.MockMvcResultPrinter; +import org.json.JSONObject; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; @@ -270,6 +272,31 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest { } + @Test + @Description("Testing that rollout can be updated") + void updateRollout() throws Exception { + testdataFactory.createTargets(4, "rollout", "description"); + final DistributionSet dsA = testdataFactory.createDistributionSet(""); + // create a running rollout for the created targets + final Rollout rollout = rolloutManagement.create( + entityFactory + .rollout() + .create() + .name("rollout1") + .distributionSetId(dsA.getId()) + .targetFilterQuery("controllerId==rollout*"), + 4, false, new RolloutGroupConditionBuilder().withDefaults() + .successCondition(RolloutGroupSuccessCondition.THRESHOLD, "100").build()); + + + mvc.perform(put("/rest/v1/rollouts/" + rollout.getId()).content( + new JSONObject().put("name", "newName").put("description", "newDesc").toString() + ).contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + .andExpect(jsonPath("$.name", equalTo("newName"))) + .andExpect(jsonPath("$.description", equalTo("newDesc"))); + } + @Test @Description("Testing the empty list is returned if no rollout exists") void noRolloutReturnsEmptyList() throws Exception { @@ -286,7 +313,7 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest { // create rollout including the created targets with prefix 'rollout' final Rollout rollout = rolloutManagement.create( - entityFactory.rollout().create().name("rollout1").set(dsA.getId()) + entityFactory.rollout().create().name("rollout1").distributionSetId(dsA.getId()) .targetFilterQuery("controllerId==rollout*"), 4, false, new RolloutGroupConditionBuilder().withDefaults() .successCondition(RolloutGroupSuccessCondition.THRESHOLD, "100").build()); @@ -305,7 +332,7 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest { // create a running rollout for the created targets final Rollout rollout = rolloutManagement.create( - entityFactory.rollout().create().name("rollout1").set(dsA.getId()) + entityFactory.rollout().create().name("rollout1").distributionSetId(dsA.getId()) .targetFilterQuery("controllerId==rollout*"), 4, false, new RolloutGroupConditionBuilder().withDefaults() .successCondition(RolloutGroupSuccessCondition.THRESHOLD, "100").build()); @@ -345,13 +372,13 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest { // create a running rollout for the created targets final Rollout rollout = rolloutManagement.create( - entityFactory.rollout().create().name("rollout1").set(dsA.getId()) + entityFactory.rollout().create().name("rollout1").distributionSetId(dsA.getId()) .targetFilterQuery("controllerId==rollout*"), 4, false, new RolloutGroupConditionBuilder().withDefaults() .successCondition(RolloutGroupSuccessCondition.THRESHOLD, "100").build()); rolloutManagement.create( - entityFactory.rollout().create().name("rollout2").set(dsA.getId()) + entityFactory.rollout().create().name("rollout2").distributionSetId(dsA.getId()) .targetFilterQuery("controllerId==rollout*"), 4, false, new RolloutGroupConditionBuilder().withDefaults() .successCondition(RolloutGroupSuccessCondition.THRESHOLD, "100").build()); @@ -399,7 +426,7 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest { .rollout() .create() .name("rollout1") - .set(dsA.getId()) + .distributionSetId(dsA.getId()) .targetFilterQuery("controllerId==rollout*"), 4, false, new RolloutGroupConditionBuilder().withDefaults() .successCondition(RolloutGroupSuccessCondition.THRESHOLD, "100").build()); @@ -431,7 +458,7 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest { // create rollout including the created targets with prefix 'rollout' final Rollout rollout = rolloutManagement.create( - entityFactory.rollout().create().name("rollout1").set(dsA.getId()) + entityFactory.rollout().create().name("rollout1").distributionSetId(dsA.getId()) .targetFilterQuery("controllerId==rollout*"), 4, false, new RolloutGroupConditionBuilder().withDefaults() .successCondition(RolloutGroupSuccessCondition.THRESHOLD, "100").build()); @@ -982,7 +1009,7 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest { // create rollout including the created targets with prefix 'rollout' final Rollout rollout = rolloutManagement.create( - entityFactory.rollout().create().name("rollout1").set(dsA.getId()) + entityFactory.rollout().create().name("rollout1").distributionSetId(dsA.getId()) .targetFilterQuery("controllerId==rollout*"), 4, confirmationRequired, new RolloutGroupConditionBuilder().withDefaults() .successCondition(RolloutGroupSuccessCondition.THRESHOLD, "100").build()); @@ -1328,7 +1355,7 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest { // create a running rollout for the created targets final Rollout rollout = rolloutManagement.create( - entityFactory.rollout().create().name("rollout1").set(dsA.getId()) + entityFactory.rollout().create().name("rollout1").distributionSetId(dsA.getId()) .targetFilterQuery("controllerId==rollout*"), 4, false, new RolloutGroupConditionBuilder().withDefaults() .successCondition(RolloutGroupSuccessCondition.THRESHOLD, "100").build()); @@ -1509,7 +1536,7 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest { private Rollout createRollout(final String name, final int amountGroups, final long distributionSetId, final String targetFilterQuery, final boolean confirmationRequired) { final Rollout rollout = rolloutManagement.create( - entityFactory.rollout().create().name(name).set(distributionSetId).targetFilterQuery(targetFilterQuery), + entityFactory.rollout().create().name(name).distributionSetId(distributionSetId).targetFilterQuery(targetFilterQuery), amountGroups, confirmationRequired, new RolloutGroupConditionBuilder().withDefaults() .successCondition(RolloutGroupSuccessCondition.THRESHOLD, "100").build()); diff --git a/hawkbit-runtime/hawkbit-simple-ui/src/main/java/org/eclipse/hawkbit/ui/simple/view/RolloutView.java b/hawkbit-runtime/hawkbit-simple-ui/src/main/java/org/eclipse/hawkbit/ui/simple/view/RolloutView.java index a24cd6d48..4e377dd34 100644 --- a/hawkbit-runtime/hawkbit-simple-ui/src/main/java/org/eclipse/hawkbit/ui/simple/view/RolloutView.java +++ b/hawkbit-runtime/hawkbit-simple-ui/src/main/java/org/eclipse/hawkbit/ui/simple/view/RolloutView.java @@ -43,7 +43,7 @@ import org.eclipse.hawkbit.mgmt.json.model.distributionset.MgmtDistributionSet; import org.eclipse.hawkbit.mgmt.json.model.rollout.MgmtRolloutCondition; import org.eclipse.hawkbit.mgmt.json.model.rollout.MgmtRolloutErrorAction; import org.eclipse.hawkbit.mgmt.json.model.rollout.MgmtRolloutResponseBody; -import org.eclipse.hawkbit.mgmt.json.model.rollout.MgmtRolloutRestRequestBody; +import org.eclipse.hawkbit.mgmt.json.model.rollout.MgmtRolloutRestRequestBodyPost; import org.eclipse.hawkbit.mgmt.json.model.rolloutgroup.MgmtRolloutGroupResponseBody; import org.eclipse.hawkbit.mgmt.json.model.targetfilter.MgmtTargetFilterQuery; import org.springframework.util.ObjectUtils; @@ -403,7 +403,7 @@ public class RolloutView extends TableView { private void addCreateClickListener(final HawkbitMgmtClient hawkbitClient) { create.addClickListener(e -> { close(); - final MgmtRolloutRestRequestBody request = new MgmtRolloutRestRequestBody(); + final MgmtRolloutRestRequestBodyPost request = new MgmtRolloutRestRequestBodyPost(); request.setName(name.getValue()); request.setDistributionSetId(distributionSet.getValue().getDsId()); request.setTargetFilterQuery(targetFilter.getValue().getQuery());