Add AccessContext.asTenant and use where possible (#2838)
Signed-off-by: Avgustin Marinov <Avgustin.Marinov@bosch.com>
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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));
|
||||
}));
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -17,7 +17,7 @@ import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.awaitility.Awaitility;
|
||||
@@ -63,8 +63,7 @@ class ConcurrentDistributionSetInvalidationTest extends AbstractJpaIntegrationTe
|
||||
final Rollout rollout = createRollout(distributionSet);
|
||||
final String tenant = AccessContext.tenant();
|
||||
|
||||
// run in new Thread so that the invalidation can be executed in
|
||||
// parallel
|
||||
// run in new Thread so that the invalidation can be executed in parallel
|
||||
new Thread(() -> asSystemAsTenant(tenant, rolloutHandler::handleAll)).start();
|
||||
|
||||
// wait until at least one RolloutGroup is created, as this means that the thread has started and has acquired the lock
|
||||
@@ -74,7 +73,7 @@ class ConcurrentDistributionSetInvalidationTest extends AbstractJpaIntegrationTe
|
||||
.until(() -> asSystemAsTenant(tenant, () -> rolloutGroupManagement.findByRollout(rollout.getId(), PAGE).getSize() > 0));
|
||||
|
||||
final DistributionSetInvalidation distributionSetInvalidation = new DistributionSetInvalidation(
|
||||
Collections.singletonList(distributionSet.getId()), ActionCancellationType.SOFT);
|
||||
List.of(distributionSet.getId()), ActionCancellationType.SOFT);
|
||||
assertThatExceptionOfType(StopRolloutException.class)
|
||||
.as("Invalidation of distributionSet should throw an exception")
|
||||
.isThrownBy(() -> distributionSetInvalidationManagement.invalidateDistributionSet(distributionSetInvalidation));
|
||||
|
||||
@@ -12,6 +12,7 @@ package org.eclipse.hawkbit.repository.jpa.management;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.hawkbit.auth.SpRole;
|
||||
@@ -37,11 +38,15 @@ class SystemManagementTest extends AbstractJpaIntegrationTest {
|
||||
*/
|
||||
@Test
|
||||
void findTenantsReturnsAllTenantsNotOnlyWhichLoggedIn() {
|
||||
assertThat(systemManagement.findTenants(PAGE).getContent()).hasSize(1);
|
||||
|
||||
assertThat(listTenants()).hasSize(1);
|
||||
createTestTenantsForSystemStatistics(2, 0, 0, 0);
|
||||
assertThat(listTenants()).hasSize(3);
|
||||
}
|
||||
|
||||
assertThat(systemManagement.findTenants(PAGE).getContent()).hasSize(3);
|
||||
private List<String> listTenants() {
|
||||
final List<String> tenants = new ArrayList<>();
|
||||
systemManagement.forEachTenantAsSystem(tenants::add);
|
||||
return tenants;
|
||||
}
|
||||
|
||||
private void createTestTenantsForSystemStatistics(final int tenants, final int artifactSize, final int targets, final int updates) {
|
||||
|
||||
@@ -11,11 +11,14 @@ package org.eclipse.hawkbit.repository.jpa.tenancy;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.fail;
|
||||
import static org.eclipse.hawkbit.context.AccessContext.asSystem;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import org.eclipse.hawkbit.context.AccessContext;
|
||||
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
|
||||
import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
@@ -59,8 +62,7 @@ class MultiTenancyEntityTest extends AbstractJpaIntegrationTest {
|
||||
assertThat(findTargetsForTenant.getContent().get(0).getTenant().toUpperCase()).isEqualTo(tenant.toUpperCase());
|
||||
final Page<? extends Target> findTargetsForAnotherTenant = findTargetsForTenant(anotherTenant);
|
||||
assertThat(findTargetsForAnotherTenant).hasSize(1);
|
||||
assertThat(findTargetsForAnotherTenant.getContent().get(0).getTenant().toUpperCase())
|
||||
.isEqualTo(anotherTenant.toUpperCase());
|
||||
assertThat(findTargetsForAnotherTenant.getContent().get(0).getTenant().toUpperCase()).isEqualTo(anotherTenant.toUpperCase());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -96,11 +98,9 @@ class MultiTenancyEntityTest extends AbstractJpaIntegrationTest {
|
||||
final String controllerAnotherTenant = "anotherController";
|
||||
createTargetForTenant(controllerAnotherTenant, anotherTenant);
|
||||
|
||||
assertThat(systemManagement.findTenants(PAGE)).as("Expected number if tenants before deletion is").hasSize(3);
|
||||
|
||||
assertThat(listTenants()).as("Expected number if tenants before deletion is").hasSize(3);
|
||||
systemManagement.deleteTenant(anotherTenant);
|
||||
|
||||
assertThat(systemManagement.findTenants(PAGE)).as("Expected number if tenants after deletion is").hasSize(2);
|
||||
assertThat(listTenants()).as("Expected number if tenants after deletion is").hasSize(2);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -202,4 +202,10 @@ class MultiTenancyEntityTest extends AbstractJpaIntegrationTest {
|
||||
private Slice<? extends DistributionSet> findDistributionSetForTenant(final String tenant) throws Exception {
|
||||
return runAsTenant(tenant, () -> distributionSetManagement.findAll(PAGE));
|
||||
}
|
||||
|
||||
private List<String> listTenants() {
|
||||
final List<String> tenants = new ArrayList<>();
|
||||
asSystem(() -> systemManagement.forEachTenantAsSystem(tenants::add));
|
||||
return tenants;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user