Improve DS Tag REST & management API (#1883)
* added methods to unassign by multiple ds * deprecated toggle assigments - too complex to undestand * deprecated unassign (management) of single ds - in favour of methods with multiple ds Signed-off-by: Marinov Avgustin <Avgustin.Marinov@bosch.com>
This commit is contained in:
@@ -96,6 +96,17 @@ public interface DistributionSetManagement
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY)
|
||||
List<DistributionSet> assignTag(@NotEmpty Collection<Long> ids, long tagId);
|
||||
|
||||
/**
|
||||
* Unassign a {@link DistributionSetTag} assignment to given {@link DistributionSet}s.
|
||||
*
|
||||
* @param ids to assign for
|
||||
* @param tagId to assign
|
||||
* @return list of assigned ds
|
||||
* @throws EntityNotFoundException if tag with given ID does not exist or (at least one) of the distribution sets.
|
||||
*/
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY)
|
||||
List<DistributionSet> unassignTag(@NotEmpty Collection<Long> ids, long tagId);
|
||||
|
||||
/**
|
||||
* Creates a list of distribution set meta data entries.
|
||||
*
|
||||
@@ -452,25 +463,6 @@ public interface DistributionSetManagement
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
|
||||
boolean isInUse(long id);
|
||||
|
||||
/**
|
||||
* Toggles {@link DistributionSetTag} assignment to given
|
||||
* {@link DistributionSet}s by means that if some (or all) of the targets in
|
||||
* the list have the {@link Tag} not yet assigned, they will be. Only if all
|
||||
* of theme have the tag already assigned they will be removed instead.
|
||||
*
|
||||
* @param ids
|
||||
* to toggle for
|
||||
* @param tagName
|
||||
* to toggle
|
||||
* @return {@link DistributionSetTagAssignmentResult} with all meta data of
|
||||
* the assignment outcome.
|
||||
*
|
||||
* @throws EntityNotFoundException
|
||||
* if given tag does not exist or (at least one) module
|
||||
*/
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY)
|
||||
DistributionSetTagAssignmentResult toggleTagAssignment(@NotEmpty Collection<Long> ids, @NotNull String tagName);
|
||||
|
||||
/**
|
||||
* Unassigns a {@link SoftwareModule} form an existing
|
||||
* {@link DistributionSet}.
|
||||
@@ -491,22 +483,6 @@ public interface DistributionSetManagement
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY)
|
||||
DistributionSet unassignSoftwareModule(long id, long moduleId);
|
||||
|
||||
/**
|
||||
* Unassign a {@link DistributionSetTag} assignment to given
|
||||
* {@link DistributionSet}.
|
||||
*
|
||||
* @param id
|
||||
* to unassign for
|
||||
* @param tagId
|
||||
* to unassign
|
||||
* @return the unassigned ds or <null> if no ds is unassigned
|
||||
*
|
||||
* @throws EntityNotFoundException
|
||||
* if set or tag with given ID does not exist
|
||||
*/
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY)
|
||||
DistributionSet unassignTag(long id, long tagId);
|
||||
|
||||
/**
|
||||
* Updates a distribution set meta data value if corresponding entry exists.
|
||||
*
|
||||
@@ -585,4 +561,34 @@ public interface DistributionSetManagement
|
||||
*/
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY)
|
||||
void invalidate(DistributionSet distributionSet);
|
||||
|
||||
/**
|
||||
* Toggles {@link DistributionSetTag} assignment to given
|
||||
* {@link DistributionSet}s by means that if some (or all) of the targets in
|
||||
* the list have the {@link Tag} not yet assigned, they will be. Only if all
|
||||
* of theme have the tag already assigned they will be removed instead.
|
||||
*
|
||||
* @deprecated since 0.6.0 in favor of assign/unassign
|
||||
* @param ids to toggle for
|
||||
* @param tagName to toggle
|
||||
* @return {@link DistributionSetTagAssignmentResult} with all meta data of the assignment outcome.
|
||||
* @throws EntityNotFoundException if given tag does not exist or (at least one) module
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY)
|
||||
DistributionSetTagAssignmentResult toggleTagAssignment(@NotEmpty Collection<Long> ids, @NotNull String tagName);
|
||||
|
||||
|
||||
/**
|
||||
* Unassign a {@link DistributionSetTag} assignment to given {@link DistributionSet}.
|
||||
*
|
||||
* @deprecated since 0.6.0 in favor of unassignTag(List<Long>, long)
|
||||
* @param id to unassign for
|
||||
* @param tagId to unassign
|
||||
* @return the unassigned ds or <null> if no ds is unassigned
|
||||
* @throws EntityNotFoundException if set or tag with given ID does not exist
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY)
|
||||
DistributionSet unassignTag(long id, long tagId);
|
||||
}
|
||||
|
||||
@@ -62,7 +62,6 @@ import org.eclipse.hawkbit.repository.jpa.repository.TargetRepository;
|
||||
import org.eclipse.hawkbit.repository.jpa.rsql.RSQLUtility;
|
||||
import org.eclipse.hawkbit.repository.jpa.specifications.DistributionSetSpecification;
|
||||
import org.eclipse.hawkbit.repository.jpa.specifications.TargetSpecifications;
|
||||
import org.eclipse.hawkbit.repository.jpa.utils.DeploymentHelper;
|
||||
import org.eclipse.hawkbit.repository.jpa.utils.QuotaHelper;
|
||||
import org.eclipse.hawkbit.repository.model.Action;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
@@ -85,7 +84,6 @@ import org.springframework.data.jpa.domain.Specification;
|
||||
import org.springframework.orm.jpa.vendor.Database;
|
||||
import org.springframework.retry.annotation.Backoff;
|
||||
import org.springframework.retry.annotation.Retryable;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
@@ -187,43 +185,6 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
|
||||
return distributionSetRepository.countAutoAssignmentsForDistributionSet(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
@Retryable(include = {
|
||||
ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY))
|
||||
public DistributionSetTagAssignmentResult toggleTagAssignment(final Collection<Long> ids, final String tagName) {
|
||||
return updateTags(
|
||||
ids,
|
||||
() -> distributionSetTagManagement
|
||||
.getByName(tagName)
|
||||
.orElseThrow(() -> new EntityNotFoundException(DistributionSetTag.class, tagName)),
|
||||
(allDs, distributionSetTag) -> {
|
||||
final List<JpaDistributionSet> toBeChangedDSs = allDs.stream().filter(set -> set.addTag(distributionSetTag))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
final DistributionSetTagAssignmentResult result;
|
||||
// un-assignment case
|
||||
if (toBeChangedDSs.isEmpty()) {
|
||||
for (final JpaDistributionSet set : allDs) {
|
||||
if (set.removeTag(distributionSetTag)) {
|
||||
toBeChangedDSs.add(set);
|
||||
}
|
||||
}
|
||||
result = new DistributionSetTagAssignmentResult(ids.size() - toBeChangedDSs.size(),
|
||||
Collections.emptyList(),
|
||||
Collections.unmodifiableList(
|
||||
toBeChangedDSs.stream().map(distributionSetRepository::save).collect(Collectors.toList())),
|
||||
distributionSetTag);
|
||||
} else {
|
||||
result = new DistributionSetTagAssignmentResult(ids.size() - toBeChangedDSs.size(),
|
||||
Collections.unmodifiableList(
|
||||
toBeChangedDSs.stream().map(distributionSetRepository::save).collect(Collectors.toList())),
|
||||
Collections.emptyList(), distributionSetTag);
|
||||
}
|
||||
return result;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
@Retryable(include = {
|
||||
@@ -238,13 +199,28 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
@Retryable(include = {
|
||||
ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY))
|
||||
public List<DistributionSet> unassignTag(final Collection<Long> ids, final long dsTagId) {
|
||||
return updateTags(
|
||||
ids,
|
||||
() -> distributionSetTagManagement.get(dsTagId).orElseThrow(() -> new EntityNotFoundException(DistributionSetTag.class, dsTagId)),
|
||||
(allDs, distributionSetTag) -> {
|
||||
allDs.forEach(ds -> ds.removeTag(distributionSetTag));
|
||||
return Collections.unmodifiableList(distributionSetRepository.saveAll(allDs));
|
||||
});
|
||||
}
|
||||
|
||||
private <T> T updateTags(
|
||||
final Collection<Long> dsIds, final Supplier<DistributionSetTag> tagSupplier,
|
||||
final BiFunction<List<JpaDistributionSet>, DistributionSetTag, T> updater) {
|
||||
final List<JpaDistributionSet> allDs = findDistributionSetListWithDetails(dsIds);
|
||||
final List<JpaDistributionSet> allDs = dsIds.size() == 1 ?
|
||||
distributionSetRepository.findById(dsIds.iterator().next()).map(List::of).orElseGet(Collections::emptyList) :
|
||||
distributionSetRepository.findAll(DistributionSetSpecification.byIds(dsIds));
|
||||
if (allDs.size() < dsIds.size()) {
|
||||
throw new EntityNotFoundException(DistributionSet.class, dsIds,
|
||||
allDs.stream().map(DistributionSet::getId).toList());
|
||||
throw new EntityNotFoundException(DistributionSet.class, dsIds, allDs.stream().map(DistributionSet::getId).toList());
|
||||
}
|
||||
|
||||
final DistributionSetTag distributionSetTag = tagSupplier.get();
|
||||
@@ -256,10 +232,6 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
|
||||
}
|
||||
}
|
||||
|
||||
private List<JpaDistributionSet> findDistributionSetListWithDetails(final Collection<Long> distributionIdSet) {
|
||||
return distributionSetRepository.findAll(DistributionSetSpecification.byIds(distributionIdSet));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
@Retryable(include = {
|
||||
@@ -659,25 +631,6 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
@Retryable(include = {
|
||||
ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY))
|
||||
public DistributionSet unassignTag(final long id, final long dsTagId) {
|
||||
final JpaDistributionSet set = (JpaDistributionSet) getWithDetails(id)
|
||||
.orElseThrow(() -> new EntityNotFoundException(DistributionSet.class, id));
|
||||
|
||||
final DistributionSetTag distributionSetTag = distributionSetTagManagement.get(dsTagId)
|
||||
.orElseThrow(() -> new EntityNotFoundException(DistributionSetTag.class, dsTagId));
|
||||
set.removeTag(distributionSetTag);
|
||||
|
||||
final JpaDistributionSet result = distributionSetRepository.save(set);
|
||||
|
||||
// No reason to save the tag
|
||||
entityManager.detach(distributionSetTag);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
@Retryable(include = {
|
||||
@@ -865,4 +818,60 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
|
||||
throw new EntityNotFoundException(DistributionSetTag.class, tagId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
@Retryable(include = {
|
||||
ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY))
|
||||
public DistributionSetTagAssignmentResult toggleTagAssignment(final Collection<Long> ids, final String tagName) {
|
||||
return updateTags(
|
||||
ids,
|
||||
() -> distributionSetTagManagement
|
||||
.getByName(tagName)
|
||||
.orElseThrow(() -> new EntityNotFoundException(DistributionSetTag.class, tagName)),
|
||||
(allDs, distributionSetTag) -> {
|
||||
final List<JpaDistributionSet> toBeChangedDSs = allDs.stream().filter(set -> set.addTag(distributionSetTag))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
final DistributionSetTagAssignmentResult result;
|
||||
// un-assignment case
|
||||
if (toBeChangedDSs.isEmpty()) {
|
||||
for (final JpaDistributionSet set : allDs) {
|
||||
if (set.removeTag(distributionSetTag)) {
|
||||
toBeChangedDSs.add(set);
|
||||
}
|
||||
}
|
||||
result = new DistributionSetTagAssignmentResult(ids.size() - toBeChangedDSs.size(),
|
||||
Collections.emptyList(),
|
||||
Collections.unmodifiableList(
|
||||
toBeChangedDSs.stream().map(distributionSetRepository::save).collect(Collectors.toList())),
|
||||
distributionSetTag);
|
||||
} else {
|
||||
result = new DistributionSetTagAssignmentResult(ids.size() - toBeChangedDSs.size(),
|
||||
Collections.unmodifiableList(
|
||||
toBeChangedDSs.stream().map(distributionSetRepository::save).collect(Collectors.toList())),
|
||||
Collections.emptyList(), distributionSetTag);
|
||||
}
|
||||
return result;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
@Retryable(include = {
|
||||
ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY))
|
||||
public DistributionSet unassignTag(final long id, final long dsTagId) {
|
||||
final JpaDistributionSet set = (JpaDistributionSet) getWithDetails(id)
|
||||
.orElseThrow(() -> new EntityNotFoundException(DistributionSet.class, id));
|
||||
|
||||
final DistributionSetTag distributionSetTag = distributionSetTagManagement.get(dsTagId)
|
||||
.orElseThrow(() -> new EntityNotFoundException(DistributionSetTag.class, dsTagId));
|
||||
set.removeTag(distributionSetTag);
|
||||
|
||||
final JpaDistributionSet result = distributionSetRepository.save(set);
|
||||
|
||||
// No reason to save the tag
|
||||
entityManager.detach(distributionSetTag);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user