Signed-off-by: Marinov Avgustin <Avgustin.Marinov@bosch.com>
This commit is contained in:
@@ -329,10 +329,11 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl
|
||||
}
|
||||
|
||||
private DistributionSetAssignmentResult assignDistributionSetToTargetsWithRetry(final String initiatedBy,
|
||||
final Long dsID, final Collection<TargetWithActionType> targetsWithActionType, final String actionMessage,
|
||||
final Long dsId, final Collection<TargetWithActionType> targetsWithActionType, final String actionMessage,
|
||||
final AbstractDsAssignmentStrategy assignmentStrategy) {
|
||||
final RetryCallback<DistributionSetAssignmentResult, ConcurrencyFailureException> retryCallback = retryContext -> assignDistributionSetToTargets(
|
||||
initiatedBy, dsID, targetsWithActionType, actionMessage, assignmentStrategy);
|
||||
final RetryCallback<DistributionSetAssignmentResult, ConcurrencyFailureException> retryCallback =
|
||||
retryContext -> assignDistributionSetToTargets(
|
||||
initiatedBy, dsId, targetsWithActionType, actionMessage, assignmentStrategy);
|
||||
return retryTemplate.execute(retryCallback);
|
||||
}
|
||||
|
||||
@@ -351,7 +352,7 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl
|
||||
*
|
||||
* @param initiatedBy
|
||||
* the username of the user who initiated the assignment
|
||||
* @param dsID
|
||||
* @param dsId
|
||||
* the ID of the distribution set to assign
|
||||
* @param targetsWithActionType
|
||||
* a list of all targets and their action type
|
||||
@@ -365,12 +366,20 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl
|
||||
* if mandatory {@link SoftwareModuleType} are not assigned as
|
||||
* define by the {@link DistributionSetType}.
|
||||
*/
|
||||
private DistributionSetAssignmentResult assignDistributionSetToTargets(final String initiatedBy, final Long dsID,
|
||||
private DistributionSetAssignmentResult assignDistributionSetToTargets(final String initiatedBy, final Long dsId,
|
||||
final Collection<TargetWithActionType> targetsWithActionType, final String actionMessage,
|
||||
final AbstractDsAssignmentStrategy assignmentStrategy) {
|
||||
final JpaDistributionSet distributionSet =
|
||||
(JpaDistributionSet) distributionSetManagement.getValidAndComplete(dsId);
|
||||
// implicit lock
|
||||
if (!distributionSet.isLocked()) {
|
||||
// without new transaction DS changed event is not thrown
|
||||
DeploymentHelper.runInNewTransaction(txManager, "Implicit lock", status -> {
|
||||
distributionSetManagement.lock(distributionSet.getId());
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
final JpaDistributionSet distributionSetEntity = (JpaDistributionSet) distributionSetManagement
|
||||
.getValidAndComplete(dsID);
|
||||
final List<String> providedTargetIds = targetsWithActionType.stream().map(TargetWithActionType::getControllerId)
|
||||
.distinct().toList();
|
||||
|
||||
@@ -381,19 +390,19 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl
|
||||
.flatMap(List::stream).map(JpaTarget::getControllerId).toList();
|
||||
|
||||
final List<JpaTarget> targetEntities = assignmentStrategy.findTargetsForAssignment(existingTargetIds,
|
||||
distributionSetEntity.getId());
|
||||
distributionSet.getId());
|
||||
|
||||
if (targetEntities.isEmpty()) {
|
||||
return allTargetsAlreadyAssignedResult(distributionSetEntity, existingTargetIds.size());
|
||||
return allTargetsAlreadyAssignedResult(distributionSet, existingTargetIds.size());
|
||||
}
|
||||
|
||||
final List<TargetWithActionType> existingTargetsWithActionType = targetsWithActionType.stream()
|
||||
.filter(target -> existingTargetIds.contains(target.getControllerId())).toList();
|
||||
|
||||
final List<JpaAction> assignedActions = doAssignDistributionSetToTargets(initiatedBy,
|
||||
existingTargetsWithActionType, actionMessage, assignmentStrategy, distributionSetEntity,
|
||||
existingTargetsWithActionType, actionMessage, assignmentStrategy, distributionSet,
|
||||
targetEntities);
|
||||
return buildAssignmentResult(distributionSetEntity, assignedActions, existingTargetsWithActionType.size());
|
||||
return buildAssignmentResult(distributionSet, assignedActions, existingTargetsWithActionType.size());
|
||||
}
|
||||
|
||||
private DistributionSetAssignmentResult allTargetsAlreadyAssignedResult(
|
||||
|
||||
@@ -20,6 +20,7 @@ import org.eclipse.hawkbit.repository.DistributionSetManagement;
|
||||
import org.eclipse.hawkbit.repository.RepositoryProperties;
|
||||
import org.eclipse.hawkbit.repository.RolloutManagement;
|
||||
import org.eclipse.hawkbit.repository.TargetFilterQueryManagement;
|
||||
import org.eclipse.hawkbit.repository.exception.IncompleteDistributionSetException;
|
||||
import org.eclipse.hawkbit.repository.exception.StopRolloutException;
|
||||
import org.eclipse.hawkbit.repository.jpa.repository.ActionRepository;
|
||||
import org.eclipse.hawkbit.repository.jpa.utils.DeploymentHelper;
|
||||
@@ -94,7 +95,6 @@ public class JpaDistributionSetInvalidationManagement implements DistributionSet
|
||||
// no lock is needed as no rollout will be stopped
|
||||
invalidateDistributionSetsInTransaction(distributionSetInvalidation, tenant);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void invalidateDistributionSetsInTransaction(final DistributionSetInvalidation distributionSetInvalidation,
|
||||
@@ -108,21 +108,25 @@ public class JpaDistributionSetInvalidationManagement implements DistributionSet
|
||||
|
||||
private void invalidateDistributionSet(final long setId, final CancelationType cancelationType,
|
||||
final boolean cancelRollouts) {
|
||||
final DistributionSet set = distributionSetManagement.getValidAndComplete(setId);
|
||||
distributionSetManagement.invalidate(set);
|
||||
final DistributionSet distributionSet = distributionSetManagement.getOrElseThrowException(setId);
|
||||
if (!distributionSet.isComplete()) {
|
||||
throw new IncompleteDistributionSetException("Distribution set of type "
|
||||
+ distributionSet.getType().getKey() + " is incomplete: " + distributionSet.getId());
|
||||
}
|
||||
distributionSetManagement.invalidate(distributionSet);
|
||||
log.debug("Distribution set {} marked as invalid.", setId);
|
||||
|
||||
// rollout cancellation should only be permitted with UPDATE_ROLLOUT permission
|
||||
if (shouldRolloutsBeCanceled(cancelationType, cancelRollouts)) {
|
||||
log.debug("Cancel rollouts after ds invalidation. ID: {}", setId);
|
||||
rolloutManagement.cancelRolloutsForDistributionSet(set);
|
||||
rolloutManagement.cancelRolloutsForDistributionSet(distributionSet);
|
||||
}
|
||||
|
||||
// Do run as system to ensure all actions (even invisible) are canceled due to invalidation.
|
||||
systemSecurityContext.runAsSystem(() -> {
|
||||
if (cancelationType != CancelationType.NONE) {
|
||||
log.debug("Cancel actions after ds invalidation. ID: {}", setId);
|
||||
deploymentManagement.cancelActionsForDistributionSet(cancelationType, set);
|
||||
deploymentManagement.cancelActionsForDistributionSet(cancelationType, distributionSet);
|
||||
}
|
||||
|
||||
log.debug("Cancel auto assignments after ds invalidation. ID: {}", setId);
|
||||
|
||||
@@ -34,6 +34,7 @@ import org.eclipse.hawkbit.repository.builder.DistributionSetCreate;
|
||||
import org.eclipse.hawkbit.repository.builder.DistributionSetUpdate;
|
||||
import org.eclipse.hawkbit.repository.builder.GenericDistributionSetUpdate;
|
||||
import org.eclipse.hawkbit.repository.event.remote.DistributionSetDeletedEvent;
|
||||
import org.eclipse.hawkbit.repository.exception.DeletedException;
|
||||
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
|
||||
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
|
||||
import org.eclipse.hawkbit.repository.exception.EntityReadOnlyException;
|
||||
@@ -697,6 +698,13 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
|
||||
public void lock(final long id) {
|
||||
final JpaDistributionSet distributionSet = getById(id);
|
||||
if (!distributionSet.isLocked()) {
|
||||
distributionSet.getModules().forEach(module -> {
|
||||
if (!module.isLocked()) {
|
||||
final JpaSoftwareModule jpaSoftwareModule = (JpaSoftwareModule)module;
|
||||
jpaSoftwareModule.lock();
|
||||
softwareModuleRepository.save(jpaSoftwareModule);
|
||||
}
|
||||
});
|
||||
distributionSet.lock();
|
||||
distributionSetRepository.save(distributionSet);
|
||||
}
|
||||
@@ -780,6 +788,10 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
|
||||
+ distributionSet.getType().getKey() + " is incomplete: " + distributionSet.getId());
|
||||
}
|
||||
|
||||
if (distributionSet.isDeleted()) {
|
||||
throw new DeletedException(DistributionSet.class, id);
|
||||
}
|
||||
|
||||
return distributionSet;
|
||||
}
|
||||
|
||||
|
||||
@@ -49,6 +49,7 @@ import org.eclipse.hawkbit.repository.jpa.JpaManagementHelper;
|
||||
import org.eclipse.hawkbit.repository.jpa.builder.JpaRolloutGroupCreate;
|
||||
import org.eclipse.hawkbit.repository.jpa.configuration.Constants;
|
||||
import org.eclipse.hawkbit.repository.jpa.executor.AfterTransactionCommitExecutor;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaRollout;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaRolloutGroup;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaRollout_;
|
||||
@@ -205,22 +206,29 @@ public class JpaRolloutManagement implements RolloutManagement {
|
||||
|
||||
private JpaRollout createRollout(final JpaRollout rollout) {
|
||||
WeightValidationHelper.usingContext(systemSecurityContext, tenantConfigurationManagement).validate(rollout);
|
||||
long totalTargets;
|
||||
String errMsg;
|
||||
final JpaDistributionSet distributionSet = (JpaDistributionSet) rollout.getDistributionSet();
|
||||
final long totalTargets;
|
||||
final String errMsg;
|
||||
if (RolloutHelper.isRolloutRetried(rollout.getTargetFilterQuery())) {
|
||||
totalTargets = targetManagement.countByFailedInRollout(
|
||||
RolloutHelper.getIdFromRetriedTargetFilter(rollout.getTargetFilterQuery()),
|
||||
rollout.getDistributionSet().getType().getId());
|
||||
distributionSet.getType().getId());
|
||||
errMsg = "No failed targets in Rollout";
|
||||
} else {
|
||||
totalTargets = targetManagement.countByRsqlAndCompatible(rollout.getTargetFilterQuery(),
|
||||
rollout.getDistributionSet().getType().getId());
|
||||
distributionSet.getType().getId());
|
||||
errMsg = "Rollout does not match any existing targets";
|
||||
}
|
||||
if (totalTargets == 0) {
|
||||
throw new ValidationException(errMsg);
|
||||
}
|
||||
rollout.setTotalTargets(totalTargets);
|
||||
|
||||
// implicit lock
|
||||
if (!distributionSet.isLocked()) {
|
||||
distributionSetManagement.lock(distributionSet.getId());
|
||||
}
|
||||
|
||||
if (rollout.getWeight().isEmpty()) {
|
||||
rollout.setWeight(repositoryProperties.getActionWeightIfAbsent());
|
||||
}
|
||||
@@ -526,7 +534,6 @@ public class JpaRolloutManagement implements RolloutManagement {
|
||||
rollout.setStartAt(update.getStartAt().orElse(null));
|
||||
update.getSet().ifPresent(setId -> {
|
||||
final DistributionSet set = distributionSetManagement.getValidAndComplete(setId);
|
||||
|
||||
rollout.setDistributionSet(set);
|
||||
});
|
||||
if (rolloutApprovalStrategy.isApprovalNeeded(rollout)) {
|
||||
|
||||
@@ -276,11 +276,14 @@ public class JpaTargetFilterQueryManagement implements TargetFilterQueryManageme
|
||||
} else {
|
||||
WeightValidationHelper.usingContext(systemSecurityContext, tenantConfigurationManagement).validate(update);
|
||||
assertMaxTargetsQuota(targetFilterQuery.getQuery(), targetFilterQuery.getName(), update.getDsId());
|
||||
final JpaDistributionSet ds = (JpaDistributionSet) distributionSetManagement
|
||||
final JpaDistributionSet distributionSet = (JpaDistributionSet) distributionSetManagement
|
||||
.getValidAndComplete(update.getDsId());
|
||||
verifyDistributionSetAndThrowExceptionIfDeleted(ds);
|
||||
// implicit lock
|
||||
if (!distributionSet.isLocked()) {
|
||||
distributionSetManagement.lock(distributionSet.getId());
|
||||
}
|
||||
|
||||
targetFilterQuery.setAutoAssignDistributionSet(ds);
|
||||
targetFilterQuery.setAutoAssignDistributionSet(distributionSet);
|
||||
contextAware.getCurrentContext().ifPresent(targetFilterQuery::setAccessControlContext);
|
||||
targetFilterQuery.setAutoAssignInitiatedBy(contextAware.getCurrentUsername());
|
||||
targetFilterQuery.setAutoAssignActionType(sanitizeAutoAssignActionType(update.getActionType()));
|
||||
@@ -299,12 +302,6 @@ public class JpaTargetFilterQueryManagement implements TargetFilterQueryManageme
|
||||
.isConfirmationFlowEnabled();
|
||||
}
|
||||
|
||||
private static void verifyDistributionSetAndThrowExceptionIfDeleted(final DistributionSet distributionSet) {
|
||||
if (distributionSet.isDeleted()) {
|
||||
throw new EntityNotFoundException(DistributionSet.class, distributionSet.getId());
|
||||
}
|
||||
}
|
||||
|
||||
private static ActionType sanitizeAutoAssignActionType(final ActionType actionType) {
|
||||
if (actionType == null) {
|
||||
return ActionType.FORCED;
|
||||
|
||||
Reference in New Issue
Block a user