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:
Stanislav Trailov
2025-10-21 10:34:58 +03:00
committed by GitHub
parent 9984c89183
commit f1c3d0175e
21 changed files with 662 additions and 44 deletions

View File

@@ -12,6 +12,7 @@ package org.eclipse.hawkbit.mgmt.rest.resource;
import static org.eclipse.hawkbit.mgmt.rest.resource.util.PagingUtility.sanitizeActionSortParam;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.hawkbit.audit.AuditLog;
import org.eclipse.hawkbit.mgmt.json.model.PagedList;
import org.eclipse.hawkbit.mgmt.json.model.action.MgmtAction;
import org.eclipse.hawkbit.mgmt.rest.api.MgmtActionRestApi;
@@ -26,8 +27,11 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.http.ResponseEntity;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@Slf4j
@RestController
@ConditionalOnProperty(name = "hawkbit.rest.MgmtActionResource.enabled", matchIfMissing = true)
@@ -71,6 +75,34 @@ public class MgmtActionResource implements MgmtActionRestApi {
return ResponseEntity.ok(MgmtActionMapper.toResponse(action, MgmtRepresentationMode.FULL));
}
@Override
@AuditLog(entity = "Actions",type = AuditLog.Type.DELETE, description = "Delete Action", logResponse = true)
public ResponseEntity<Void> deleteAction(Long actionId) {
deploymentManagement.deleteAction(actionId);
return ResponseEntity.ok().build();
}
@Override
@AuditLog(entity = "Actions", type = AuditLog.Type.DELETE, description = "Delete Actions", logResponse = true)
public ResponseEntity<Void> deleteActions(String rsqlParam, List<Long> actionIds) {
final boolean isActionIdsNotEmpty = !ObjectUtils.isEmpty(actionIds);
if (!ObjectUtils.isEmpty(rsqlParam)) {
if (isActionIdsNotEmpty) {
throw new IllegalArgumentException("Only one of the parameters should be provided!");
}
deploymentManagement.deleteActionsByRsql(rsqlParam);
} else if (isActionIdsNotEmpty) {
deploymentManagement.deleteActionsByIds(actionIds);
} else {
throw new IllegalArgumentException("Either action id list or rsql filter should be provided.");
}
return ResponseEntity.ok().build();
}
private MgmtRepresentationMode getRepresentationModeFromString(final String representationModeParam) {
return MgmtRepresentationMode.fromValue(representationModeParam)
.orElseGet(() -> {

View File

@@ -73,6 +73,7 @@ import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.RestController;
/**
@@ -226,6 +227,26 @@ public class MgmtTargetResource implements MgmtTargetRestApi {
return ResponseEntity.ok(new PagedList<>(MgmtTargetMapper.toResponse(targetId, activeActions.getContent()), totalActionCount));
}
@Override
@AuditLog(entity = "Target", type = AuditLog.Type.DELETE, description = "Delete Actions For Target")
public ResponseEntity<Void> deleteActionsForTarget(final String targetId, final int keepLast, final List<Long> actionIds) {
if (keepLast < 0 && ObjectUtils.isEmpty(actionIds)) {
throw new IllegalArgumentException("Either keepLast OR action ID list should be provided!");
}
if (!ObjectUtils.isEmpty(actionIds)) {
if (keepLast >= 0) {
throw new IllegalArgumentException("Only one of the parameters should be provided!");
}
deploymentManagement.deleteTargetActionsByIds(targetId, actionIds);
} else {
deploymentManagement.deleteOldestTargetActions(targetId, keepLast);
}
return ResponseEntity.ok().build();
}
@Override
public ResponseEntity<MgmtAction> getAction(final String targetId, final Long actionId) {
return getValidatedAction(targetId, actionId)