From 28d90c3754ef216744f43cb577857ddfed027ca9 Mon Sep 17 00:00:00 2001 From: Stefan Klotz <35995139+StefanKlt@users.noreply.github.com> Date: Wed, 21 Dec 2022 16:16:53 +0100 Subject: [PATCH] Exclude soft deleted entities from findByRsql result for all entities (#1297) * exclude soft deleted SMs and SM types from findByRsql result Signed-off-by: Stefan Klotz * add tests Signed-off-by: Stefan Klotz * clean up code Signed-off-by: Stefan Klotz Signed-off-by: Stefan Klotz --- .../jpa/JpaSoftwareModuleManagement.java | 9 +++-- .../jpa/JpaSoftwareModuleTypeManagement.java | 15 +++++--- .../SoftwareModuleTypeSpecification.java | 38 +++++++++++++++++++ .../jpa/DistributionSetManagementTest.java | 7 +++- .../DistributionSetTypeManagementTest.java | 9 +++-- .../repository/jpa/RolloutManagementTest.java | 7 ++-- .../jpa/SoftwareModuleManagementTest.java | 2 + .../jpa/SoftwareModuleTypeManagementTest.java | 3 ++ 8 files changed, 72 insertions(+), 18 deletions(-) create mode 100644 hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/specifications/SoftwareModuleTypeSpecification.java diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSoftwareModuleManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSoftwareModuleManagement.java index 86a168bd7..5f46047f3 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSoftwareModuleManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSoftwareModuleManagement.java @@ -270,11 +270,12 @@ public class JpaSoftwareModuleManagement implements SoftwareModuleManagement { @Override public Page findByRsql(final Pageable pageable, final String rsqlParam) { - final Specification spec = RSQLUtility.buildRsqlSpecification(rsqlParam, - SoftwareModuleFields.class, virtualPropertyReplacer, database); + final List> specList = Lists.newArrayListWithExpectedSize(2); + specList.add(RSQLUtility.buildRsqlSpecification(rsqlParam, SoftwareModuleFields.class, virtualPropertyReplacer, + database)); + specList.add(SoftwareModuleSpecification.isDeletedFalse()); - return JpaManagementHelper.findAllWithCountBySpec(softwareModuleRepository, pageable, - Collections.singletonList(spec)); + return JpaManagementHelper.findAllWithCountBySpec(softwareModuleRepository, pageable, specList); } @Override diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSoftwareModuleTypeManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSoftwareModuleTypeManagement.java index d1eb97be0..e70ddd73e 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSoftwareModuleTypeManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSoftwareModuleTypeManagement.java @@ -8,6 +8,7 @@ */ package org.eclipse.hawkbit.repository.jpa; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; @@ -23,8 +24,8 @@ import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; import org.eclipse.hawkbit.repository.jpa.builder.JpaSoftwareModuleTypeCreate; import org.eclipse.hawkbit.repository.jpa.configuration.Constants; import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleType; -import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleType_; import org.eclipse.hawkbit.repository.jpa.rsql.RSQLUtility; +import org.eclipse.hawkbit.repository.jpa.specifications.SoftwareModuleTypeSpecification; import org.eclipse.hawkbit.repository.model.SoftwareModuleType; import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer; import org.springframework.dao.ConcurrencyFailureException; @@ -84,16 +85,18 @@ public class JpaSoftwareModuleTypeManagement implements SoftwareModuleTypeManage @Override public Page findByRsql(final Pageable pageable, final String rsqlParam) { - return JpaManagementHelper.findAllWithCountBySpec(softwareModuleTypeRepository, pageable, - Collections.singletonList(RSQLUtility.buildRsqlSpecification(rsqlParam, SoftwareModuleTypeFields.class, - virtualPropertyReplacer, database))); + return JpaManagementHelper + .findAllWithCountBySpec(softwareModuleTypeRepository, pageable, + Arrays.asList( + RSQLUtility.buildRsqlSpecification(rsqlParam, SoftwareModuleTypeFields.class, + virtualPropertyReplacer, database), + SoftwareModuleTypeSpecification.isDeleted(false))); } @Override public Slice findAll(final Pageable pageable) { return JpaManagementHelper.findAllWithoutCountBySpec(softwareModuleTypeRepository, pageable, - Collections.singletonList( - (smTypeRoot, query, cb) -> cb.equal(smTypeRoot.get(JpaSoftwareModuleType_.deleted), false))); + Collections.singletonList(SoftwareModuleTypeSpecification.isDeleted(false))); } @Override diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/specifications/SoftwareModuleTypeSpecification.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/specifications/SoftwareModuleTypeSpecification.java new file mode 100644 index 000000000..c5c5354c0 --- /dev/null +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/specifications/SoftwareModuleTypeSpecification.java @@ -0,0 +1,38 @@ +/** + * Copyright (c) 2022 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.jpa.specifications; + +import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleType; +import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleType_; +import org.eclipse.hawkbit.repository.model.SoftwareModuleType; +import org.springframework.data.jpa.domain.Specification; + +/** + * Specifications class for {@link SoftwareModuleType}s. The class provides + * Spring Data JPQL Specifications. + */ +public class SoftwareModuleTypeSpecification { + + private SoftwareModuleTypeSpecification() { + // utility class + } + + /** + * {@link Specification} for retrieving {@link SoftwareModuleType}s by its + * DELETED attribute. + * + * @param isDeleted + * TRUE/FALSE are compared to the attribute DELETED. If NULL the + * attribute is ignored + * @return the {@link SoftwareModuleType} {@link Specification} + */ + public static Specification isDeleted(final Boolean isDeleted) { + return (root, query, cb) -> cb.equal(root.get(JpaSoftwareModuleType_.deleted), isDeleted); + } +} diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/DistributionSetManagementTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/DistributionSetManagementTest.java index d1acc8234..6ddf0f7fe 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/DistributionSetManagementTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/DistributionSetManagementTest.java @@ -678,8 +678,8 @@ class DistributionSetManagementTest extends AbstractJpaIntegrationTest { // correct final List tSecondPinOrderedByName = distributionSetManagement .findByDistributionSetFilterOrderByLinkedTarget( - PageRequest.of(0, 500, Sort.by(Direction.DESC, "version")), - distributionSetFilter, tSecond.getControllerId()) + PageRequest.of(0, 500, Sort.by(Direction.DESC, "version")), distributionSetFilter, + tSecond.getControllerId()) .getContent(); assertThat(tSecondPinOrderedByName).hasSize(10); // installed @@ -1081,6 +1081,9 @@ class DistributionSetManagementTest extends AbstractJpaIntegrationTest { // not assigned so not marked as deleted assertThat(distributionSetRepository.findAll()).hasSize(4); assertThat(distributionSetManagement.findByCompleted(PAGE, true)).hasSize(2); + assertThat(distributionSetManagement.findAll(PAGE)).hasSize(2); + assertThat(distributionSetManagement.findByRsql(PAGE, "name==*")).hasSize(2); + assertThat(distributionSetManagement.count()).isEqualTo(2); } @Test diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/DistributionSetTypeManagementTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/DistributionSetTypeManagementTest.java index 83d102b40..7654fcf23 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/DistributionSetTypeManagementTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/DistributionSetTypeManagementTest.java @@ -115,9 +115,8 @@ public class DistributionSetTypeManagementTest extends AbstractJpaIntegrationTes assertThatExceptionOfType(ConstraintViolationException.class) .as("set invalid description text should not be created") - .isThrownBy(() -> distributionSetManagement.create( - entityFactory.distributionSet().create().name("a").version("a") - .description(INVALID_TEXT_HTML))); + .isThrownBy(() -> distributionSetManagement.create(entityFactory.distributionSet().create().name("a") + .version("a").description(INVALID_TEXT_HTML))); assertThatExceptionOfType(ConstraintViolationException.class) .as("set with too long description should not be updated") @@ -334,6 +333,7 @@ public class DistributionSetTypeManagementTest extends AbstractJpaIntegrationTes @Test @Description("Tests the successfull deletion of used (soft delete) distribution set types.") public void deleteAssignedDistributionSetType() { + final int existing = (int) distributionSetTypeManagement.count(); final JpaDistributionSetType toBeDeleted = (JpaDistributionSetType) distributionSetTypeManagement .create(entityFactory.distributionSetType().create().key("softdeleted").name("to be deleted")); @@ -345,6 +345,9 @@ public class DistributionSetTypeManagementTest extends AbstractJpaIntegrationTes final Optional softdeleted = distributionSetTypeManagement.getByKey("softdeleted"); assertThat(softdeleted).isPresent(); assertThat(softdeleted.get().isDeleted()).isTrue(); + assertThat(distributionSetTypeManagement.findAll(PAGE)).hasSize(existing); + assertThat(distributionSetTypeManagement.findByRsql(PAGE, "name==*")).hasSize(existing); + assertThat(distributionSetTypeManagement.count()).isEqualTo(existing); } @Test diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/RolloutManagementTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/RolloutManagementTest.java index 8ea383f00..2bc6cd978 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/RolloutManagementTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/RolloutManagementTest.java @@ -1752,6 +1752,9 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest { assertThat(rolloutManagement.findAll(PAGE, true).getContent()).hasSize(1); assertThat(rolloutManagement.findAll(PAGE, false).getContent()).isEmpty(); + assertThat(rolloutManagement.findByRsql(PAGE, "name==*", true).getContent()).hasSize(1); + assertThat(rolloutManagement.findByRsql(PAGE, "name==*", false).getContent()).isEmpty(); + assertThat(rolloutManagement.count()).isZero(); assertThat(rolloutGroupManagement.findByRolloutWithDetailedStatus(PAGE, createdRollout.getId()).getContent()) .hasSize(amountGroups); @@ -1787,8 +1790,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest { final String prefixRolloutReady = randomString + "2"; final RolloutCreate rolloutReadyCreate = entityFactory.rollout().create() - .name(prefixRolloutReady + "-testRollout").targetFilterQuery("name==" + randomString + "*") - .set(testDs); + .name(prefixRolloutReady + "-testRollout").targetFilterQuery("name==" + randomString + "*").set(testDs); Rollout rolloutReady = rolloutManagement.create(rolloutReadyCreate, 1, conditions); // Let the executor handle created Rollout rolloutManagement.handleRollouts(); @@ -1803,7 +1805,6 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest { assertThat(rolloutsOrderedByName).containsSubsequence(List.of(rolloutRunning, rolloutReady)); } - @Test @Description("Creating a rollout without weight value when multi assignment in enabled.") void weightNotRequiredInMultiAssignmentMode() { diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/SoftwareModuleManagementTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/SoftwareModuleManagementTest.java index ec11988be..6efd7fa85 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/SoftwareModuleManagementTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/SoftwareModuleManagementTest.java @@ -308,6 +308,8 @@ public class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest { assignedModule = softwareModuleManagement.get(assignedModule.getId()).get(); assertTrue(assignedModule.isDeleted(), "The module should be flagged as deleted"); assertThat(softwareModuleManagement.findAll(PAGE)).isEmpty(); + assertThat(softwareModuleManagement.findByRsql(PAGE, "name==*")).isEmpty(); + assertThat(softwareModuleManagement.count()).isZero(); assertThat(softwareModuleRepository.findAll()).hasSize(1); // verify: binary data is deleted diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/SoftwareModuleTypeManagementTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/SoftwareModuleTypeManagementTest.java index 31d135556..c0dbc6e2d 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/SoftwareModuleTypeManagementTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/SoftwareModuleTypeManagementTest.java @@ -128,6 +128,9 @@ public class SoftwareModuleTypeManagementTest extends AbstractJpaIntegrationTest // delete assigned softwareModuleTypeManagement.delete(type.getId()); assertThat(softwareModuleTypeManagement.findAll(PAGE)).hasSize(3).contains(osType, runtimeType, appType); + assertThat(softwareModuleTypeManagement.findByRsql(PAGE, "name==*")).hasSize(3).contains(osType, runtimeType, + appType); + assertThat(softwareModuleTypeManagement.count()).isEqualTo(3); assertThat(softwareModuleTypeRepository.findAll()).hasSize(4).contains((JpaSoftwareModuleType) osType, (JpaSoftwareModuleType) runtimeType, (JpaSoftwareModuleType) appType,