From 4d104873dee342630b482d0330ce23e2dccb96cf Mon Sep 17 00:00:00 2001 From: Avgustin Marinov Date: Fri, 8 Mar 2024 09:19:11 +0200 Subject: [PATCH] [#1651] Add SoftwareModule and DistributionSet unlock (Mgmt) (#1676) Signed-off-by: Marinov Avgustin --- .../repository/DistributionSetManagement.java | 11 +++++++++ .../repository/SoftwareModuleManagement.java | 11 +++++++++ .../JpaDistributionSetManagement.java | 12 ++++++++++ .../JpaSoftwareModuleManagement.java | 14 +++++++++++ .../jpa/model/JpaDistributionSet.java | 4 ++++ .../jpa/model/JpaSoftwareModule.java | 4 ++++ .../DistributionSetManagementTest.java | 24 +++++++++++++++++++ .../SoftwareModuleManagementTest.java | 14 +++++++++++ 8 files changed, 94 insertions(+) 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 9dbf93d202..5d4e4b0b15 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 @@ -144,6 +144,17 @@ public interface DistributionSetManagement @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) void 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(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + void unlock(final long id); + /** * Retrieves the distribution set for a given action. * diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SoftwareModuleManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SoftwareModuleManagement.java index dc7fa41e9d..b305fc7b7c 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SoftwareModuleManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SoftwareModuleManagement.java @@ -336,6 +336,17 @@ Slice findAllOrderBySetAssignmentAndModuleNameAscModuleV @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) void lock(long id); + /** + * Unlocks a software module.
+ * Use it with extreme care! In general once software module is locked + * it shall not be unlocked. Note that it could have been assigned / deployed to targets. + * + * @param id the software module id + * @throws EntityNotFoundException if software module with given ID does not exist + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + void unlock(long id); + /** * Updates a distribution set meta data value if corresponding entry exists. * 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 3aa14e13b6..eaab8dfd2e 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 @@ -710,6 +710,18 @@ public void lock(final long id) { } } + @Override + @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) + public void unlock(final long id) { + final JpaDistributionSet distributionSet = getById(id); + if (distributionSet.isLocked()) { + distributionSet.unlock(); + distributionSetRepository.save(distributionSet); + } + } + @Override @Transactional @Retryable(include = { diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaSoftwareModuleManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaSoftwareModuleManagement.java index 2815fb867d..b67dc897b7 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaSoftwareModuleManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaSoftwareModuleManagement.java @@ -633,6 +633,20 @@ public void lock(final long id) { } } + @Override + @Transactional + @Retryable(include = { + ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) + public void unlock(final long id) { + final JpaSoftwareModule softwareModule = softwareModuleRepository + .findById(id) + .orElseThrow(() -> new EntityNotFoundException(SoftwareModule.class, id)); + if (softwareModule.isLocked()) { + softwareModule.unlock(); + softwareModuleRepository.save(softwareModule); + } + } + @Override @Transactional @Retryable(include = { 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 43a7e72eb0..c707177569 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 @@ -268,6 +268,10 @@ public void lock() { locked = true; } + public void unlock() { + locked = false; + } + public void setDeleted(final boolean deleted) { this.deleted = deleted; } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaSoftwareModule.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaSoftwareModule.java index 6827ce62eb..3c366e3adc 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaSoftwareModule.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaSoftwareModule.java @@ -177,6 +177,10 @@ public void lock() { locked = true; } + public void unlock() { + locked = false; + } + /** * Marks or un-marks this software module as deleted. * 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 205e82bd7f..68f1fd378d 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 @@ -1008,6 +1008,30 @@ void lockDistributionSet() { distributionSetManagement.get(distributionSet.getId()).map(DistributionSet::isLocked) .orElse(false)) .isTrue(); + // assert software modules are locked + assertThat(distributionSet.getModules().size()).isNotEqualTo(0); + distributionSetManagement.get(distributionSet.getId()).map(DistributionSet::getModules) + .orElseThrow().forEach(module -> assertThat(module.isLocked()).isTrue()); + } + + @Test + @Description("Unlocks a DS.") + 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(); + // assert software modules are not unlocked + assertThat(distributionSet.getModules().size()).isNotEqualTo(0); + distributionSetManagement.get(distributionSet.getId()).map(DistributionSet::getModules) + .orElseThrow().forEach(module -> assertThat(module.isLocked()).isTrue()); } @Test 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 8e9fb5e20b..75c898b152 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 @@ -839,6 +839,20 @@ void lockSoftwareModule() { .isTrue(); } + @Test + @Description("Unlocks a SM.") + void unlockSoftwareModule() { + final SoftwareModule softwareModule = testdataFactory.createSoftwareModule("sm-1"); + softwareModuleManagement.lock(softwareModule.getId()); + assertThat( + softwareModuleManagement.get(softwareModule.getId()).map(SoftwareModule::isLocked).orElse(false)) + .isTrue(); + softwareModuleManagement.unlock(softwareModule.getId()); + assertThat( + softwareModuleManagement.get(softwareModule.getId()).map(SoftwareModule::isLocked).orElse(true)) + .isFalse(); + } + @Test @Description("Artifacts of a locked SM can't be modified. Expected behaviour is to throw an exception and to do not modify them.") void lockSoftwareModuleApplied() {