Move deprecated repository and mgmt rest methods in separate module (#2177)

Some already deprecated management REST methods are moved in separate module (together with used only for them repository api and impl) in order to have cleanly separate deprecatd REST API.
The new module is hawkbit-mgmt-resource-deprecated. It is inculded, by default, in hawkbit-mgmt-stater.
* when we decide to remove the deprecated REST API implementation completely - will be easily remved - just module and refs
* deprecated REST API could be excluded (by removing the module from runtime) even before that for the runtimes.
* after removal, for some time (untill the usad management and repository APIs are compatible) it will be possible to refer (and include) the deprecated method implementation together with the next hawkBit versions.

The deprecated methods are:
* POST /rest/v1/distributionsettags/{distributionsetTagId}/assigned/toggleTagAssignment
* POST /rest/v1/distributionsettags/{distributionsetTagId}/assigned
* POST /rest/v1/targettags/{targetTagId}/assigned/toggleTagAssignment
* POST /rest/v1/targettags/{targetTagId}/assigned

Signed-off-by: Avgustin Marinov <Avgustin.Marinov@bosch.com>
This commit is contained in:
Avgustin Marinov
2025-01-09 11:04:39 +02:00
committed by GitHub
parent 3fde9604f4
commit d2799f4bbc
31 changed files with 816 additions and 671 deletions

View File

@@ -21,7 +21,6 @@ import java.util.Optional;
import java.util.Set;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import jakarta.persistence.EntityManager;
@@ -72,7 +71,6 @@ import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSetFilter;
import org.eclipse.hawkbit.repository.model.DistributionSetMetadata;
import org.eclipse.hawkbit.repository.model.DistributionSetTag;
import org.eclipse.hawkbit.repository.model.DistributionSetTagAssignmentResult;
import org.eclipse.hawkbit.repository.model.DistributionSetType;
import org.eclipse.hawkbit.repository.model.MetaData;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
@@ -625,62 +623,6 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
return distributionSetRepository.countAutoAssignmentsForDistributionSet(id);
}
@Override
@Transactional
@Retryable(retryFor = { 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 updateTag(
ids,
() -> distributionSetTagManagement
.findByName(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(retryFor = { 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;
}
// check if shall implicitly lock a distribution set
boolean isImplicitLockApplicable(final DistributionSet distributionSet) {
final JpaDistributionSet jpaDistributionSet = (JpaDistributionSet) distributionSet;
@@ -876,23 +818,4 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
throw new EntityNotFoundException(DistributionSetTag.class, tagId);
}
}
private <T> T updateTag(
final Collection<Long> dsIds, final Supplier<DistributionSetTag> tagSupplier,
final BiFunction<List<JpaDistributionSet>, DistributionSetTag, T> updater) {
final List<JpaDistributionSet> allDs = dsIds.size() == 1 ?
distributionSetRepository.findById(dsIds.iterator().next()).map(List::of).orElseGet(Collections::emptyList) :
distributionSetRepository.findAll(DistributionSetSpecification.byIdsFetch(dsIds));
if (allDs.size() < dsIds.size()) {
throw new EntityNotFoundException(DistributionSet.class, dsIds, allDs.stream().map(DistributionSet::getId).toList());
}
final DistributionSetTag distributionSetTag = tagSupplier.get();
try {
return updater.apply(allDs, distributionSetTag);
} finally {
// No reason to save the tag
entityManager.detach(distributionSetTag);
}
}
}

View File

@@ -78,7 +78,6 @@ import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
import org.eclipse.hawkbit.repository.model.TargetMetadata;
import org.eclipse.hawkbit.repository.model.TargetTag;
import org.eclipse.hawkbit.repository.model.TargetTagAssignmentResult;
import org.eclipse.hawkbit.repository.model.TargetType;
import org.eclipse.hawkbit.repository.model.TargetTypeAssignmentResult;
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
@@ -830,62 +829,6 @@ public class JpaTargetManagement implements TargetManagement {
return metadata;
}
@Override
@Transactional
@Retryable(retryFor = { ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX,
backoff = @Backoff(delay = Constants.TX_RT_DELAY))
public TargetTagAssignmentResult toggleTagAssignment(final Collection<String> controllerIds, final String tagName) {
final TargetTag tag = targetTagRepository
.findByNameEquals(tagName)
.orElseThrow(() -> new EntityNotFoundException(TargetTag.class, tagName));
final List<JpaTarget> allTargets = targetRepository
.findAll(TargetSpecifications.byControllerIdWithTagsInJoin(controllerIds));
if (allTargets.size() < controllerIds.size()) {
throw new EntityNotFoundException(Target.class, controllerIds,
allTargets.stream().map(Target::getControllerId).toList());
}
final List<JpaTarget> alreadyAssignedTargets = targetRepository.findAll(
TargetSpecifications.hasTagName(tagName).and(TargetSpecifications.hasControllerIdIn(controllerIds)));
// all are already assigned -> unassign
if (alreadyAssignedTargets.size() == allTargets.size()) {
alreadyAssignedTargets.forEach(target -> target.removeTag(tag));
return new TargetTagAssignmentResult(0, Collections.emptyList(),
Collections.unmodifiableList(alreadyAssignedTargets), tag);
}
allTargets.removeAll(alreadyAssignedTargets);
// some or none are assigned -> assign
allTargets.forEach(target -> target.addTag(tag));
final TargetTagAssignmentResult result = new TargetTagAssignmentResult(alreadyAssignedTargets.size(),
targetRepository.saveAll(allTargets), Collections.emptyList(), tag);
// no reason to persist the tag
entityManager.detach(tag);
return result;
}
@Override
@Transactional
@Retryable(retryFor = { ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX,
backoff = @Backoff(delay = Constants.TX_RT_DELAY))
public Target unassignTag(final String controllerId, final long targetTagId) {
final JpaTarget target = getByControllerIdAndThrowIfNotFound(controllerId);
final TargetTag tag = targetTagRepository.findById(targetTagId)
.orElseThrow(() -> new EntityNotFoundException(TargetTag.class, targetTagId));
target.removeTag(tag);
final Target result = targetRepository.save(target);
// No reason to save the tag
entityManager.detach(tag);
return result;
}
private static boolean hasTagsFilterActive(final FilterParams filterParams) {
final boolean isNoTagActive = Boolean.TRUE.equals(filterParams.getSelectTargetWithNoTag());
final boolean isAtLeastOneTagActive = filterParams.getFilterByTagNames() != null

View File

@@ -204,7 +204,7 @@ public abstract class AbstractJpaIntegrationTest extends AbstractIntegrationTest
protected List<DistributionSet> unassignTag(final Collection<DistributionSet> sets,
final DistributionSetTag tag) {
return distributionSetManagement.unassignTag(
sets.stream().map(DistributionSet::getId).collect(Collectors.toList()), tag.getId());
sets.stream().map(DistributionSet::getId).toList(), tag.getId());
}
protected TargetTypeAssignmentResult initiateTypeAssignment(final Collection<Target> targets, final TargetType type) {

View File

@@ -249,7 +249,7 @@ class DistributionSetAccessControllerTest extends AbstractAccessControllerTest {
// assignment is denied for hiddenTarget since it's hidden
assertThatThrownBy(() -> {
distributionSetManagement.unassignTag(hidden.getId(), dsTag.getId());
distributionSetManagement.unassignTag(List.of(hidden.getId()), dsTag.getId());
}).as("Missing update permissions for target to toggle tag assignment.")
.isInstanceOf(EntityNotFoundException.class);
}

View File

@@ -195,7 +195,7 @@ class TargetAccessControllerTest extends AbstractAccessControllerTest {
.isInstanceOf(InsufficientPermissionException.class);
// assignment is denied for hiddenTarget since it's hidden
assertThatThrownBy(() -> targetManagement.unassignTag(hiddenTarget.getControllerId(), myTag.getId()))
assertThatThrownBy(() -> targetManagement.unassignTag(List.of(hiddenTarget.getControllerId()), myTag.getId()))
.as("Missing update permissions for target to toggle tag assignment.")
.isInstanceOf(InsufficientPermissionException.class);
}

View File

@@ -132,9 +132,9 @@ class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
verifyThrownExceptionBy(() ->
distributionSetManagement.assignTag(singletonList(set.getId()), Long.parseLong(NOT_EXIST_ID)), "DistributionSetTag");
verifyThrownExceptionBy(() -> distributionSetManagement.unassignTag(set.getId(), NOT_EXIST_IDL), "DistributionSetTag");
verifyThrownExceptionBy(() -> distributionSetManagement.unassignTag(singletonList(set.getId()), NOT_EXIST_IDL), "DistributionSetTag");
verifyThrownExceptionBy(() -> distributionSetManagement.unassignTag(NOT_EXIST_IDL, dsTag.getId()), "DistributionSet");
verifyThrownExceptionBy(() -> distributionSetManagement.unassignTag(singletonList(NOT_EXIST_IDL), dsTag.getId()), "DistributionSet");
verifyThrownExceptionBy(() -> distributionSetManagement.create(
entityFactory.distributionSet().create().name("xxx").type(NOT_EXIST_ID)), "DistributionSetType");
@@ -331,7 +331,7 @@ class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
.isEqualTo(distributionSetManagement.findByTag(tag.getId(), PAGE).getNumberOfElements());
final JpaDistributionSet unAssignDS = (JpaDistributionSet) distributionSetManagement
.unassignTag(assignDS.get(0), findDistributionSetTag.getId());
.unassignTag(List.of(assignDS.get(0)), findDistributionSetTag.getId()).get(0);
assertThat(unAssignDS.getId()).as("unassigned ds is wrong").isEqualTo(assignDS.get(0));
assertThat(unAssignDS.getTags().size()).as("unassigned ds has wrong tag size").isZero();
assertThat(distributionSetTagManagement.findByName(TAG1_NAME)).isPresent();