diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TargetManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TargetManagement.java index 080b6757d..b35c6ec58 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TargetManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TargetManagement.java @@ -52,6 +52,12 @@ import org.springframework.security.access.prepost.PreAuthorize; */ public interface TargetManagement { + enum OnNotFoundPolicy { + FAIL, // default + TAG_AND_SUCCESS, + TAG_AND_ERROR + } + /** * Counts number of targets with the given distribution set assigned. * @@ -668,11 +674,37 @@ public interface TargetManagement { * * @param controllerIds to assign for * @param targetTagId to assign + * @param onNotFoundPolicy what to do if there are targets that are not found * @return list of assigned targets * @throws EntityNotFoundException if given targetTagId or at least one of the targets do not exist */ @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET) - List assignTag(@NotEmpty Collection controllerIds, long targetTagId); + List assignTag(@NotEmpty Collection controllerIds, long targetTagId, final OnNotFoundPolicy onNotFoundPolicy); + + /** + * Assign a {@link TargetTag} assignment to given {@link Target}s. + * + * @param controllerIds to assign for + * @param targetTagId to assign + * @return list of assigned targets + * @throws EntityNotFoundException if given targetTagId or at least one of the targets do not exist + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET) + default List assignTag(@NotEmpty Collection controllerIds, long targetTagId) { + return assignTag(controllerIds, targetTagId, OnNotFoundPolicy.FAIL); + } + + /** + * Un-assign a {@link TargetTag} assignment to given {@link Target}s. + * + * @param controllerIds to un-assign for + * @param targetTagId to un-assign + * @param onNotFoundPolicy what to do if there are targets that are not found + * @return list of unassigned targets + * @throws EntityNotFoundException if given targetTagId or at least one of the targets do not exist + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET) + List unassignTag(@NotEmpty Collection controllerIds, long targetTagId, final OnNotFoundPolicy onNotFoundPolicy); /** * Un-assign a {@link TargetTag} assignment to given {@link Target}s. @@ -683,7 +715,9 @@ public interface TargetManagement { * @throws EntityNotFoundException if given targetTagId or at least one of the targets do not exist */ @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET) - List unassignTag(@NotEmpty Collection controllerIds, long targetTagId); + default List unassignTag(@NotEmpty Collection controllerIds, long targetTagId) { + return unassignTag(controllerIds, targetTagId, OnNotFoundPolicy.FAIL); + } /** * Un-assign a {@link TargetType} assignment to given {@link Target}. @@ -978,7 +1012,7 @@ public interface TargetManagement { /** * Un-assign a {@link TargetTag} assignment to given {@link Target}. * - * @deprecated since 0.6.0 - use {@link #unassignTag(List, long)} instead + * @deprecated since 0.6.0 - use {@link #unassigнnTag(List, long)} instead * @param controllerId to un-assign for * @param targetTagId to un-assign * @return the unassigned target or if no target is unassigned diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaTargetManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaTargetManagement.java index 7bdaf3e6b..f0f6447b5 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaTargetManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaTargetManagement.java @@ -9,7 +9,6 @@ */ package org.eclipse.hawkbit.repository.jpa.management; -import java.net.URI; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -20,7 +19,6 @@ import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.Set; -import java.util.function.BiConsumer; import java.util.function.BiFunction; import java.util.function.Function; import java.util.stream.Collectors; @@ -535,8 +533,8 @@ public class JpaTargetManagement implements TargetManagement { @Transactional @Retryable(include = { ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) - public List assignTag(final Collection controllerIds, final long targetTagId) { - return updateTag(controllerIds, targetTagId, (tag, target) -> { + public List assignTag(final Collection controllerIds, final long targetTagId, final OnNotFoundPolicy onNotFoundPolicy) { + return updateTag(controllerIds, targetTagId, onNotFoundPolicy, (tag, target) -> { if (target.getTags().contains(tag)) { return target; } else { @@ -549,8 +547,8 @@ public class JpaTargetManagement implements TargetManagement { @Transactional @Retryable(include = { ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) - public List unassignTag(final Collection controllerIds, final long targetTagId) { - return updateTag(controllerIds, targetTagId, (tag, target) -> { + public List unassignTag(final Collection controllerIds, final long targetTagId, final OnNotFoundPolicy onNotFoundPolicy) { + return updateTag(controllerIds, targetTagId, onNotFoundPolicy, (tag, target) -> { if (target.getTags().contains(tag)) { target.removeTag(tag); return targetRepository.save(target); @@ -560,7 +558,7 @@ public class JpaTargetManagement implements TargetManagement { }); } private List updateTag( - final Collection controllerIds, final long targetTagId, + final Collection controllerIds, final long targetTagId, final OnNotFoundPolicy notFoundPolicy, final BiFunction updater) { final JpaTargetTag tag = targetTagRepository.findById(targetTagId) .orElseThrow(() -> new EntityNotFoundException(TargetTag.class, targetTagId)); @@ -570,14 +568,25 @@ public class JpaTargetManagement implements TargetManagement { .orElseGet(Collections::emptyList) : targetRepository .findAll(TargetSpecifications.byControllerIdWithTagsInJoin(controllerIds)); - if (targets.size() < controllerIds.size()) { - throw new EntityNotFoundException(Target.class, notFound(controllerIds, targets)); + final EntityNotFoundException notFoundException; + if (targets.size() < controllerIds.size() && notFoundPolicy != OnNotFoundPolicy.TAG_AND_SUCCESS) { + notFoundException = new EntityNotFoundException(Target.class, notFound(controllerIds, targets)); + if (notFoundPolicy == OnNotFoundPolicy.FAIL) { + throw notFoundException; + } + } else { + notFoundException = null; } targetRepository.getAccessController() .ifPresent(acm -> acm.assertOperationAllowed(AccessController.Operation.UPDATE, targets)); try { - return targets.stream().map(target -> updater.apply(tag, target)).toList(); + final List result = targets.stream().map(target -> updater.apply(tag, target)).toList(); + if (notFoundException != null) { // if notFoundPolicy is NotFoundPolicy.TAG_AND_FAIL + throw notFoundException; + } else { + return result; // if all found or notFoundPolicy is NotFoundPolicy.TAG_AND_SUCCESS + } } finally { // No reason to save the tag entityManager.detach(tag);