Remove unused group repo methods (#2263)

Signed-off-by: Avgustin Marinov <Avgustin.Marinov@bosch.com>
This commit is contained in:
Avgustin Marinov
2025-02-04 17:21:04 +02:00
committed by GitHub
parent 4e59c6c8cc
commit 46caed139d
8 changed files with 96 additions and 150 deletions

View File

@@ -286,27 +286,27 @@ public interface TargetManagement {
* that are not assigned to one of the {@link RolloutGroup}s and are compatible * that are not assigned to one of the {@link RolloutGroup}s and are compatible
* with the passed {@link DistributionSetType}. * with the passed {@link DistributionSetType}.
* *
* @param groups the list of {@link RolloutGroup}s
* @param rsqlParam filter definition in RSQL syntax * @param rsqlParam filter definition in RSQL syntax
* @param groups the list of {@link RolloutGroup}s
* @param distributionSetType type of the {@link DistributionSet} the targets must be compatible * @param distributionSetType type of the {@link DistributionSet} the targets must be compatible
* with * with
* @return count of the found {@link Target}s * @return count of the found {@link Target}s
*/ */
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ_AND_TARGET_READ) @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ_AND_TARGET_READ)
long countByRsqlAndNotInRolloutGroupsAndCompatibleAndUpdatable(@NotEmpty Collection<Long> groups, long countByRsqlAndNotInRolloutGroupsAndCompatibleAndUpdatable(@NotNull String rsqlParam, @NotEmpty Collection<Long> groups,
@NotNull String rsqlParam, @NotNull DistributionSetType distributionSetType); @NotNull DistributionSetType distributionSetType);
/** /**
* Counts all targets with failed actions for specific Rollout and that are not * Counts all targets with failed actions for specific Rollout and that are not
* assigned to one of the {@link RolloutGroup}s and are compatible with the * assigned to one of the {@link RolloutGroup}s and are compatible with the
* passed {@link DistributionSetType}. * passed {@link DistributionSetType}.
* *
* @param groups the list of {@link RolloutGroup}s
* @param rolloutId rolloutId of the rollout to be retried. * @param rolloutId rolloutId of the rollout to be retried.
* @param groups the list of {@link RolloutGroup}s
* @return count of the found {@link Target}s * @return count of the found {@link Target}s
*/ */
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ_AND_TARGET_READ) @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ_AND_TARGET_READ)
long countByFailedRolloutAndNotInRolloutGroups(@NotEmpty Collection<Long> groups, @NotNull String rolloutId); long countByFailedRolloutAndNotInRolloutGroups(@NotNull String rolloutId, @NotEmpty Collection<Long> groups);
/** /**
* Finds all targets of the provided {@link RolloutGroup} that have no Action * Finds all targets of the provided {@link RolloutGroup} that have no Action

View File

@@ -137,7 +137,8 @@ public final class RolloutHelper {
*/ */
public static List<Long> getGroupsByStatusIncludingGroup( public static List<Long> getGroupsByStatusIncludingGroup(
final List<RolloutGroup> groups, final RolloutGroup.RolloutGroupStatus status, final RolloutGroup group) { final List<RolloutGroup> groups, final RolloutGroup.RolloutGroupStatus status, final RolloutGroup group) {
return groups.stream().filter(innerGroup -> innerGroup.getStatus() == status || innerGroup.equals(group)) return groups.stream()
.filter(innerGroup -> innerGroup.getStatus() == status || innerGroup.equals(group))
.map(RolloutGroup::getId).toList(); .map(RolloutGroup::getId).toList();
} }
@@ -215,8 +216,8 @@ public final class RolloutHelper {
public static void checkIfRolloutCanStarted(final Rollout rollout, final Rollout mergedRollout) { public static void checkIfRolloutCanStarted(final Rollout rollout, final Rollout mergedRollout) {
if (Rollout.RolloutStatus.READY != mergedRollout.getStatus()) { if (Rollout.RolloutStatus.READY != mergedRollout.getStatus()) {
throw new RolloutIllegalStateException("Rollout can only be started in state ready but current state is " throw new RolloutIllegalStateException("Rollout can only be started in state ready but current state is " +
+ rollout.getStatus().name().toLowerCase()); rollout.getStatus().name().toLowerCase());
} }
} }

View File

@@ -20,7 +20,6 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport; import java.util.stream.StreamSupport;
import jakarta.persistence.EntityManager; import jakarta.persistence.EntityManager;
@@ -166,7 +165,7 @@ public class JpaRolloutExecutor implements RolloutExecutor {
// the lastModifiedBy user is probably the user that has actually called the rollout start (unless overridden) - not the creator // the lastModifiedBy user is probably the user that has actually called the rollout start (unless overridden) - not the creator
SpringSecurityAuditorAware.setAuditorOverride(rollout.getLastModifiedBy()); SpringSecurityAuditorAware.setAuditorOverride(rollout.getLastModifiedBy());
try { try {
handleStartingRollout(rollout); handleStartingRollout((JpaRollout) rollout);
} finally { } finally {
// clear, ALWAYS, the set auditor override // clear, ALWAYS, the set auditor override
SpringSecurityAuditorAware.clearAuditorOverride(); SpringSecurityAuditorAware.clearAuditorOverride();
@@ -219,26 +218,24 @@ public class JpaRolloutExecutor implements RolloutExecutor {
continue; continue;
} }
final RolloutGroup filledGroup = fillRolloutGroupWithTargets(rollout, (JpaRolloutGroup) group, final RolloutGroup filledGroup = fillRolloutGroupWithTargets(rollout, (JpaRolloutGroup) group, rolloutGroups);
rolloutGroups);
if (RolloutGroupStatus.READY == filledGroup.getStatus()) { if (RolloutGroupStatus.READY == filledGroup.getStatus()) {
readyGroups++; readyGroups++;
totalTargets += filledGroup.getTotalTargets(); totalTargets += filledGroup.getTotalTargets();
} }
} }
// When all groups are ready the rollout status can be changed to be // When all groups are ready the rollout status can be changed to be ready, too.
// ready, too.
if (readyGroups == rolloutGroups.size()) { if (readyGroups == rolloutGroups.size()) {
if (rollout.isDynamic() && !rolloutGroups.get(rolloutGroups.size() - 1).isDynamic()) { if (rollout.isDynamic() && !rolloutGroups.get(rolloutGroups.size() - 1).isDynamic()) {
// add first dynamic group one by using the last as a parent and as a pattern // add first dynamic group one by using the last as a parent and as a pattern
createDynamicGroup(rollout, (JpaRolloutGroup) rolloutGroups.get(rolloutGroups.size() - 1), rolloutGroups.size(), createDynamicGroup(
RolloutGroupStatus.READY); rollout, (JpaRolloutGroup) rolloutGroups.get(rolloutGroups.size() - 1), rolloutGroups.size(), RolloutGroupStatus.READY);
} }
if (!rolloutApprovalStrategy.isApprovalNeeded(rollout)) { if (!rolloutApprovalStrategy.isApprovalNeeded(rollout)) {
rollout.setStatus(RolloutStatus.READY);
log.debug("rollout {} creation done. Switch to READY.", rollout.getId()); log.debug("rollout {} creation done. Switch to READY.", rollout.getId());
rollout.setStatus(RolloutStatus.READY);
} else { } else {
log.debug("rollout {} creation done. Switch to WAITING_FOR_APPROVAL.", rollout.getId()); log.debug("rollout {} creation done. Switch to WAITING_FOR_APPROVAL.", rollout.getId());
rollout.setStatus(RolloutStatus.WAITING_FOR_APPROVAL); rollout.setStatus(RolloutStatus.WAITING_FOR_APPROVAL);
@@ -325,18 +322,20 @@ public class JpaRolloutExecutor implements RolloutExecutor {
private void handleReadyRollout(final Rollout rollout) { private void handleReadyRollout(final Rollout rollout) {
if (rollout.getStartAt() != null && rollout.getStartAt() <= System.currentTimeMillis()) { if (rollout.getStartAt() != null && rollout.getStartAt() <= System.currentTimeMillis()) {
log.debug( log.debug("handleReadyRollout called for rollout {} with autostart beyond define time. Switch to STARTING", rollout.getId());
"handleReadyRollout called for rollout {} with autostart beyond define time. Switch to STARTING",
rollout.getId());
rolloutManagement.start(rollout.getId()); rolloutManagement.start(rollout.getId());
} }
} }
private void handleStartingRollout(final Rollout rollout) { private void handleStartingRollout(final JpaRollout rollout) {
log.debug("handleStartingRollout called for rollout {}", rollout.getId()); log.debug("handleStartingRollout called for rollout {}", rollout.getId());
if (ensureAllGroupsAreScheduled(rollout)) { if (ensureAllGroupsAreScheduled(rollout)) {
startFirstRolloutGroup(rollout); startFirstRolloutGroup(rollout);
rollout.setStatus(RolloutStatus.RUNNING);
rollout.setLastCheck(0);
rolloutRepository.save(rollout);
} }
} }
@@ -348,8 +347,7 @@ public class JpaRolloutExecutor implements RolloutExecutor {
return; return;
} }
final List<JpaRolloutGroup> runningGroups = final List<JpaRolloutGroup> runningGroups = rollout.getRolloutGroups().stream()
rollout.getRolloutGroups().stream()
.filter(group -> group.getStatus() == RolloutGroupStatus.RUNNING) .filter(group -> group.getStatus() == RolloutGroupStatus.RUNNING)
.map(JpaRolloutGroup.class::cast) .map(JpaRolloutGroup.class::cast)
.toList(); .toList();
@@ -413,7 +411,6 @@ public class JpaRolloutExecutor implements RolloutExecutor {
} }
private void executeLatestRolloutGroup(final JpaRollout rollout) { private void executeLatestRolloutGroup(final JpaRollout rollout) {
// was - rolloutGroupRepository.findByRolloutAndStatusNotOrderByIdDesc(rollout, RolloutGroupStatus.SCHEDULED);
final List<JpaRolloutGroup> latestRolloutGroup = rollout.getRolloutGroups().stream() final List<JpaRolloutGroup> latestRolloutGroup = rollout.getRolloutGroups().stream()
.filter(group -> group.getStatus() != RolloutGroupStatus.SCHEDULED) .filter(group -> group.getStatus() != RolloutGroupStatus.SCHEDULED)
.sorted(DESC_COMP) .sorted(DESC_COMP)
@@ -548,60 +545,56 @@ public class JpaRolloutExecutor implements RolloutExecutor {
evaluationManager.getSuccessActionEvaluator(rolloutGroup.getSuccessAction()).exec(rollout, rolloutGroup); evaluationManager.getSuccessActionEvaluator(rolloutGroup.getSuccessAction()).exec(rollout, rolloutGroup);
} }
private void startFirstRolloutGroup(final Rollout rollout) { private void startFirstRolloutGroup(final JpaRollout rollout) {
log.debug("startFirstRolloutGroup called for rollout {}", rollout.getId()); log.debug("startFirstRolloutGroup called for rollout {}", rollout.getId());
RolloutHelper.verifyRolloutInStatus(rollout, RolloutStatus.STARTING); RolloutHelper.verifyRolloutInStatus(rollout, RolloutStatus.STARTING);
final JpaRollout jpaRollout = (JpaRollout) rollout;
final List<JpaRolloutGroup> rolloutGroups = rolloutGroupRepository.findByRolloutOrderByIdAsc(jpaRollout); final List<JpaRolloutGroup> rolloutGroups = rolloutGroupRepository.findByRolloutOrderByIdAsc(rollout);
final JpaRolloutGroup rolloutGroup = rolloutGroups.get(0); final JpaRolloutGroup rolloutGroup = rolloutGroups.get(0);
if (rolloutGroup.getParent() != null) { if (rolloutGroup.getParent() != null) {
throw new RolloutIllegalStateException("First Group is not the first group."); throw new RolloutIllegalStateException("First found group is not the first group (has a parent).");
} }
deploymentManagement.startScheduledActionsByRolloutGroupParent(rollout.getId(), deploymentManagement.startScheduledActionsByRolloutGroupParent(
rollout.getDistributionSet().getId(), null); rollout.getId(), rollout.getDistributionSet().getId(), null);
rolloutGroup.setStatus(RolloutGroupStatus.RUNNING); rolloutGroup.setStatus(RolloutGroupStatus.RUNNING);
rolloutGroupRepository.save(rolloutGroup); rolloutGroupRepository.save(rolloutGroup);
jpaRollout.setStatus(RolloutStatus.RUNNING);
jpaRollout.setLastCheck(0);
rolloutRepository.save(jpaRollout);
} }
private boolean ensureAllGroupsAreScheduled(final Rollout rollout) { private boolean ensureAllGroupsAreScheduled(final Rollout rollout) {
final JpaRollout jpaRollout = (JpaRollout) rollout;
final List<JpaRolloutGroup> groupsToBeScheduled = rolloutGroupRepository.findByRolloutAndStatus(rollout, RolloutGroupStatus.READY); final List<JpaRolloutGroup> groupsToBeScheduled = rolloutGroupRepository.findByRolloutAndStatus(rollout, RolloutGroupStatus.READY);
if (groupsToBeScheduled.isEmpty()) { if (groupsToBeScheduled.isEmpty()) {
return true; return true;
} }
final long scheduledGroups = groupsToBeScheduled.stream().filter(group -> scheduleRolloutGroup(jpaRollout, group)).count();
final long scheduledGroups = groupsToBeScheduled.stream().filter(group -> scheduleRolloutGroup((JpaRollout) rollout, group)).count();
entityManager.flush(); // flush groups so scheduled group to start to have scheduled event entityManager.flush(); // flush groups so scheduled group to start to have scheduled event
return scheduledGroups == groupsToBeScheduled.size(); return scheduledGroups == groupsToBeScheduled.size();
} }
private JpaRolloutGroup fillRolloutGroupWithTargets(final JpaRollout rollout, final JpaRolloutGroup group, private JpaRolloutGroup fillRolloutGroupWithTargets(
final List<RolloutGroup> rolloutGroups) { final JpaRollout rollout, final JpaRolloutGroup group, final List<RolloutGroup> rolloutGroups) {
// TODO - is that needed? in execute already has been checked that it is in CREATING
// if it has been paused/deleted meanwhile - no problem, anyway - couldn't be prevented race condition
RolloutHelper.verifyRolloutInStatus(rollout, RolloutStatus.CREATING); RolloutHelper.verifyRolloutInStatus(rollout, RolloutStatus.CREATING);
final String groupTargetFilter = RolloutHelper.getGroupTargetFilter( final String groupTargetFilter = RolloutHelper.getGroupTargetFilter(RolloutHelper.getTargetFilterQuery(rollout), group);
RolloutHelper.getTargetFilterQuery(rollout), group);
final List<Long> readyGroups = RolloutHelper.getGroupsByStatusIncludingGroup(rollout.getRolloutGroups(), final List<Long> readyGroups = RolloutHelper.getGroupsByStatusIncludingGroup(
RolloutGroupStatus.READY, group); rollout.getRolloutGroups(), RolloutGroupStatus.READY, group);
long targetsInGroupFilter; final long targetsInGroupFilter;
if (!RolloutHelper.isRolloutRetried(rollout.getTargetFilterQuery())) { if (!RolloutHelper.isRolloutRetried(rollout.getTargetFilterQuery())) { // default case
targetsInGroupFilter = DeploymentHelper.runInNewTransaction(txManager, targetsInGroupFilter = DeploymentHelper.runInNewTransaction(txManager,
"countAllTargetsByTargetFilterQueryAndNotInRolloutGroups", "countByRsqlAndNotInRolloutGroupsAndCompatibleAndUpdatable",
count -> targetManagement.countByRsqlAndNotInRolloutGroupsAndCompatibleAndUpdatable(readyGroups, count -> targetManagement.countByRsqlAndNotInRolloutGroupsAndCompatibleAndUpdatable(
groupTargetFilter, rollout.getDistributionSet().getType())); groupTargetFilter, readyGroups, rollout.getDistributionSet().getType()));
} else { } else { // if it is a rollout retry
targetsInGroupFilter = DeploymentHelper.runInNewTransaction(txManager, targetsInGroupFilter = DeploymentHelper.runInNewTransaction(txManager,
"countByFailedRolloutAndNotInRolloutGroupsAndCompatible", "countByFailedRolloutAndNotInRolloutGroupsAndCompatible",
count -> targetManagement.countByFailedRolloutAndNotInRolloutGroups(readyGroups, count -> targetManagement.countByFailedRolloutAndNotInRolloutGroups(
RolloutHelper.getIdFromRetriedTargetFilter(rollout.getTargetFilterQuery()))); RolloutHelper.getIdFromRetriedTargetFilter(rollout.getTargetFilterQuery()), readyGroups));
} }
final double percentFromTheRest; final double percentFromTheRest;
@@ -616,7 +609,7 @@ public class JpaRolloutExecutor implements RolloutExecutor {
"countRolloutTargetGroupByRolloutGroup", "countRolloutTargetGroupByRolloutGroup",
count -> rolloutTargetGroupRepository.countByRolloutGroup(group)); count -> rolloutTargetGroupRepository.countByRolloutGroup(group));
// Switch the Group status to READY, when there are enough Targets in the Group // if there are enough Targets in the group, switch the group status to READY,
if (currentlyInGroup >= expectedInGroup) { if (currentlyInGroup >= expectedInGroup) {
group.setStatus(RolloutGroupStatus.READY); group.setStatus(RolloutGroupStatus.READY);
return rolloutGroupRepository.save(group); return rolloutGroupRepository.save(group);
@@ -624,10 +617,8 @@ public class JpaRolloutExecutor implements RolloutExecutor {
try { try {
long targetsLeftToAdd = expectedInGroup - currentlyInGroup; long targetsLeftToAdd = expectedInGroup - currentlyInGroup;
do { do {
// Add up to TRANSACTION_TARGETS of the left targets // Add up to TRANSACTION_TARGETS of the left targets. In case a TransactionException is thrown this loop aborts
// In case a TransactionException is thrown this loop aborts
final long assigned = assignTargetsToGroupInNewTransaction( final long assigned = assignTargetsToGroupInNewTransaction(
rollout, group, groupTargetFilter, Math.min(TRANSACTION_TARGETS, targetsLeftToAdd)); rollout, group, groupTargetFilter, Math.min(TRANSACTION_TARGETS, targetsLeftToAdd));
if (assigned == 0) { if (assigned == 0) {
@@ -638,24 +629,23 @@ public class JpaRolloutExecutor implements RolloutExecutor {
} while (targetsLeftToAdd > 0); } while (targetsLeftToAdd > 0);
group.setStatus(RolloutGroupStatus.READY); group.setStatus(RolloutGroupStatus.READY);
group.setTotalTargets( group.setTotalTargets(DeploymentHelper.runInNewTransaction(txManager,
DeploymentHelper.runInNewTransaction(txManager, "countRolloutTargetGroupByRolloutGroup", "countRolloutTargetGroupByRolloutGroup",
count -> rolloutTargetGroupRepository.countByRolloutGroup(group)).intValue()); count -> rolloutTargetGroupRepository.countByRolloutGroup(group)).intValue());
return rolloutGroupRepository.save(group); return rolloutGroupRepository.save(group);
} catch (final TransactionException e) { } catch (final TransactionException e) {
log.warn(TRANSACTION_ASSIGNING_TARGETS_TO_ROLLOUT_GROUP_FAILED, e); log.warn(TRANSACTION_ASSIGNING_TARGETS_TO_ROLLOUT_GROUP_FAILED, e);
return group; return group;
} }
} }
private Long assignTargetsToGroupInNewTransaction(final JpaRollout rollout, final RolloutGroup group, private Long assignTargetsToGroupInNewTransaction(
final String targetFilter, final long limit) { final JpaRollout rollout, final RolloutGroup group, final String targetFilter, final long limit) {
return DeploymentHelper.runInNewTransaction(txManager, "assignTargetsToRolloutGroup", status -> { return DeploymentHelper.runInNewTransaction(txManager, "assignTargetsToRolloutGroup", status -> {
final PageRequest pageRequest = PageRequest.of(0, Math.toIntExact(limit)); final PageRequest pageRequest = PageRequest.of(0, Math.toIntExact(limit));
final List<Long> readyGroups = RolloutHelper.getGroupsByStatusIncludingGroup(rollout.getRolloutGroups(), final List<Long> readyGroups = RolloutHelper.getGroupsByStatusIncludingGroup(
RolloutGroupStatus.READY, group); rollout.getRolloutGroups(), RolloutGroupStatus.READY, group);
Slice<Target> targets; final Slice<Target> targets;
if (!RolloutHelper.isRolloutRetried(rollout.getTargetFilterQuery())) { if (!RolloutHelper.isRolloutRetried(rollout.getTargetFilterQuery())) {
targets = targetManagement.findByTargetFilterQueryAndNotInRolloutGroupsAndCompatibleAndUpdatable( targets = targetManagement.findByTargetFilterQueryAndNotInRolloutGroupsAndCompatibleAndUpdatable(
pageRequest, readyGroups, targetFilter, rollout.getDistributionSet().getType()); pageRequest, readyGroups, targetFilter, rollout.getDistributionSet().getType());
@@ -664,7 +654,7 @@ public class JpaRolloutExecutor implements RolloutExecutor {
pageRequest, readyGroups, RolloutHelper.getIdFromRetriedTargetFilter(rollout.getTargetFilterQuery())); pageRequest, readyGroups, RolloutHelper.getIdFromRetriedTargetFilter(rollout.getTargetFilterQuery()));
} }
createAssignmentOfTargetsToGroup(targets, group); rolloutTargetGroupRepository.saveAll(targets.stream().map(target -> new RolloutTargetGroup(group, target)).toList());
return Long.valueOf(targets.getNumberOfElements()); return Long.valueOf(targets.getNumberOfElements());
}); });
@@ -831,7 +821,7 @@ public class JpaRolloutExecutor implements RolloutExecutor {
try { try {
long actionsCreated; long actionsCreated;
do { do {
actionsCreated = createActionsForTargetsInNewTransaction(rollout, group, TRANSACTION_TARGETS); actionsCreated = createActionsForTargetsInNewTransaction(rollout, group);
totalActionsCreated += actionsCreated; totalActionsCreated += actionsCreated;
} while (actionsCreated > 0); } while (actionsCreated > 0);
@@ -842,9 +832,10 @@ public class JpaRolloutExecutor implements RolloutExecutor {
return totalActionsCreated; return totalActionsCreated;
} }
private Long createActionsForTargetsInNewTransaction(final Rollout rollout, final RolloutGroup group, final int limit) { private Long createActionsForTargetsInNewTransaction(final Rollout rollout, final RolloutGroup group) {
return DeploymentHelper.runInNewTransaction(txManager, "createActionsForTargets", status -> { return DeploymentHelper.runInNewTransaction(txManager, "createActionsForTargets", status -> {
final Slice<Target> targets = targetManagement.findByInRolloutGroupWithoutAction(PageRequest.of(0, limit), group.getId()); final Slice<Target> targets = targetManagement.findByInRolloutGroupWithoutAction(
PageRequest.of(0, JpaRolloutExecutor.TRANSACTION_TARGETS), group.getId());
if (targets.getNumberOfElements() > 0) { if (targets.getNumberOfElements() > 0) {
final DistributionSet distributionSet = rollout.getDistributionSet(); final DistributionSet distributionSet = rollout.getDistributionSet();
@@ -858,10 +849,6 @@ public class JpaRolloutExecutor implements RolloutExecutor {
}); });
} }
private void createAssignmentOfTargetsToGroup(final Slice<Target> targets, final RolloutGroup group) {
targets.forEach(target -> rolloutTargetGroupRepository.save(new RolloutTargetGroup(group, target)));
}
/** /**
* Creates an action entry into the action repository. In case of existing scheduled actions the scheduled actions gets canceled. * Creates an action entry into the action repository. In case of existing scheduled actions the scheduled actions gets canceled.
* A scheduled action is created in-active for static and running for dynamic groups. * A scheduled action is created in-active for static and running for dynamic groups.

View File

@@ -336,14 +336,12 @@ public class JpaRolloutManagement implements RolloutManagement {
public void pauseRollout(final long rolloutId) { public void pauseRollout(final long rolloutId) {
final JpaRollout rollout = getRolloutOrThrowExceptionIfNotFound(rolloutId); final JpaRollout rollout = getRolloutOrThrowExceptionIfNotFound(rolloutId);
if (RolloutStatus.RUNNING != rollout.getStatus()) { if (RolloutStatus.RUNNING != rollout.getStatus()) {
throw new RolloutIllegalStateException("Rollout can only be paused in state running but current state is " throw new RolloutIllegalStateException("Rollout can only be paused in state running but current state is " +
+ rollout.getStatus().name().toLowerCase()); rollout.getStatus().name().toLowerCase());
} }
// setting the complete rollout only in paused state. This is sufficient // setting the complete rollout only in paused state. This is sufficient due the currently running groups will be completed and
// due the currently running groups will be completed and new groups are // new groups are not started until rollout goes back to running state again. The periodically check for running rollouts will skip
// not started until rollout goes back to running state again. The // rollouts in pause state.
// periodically check for running rollouts will skip rollouts in pause
// state.
rollout.setStatus(RolloutStatus.PAUSED); rollout.setStatus(RolloutStatus.PAUSED);
rolloutRepository.save(rollout); rolloutRepository.save(rollout);
} }
@@ -355,8 +353,8 @@ public class JpaRolloutManagement implements RolloutManagement {
public void resumeRollout(final long rolloutId) { public void resumeRollout(final long rolloutId) {
final JpaRollout rollout = getRolloutOrThrowExceptionIfNotFound(rolloutId); final JpaRollout rollout = getRolloutOrThrowExceptionIfNotFound(rolloutId);
if (RolloutStatus.PAUSED != rollout.getStatus()) { if (RolloutStatus.PAUSED != rollout.getStatus()) {
throw new RolloutIllegalStateException("Rollout can only be resumed in state paused but current state is " throw new RolloutIllegalStateException("Rollout can only be resumed in state paused but current state is " +
+ rollout.getStatus().name().toLowerCase()); rollout.getStatus().name().toLowerCase());
} }
rollout.setStatus(RolloutStatus.RUNNING); rollout.setStatus(RolloutStatus.RUNNING);
rolloutRepository.save(rollout); rolloutRepository.save(rollout);

View File

@@ -338,8 +338,8 @@ public class JpaTargetManagement implements TargetManagement {
} }
@Override @Override
public long countByRsqlAndNotInRolloutGroupsAndCompatibleAndUpdatable(final Collection<Long> groups, public long countByRsqlAndNotInRolloutGroupsAndCompatibleAndUpdatable(final String targetFilterQuery, final Collection<Long> groups,
final String targetFilterQuery, final DistributionSetType dsType) { final DistributionSetType dsType) {
return targetRepository.count(AccessController.Operation.UPDATE, return targetRepository.count(AccessController.Operation.UPDATE,
combineWithAnd(List.of( combineWithAnd(List.of(
RSQLUtility.buildRsqlSpecification(targetFilterQuery, TargetFields.class, RSQLUtility.buildRsqlSpecification(targetFilterQuery, TargetFields.class,
@@ -349,7 +349,7 @@ public class JpaTargetManagement implements TargetManagement {
} }
@Override @Override
public long countByFailedRolloutAndNotInRolloutGroups(Collection<Long> groups, String rolloutId) { public long countByFailedRolloutAndNotInRolloutGroups(String rolloutId, Collection<Long> groups) {
final List<Specification<JpaTarget>> specList = Arrays.asList( final List<Specification<JpaTarget>> specList = Arrays.asList(
TargetSpecifications.failedActionsForRollout(rolloutId), TargetSpecifications.failedActionsForRollout(rolloutId),
TargetSpecifications.isNotInRolloutGroups(groups)); TargetSpecifications.isNotInRolloutGroups(groups));

View File

@@ -28,12 +28,10 @@ import org.springframework.transaction.annotation.Transactional;
* The repository interface for the {@link RolloutGroup} model. * The repository interface for the {@link RolloutGroup} model.
*/ */
@Transactional(readOnly = true) @Transactional(readOnly = true)
public interface RolloutGroupRepository public interface RolloutGroupRepository extends BaseEntityRepository<JpaRolloutGroup> {
extends BaseEntityRepository<JpaRolloutGroup> {
/** /**
* Retrieves all {@link RolloutGroup} referring a specific rollout in the * Retrieves all {@link RolloutGroup} referring a specific rollout in the order of creating them. ID ASC.
* order of creating them. ID ASC.
* *
* @param rollout the rollout the rolloutgroups belong to * @param rollout the rollout the rolloutgroups belong to
* @return the rollout groups belonging to a rollout ordered by ID ASC. * @return the rollout groups belonging to a rollout ordered by ID ASC.
@@ -41,8 +39,7 @@ public interface RolloutGroupRepository
List<JpaRolloutGroup> findByRolloutOrderByIdAsc(JpaRollout rollout); List<JpaRolloutGroup> findByRolloutOrderByIdAsc(JpaRollout rollout);
/** /**
* Retrieves all {@link RolloutGroup} referring a specific rollout in a * Retrieves all {@link RolloutGroup} referring a specific rollout in a specific {@link RolloutGroupStatus}.
* specific {@link RolloutGroupStatus}.
* *
* @param rollout the rollout the rolloutgroup belong to * @param rollout the rollout the rolloutgroup belong to
* @param status the status of the rollout groups * @param status the status of the rollout groups
@@ -51,54 +48,17 @@ public interface RolloutGroupRepository
List<JpaRolloutGroup> findByRolloutAndStatus(Rollout rollout, RolloutGroupStatus status); List<JpaRolloutGroup> findByRolloutAndStatus(Rollout rollout, RolloutGroupStatus status);
/** /**
* Counts all {@link RolloutGroup} referring a specific rollout in specific * Retrieves all {@link RolloutGroup} for a specific parent in a specific status. Retrieves the child rolloutgroup for a specific status.
* {@link RolloutGroupStatus}s. An in-clause statement does not work with
* the spring-data, so this is specific usecase regarding to the
* rollout-management to find out rolloutgroups which are in specific
* states.
*
* @param rolloutId the ID of the rollout the rolloutgroup belong to
* @param rolloutGroupStatus1 the status of the rollout groups
* @param rolloutGroupStatus2 the status of the rollout groups
* @return the count of rollout groups belonging to a rollout in specific
* status
*/
@Query("SELECT COUNT(r.id) FROM JpaRolloutGroup r WHERE r.rollout.id = :rolloutId and (r.status = :status1 or r.status = :status2)")
Long countByRolloutIdAndStatusOrStatus(@Param("rolloutId") long rolloutId,
@Param("status1") RolloutGroupStatus rolloutGroupStatus1,
@Param("status2") RolloutGroupStatus rolloutGroupStatus2);
/**
* Counts all rollout-groups refering to a given {@link Rollout} by its ID
* and groups which not having the given status.
*
* @param rolloutId the ID of the rollout refering the groups
* @param status1 the status which the groups should not have
* @param status2 the status which the groups should not have
* @param status2 the status which the groups should not have
* @return count of rollout-groups referning a rollout and not in the given
* states
*/
long countByRolloutIdAndStatusNotAndStatusNotAndStatusNot(@Param("rolloutId") long rolloutId,
@Param("status1") RolloutGroup.RolloutGroupStatus status1,
@Param("status2") RolloutGroup.RolloutGroupStatus status2,
@Param("status3") RolloutGroup.RolloutGroupStatus status3);
/**
* Retrieves all {@link RolloutGroup} for a specific parent in a specific
* status. Retrieves the child rolloutgroup for a specific status.
* *
* @param rolloutGroupId the rolloutgroupId to find the parents * @param rolloutGroupId the rolloutgroupId to find the parents
* @param status the status of the rolloutgroups * @param status the status of the rolloutgroups
* @return The child {@link RolloutGroup}s in a specific status * @return The child {@link RolloutGroup}s in a specific status
*/ */
@Query("SELECT g FROM JpaRolloutGroup g WHERE g.parent.id=:rolloutGroupId and g.status=:status") @Query("SELECT g FROM JpaRolloutGroup g WHERE g.parent.id=:rolloutGroupId and g.status=:status")
List<JpaRolloutGroup> findByParentIdAndStatus(@Param("rolloutGroupId") long rolloutGroupId, List<JpaRolloutGroup> findByParentIdAndStatus(@Param("rolloutGroupId") long rolloutGroupId, @Param("status") RolloutGroupStatus status);
@Param("status") RolloutGroupStatus status);
/** /**
* Updates all {@link RolloutGroup#getStatus()} of children for given * Updates all {@link RolloutGroup#getStatus()} of children for given parent.
* parent.
* *
* @param parent the parent rolloutgroup * @param parent the parent rolloutgroup
* @param status the status of the rolloutgroups * @param status the status of the rolloutgroups
@@ -109,24 +69,11 @@ public interface RolloutGroupRepository
void setStatusForChildren(@Param("status") RolloutGroupStatus status, @Param("parent") RolloutGroup parent); void setStatusForChildren(@Param("status") RolloutGroupStatus status, @Param("parent") RolloutGroup parent);
/** /**
* Retrieves all {@link RolloutGroup} for a specific rollout and status not * Retrieves all {@link RolloutGroup}s for a specific rollout and status not having.
* having ordered by ID DESC, latest top.
*
* @param rollout the rollout the rolloutgroup belong to
* @param notStatus the status which the rolloutgroup should not have
* @return rolloutgroup referring to a rollout and not having a specific
* status ordered by ID DESC.
*/
List<JpaRolloutGroup> findByRolloutAndStatusNotOrderByIdDesc(JpaRollout rollout, RolloutGroupStatus notStatus);
/**
* Retrieves all {@link RolloutGroup}s for a specific rollout and status not
* having.
* *
* @param rollout the rollout the rolloutgroup belong to * @param rollout the rollout the rolloutgroup belong to
* @param status the status which the rolloutgroup should not have * @param status the status which the rolloutgroup should not have
* @return rolloutgroup referring to a rollout and not having a specific * @return rolloutgroup referring to a rollout and not having a specific status.
* status.
*/ */
List<JpaRolloutGroup> findByRolloutAndStatusNotIn(JpaRollout rollout, Collection<RolloutGroupStatus> status); List<JpaRolloutGroup> findByRolloutAndStatusNotIn(JpaRollout rollout, Collection<RolloutGroupStatus> status);
@@ -147,7 +94,19 @@ public interface RolloutGroupRepository
*/ */
long countByRolloutId(Long rolloutId); long countByRolloutId(Long rolloutId);
@Modifying /**
@Query("DELETE FROM JpaRolloutGroup g where g.id in :rolloutGroupIds") * Counts all {@link RolloutGroup} referring a specific rollout in specific {@link RolloutGroupStatus}s. An in-clause statement
void deleteByIds(@Param("rolloutGroupIds") List<Long> rolloutGroups); * does not work with the spring-data, so this is specific usecase regarding the rollout-management to find out rolloutgroups which are
} * in specific states.
*
* @param rolloutId the ID of the rollout the rolloutgroup belong to
* @param rolloutGroupStatus1 the status of the rollout groups
* @param rolloutGroupStatus2 the status of the rollout groups
* @return the count of rollout groups belonging to a rollout in specific status
*/
@Query("SELECT COUNT(r.id) FROM JpaRolloutGroup r WHERE r.rollout.id = :rolloutId and (r.status = :status1 or r.status = :status2)")
Long countByRolloutIdAndStatusOrStatus(
@Param("rolloutId") long rolloutId,
@Param("status1") RolloutGroupStatus rolloutGroupStatus1,
@Param("status2") RolloutGroupStatus rolloutGroupStatus2);
}

View File

@@ -163,7 +163,7 @@ class TargetManagementSecurityTest extends AbstractJpaIntegrationTest {
@Test @Test
@Description("Tests ManagementAPI PreAuthorized method with correct and insufficient permissions.") @Description("Tests ManagementAPI PreAuthorized method with correct and insufficient permissions.")
void countByRsqlAndNotInRolloutGroupsAndCompatibleAndUpdatablePermissionsCheck() { void countByRsqlAndNotInRolloutGroupsAndCompatibleAndUpdatablePermissionsCheck() {
assertPermissions(() -> targetManagement.countByRsqlAndNotInRolloutGroupsAndCompatibleAndUpdatable(List.of(1L), "controllerId==id", assertPermissions(() -> targetManagement.countByRsqlAndNotInRolloutGroupsAndCompatibleAndUpdatable("controllerId==id", List.of(1L),
entityFactory.distributionSetType().create().build()), List.of(SpPermission.READ_TARGET, SpPermission.READ_ROLLOUT)); entityFactory.distributionSetType().create().build()), List.of(SpPermission.READ_TARGET, SpPermission.READ_ROLLOUT));
} }
@@ -177,7 +177,7 @@ class TargetManagementSecurityTest extends AbstractJpaIntegrationTest {
@Test @Test
@Description("Tests ManagementAPI PreAuthorized method with correct and insufficient permissions.") @Description("Tests ManagementAPI PreAuthorized method with correct and insufficient permissions.")
void countByFailedRolloutAndNotInRolloutGroupsPermissionsCheck() { void countByFailedRolloutAndNotInRolloutGroupsPermissionsCheck() {
assertPermissions(() -> targetManagement.countByFailedRolloutAndNotInRolloutGroups(List.of(1L), "1"), assertPermissions(() -> targetManagement.countByFailedRolloutAndNotInRolloutGroups("1", List.of(1L)),
List.of(SpPermission.READ_TARGET, SpPermission.READ_ROLLOUT)); List.of(SpPermission.READ_TARGET, SpPermission.READ_ROLLOUT));
} }

View File

@@ -1,2 +1,3 @@
frontend frontend
bundles bundles
package-lock.json