From 6aa8ccaa9c889681b4cc0a5a4b850e3fb36ab442 Mon Sep 17 00:00:00 2001 From: Avgustin Marinov Date: Tue, 5 Aug 2025 15:45:41 +0300 Subject: [PATCH] Refactor DS Management (#2591) Signed-off-by: Avgustin Marinov --- .../AbstractDDiApiIntegrationTest.java | 9 + .../resource/DdiConfirmationBaseTest.java | 2 +- .../rest/resource/DdiDeploymentBaseTest.java | 8 +- .../MgmtDistributionSetTagResource.java | 5 +- .../AbstractManagementApiIntegrationTest.java | 2 +- .../MgmtDistributionSetResourceTest.java | 30 +- .../repository/DeploymentManagement.java | 2 +- .../repository/DistributionSetManagement.java | 133 ++------- .../DistributionSetTagManagement.java | 30 -- .../jpa/model/AbstractJpaBaseEntity.java | 10 +- .../AbstractJpaTenantAwareBaseEntity.java | 2 +- .../jpa/model/AbstractJpaBaseEntity.java | 2 +- .../AbstractJpaTenantAwareBaseEntity.java | 2 +- .../management/JpaControllerManagement.java | 2 +- .../management/JpaDeploymentManagement.java | 50 ++-- ...DistributionSetInvalidationManagement.java | 6 +- .../JpaDistributionSetManagement.java | 266 ++++++------------ .../JpaDistributionSetTagManagement.java | 32 +-- .../jpa/management/JpaRolloutManagement.java | 4 +- .../JpaTargetFilterQueryManagement.java | 8 +- .../jpa/model/AbstractJpaNamedEntity.java | 2 + .../AbstractJpaNamedVersionedEntity.java | 15 +- .../jpa/model/JpaDistributionSet.java | 18 +- .../repository/DistributionSetRepository.java | 11 - .../DistributionSetTagRepository.java | 10 +- .../DistributionSetTypeRepository.java | 22 +- .../jpa/AbstractJpaIntegrationTest.java | 53 +++- .../DistributionSetAccessControllerTest.java | 27 +- .../jpa/acm/TargetAccessControllerTest.java | 16 +- .../DeploymentManagementSecurityTest.java | 2 +- .../management/DeploymentManagementTest.java | 11 +- ...DistributionSetManagementSecurityTest.java | 92 +----- .../DistributionSetManagementTest.java | 128 +++------ ...tributionSetTagManagementSecurityTest.java | 28 -- .../DistributionSetTagManagementTest.java | 41 ++- .../jpa/management/RolloutManagementTest.java | 4 +- .../SoftwareModuleManagementTest.java | 28 +- .../jpa/tenancy/MultiTenancyEntityTest.java | 7 +- .../test/util/AbstractIntegrationTest.java | 21 +- 39 files changed, 365 insertions(+), 776 deletions(-) diff --git a/hawkbit-ddi/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/AbstractDDiApiIntegrationTest.java b/hawkbit-ddi/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/AbstractDDiApiIntegrationTest.java index 7f9d9c034..46c746683 100644 --- a/hawkbit-ddi/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/AbstractDDiApiIntegrationTest.java +++ b/hawkbit-ddi/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/AbstractDDiApiIntegrationTest.java @@ -22,6 +22,7 @@ import java.io.IOException; import java.io.StringWriter; import java.util.Collections; import java.util.List; +import java.util.Optional; import java.util.Random; import com.fasterxml.jackson.core.JsonFactory; @@ -38,8 +39,12 @@ import org.eclipse.hawkbit.ddi.json.model.DdiConfirmationFeedback; import org.eclipse.hawkbit.ddi.json.model.DdiProgress; import org.eclipse.hawkbit.ddi.json.model.DdiResult; import org.eclipse.hawkbit.ddi.json.model.DdiStatus; +import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; +import org.eclipse.hawkbit.repository.exception.InsufficientPermissionException; import org.eclipse.hawkbit.repository.jpa.JpaRepositoryConfiguration; import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet; +import org.eclipse.hawkbit.repository.jpa.specifications.DistributionSetSpecification; +import org.eclipse.hawkbit.repository.jpa.specifications.TargetSpecifications; import org.eclipse.hawkbit.repository.model.Action; import org.eclipse.hawkbit.repository.model.Artifact; import org.eclipse.hawkbit.repository.model.DistributionSet; @@ -396,4 +401,8 @@ public abstract class AbstractDDiApiIntegrationTest extends AbstractRestIntegrat .andExpect(jsonPath(prefix + ".chunks[?(@.part=='bApp')].name") .value(findFirstModuleByType(ds, appType).orElseThrow().getName())); } + + protected Optional findDsByAction(final long actionId) { + return deploymentManagement.findAction(actionId).map(Action::getDistributionSet); + } } \ No newline at end of file diff --git a/hawkbit-ddi/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DdiConfirmationBaseTest.java b/hawkbit-ddi/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DdiConfirmationBaseTest.java index 3d6b54b21..2fe1fda1b 100644 --- a/hawkbit-ddi/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DdiConfirmationBaseTest.java +++ b/hawkbit-ddi/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DdiConfirmationBaseTest.java @@ -119,7 +119,7 @@ class DdiConfirmationBaseTest extends AbstractDDiApiIntegrationTest { .isLessThanOrEqualTo(System.currentTimeMillis()); assertThat(actionStatusRepository.count()).isEqualTo(2); - final DistributionSet findDistributionSetByAction = distributionSetManagement.findByAction(action.getId()).get(); + final DistributionSet findDistributionSetByAction = findDsByAction(action.getId()).get(); getAndVerifyConfirmationBasePayload( DEFAULT_CONTROLLER_ID, MediaType.APPLICATION_JSON, ds, artifact, diff --git a/hawkbit-ddi/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DdiDeploymentBaseTest.java b/hawkbit-ddi/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DdiDeploymentBaseTest.java index 8966b2df8..f884e4eae 100644 --- a/hawkbit-ddi/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DdiDeploymentBaseTest.java +++ b/hawkbit-ddi/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DdiDeploymentBaseTest.java @@ -187,7 +187,7 @@ class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest { .isLessThanOrEqualTo(System.currentTimeMillis()); assertThat(countActionStatusAll()).isEqualTo(2); - final DistributionSet findDistributionSetByAction = distributionSetManagement.findByAction(action.getId()).get(); + final DistributionSet findDistributionSetByAction = findDsByAction(action.getId()).get(); getAndVerifyDeploymentBasePayload(DEFAULT_CONTROLLER_ID, MediaType.APPLICATION_JSON, ds, artifact, artifactSignature, action.getId(), findFirstModuleByType(findDistributionSetByAction, osType).orElseThrow().getId(), "forced", "forced"); @@ -287,7 +287,7 @@ class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest { .isLessThanOrEqualTo(System.currentTimeMillis()); assertThat(countActionStatusAll()).isEqualTo(2); - final DistributionSet findDistributionSetByAction = distributionSetManagement.findByAction(action.getId()).get(); + final DistributionSet findDistributionSetByAction = findDsByAction(action.getId()).get(); getAndVerifyDeploymentBasePayload(DEFAULT_CONTROLLER_ID, MediaType.APPLICATION_JSON, ds, visibleMetadataOsKey, visibleMetadataOsValue, artifact, artifactSignature, action.getId(), "attempt", "attempt", @@ -344,7 +344,7 @@ class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest { .isLessThanOrEqualTo(System.currentTimeMillis()); assertThat(countActionStatusAll()).isEqualTo(2); - final DistributionSet findDistributionSetByAction = distributionSetManagement.findByAction(action.getId()).get(); + final DistributionSet findDistributionSetByAction = findDsByAction(action.getId()).get(); getAndVerifyDeploymentBasePayload(DEFAULT_CONTROLLER_ID, MediaType.APPLICATION_JSON, ds, artifact, artifactSignature, action.getId(), findFirstModuleByType(findDistributionSetByAction, osType).orElseThrow().getId(), "forced", "forced"); @@ -409,7 +409,7 @@ class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest { .isLessThanOrEqualTo(System.currentTimeMillis()); assertThat(countActionStatusAll()).isEqualTo(2); - final DistributionSet findDistributionSetByAction = distributionSetManagement.findByAction(action.getId()).get(); + final DistributionSet findDistributionSetByAction = findDsByAction(action.getId()).get(); getAndVerifyDeploymentBasePayload(DEFAULT_CONTROLLER_ID, MediaType.APPLICATION_JSON, ds, "metaDataVisible", "withValue", artifact, artifactSignature, action.getId(), "forced", "skip", getOsModule(findDistributionSetByAction)); diff --git a/hawkbit-mgmt/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetTagResource.java b/hawkbit-mgmt/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetTagResource.java index e92088d5d..04c800aaf 100644 --- a/hawkbit-mgmt/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetTagResource.java +++ b/hawkbit-mgmt/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetTagResource.java @@ -107,10 +107,7 @@ class MgmtDistributionSetTagResource implements MgmtDistributionSetTagRestApi { @AuditLog(entity = "DistributionSetTag", type = AuditLog.Type.DELETE, description = "Delete Distribution Set Tag") public ResponseEntity deleteDistributionSetTag(final Long distributionsetTagId) { log.debug("Delete {} distribution set tag", distributionsetTagId); - final DistributionSetTag tag = findDistributionTagById(distributionsetTagId); - - distributionSetTagManagement.delete(tag.getName()); - + distributionSetTagManagement.delete(distributionsetTagId); return ResponseEntity.ok().build(); } diff --git a/hawkbit-mgmt/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/AbstractManagementApiIntegrationTest.java b/hawkbit-mgmt/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/AbstractManagementApiIntegrationTest.java index 68a851cc0..f5d9f793a 100644 --- a/hawkbit-mgmt/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/AbstractManagementApiIntegrationTest.java +++ b/hawkbit-mgmt/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/AbstractManagementApiIntegrationTest.java @@ -198,7 +198,7 @@ public abstract class AbstractManagementApiIntegrationTest extends AbstractRestI static void implicitLock(final DistributionSet set) { if (!set.isLocked()) { ((JpaDistributionSet) set).setOptLockRevision(set.getOptLockRevision() + 1); - ((JpaDistributionSet) set).lock(); + ((JpaDistributionSet) set).setLocked(true); } } } \ No newline at end of file diff --git a/hawkbit-mgmt/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetResourceTest.java b/hawkbit-mgmt/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetResourceTest.java index 066bbc436..72c688971 100644 --- a/hawkbit-mgmt/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetResourceTest.java +++ b/hawkbit-mgmt/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetResourceTest.java @@ -851,7 +851,7 @@ class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegrationTe @WithUser(principal = "uploadTester", allSpPermissions = true) void getDistributionSets() throws Exception { // prepare test data - assertThat(distributionSetManagement.findByCompleted(true, PAGE)).isEmpty(); + assertThat(distributionSetManagement.findAll(PAGE)).isEmpty(); DistributionSet set = testdataFactory.createDistributionSet("one"); set = distributionSetManagement.update(DistributionSetManagement.Update.builder().id(set.getId()) @@ -860,7 +860,7 @@ class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegrationTe // load also lazy stuff set = distributionSetManagement.getWithDetails(set.getId()).get(); - assertThat(distributionSetManagement.findByCompleted(true, PAGE)).hasSize(1); + assertThat(distributionSetManagement.findAll(PAGE)).hasSize(1); // perform request mvc.perform(get("/rest/v1/distributionsets").accept(MediaType.APPLICATION_JSON)) @@ -930,7 +930,7 @@ class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegrationTe @Test @WithUser(principal = "uploadTester", allSpPermissions = true) void createDistributionSets() throws Exception { - assertThat(distributionSetManagement.findByCompleted(true, PAGE)).isEmpty(); + assertThat(distributionSetManagement.findAll(PAGE)).isEmpty(); final SoftwareModule ah = testdataFactory.createSoftwareModule(TestdataFactory.SM_TYPE_APP); final SoftwareModule jvm = testdataFactory.createSoftwareModule(TestdataFactory.SM_TYPE_RT); final SoftwareModule os = testdataFactory.createSoftwareModule(TestdataFactory.SM_TYPE_OS); @@ -966,7 +966,7 @@ class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegrationTe .hasToString(String.valueOf(three.getId())); // check in database - assertThat(distributionSetManagement.findByCompleted(true, PAGE)).hasSize(3); + assertThat(distributionSetManagement.findAll(PAGE)).hasSize(3); assertThat(one.isRequiredMigrationStep()).isFalse(); assertThat(two.isRequiredMigrationStep()).isFalse(); assertThat(three.isRequiredMigrationStep()).isTrue(); @@ -982,11 +982,11 @@ class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegrationTe @Test void deleteUnassignedistributionSet() throws Exception { // prepare test data - assertThat(distributionSetManagement.findByCompleted(true, PAGE)).isEmpty(); + assertThat(distributionSetManagement.findAll(PAGE)).isEmpty(); final DistributionSet set = testdataFactory.createDistributionSet("one"); - assertThat(distributionSetManagement.findByCompleted(true, PAGE)).hasSize(1); + assertThat(distributionSetManagement.findAll(PAGE)).hasSize(1); // perform request mvc.perform(delete("/rest/v1/distributionsets/{smId}", set.getId())) @@ -994,7 +994,7 @@ class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegrationTe .andExpect(status().isOk()); // check repository content - assertThat(distributionSetManagement.findByCompleted(true, PAGE)).isEmpty(); + assertThat(distributionSetManagement.findAll(PAGE)).isEmpty(); assertThat(distributionSetManagement.count()).isZero(); } @@ -1014,13 +1014,13 @@ class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegrationTe @Test void deleteAssignedDistributionSet() throws Exception { // prepare test data - assertThat(distributionSetManagement.findByCompleted(true, PAGE)).isEmpty(); + assertThat(distributionSetManagement.findAll(PAGE)).isEmpty(); final DistributionSet set = testdataFactory.createDistributionSet("one"); testdataFactory.createTarget("test"); assignDistributionSet(set.getId(), "test"); - assertThat(distributionSetManagement.findByCompleted(true, PAGE)).hasSize(1); + assertThat(distributionSetManagement.findAll(PAGE)).hasSize(1); mvc.perform(get("/rest/v1/distributionsets/{dsId}", set.getId())) .andDo(MockMvcResultPrinter.print()) @@ -1037,7 +1037,7 @@ class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegrationTe .andExpect(jsonPath("$.deleted", equalTo(true))); // check repository content - assertThat(distributionSetManagement.findByCompleted(true, PAGE)).isEmpty(); + assertThat(distributionSetManagement.findAll(PAGE)).isEmpty(); } /** @@ -1046,7 +1046,7 @@ class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegrationTe @Test void updateDistributionSet() throws Exception { // prepare test data - assertThat(distributionSetManagement.findByCompleted(true, PAGE)).isEmpty(); + assertThat(distributionSetManagement.findAll(PAGE)).isEmpty(); final DistributionSet set = testdataFactory.createDistributionSet("one"); assertThat(distributionSetManagement.count()).isEqualTo(1); @@ -1081,7 +1081,7 @@ class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegrationTe void updateRequiredMigrationStepFailsIfDistributionSetisInUse() throws Exception { // prepare test data - assertThat(distributionSetManagement.findByCompleted(true, PAGE)).isEmpty(); + assertThat(distributionSetManagement.findAll(PAGE)).isEmpty(); final DistributionSet set = testdataFactory.createDistributionSet("one"); assignDistributionSet(set.getId(), testdataFactory.createTarget().getControllerId()); @@ -1723,7 +1723,7 @@ class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegrationTe @Test void lockDistributionSet() throws Exception { // prepare test data - assertThat(distributionSetManagement.findByCompleted(true, PAGE)).isEmpty(); + assertThat(distributionSetManagement.findAll(PAGE)).isEmpty(); final DistributionSet set = testdataFactory.createDistributionSet("one"); assertThat(distributionSetManagement.count()).isEqualTo(1); @@ -1747,11 +1747,11 @@ class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegrationTe @Test void unlockDistributionSet() throws Exception { // prepare test data - assertThat(distributionSetManagement.findByCompleted(true, PAGE)).isEmpty(); + assertThat(distributionSetManagement.findAll(PAGE)).isEmpty(); final DistributionSet set = testdataFactory.createDistributionSet("one"); assertThat(distributionSetManagement.count()).isEqualTo(1); - distributionSetManagement.lock(set.getId()); + distributionSetManagement.lock(set); assertThat(distributionSetManagement.get(set.getId()) .orElseThrow(() -> new EntityNotFoundException(SoftwareModule.class, set.getId())).isLocked()) .as("Distribution set should be locked") diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DeploymentManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DeploymentManagement.java index 88955d0ee..ff34697b1 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DeploymentManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DeploymentManagement.java @@ -119,7 +119,7 @@ public interface DeploymentManagement { * target and multi-assignment is disabled */ @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET) - List offlineAssignedDistributionSets(Collection> assignments, String initiatedBy); + List offlineAssignedDistributionSets(String initiatedBy, Collection> assignments); @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY) List offlineAssignedDistributionSets(Collection> assignments); diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DistributionSetManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DistributionSetManagement.java index a6edb7e79..8d162c1ae 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DistributionSetManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DistributionSetManagement.java @@ -79,13 +79,36 @@ public interface DistributionSetManagement @PreAuthorize(HAS_READ_REPOSITORY) T getOrElseThrowException(long id); + @PreAuthorize(HAS_READ_REPOSITORY) + boolean shouldLockImplicitly(final DistributionSet distributionSet); + + /** + * Locks a distribution set. From then on its functional properties could not be changed, and it could be assigned to targets + * + * @param distributionSet the distribution set + * @throws EntityNotFoundException if distribution set with given ID does not exist + */ + @PreAuthorize(HAS_UPDATE_REPOSITORY) + T lock(final DistributionSet distributionSet); + + /** + * Unlocks a distribution set.
+ * Use it with extreme care! In general once distribution set is locked it shall not be unlocked. Note that it could have been assigned / + * deployed to targets. + * + * @param distributionSet the distribution set + * @throws EntityNotFoundException if distribution set with given ID does not exist + */ + @PreAuthorize(HAS_UPDATE_REPOSITORY) + T unlock(final DistributionSet distributionSet); + /** * Sets the specified {@link DistributionSet} as invalidated. * * @param distributionSet the ID of the {@link DistributionSet} to be set to invalid */ @PreAuthorize(HAS_UPDATE_REPOSITORY) - void invalidate(T distributionSet); + T invalidate(DistributionSet distributionSet); /** * Assigns {@link SoftwareModule} to existing {@link DistributionSet}. @@ -137,37 +160,6 @@ public interface DistributionSetManagement @PreAuthorize(HAS_UPDATE_REPOSITORY) List unassignTag(@NotEmpty Collection ids, long tagId); - /** - * Locks a distribution set. From then on its functional properties could not be changed, and it could be assigned to targets - * - * @param id the distribution set id - * @throws EntityNotFoundException if distribution set with given ID does not exist - */ - @PreAuthorize(HAS_UPDATE_REPOSITORY) - T lock(final long id); - - /** - * Unlocks a distribution set.
- * Use it with extreme care! In general once distribution set is locked it shall not be unlocked. Note that it could have been assigned / - * deployed to targets. - * - * @param id the distribution set id - * @throws EntityNotFoundException if distribution set with given ID does not exist - */ - @PreAuthorize(HAS_UPDATE_REPOSITORY) - T unlock(final long id); - - /** - * Find distribution set by id and throw an exception if it is deleted or invalidated. - * - * @param id id of {@link DistributionSet} - * @return the found valid {@link DistributionSet} - * @throws EntityNotFoundException if distribution set with given ID does not exist - * @throws InvalidDistributionSetException if distribution set with given ID is invalidated - */ - @PreAuthorize(HAS_READ_REPOSITORY) - T getValid(long id); - /** * Find distribution set by id and throw an exception if it is deleted, incomplete or invalidated. * @@ -180,16 +172,6 @@ public interface DistributionSetManagement @PreAuthorize(HAS_READ_REPOSITORY) T getValidAndComplete(long id); - /** - * Retrieves the distribution set for a given action. - * - * @param actionId the action associated with the distribution set - * @return the distribution set which is associated with the action - * @throws EntityNotFoundException if action with given ID does not exist - */ - @PreAuthorize(HAS_READ_REPOSITORY) - Optional findByAction(long actionId); - /** * Find distribution set by name and version. * @@ -200,27 +182,6 @@ public interface DistributionSetManagement @PreAuthorize(HAS_READ_REPOSITORY) Optional findByNameAndVersion(@NotEmpty String distributionName, @NotEmpty String version); - /** - * Finds all {@link DistributionSet}s based on completeness. - * - * @param complete to true for returning only completed distribution sets or false for only incomplete ones nor - * null to return both. - * @param pageable the pagination parameter - * @return all found {@link DistributionSet}s - */ - @PreAuthorize(HAS_READ_REPOSITORY) - Slice findByCompleted(Boolean complete, @NotNull Pageable pageable); - - /** - * Retrieves {@link DistributionSet}s by filtering on the given parameters. - * - * @param distributionSetFilter has details of filters to be applied. - * @param pageable page parameter - * @return the page of found {@link DistributionSet} - */ - @PreAuthorize(HAS_READ_REPOSITORY) - Slice findByDistributionSetFilter(@NotNull DistributionSetFilter distributionSetFilter, @NotNull Pageable pageable); - /** * Retrieves {@link DistributionSet}s by filtering on the given parameters. * @@ -247,46 +208,6 @@ public interface DistributionSetManagement @PreAuthorize(HAS_READ_REPOSITORY) Page findByRsqlAndTag(@NotNull String rsql, long tagId, @NotNull Pageable pageable); - /** - * Counts all {@link DistributionSet}s based on completeness. - * - * @param complete to true for counting only completed distribution sets or false for only incomplete ones - * nor null to count both. - * @return count of all found {@link DistributionSet}s - */ - @PreAuthorize(HAS_READ_REPOSITORY) - long countByCompleted(Boolean complete); - - /** - * Counts all {@link DistributionSet}s in repository based on given filter. - * - * @param distributionSetFilter has details of filters to be applied. - * @return count of {@link DistributionSet}s - */ - @PreAuthorize(HAS_READ_REPOSITORY) - long countByDistributionSetFilter(@NotNull DistributionSetFilter distributionSetFilter); - - /** - * Count all {@link DistributionSet}s in the repository that are not marked - * as deleted. - * - * @param typeId to look for - * @return number of {@link DistributionSet}s - * @throws EntityNotFoundException if type with given ID does not exist - */ - @PreAuthorize(HAS_READ_REPOSITORY) - long countByTypeId(long typeId); - - /** - * Checks if a {@link DistributionSet} is currently in use by a target in - * the repository. - * - * @param id to check - * @return true if in use - */ - @PreAuthorize(HAS_READ_REPOSITORY) - boolean isInUse(long id); - /** * Count all {@link org.eclipse.hawkbit.repository.model.Rollout}s by status for * Distribution Set. @@ -298,8 +219,7 @@ public interface DistributionSetManagement List countRolloutsByStatusForDistributionSet(@NotNull Long id); /** - * Count all {@link org.eclipse.hawkbit.repository.model.Action}s by status for - * Distribution Set. + * Count all {@link org.eclipse.hawkbit.repository.model.Action}s by status for Distribution Set. * * @param id to look for * @return List of Statistics for {@link org.eclipse.hawkbit.repository.model.Action}s status counts @@ -308,8 +228,7 @@ public interface DistributionSetManagement List countActionsByStatusForDistributionSet(@NotNull Long id); /** - * Count all {@link TargetFilterQueryManagement.AutoAssignDistributionSetUpdate}s - * for Distribution Set. + * Count all {@link TargetFilterQueryManagement.AutoAssignDistributionSetUpdate}s for Distribution Set. * * @param id to look for * @return number of {@link TargetFilterQueryManagement.AutoAssignDistributionSetUpdate}s diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DistributionSetTagManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DistributionSetTagManagement.java index 662e2b7fa..65c4c072d 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DistributionSetTagManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DistributionSetTagManagement.java @@ -37,36 +37,6 @@ import org.springframework.security.access.prepost.PreAuthorize; public interface DistributionSetTagManagement extends RepositoryManagement { - /** - * Find {@link DistributionSet} based on given name. - * - * @param name to look for. - * @return {@link DistributionSet} - */ - @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY) - Optional findByName(@NotEmpty String name); - - /** - * Finds all {@link TargetTag} assigned to given {@link Target}. - * - * @param distributionSetId of the {@link DistributionSet} - * @param pageable information for page size, offset and sort order. - * @return page of the found {@link TargetTag}s - * @throws EntityNotFoundException if {@link DistributionSet} with given ID does not exist - */ - @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY) - Page findByDistributionSet(long distributionSetId, @NotNull Pageable pageable); - - /** - * Deletes {@link DistributionSetTag} by given - * {@link DistributionSetTag#getName()}. - * - * @param tagName to be deleted - * @throws EntityNotFoundException if tag with given name does not exist - */ - @PreAuthorize(SpringEvalExpressions.HAS_DELETE_REPOSITORY) - void delete(@NotEmpty String tagName); - @SuperBuilder @Getter @EqualsAndHashCode(callSuper = true) diff --git a/hawkbit-repository/hawkbit-repository-jpa-eclipselink/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaBaseEntity.java b/hawkbit-repository/hawkbit-repository-jpa-eclipselink/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaBaseEntity.java index f4f55db5d..1b81f67b5 100644 --- a/hawkbit-repository/hawkbit-repository-jpa-eclipselink/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaBaseEntity.java +++ b/hawkbit-repository/hawkbit-repository-jpa-eclipselink/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaBaseEntity.java @@ -173,7 +173,7 @@ public abstract class AbstractJpaBaseEntity implements BaseEntity { @Override public String toString() { - return getClass().getSimpleName() + " [id=" + getId() + "]"; + return getClass().getSimpleName() + " [id=" + getId() + " / optLockRevision=" + getOptLockRevision() + "]"; } @PostPersist @@ -203,9 +203,9 @@ public abstract class AbstractJpaBaseEntity implements BaseEntity { } protected boolean isController() { - return SecurityContextHolder.getContext().getAuthentication() != null - && SecurityContextHolder.getContext().getAuthentication() - .getDetails() instanceof TenantAwareAuthenticationDetails tenantAwareDetails - && tenantAwareDetails.isController(); + return SecurityContextHolder.getContext().getAuthentication() != null && + SecurityContextHolder.getContext().getAuthentication().getDetails() + instanceof TenantAwareAuthenticationDetails tenantAwareDetails && + tenantAwareDetails.isController(); } } \ No newline at end of file diff --git a/hawkbit-repository/hawkbit-repository-jpa-eclipselink/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaTenantAwareBaseEntity.java b/hawkbit-repository/hawkbit-repository-jpa-eclipselink/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaTenantAwareBaseEntity.java index e12ba9bb9..4b59da01a 100644 --- a/hawkbit-repository/hawkbit-repository-jpa-eclipselink/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaTenantAwareBaseEntity.java +++ b/hawkbit-repository/hawkbit-repository-jpa-eclipselink/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaTenantAwareBaseEntity.java @@ -75,7 +75,7 @@ public abstract class AbstractJpaTenantAwareBaseEntity extends AbstractJpaBaseEn @Override public String toString() { - return getClass().getSimpleName() + " [tenant=" + getTenant() + ", id=" + getId() + "]"; + return getClass().getSimpleName() + " [tenant=" + getTenant() + ", id=" + getId() + " / optLockRevision=" + getOptLockRevision() + "]"; } /** diff --git a/hawkbit-repository/hawkbit-repository-jpa-hibernate/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaBaseEntity.java b/hawkbit-repository/hawkbit-repository-jpa-hibernate/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaBaseEntity.java index 434c21738..ac3aa51a3 100644 --- a/hawkbit-repository/hawkbit-repository-jpa-hibernate/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaBaseEntity.java +++ b/hawkbit-repository/hawkbit-repository-jpa-hibernate/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaBaseEntity.java @@ -173,7 +173,7 @@ public abstract class AbstractJpaBaseEntity implements BaseEntity { @Override public String toString() { - return getClass().getSimpleName() + " [id=" + getId() + "]"; + return getClass().getSimpleName() + " [id=" + getId() + " / optLockRevision=" + getOptLockRevision() + "]"; } @PostPersist diff --git a/hawkbit-repository/hawkbit-repository-jpa-hibernate/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaTenantAwareBaseEntity.java b/hawkbit-repository/hawkbit-repository-jpa-hibernate/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaTenantAwareBaseEntity.java index 8f0bbd0e2..67c0f1f09 100644 --- a/hawkbit-repository/hawkbit-repository-jpa-hibernate/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaTenantAwareBaseEntity.java +++ b/hawkbit-repository/hawkbit-repository-jpa-hibernate/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaTenantAwareBaseEntity.java @@ -71,7 +71,7 @@ public abstract class AbstractJpaTenantAwareBaseEntity extends AbstractJpaBaseEn @Override public String toString() { - return getClass().getSimpleName() + " [tenant=" + getTenant() + ", id=" + getId() + "]"; + return getClass().getSimpleName() + " [tenant=" + getTenant() + ", id=" + getId() + " / optLockRevision=" + getOptLockRevision() + "]"; } /** diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaControllerManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaControllerManagement.java index ea988367c..7501e191c 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaControllerManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaControllerManagement.java @@ -588,7 +588,7 @@ public class JpaControllerManagement extends JpaActionManagement implements Cont systemSecurityContext.runAsSystem(() -> distributionSetManagement.findByNameAndVersion(distributionName, version).map( distributionSet -> deploymentManagement.offlineAssignedDistributionSets( - List.of(Map.entry(controllerId, distributionSet.getId())), controllerId)) + controllerId, List.of(Map.entry(controllerId, distributionSet.getId())))) .orElseThrow(() -> new EntityNotFoundException(DistributionSet.class, Map.entry(distributionName, version)))); diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaDeploymentManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaDeploymentManagement.java index 82a2ff1ec..4d5220a15 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaDeploymentManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaDeploymentManagement.java @@ -180,40 +180,41 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl @Override @Transactional(isolation = Isolation.READ_COMMITTED) - public List assignDistributionSets(final String initiatedBy, - final List deploymentRequests, final String actionMessage) { + public List assignDistributionSets( + final String initiatedBy, final List deploymentRequests, final String actionMessage) { return assignDistributionSets0(initiatedBy, deploymentRequests, actionMessage); } - private List assignDistributionSets0(final String initiatedBy, - final List deploymentRequests, final String actionMessage) { + private List assignDistributionSets0( + final String initiatedBy, final List deploymentRequests, final String actionMessage) { WeightValidationHelper.usingContext(systemSecurityContext, tenantConfigurationManagement).validate(deploymentRequests); return assignDistributionSets(initiatedBy, deploymentRequests, actionMessage, onlineDsAssignmentStrategy); } @Override - public List offlineAssignedDistributionSets(final Collection> assignments, - final String initiatedBy) { + public List offlineAssignedDistributionSets( + final String initiatedBy, final Collection> assignments) { final Collection> distinctAssignments = assignments.stream().distinct().toList(); enforceMaxAssignmentsPerRequest(distinctAssignments.size()); final List deploymentRequests = distinctAssignments.stream() .map(entry -> DeploymentManagement.deploymentRequest(entry.getKey(), entry.getValue()).build()).toList(); - return assignDistributionSets(auditorAware.getCurrentAuditor().orElse(tenantAware.getCurrentUsername()), deploymentRequests, null, + return assignDistributionSets( + auditorAware.getCurrentAuditor().orElse(tenantAware.getCurrentUsername()), deploymentRequests, null, offlineDsAssignmentStrategy); } @Override @Transactional(isolation = Isolation.READ_COMMITTED) public List offlineAssignedDistributionSets(final Collection> assignments) { - return offlineAssignedDistributionSets(assignments, tenantAware.getCurrentUsername()); + return offlineAssignedDistributionSets(tenantAware.getCurrentUsername(), assignments); } @Override @Transactional(isolation = Isolation.READ_COMMITTED) - @Retryable(retryFor = { - ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) + @Retryable(retryFor = { ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, + backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public Action cancelAction(final long actionId) { return cancelAction0(actionId); } @@ -452,7 +453,7 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl startScheduledActions(groupScheduledActions.getContent()); return groupScheduledActions.getTotalElements(); } - }) > 0) ; + }) > 0); } @Override @@ -483,7 +484,7 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl } @Override - @Transactional(readOnly = false) + @Transactional public int deleteActionsByStatusAndLastModifiedBefore(final Set status, final long lastModified) { if (status.isEmpty()) { return 0; @@ -590,8 +591,9 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl return template; } - private List assignDistributionSets(final String initiatedBy, - final List deploymentRequests, final String actionMessage, final AbstractDsAssignmentStrategy strategy) { + private List assignDistributionSets( + final String initiatedBy, final List deploymentRequests, final String actionMessage, + final AbstractDsAssignmentStrategy strategy) { final List validatedRequests = validateAndFilterRequestForAssignments(deploymentRequests); final Map> assignmentsByDsIds = convertRequest(validatedRequests); @@ -720,10 +722,15 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl private DistributionSetAssignmentResult assignDistributionSetToTargets( final String initiatedBy, final Long dsId, final Collection targetsWithActionType, final String actionMessage, final AbstractDsAssignmentStrategy assignmentStrategy) { - JpaDistributionSet distributionSet = distributionSetManagement.getValidAndComplete(dsId); - if (distributionSetManagement.isImplicitLockApplicable(distributionSet)) { - // without new transaction DS changed event is not thrown - distributionSet = DeploymentHelper.runInNewTransaction(txManager, "Implicit lock", status -> distributionSetManagement.lock(dsId)); + final JpaDistributionSet dsValidAndComplete = distributionSetManagement.getValidAndComplete(dsId); + final JpaDistributionSet distributionSet; + if (distributionSetManagement.shouldLockImplicitly(dsValidAndComplete)) { + // implicitly lock, for some reason no update happen if lock in same transaction + distributionSet = DeploymentHelper.runInNewTransaction( + txManager, "lockDistributionSet-" + dsId, + status -> distributionSetManagement.lock(dsValidAndComplete)); + } else { + distributionSet = dsValidAndComplete; } final List providedTargetIds = targetsWithActionType.stream().map(TargetWithActionType::getControllerId).distinct().toList(); @@ -766,8 +773,8 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl // not active before and the manual assignment which has been done cancels them targetEntitiesIdsChunks.forEach(this::cancelInactiveScheduledActionsForTargets); setAssignedDistributionSetAndTargetUpdateStatus(assignmentStrategy, distributionSetEntity, targetEntitiesIdsChunks); - final Map assignedActions = createActions(targetsWithActionType, targetEntities, distributionSetEntity, - assignmentStrategy, initiatedBy); + final Map assignedActions = + createActions(targetsWithActionType, targetEntities, distributionSetEntity, assignmentStrategy, initiatedBy); // create initial action status when action is created, so we remember // the initial running status because we will change the status // of the action itself and with this action status we have a nicer action history. @@ -820,7 +827,8 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl return persistedActions; } - private void createActionsStatus(final Map actions, final AbstractDsAssignmentStrategy assignmentStrategy, + private void createActionsStatus( + final Map actions, final AbstractDsAssignmentStrategy assignmentStrategy, final String actionMessage) { actionStatusRepository.saveAll(actions.entrySet().stream().map(entry -> { final JpaAction action = entry.getValue(); diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaDistributionSetInvalidationManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaDistributionSetInvalidationManagement.java index 955bccd71..ceb55a737 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaDistributionSetInvalidationManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaDistributionSetInvalidationManagement.java @@ -132,10 +132,10 @@ public class JpaDistributionSetInvalidationManagement implements DistributionSet private void invalidateDistributionSet(final long setId, final CancelationType cancelationType, final boolean cancelRollouts) { final DistributionSet distributionSet = distributionSetManagement.getOrElseThrowException(setId); if (!distributionSet.isComplete()) { - throw new IncompleteDistributionSetException("Distribution set of type " - + distributionSet.getType().getKey() + " is incomplete: " + distributionSet.getId()); + throw new IncompleteDistributionSetException( + "Distribution set of type " + distributionSet.getType().getKey() + " is incomplete: " + distributionSet.getId()); } - ((DistributionSetManagement)distributionSetManagement).invalidate(distributionSet); + distributionSetManagement.invalidate(distributionSet); log.debug("Distribution set {} marked as invalid.", setId); // rollout cancellation should only be permitted with UPDATE_ROLLOUT permission diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaDistributionSetManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaDistributionSetManagement.java index 95f57a5fe..4019c4272 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaDistributionSetManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaDistributionSetManagement.java @@ -13,7 +13,6 @@ import static org.eclipse.hawkbit.repository.jpa.configuration.Constants.TX_RT_D import static org.eclipse.hawkbit.repository.jpa.configuration.Constants.TX_RT_MAX; import static org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey.IMPLICIT_LOCK_ENABLED; -import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashSet; @@ -26,12 +25,10 @@ import java.util.function.Function; import java.util.stream.Collectors; import jakarta.persistence.EntityManager; -import jakarta.validation.constraints.NotNull; import org.eclipse.hawkbit.repository.DistributionSetFields; import org.eclipse.hawkbit.repository.DistributionSetManagement; import org.eclipse.hawkbit.repository.DistributionSetTagManagement; -import org.eclipse.hawkbit.repository.DistributionSetTypeManagement; import org.eclipse.hawkbit.repository.QuotaManagement; import org.eclipse.hawkbit.repository.RepositoryProperties; import org.eclipse.hawkbit.repository.TenantConfigurationManagement; @@ -39,12 +36,10 @@ import org.eclipse.hawkbit.repository.exception.DeletedException; import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; import org.eclipse.hawkbit.repository.exception.EntityReadOnlyException; import org.eclipse.hawkbit.repository.exception.IncompleteDistributionSetException; -import org.eclipse.hawkbit.repository.exception.InsufficientPermissionException; import org.eclipse.hawkbit.repository.exception.InvalidDistributionSetException; import org.eclipse.hawkbit.repository.jpa.JpaManagementHelper; import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet; import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetTag; -import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetType; import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet_; import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule; import org.eclipse.hawkbit.repository.jpa.repository.ActionRepository; @@ -52,16 +47,11 @@ import org.eclipse.hawkbit.repository.jpa.repository.DistributionSetRepository; import org.eclipse.hawkbit.repository.jpa.repository.DistributionSetTagRepository; import org.eclipse.hawkbit.repository.jpa.repository.SoftwareModuleRepository; import org.eclipse.hawkbit.repository.jpa.repository.TargetFilterQueryRepository; -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.QuotaHelper; -import org.eclipse.hawkbit.repository.model.Action; import org.eclipse.hawkbit.repository.model.DistributionSet; -import org.eclipse.hawkbit.repository.model.DistributionSetFilter; import org.eclipse.hawkbit.repository.model.DistributionSetTag; -import org.eclipse.hawkbit.repository.model.DistributionSetType; import org.eclipse.hawkbit.repository.model.SoftwareModule; import org.eclipse.hawkbit.repository.model.Statistic; import org.eclipse.hawkbit.security.SystemSecurityContext; @@ -70,13 +60,10 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProp import org.springframework.dao.ConcurrencyFailureException; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Slice; -import org.springframework.data.jpa.domain.Specification; import org.springframework.retry.annotation.Backoff; import org.springframework.retry.annotation.Retryable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; @Service @@ -86,10 +73,8 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { private final DistributionSetTagManagement distributionSetTagManagement; - private final DistributionSetTypeManagement distributionSetTypeManagement; private final SoftwareModuleRepository softwareModuleRepository; private final DistributionSetTagRepository distributionSetTagRepository; - private final TargetRepository targetRepository; private final TargetFilterQueryRepository targetFilterQueryRepository; private final ActionRepository actionRepository; private final QuotaManagement quotaManagement; @@ -101,10 +86,8 @@ public class JpaDistributionSetManagement final DistributionSetRepository jpaRepository, final EntityManager entityManager, final DistributionSetTagManagement distributionSetTagManagement, - final DistributionSetTypeManagement distributionSetTypeManagement, final SoftwareModuleRepository softwareModuleRepository, final DistributionSetTagRepository distributionSetTagRepository, - final TargetRepository targetRepository, final TargetFilterQueryRepository targetFilterQueryRepository, final ActionRepository actionRepository, final QuotaManagement quotaManagement, @@ -113,10 +96,8 @@ public class JpaDistributionSetManagement final RepositoryProperties repositoryProperties) { super(jpaRepository, entityManager); this.distributionSetTagManagement = distributionSetTagManagement; - this.distributionSetTypeManagement = distributionSetTypeManagement; this.softwareModuleRepository = softwareModuleRepository; this.distributionSetTagRepository = distributionSetTagRepository; - this.targetRepository = targetRepository; this.targetFilterQueryRepository = targetFilterQueryRepository; this.actionRepository = actionRepository; this.quotaManagement = quotaManagement; @@ -133,11 +114,11 @@ public class JpaDistributionSetManagement if (Boolean.TRUE.equals(update.getLocked())) { if (!distributionSet.isLocked()) { lockSoftwareModules(distributionSet); - distributionSet.lock(); + distributionSet.setLocked(true); } } else if (Boolean.FALSE.equals(update.getLocked())) { if (distributionSet.isLocked()) { - distributionSet.unlock(); + distributionSet.setLocked(false); } } @@ -173,16 +154,80 @@ public class JpaDistributionSetManagement return jpaRepository.findOne(jpaRepository.byIdSpec(id), JpaDistributionSet_.GRAPH_DISTRIBUTION_SET_DETAIL); } + @Override + public JpaDistributionSet getOrElseThrowException(final long id) { + return getById(id); + } + + // implicitly lock a distribution set if not already locked and implicit lock is enabled and not to skip @Override @Transactional - public void invalidate(final JpaDistributionSet distributionSet) { - distributionSet.invalidate(); - jpaRepository.save(distributionSet); + @Retryable(retryFor = { ConcurrencyFailureException.class }, maxAttempts = TX_RT_MAX, backoff = @Backoff(delay = TX_RT_DELAY)) + public boolean shouldLockImplicitly(final DistributionSet distributionSet) { + final JpaDistributionSet jpaDistributionSet = toJpaDistributionSet(distributionSet); + if (jpaDistributionSet.isLocked()) { + // already locked + return false; + } + + if (Boolean.FALSE.equals(tenantConfigHelper.getConfigValue(IMPLICIT_LOCK_ENABLED, Boolean.class))) { + // implicit lock disabled + return false; + } + + final List skipForTags = repositoryProperties.getSkipImplicitLockForTags(); + if (!ObjectUtils.isEmpty(skipForTags)) { + final Set tags = jpaDistributionSet.getTags(); + if (!ObjectUtils.isEmpty(tags)) { + for (final DistributionSetTag tag : tags) { + if (skipForTags.contains(tag.getName())) { + // has a skip tag + return false; + } + } + } + } + + // finally - implicitly lock + return true; } @Override - public JpaDistributionSet getOrElseThrowException(final long id) { - return getById(id); + @Transactional + @Retryable(retryFor = { ConcurrencyFailureException.class }, maxAttempts = TX_RT_MAX, backoff = @Backoff(delay = TX_RT_DELAY)) + public JpaDistributionSet lock(final DistributionSet distributionSet) { + final JpaDistributionSet jpaDistributionSet = toJpaDistributionSet(distributionSet); + if (distributionSet.isLocked()) { + return jpaDistributionSet; + } else { + if (!jpaDistributionSet.isComplete()) { + throw new IncompleteDistributionSetException("Could not be locked while incomplete!"); + } + lockSoftwareModules(jpaDistributionSet); + jpaDistributionSet.setLocked(true); + return jpaRepository.save(jpaDistributionSet); + } + } + + @Override + @Transactional + @Retryable(retryFor = { ConcurrencyFailureException.class }, maxAttempts = TX_RT_MAX, backoff = @Backoff(delay = TX_RT_DELAY)) + public JpaDistributionSet unlock(final DistributionSet distributionSet) { + final JpaDistributionSet jpaDistributionSet = toJpaDistributionSet(distributionSet); + if (jpaDistributionSet.isLocked()) { + jpaDistributionSet.setLocked(false); + return jpaRepository.save(jpaDistributionSet); + } else { + return jpaDistributionSet; + } + } + + @Override + @Transactional + public JpaDistributionSet invalidate(final DistributionSet distributionSet) { + final JpaDistributionSet jpaDistributionSet = toJpaDistributionSet(distributionSet); + jpaDistributionSet.invalidate(); + return jpaRepository.save(jpaDistributionSet); } @Override @@ -245,51 +290,6 @@ public class JpaDistributionSetManagement }); } - @Override - @Transactional - @Retryable(retryFor = { ConcurrencyFailureException.class }, maxAttempts = TX_RT_MAX, backoff = @Backoff(delay = TX_RT_DELAY)) - public JpaDistributionSet lock(final long id) { - final JpaDistributionSet distributionSet = getById(id); - if (distributionSet.isLocked()) { - return distributionSet; - } else { - lockSoftwareModules(distributionSet); - distributionSet.lock(); - return jpaRepository.save(distributionSet); - } - } - - @Override - @Transactional - @Retryable(retryFor = { ConcurrencyFailureException.class }, maxAttempts = TX_RT_MAX, backoff = @Backoff(delay = TX_RT_DELAY)) - public JpaDistributionSet unlock(final long id) { - final JpaDistributionSet distributionSet = getById(id); - if (distributionSet.isLocked()) { - distributionSet.unlock(); - return jpaRepository.save(distributionSet); - } else { - return distributionSet; - } - } - - @Override - public Optional findByAction(final long actionId) { - return actionRepository - .findById(actionId) - .map(action -> { - if (!targetRepository.exists(TargetSpecifications.hasId(action.getTarget().getId()))) { - throw new InsufficientPermissionException("Target not accessible (or not found)!"); - } - return jpaRepository - .findOne(DistributionSetSpecification.byIdFetch(action.getDistributionSet().getId())) - .orElseThrow(() -> - new InsufficientPermissionException("DistributionSet not accessible (or not found)!")); - }) - .or(() -> { - throw new EntityNotFoundException(Action.class, actionId); - }); - } - @Override public Optional findByNameAndVersion(final String distributionName, final String version) { return jpaRepository.findOne(DistributionSetSpecification.equalsNameAndVersionIgnoreCase(distributionName, version)); @@ -311,35 +311,6 @@ public class JpaDistributionSetManagement return distributionSet; } - @Override - public JpaDistributionSet getValid(final long id) { - return getValid0(id); - } - - @Override - public Slice findByCompleted(final Boolean complete, final Pageable pageReq) { - final List> specifications = buildSpecsByComplete(complete); - - return JpaManagementHelper.findAllWithoutCountBySpec(jpaRepository, specifications, pageReq); - } - - @Override - public long countByCompleted(final Boolean complete) { - return JpaManagementHelper.countBySpec(jpaRepository, buildSpecsByComplete(complete)); - } - - @Override - public Slice findByDistributionSetFilter(final DistributionSetFilter distributionSetFilter, final Pageable pageable) { - final List> specList = buildDistributionSetSpecifications(distributionSetFilter); - return JpaManagementHelper.findAllWithoutCountBySpec(jpaRepository, specList, pageable); - } - - @Override - public long countByDistributionSetFilter(@NotNull final DistributionSetFilter distributionSetFilter) { - final List> specList = buildDistributionSetSpecifications(distributionSetFilter); - return JpaManagementHelper.countBySpec(jpaRepository, specList); - } - @Override public Page findByTag(final long tagId, final Pageable pageable) { assertDsTagExists(tagId); @@ -357,20 +328,6 @@ public class JpaDistributionSetManagement pageable); } - @Override - public long countByTypeId(final long typeId) { - if (!distributionSetTypeManagement.exists(typeId)) { - throw new EntityNotFoundException(DistributionSetType.class, typeId); - } - return jpaRepository.count(DistributionSetSpecification.byType(typeId)); - } - - @Override - public boolean isInUse(final long id) { - assertDistributionSetExists(id); - return actionRepository.countByDistributionSetId(id) > 0; - } - @Override public List countRolloutsByStatusForDistributionSet(final Long id) { assertDistributionSetExists(id); @@ -400,70 +357,6 @@ public class JpaDistributionSetManagement QuotaHelper.assertAssignmentQuota(requested, maxMetaData, String.class, DistributionSet.class); } - // check if it shall implicitly lock a distribution set - boolean isImplicitLockApplicable(final DistributionSet distributionSet) { - final JpaDistributionSet jpaDistributionSet = (JpaDistributionSet) distributionSet; - if (jpaDistributionSet.isLocked()) { - // already locked - return false; - } - - if (Boolean.FALSE.equals(tenantConfigHelper.getConfigValue(IMPLICIT_LOCK_ENABLED, Boolean.class))) { - // implicit lock disabled - return false; - } - - final List skipForTags = repositoryProperties.getSkipImplicitLockForTags(); - if (!ObjectUtils.isEmpty(skipForTags)) { - final Set tags = jpaDistributionSet.getTags(); - if (!ObjectUtils.isEmpty(tags)) { - for (final DistributionSetTag tag : tags) { - if (skipForTags.contains(tag.getName())) { - // has a skip tag - return false; - } - } - } - } - - // finally - implicit lock is applicable - return true; - } - - private static List> buildDistributionSetSpecifications( - final DistributionSetFilter distributionSetFilter) { - final List> specList = new ArrayList<>(10); - - if (distributionSetFilter.getIsComplete() != null) { - specList.add(DistributionSetSpecification.isCompleted(distributionSetFilter.getIsComplete())); - } - if (distributionSetFilter.getIsDeleted() != null) { - specList.add(DistributionSetSpecification.isDeleted(distributionSetFilter.getIsDeleted())); - } - if (distributionSetFilter.getIsValid() != null) { - specList.add(DistributionSetSpecification.isValid(distributionSetFilter.getIsValid())); - } - if (distributionSetFilter.getTypeId() != null) { - specList.add(DistributionSetSpecification.byType(distributionSetFilter.getTypeId())); - } - if (!ObjectUtils.isEmpty(distributionSetFilter.getSearchText())) { - final String[] dsFilterNameAndVersionEntries = JpaManagementHelper - .getFilterNameAndVersionEntries(distributionSetFilter.getSearchText().trim()); - specList.add(DistributionSetSpecification.likeNameAndVersion(dsFilterNameAndVersionEntries[0], dsFilterNameAndVersionEntries[1])); - } - if (hasTagsFilterActive(distributionSetFilter)) { - specList.add(DistributionSetSpecification.hasTags( - distributionSetFilter.getTagNames(), distributionSetFilter.getSelectDSWithNoTag())); - } - return specList; - } - - private static boolean hasTagsFilterActive(final DistributionSetFilter distributionSetFilter) { - final boolean isNoTagActive = Boolean.TRUE.equals(distributionSetFilter.getSelectDSWithNoTag()); - final boolean isAtLeastOneTagActive = !CollectionUtils.isEmpty(distributionSetFilter.getTagNames()); - return isNoTagActive || isAtLeastOneTagActive; - } - private static Collection notFound(final Collection distributionSetIds, final List foundDistributionSets) { final Map foundDistributionSetMap = foundDistributionSets.stream() .collect(Collectors.toMap(JpaDistributionSet::getId, Function.identity())); @@ -507,15 +400,6 @@ public class JpaDistributionSetManagement .orElseThrow(() -> new EntityNotFoundException(SoftwareModule.class, softwareModuleId)); } - private List> buildSpecsByComplete(final Boolean complete) { - final List> specifications = new ArrayList<>(); - specifications.add(DistributionSetSpecification.isNotDeleted()); - if (complete != null) { - specifications.add(DistributionSetSpecification.isCompleted(complete)); - } - return specifications; - } - private void assertSoftwareModuleQuota(final Long id, final int requested) { QuotaHelper.assertAssignmentQuota(id, requested, quotaManagement.getMaxSoftwareModulesPerDistributionSet(), SoftwareModule.class, DistributionSet.class, softwareModuleRepository::countByAssignedToId); @@ -544,6 +428,14 @@ public class JpaDistributionSetManagement .orElseThrow(() -> new EntityNotFoundException(DistributionSet.class, id)); } + private JpaDistributionSet toJpaDistributionSet(final DistributionSet distributionSet) { + if (distributionSet instanceof JpaDistributionSet jpaDistributionSet) { + return entityManager.merge(jpaDistributionSet); // if from + } else { + return getById(distributionSet.getId()); + } + } + private void assertDistributionSetExists(final long id) { if (!jpaRepository.existsById(id)) { throw new EntityNotFoundException(DistributionSet.class, id); diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaDistributionSetTagManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaDistributionSetTagManagement.java index a5709c34e..c3353435e 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaDistributionSetTagManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaDistributionSetTagManagement.java @@ -43,39 +43,9 @@ public class JpaDistributionSetTagManagement extends AbstractJpaRepositoryManagement implements DistributionSetTagManagement { - private final DistributionSetRepository distributionSetRepository; - protected JpaDistributionSetTagManagement( final DistributionSetTagRepository distributionSetTagRepository, - final EntityManager entityManager, - final DistributionSetRepository distributionSetRepository) { + final EntityManager entityManager) { super(distributionSetTagRepository, entityManager); - this.distributionSetRepository = distributionSetRepository; - } - - @Override - public Optional findByName(final String name) { - return jpaRepository.findByNameEquals(name); - } - - @Override - public Page findByDistributionSet(final long distributionSetId, final Pageable pageable) { - if (!distributionSetRepository.existsById(distributionSetId)) { - throw new EntityNotFoundException(DistributionSet.class, distributionSetId); - } - - return JpaManagementHelper.findAllWithCountBySpec(jpaRepository, - Collections.singletonList(TagSpecification.ofDistributionSet(distributionSetId)), pageable - ); - } - - @Override - @Transactional - @Retryable(retryFor = { ConcurrencyFailureException.class }, maxAttempts = TX_RT_MAX, backoff = @Backoff(delay = TX_RT_DELAY)) - public void delete(final String tagName) { - final JpaDistributionSetTag dsTag = jpaRepository - .findOne(DistributionSetTagSpecifications.byName(tagName)) - .orElseThrow(() -> new EntityNotFoundException(DistributionSetTag.class, tagName)); - jpaRepository.delete(dsTag); } } \ No newline at end of file diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaRolloutManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaRolloutManagement.java index 42d9791a5..991253afa 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaRolloutManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaRolloutManagement.java @@ -564,8 +564,8 @@ public class JpaRolloutManagement implements RolloutManagement { rollout.setTotalTargets(totalTargets); } - if (((JpaDistributionSetManagement) distributionSetManagement).isImplicitLockApplicable(distributionSet)) { - distributionSetManagement.lock(distributionSet.getId()); + if (distributionSetManagement.shouldLockImplicitly(distributionSet)) { + distributionSetManagement.lock(distributionSet); } if (rollout.getWeight().isEmpty()) { diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaTargetFilterQueryManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaTargetFilterQueryManagement.java index 4242bc86f..3defc80ad 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaTargetFilterQueryManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaTargetFilterQueryManagement.java @@ -33,7 +33,6 @@ import org.eclipse.hawkbit.repository.exception.InvalidAutoAssignActionTypeExcep import org.eclipse.hawkbit.repository.exception.InvalidDistributionSetException; import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException; import org.eclipse.hawkbit.repository.jpa.JpaManagementHelper; -import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet; import org.eclipse.hawkbit.repository.jpa.model.JpaTarget; import org.eclipse.hawkbit.repository.jpa.model.JpaTargetFilterQuery; import org.eclipse.hawkbit.repository.jpa.repository.TargetFilterQueryRepository; @@ -164,11 +163,10 @@ class JpaTargetFilterQueryManagement } else { WeightValidationHelper.usingContext(systemSecurityContext, tenantConfigurationManagement).validate(update); assertMaxTargetsQuota(targetFilterQuery.getQuery(), targetFilterQuery.getName(), update.dsId()); - final JpaDistributionSet distributionSet = (JpaDistributionSet) distributionSetManagement - .getValidAndComplete(update.dsId()); - if (((JpaDistributionSetManagement) distributionSetManagement).isImplicitLockApplicable(distributionSet)) { - distributionSetManagement.lock(distributionSet.getId()); + DistributionSet distributionSet = distributionSetManagement.getValidAndComplete(update.dsId()); + if (distributionSetManagement.shouldLockImplicitly(distributionSet)) { + distributionSet = distributionSetManagement.lock(distributionSet); } targetFilterQuery.setAutoAssignDistributionSet(distributionSet); diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaNamedEntity.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaNamedEntity.java index 62ab39bef..969c21b4e 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaNamedEntity.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaNamedEntity.java @@ -20,6 +20,7 @@ import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; +import lombok.ToString; import org.eclipse.hawkbit.repository.model.NamedEntity; import org.eclipse.hawkbit.repository.model.TenantAwareBaseEntity; @@ -29,6 +30,7 @@ import org.eclipse.hawkbit.repository.model.TenantAwareBaseEntity; @NoArgsConstructor(access = AccessLevel.PROTECTED) // Default constructor needed for JPA entities @Setter @Getter +@ToString(callSuper = true) @MappedSuperclass // exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for sub entities @SuppressWarnings("squid:S2160") diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaNamedVersionedEntity.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaNamedVersionedEntity.java index 2496af0be..4a7d0572c 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaNamedVersionedEntity.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaNamedVersionedEntity.java @@ -16,12 +16,18 @@ import jakarta.persistence.MappedSuperclass; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; import org.eclipse.hawkbit.repository.model.NamedEntity; import org.eclipse.hawkbit.repository.model.NamedVersionedEntity; /** * Extension for {@link NamedEntity} that are versioned. */ +@Setter +@Getter +@ToString(callSuper = true) @MappedSuperclass // exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for sub entities @SuppressWarnings("squid:S2160") @@ -50,13 +56,4 @@ public abstract class AbstractJpaNamedVersionedEntity extends AbstractJpaNamedEn AbstractJpaNamedVersionedEntity() { // Default constructor needed for JPA entities } - - @Override - public String getVersion() { - return version; - } - - public void setVersion(final String version) { - this.version = version; - } } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaDistributionSet.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaDistributionSet.java index 9bd38dec9..2fe260b43 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaDistributionSet.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaDistributionSet.java @@ -124,6 +124,7 @@ public class JpaDistributionSet @Column(name = "complete") private boolean complete; + @Setter @Column(name = "locked") private boolean locked; @@ -213,31 +214,18 @@ public class JpaDistributionSet return tags.remove(tag); } - public void lock() { - if (!isComplete()) { - throw new IncompleteDistributionSetException("Could not be locked while incomplete!"); - } - locked = true; - } - - public void unlock() { - locked = false; - } - public void invalidate() { this.valid = false; } @Override public void fireCreateEvent() { - publishEventWithEventPublisher( - new DistributionSetCreatedEvent(this)); + publishEventWithEventPublisher(new DistributionSetCreatedEvent(this)); } @Override public void fireUpdateEvent() { - publishEventWithEventPublisher( - new DistributionSetUpdatedEvent(this, complete)); + publishEventWithEventPublisher(new DistributionSetUpdatedEvent(this, complete)); if (deleted) { publishEventWithEventPublisher(new DistributionSetDeletedEvent(getTenant(), getId(), getClass())); diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/repository/DistributionSetRepository.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/repository/DistributionSetRepository.java index 8459fca75..47a5adb2c 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/repository/DistributionSetRepository.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/repository/DistributionSetRepository.java @@ -19,7 +19,6 @@ import org.eclipse.hawkbit.repository.jpa.model.JpaStatistic; import org.eclipse.hawkbit.repository.model.Action; import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.Rollout; -import org.eclipse.hawkbit.repository.model.SoftwareModule; import org.eclipse.hawkbit.repository.model.TenantAwareBaseEntity; import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; @@ -65,16 +64,6 @@ public interface DistributionSetRepository extends BaseEntityRepository - * No access control applied. - * - * @param moduleId to search for - * @return {@link List} of found {@link DistributionSet}s - */ - Long countByModulesId(Long moduleId); - /** * Finds {@link DistributionSet}s based on given ID that are assigned yet to an {@link Action}, i.e. in use. *

diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/repository/DistributionSetTagRepository.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/repository/DistributionSetTagRepository.java index e3a1d6f3d..bde8dea98 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/repository/DistributionSetTagRepository.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/repository/DistributionSetTagRepository.java @@ -30,14 +30,6 @@ import org.springframework.transaction.annotation.Transactional; public interface DistributionSetTagRepository extends BaseEntityRepository { - /** - * find {@link DistributionSetTag} by its name. - * - * @param tagName to filter on - * @return the {@link DistributionSetTag} if found, otherwise null - */ - Optional findByNameEquals(String tagName); - /** * Returns all instances of the type. * @@ -58,4 +50,4 @@ public interface DistributionSetTagRepository @Transactional @Query("DELETE FROM JpaDistributionSetTag t WHERE t.tenant = :tenant") void deleteByTenant(@Param("tenant") String tenant); -} +} \ No newline at end of file diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/repository/DistributionSetTypeRepository.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/repository/DistributionSetTypeRepository.java index 509400ced..123a0b675 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/repository/DistributionSetTypeRepository.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/repository/DistributionSetTypeRepository.java @@ -38,17 +38,6 @@ public interface DistributionSetTypeRepository extends BaseEntityRepository @@ -59,4 +48,15 @@ public interface DistributionSetTypeRepository extends BaseEntityRepository findDsByDistributionSetFilter(final DistributionSetFilter distributionSetFilter, final Pageable pageable) { + final List> specList = buildDistributionSetSpecifications(distributionSetFilter); + return JpaManagementHelper.findAllWithoutCountBySpec(distributionSetRepository, specList, pageable); + } + + private static List> buildDistributionSetSpecifications( + final DistributionSetFilter distributionSetFilter) { + final List> specList = new ArrayList<>(10); + + if (distributionSetFilter.getIsComplete() != null) { + specList.add(DistributionSetSpecification.isCompleted(distributionSetFilter.getIsComplete())); + } + if (distributionSetFilter.getIsDeleted() != null) { + specList.add(DistributionSetSpecification.isDeleted(distributionSetFilter.getIsDeleted())); + } + if (distributionSetFilter.getIsValid() != null) { + specList.add(DistributionSetSpecification.isValid(distributionSetFilter.getIsValid())); + } + if (distributionSetFilter.getTypeId() != null) { + specList.add(DistributionSetSpecification.byType(distributionSetFilter.getTypeId())); + } + if (!ObjectUtils.isEmpty(distributionSetFilter.getSearchText())) { + final String[] dsFilterNameAndVersionEntries = JpaManagementHelper + .getFilterNameAndVersionEntries(distributionSetFilter.getSearchText().trim()); + specList.add(DistributionSetSpecification.likeNameAndVersion(dsFilterNameAndVersionEntries[0], dsFilterNameAndVersionEntries[1])); + } + if (hasTagsFilterActive(distributionSetFilter)) { + specList.add(DistributionSetSpecification.hasTags( + distributionSetFilter.getTagNames(), distributionSetFilter.getSelectDSWithNoTag())); + } + return specList; + } + + private static boolean hasTagsFilterActive(final DistributionSetFilter distributionSetFilter) { + final boolean isNoTagActive = Boolean.TRUE.equals(distributionSetFilter.getSelectDSWithNoTag()); + final boolean isAtLeastOneTagActive = !CollectionUtils.isEmpty(distributionSetFilter.getTagNames()); + return isNoTagActive || isAtLeastOneTagActive; + } } \ No newline at end of file diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/acm/DistributionSetAccessControllerTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/acm/DistributionSetAccessControllerTest.java index 3681bac50..4a832319a 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/acm/DistributionSetAccessControllerTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/acm/DistributionSetAccessControllerTest.java @@ -58,7 +58,6 @@ class DistributionSetAccessControllerTest extends AbstractJpaIntegrationTest { final DistributionSet hidden = testdataFactory.createDistributionSet(); final Action permittedAction = testdataFactory.performAssignment(permitted); - final Action hiddenAction = testdataFactory.performAssignment(hidden); runAs(withUser("user", READ_REPOSITORY, @@ -74,15 +73,6 @@ class DistributionSetAccessControllerTest extends AbstractJpaIntegrationTest { assertThat(distributionSetManagement.findByRsql("name==*", Pageable.unpaged()).get().map(Identifiable::getId) .toList()).containsOnly(permittedActionId); - // verify distributionSetManagement#findByCompleted - assertThat(distributionSetManagement.findByCompleted(true, Pageable.unpaged()).get().map(Identifiable::getId) - .toList()).containsOnly(permittedActionId); - - // verify distributionSetManagement#findByDistributionSetFilter - assertThat(distributionSetManagement - .findByDistributionSetFilter(DistributionSetFilter.builder().isDeleted(false).build(), Pageable.unpaged()) - .get().map(Identifiable::getId).toList()).containsOnly(permittedActionId); - // verify distributionSetManagement#get assertThat(distributionSetManagement.get(permittedActionId)).isPresent(); final Long hiddenId = hidden.getId(); @@ -92,11 +82,6 @@ class DistributionSetAccessControllerTest extends AbstractJpaIntegrationTest { assertThat(distributionSetManagement.getWithDetails(permittedActionId)).isPresent(); assertThat(distributionSetManagement.getWithDetails(hiddenId)).isEmpty(); - // verify distributionSetManagement#get - assertThat(distributionSetManagement.getValid(permittedActionId).getId()).isEqualTo(permittedActionId); - assertThatThrownBy(() -> distributionSetManagement.getValid(hiddenId)) - .as("Distribution set should not be found.").isInstanceOf(EntityNotFoundException.class); - // verify distributionSetManagement#get final List allActionIds = Arrays.asList(permittedActionId, hiddenId); assertThatThrownBy(() -> distributionSetManagement.get(allActionIds)) @@ -105,12 +90,6 @@ class DistributionSetAccessControllerTest extends AbstractJpaIntegrationTest { // verify distributionSetManagement#getByNameAndVersion assertThat(distributionSetManagement.findByNameAndVersion(permitted.getName(), permitted.getVersion())).isPresent(); assertThat(distributionSetManagement.findByNameAndVersion(hidden.getName(), hidden.getVersion())).isEmpty(); - - // verify distributionSetManagement#getByAction - assertThat(distributionSetManagement.findByAction(permittedAction.getId())).isPresent(); - final Long hiddenActionId = hiddenAction.getId(); - assertThatThrownBy(() -> distributionSetManagement.findByAction(hiddenActionId)) - .as("Action is hidden.").isInstanceOf(InsufficientPermissionException.class); }); } @@ -254,9 +233,9 @@ class DistributionSetAccessControllerTest extends AbstractJpaIntegrationTest { final DistributionSet readOnly = testdataFactory.createDistributionSet(); final DistributionSet hidden = testdataFactory.createDistributionSet(); // has to lock them, otherwise implicit lock shall be made which require DistributionSet update permissions - distributionSetManagement.lock(permitted.getId()); - distributionSetManagement.lock(readOnly.getId()); - distributionSetManagement.lock(hidden.getId()); + distributionSetManagement.lock(permitted); + distributionSetManagement.lock(readOnly); + distributionSetManagement.lock(hidden); final TargetFilterQuery targetFilterQuery = targetFilterQueryManagement .create(TargetFilterQueryManagement.Create.builder().name("test").query("id==*").build()); diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/acm/TargetAccessControllerTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/acm/TargetAccessControllerTest.java index 19419c470..15c19b558 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/acm/TargetAccessControllerTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/acm/TargetAccessControllerTest.java @@ -196,8 +196,8 @@ class TargetAccessControllerTest extends AbstractJpaIntegrationTest { */ @Test void verifyTargetAssignment() { - final Long dsId = testdataFactory.createDistributionSet("myDs").getId(); - distributionSetManagement.lock(dsId); + final DistributionSet ds = testdataFactory.createDistributionSet("myDs"); + distributionSetManagement.lock(ds); final Target permittedTarget = targetManagement .create(entityFactory.target().create().controllerId("device01").status(TargetUpdateStatus.REGISTERED)); @@ -214,6 +214,7 @@ class TargetAccessControllerTest extends AbstractJpaIntegrationTest { READ_TARGET + "/controllerId==" + permittedTarget.getControllerId(), UPDATE_TARGET + "/controllerId==" + permittedTarget.getControllerId(), READ_REPOSITORY), () -> { + final Long dsId = ds.getId(); assertThat(assignDistributionSet(dsId, permittedTarget.getControllerId()).getAssigned()).isEqualTo(1); // assigning of not allowed target behaves as not found assertThatThrownBy(() -> assignDistributionSet(dsId, hiddenTargetControllerId)).isInstanceOf(AssertionError.class); @@ -233,10 +234,10 @@ class TargetAccessControllerTest extends AbstractJpaIntegrationTest { */ @Test void verifyTargetAssignmentOnNonUpdatableTarget() { - final Long firstDsId = testdataFactory.createDistributionSet("myDs").getId(); - distributionSetManagement.lock(firstDsId); + final DistributionSet firstDs = testdataFactory.createDistributionSet("myDs"); + distributionSetManagement.lock(firstDs); final DistributionSet secondDs = testdataFactory.createDistributionSet("anotherDs"); - distributionSetManagement.lock(secondDs.getId()); + distributionSetManagement.lock(secondDs); final Target manageableTarget = targetManagement .create(entityFactory.target().create().controllerId("device01").status(TargetUpdateStatus.REGISTERED)); @@ -247,6 +248,7 @@ class TargetAccessControllerTest extends AbstractJpaIntegrationTest { READ_TARGET + "/controllerId==" + manageableTarget.getControllerId() + " or controllerId==" + readOnlyTarget.getControllerId(), UPDATE_TARGET + "/controllerId==" + manageableTarget.getControllerId(), READ_REPOSITORY), () -> { + final Long firstDsId = firstDs.getId(); // assignment is permitted for manageableTarget assertThat(assignDistributionSet(firstDsId, manageableTarget.getControllerId()).getAssigned()).isEqualTo(1); @@ -267,7 +269,7 @@ class TargetAccessControllerTest extends AbstractJpaIntegrationTest { @Test void verifyRolloutTargetScope() { final DistributionSet ds = testdataFactory.createDistributionSet("myDs"); - distributionSetManagement.lock(ds.getId()); + distributionSetManagement.lock(ds); final String[] updateTargetControllerIds = { "update1", "update2", "update3" }; final List updateTargets = testdataFactory.createTargets(updateTargetControllerIds); @@ -307,7 +309,7 @@ class TargetAccessControllerTest extends AbstractJpaIntegrationTest { @Test void verifyAutoAssignmentTargetScope() { final DistributionSet distributionSet = testdataFactory.createDistributionSet(); - distributionSetManagement.lock(distributionSet.getId()); + distributionSetManagement.lock(distributionSet); final String[] updateTargetControllerIds = { "update1", "update2", "update3" }; final List updateTargets = testdataFactory.createTargets(updateTargetControllerIds); diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/DeploymentManagementSecurityTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/DeploymentManagementSecurityTest.java index 5531cb044..4385d8713 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/DeploymentManagementSecurityTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/DeploymentManagementSecurityTest.java @@ -63,7 +63,7 @@ class DeploymentManagementSecurityTest extends AbstractJpaIntegrationTest { */ @Test void offlineAssignedDistributionSetsWithInitiatedByPermissionsCheck() { - assertPermissions(() -> deploymentManagement.offlineAssignedDistributionSets(List.of(), "initiator"), + assertPermissions(() -> deploymentManagement.offlineAssignedDistributionSets("initiator", List.of()), List.of(SpPermission.READ_REPOSITORY, SpPermission.UPDATE_TARGET)); } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/DeploymentManagementTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/DeploymentManagementTest.java index 666165d2f..f85c36d44 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/DeploymentManagementTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/DeploymentManagementTest.java @@ -1356,7 +1356,7 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest { } // verify that deleted attribute is used correctly - List allFoundDS = distributionSetManagement.findByCompleted(true, PAGE).getContent(); + List allFoundDS = distributionSetManagement.findAll(PAGE).getContent(); assertThat(allFoundDS).as("no ds should be founded").isEmpty(); assertThat(distributionSetRepository.findAll(SpecificationsBuilder.combineWithAnd(Arrays @@ -1368,16 +1368,13 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest { // try to delete again distributionSetManagement.delete(deploymentResult.getDistributionSetIDs()); - // verify that the result is the same, even though distributionSet dsA - // has been installed - // successfully and no activeAction is referring to created distribution - // sets - allFoundDS = distributionSetManagement.findByCompleted(true, pageRequest).getContent(); + // verify that the result is the same, even though distributionSet dsA has been installed + // successfully and no activeAction is referring to created distribution sets + allFoundDS = distributionSetManagement.findAll(pageRequest).getContent(); assertThat(allFoundDS).as("no ds should be founded").isEmpty(); assertThat(distributionSetRepository.findAll(SpecificationsBuilder.combineWithAnd(Arrays .asList(DistributionSetSpecification.isDeleted(true), DistributionSetSpecification.isCompleted(true))), PAGE).getContent()).as("wrong size of founded ds").hasSize(noOfDistributionSets); - } /** diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/DistributionSetManagementSecurityTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/DistributionSetManagementSecurityTest.java index 986a05f8d..78586a80d 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/DistributionSetManagementSecurityTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/DistributionSetManagementSecurityTest.java @@ -14,11 +14,8 @@ import java.util.Map; import org.eclipse.hawkbit.im.authentication.SpPermission; import org.eclipse.hawkbit.repository.DistributionSetManagement; -import org.eclipse.hawkbit.repository.DistributionSetTypeManagement; import org.eclipse.hawkbit.repository.jpa.AbstractRepositoryManagementSecurityTest; import org.eclipse.hawkbit.repository.model.DistributionSet; -import org.eclipse.hawkbit.repository.model.DistributionSetFilter; -import org.eclipse.hawkbit.repository.model.DistributionSetType; import org.junit.jupiter.api.Test; /** @@ -119,10 +116,8 @@ class DistributionSetManagementSecurityTest */ @Test void lockPermissionsCheck() { - assertPermissions(() -> { - distributionSetManagement.lock(1L); - return null; - }, List.of(SpPermission.UPDATE_REPOSITORY)); + final DistributionSet ds = testdataFactory.createDistributionSet(); + assertPermissions(() -> distributionSetManagement.lock(ds), List.of(SpPermission.UPDATE_REPOSITORY)); } /** @@ -130,18 +125,8 @@ class DistributionSetManagementSecurityTest */ @Test void unlockPermissionsCheck() { - assertPermissions(() -> { - distributionSetManagement.unlock(1L); - return null; - }, List.of(SpPermission.UPDATE_REPOSITORY)); - } - - /** - * Tests ManagementAPI PreAuthorized method with correct and insufficient permissions. - */ - @Test - void getByActionPermissionsCheck() { - assertPermissions(() -> distributionSetManagement.findByAction(1L), List.of(SpPermission.READ_REPOSITORY)); + final DistributionSet ds = testdataFactory.createDistributionSet(); + assertPermissions(() -> distributionSetManagement.unlock(ds), List.of(SpPermission.UPDATE_REPOSITORY)); } /** @@ -168,14 +153,6 @@ class DistributionSetManagementSecurityTest assertPermissions(() -> distributionSetManagement.getValidAndComplete(1L), List.of(SpPermission.READ_REPOSITORY)); } - /** - * Tests ManagementAPI PreAuthorized method with correct and insufficient permissions. - */ - @Test - void getValidPermissionsCheck() { - assertPermissions(() -> distributionSetManagement.getValid(1L), List.of(SpPermission.READ_REPOSITORY)); - } - /** * Tests ManagementAPI PreAuthorized method with correct and insufficient permissions. */ @@ -184,40 +161,6 @@ class DistributionSetManagementSecurityTest assertPermissions(() -> distributionSetManagement.getOrElseThrowException(1L), List.of(SpPermission.READ_REPOSITORY)); } - /** - * Tests ManagementAPI PreAuthorized method with correct and insufficient permissions. - */ - @Test - void findByCompletedPermissionsCheck() { - assertPermissions(() -> distributionSetManagement.findByCompleted(true, PAGE), List.of(SpPermission.READ_REPOSITORY)); - } - - /** - * Tests ManagementAPI PreAuthorized method with correct and insufficient permissions. - */ - @Test - void countByCompletedPermissionsCheck() { - assertPermissions(() -> distributionSetManagement.countByCompleted(true), List.of(SpPermission.READ_REPOSITORY)); - } - - /** - * Tests ManagementAPI PreAuthorized method with correct and insufficient permissions. - */ - @Test - void findByDistributionSetFilterPermissionsCheck() { - assertPermissions(() -> distributionSetManagement.findByDistributionSetFilter(DistributionSetFilter.builder().build(), PAGE), - List.of(SpPermission.READ_REPOSITORY)); - } - - /** - * Tests ManagementAPI PreAuthorized method with correct and insufficient permissions. - */ - @Test - void countByDistributionSetFilterPermissionsCheck() { - assertPermissions(() -> distributionSetManagement.countByDistributionSetFilter(DistributionSetFilter.builder().build()), - List.of(SpPermission.READ_REPOSITORY)); - } - /** * Tests ManagementAPI PreAuthorized method with correct and insufficient permissions. */ @@ -234,14 +177,6 @@ class DistributionSetManagementSecurityTest assertPermissions(() -> distributionSetManagement.findByRsqlAndTag("rsql", 1L, PAGE), List.of(SpPermission.READ_REPOSITORY)); } - /** - * Tests ManagementAPI PreAuthorized method with correct and insufficient permissions. - */ - @Test - void isInUsePermissionsCheck() { - assertPermissions(() -> distributionSetManagement.isInUse(1L), List.of(SpPermission.READ_REPOSITORY)); - } - /** * Tests ManagementAPI PreAuthorized method with correct and insufficient permissions. */ @@ -250,14 +185,6 @@ class DistributionSetManagementSecurityTest assertPermissions(() -> distributionSetManagement.unassignSoftwareModule(1L, 1L), List.of(SpPermission.UPDATE_REPOSITORY)); } - /** - * Tests ManagementAPI PreAuthorized method with correct and insufficient permissions. - */ - @Test - void countByTypeIdPermissionsCheck() { - assertPermissions(() -> distributionSetManagement.countByTypeId(1L), List.of(SpPermission.READ_REPOSITORY)); - } - /** * Tests ManagementAPI PreAuthorized method with correct and insufficient permissions. */ @@ -287,13 +214,8 @@ class DistributionSetManagementSecurityTest */ @Test void invalidatePermissionsCheck() { - final DistributionSetType dsType = distributionSetTypeManagement.create(DistributionSetTypeManagement.Create.builder() - .key("type").name("name").build()); - final DistributionSet ds = distributionSetManagement.create(DistributionSetManagement.Create.builder() - .type(dsType).name("test").version("1.0.0").build()); - assertPermissions(() -> { - ((DistributionSetManagement) distributionSetManagement).invalidate(ds); - return null; - }, List.of(SpPermission.UPDATE_REPOSITORY, SpPermission.READ_REPOSITORY)); + final DistributionSet ds = testdataFactory.createDistributionSet(); + assertPermissions(() -> distributionSetManagement.invalidate(ds), + List.of(SpPermission.UPDATE_REPOSITORY, SpPermission.READ_REPOSITORY)); } } \ No newline at end of file diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/DistributionSetManagementTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/DistributionSetManagementTest.java index 83bea6d79..f3195680e 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/DistributionSetManagementTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/DistributionSetManagementTest.java @@ -42,7 +42,6 @@ import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetUpdated import org.eclipse.hawkbit.repository.event.remote.entity.SoftwareModuleCreatedEvent; import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException; import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException; -import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; import org.eclipse.hawkbit.repository.exception.EntityReadOnlyException; import org.eclipse.hawkbit.repository.exception.IncompleteDistributionSetException; import org.eclipse.hawkbit.repository.exception.InvalidDistributionSetException; @@ -117,8 +116,6 @@ class DistributionSetManagementTest extends AbstractJpaIntegrationTest { verifyThrownExceptionBy( () -> distributionSetManagement.assignSoftwareModules(set.getId(), singletonList(NOT_EXIST_IDL)), "SoftwareModule"); - verifyThrownExceptionBy(() -> distributionSetManagement.countByTypeId(NOT_EXIST_IDL), "DistributionSet"); - verifyThrownExceptionBy(() -> distributionSetManagement.unassignSoftwareModule(NOT_EXIST_IDL, module.getId()), "DistributionSet"); verifyThrownExceptionBy(() -> distributionSetManagement.unassignSoftwareModule(set.getId(), NOT_EXIST_IDL), "SoftwareModule"); @@ -143,27 +140,17 @@ class DistributionSetManagementTest extends AbstractJpaIntegrationTest { verifyThrownExceptionBy(() -> distributionSetManagement.deleteMetadata(NOT_EXIST_IDL, "xxx"), "DistributionSet"); verifyThrownExceptionBy(() -> distributionSetManagement.deleteMetadata(set.getId(), NOT_EXIST_ID), "DistributionSet"); - verifyThrownExceptionBy(() -> distributionSetManagement.findByAction(NOT_EXIST_IDL), "Action"); - verifyThrownExceptionBy(() -> distributionSetManagement.getMetadata(NOT_EXIST_IDL).get("xxx"), "DistributionSet"); - verifyThrownExceptionBy(() -> distributionSetManagement.getMetadata(NOT_EXIST_IDL).get(PAGE), "DistributionSet"); - - assertThatThrownBy(() -> distributionSetManagement.isInUse(NOT_EXIST_IDL)) - .isInstanceOf(EntityNotFoundException.class).hasMessageContaining(NOT_EXIST_ID) - .hasMessageContaining("DistributionSet"); + verifyThrownExceptionBy(() -> distributionSetManagement.getMetadata(NOT_EXIST_IDL), "DistributionSet"); verifyThrownExceptionBy( () -> distributionSetManagement.update(DistributionSetManagement.Update.builder().id(NOT_EXIST_IDL).build()), "DistributionSet"); verifyThrownExceptionBy(() -> distributionSetManagement.createMetadata(NOT_EXIST_IDL, "xxx", "xxx"), "DistributionSet"); - verifyThrownExceptionBy(() -> distributionSetManagement.getOrElseThrowException(NOT_EXIST_IDL), "DistributionSet"); - verifyThrownExceptionBy(() -> distributionSetManagement.getValidAndComplete(NOT_EXIST_IDL), "DistributionSet"); - - verifyThrownExceptionBy(() -> distributionSetManagement.getValid(NOT_EXIST_IDL), "DistributionSet"); } /** @@ -305,7 +292,7 @@ class DistributionSetManagementTest extends AbstractJpaIntegrationTest { .as("ds has wrong tag size") .hasSize(1)); - final DistributionSetTag findDistributionSetTag = getOrThrow(distributionSetTagManagement.findByName(TAG1_NAME)); + final DistributionSetTag findDistributionSetTag = getOrThrow(distributionSetTagManagement.get(tag.getId())); assertThat(assignedDS) .as("assigned ds has wrong size") @@ -315,7 +302,7 @@ class DistributionSetManagementTest extends AbstractJpaIntegrationTest { .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()).as("unassigned ds has wrong tag size").isEmpty(); - assertThat(distributionSetTagManagement.findByName(TAG1_NAME)).isPresent(); + assertThat(distributionSetTagManagement.get(tag.getId())).isPresent(); assertThat(distributionSetManagement.findByTag(tag.getId(), PAGE).getNumberOfElements()) .as("ds tag ds has wrong ds size").isEqualTo(3); @@ -534,7 +521,7 @@ class DistributionSetManagementTest extends AbstractJpaIntegrationTest { assertThat(reloadedDS.getLastModifiedAt()).isPositive(); // verify updated meta data is the updated value - assertThat(distributionSetManagement.getMetadata(ds.getId()).get(knownKey)).isEqualTo(knownUpdateValue); + assertThat(distributionSetManagement.getMetadata(ds.getId())).containsEntry(knownKey, knownUpdateValue); } /** @@ -578,11 +565,11 @@ class DistributionSetManagementTest extends AbstractJpaIntegrationTest { dsDeleted = getOrThrow(distributionSetManagement.get(dsDeleted.getId())); dsGroup1 = assignTag(dsGroup1, dsTagA); - dsTagA = getOrThrow(distributionSetTagRepository.findByNameEquals(dsTagA.getName())); + dsTagA = getOrThrow(distributionSetTagRepository.findById(dsTagA.getId())); dsGroup1 = assignTag(dsGroup1, dsTagB); - dsTagA = getOrThrow(distributionSetTagRepository.findByNameEquals(dsTagA.getName())); + dsTagA = getOrThrow(distributionSetTagRepository.findById(dsTagA.getId())); dsGroup2 = assignTag(dsGroup2, dsTagA); - dsTagA = getOrThrow(distributionSetTagRepository.findByNameEquals(dsTagA.getName())); + dsTagA = getOrThrow(distributionSetTagRepository.findById(dsTagA.getId())); final List allDistributionSets = Stream .of(dsGroup1, dsGroup2, Arrays.asList(dsDeleted, dsInComplete, dsNewType)).flatMap(Collection::stream) @@ -607,33 +594,19 @@ class DistributionSetManagementTest extends AbstractJpaIntegrationTest { validateDeletedAndCompletedAndTypeAndSearchTextAndTag(dsGroup2, dsTagA, dsGroup2Prefix); } - /** - * Simple DS load without the related data that should be loaded lazy. - */ - @Test - void findDistributionSetsWithoutLazy() { - testdataFactory.createDistributionSets(20); - - assertThat(distributionSetManagement.findByCompleted(true, PAGE)).hasSize(20); - } - /** * Locks a DS. */ @Test void lockDistributionSet() { final DistributionSet distributionSet = testdataFactory.createDistributionSet("ds-1"); - assertThat( - distributionSetManagement.get(distributionSet.getId()).map(DistributionSet::isLocked).orElse(true)) - .isFalse(); - distributionSetManagement.lock(distributionSet.getId()); - assertThat( - distributionSetManagement.get(distributionSet.getId()).map(DistributionSet::isLocked).orElse(false)) - .isTrue(); + assertThat(distributionSetManagement.get(distributionSet.getId()).map(DistributionSet::isLocked).orElse(true)).isFalse(); + distributionSetManagement.lock(distributionSet); + assertThat(distributionSetManagement.get(distributionSet.getId()).map(DistributionSet::isLocked).orElse(false)).isTrue(); // assert software modules are locked assertThat(distributionSet.getModules().size()).isNotZero(); - distributionSetManagement.getWithDetails(distributionSet.getId()).map(DistributionSet::getModules) - .orElseThrow().forEach(module -> assertThat(module.isLocked()).isTrue()); + distributionSetManagement.getWithDetails(distributionSet.getId()).map(DistributionSet::getModules).orElseThrow() + .forEach(module -> assertThat(module.isLocked()).isTrue()); } /** @@ -642,11 +615,8 @@ class DistributionSetManagementTest extends AbstractJpaIntegrationTest { @Test void deleteUnassignedLockedDistributionSet() { final DistributionSet distributionSet = testdataFactory.createDistributionSet("ds-1"); - distributionSetManagement.lock(distributionSet.getId()); - assertThat( - distributionSetManagement.get(distributionSet.getId()).map(DistributionSet::isLocked) - .orElse(false)) - .isTrue(); + distributionSetManagement.lock(distributionSet); + assertThat(distributionSetManagement.get(distributionSet.getId()).map(DistributionSet::isLocked).orElse(false)).isTrue(); distributionSetManagement.delete(distributionSet.getId()); assertThat(distributionSetManagement.get(distributionSet.getId())).isEmpty(); @@ -658,11 +628,8 @@ class DistributionSetManagementTest extends AbstractJpaIntegrationTest { @Test void deleteAssignedLockedDistributionSet() { final DistributionSet distributionSet = testdataFactory.createDistributionSet("ds-1"); - distributionSetManagement.lock(distributionSet.getId()); - assertThat( - distributionSetManagement.get(distributionSet.getId()).map(DistributionSet::isLocked) - .orElse(false)) - .isTrue(); + distributionSetManagement.lock(distributionSet); + assertThat(distributionSetManagement.get(distributionSet.getId()).map(DistributionSet::isLocked).orElse(false)).isTrue(); final Target target = testdataFactory.createTarget(); assignDistributionSet(distributionSet.getId(), target.getControllerId()); @@ -676,21 +643,15 @@ class DistributionSetManagementTest extends AbstractJpaIntegrationTest { */ @Test void unlockDistributionSet() { - final DistributionSet distributionSet = testdataFactory.createDistributionSet("ds-1"); - distributionSetManagement.lock(distributionSet.getId()); - assertThat( - distributionSetManagement.get(distributionSet.getId()).map(DistributionSet::isLocked) - .orElse(false)) - .isTrue(); - distributionSetManagement.unlock(distributionSet.getId()); - assertThat( - distributionSetManagement.get(distributionSet.getId()).map(DistributionSet::isLocked) - .orElse(true)) - .isFalse(); + DistributionSet distributionSet = testdataFactory.createDistributionSet("ds-1"); + distributionSet = distributionSetManagement.lock(distributionSet); + assertThat(distributionSetManagement.get(distributionSet.getId()).map(DistributionSet::isLocked).orElse(false)).isTrue(); + distributionSet = distributionSetManagement.unlock(distributionSet); + assertThat(distributionSetManagement.get(distributionSet.getId()).map(DistributionSet::isLocked).orElse(true)).isFalse(); // assert software modules are not unlocked assertThat(distributionSet.getModules().size()).isNotZero(); - distributionSetManagement.getWithDetails(distributionSet.getId()).map(DistributionSet::getModules) - .orElseThrow().forEach(module -> assertThat(module.isLocked()).isTrue()); + distributionSetManagement.getWithDetails(distributionSet.getId()).map(DistributionSet::getModules).orElseThrow() + .forEach(module -> assertThat(module.isLocked()).isTrue()); } /** @@ -701,8 +662,8 @@ class DistributionSetManagementTest extends AbstractJpaIntegrationTest { final DistributionSet distributionSet = testdataFactory.createDistributionSet("ds-1"); final int softwareModuleCount = distributionSet.getModules().size(); assertThat(softwareModuleCount).isNotZero(); + distributionSetManagement.lock(distributionSet); final Long distributionSetId = distributionSet.getId(); - distributionSetManagement.lock(distributionSetId); assertThat(distributionSetManagement.get(distributionSetId).map(DistributionSet::isLocked).orElse(false)).isTrue(); // try add @@ -710,16 +671,16 @@ class DistributionSetManagementTest extends AbstractJpaIntegrationTest { assertThatExceptionOfType(LockedException.class) .as("Attempt to modify a locked DS software modules should throw an exception") .isThrownBy(() -> distributionSetManagement.assignSoftwareModules(distributionSetId, moduleIds)); - assertThat(distributionSetManagement.getWithDetails(distributionSetId).get().getModules()) + assertThat(distributionSetManagement.getWithDetails(distributionSetId).orElseThrow().getModules()) .as("Software module shall not be added to a locked DS.") .hasSize(softwareModuleCount); // try remove - final Long fisrtModuleId = distributionSet.getModules().stream().findFirst().get().getId(); + final Long firstModuleId = distributionSet.getModules().stream().findFirst().orElseThrow().getId(); assertThatExceptionOfType(LockedException.class) .as("Attempt to modify a locked DS software modules should throw an exception") - .isThrownBy(() -> distributionSetManagement.unassignSoftwareModule(distributionSetId, fisrtModuleId)); - assertThat(distributionSetManagement.getWithDetails(distributionSetId).get().getModules()) + .isThrownBy(() -> distributionSetManagement.unassignSoftwareModule(distributionSetId, firstModuleId)); + assertThat(distributionSetManagement.getWithDetails(distributionSetId).orElseThrow().getModules()) .as("Software module shall not be removed from a locked DS.") .hasSize(softwareModuleCount); } @@ -729,11 +690,11 @@ class DistributionSetManagementTest extends AbstractJpaIntegrationTest { */ @SuppressWarnings("rawtypes") @Test - void isImplicitLockApplicableForDistributionSet() { + void shouldLockImplicitlyForDistributionSet() { final JpaDistributionSetManagement distributionSetManagement = (JpaDistributionSetManagement) (DistributionSetManagement) this.distributionSetManagement; final DistributionSet distributionSet = testdataFactory.createDistributionSet("ds-non-skip"); // assert that implicit lock is applicable for non skip tags - assertThat(distributionSetManagement.isImplicitLockApplicable(distributionSet)).isTrue(); + assertThat(distributionSetManagement.shouldLockImplicitly(distributionSet)).isTrue(); assertThat(repositoryProperties.getSkipImplicitLockForTags().size()).isNotZero(); final List skipTags = distributionSetTagManagement.create( @@ -750,7 +711,7 @@ class DistributionSetManagementTest extends AbstractJpaIntegrationTest { distributionSetManagement.assignTag(List.of(distributionSetWithSkipTag.getId()), skipTag.getId()); distributionSetWithSkipTag = distributionSetManagement.get(distributionSetWithSkipTag.getId()).orElseThrow(); // assert that implicit lock isn't applicable for skip tags - assertThat(distributionSetManagement.isImplicitLockApplicable(distributionSetWithSkipTag)).isFalse(); + assertThat(distributionSetManagement.shouldLockImplicitly(distributionSetWithSkipTag)).isFalse(); }); } @@ -759,12 +720,12 @@ class DistributionSetManagementTest extends AbstractJpaIntegrationTest { */ @Test void lockIncompleteDistributionSetFails() { - final long incompleteDistributionSetId = testdataFactory.createIncompleteDistributionSet().getId(); + final DistributionSet incompleteDistributionSet = testdataFactory.createIncompleteDistributionSet(); assertThatExceptionOfType(IncompleteDistributionSetException.class) .as("Locking an incomplete distribution set should throw an exception") - .isThrownBy(() -> distributionSetManagement.lock(incompleteDistributionSetId)); + .isThrownBy(() -> distributionSetManagement.lock(incompleteDistributionSet)); assertThat( - distributionSetManagement.get(incompleteDistributionSetId).map(DistributionSet::isLocked).orElse(true)) + distributionSetManagement.get(incompleteDistributionSet.getId()).map(DistributionSet::isLocked).orElse(true)) .isFalse(); } @@ -781,7 +742,6 @@ class DistributionSetManagementTest extends AbstractJpaIntegrationTest { distributionSetManagement.delete(ds1.getId()); // not assigned so not marked as deleted but fully deleted assertThat(distributionSetRepository.findAll()).hasSize(1); - assertThat(distributionSetManagement.findByCompleted(true, PAGE)).hasSize(1); } /** @@ -851,7 +811,6 @@ class DistributionSetManagementTest extends AbstractJpaIntegrationTest { // not assigned so not marked as deleted assertThat(distributionSetRepository.findAll()).hasSize(4); - assertThat(distributionSetManagement.findByCompleted(true, PAGE)).hasSize(2); assertThat(distributionSetManagement.findAll(PAGE)).hasSize(2); assertThat(distributionSetManagement.findByRsql("name==*", PAGE)).hasSize(2); assertThat(distributionSetManagement.count()).isEqualTo(2); @@ -887,10 +846,6 @@ class DistributionSetManagementTest extends AbstractJpaIntegrationTest { @Test void verifyGetValid() { final Long distributionSetId = testdataFactory.createAndInvalidateDistributionSet().getId(); - - assertThatExceptionOfType(InvalidDistributionSetException.class) - .as("Invalid distributionSet should throw an exception") - .isThrownBy(() -> distributionSetManagement.getValid(distributionSetId)); assertThatExceptionOfType(InvalidDistributionSetException.class) .as("Invalid distributionSet should throw an exception") .isThrownBy(() -> distributionSetManagement.getValidAndComplete(distributionSetId)); @@ -1098,7 +1053,6 @@ class DistributionSetManagementTest extends AbstractJpaIntegrationTest { } private void validateDeleted(final DistributionSet deletedDistributionSet, final int notDeletedSize) { - assertThatFilterContainsOnlyGivenDistributionSets(DistributionSetFilter.builder().isDeleted(Boolean.TRUE), singletonList(deletedDistributionSet)); @@ -1107,7 +1061,6 @@ class DistributionSetManagementTest extends AbstractJpaIntegrationTest { } private void validateCompleted(final DistributionSet dsIncomplete, final int completedSize) { - assertThatFilterHasSizeAndDoesNotContainDistributionSet( DistributionSetFilter.builder().isComplete(Boolean.TRUE), completedSize, dsIncomplete); @@ -1115,8 +1068,7 @@ class DistributionSetManagementTest extends AbstractJpaIntegrationTest { DistributionSetFilter.builder().isComplete(Boolean.FALSE), singletonList(dsIncomplete)); } - private void validateType(final DistributionSetType newType, final DistributionSet dsNewType, - final int standardDsTypeSize) { + private void validateType(final DistributionSetType newType, final DistributionSet dsNewType, final int standardDsTypeSize) { assertThatFilterContainsOnlyGivenDistributionSets(DistributionSetFilter.builder().typeId(newType.getId()), singletonList(dsNewType)); assertThatFilterHasSizeAndDoesNotContainDistributionSet( @@ -1277,19 +1229,17 @@ class DistributionSetManagementTest extends AbstractJpaIntegrationTest { private void assertThatFilterContainsOnlyGivenDistributionSets(final DistributionSetFilterBuilder filterBuilder, final List distributionSets) { final int expectedDsSize = distributionSets.size(); - assertThat(((DistributionSetManagement)distributionSetManagement).findByDistributionSetFilter(filterBuilder.build(), PAGE).getContent()) - .hasSize(expectedDsSize).containsOnly(distributionSets.toArray(new DistributionSet[expectedDsSize])); + assertThat(findDsByDistributionSetFilter(filterBuilder.build(), PAGE).getContent()) + .hasSize(expectedDsSize).containsOnly(distributionSets.toArray(new JpaDistributionSet[expectedDsSize])); } private void assertThatFilterDoesNotContainAnyDistributionSet(final DistributionSetFilterBuilder filterBuilder) { - assertThat(distributionSetManagement.findByDistributionSetFilter(filterBuilder.build(), PAGE).getContent()) - .isEmpty(); + assertThat(findDsByDistributionSetFilter(filterBuilder.build(), PAGE).getContent()).isEmpty(); } private void assertThatFilterHasSizeAndDoesNotContainDistributionSet( final DistributionSetFilterBuilder filterBuilder, final int size, final DistributionSet ds) { - assertThat(((DistributionSetManagement)distributionSetManagement).findByDistributionSetFilter(filterBuilder.build(), PAGE).getContent()) - .hasSize(size).doesNotContain(ds); + assertThat((List)findDsByDistributionSetFilter(filterBuilder.build(), PAGE).getContent()).hasSize(size).doesNotContain(ds); } // can be removed with java-11 diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/DistributionSetTagManagementSecurityTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/DistributionSetTagManagementSecurityTest.java index 1c7c0ee08..0724d6e60 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/DistributionSetTagManagementSecurityTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/DistributionSetTagManagementSecurityTest.java @@ -41,32 +41,4 @@ class DistributionSetTagManagementSecurityTest protected DistributionSetTagManagement.Update getUpdateObject() { return DistributionSetTagManagement.Update.builder().id(1L).name("tag").build(); } - - /** - * Tests ManagementAPI PreAuthorized method with correct and insufficient permissions. - */ - @Test - void getByNameWitPermissionWorks() { - assertPermissions(() -> distributionSetTagManagement.findByName("tagName"), List.of(SpPermission.READ_REPOSITORY)); - } - - /** - * Tests ManagementAPI PreAuthorized method with correct and insufficient permissions. - */ - @Test - void findByDistributionSetPermissionsCheck() { - assertPermissions(() -> distributionSetTagManagement.findByDistributionSet(1L, Pageable.unpaged()), - List.of(SpPermission.READ_REPOSITORY)); - } - - /** - * Tests ManagementAPI PreAuthorized method with correct and insufficient permissions. - */ - @Test - void deleteDistributionSetTagPermissionsCheck() { - assertPermissions(() -> { - distributionSetTagManagement.delete("tagName"); - return null; - }, List.of(SpPermission.DELETE_REPOSITORY)); - } } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/DistributionSetTagManagementTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/DistributionSetTagManagementTest.java index 0dd1d7012..9e75f80bf 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/DistributionSetTagManagementTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/DistributionSetTagManagementTest.java @@ -45,15 +45,12 @@ import org.springframework.data.domain.Pageable; */ class DistributionSetTagManagementTest extends AbstractJpaIntegrationTest { - private static final Random RND = new Random(); - /** * Verifies that management get access reacts as specified on calls for non existing entities by means of Optional not present. */ @Test @ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 0) }) void nonExistingEntityAccessReturnsNotPresent() { - assertThat(distributionSetTagManagement.findByName(NOT_EXIST_ID)).isNotPresent(); assertThat(distributionSetTagManagement.get(NOT_EXIST_IDL)).isNotPresent(); } @@ -66,8 +63,7 @@ class DistributionSetTagManagementTest extends AbstractJpaIntegrationTest { @Expect(type = DistributionSetTagUpdatedEvent.class, count = 0), @Expect(type = TargetTagUpdatedEvent.class, count = 0) }) void entityQueriesReferringToNotExistingEntitiesThrowsException() { - verifyThrownExceptionBy(() -> distributionSetTagManagement.delete(NOT_EXIST_ID), "DistributionSetTag"); - verifyThrownExceptionBy(() -> distributionSetTagManagement.findByDistributionSet(NOT_EXIST_IDL, PAGE), "DistributionSet"); + verifyThrownExceptionBy(() -> distributionSetTagManagement.delete(NOT_EXIST_IDL), "DistributionSetTag"); verifyThrownExceptionBy(() -> distributionSetTagManagement.update( DistributionSetTagManagement.Update.builder().id(NOT_EXIST_IDL).build()), "DistributionSetTag"); } @@ -95,18 +91,18 @@ class DistributionSetTagManagementTest extends AbstractJpaIntegrationTest { assignTag(dsBs, tagB); assignTag(dsCs, tagC); - assignTag(dsABs, distributionSetTagManagement.findByName(tagA.getName()).get()); - assignTag(dsABs, distributionSetTagManagement.findByName(tagB.getName()).get()); + assignTag(dsABs, distributionSetTagManagement.get(tagA.getId()).orElseThrow()); + assignTag(dsABs, distributionSetTagManagement.get(tagB.getId()).orElseThrow()); - assignTag(dsACs, distributionSetTagManagement.findByName(tagA.getName()).get()); - assignTag(dsACs, distributionSetTagManagement.findByName(tagC.getName()).get()); + assignTag(dsACs, distributionSetTagManagement.get(tagA.getId()).orElseThrow()); + assignTag(dsACs, distributionSetTagManagement.get(tagC.getId()).orElseThrow()); - assignTag(dsBCs, distributionSetTagManagement.findByName(tagB.getName()).get()); - assignTag(dsBCs, distributionSetTagManagement.findByName(tagC.getName()).get()); + assignTag(dsBCs, distributionSetTagManagement.get(tagB.getId()).orElseThrow()); + assignTag(dsBCs, distributionSetTagManagement.get(tagC.getId()).orElseThrow()); - assignTag(dsABCs, distributionSetTagManagement.findByName(tagA.getName()).get()); - assignTag(dsABCs, distributionSetTagManagement.findByName(tagB.getName()).get()); - assignTag(dsABCs, distributionSetTagManagement.findByName(tagC.getName()).get()); + assignTag(dsABCs, distributionSetTagManagement.get(tagA.getId()).orElseThrow()); + assignTag(dsABCs, distributionSetTagManagement.get(tagB.getId()).orElseThrow()); + assignTag(dsABCs, distributionSetTagManagement.get(tagC.getId()).orElseThrow()); // search for not deleted final DistributionSetFilter.DistributionSetFilterBuilder distributionSetFilterBuilder = getDistributionSetFilterBuilder() @@ -121,11 +117,11 @@ class DistributionSetTagManagementTest extends AbstractJpaIntegrationTest { Stream.empty()); assertThat(distributionSetTagRepository.findAll()).hasSize(5); - distributionSetTagManagement.delete(tagY.getName()); + distributionSetTagManagement.delete(tagY.getId()); assertThat(distributionSetTagRepository.findAll()).hasSize(4); - distributionSetTagManagement.delete(tagX.getName()); + distributionSetTagManagement.delete(tagX.getId()); assertThat(distributionSetTagRepository.findAll()).hasSize(3); - distributionSetTagManagement.delete(tagB.getName()); + distributionSetTagManagement.delete(tagB.getId()); assertThat(distributionSetTagRepository.findAll()).hasSize(2); verifyExpectedFilteredDistributionSets(distributionSetFilterBuilder.tagNames(Arrays.asList(tagA.getName())), @@ -217,11 +213,11 @@ class DistributionSetTagManagementTest extends AbstractJpaIntegrationTest { final Tag tag = distributionSetTagManagement .create(DistributionSetTagManagement.Create.builder().name("kai1").description("kai2").colour("colour").build()); - assertThat(distributionSetTagRepository.findByNameEquals("kai1").get().getDescription()).as("wrong tag found") + assertThat(distributionSetTagRepository.findById(tag.getId()).orElseThrow().getDescription()).as("wrong tag found") .isEqualTo("kai2"); - assertThat(distributionSetTagManagement.findByName("kai1").get().getColour()).as("wrong tag found") + assertThat(distributionSetTagManagement.get(tag.getId()).orElseThrow().getColour()).as("wrong tag found") .isEqualTo("colour"); - assertThat(distributionSetTagManagement.get(tag.getId()).get().getColour()).as("wrong tag found") + assertThat(distributionSetTagManagement.get(tag.getId()).orElseThrow().getColour()).as("wrong tag found") .isEqualTo("colour"); } @@ -240,7 +236,7 @@ class DistributionSetTagManagementTest extends AbstractJpaIntegrationTest { } // delete - distributionSetTagManagement.delete(tags.iterator().next().getName()); + distributionSetTagManagement.delete(tags.iterator().next().getId()); // check assertThat(distributionSetTagRepository.findById(toDelete.getId())).as("Deleted tag should be null") @@ -321,8 +317,7 @@ class DistributionSetTagManagementTest extends AbstractJpaIntegrationTest { private void verifyExpectedFilteredDistributionSets(final DistributionSetFilter.DistributionSetFilterBuilder distributionSetFilterBuilder, final Stream> expectedFilteredDistributionSets) { - final Collection retrievedFilteredDsIds = distributionSetManagement - .findByDistributionSetFilter(distributionSetFilterBuilder.build(), PAGE).stream() + final Collection retrievedFilteredDsIds = findDsByDistributionSetFilter(distributionSetFilterBuilder.build(), PAGE).stream() .map(DistributionSet::getId).toList(); final Collection expectedFilteredDsIds = expectedFilteredDistributionSets.flatMap(Collection::stream) .map(DistributionSet::getId).toList(); diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/RolloutManagementTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/RolloutManagementTest.java index 9d10337d9..3ea7eb150 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/RolloutManagementTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/RolloutManagementTest.java @@ -1424,11 +1424,11 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest { * Verify the creation and the start of a rollout. */ @Test - void createScheduledRollout() throws Exception { + void createScheduledRollout() { final String rolloutName = "scheduledRolloutTest"; testdataFactory.createTargets(50, rolloutName + "-", rolloutName); final DistributionSet distributionSet = testdataFactory.createDistributionSet("dsFor" + rolloutName); - distributionSetManagement.lock(distributionSet.getId()); + distributionSetManagement.lock(distributionSet); final WithUser userWithoutHandleRollout = SecurityContextSwitch.withUser( "user_without_handle_rollout", diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/SoftwareModuleManagementTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/SoftwareModuleManagementTest.java index d7b22efc5..a8bda4052 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/SoftwareModuleManagementTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/SoftwareModuleManagementTest.java @@ -194,18 +194,16 @@ class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest { assertThat(softwareModuleManagement.findByTextAndType("oracle", runtimeType.getId(), PAGE).getContent()) .hasSize(1); assertThat( - softwareModuleManagement.findByTextAndType("oracle", runtimeType.getId(), PAGE).getContent().get(0)) - .isEqualTo(jvm); + softwareModuleManagement.findByTextAndType("oracle", runtimeType.getId(), PAGE).getContent().get(0)).isEqualTo(jvm); assertThat(softwareModuleManagement.findByTextAndType(":1.0.1", appType.getId(), PAGE).getContent()).hasSize(1) .first().isEqualTo(ah); assertThat(softwareModuleManagement.findByTextAndType(":1.0", appType.getId(), PAGE).getContent()).hasSize(2); - distributionSetManagement.unlock(ds.getId()); // otherwise delete will be rejected as a part of a locked DS + distributionSetManagement.unlock(ds); // otherwise delete will be rejected as a part of a locked DS softwareModuleManagement.delete(ah2.getId()); assertThat(softwareModuleManagement.findByTextAndType(":1.0", appType.getId(), PAGE).getContent()).hasSize(1); - assertThat(softwareModuleManagement.findByTextAndType(":1.0", appType.getId(), PAGE).getContent().get(0)) - .isEqualTo(ah); + assertThat(softwareModuleManagement.findByTextAndType(":1.0", appType.getId(), PAGE).getContent().get(0)).isEqualTo(ah); } /** @@ -429,16 +427,16 @@ class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest { final Artifact artifactY = moduleY.getArtifacts().iterator().next(); // [STEP3]: Assign SoftwareModuleX to DistributionSetX and to target - final DistributionSet disSetX = testdataFactory.createDistributionSet(Set.of(moduleX), "X"); - assignDistributionSet(disSetX, Collections.singletonList(target)); + final DistributionSet disSetX = assignDistributionSet(testdataFactory.createDistributionSet(Set.of(moduleX), "X"), List.of(target)) + .getDistributionSet(); // [STEP4]: Assign SoftwareModuleY to DistributionSet and to target - final DistributionSet disSetY = testdataFactory.createDistributionSet(Set.of(moduleY), "Y"); - assignDistributionSet(disSetY, Collections.singletonList(target)); + final DistributionSet disSetY = assignDistributionSet(testdataFactory.createDistributionSet(Set.of(moduleY), "Y"), List.of(target)) + .getDistributionSet(); // [STEP5]: Delete SoftwareModuleX - distributionSetManagement.unlock(disSetX.getId()); // otherwise delete will be rejected as a part of a locked DS - distributionSetManagement.unlock(disSetY.getId()); // otherwise delete will be rejected as a part of a locked DS + distributionSetManagement.unlock(disSetX); // otherwise delete will be rejected as a part of a locked DS + distributionSetManagement.unlock(disSetY); // otherwise delete will be rejected as a part of a locked DS softwareModuleManagement.delete(moduleX.getId()); // [STEP6]: Delete SoftwareModuleY @@ -757,10 +755,8 @@ class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest { // try to delete while DS is not locked softwareModuleManagement.delete(modules.get(0).getId()); - distributionSetManagement.lock(distributionSet.getId()); - assertThat( - distributionSetManagement.get(distributionSet.getId()).map(DistributionSet::isLocked).orElse(false)) - .isTrue(); + distributionSetManagement.lock(distributionSet); + assertThat(distributionSetManagement.get(distributionSet.getId()).map(DistributionSet::isLocked).orElse(false)).isTrue(); // try to delete SM of a locked DS final Long moduleId = modules.get(1).getId(); @@ -772,7 +768,7 @@ class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest { private Action assignSet(final JpaTarget target, final JpaDistributionSet ds) { assignDistributionSet(ds.getId(), target.getControllerId()); implicitLock(ds); - assertThat(targetManagement.getByControllerID(target.getControllerId()).get().getUpdateStatus()) + assertThat(targetManagement.getByControllerID(target.getControllerId()).orElseThrow().getUpdateStatus()) .isEqualTo(TargetUpdateStatus.PENDING); final Optional assignedDistributionSet = deploymentManagement .getAssignedDistributionSet(target.getControllerId()); diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/tenancy/MultiTenancyEntityTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/tenancy/MultiTenancyEntityTest.java index 631d467b1..17a10ba10 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/tenancy/MultiTenancyEntityTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/tenancy/MultiTenancyEntityTest.java @@ -28,9 +28,8 @@ import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.data.domain.Slice; /** - * Multi-Tenancy tests which testing the CRUD operations of entities that all - * CRUD-Operations are tenant aware and cannot access or delete entities not - * belonging to the current tenant. + * Multi-Tenancy tests which testing the CRUD operations of entities that all CRUD-Operations are tenant aware and cannot access + * or delete entities not belonging to the current tenant. *

* Feature: Component Tests - Repository
* Story: Multi Tenancy @@ -201,6 +200,6 @@ class MultiTenancyEntityTest extends AbstractJpaIntegrationTest { } private Slice findDistributionSetForTenant(final String tenant) throws Exception { - return runAsTenant(tenant, () -> distributionSetManagement.findByCompleted(true, PAGE)); + return runAsTenant(tenant, () -> distributionSetManagement.findAll(PAGE)); } } \ No newline at end of file diff --git a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/AbstractIntegrationTest.java b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/AbstractIntegrationTest.java index 2982e95bb..307e80ffc 100644 --- a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/AbstractIntegrationTest.java +++ b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/AbstractIntegrationTest.java @@ -25,6 +25,7 @@ import java.util.Comparator; import java.util.List; import java.util.NoSuchElementException; import java.util.Optional; +import java.util.Random; import lombok.extern.slf4j.Slf4j; import org.apache.commons.io.FileUtils; @@ -117,6 +118,7 @@ public abstract class AbstractIntegrationTest { protected static final Pageable PAGE = PageRequest.of(0, 500, Sort.by(Direction.ASC, "id")); protected static final URI LOCALHOST = URI.create("http://127.0.0.1"); protected static final int DEFAULT_TEST_WEIGHT = 500; + protected static final Random RND = new Random(); /** * Number of {@link DistributionSetType}s that exist in every test case. One @@ -286,14 +288,12 @@ public abstract class AbstractIntegrationTest { return defaultDsType().getMandatoryModuleTypes().stream().findAny().orElseThrow(); } - protected static Action getFirstAssignedAction( - final DistributionSetAssignmentResult distributionSetAssignmentResult) { + protected static Action getFirstAssignedAction(final DistributionSetAssignmentResult distributionSetAssignmentResult) { return distributionSetAssignmentResult.getAssignedEntity().stream().findFirst() .orElseThrow(() -> new IllegalStateException("expected one assigned action, found none")); } - protected static Long getFirstAssignedActionId( - final DistributionSetAssignmentResult distributionSetAssignmentResult) { + protected static Long getFirstAssignedActionId(final DistributionSetAssignmentResult distributionSetAssignmentResult) { return getFirstAssignedAction(distributionSetAssignmentResult).getId(); } @@ -313,13 +313,12 @@ public abstract class AbstractIntegrationTest { return TestdataFactory.randomBytes(len); } - protected DistributionSetAssignmentResult assignDistributionSet(final long dsID, final String controllerId) { - return assignDistributionSet(dsID, controllerId, ActionType.FORCED); + protected DistributionSetAssignmentResult assignDistributionSet(final long dsId, final String controllerId) { + return assignDistributionSet(dsId, controllerId, ActionType.FORCED); } - protected DistributionSetAssignmentResult assignDistributionSet( - final long dsID, final String controllerId, final ActionType actionType) { - return assignDistributionSet(dsID, Collections.singletonList(controllerId), actionType); + protected DistributionSetAssignmentResult assignDistributionSet(final long dsId, final String controllerId, final ActionType actionType) { + return assignDistributionSet(dsId, Collections.singletonList(controllerId), actionType); } protected DistributionSetAssignmentResult assignDistributionSet( @@ -333,8 +332,8 @@ public abstract class AbstractIntegrationTest { } protected DistributionSetAssignmentResult assignDistributionSet( - final long dsID, final List controllerIds, final ActionType actionType, final long forcedTime) { - return assignDistributionSet(dsID, controllerIds, actionType, forcedTime, null); + final long dsId, final List controllerIds, final ActionType actionType, final long forcedTime) { + return assignDistributionSet(dsId, controllerIds, actionType, forcedTime, null); } protected DistributionSetAssignmentResult assignDistributionSet(