Action history cleanup/purge initial (#2728)
* Action history cleanup/purge initial Signed-off-by: strailov <Stanislav.Trailov@bosch.io> * apply changes after review Signed-off-by: strailov <Stanislav.Trailov@bosch.io> * fix hibernate build by annotating delete methods with transactional annotation Signed-off-by: strailov <Stanislav.Trailov@bosch.io> * changes after review and new test cases for new requirements * accept 0 for keep last Signed-off-by: strailov <Stanislav.Trailov@bosch.io> * Fix ManagementSecurityTest Signed-off-by: strailov <Stanislav.Trailov@bosch.io> * apply object utils check Signed-off-by: strailov <Stanislav.Trailov@bosch.io> * fix for oldestAction deletion Signed-off-by: strailov <Stanislav.Trailov@bosch.io> * remove unused comment Signed-off-by: strailov <Stanislav.Trailov@bosch.io> * rename action ids variable Signed-off-by: strailov <Stanislav.Trailov@bosch.io> * Fix access control handling Signed-off-by: Avgustin Marinov <Avgustin.Marinov@bosch.com> --------- Signed-off-by: strailov <Stanislav.Trailov@bosch.io> Signed-off-by: Avgustin Marinov <Avgustin.Marinov@bosch.com> Co-authored-by: Avgustin Marinov <Avgustin.Marinov@bosch.com>
This commit is contained in:
committed by
GitHub
parent
9984c89183
commit
f1c3d0175e
@@ -14,6 +14,7 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.eclipse.hawkbit.repository.model.Action.Status.RUNNING;
|
||||
import static org.eclipse.hawkbit.repository.model.Action.Status.WAIT_FOR_CONFIRMATION;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
import java.util.AbstractMap.SimpleEntry;
|
||||
import java.util.ArrayList;
|
||||
@@ -34,6 +35,7 @@ import org.assertj.core.api.Assertions;
|
||||
import org.eclipse.hawkbit.repository.ActionStatusFields;
|
||||
import org.eclipse.hawkbit.repository.DistributionSetManagement;
|
||||
import org.eclipse.hawkbit.repository.DistributionSetTagManagement;
|
||||
import org.eclipse.hawkbit.repository.Identifiable;
|
||||
import org.eclipse.hawkbit.repository.event.remote.CancelTargetAssignmentEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.MultiActionAssignEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.MultiActionCancelEvent;
|
||||
@@ -75,6 +77,7 @@ import org.eclipse.hawkbit.repository.model.DeploymentRequest;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetAssignmentResult;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetType;
|
||||
import org.eclipse.hawkbit.repository.model.Rollout;
|
||||
import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
||||
import org.eclipse.hawkbit.repository.model.Target;
|
||||
import org.eclipse.hawkbit.repository.model.TargetType;
|
||||
@@ -1673,6 +1676,105 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest {
|
||||
.isThrownBy(() -> deploymentManagement.assignDistributionSets(deploymentRequests));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testManualAssignmentsActionsPurge() {
|
||||
Target target = testdataFactory.createTarget();
|
||||
|
||||
for (int i = 0; i < 20; i++) {
|
||||
DistributionSet distributionSet = testdataFactory.createDistributionSet("ds_" + i);
|
||||
assignDistributionSet(distributionSet.getId(), target.getControllerId());
|
||||
}
|
||||
|
||||
long actions = deploymentManagement.countActionsByTarget(target.getControllerId());
|
||||
// quota in tests is set to 20 ...
|
||||
assertEquals(20, actions);
|
||||
|
||||
// extract the first 5 action ids
|
||||
List<Action> firstSample = deploymentManagement.findActionsByTarget(target.getControllerId(), PAGE).getContent();
|
||||
List<Long> shouldBePurgedActionsList = firstSample.stream().map(Identifiable::getId).limit(5).toList();
|
||||
|
||||
DistributionSet exceededQuotaDsAssign = testdataFactory.createDistributionSet("exceededQuotaAssignment");
|
||||
|
||||
// should throw quota exception if not explicitly configured to purge actions
|
||||
assertThrows(AssignmentQuotaExceededException.class,
|
||||
() -> assignDistributionSet(exceededQuotaDsAssign.getId(), target.getControllerId()));
|
||||
|
||||
// set purge config to 25 %
|
||||
tenantConfigurationManagement.addOrUpdateConfiguration("actions.cleanup.onQuotaHit.percent", 25);
|
||||
|
||||
// assign again
|
||||
assignDistributionSet(exceededQuotaDsAssign.getId(), target.getControllerId());
|
||||
// 16 actions should be present
|
||||
actions = deploymentManagement.countActionsByTarget(target.getControllerId());
|
||||
assertEquals(16, actions);
|
||||
|
||||
List<Action> actionsList = deploymentManagement.findActionsByTarget(target.getControllerId(), PAGE).getContent();
|
||||
// first 5 should have been purged so the first actionId should be the last purged action id + 1
|
||||
assertEquals(shouldBePurgedActionsList.get(shouldBePurgedActionsList.size() - 1) + 1, actionsList.get(0).getId());
|
||||
assertEquals(firstSample.get(firstSample.size() - 1).getId() + 1, actionsList.get(15).getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRolloutAssignmentsActionsPurge() {
|
||||
final Target target = testdataFactory.createTarget();
|
||||
for (int i = 0; i < 20; i++) {
|
||||
DistributionSet distributionSet = testdataFactory.createDistributionSet();
|
||||
Rollout rollout = testdataFactory.createRolloutByVariables("rollout-" + i, "Description", 1, "controllerId==" + target
|
||||
.getControllerId(),
|
||||
distributionSet, "50", "50");
|
||||
rolloutManagement.start(rollout.getId());
|
||||
rolloutHandler.handleAll();
|
||||
}
|
||||
|
||||
assertEquals(20, deploymentManagement.countActionsByTarget(target.getControllerId()));
|
||||
List<Action> firstSample = deploymentManagement.findActionsByTarget(target.getControllerId(), PAGE).getContent();
|
||||
List<Long> shouldBePurgedActionsList = firstSample.stream().map(Identifiable::getId).limit(5).toList();
|
||||
|
||||
DistributionSet distributionSet = testdataFactory.createDistributionSet();
|
||||
Rollout rollout = testdataFactory.createRolloutByVariables("rollout-quota", "Description", 1, "controllerId==" + target
|
||||
.getControllerId(),
|
||||
distributionSet, "50", "50");
|
||||
rolloutManagement.start(rollout.getId());
|
||||
// don't assert quota exception here because rollout executor does not throw such in order to not interrupt other executions
|
||||
rolloutHandler.handleAll();
|
||||
//check that the old number of actions remain instead
|
||||
assertEquals(20, deploymentManagement.countActionsByTarget(target.getControllerId()));
|
||||
|
||||
// set purge config to 25 %
|
||||
tenantConfigurationManagement.addOrUpdateConfiguration("actions.cleanup.onQuotaHit.percent", 25);
|
||||
rolloutHandler.handleAll();
|
||||
assertEquals(16, deploymentManagement.countActionsByTarget(target.getControllerId()));
|
||||
|
||||
List<Action> actionsList = deploymentManagement.findActionsByTarget(target.getControllerId(), PAGE).getContent();
|
||||
// first 5 should have been purged so the first actionId should be the last purged action id + 1
|
||||
assertEquals(shouldBePurgedActionsList.get(shouldBePurgedActionsList.size() - 1) + 1, actionsList.get(0).getId());
|
||||
assertEquals(firstSample.get(firstSample.size() - 1).getId() + 1, actionsList.get(15).getId());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void testThatOnlyNeededNumberOfActionsIsPurged() {
|
||||
final Target target = testdataFactory.createTarget();
|
||||
for (int i = 0; i < 18; i++) {
|
||||
DistributionSet distributionSet = testdataFactory.createDistributionSet();
|
||||
Rollout rollout = testdataFactory.createRolloutByVariables("rollout-" + i, "Description", 1, "controllerId==" + target
|
||||
.getControllerId(),
|
||||
distributionSet, "50", "50");
|
||||
rolloutManagement.start(rollout.getId());
|
||||
rolloutHandler.handleAll();
|
||||
}
|
||||
|
||||
tenantConfigurationManagement.addOrUpdateConfiguration("actions.cleanup.onQuotaHit.percent", 25);
|
||||
deploymentManagement.handleMaxAssignmentsExceeded(target.getId(), 5L, new AssignmentQuotaExceededException());
|
||||
// only 3 actions should be deleted in such case :
|
||||
assertEquals(15, deploymentManagement.countActionsByTarget(target.getControllerId()));
|
||||
|
||||
// should throw the quota exception if requested is bigger than the configured limit of actions purge
|
||||
assertThrows(AssignmentQuotaExceededException.class, () ->
|
||||
deploymentManagement.handleMaxAssignmentsExceeded(target.getId(), 10L, new AssignmentQuotaExceededException()));
|
||||
|
||||
}
|
||||
|
||||
private List<DeploymentRequest> createAssignmentRequests(
|
||||
final Collection<DistributionSet> distributionSets, final Collection<Target> targets, final int weight) {
|
||||
return createAssignmentRequests(distributionSets, targets, weight, false);
|
||||
|
||||
@@ -139,6 +139,10 @@ class ManagementSecurityTest extends AbstractJpaIntegrationTest {
|
||||
method.getReturnType() != String.class)
|
||||
// jacoco adds some methods with bytecode instrumentation
|
||||
.filter(method -> !"$jacocoInit".equals(method.getName()))
|
||||
// skip maxAssignmentsExceededHandler in DeploymentManagement since it throws quota exception
|
||||
// because of actions.cleanup.onQuotaHit.percent not configured
|
||||
// other option would be to configure it for all tests
|
||||
.filter(method -> !"handleMaxAssignmentsExceeded".equals(method.getName()))
|
||||
.map(method -> Arguments.of(clazz, method)))
|
||||
// consumes the stream because scan result couldn't be used after being closed
|
||||
.toList()
|
||||
|
||||
Reference in New Issue
Block a user