Tune/fix action cleanup tenant properties (#2782)
* actions.cleanup.onQuotaHit.percent -> action.cleanup.onQuotaHit.percent * action.cleanup.enabled - removed - instead enabled / disable <=> expire < / >= 0 * action.cleanup.actionExpiry -> action.cleanup.auto.expiry and action.cleanup.auto.status - so both are under action.cleanup.auto, and differentiate from on quota hit * auto db convert of props with one backward incompatibility - if you had action.cleanup.enabled=true and not set action.cleanup.actionExpiry (assuming default 30 days) - auto cleanup will be disabled you should set action.cleanup.auto.expiry=2592000000 in order to get the old behavior * Note that if you have configured global action cleanup the properties are changed also this config you shall change manually Signed-off-by: Avgustin Marinov <Avgustin.Marinov@bosch.com>
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -32,12 +32,11 @@ import org.springframework.hateoas.RepresentationModel;
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
@Schema(description = """
|
||||
**properties**:
|
||||
* **rollout.approval.enabled** - Boolean, The configuration key 'rollout.approval.enabled' defines if approval mode for Rollout Management is enabled.
|
||||
* **repository.actions.autoclose.enabled** - Boolean, The configuration key 'repository.actions.autoclose.enabled' defines if autoclose running actions with new Distribution Set assignment is enabled.
|
||||
* **user.confirmation.flow.enabled** - Boolean, The configuration key 'user.confirmation.flow.enabled' defines if confirmation is required when distribution set is assigned to target.
|
||||
* **authentication.gatewaytoken.enabled** - Boolean, The configuration key 'authentication.gatewaytoken.enabled' defines if the authentication mode 'gateway security token' is enabled.
|
||||
* **action.cleanup.enabled** - Boolean, The configuration key 'action.cleanup.enabled' defines if automatic cleanup of deployment actions is enabled.
|
||||
* **action.cleanup.actionExpiry** - Long, The configuration key 'action.cleanup.actionExpiry' defines the expiry time in milliseconds that needs to elapse before an action may be cleaned up.
|
||||
* **action.cleanup.auto.expiry** - Long, The configuration key 'action.cleanup.auto.expiry' defines the expiry time in milliseconds that needs to elapse before an action may be cleaned up.
|
||||
* **authentication.header.enabled** - Boolean, The configuration key 'authentication.header.enabled' defines if the authentication mode 'authority header' is enabled.
|
||||
* **maintenanceWindowPollCount** - Integer, The configuration key 'maintenanceWindowPollCount' defines the polling interval so that controller tries to poll at least these many times between the last polling and before start of maintenance window. The polling interval is bounded by configured pollingTime and minPollingTime. The polling interval is modified as per following scheme: pollingTime(@time=t) = (maintenanceWindowStartTime - t)/maintenanceWindowPollCount.
|
||||
* **authentication.targettoken.enabled** - Boolean, The configuration key 'authentication.targettoken.enabled' defines if the authentication mode 'target security token' is enabled.
|
||||
@@ -46,7 +45,7 @@ import org.springframework.hateoas.RepresentationModel;
|
||||
* **pollingOverdueTime** - String, The configuration key 'pollingOverdueTime' defines the period of time after the SP server will recognize a target, which is not performing pull requests anymore.
|
||||
* **authentication.header.authority** - String, The configuration key 'authentication.header.authority' defines the name of the 'authority header'.
|
||||
* **authentication.gatewaytoken.key** - String, The configuration key 'authentication.gatewaytoken.key' defines the key of the gateway security token.
|
||||
* **action.cleanup.actionStatus** - String, The configuration key 'action.cleanup.actionStatus' defines the list of action status that should be taken into account for the cleanup.
|
||||
* **action.cleanup.auto.status** - String, The configuration key 'action.cleanup.auto.status' defines the list of action status that should be taken into account for the cleanup.
|
||||
* **multi.assignments.enabled** - Boolean, The configuration key 'multi.assignments.enabled' defines if multiple distribution sets can be assigned to the same targets.
|
||||
* **batch.assignments.enabled** - Boolean, The configuration key 'batch.assignments.enabled' defines if distribution set can be assigned to multiple targets in a single batch message.
|
||||
* **implicit.lock.enabled** - Boolean (true by default), The configuration key 'implicit.lock.enabled' defines if distribution set and their software modules shall be implicitly locked when assigned to target, rollout or target filter.
|
||||
|
||||
@@ -104,18 +104,18 @@ public class TenantConfigurationProperties {
|
||||
* Repository on autoclose mode instead of canceling in case of new Distribution Set assignment over active actions.
|
||||
*/
|
||||
public static final String REPOSITORY_ACTIONS_AUTOCLOSE_ENABLED = "repository.actions.autoclose.enabled";
|
||||
/**
|
||||
* Switch to enable/disable automatic action cleanup.
|
||||
*/
|
||||
public static final String ACTION_CLEANUP_ENABLED = "action.cleanup.enabled";
|
||||
/**
|
||||
* Specifies the action expiry in milliseconds.
|
||||
*/
|
||||
public static final String ACTION_CLEANUP_ACTION_EXPIRY = "action.cleanup.actionExpiry";
|
||||
public static final String ACTION_CLEANUP_AUTO_EXPIRY = "action.cleanup.auto.expiry";
|
||||
/**
|
||||
* Specifies the action status.
|
||||
*/
|
||||
public static final String ACTION_CLEANUP_ACTION_STATUS = "action.cleanup.actionStatus";
|
||||
public static final String ACTION_CLEANUP_AUTO_STATUS = "action.cleanup.auto.status";
|
||||
/**
|
||||
* Configuration value for percentage of oldest actions to be cleaned if @maxActionsPerTarget quota is hit
|
||||
*/
|
||||
public static final String ACTION_PURGE_PERCENTAGE_ON_QUOTA_HIT = "action.cleanup.onQuotaHit.percent";
|
||||
/**
|
||||
* Switch to enable/disable the multi-assignment feature.
|
||||
*/
|
||||
@@ -133,11 +133,6 @@ public class TenantConfigurationProperties {
|
||||
*/
|
||||
public static final String IMPLICIT_LOCK_ENABLED = "implicit.lock.enabled";
|
||||
|
||||
/**
|
||||
* Configuration value for percentage of oldest actions to be cleaned if @maxActionsPerTarget quota is hit
|
||||
*/
|
||||
public static final String ACTIONS_PURGE_PERCENTAGE_ON_QUOTA_HIT = "actions.cleanup.onQuotaHit.percent";
|
||||
|
||||
private static final Map<Class<? extends Serializable>, TenantConfigurationValidator> DEFAULT_TYPE_VALIDATORS = Map.of(
|
||||
Boolean.class, new TenantConfigurationBooleanValidator(),
|
||||
Integer.class, new TenantConfigurationIntegerValidator(),
|
||||
|
||||
@@ -73,21 +73,17 @@ hawkbit.server.tenant.configuration.rollout-approval-enabled.keyName=rollout.app
|
||||
hawkbit.server.tenant.configuration.rollout-approval-enabled.defaultValue=false
|
||||
hawkbit.server.tenant.configuration.rollout-approval-enabled.dataType=java.lang.Boolean
|
||||
|
||||
hawkbit.server.tenant.configuration.action-cleanup-enabled.keyName=action.cleanup.enabled
|
||||
hawkbit.server.tenant.configuration.action-cleanup-enabled.defaultValue=false
|
||||
hawkbit.server.tenant.configuration.action-cleanup-enabled.dataType=java.lang.Boolean
|
||||
hawkbit.server.tenant.configuration.action-cleanup-auto-expiry.keyName=action.cleanup.auto.expiry
|
||||
# in millis, default: -1 (disabled), e.g. for 30 days set it to 2592000000
|
||||
hawkbit.server.tenant.configuration.action-cleanup-auto-expiry.defaultValue=-1
|
||||
hawkbit.server.tenant.configuration.action-cleanup-auto-expiry.dataType=java.lang.Long
|
||||
|
||||
hawkbit.server.tenant.configuration.action-cleanup-action-expiry.keyName=action.cleanup.actionExpiry
|
||||
# default: 30 days
|
||||
hawkbit.server.tenant.configuration.action-cleanup-action-expiry.defaultValue=2592000000
|
||||
hawkbit.server.tenant.configuration.action-cleanup-action-expiry.dataType=java.lang.Long
|
||||
hawkbit.server.tenant.configuration.action-cleanup-auto-status.keyName=action.cleanup.auto.status
|
||||
hawkbit.server.tenant.configuration.action-cleanup-auto-status.defaultValue=CANCELED,ERROR
|
||||
|
||||
hawkbit.server.tenant.configuration.action-cleanup-action-status.keyName=action.cleanup.actionStatus
|
||||
hawkbit.server.tenant.configuration.action-cleanup-action-status.defaultValue=CANCELED,ERROR
|
||||
|
||||
hawkbit.server.tenant.configuration.actions-cleanup-on-quota-hit-percent.keyName=actions.cleanup.onQuotaHit.percent
|
||||
hawkbit.server.tenant.configuration.actions-cleanup-on-quota-hit-percent.defaultValue=0
|
||||
hawkbit.server.tenant.configuration.actions-cleanup-on-quota-hit-percent.dataType=java.lang.Integer
|
||||
hawkbit.server.tenant.configuration.action-cleanup-on-quota-hit-percent.keyName=action.cleanup.onQuotaHit.percent
|
||||
hawkbit.server.tenant.configuration.action-cleanup-on-quota-hit-percent.defaultValue=0
|
||||
hawkbit.server.tenant.configuration.action-cleanup-on-quota-hit-percent.dataType=java.lang.Integer
|
||||
|
||||
hawkbit.server.tenant.configuration.multi-assignments-enabled.keyName=multi.assignments.enabled
|
||||
hawkbit.server.tenant.configuration.multi-assignments-enabled.defaultValue=false
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
DELETE FROM sp_tenant_configuration WHERE conf_key='action.cleanup.enabled';
|
||||
UPDATE sp_tenant_configuration SET conf_key='action.cleanup.auto.expiry' WHERE conf_key='action.cleanup.actionExpiry';
|
||||
UPDATE sp_tenant_configuration SET conf_key='action.cleanup.auto.expiry' WHERE conf_key='action.cleanup.auto.status';
|
||||
UPDATE sp_tenant_configuration SET conf_key='actions.cleanup.onQuotaHit.percent' WHERE conf_key='action.cleanup.onQuotaHit.percent';
|
||||
@@ -0,0 +1,4 @@
|
||||
DELETE FROM sp_tenant_configuration WHERE conf_key='action.cleanup.enabled';
|
||||
UPDATE sp_tenant_configuration SET conf_key='action.cleanup.auto.expiry' WHERE conf_key='action.cleanup.actionExpiry';
|
||||
UPDATE sp_tenant_configuration SET conf_key='action.cleanup.auto.expiry' WHERE conf_key='action.cleanup.auto.status';
|
||||
UPDATE sp_tenant_configuration SET conf_key='actions.cleanup.onQuotaHit.percent' WHERE conf_key='action.cleanup.onQuotaHit.percent';
|
||||
@@ -0,0 +1,4 @@
|
||||
DELETE FROM sp_tenant_configuration WHERE conf_key='action.cleanup.enabled';
|
||||
UPDATE sp_tenant_configuration SET conf_key='action.cleanup.auto.expiry' WHERE conf_key='action.cleanup.actionExpiry';
|
||||
UPDATE sp_tenant_configuration SET conf_key='action.cleanup.auto.expiry' WHERE conf_key='action.cleanup.auto.status';
|
||||
UPDATE sp_tenant_configuration SET conf_key='actions.cleanup.onQuotaHit.percent' WHERE conf_key='action.cleanup.onQuotaHit.percent';
|
||||
@@ -47,7 +47,6 @@ import org.eclipse.hawkbit.repository.jpa.acm.AccessController;
|
||||
import org.eclipse.hawkbit.repository.jpa.aspects.ExceptionMappingAspectHandler;
|
||||
import org.eclipse.hawkbit.repository.jpa.autocleanup.AutoActionCleanup;
|
||||
import org.eclipse.hawkbit.repository.jpa.autocleanup.AutoCleanupScheduler;
|
||||
import org.eclipse.hawkbit.repository.jpa.autocleanup.CleanupTask;
|
||||
import org.eclipse.hawkbit.repository.jpa.cluster.DistributedLockRepository;
|
||||
import org.eclipse.hawkbit.repository.jpa.cluster.LockProperties;
|
||||
import org.eclipse.hawkbit.repository.jpa.event.JpaEventEntityManager;
|
||||
@@ -416,8 +415,7 @@ public class JpaRepositoryConfiguration {
|
||||
* @return a new {@link AutoActionCleanup} bean
|
||||
*/
|
||||
@Bean
|
||||
CleanupTask actionCleanup(final DeploymentManagement deploymentManagement,
|
||||
final TenantConfigurationManagement configManagement) {
|
||||
AutoCleanupScheduler.CleanupTask actionCleanup(final DeploymentManagement deploymentManagement, final TenantConfigurationManagement configManagement) {
|
||||
return new AutoActionCleanup(deploymentManagement, configManagement);
|
||||
}
|
||||
|
||||
@@ -434,10 +432,10 @@ public class JpaRepositoryConfiguration {
|
||||
@ConditionalOnMissingBean
|
||||
@Profile("!test")
|
||||
@ConditionalOnProperty(prefix = "hawkbit.autocleanup.scheduler", name = "enabled", matchIfMissing = true)
|
||||
AutoCleanupScheduler autoCleanupScheduler(final SystemManagement systemManagement,
|
||||
final SystemSecurityContext systemSecurityContext, final LockRegistry lockRegistry,
|
||||
final List<CleanupTask> cleanupTasks) {
|
||||
return new AutoCleanupScheduler(systemManagement, systemSecurityContext, lockRegistry, cleanupTasks);
|
||||
AutoCleanupScheduler autoCleanupScheduler(
|
||||
final List<AutoCleanupScheduler.CleanupTask> cleanupTasks,
|
||||
final SystemManagement systemManagement, final SystemSecurityContext systemSecurityContext, final LockRegistry lockRegistry) {
|
||||
return new AutoCleanupScheduler(cleanupTasks, systemManagement, systemSecurityContext, lockRegistry);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -9,15 +9,12 @@
|
||||
*/
|
||||
package org.eclipse.hawkbit.repository.jpa.autocleanup;
|
||||
|
||||
import static org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey.ACTION_CLEANUP_ACTION_EXPIRY;
|
||||
import static org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey.ACTION_CLEANUP_ACTION_STATUS;
|
||||
import static org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey.ACTION_CLEANUP_ENABLED;
|
||||
import static org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey.ACTION_CLEANUP_AUTO_EXPIRY;
|
||||
import static org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey.ACTION_CLEANUP_AUTO_STATUS;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.Instant;
|
||||
import java.util.Arrays;
|
||||
import java.util.EnumSet;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -28,31 +25,20 @@ import org.eclipse.hawkbit.repository.model.Action.Status;
|
||||
import org.eclipse.hawkbit.repository.model.TenantConfigurationValue;
|
||||
|
||||
/**
|
||||
* A cleanup task for {@link Action} entities which can be used to delete
|
||||
* actions which are in a certain {@link Action.Status}. It is recommended to
|
||||
* only clean up actions which have terminated already (i.e. actions in status
|
||||
* CANCELLED or ERROR).
|
||||
*
|
||||
* The cleanup task can be enabled /disabled and configured on a per tenant
|
||||
* basis.
|
||||
* A cleanup task for {@link Action} entities which can be used to delete actions which are in a certain {@link Action.Status}.
|
||||
* It is recommended to only clean up actions which have terminated already (i.e. actions in status CANCELLED or ERROR).
|
||||
* <p/>
|
||||
* The cleanup task can be enabled /disabled and configured on a per-tenant basis.
|
||||
*/
|
||||
@Slf4j
|
||||
public class AutoActionCleanup implements CleanupTask {
|
||||
public class AutoActionCleanup implements AutoCleanupScheduler.CleanupTask {
|
||||
|
||||
private static final String ID = "action-cleanup";
|
||||
private static final boolean ACTION_CLEANUP_ENABLED_DEFAULT = false;
|
||||
private static final long ACTION_CLEANUP_ACTION_EXPIRY_DEFAULT = TimeUnit.DAYS.toMillis(30);
|
||||
private static final EnumSet<Status> EMPTY_STATUS_SET = EnumSet.noneOf(Status.class);
|
||||
|
||||
private final DeploymentManagement deploymentMgmt;
|
||||
private final TenantConfigurationManagement config;
|
||||
|
||||
/**
|
||||
* Constructs the action cleanup handler.
|
||||
*
|
||||
* @param deploymentMgmt The {@link DeploymentManagement} to operate on.
|
||||
* @param configMgmt The {@link TenantConfigurationManagement} service.
|
||||
*/
|
||||
public AutoActionCleanup(final DeploymentManagement deploymentMgmt, final TenantConfigurationManagement configMgmt) {
|
||||
this.deploymentMgmt = deploymentMgmt;
|
||||
this.config = configMgmt;
|
||||
@@ -60,17 +46,20 @@ public class AutoActionCleanup implements CleanupTask {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (!isEnabled()) {
|
||||
final TenantConfigurationValue<Long> expiryCV = config.getConfigurationValue(ACTION_CLEANUP_AUTO_EXPIRY, Long.class);
|
||||
final long expiry = expiryCV != null ? expiryCV.getValue() : -1L;
|
||||
if (expiry < 0L) {
|
||||
log.debug("Action cleanup is disabled for this tenant...");
|
||||
return;
|
||||
}
|
||||
|
||||
final EnumSet<Status> status = getActionStatus();
|
||||
if (!status.isEmpty()) {
|
||||
final long lastModified = System.currentTimeMillis() - getExpiry();
|
||||
final int actionsCount = deploymentMgmt.deleteActionsByStatusAndLastModifiedBefore(status, lastModified);
|
||||
log.debug("Deleted {} actions in status {} which have not been modified since {} ({})", actionsCount,
|
||||
status, Instant.ofEpochMilli(lastModified), lastModified);
|
||||
} else {
|
||||
final EnumSet<Status> status = getActionStatus();
|
||||
if (status.isEmpty()) {
|
||||
log.debug("Action cleanup is disabled for this tenant...");
|
||||
} else {
|
||||
final long lastModified = System.currentTimeMillis() - expiry;
|
||||
final int actionsCount = deploymentMgmt.deleteActionsByStatusAndLastModifiedBefore(status, lastModified);
|
||||
log.debug("Deleted {} actions in status {} which have not been modified since {} ({})",
|
||||
actionsCount, status, Instant.ofEpochMilli(lastModified), lastModified);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,27 +68,12 @@ public class AutoActionCleanup implements CleanupTask {
|
||||
return ID;
|
||||
}
|
||||
|
||||
private long getExpiry() {
|
||||
final TenantConfigurationValue<Long> expiry = getConfigValue(ACTION_CLEANUP_ACTION_EXPIRY, Long.class);
|
||||
return expiry != null ? expiry.getValue() : ACTION_CLEANUP_ACTION_EXPIRY_DEFAULT;
|
||||
}
|
||||
|
||||
private EnumSet<Status> getActionStatus() {
|
||||
final TenantConfigurationValue<String> statusStr = getConfigValue(ACTION_CLEANUP_ACTION_STATUS, String.class);
|
||||
final TenantConfigurationValue<String> statusStr = config.getConfigurationValue(ACTION_CLEANUP_AUTO_STATUS, String.class);
|
||||
if (statusStr != null) {
|
||||
return Arrays.stream(statusStr.getValue().split("[;,]")).map(Status::valueOf)
|
||||
.collect(Collectors.toCollection(() -> EnumSet.noneOf(Status.class)));
|
||||
return Arrays.stream(statusStr.getValue().split("[;,]"))
|
||||
.map(Status::valueOf).collect(Collectors.toCollection(() -> EnumSet.noneOf(Status.class)));
|
||||
}
|
||||
return EMPTY_STATUS_SET;
|
||||
}
|
||||
|
||||
private boolean isEnabled() {
|
||||
final TenantConfigurationValue<Boolean> isEnabled = getConfigValue(ACTION_CLEANUP_ENABLED, Boolean.class);
|
||||
return isEnabled != null ? isEnabled.getValue() : ACTION_CLEANUP_ENABLED_DEFAULT;
|
||||
}
|
||||
|
||||
private <T extends Serializable> TenantConfigurationValue<T> getConfigValue(final String key,
|
||||
final Class<T> valueType) {
|
||||
return config.getConfigurationValue(key, valueType);
|
||||
}
|
||||
}
|
||||
@@ -36,15 +36,14 @@ public class AutoCleanupScheduler {
|
||||
/**
|
||||
* Constructs the cleanup schedulers and initializes it with a set of cleanup handlers.
|
||||
*
|
||||
* @param cleanupTasks A list of cleanup tasks.
|
||||
* @param systemManagement Management APIs to invoke actions in a certain tenant context.
|
||||
* @param systemSecurityContext The system security context.
|
||||
* @param lockRegistry A registry for shared locks.
|
||||
* @param cleanupTasks A list of cleanup tasks.
|
||||
*/
|
||||
public AutoCleanupScheduler(
|
||||
final SystemManagement systemManagement,
|
||||
final SystemSecurityContext systemSecurityContext, final LockRegistry lockRegistry,
|
||||
final List<CleanupTask> cleanupTasks) {
|
||||
final List<CleanupTask> cleanupTasks,
|
||||
final SystemManagement systemManagement, final SystemSecurityContext systemSecurityContext, final LockRegistry lockRegistry) {
|
||||
this.systemManagement = systemManagement;
|
||||
this.systemSecurityContext = systemSecurityContext;
|
||||
this.lockRegistry = lockRegistry;
|
||||
@@ -57,8 +56,7 @@ public class AutoCleanupScheduler {
|
||||
@Scheduled(initialDelayString = PROP_AUTO_CLEANUP_INTERVAL, fixedDelayString = PROP_AUTO_CLEANUP_INTERVAL)
|
||||
public void run() {
|
||||
log.debug("Auto cleanup scheduler has been triggered.");
|
||||
// run this code in system code privileged to have the necessary
|
||||
// permission to query and create entities
|
||||
// run this code in system code privileged to have the necessary permission to query and create entities
|
||||
if (!cleanupTasks.isEmpty()) {
|
||||
systemSecurityContext.runAsSystem(this::executeAutoCleanup);
|
||||
}
|
||||
@@ -70,7 +68,7 @@ public class AutoCleanupScheduler {
|
||||
@SuppressWarnings("squid:S3516")
|
||||
private Void executeAutoCleanup() {
|
||||
systemManagement.forEachTenant(tenant -> cleanupTasks.forEach(task -> {
|
||||
final Lock lock = obtainLock(task, tenant);
|
||||
final Lock lock = lockRegistry.obtain(AUTO_CLEANUP + SEP + task.getId() + SEP + tenant);
|
||||
if (!lock.tryLock()) {
|
||||
return;
|
||||
}
|
||||
@@ -85,7 +83,20 @@ public class AutoCleanupScheduler {
|
||||
return null;
|
||||
}
|
||||
|
||||
private Lock obtainLock(final CleanupTask task, final String tenant) {
|
||||
return lockRegistry.obtain(AUTO_CLEANUP + SEP + task.getId() + SEP + tenant);
|
||||
/**
|
||||
* Interface modeling a cleanup task.
|
||||
*/
|
||||
public interface CleanupTask extends Runnable {
|
||||
|
||||
/**
|
||||
* Executes the cleanup task.
|
||||
*/
|
||||
@Override
|
||||
void run();
|
||||
|
||||
/**
|
||||
* @return The identifier of this cleanup task. Never null.
|
||||
*/
|
||||
String getId();
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2018 Bosch Software Innovations GmbH and others
|
||||
*
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.eclipse.hawkbit.repository.jpa.autocleanup;
|
||||
|
||||
/**
|
||||
* Interface modeling a cleanup task.
|
||||
*/
|
||||
public interface CleanupTask extends Runnable {
|
||||
|
||||
/**
|
||||
* Executes the cleanup task.
|
||||
*/
|
||||
@Override
|
||||
void run();
|
||||
|
||||
/**
|
||||
* @return The identifier of this cleanup task. Never null.
|
||||
*/
|
||||
String getId();
|
||||
}
|
||||
@@ -89,6 +89,7 @@ import org.eclipse.hawkbit.repository.model.TargetWithActionType;
|
||||
import org.eclipse.hawkbit.security.SystemSecurityContext;
|
||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
||||
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties;
|
||||
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey;
|
||||
import org.eclipse.hawkbit.utils.TenantConfigHelper;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty;
|
||||
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
|
||||
@@ -628,7 +629,7 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl
|
||||
}
|
||||
|
||||
private int getActionsPurgePercentage() {
|
||||
return getConfigValue(TenantConfigurationProperties.TenantConfigurationKey.ACTIONS_PURGE_PERCENTAGE_ON_QUOTA_HIT, Integer.class);
|
||||
return getConfigValue(TenantConfigurationKey.ACTION_PURGE_PERCENTAGE_ON_QUOTA_HIT, Integer.class);
|
||||
}
|
||||
|
||||
protected boolean isActionsAutocloseEnabled() {
|
||||
|
||||
@@ -10,9 +10,8 @@
|
||||
package org.eclipse.hawkbit.repository.jpa.autocleanup;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey.ACTION_CLEANUP_ACTION_EXPIRY;
|
||||
import static org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey.ACTION_CLEANUP_ACTION_STATUS;
|
||||
import static org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey.ACTION_CLEANUP_ENABLED;
|
||||
import static org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey.ACTION_CLEANUP_AUTO_EXPIRY;
|
||||
import static org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey.ACTION_CLEANUP_AUTO_STATUS;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -44,7 +43,7 @@ class AutoActionCleanupTest extends AbstractJpaIntegrationTest {
|
||||
@Test
|
||||
void runningActionsAreNotCleanedUp() {
|
||||
// cleanup config for this test case
|
||||
setupCleanupConfiguration(true, 0, Action.Status.CANCELED, Action.Status.ERROR);
|
||||
setupCleanupConfiguration(0, Action.Status.CANCELED, Action.Status.ERROR);
|
||||
|
||||
final Target trg1 = testdataFactory.createTarget("trg1");
|
||||
final Target trg2 = testdataFactory.createTarget("trg2");
|
||||
@@ -69,7 +68,7 @@ class AutoActionCleanupTest extends AbstractJpaIntegrationTest {
|
||||
@Test
|
||||
void cleanupDisabled() {
|
||||
// cleanup config for this test case
|
||||
setupCleanupConfiguration(false, 0, Action.Status.CANCELED);
|
||||
setupCleanupConfiguration(-1L, Action.Status.CANCELED);
|
||||
|
||||
final Target trg1 = testdataFactory.createTarget("trg1");
|
||||
final Target trg2 = testdataFactory.createTarget("trg2");
|
||||
@@ -96,7 +95,7 @@ class AutoActionCleanupTest extends AbstractJpaIntegrationTest {
|
||||
@Test
|
||||
void canceledAndFailedActionsAreCleanedUp() {
|
||||
// cleanup config for this test case
|
||||
setupCleanupConfiguration(true, 0, Action.Status.CANCELED, Action.Status.ERROR);
|
||||
setupCleanupConfiguration( 0, Action.Status.CANCELED, Action.Status.ERROR);
|
||||
|
||||
final Target trg1 = testdataFactory.createTarget("trg1");
|
||||
final Target trg2 = testdataFactory.createTarget("trg2");
|
||||
@@ -129,7 +128,7 @@ class AutoActionCleanupTest extends AbstractJpaIntegrationTest {
|
||||
@Test
|
||||
void canceledActionsAreCleanedUp() {
|
||||
// cleanup config for this test case
|
||||
setupCleanupConfiguration(true, 0, Action.Status.CANCELED);
|
||||
setupCleanupConfiguration(0, Action.Status.CANCELED);
|
||||
|
||||
final Target trg1 = testdataFactory.createTarget("trg1");
|
||||
final Target trg2 = testdataFactory.createTarget("trg2");
|
||||
@@ -164,7 +163,7 @@ class AutoActionCleanupTest extends AbstractJpaIntegrationTest {
|
||||
@SuppressWarnings("squid:S2925")
|
||||
void canceledAndFailedActionsAreCleanedUpWhenExpired() throws InterruptedException {
|
||||
// cleanup config for this test case
|
||||
setupCleanupConfiguration(true, 500, Action.Status.CANCELED, Action.Status.ERROR);
|
||||
setupCleanupConfiguration(500, Action.Status.CANCELED, Action.Status.ERROR);
|
||||
|
||||
final Target trg1 = testdataFactory.createTarget("trg1");
|
||||
final Target trg2 = testdataFactory.createTarget("trg2");
|
||||
@@ -206,11 +205,10 @@ class AutoActionCleanupTest extends AbstractJpaIntegrationTest {
|
||||
controllerManagement.addUpdateActionStatus(ActionStatusCreate.builder().actionId(id).status(Status.ERROR).build());
|
||||
}
|
||||
|
||||
private void setupCleanupConfiguration(final boolean cleanupEnabled, final long expiry, final Status... status) {
|
||||
tenantConfigurationManagement.addOrUpdateConfiguration(ACTION_CLEANUP_ENABLED, cleanupEnabled);
|
||||
tenantConfigurationManagement.addOrUpdateConfiguration(ACTION_CLEANUP_ACTION_EXPIRY, expiry);
|
||||
private void setupCleanupConfiguration(final long expiry, final Status... status) {
|
||||
tenantConfigurationManagement.addOrUpdateConfiguration(ACTION_CLEANUP_AUTO_EXPIRY, expiry);
|
||||
tenantConfigurationManagement.addOrUpdateConfiguration(
|
||||
ACTION_CLEANUP_ACTION_STATUS,
|
||||
ACTION_CLEANUP_AUTO_STATUS,
|
||||
Arrays.stream(status).map(Status::toString).collect(Collectors.joining(",")));
|
||||
}
|
||||
}
|
||||
@@ -11,10 +11,11 @@ package org.eclipse.hawkbit.repository.jpa.autocleanup;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest;
|
||||
import org.eclipse.hawkbit.repository.jpa.autocleanup.AutoCleanupScheduler.CleanupTask;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -44,12 +45,10 @@ class AutoCleanupSchedulerTest extends AbstractJpaIntegrationTest {
|
||||
*/
|
||||
@Test
|
||||
void executeHandlerChain() {
|
||||
|
||||
new AutoCleanupScheduler(systemManagement, systemSecurityContext, lockRegistry, Arrays.asList(
|
||||
new SuccessfulCleanup(), new SuccessfulCleanup(), new FailingCleanup(), new SuccessfulCleanup())).run();
|
||||
|
||||
new AutoCleanupScheduler(
|
||||
List.of(new SuccessfulCleanup(), new SuccessfulCleanup(), new FailingCleanup(), new SuccessfulCleanup()),
|
||||
systemManagement, systemSecurityContext, lockRegistry).run();
|
||||
assertThat(counter.get()).isEqualTo(4);
|
||||
|
||||
}
|
||||
|
||||
private class SuccessfulCleanup implements CleanupTask {
|
||||
|
||||
@@ -1698,7 +1698,7 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest {
|
||||
() -> assignDistributionSet(exceededQuotaDsAssign.getId(), target.getControllerId()));
|
||||
|
||||
// set purge config to 25 %
|
||||
tenantConfigurationManagement.addOrUpdateConfiguration("actions.cleanup.onQuotaHit.percent", 25);
|
||||
tenantConfigurationManagement.addOrUpdateConfiguration(TenantConfigurationKey.ACTION_PURGE_PERCENTAGE_ON_QUOTA_HIT, 25);
|
||||
|
||||
// assign again
|
||||
assignDistributionSet(exceededQuotaDsAssign.getId(), target.getControllerId());
|
||||
@@ -1739,7 +1739,7 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest {
|
||||
assertEquals(20, deploymentManagement.countActionsByTarget(target.getControllerId()));
|
||||
|
||||
// set purge config to 25 %
|
||||
tenantConfigurationManagement.addOrUpdateConfiguration("actions.cleanup.onQuotaHit.percent", 25);
|
||||
tenantConfigurationManagement.addOrUpdateConfiguration(TenantConfigurationKey.ACTION_PURGE_PERCENTAGE_ON_QUOTA_HIT, 25);
|
||||
rolloutHandler.handleAll();
|
||||
assertEquals(16, deploymentManagement.countActionsByTarget(target.getControllerId()));
|
||||
|
||||
@@ -1762,7 +1762,7 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest {
|
||||
rolloutHandler.handleAll();
|
||||
}
|
||||
|
||||
tenantConfigurationManagement.addOrUpdateConfiguration("actions.cleanup.onQuotaHit.percent", 25);
|
||||
tenantConfigurationManagement.addOrUpdateConfiguration(TenantConfigurationKey.ACTION_PURGE_PERCENTAGE_ON_QUOTA_HIT, 25);
|
||||
deploymentManagement.handleMaxAssignmentsExceeded(target.getId(), 5L, new AssignmentQuotaExceededException());
|
||||
// only 3 actions should be deleted in such case :
|
||||
assertEquals(15, deploymentManagement.countActionsByTarget(target.getControllerId()));
|
||||
|
||||
@@ -140,7 +140,7 @@ class ManagementSecurityTest extends AbstractJpaIntegrationTest {
|
||||
// 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
|
||||
// because of action.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)))
|
||||
|
||||
Reference in New Issue
Block a user