[#1580] Software Module & Distribution Set lock: implicit (#1649)

Signed-off-by: Marinov Avgustin <Avgustin.Marinov@bosch.com>
This commit is contained in:
Avgustin Marinov
2024-02-18 23:01:55 +02:00
committed by GitHub
parent 94576bd6fe
commit 9e76223a91
34 changed files with 630 additions and 293 deletions

View File

@@ -15,7 +15,9 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
import org.eclipse.hawkbit.mgmt.json.model.distributionset.MgmtActionType;
import org.eclipse.hawkbit.repository.jpa.RepositoryApplicationConfiguration;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet;
import org.eclipse.hawkbit.repository.model.BaseEntity;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.NamedEntity;
import org.eclipse.hawkbit.repository.model.NamedVersionedEntity;
import org.eclipse.hawkbit.repository.model.Tag;
@@ -223,4 +225,12 @@ public abstract class AbstractManagementApiIntegrationTest extends AbstractRestI
return new JSONObject();
}
}
// the set is a candidate for implicitly locking. So, lock it if not already locked
// set lock flag to true to avoid re-locking
static void implicitLock(final DistributionSet set) {
if (!set.isLocked()) {
((JpaDistributionSet) set).setOptLockRevision(set.getOptLockRevision() + 1);
((JpaDistributionSet) set).lock();
}
}
}

View File

@@ -30,7 +30,7 @@ import org.eclipse.hawkbit.exception.SpServerError;
import org.eclipse.hawkbit.mgmt.json.model.distributionset.MgmtActionType;
import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants;
import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.exception.DeletedException;
import org.eclipse.hawkbit.repository.exception.IncompleteDistributionSetException;
import org.eclipse.hawkbit.repository.exception.InvalidAutoAssignActionTypeException;
import org.eclipse.hawkbit.repository.model.Action;
@@ -427,20 +427,21 @@ public class MgmtTargetFilterQueryResourceTest extends AbstractManagementApiInt
@Description("Ensures that the update of a target filter query results in a HTTP Forbidden error (403) "
+ "if the updated query addresses too many targets.")
public void updateTargetFilterQueryWithQueryThatExceedsQuota() throws Exception {
// create targets
final int maxTargets = quotaManagement.getMaxTargetsPerAutoAssignment();
testdataFactory.createTargets(maxTargets + 1, "target");
final TargetFilterQuery filterQuery = createSingleTargetFilterQuery("1", "controllerId==target1");
// create the filter query and the distribution set
final DistributionSet set = testdataFactory.createDistributionSet();
final TargetFilterQuery filterQuery = createSingleTargetFilterQuery("1", "controllerId==target1");
// assign the auto-assign distribution set, this should work
mvc.perform(
post(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/" + filterQuery.getId() + "/autoAssignDS")
.content("{\"id\":" + set.getId() + "}").contentType(MediaType.APPLICATION_JSON))
.andDo(print()).andExpect(status().isOk());
implicitLock(set);
final TargetFilterQuery updatedFilterQuery = targetFilterQueryManagement.get(filterQuery.getId()).get();
@@ -469,23 +470,18 @@ public class MgmtTargetFilterQueryResourceTest extends AbstractManagementApiInt
enableConfirmationFlow();
}
final DistributionSet set = testdataFactory.createDistributionSet();
final TargetFilterQuery tfq = createSingleTargetFilterQuery(knownName, knownQuery);
// set will be locked after first assignment
final DistributionSet set = testdataFactory.createDistributionSet();
verifyAutoAssignmentWithoutActionType(tfq, set, confirmationRequired);
verifyAutoAssignmentWithForcedActionType(tfq, set, confirmationRequired);
verifyAutoAssignmentWithSoftActionType(tfq, set, confirmationRequired);
verifyAutoAssignmentWithTimeForcedActionType(tfq, set);
verifyAutoAssignmentWithDownloadOnlyActionType(tfq, set, confirmationRequired);
verifyAutoAssignmentWithUnknownActionType(tfq, set);
verifyAutoAssignmentWithIncompleteDs(tfq);
verifyAutoAssignmentWithSoftDeletedDs(tfq);
}
@@ -500,8 +496,9 @@ public class MgmtTargetFilterQueryResourceTest extends AbstractManagementApiInt
enableConfirmationFlow();
}
final DistributionSet set = testdataFactory.createDistributionSet();
final TargetFilterQuery tfq = createSingleTargetFilterQuery(knownName, knownQuery);
// set will be implicitly locked
final DistributionSet set = testdataFactory.createDistributionSet();
// do not provide something about the confirmation
verifyAutoAssignmentByActionType(tfq, set, null, null);
@@ -551,6 +548,7 @@ public class MgmtTargetFilterQueryResourceTest extends AbstractManagementApiInt
mvc.perform(post(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/" + tfq.getId() + "/autoAssignDS")
.content(jsonObject.toString()).contentType(MediaType.APPLICATION_JSON)).andDo(print())
.andExpect(status().isOk());
implicitLock(set);
final TargetFilterQuery updatedFilterQuery = targetFilterQueryManagement.get(tfq.getId()).get();
final MgmtActionType expectedActionType = actionType != null ? actionType : MgmtActionType.FORCED;
@@ -623,8 +621,8 @@ public class MgmtTargetFilterQueryResourceTest extends AbstractManagementApiInt
mvc.perform(post(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/" + tfq.getId() + "/autoAssignDS")
.content("{\"id\":" + softDeletedDs.getId() + "}").contentType(MediaType.APPLICATION_JSON))
.andDo(print()).andExpect(status().isNotFound())
.andExpect(jsonPath(JSON_PATH_EXCEPTION_CLASS, equalTo(EntityNotFoundException.class.getName())))
.andExpect(jsonPath(JSON_PATH_ERROR_CODE, equalTo(SpServerError.SP_REPO_ENTITY_NOT_EXISTS.getKey())));
.andExpect(jsonPath(JSON_PATH_EXCEPTION_CLASS, equalTo(DeletedException.class.getName())))
.andExpect(jsonPath(JSON_PATH_ERROR_CODE, equalTo(SpServerError.SP_DELETED.getKey())));
}
@Test
@@ -677,7 +675,6 @@ public class MgmtTargetFilterQueryResourceTest extends AbstractManagementApiInt
@Test
@Description("Ensures that the deletion of auto-assignment distribution set works as intended, deleting the auto-assignment action type as well")
public void deleteAutoAssignDistributionSetOfTargetFilterQuery() throws Exception {
final String knownQuery = "name==test06";
final String knownName = "filter06";
final String dsName = "testDS";
@@ -686,6 +683,7 @@ public class MgmtTargetFilterQueryResourceTest extends AbstractManagementApiInt
final TargetFilterQuery tfq = createSingleTargetFilterQuery(knownName, knownQuery);
targetFilterQueryManagement
.updateAutoAssignDS(entityFactory.targetFilterQuery().updateAutoAssign(tfq.getId()).ds(set.getId()));
implicitLock(set);
final TargetFilterQuery updatedFilterQuery = targetFilterQueryManagement.get(tfq.getId()).get();

View File

@@ -92,7 +92,6 @@ import org.springframework.data.domain.Sort.Direction;
import org.springframework.hateoas.MediaTypes;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.orm.jpa.vendor.Database;
import org.springframework.test.web.servlet.MvcResult;
import com.jayway.jsonpath.JsonPath;
@@ -1391,10 +1390,9 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest {
}
@Test
@Description("Verfies that a DS to target assignment is reflected by the repository and that repeating "
@Description("Verifies that a DS to target assignment is reflected by the repository and that repeating "
+ "the assignment does not change the target.")
void assignDistributionSetToTarget() throws Exception {
Target target = testdataFactory.createTarget();
final DistributionSet set = testdataFactory.createDistributionSet("one");
@@ -1403,6 +1401,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest {
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
.andExpect(jsonPath("assigned", equalTo(1))).andExpect(jsonPath("alreadyAssigned", equalTo(0)))
.andExpect(jsonPath("total", equalTo(1)));
implicitLock(set);
assertThat(deploymentManagement.getAssignedDistributionSet(target.getControllerId()).get()).isEqualTo(set);
target = targetManagement.getByControllerID(target.getControllerId()).get();
@@ -1425,7 +1424,6 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest {
@Description("Ensures that confirmation option is considered in assignment request.")
void assignDistributionSetToTargetWithConfirmationOptions(final boolean confirmationFlowActive,
final Boolean confirmationRequired) throws Exception {
final Target target = testdataFactory.createTarget();
final DistributionSet set = testdataFactory.createDistributionSet("one");
@@ -1444,6 +1442,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest {
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
.andExpect(jsonPath("assigned", equalTo(1))).andExpect(jsonPath("alreadyAssigned", equalTo(0)))
.andExpect(jsonPath("total", equalTo(1)));
implicitLock(set);
assertThat(deploymentManagement.getAssignedDistributionSet(target.getControllerId()).get()).isEqualTo(set);
@@ -1468,7 +1467,6 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest {
@Test
@Description("Verfies that a DOWNLOAD_ONLY DS to target assignment is properly handled")
void assignDownloadOnlyDistributionSetToTarget() throws Exception {
final Target target = testdataFactory.createTarget();
final DistributionSet set = testdataFactory.createDistributionSet("one");
@@ -1477,6 +1475,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest {
.contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
.andExpect(jsonPath("assigned", equalTo(1))).andExpect(jsonPath("alreadyAssigned", equalTo(0)))
.andExpect(jsonPath("total", equalTo(1)));
implicitLock(set);
assertThat(deploymentManagement.getAssignedDistributionSet(target.getControllerId()).get()).isEqualTo(set);
final Slice<Action> actions = deploymentManagement.findActionsByTarget("targetExist", PageRequest.of(0, 100));
@@ -1488,7 +1487,6 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest {
@Description("Verfies that an offline DS to target assignment is reflected by the repository and that repeating "
+ "the assignment does not change the target.")
void offlineAssignDistributionSetToTarget() throws Exception {
Target target = testdataFactory.createTarget();
final DistributionSet set = testdataFactory.createDistributionSet("one");
@@ -1498,6 +1496,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest {
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
.andExpect(jsonPath("assigned", equalTo(1))).andExpect(jsonPath("alreadyAssigned", equalTo(0)))
.andExpect(jsonPath("total", equalTo(1)));
implicitLock(set);
assertThat(deploymentManagement.getAssignedDistributionSet(target.getControllerId()).get()).isEqualTo(set);
assertThat(deploymentManagement.getInstalledDistributionSet(target.getControllerId()).get()).isEqualTo(set);
@@ -1518,7 +1517,6 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest {
@Test
void assignDistributionSetToTargetWithActionTimeForcedAndTime() throws Exception {
final Target target = testdataFactory.createTarget("fsdfsd");
final DistributionSet set = testdataFactory.createDistributionSet("one");
@@ -1529,6 +1527,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest {
mvc.perform(post(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/fsdfsd/assignedDS").content(body)
.contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print())
.andExpect(status().isOk());
implicitLock(set);
final List<Action> findActiveActionsByTarget = deploymentManagement
.findActiveActionsByTarget(PAGE, target.getControllerId()).getContent();