Fix circular rollout dependencies (#1337)

* Do some refactoring to fix dependencies between rollout management, executor and evaluator beans.
* Move rollout retrieving in same transaction as execution.
* Do some refactoring. Extend logging and exception handling.
* Remove unnecessary transactional and validation annotations.
* remove catching never thrown bean
* Fix new rollout handling API
This commit is contained in:
Michael Herdt
2023-04-03 09:13:00 +02:00
committed by GitHub
parent 17bf633df9
commit fbda9764b1
29 changed files with 537 additions and 352 deletions

View File

@@ -0,0 +1,52 @@
/**
* Copyright (c) 2023 Bosch.IO GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository;
import static org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions;
import org.eclipse.hawkbit.repository.model.Rollout;
import org.eclipse.hawkbit.repository.model.RolloutGroup;
import org.eclipse.hawkbit.repository.model.Target;
import org.springframework.security.access.prepost.PreAuthorize;
/**
* Represents the handler service for creating, deleting, and starting a Rollout
*/
@FunctionalInterface
public interface RolloutHandler {
/**
* Process rollout based on its current {@link Rollout#getStatus()}.
*
* For {@link Rollout.RolloutStatus#CREATING} that means creating the
* {@link RolloutGroup}s with {@link Target}s and when finished switch to
* {@link Rollout.RolloutStatus#READY}.
*
* For {@link Rollout.RolloutStatus#READY} that means switching to
* {@link Rollout.RolloutStatus#STARTING} if the {@link Rollout#getStartAt()} is
* set and time of calling this method is beyond this point in time. This auto
* start mechanism is optional. Call {@link RolloutManagement#start(long)} otherwise.
*
* For {@link Rollout.RolloutStatus#STARTING} that means starting the first
* {@link RolloutGroup}s in line and when finished switch to
* {@link Rollout.RolloutStatus#RUNNING}.
*
* For {@link Rollout.RolloutStatus#RUNNING} that means checking to activate
* further groups based on the defined thresholds. Switched to
* {@link Rollout.RolloutStatus#FINISHED} is all groups are finished.
*
* For {@link Rollout.RolloutStatus#DELETING} that means either soft delete in
* case rollout was already {@link Rollout.RolloutStatus#RUNNING} which results
* in status change {@link Rollout.RolloutStatus#DELETED} or hard delete from
* the persistence otherwise.
*
*/
@PreAuthorize(SpringEvalExpressions.IS_SYSTEM_CODE)
void handleAll();
}

View File

@@ -33,7 +33,6 @@ import org.eclipse.hawkbit.repository.model.RolloutGroup;
import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupStatus;
import org.eclipse.hawkbit.repository.model.RolloutGroupConditions;
import org.eclipse.hawkbit.repository.model.RolloutGroupsValidation;
import org.eclipse.hawkbit.repository.model.Target;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
@@ -48,37 +47,7 @@ import org.springframework.util.concurrent.ListenableFuture;
public interface RolloutManagement {
/**
* Process rollout based on its current {@link Rollout#getStatus()}.
*
* For {@link RolloutStatus#CREATING} that means creating the
* {@link RolloutGroup}s with {@link Target}s and when finished switch to
* {@link RolloutStatus#READY}.
*
* For {@link RolloutStatus#READY} that means switching to
* {@link RolloutStatus#STARTING} if the {@link Rollout#getStartAt()} is set
* and time of calling this method is beyond this point in time. This auto
* start mechanism is optional. Call {@link #start(Long)} otherwise.
*
* For {@link RolloutStatus#STARTING} that means starting the first
* {@link RolloutGroup}s in line and when finished switch to
* {@link RolloutStatus#RUNNING}.
*
* For {@link RolloutStatus#RUNNING} that means checking to activate further
* groups based on the defined thresholds. Switched to
* {@link RolloutStatus#FINISHED} is all groups are finished.
*
* For {@link RolloutStatus#DELETING} that means either soft delete in case
* rollout was already {@link RolloutStatus#RUNNING} which results in status
* change {@link RolloutStatus#DELETED} or hard delete from the persistence
* otherwise.
*
*/
@PreAuthorize(SpringEvalExpressions.IS_SYSTEM_CODE)
void handleRollouts();
/**
* Counts all {@link Rollout}s in the repository that are not marked as
* deleted.
* Counts all {@link Rollout}s in the repository that are not marked as deleted.
*
* @return number of roll outs
*/
@@ -267,6 +236,14 @@ public interface RolloutManagement {
Slice<Rollout> findByFiltersWithDetailedStatus(@NotNull Pageable pageable, @NotEmpty String searchText,
boolean deleted);
/**
* Find rollouts which are still active and needs to be handled.
*
* @return a list of active rollouts
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ)
List<Long> findActiveRollouts();
/**
* Retrieves a specific rollout by its ID.
*

View File

@@ -157,40 +157,14 @@ public interface RolloutGroup extends NamedEntity {
* The condition to evaluate if an group is success state.
*/
enum RolloutGroupSuccessCondition {
THRESHOLD("thresholdRolloutGroupSuccessCondition");
private final String beanName;
RolloutGroupSuccessCondition(final String beanName) {
this.beanName = beanName;
}
/**
* @return the beanName
*/
public String getBeanName() {
return beanName;
}
THRESHOLD
}
/**
* The condition to evaluate if an group is in error state.
*/
enum RolloutGroupErrorCondition {
THRESHOLD("thresholdRolloutGroupErrorCondition");
private final String beanName;
RolloutGroupErrorCondition(final String beanName) {
this.beanName = beanName;
}
/**
* @return the beanName
*/
public String getBeanName() {
return beanName;
}
THRESHOLD
}
/**
@@ -198,20 +172,7 @@ public interface RolloutGroup extends NamedEntity {
* hit.
*/
enum RolloutGroupErrorAction {
PAUSE("pauseRolloutGroupAction");
private final String beanName;
RolloutGroupErrorAction(final String beanName) {
this.beanName = beanName;
}
/**
* @return the beanName
*/
public String getBeanName() {
return beanName;
}
PAUSE
}
/**
@@ -219,19 +180,6 @@ public interface RolloutGroup extends NamedEntity {
* is hit.
*/
enum RolloutGroupSuccessAction {
NEXTGROUP("startNextRolloutGroupAction");
private final String beanName;
RolloutGroupSuccessAction(final String beanName) {
this.beanName = beanName;
}
/**
* @return the beanName
*/
public String getBeanName() {
return beanName;
}
NEXTGROUP
}
}