Add AccessContext.asTenant and use where possible (#2838)

Signed-off-by: Avgustin Marinov <Avgustin.Marinov@bosch.com>
This commit is contained in:
Avgustin Marinov
2025-11-27 16:27:56 +02:00
committed by GitHub
parent f6f62db0ad
commit 42384b7e31
17 changed files with 184 additions and 97 deletions

View File

@@ -65,7 +65,7 @@ public class AutoCleanupScheduler {
*/
@SuppressWarnings("squid:S3516")
private Void executeAutoCleanup() {
systemManagement.forEachTenant(tenant -> cleanupTasks.forEach(task -> {
systemManagement.forEachTenantAsSystem(tenant -> cleanupTasks.forEach(task -> {
final Lock lock = lockRegistry.obtain(AUTO_CLEANUP + SEP + task.getId() + SEP + tenant);
if (!lock.tryLock()) {
return;

View File

@@ -9,7 +9,7 @@
*/
package org.eclipse.hawkbit.repository.jpa.event;
import static org.eclipse.hawkbit.context.AccessContext.asSystemAsTenant;
import static org.eclipse.hawkbit.context.AccessContext.asTenant;
import jakarta.persistence.EntityManager;
@@ -36,6 +36,6 @@ public class JpaEventEntityManager implements EventEntityManager {
@Override
public <E extends TenantAwareBaseEntity> E findEntity(final String tenant, final Long id, final Class<E> entityType) {
return asSystemAsTenant(tenant, () -> entityManager.find(entityType, id));
return asTenant(tenant, () -> entityManager.find(entityType, id));
}
}

View File

@@ -11,7 +11,6 @@ package org.eclipse.hawkbit.repository.jpa.management;
import static org.eclipse.hawkbit.context.AccessContext.asActor;
import static org.eclipse.hawkbit.context.AccessContext.asSystem;
import static org.eclipse.hawkbit.context.AccessContext.asSystemAsTenant;
import static org.eclipse.hawkbit.repository.jpa.executor.AfterTransactionCommitExecutor.afterCommit;
import static org.eclipse.hawkbit.repository.model.Action.Status.DOWNLOADED;
import static org.eclipse.hawkbit.repository.model.Action.Status.FINISHED;
@@ -125,7 +124,6 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
@@ -694,11 +692,10 @@ public class JpaControllerManagement extends JpaActionManagement implements Cont
}
try {
events.stream().collect(Collectors.groupingBy(TargetPoll::getTenant)).forEach((tenant, polls) -> {
final TransactionCallback<Void> createTransaction = status -> updateLastTargetQueries(tenant, polls);
asSystemAsTenant(
tenant, () -> DeploymentHelper.runInNewTransaction(txManager, "flushUpdateQueue", createTransaction));
});
events.stream().collect(Collectors.groupingBy(TargetPoll::getTenant))
.forEach((tenant, polls) -> DeploymentHelper.runInNewTransaction(
txManager, "flushUpdateQueue",
status -> updateLastTargetQueries(tenant, polls)));
} catch (final RuntimeException ex) {
log.error("Failed to persist UpdateQueue content.", ex);
return;

View File

@@ -10,6 +10,7 @@
package org.eclipse.hawkbit.repository.jpa.management;
import static org.eclipse.hawkbit.context.AccessContext.asSystemAsTenant;
import static org.eclipse.hawkbit.context.AccessContext.asTenant;
import java.util.Set;
import java.util.function.Consumer;
@@ -136,20 +137,15 @@ public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, Syst
return currentTenantCacheKeyGenerator.currentTenantKeyGenerator();
}
@Override
public Page<String> findTenants(final Pageable pageable) {
return tenantMetaDataRepository.findTenants(pageable);
}
@Override
@Transactional(propagation = Propagation.NOT_SUPPORTED)
// Exception squid:S2229 - calling findTenants without transaction is intended in this case
@SuppressWarnings("squid:S2229")
public void forEachTenant(final Consumer<String> consumer) {
public void forEachTenantAsSystem(final Consumer<String> consumer) {
Page<String> tenants;
Pageable query = PageRequest.of(0, MAX_TENANTS_QUERY);
do {
tenants = findTenants(query); // with IS_SYSTEM_CODE so we could find all tenants
tenants = tenantMetaDataRepository.findTenants(query); // with IS_SYSTEM_CODE so we could find all tenants
tenants.forEach(tenant -> asSystemAsTenant(tenant, () -> {
try {
consumer.accept(tenant);
@@ -200,7 +196,7 @@ public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, Syst
}
final String tenant = t.toUpperCase();
asSystemAsTenant(tenant, () -> DeploymentHelper.runInNewTransaction(txManager, "deleteTenant", status -> {
asTenant(tenant, () -> DeploymentHelper.runInNewTransaction(txManager, "deleteTenant", status -> {
tenantMetaDataRepository.deleteByTenantIgnoreCase(tenant);
tenantConfigurationRepository.deleteByTenant(tenant);
targetRepository.deleteByTenant(tenant);
@@ -293,10 +289,9 @@ public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, Syst
* @return the initial created {@link TenantMetaData}
*/
private TenantMetaData createInitialTenantMetaData(final String tenant) {
return asSystemAsTenant(
tenant, () -> DeploymentHelper.runInNewTransaction(txManager, "initial-tenant-creation", status -> {
final DistributionSetType defaultDsType = createStandardSoftwareDataSetup();
return tenantMetaDataRepository.save(new JpaTenantMetaData(defaultDsType, tenant));
}));
return asSystemAsTenant(tenant, () -> DeploymentHelper.runInNewTransaction(txManager, "initial-tenant-creation", status -> {
final DistributionSetType defaultDsType = createStandardSoftwareDataSetup();
return tenantMetaDataRepository.save(new JpaTenantMetaData(defaultDsType, tenant));
}));
}
}

View File

@@ -68,7 +68,7 @@ public class AutoAssignScheduler {
final long startNano = java.lang.System.nanoTime();
try {
log.debug("Auto assign scheduled execution has acquired lock and started for each tenant.");
systemManagement.forEachTenant(tenant -> {
systemManagement.forEachTenantAsSystem(tenant -> {
final long startNanoT = java.lang.System.nanoTime();
autoAssignExecutor.checkAllTargets();

View File

@@ -50,7 +50,7 @@ public class RolloutScheduler {
}
/**
* Scheduler method called by the spring-async mechanism. For all tenants, using {@link SystemManagement#forEachTenant},
* Scheduler method called by the spring-async mechanism. For all tenants, using {@link SystemManagement#forEachTenantAsSystem},
* runs the {@link RolloutHandler#handleAll()} scoped to permission of access control context or unscoped (with {@link System}) if null
*/
@Scheduled(initialDelayString = PROP_SCHEDULER_DELAY_PLACEHOLDER, fixedDelayString = PROP_SCHEDULER_DELAY_PLACEHOLDER)
@@ -63,7 +63,7 @@ public class RolloutScheduler {
// workaround eclipselink that is currently not possible to execute a query without multi-tenancy if MultiTenant
// annotation is used. https://bugs.eclipse.org/bugs/show_bug.cgi?id=355458. So
// iterate through all tenants and execute the rollout check for each tenant separately.
systemManagement.forEachTenant(tenant -> {
systemManagement.forEachTenantAsSystem(tenant -> {
if (rolloutTaskExecutor == null) {
handleAll(tenant);
} else {