Refactor hawkbit core and security (#2833)

* Refactor hawkbit core and security

* improve access to the base core features - static
* thus easiear access
* and less boilerplate passing of instances

Signed-off-by: Avgustin Marinov <Avgustin.Marinov@bosch.com>

* Refactor context classes

* make JSON context serialization default

* AccessContext

* Split hawkbit-security-core to other modules and remove it

---------

Signed-off-by: Avgustin Marinov <Avgustin.Marinov@bosch.com>
This commit is contained in:
Avgustin Marinov
2025-11-27 13:07:49 +02:00
committed by GitHub
parent 58dbc32a80
commit f6f62db0ad
274 changed files with 2534 additions and 4458 deletions

View File

@@ -12,6 +12,7 @@ package org.eclipse.hawkbit.ql.rsql;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import org.eclipse.hawkbit.context.AccessContext;
import org.eclipse.hawkbit.repository.TargetManagement.Create;
import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException;
import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException;
@@ -117,7 +118,7 @@ class RsqlActionFieldsTest extends AbstractJpaIntegrationTest {
newAction.setStatus(active ? Status.RUNNING : Status.FINISHED);
newAction.setTarget(target);
newAction.setWeight(45);
newAction.setInitiatedBy(tenantAware.getCurrentUsername());
newAction.setInitiatedBy(AccessContext.actor());
if (extRef != null) {
newAction.setExternalRef(extRef);
}

View File

@@ -12,23 +12,16 @@ package org.eclipse.hawkbit.ql.rsql;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.when;
import java.util.concurrent.Callable;
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
import org.eclipse.hawkbit.repository.helper.SystemSecurityContextHolder;
import org.eclipse.hawkbit.repository.helper.TenantConfigurationManagementHolder;
import org.eclipse.hawkbit.repository.helper.TenantConfigHelper;
import org.eclipse.hawkbit.repository.model.TenantConfigurationValue;
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyResolver;
import org.eclipse.hawkbit.security.SystemSecurityContext;
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.mockito.Mockito;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.bean.override.mockito.MockitoBean;
import org.springframework.test.context.junit.jupiter.SpringExtension;
@@ -45,18 +38,17 @@ class VirtualPropertyResolverTest {
TenantConfigurationValue.<String> builder().value("00:07:37").build();
@MockitoBean
private TenantConfigurationManagement confMgmt;
@MockitoBean
private SystemSecurityContext securityContext;
private TenantConfigurationManagement tenantConfigurationManagement;
private final VirtualPropertyResolver substitutor = new VirtualPropertyResolver();
@BeforeEach
void before() {
when(confMgmt.getConfigurationValue(TenantConfigurationKey.POLLING_TIME, String.class))
when(tenantConfigurationManagement.getConfigurationValue(TenantConfigurationKey.POLLING_TIME, String.class))
.thenReturn(TEST_POLLING_TIME_INTERVAL);
when(confMgmt.getConfigurationValue(TenantConfigurationKey.POLLING_OVERDUE_TIME, String.class))
when(tenantConfigurationManagement.getConfigurationValue(TenantConfigurationKey.POLLING_OVERDUE_TIME, String.class))
.thenReturn(TEST_POLLING_OVERDUE_TIME_INTERVAL);
TenantConfigHelper.setTenantConfigurationManagement(tenantConfigurationManagement);
}
/**
@@ -90,24 +82,9 @@ class VirtualPropertyResolverTest {
@ParameterizedTest
@ValueSource(strings = { "${NOW_TS}", "${OVERDUE_TS}", "${overdue_ts}" })
void resolveNowTimestampPlaceholder(final String placeholder) {
when(securityContext.runAsSystem(Mockito.any(Callable.class))).thenAnswer(a -> ((Callable<?>) a.getArgument(0)).call());
final String testString = "lhs=lt=" + placeholder;
final String resolvedPlaceholders = substitutor.replace(testString);
assertThat(resolvedPlaceholders).as("'%s' placeholder was not replaced", placeholder).doesNotContain(placeholder);
}
@Configuration
static class Config {
@Bean
TenantConfigurationManagementHolder tenantConfigurationManagementHolder() {
return TenantConfigurationManagementHolder.getInstance();
}
@Bean
SystemSecurityContextHolder systemSecurityContextHolder() {
return SystemSecurityContextHolder.getInstance();
}
}
}

View File

@@ -8,7 +8,9 @@
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.hawkbit.repository.event.remote;
import java.util.Map;
import org.eclipse.hawkbit.event.EventJacksonMessageConverter;
import org.eclipse.hawkbit.event.EventProtoStuffMessageConverter;
import org.eclipse.hawkbit.repository.event.TenantAwareEvent;

View File

@@ -13,6 +13,7 @@ import static org.assertj.core.api.Assertions.assertThat;
import java.util.List;
import org.eclipse.hawkbit.context.AccessContext;
import org.eclipse.hawkbit.repository.jpa.model.JpaAction;
import org.eclipse.hawkbit.repository.model.Action;
import org.eclipse.hawkbit.repository.model.Action.ActionType;
@@ -25,7 +26,7 @@ import org.junit.jupiter.api.Test;
* Feature: Component Tests - Repository<br/>
* Story: RemoteTenantAwareEvent Tests
*/
class RemoteTenantAwareEventTest extends AbstractRemoteEventTest {
class RemoteTenantEventTest extends AbstractRemoteEventTest {
private static final String TENANT_DEFAULT = "DEFAULT";
@@ -93,7 +94,7 @@ class RemoteTenantAwareEventTest extends AbstractRemoteEventTest {
generateAction.setTarget(testdataFactory.createTarget("Test"));
generateAction.setDistributionSet(dsA);
generateAction.setStatus(Status.RUNNING);
generateAction.setInitiatedBy(tenantAware.getCurrentUsername());
generateAction.setInitiatedBy(AccessContext.actor());
generateAction.setWeight(1000);
final Action action = actionRepository.save(generateAction);
@@ -120,7 +121,7 @@ class RemoteTenantAwareEventTest extends AbstractRemoteEventTest {
generateAction.setTarget(testdataFactory.createTarget("Test"));
generateAction.setDistributionSet(dsA);
generateAction.setStatus(Status.RUNNING);
generateAction.setInitiatedBy(tenantAware.getCurrentUsername());
generateAction.setInitiatedBy(AccessContext.actor());
generateAction.setWeight(1000);
final Action action = actionRepository.save(generateAction);

View File

@@ -9,6 +9,16 @@
*/
package org.eclipse.hawkbit.repository.event.remote;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.util.List;
import java.util.Set;
import org.eclipse.hawkbit.repository.event.EventPublisherHolder;
import org.eclipse.hawkbit.repository.event.remote.entity.ActionCreatedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.ActionUpdatedEvent;
@@ -28,12 +38,6 @@ import org.junit.jupiter.api.Test;
import org.springframework.cloud.stream.function.StreamBridge;
import org.springframework.context.ApplicationEventPublisher;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.*;
import java.util.List;
import java.util.Set;
class ServiceEventsTest {
private StreamBridge streamBridge;

View File

@@ -11,6 +11,7 @@ package org.eclipse.hawkbit.repository.event.remote.entity;
import static org.assertj.core.api.Assertions.assertThat;
import org.eclipse.hawkbit.context.AccessContext;
import org.eclipse.hawkbit.repository.jpa.model.JpaAction;
import org.eclipse.hawkbit.repository.model.Action;
import org.eclipse.hawkbit.repository.model.Action.ActionType;
@@ -86,7 +87,7 @@ class ActionEventTest extends AbstractRemoteEntityEventTest<Action> {
generateAction.setTarget(target);
generateAction.setDistributionSet(distributionSet);
generateAction.setStatus(Status.RUNNING);
generateAction.setInitiatedBy(tenantAware.getCurrentUsername());
generateAction.setInitiatedBy(AccessContext.actor());
generateAction.setWeight(1000);
return actionRepository.save(generateAction);
}

View File

@@ -16,6 +16,7 @@ import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.stream.StreamSupport;
import lombok.extern.slf4j.Slf4j;
import org.assertj.core.api.Assertions;
import org.assertj.core.api.ThrowableAssert.ThrowingCallable;
@@ -29,10 +30,10 @@ import org.eclipse.hawkbit.repository.jpa.model.JpaRolloutGroup;
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule;
import org.eclipse.hawkbit.repository.jpa.repository.ActionRepository;
import org.eclipse.hawkbit.repository.jpa.repository.ActionStatusRepository;
import org.eclipse.hawkbit.repository.jpa.repository.ArtifactRepository;
import org.eclipse.hawkbit.repository.jpa.repository.DistributionSetRepository;
import org.eclipse.hawkbit.repository.jpa.repository.DistributionSetTagRepository;
import org.eclipse.hawkbit.repository.jpa.repository.DistributionSetTypeRepository;
import org.eclipse.hawkbit.repository.jpa.repository.ArtifactRepository;
import org.eclipse.hawkbit.repository.jpa.repository.RolloutGroupRepository;
import org.eclipse.hawkbit.repository.jpa.repository.RolloutRepository;
import org.eclipse.hawkbit.repository.jpa.repository.RolloutTargetGroupRepository;

View File

@@ -10,6 +10,7 @@
package org.eclipse.hawkbit.repository.jpa;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.eclipse.hawkbit.context.AccessContext.asSystemAsTenant;
import static org.mockito.AdditionalAnswers.delegatesTo;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doAnswer;
@@ -20,6 +21,7 @@ import java.util.Collections;
import java.util.concurrent.TimeUnit;
import org.awaitility.Awaitility;
import org.eclipse.hawkbit.context.AccessContext;
import org.eclipse.hawkbit.repository.RolloutManagement.Create;
import org.eclipse.hawkbit.repository.exception.StopRolloutException;
import org.eclipse.hawkbit.repository.jpa.model.JpaRolloutGroup;
@@ -59,23 +61,17 @@ class ConcurrentDistributionSetInvalidationTest extends AbstractJpaIntegrationTe
void verifyInvalidateDistributionSetWithLargeRolloutThrowsException() {
final DistributionSet distributionSet = testdataFactory.createDistributionSet();
final Rollout rollout = createRollout(distributionSet);
final String tenant = tenantAware.getCurrentTenant();
final String tenant = AccessContext.tenant();
// run in new Thread so that the invalidation can be executed in
// parallel
new Thread(() -> systemSecurityContext.runAsSystemAsTenant(() -> {
rolloutHandler.handleAll();
return 0;
}, tenant)).start();
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
Awaitility.await()
.pollInterval(Duration.ofMillis(100))
.atMost(Duration.ofSeconds(5))
.until(() -> tenantAware.runAsTenant(
tenant,
() -> systemSecurityContext.runAsSystem(
() -> rolloutGroupManagement.findByRollout(rollout.getId(), PAGE).getSize() > 0)));
.until(() -> asSystemAsTenant(tenant, () -> rolloutGroupManagement.findByRollout(rollout.getId(), PAGE).getSize() > 0));
final DistributionSetInvalidation distributionSetInvalidation = new DistributionSetInvalidation(
Collections.singletonList(distributionSet.getId()), ActionCancellationType.SOFT);

View File

@@ -10,7 +10,7 @@
package org.eclipse.hawkbit.repository.jpa.acm;
import static org.assertj.core.api.Assertions.assertThat;
import static org.eclipse.hawkbit.im.authentication.SpPermission.READ_TARGET;
import static org.eclipse.hawkbit.auth.SpPermission.READ_TARGET;
import static org.eclipse.hawkbit.repository.test.util.SecurityContextSwitch.runAs;
import static org.eclipse.hawkbit.repository.test.util.SecurityContextSwitch.withUser;
@@ -24,7 +24,6 @@ import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TargetType;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestPropertySource;
@TestPropertySource(properties = "hawkbit.acm.access-controller.enabled=true")

View File

@@ -10,19 +10,19 @@
package org.eclipse.hawkbit.repository.jpa.acm;
import static org.assertj.core.api.Assertions.assertThat;
import static org.eclipse.hawkbit.im.authentication.SpPermission.CREATE_TARGET;
import static org.eclipse.hawkbit.im.authentication.SpPermission.DELETE_TARGET;
import static org.eclipse.hawkbit.im.authentication.SpPermission.READ_DISTRIBUTION_SET;
import static org.eclipse.hawkbit.im.authentication.SpPermission.READ_TARGET;
import static org.eclipse.hawkbit.im.authentication.SpPermission.UPDATE_TARGET;
import static org.eclipse.hawkbit.auth.SpPermission.CREATE_TARGET;
import static org.eclipse.hawkbit.auth.SpPermission.DELETE_TARGET;
import static org.eclipse.hawkbit.auth.SpPermission.READ_DISTRIBUTION_SET;
import static org.eclipse.hawkbit.auth.SpPermission.READ_TARGET;
import static org.eclipse.hawkbit.auth.SpPermission.UPDATE_TARGET;
import static org.eclipse.hawkbit.repository.test.util.SecurityContextSwitch.callAs;
import java.util.Optional;
import org.eclipse.hawkbit.repository.AutoAssignExecutor;
import org.eclipse.hawkbit.repository.Identifiable;
import org.eclipse.hawkbit.repository.TargetFilterQueryManagement;
import org.eclipse.hawkbit.repository.TargetFilterQueryManagement.AutoAssignDistributionSetUpdate;
import org.eclipse.hawkbit.repository.AutoAssignExecutor;
import org.eclipse.hawkbit.repository.jpa.scheduler.AutoAssignScheduler;
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
import org.junit.jupiter.api.Test;
@@ -41,8 +41,7 @@ class AutoAssignTest extends AbstractAccessControllerManagementTest {
void verifyOnlyUpdatableTargetsArePartOfAutoAssignmentByScheduler() throws Exception {
// auto assign scheduler apply stored access control context and the context is correctly applied
verifyOnlyUpdatableTargetsArePartOfAutoAssignment(
() -> new AutoAssignScheduler(systemManagement, systemSecurityContext, autoAssignExecutor, lockRegistry, Optional.empty())
.autoAssignScheduler());
() -> new AutoAssignScheduler(systemManagement, autoAssignExecutor, lockRegistry, Optional.empty()).autoAssignScheduler());
}
@Test

View File

@@ -13,9 +13,10 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.assertThatNoException;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.eclipse.hawkbit.im.authentication.SpPermission.READ_DISTRIBUTION_SET;
import static org.eclipse.hawkbit.im.authentication.SpPermission.READ_TARGET;
import static org.eclipse.hawkbit.im.authentication.SpPermission.UPDATE_TARGET;
import static org.eclipse.hawkbit.auth.SpPermission.READ_DISTRIBUTION_SET;
import static org.eclipse.hawkbit.auth.SpPermission.READ_TARGET;
import static org.eclipse.hawkbit.auth.SpPermission.UPDATE_TARGET;
import static org.eclipse.hawkbit.context.AccessContext.asSystem;
import static org.eclipse.hawkbit.repository.test.util.SecurityContextSwitch.runAs;
import java.util.List;
@@ -39,7 +40,7 @@ class DeploymentManagementTest extends AbstractAccessControllerManagementTest {
READ_DISTRIBUTION_SET),
() -> assertThat(deploymentManagement.assignDistributionSets(List.of(new DeploymentRequest(
target1Type1.getControllerId(), ds1Type1.getId(), Action.ActionType.FORCED, 0,
null, null, null, null, false)))
null, null, null, null, false)), null)
.get(0).getAssignedEntity().stream().map(Action::getTarget)
.map(Target::getId))
.hasSize(1)
@@ -51,7 +52,7 @@ class DeploymentManagementTest extends AbstractAccessControllerManagementTest {
READ_DISTRIBUTION_SET),
() -> assertThat(deploymentManagement.assignDistributionSets(List.of(new DeploymentRequest(
target1Type1.getControllerId(), ds1Type1.getId(), Action.ActionType.FORCED, 0,
null, null, null, null, false)))).isEmpty());
null, null, null, null, false)), null)).isEmpty());
}
@Test
@@ -191,7 +192,7 @@ class DeploymentManagementTest extends AbstractAccessControllerManagementTest {
}
private void verify(final Consumer<Long> noRead, final Consumer<Long> readNoUpdate, final Consumer<Long> readAndUpdate) {
final Long actionId = systemSecurityContext.runAsSystem(() -> {
final Long actionId = asSystem(() -> {
final List<Action> actions = assignDistributionSet(ds1Type1.getId(), target1Type1.getControllerId()).getAssignedEntity();
assertThat(actions).hasSize(1).allMatch(action -> action.getTarget().getId().equals(target1Type1.getId()));
return actions.get(0);

View File

@@ -12,10 +12,10 @@ package org.eclipse.hawkbit.repository.jpa.acm;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.eclipse.hawkbit.im.authentication.SpPermission.CREATE_PREFIX;
import static org.eclipse.hawkbit.im.authentication.SpPermission.DISTRIBUTION_SET;
import static org.eclipse.hawkbit.im.authentication.SpPermission.READ_DISTRIBUTION_SET;
import static org.eclipse.hawkbit.im.authentication.SpPermission.UPDATE_DISTRIBUTION_SET;
import static org.eclipse.hawkbit.auth.SpPermission.CREATE_PREFIX;
import static org.eclipse.hawkbit.auth.SpPermission.DISTRIBUTION_SET;
import static org.eclipse.hawkbit.auth.SpPermission.READ_DISTRIBUTION_SET;
import static org.eclipse.hawkbit.auth.SpPermission.UPDATE_DISTRIBUTION_SET;
import static org.eclipse.hawkbit.repository.test.util.SecurityContextSwitch.runAs;
import java.util.List;
@@ -157,7 +157,7 @@ class DistributionSetManagementTest extends AbstractAccessControllerManagementTe
assertThat(ds1Type1).matches(updated -> updated.getModules().stream()
.map(Identifiable::getId).anyMatch(sm1Type1.getId()::equals));
try {
SecurityContextSwitch.callAsPrivileged(() -> distributionSetManagement.unlock(ds2Type2));
SecurityContextSwitch.asPrivileged(() -> distributionSetManagement.unlock(ds2Type2));
} catch (Exception e) {
throw new RuntimeException(e);
}

View File

@@ -12,11 +12,11 @@ package org.eclipse.hawkbit.repository.jpa.acm;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.eclipse.hawkbit.im.authentication.SpPermission.CREATE_PREFIX;
import static org.eclipse.hawkbit.im.authentication.SpPermission.DELETE_PREFIX;
import static org.eclipse.hawkbit.im.authentication.SpPermission.DISTRIBUTION_SET_TYPE;
import static org.eclipse.hawkbit.im.authentication.SpPermission.READ_PREFIX;
import static org.eclipse.hawkbit.im.authentication.SpPermission.UPDATE_PREFIX;
import static org.eclipse.hawkbit.auth.SpPermission.CREATE_PREFIX;
import static org.eclipse.hawkbit.auth.SpPermission.DELETE_PREFIX;
import static org.eclipse.hawkbit.auth.SpPermission.DISTRIBUTION_SET_TYPE;
import static org.eclipse.hawkbit.auth.SpPermission.READ_PREFIX;
import static org.eclipse.hawkbit.auth.SpPermission.UPDATE_PREFIX;
import static org.eclipse.hawkbit.repository.test.util.SecurityContextSwitch.runAs;
import java.util.List;

View File

@@ -10,12 +10,13 @@
package org.eclipse.hawkbit.repository.jpa.acm;
import static org.assertj.core.api.Assertions.assertThat;
import static org.eclipse.hawkbit.im.authentication.SpPermission.CREATE_ROLLOUT;
import static org.eclipse.hawkbit.im.authentication.SpPermission.HANDLE_ROLLOUT;
import static org.eclipse.hawkbit.im.authentication.SpPermission.READ_DISTRIBUTION_SET;
import static org.eclipse.hawkbit.im.authentication.SpPermission.READ_ROLLOUT;
import static org.eclipse.hawkbit.im.authentication.SpPermission.READ_TARGET;
import static org.eclipse.hawkbit.im.authentication.SpPermission.UPDATE_TARGET;
import static org.eclipse.hawkbit.auth.SpPermission.CREATE_ROLLOUT;
import static org.eclipse.hawkbit.auth.SpPermission.HANDLE_ROLLOUT;
import static org.eclipse.hawkbit.auth.SpPermission.READ_DISTRIBUTION_SET;
import static org.eclipse.hawkbit.auth.SpPermission.READ_ROLLOUT;
import static org.eclipse.hawkbit.auth.SpPermission.READ_TARGET;
import static org.eclipse.hawkbit.auth.SpPermission.UPDATE_TARGET;
import static org.eclipse.hawkbit.context.AccessContext.asSystem;
import static org.eclipse.hawkbit.repository.test.util.SecurityContextSwitch.runAs;
import java.util.Arrays;
@@ -31,12 +32,12 @@ class RolloutExecutionTest extends AbstractAccessControllerManagementTest {
@Test
void verifyOnlyUpdatableTargetsArePartOfRolloutExecutedByScheduler() {
verify(new RolloutScheduler(rolloutHandler, systemManagement, systemSecurityContext, 1, Optional.empty())::runningRolloutScheduler);
verify(new RolloutScheduler(rolloutHandler, systemManagement, 1, Optional.empty())::runningRolloutScheduler);
}
@Test
void verifyOnlyUpdatableTargetsArePartOfRollout() {
verify(() -> systemSecurityContext.runAsSystem(rolloutHandler::handleAll));
verify(() -> asSystem(rolloutHandler::handleAll));
}
private void verify(final Runnable run) {

View File

@@ -10,8 +10,8 @@
package org.eclipse.hawkbit.repository.jpa.acm;
import static org.assertj.core.api.Assertions.assertThat;
import static org.eclipse.hawkbit.im.authentication.SpPermission.READ_ROLLOUT;
import static org.eclipse.hawkbit.im.authentication.SpPermission.READ_TARGET;
import static org.eclipse.hawkbit.auth.SpPermission.READ_ROLLOUT;
import static org.eclipse.hawkbit.auth.SpPermission.READ_TARGET;
import static org.eclipse.hawkbit.repository.model.TotalTargetCountStatus.Status.NOTSTARTED;
import static org.eclipse.hawkbit.repository.model.TotalTargetCountStatus.Status.RUNNING;
import static org.eclipse.hawkbit.repository.model.TotalTargetCountStatus.Status.SCHEDULED;

View File

@@ -10,86 +10,54 @@
package org.eclipse.hawkbit.repository.jpa.acm;
import static org.assertj.core.api.Assertions.assertThat;
import static org.eclipse.hawkbit.security.SecurityContextSerializer.JSON_SERIALIZATION;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.mockStatic;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.function.Supplier;
import lombok.SneakyThrows;
import org.eclipse.hawkbit.ContextAware;
import org.eclipse.hawkbit.im.authentication.SpPermission;
import org.eclipse.hawkbit.auth.SpPermission;
import org.eclipse.hawkbit.context.AccessContext;
import org.eclipse.hawkbit.repository.AutoAssignExecutor;
import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest;
import org.eclipse.hawkbit.repository.model.Rollout;
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
import org.eclipse.hawkbit.security.SecurityContextSerializer;
import org.eclipse.hawkbit.tenancy.TenantAwareAuthenticationDetails;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.MockedStatic;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.domain.AuditorAware;
import org.springframework.data.domain.Pageable;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.test.context.ContextConfiguration;
/**
* Feature: Component Tests - Context runner<br/>
* Story: Test Context Runner
*/
@ContextConfiguration(classes = { ContextAwareTest.TestConfiguration.class })
class ContextAwareTest extends AbstractJpaIntegrationTest {
class SecurityContextCtxTest extends AbstractJpaIntegrationTest {
private static final Set<String> AUTHORITIES = SpPermission.getAllAuthorities();
@Autowired
AutoAssignExecutor autoAssignExecutor;
@Autowired
ContextAware contextAware;
@Autowired
AuditorAware<String> auditorAware;
@BeforeEach
@AfterEach
void before() {
reset(contextAware);
}
/**
* Verifies acm context is persisted when creating Rollout
*/
@Test
void verifyAcmContextIsPersistedInCreatedRollout() {
final SecurityContext securityContext = createContext(0);
assertThat(securityContext).isNotNull();
final SecurityContext userContext = createUserContext(0);
assertThat(userContext).isNotNull();
final Rollout exampleRollout = runInContext(securityContext, testdataFactory::createRollout);
final Rollout exampleRollout = withSecurityContext(userContext, testdataFactory::createRollout);
assertThat(exampleRollout.getAccessControlContext())
.hasValueSatisfying(ctx -> assertEssentialEquals(JSON_SERIALIZATION.deserialize(ctx), securityContext));
}
/**
* Verifies acm context is reused when handling a rollout
*/
@Test
void verifyContextIsReusedWhenHandlingRollout() {
final SecurityContext securityContext = createContext(1);
// testdataFactory#createRollout will trigger a rollout handling
runInContext(securityContext, testdataFactory::createRollout);
verify(contextAware).runInContext(eq(JSON_SERIALIZATION.serialize(securityContext)), any(Runnable.class));
.hasValueSatisfying(ctx -> assertEssentialEquals(deserialize(ctx), userContext));
}
/**
@@ -97,59 +65,82 @@ class ContextAwareTest extends AbstractJpaIntegrationTest {
*/
@Test
void verifyContextIsPersistedInActiveAutoAssignment() {
final SecurityContext securityContext = createContext(2);
final SecurityContext userContext = createUserContext(2);
final TargetFilterQuery targetFilterQuery =
runInContext(securityContext, testdataFactory::createTargetFilterWithTargetsAndActiveAutoAssignment);
withSecurityContext(userContext, testdataFactory::createTargetFilterWithTargetsAndActiveAutoAssignment);
assertThat(targetFilterQuery.getAccessControlContext())
.hasValueSatisfying(ctx -> assertEssentialEquals(JSON_SERIALIZATION.deserialize(ctx), securityContext));
.hasValueSatisfying(ctx -> assertEssentialEquals(deserialize(ctx), userContext));
}
/**
* Verifies acm context is used when handling a rollout
*/
@Test
void verifyContextIsUsedWhenHandlingRollout() {
final SecurityContext userContext = createUserContext(1);
final String serialized = serialize(userContext);
try (final MockedStatic<AccessContext> mocked = mockStatic(AccessContext.class, Mockito.CALLS_REAL_METHODS)) {
// testdataFactory#createRollout will trigger a rollout handling
withSecurityContext(userContext, testdataFactory::createRollout);
mocked.verify(() -> AccessContext.withSecurityContext(eq(serialized), any(Runnable.class)));
}
}
/**
* Verifies acm context is used when performing auto assign check on all target
*/
@Test
void verifyContextIsReusedWhenCheckingForAutoAssignmentAllTargets() {
final SecurityContext securityContext = createContext(3);
void verifyContextIsUsedWhenCheckingForAutoAssignmentAllTargets() {
final SecurityContext userContext = createUserContext(3);
final String serialized = serialize(userContext);
try (final MockedStatic<AccessContext> mocked = mockStatic(AccessContext.class, Mockito.CALLS_REAL_METHODS)) {
withSecurityContext(userContext, testdataFactory::createTargetFilterWithTargetsAndActiveAutoAssignment);
withSecurityContext(userContext, () -> {
autoAssignExecutor.checkAllTargets();
return null;
});
runInContext(securityContext, testdataFactory::createTargetFilterWithTargetsAndActiveAutoAssignment);
runInContext(securityContext, () -> {
autoAssignExecutor.checkAllTargets();
return null;
});
verify(contextAware).runInContext(eq(JSON_SERIALIZATION.serialize(securityContext)), any(Runnable.class));
mocked.verify(() -> AccessContext.withSecurityContext(eq(serialized), any(Runnable.class)));
}
}
/**
* Verifies acm context is used when performing auto assign check on single target
*/
@Test
void verifyContextIsReusedWhenCheckingForAutoAssignmentSingleTarget() {
final SecurityContext securityContext = createContext(4);
void verifyContextIsUsedWhenCheckingForAutoAssignmentSingleTarget() {
final SecurityContext userContext = createUserContext(4);
final String serialized = serialize(userContext);
try (final MockedStatic<AccessContext> mocked = mockStatic(AccessContext.class, Mockito.CALLS_REAL_METHODS)) {
mocked.when(() -> AccessContext.withSecurityContext(any(SecurityContext.class), (Supplier<?>) any(Supplier.class)))
.thenCallRealMethod();
runInContext(securityContext, testdataFactory::createTargetFilterWithTargetsAndActiveAutoAssignment);
runInContext(securityContext, () -> {
autoAssignExecutor.checkSingleTarget(targetManagement.findAll(Pageable.ofSize(1)).getContent().get(0).getControllerId());
return null;
});
verify(contextAware).runInContext(eq(JSON_SERIALIZATION.serialize(securityContext)), any(Runnable.class));
withSecurityContext(userContext, testdataFactory::createTargetFilterWithTargetsAndActiveAutoAssignment);
withSecurityContext(userContext, () -> {
autoAssignExecutor.checkSingleTarget(targetManagement.findAll(Pageable.ofSize(1)).getContent().get(0).getControllerId());
return null;
});
mocked.verify(() -> AccessContext.withSecurityContext(eq(serialized), any(Runnable.class)));
}
}
private static SecurityContext createContext(final int testId) {
final SecurityContext securityContext = SecurityContextHolder.createEmptyContext();
private static SecurityContext createUserContext(final int testId) {
final SecurityContext userContext = SecurityContextHolder.createEmptyContext();
final UsernamePasswordAuthenticationToken userPassAuthentication = new UsernamePasswordAuthenticationToken(
"user", null, AUTHORITIES.stream().map(SimpleGrantedAuthority::new).toList());
final TenantAwareAuthenticationDetails details = new TenantAwareAuthenticationDetails("my_tenant_" + testId, false);
userPassAuthentication.setDetails(details);
securityContext.setAuthentication(userPassAuthentication);
userContext.setAuthentication(userPassAuthentication);
assertThat(securityContext).isNotNull();
assertThat(userContext).isNotNull();
return securityContext;
return userContext;
}
@SneakyThrows
private <T> T runInContext(final SecurityContext securityContext, final Callable<T> runnable) {
private <T> T withSecurityContext(final SecurityContext securityContext, final Callable<T> runnable) {
SecurityContextHolder.setContext(securityContext);
try {
return runnable.call();
@@ -168,19 +159,17 @@ class ContextAwareTest extends AbstractJpaIntegrationTest {
private String auditor(final SecurityContext securityContext) {
SecurityContextHolder.setContext(securityContext);
try {
return auditorAware.getCurrentAuditor().orElseThrow();
return AccessContext.actor();
} finally {
SecurityContextHolder.clearContext();
}
}
@Configuration
static class TestConfiguration {
private static String serialize(final SecurityContext securityContext) {
return AccessContext.withSecurityContext(securityContext, () -> AccessContext.securityContext().orElseThrow());
}
@Bean
@ConditionalOnMissingBean
SecurityContextSerializer securityContextSerializer() {
return SecurityContextSerializer.JSON_SERIALIZATION;
}
private static SecurityContext deserialize(final String serialized) {
return AccessContext.withSecurityContext(serialized, SecurityContextHolder::getContext);
}
}

View File

@@ -12,9 +12,9 @@ package org.eclipse.hawkbit.repository.jpa.acm;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.eclipse.hawkbit.im.authentication.SpPermission.READ_PREFIX;
import static org.eclipse.hawkbit.im.authentication.SpPermission.SOFTWARE_MODULE;
import static org.eclipse.hawkbit.im.authentication.SpPermission.UPDATE_PREFIX;
import static org.eclipse.hawkbit.auth.SpPermission.READ_PREFIX;
import static org.eclipse.hawkbit.auth.SpPermission.SOFTWARE_MODULE;
import static org.eclipse.hawkbit.auth.SpPermission.UPDATE_PREFIX;
import static org.eclipse.hawkbit.repository.test.util.SecurityContextSwitch.runAs;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;

View File

@@ -12,11 +12,11 @@ package org.eclipse.hawkbit.repository.jpa.acm;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.eclipse.hawkbit.im.authentication.SpPermission.CREATE_PREFIX;
import static org.eclipse.hawkbit.im.authentication.SpPermission.DELETE_PREFIX;
import static org.eclipse.hawkbit.im.authentication.SpPermission.READ_PREFIX;
import static org.eclipse.hawkbit.im.authentication.SpPermission.SOFTWARE_MODULE_TYPE;
import static org.eclipse.hawkbit.im.authentication.SpPermission.UPDATE_PREFIX;
import static org.eclipse.hawkbit.auth.SpPermission.CREATE_PREFIX;
import static org.eclipse.hawkbit.auth.SpPermission.DELETE_PREFIX;
import static org.eclipse.hawkbit.auth.SpPermission.READ_PREFIX;
import static org.eclipse.hawkbit.auth.SpPermission.SOFTWARE_MODULE_TYPE;
import static org.eclipse.hawkbit.auth.SpPermission.UPDATE_PREFIX;
import static org.eclipse.hawkbit.repository.test.util.SecurityContextSwitch.runAs;
import java.util.List;

View File

@@ -10,19 +10,20 @@
package org.eclipse.hawkbit.repository.jpa.acm;
import static org.assertj.core.api.Assertions.assertThat;
import static org.eclipse.hawkbit.im.authentication.SpPermission.CREATE_PREFIX;
import static org.eclipse.hawkbit.im.authentication.SpPermission.DELETE_PREFIX;
import static org.eclipse.hawkbit.im.authentication.SpPermission.DELETE_TARGET;
import static org.eclipse.hawkbit.im.authentication.SpPermission.DISTRIBUTION_SET;
import static org.eclipse.hawkbit.im.authentication.SpPermission.DISTRIBUTION_SET_TYPE;
import static org.eclipse.hawkbit.im.authentication.SpPermission.READ_DISTRIBUTION_SET;
import static org.eclipse.hawkbit.im.authentication.SpPermission.READ_PREFIX;
import static org.eclipse.hawkbit.im.authentication.SpPermission.READ_TARGET;
import static org.eclipse.hawkbit.im.authentication.SpPermission.SOFTWARE_MODULE;
import static org.eclipse.hawkbit.im.authentication.SpPermission.SOFTWARE_MODULE_TYPE;
import static org.eclipse.hawkbit.im.authentication.SpPermission.TARGET_TYPE;
import static org.eclipse.hawkbit.im.authentication.SpPermission.UPDATE_PREFIX;
import static org.eclipse.hawkbit.im.authentication.SpPermission.UPDATE_TARGET;
import static org.eclipse.hawkbit.auth.SpPermission.CREATE_PREFIX;
import static org.eclipse.hawkbit.auth.SpPermission.DELETE_PREFIX;
import static org.eclipse.hawkbit.auth.SpPermission.DELETE_TARGET;
import static org.eclipse.hawkbit.auth.SpPermission.DISTRIBUTION_SET;
import static org.eclipse.hawkbit.auth.SpPermission.DISTRIBUTION_SET_TYPE;
import static org.eclipse.hawkbit.auth.SpPermission.READ_DISTRIBUTION_SET;
import static org.eclipse.hawkbit.auth.SpPermission.READ_PREFIX;
import static org.eclipse.hawkbit.auth.SpPermission.READ_TARGET;
import static org.eclipse.hawkbit.auth.SpPermission.SOFTWARE_MODULE;
import static org.eclipse.hawkbit.auth.SpPermission.SOFTWARE_MODULE_TYPE;
import static org.eclipse.hawkbit.auth.SpPermission.TARGET_TYPE;
import static org.eclipse.hawkbit.auth.SpPermission.UPDATE_PREFIX;
import static org.eclipse.hawkbit.auth.SpPermission.UPDATE_TARGET;
import static org.eclipse.hawkbit.context.AccessContext.asSystem;
import static org.eclipse.hawkbit.repository.test.util.SecurityContextSwitch.runAs;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
@@ -101,6 +102,7 @@ class SystemExecutionTest extends AbstractAccessControllerManagementTest {
private void verifyAccessController(final AccessController<?> accessController) {
verifyAccessController(accessController, 1);
}
@SuppressWarnings({ "rawtypes", "unchecked" })
private void verifyAccessController(final AccessController<?> accessController, final int times) {
final Specification mock = mock(Specification.class);
@@ -110,8 +112,8 @@ class SystemExecutionTest extends AbstractAccessControllerManagementTest {
verify(mock, times(times)).and(any()); // once for every access controller is scoped only
final Specification mockAsSystem = mock(Specification.class);
for (Operation operation : Operation.values()) {
systemSecurityContext.runAsSystem(() -> accessController.appendAccessRules(operation, mockAsSystem));
for (final Operation operation : Operation.values()) {
asSystem(() -> accessController.appendAccessRules(operation, mockAsSystem));
}
verifyNoInteractions(mockAsSystem);
}

View File

@@ -12,14 +12,15 @@ package org.eclipse.hawkbit.repository.jpa.acm;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.eclipse.hawkbit.im.authentication.SpPermission.CREATE_ROLLOUT;
import static org.eclipse.hawkbit.im.authentication.SpPermission.CREATE_TARGET;
import static org.eclipse.hawkbit.im.authentication.SpPermission.DELETE_TARGET;
import static org.eclipse.hawkbit.im.authentication.SpPermission.HANDLE_ROLLOUT;
import static org.eclipse.hawkbit.im.authentication.SpPermission.READ_DISTRIBUTION_SET;
import static org.eclipse.hawkbit.im.authentication.SpPermission.READ_ROLLOUT;
import static org.eclipse.hawkbit.im.authentication.SpPermission.READ_TARGET;
import static org.eclipse.hawkbit.im.authentication.SpPermission.UPDATE_TARGET;
import static org.eclipse.hawkbit.auth.SpPermission.CREATE_ROLLOUT;
import static org.eclipse.hawkbit.auth.SpPermission.CREATE_TARGET;
import static org.eclipse.hawkbit.auth.SpPermission.DELETE_TARGET;
import static org.eclipse.hawkbit.auth.SpPermission.HANDLE_ROLLOUT;
import static org.eclipse.hawkbit.auth.SpPermission.READ_DISTRIBUTION_SET;
import static org.eclipse.hawkbit.auth.SpPermission.READ_ROLLOUT;
import static org.eclipse.hawkbit.auth.SpPermission.READ_TARGET;
import static org.eclipse.hawkbit.auth.SpPermission.UPDATE_TARGET;
import static org.eclipse.hawkbit.context.AccessContext.asSystem;
import static org.eclipse.hawkbit.repository.test.util.SecurityContextSwitch.runAs;
import java.util.Arrays;
@@ -169,9 +170,8 @@ class TargetManagementTest extends AbstractAccessControllerManagementTest {
.containsExactly(target1Type1);
// as system in context - doesn't apply scopes
final Rollout runAsSystem = systemSecurityContext.runAsSystem(
() -> testdataFactory.createRolloutByVariables(
"testRolloutAsSystem", "testDescriptionAsSystem", 3, "id==*", ds2Type2, "50", "5"));
asSystem(() -> testdataFactory.createRolloutByVariables(
"testRolloutAsSystem", "testDescriptionAsSystem", 3, "id==*", ds2Type2, "50", "5"));
});
}

View File

@@ -12,13 +12,13 @@ package org.eclipse.hawkbit.repository.jpa.acm;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.eclipse.hawkbit.im.authentication.SpPermission.CREATE_PREFIX;
import static org.eclipse.hawkbit.im.authentication.SpPermission.DELETE_TARGET_TYPE;
import static org.eclipse.hawkbit.im.authentication.SpPermission.DISTRIBUTION_SET_TYPE;
import static org.eclipse.hawkbit.im.authentication.SpPermission.READ_PREFIX;
import static org.eclipse.hawkbit.im.authentication.SpPermission.READ_TARGET_TYPE;
import static org.eclipse.hawkbit.im.authentication.SpPermission.TARGET_TYPE;
import static org.eclipse.hawkbit.im.authentication.SpPermission.UPDATE_TARGET_TYPE;
import static org.eclipse.hawkbit.auth.SpPermission.CREATE_PREFIX;
import static org.eclipse.hawkbit.auth.SpPermission.DELETE_TARGET_TYPE;
import static org.eclipse.hawkbit.auth.SpPermission.DISTRIBUTION_SET_TYPE;
import static org.eclipse.hawkbit.auth.SpPermission.READ_PREFIX;
import static org.eclipse.hawkbit.auth.SpPermission.READ_TARGET_TYPE;
import static org.eclipse.hawkbit.auth.SpPermission.TARGET_TYPE;
import static org.eclipse.hawkbit.auth.SpPermission.UPDATE_TARGET_TYPE;
import static org.eclipse.hawkbit.repository.test.util.SecurityContextSwitch.runAs;
import java.util.Collections;

View File

@@ -11,10 +11,10 @@ package org.eclipse.hawkbit.repository.jpa.acm;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.eclipse.hawkbit.im.authentication.SpPermission.READ_DISTRIBUTION_SET;
import static org.eclipse.hawkbit.im.authentication.SpPermission.READ_TARGET;
import static org.eclipse.hawkbit.im.authentication.SpPermission.UPDATE_DISTRIBUTION_SET;
import static org.eclipse.hawkbit.im.authentication.SpPermission.UPDATE_TARGET;
import static org.eclipse.hawkbit.auth.SpPermission.READ_DISTRIBUTION_SET;
import static org.eclipse.hawkbit.auth.SpPermission.READ_TARGET;
import static org.eclipse.hawkbit.auth.SpPermission.UPDATE_DISTRIBUTION_SET;
import static org.eclipse.hawkbit.auth.SpPermission.UPDATE_TARGET;
import static org.eclipse.hawkbit.repository.test.util.SecurityContextSwitch.runAs;
import org.eclipse.hawkbit.repository.TargetFilterQueryManagement;

View File

@@ -206,9 +206,8 @@ class AutoActionCleanupTest extends AbstractJpaIntegrationTest {
}
private void setupCleanupConfiguration(final long expiry, final Status... status) {
tenantConfigurationManagement.addOrUpdateConfiguration(ACTION_CLEANUP_AUTO_EXPIRY, expiry);
tenantConfigurationManagement.addOrUpdateConfiguration(
ACTION_CLEANUP_AUTO_STATUS,
Arrays.stream(status).map(Status::toString).collect(Collectors.joining(",")));
tenantConfigurationManagement().addOrUpdateConfiguration(ACTION_CLEANUP_AUTO_EXPIRY, expiry);
tenantConfigurationManagement().addOrUpdateConfiguration(
ACTION_CLEANUP_AUTO_STATUS, Arrays.stream(status).map(Status::toString).collect(Collectors.joining(",")));
}
}

View File

@@ -47,7 +47,7 @@ class AutoCleanupSchedulerTest extends AbstractJpaIntegrationTest {
void executeHandlerChain() {
new AutoCleanupScheduler(
List.of(new SuccessfulCleanup(), new SuccessfulCleanup(), new FailingCleanup(), new SuccessfulCleanup()),
systemManagement, systemSecurityContext, lockRegistry).run();
systemManagement, lockRegistry).run();
assertThat(counter.get()).isEqualTo(4);
}

View File

@@ -31,8 +31,9 @@ import org.eclipse.hawkbit.artifact.exception.FileSizeQuotaExceededException;
import org.eclipse.hawkbit.artifact.exception.StorageQuotaExceededException;
import org.eclipse.hawkbit.artifact.model.ArtifactHashes;
import org.eclipse.hawkbit.artifact.model.ArtifactStream;
import org.eclipse.hawkbit.im.authentication.SpPermission;
import org.eclipse.hawkbit.im.authentication.SpRole;
import org.eclipse.hawkbit.auth.SpPermission;
import org.eclipse.hawkbit.auth.SpRole;
import org.eclipse.hawkbit.context.AccessContext;
import org.eclipse.hawkbit.repository.ArtifactManagement;
import org.eclipse.hawkbit.repository.event.remote.entity.SoftwareModuleCreatedEvent;
import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException;
@@ -252,7 +253,7 @@ class ArtifactManagementTest extends AbstractJpaIntegrationTest {
assertThat(artifact2.getId()).isNotNull();
assertThat(artifact1.getSha1Hash()).isNotEqualTo(artifact2.getSha1Hash());
final String currentTenant = tenantAware.getCurrentTenant();
final String currentTenant = AccessContext.tenant();
assertThat(artifactStorage.getBySha1(currentTenant, artifact1.getSha1Hash())).isNotNull();
assertThat(artifactStorage.getBySha1(currentTenant, artifact2.getSha1Hash())).isNotNull();
@@ -296,7 +297,7 @@ class ArtifactManagementTest extends AbstractJpaIntegrationTest {
assertThat(artifact2.getId()).isNotNull();
assertThat((artifact1).getSha1Hash()).isEqualTo(artifact2.getSha1Hash());
assertThat(artifactRepository.findAll()).hasSize(2);
final String currentTenant = tenantAware.getCurrentTenant();
final String currentTenant = AccessContext.tenant();
assertThat(artifactStorage.getBySha1(currentTenant, artifact1.getSha1Hash())).isNotNull();
artifactManagement.delete(artifact1.getId());

View File

@@ -12,8 +12,9 @@ package org.eclipse.hawkbit.repository.jpa.management;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.assertThatNoException;
import static org.eclipse.hawkbit.im.authentication.SpRole.CONTROLLER_ROLE;
import static org.eclipse.hawkbit.im.authentication.SpRole.CONTROLLER_ROLE_ANONYMOUS;
import static org.eclipse.hawkbit.auth.SpRole.CONTROLLER_ROLE;
import static org.eclipse.hawkbit.auth.SpRole.CONTROLLER_ROLE_ANONYMOUS;
import static org.eclipse.hawkbit.context.AccessContext.asSystem;
import static org.eclipse.hawkbit.repository.jpa.configuration.Constants.TX_RT_MAX;
import static org.eclipse.hawkbit.repository.model.Action.ActionType.DOWNLOAD_ONLY;
import static org.eclipse.hawkbit.repository.test.util.SecurityContextSwitch.runAs;
@@ -36,7 +37,7 @@ import java.util.stream.IntStream;
import jakarta.validation.ConstraintViolationException;
import org.assertj.core.api.Assertions;
import org.eclipse.hawkbit.im.authentication.SpPermission;
import org.eclipse.hawkbit.auth.SpPermission;
import org.eclipse.hawkbit.repository.RepositoryProperties;
import org.eclipse.hawkbit.repository.TargetTypeManagement;
import org.eclipse.hawkbit.repository.UpdateMode;
@@ -203,12 +204,12 @@ class ControllerManagementTest extends AbstractJpaIntegrationTest {
final Long actionId = getFirstAssignedActionId(assignDistributionSet(testDs, testTarget));
controllerManagement.addUpdateActionStatus(ActionStatusCreate.builder().actionId(actionId)
.status(Action.Status.RUNNING).timestamp(System.currentTimeMillis()).messages(List.of("proceeding message 1"))
.status(Action.Status.RUNNING).timestamp(java.lang.System.currentTimeMillis()).messages(List.of("proceeding message 1"))
.build());
waitNextMillis();
controllerManagement.addUpdateActionStatus(ActionStatusCreate.builder().actionId(actionId)
.status(Action.Status.RUNNING).timestamp(System.currentTimeMillis()).messages(List.of("proceeding message 2"))
.status(Action.Status.RUNNING).timestamp(java.lang.System.currentTimeMillis()).messages(List.of("proceeding message 2"))
.build());
final List<String> messages = controllerManagement.getActionHistoryMessages(actionId, 2);
@@ -242,7 +243,7 @@ class ControllerManagementTest extends AbstractJpaIntegrationTest {
assertThat(actionId1).isNotNull();
final ActionStatusCreateBuilder status = ActionStatusCreate.builder().actionId(actionId1).status(Status.WARNING);
for (int i = 0; i < maxStatusEntries; i++) {
controllerManagement.addInformationalActionStatus(status.messages(List.of("Msg " + i)).timestamp(System.currentTimeMillis()).build());
controllerManagement.addInformationalActionStatus(status.messages(List.of("Msg " + i)).timestamp(java.lang.System.currentTimeMillis()).build());
}
final ActionStatusCreate actionStatusCreate = status.build();
assertThatExceptionOfType(AssignmentQuotaExceededException.class)
@@ -254,7 +255,7 @@ class ControllerManagementTest extends AbstractJpaIntegrationTest {
assertThat(actionId2).isNotEqualTo(actionId1);
final ActionStatusCreateBuilder statusWarning = ActionStatusCreate.builder().actionId(actionId2).status(Status.WARNING);
for (int i = 0; i < maxStatusEntries; i++) {
controllerManagement.addUpdateActionStatus(statusWarning.messages(List.of("Msg " + i)).timestamp(System.currentTimeMillis()).build());
controllerManagement.addUpdateActionStatus(statusWarning.messages(List.of("Msg " + i)).timestamp(java.lang.System.currentTimeMillis()).build());
}
final ActionStatusCreate actionStatusCreateQE = statusWarning.build();
assertThatExceptionOfType(AssignmentQuotaExceededException.class)
@@ -1461,7 +1462,6 @@ class ControllerManagementTest extends AbstractJpaIntegrationTest {
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 3) }
)
void assignVersionToTarget() {
final DistributionSet knownDistributionSet = testdataFactory.createDistributionSet();
// GIVEN
@@ -1798,8 +1798,7 @@ class ControllerManagementTest extends AbstractJpaIntegrationTest {
}
private void createTargetType(String targetTypeName) {
systemSecurityContext.runAsSystem(
() -> targetTypeManagement.create(TargetTypeManagement.Create.builder().name(targetTypeName).build()));
asSystem(() -> targetTypeManagement.create(TargetTypeManagement.Create.builder().name(targetTypeName).build()));
}
private void addAttributeAndVerify(final String controllerId) {
@@ -1807,8 +1806,7 @@ class ControllerManagementTest extends AbstractJpaIntegrationTest {
testData.put("test1", "testdata1");
controllerManagement.updateControllerAttributes(controllerId, testData, null);
assertThat(targetManagement.getControllerAttributes(controllerId)).as("Controller Attributes are wrong")
.isEqualTo(testData);
assertThat(targetManagement.getControllerAttributes(controllerId)).as("Controller Attributes are wrong").isEqualTo(testData);
}
private void addSecondAttributeAndVerify(final String controllerId) {

View File

@@ -32,7 +32,7 @@ import jakarta.validation.ConstraintViolationException;
import lombok.Getter;
import org.assertj.core.api.Assertions;
import org.eclipse.hawkbit.repository.qfields.ActionStatusFields;
import org.eclipse.hawkbit.context.AccessContext;
import org.eclipse.hawkbit.repository.DistributionSetManagement;
import org.eclipse.hawkbit.repository.DistributionSetTagManagement;
import org.eclipse.hawkbit.repository.Identifiable;
@@ -81,6 +81,7 @@ import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TargetType;
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
import org.eclipse.hawkbit.repository.qfields.ActionStatusFields;
import org.eclipse.hawkbit.repository.test.matcher.Expect;
import org.eclipse.hawkbit.repository.test.matcher.ExpectEvents;
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey;
@@ -526,7 +527,7 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest {
assertThat(actionRepository.count()).isEqualTo(20);
assertThat(findActionsByDistributionSet(PAGE, ds.getId())).as("Offline actions are not active")
.allMatch(action -> !action.isActive()).as("Actions should be initiated by current user")
.allMatch(a -> a.getInitiatedBy().equals(tenantAware.getCurrentUsername()));
.allMatch(a -> a.getInitiatedBy().equals(AccessContext.actor()));
assertThat(targetManagement.findByInstalledDistributionSet(ds.getId(), PAGE).getContent())
.usingElementComparator(controllerIdComparator()).containsAll(targets).hasSize(10)
@@ -568,7 +569,7 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest {
// don't use peek since it is by documentation mainly for debugging and could be skipped in some cases
assertThat(a.getInitiatedBy())
.as("Actions should be initiated by current user")
.isEqualTo(tenantAware.getCurrentUsername());
.isEqualTo(AccessContext.actor());
return a;
})
.map(action -> action.getDistributionSet().getId()).toList();
@@ -593,7 +594,7 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest {
@Expect(type = TenantConfigurationCreatedEvent.class, count = 1),
@Expect(type = TenantConfigurationUpdatedEvent.class, count = 1) })
void assignDistributionSetAndAutoCloseActiveActions() {
tenantConfigurationManagement.addOrUpdateConfiguration(TenantConfigurationKey.REPOSITORY_ACTIONS_AUTOCLOSE_ENABLED, true);
tenantConfigurationManagement().addOrUpdateConfiguration(TenantConfigurationKey.REPOSITORY_ACTIONS_AUTOCLOSE_ENABLED, true);
try {
final List<Target> targets = testdataFactory.createTargets(10);
@@ -615,7 +616,7 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest {
.as("InstallationDate not set").allMatch(target -> (target.getInstallationDate() == null));
} finally {
tenantConfigurationManagement.addOrUpdateConfiguration(TenantConfigurationKey.REPOSITORY_ACTIONS_AUTOCLOSE_ENABLED, false);
tenantConfigurationManagement().addOrUpdateConfiguration(TenantConfigurationKey.REPOSITORY_ACTIONS_AUTOCLOSE_ENABLED, false);
}
}
@@ -672,7 +673,7 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest {
final List<DeploymentRequest> deploymentRequests = createAssignmentRequests(distributionSets, targets, 34);
enableMultiAssignments();
final List<DistributionSetAssignmentResult> results = deploymentManagement.assignDistributionSets(deploymentRequests);
final List<DistributionSetAssignmentResult> results = deploymentManagement.assignDistributionSets(deploymentRequests, null);
assertThat(getResultingActionCount(results)).isEqualTo(deploymentRequests.size());
final List<Long> dsIds = distributionSets.stream().map(DistributionSet::getId).toList();
@@ -682,7 +683,7 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest {
.map(a -> {
// don't use peek since it is by documentation mainly for debugging and could be skipped in some cases
assertThat(a.getInitiatedBy()).as("Initiated by current user")
.isEqualTo(tenantAware.getCurrentUsername());
.isEqualTo(AccessContext.actor());
return a;
})
.map(action -> action.getDistributionSet().getId()).toList();
@@ -712,7 +713,7 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest {
final List<DeploymentRequest> deploymentRequests = createAssignmentRequests(distributionSets, targets, 34, false);
enableMultiAssignments();
final List<DistributionSetAssignmentResult> results = deploymentManagement.assignDistributionSets(deploymentRequests);
final List<DistributionSetAssignmentResult> results = deploymentManagement.assignDistributionSets(deploymentRequests, null);
assertThat(getResultingActionCount(results)).isEqualTo(deploymentRequests.size());
@@ -721,7 +722,7 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest {
deploymentManagement.findActionsByTarget(target.getControllerId(), PAGE).forEach(action -> {
assertThat(action.getDistributionSet().getId()).isIn(dsIds);
assertThat(action.getInitiatedBy())
.as("Should be Initiated by current user").isEqualTo(tenantAware.getCurrentUsername());
.as("Should be Initiated by current user").isEqualTo(AccessContext.actor());
deploymentManagement.cancelAction(action.getId());
}));
}
@@ -742,10 +743,10 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest {
final List<DeploymentRequest> deploymentRequests = List.of(targetToDS0, targetToDS1);
Assertions.assertThatExceptionOfType(MultiAssignmentIsNotEnabledException.class)
.isThrownBy(() -> deploymentManagement.assignDistributionSets(deploymentRequests));
.isThrownBy(() -> deploymentManagement.assignDistributionSets(deploymentRequests, null));
enableMultiAssignments();
assertThat(getResultingActionCount(deploymentManagement.assignDistributionSets(Arrays.asList(targetToDS0, targetToDS1)))).isEqualTo(2);
assertThat(getResultingActionCount(deploymentManagement.assignDistributionSets(List.of(targetToDS0, targetToDS1), null))).isEqualTo(2);
}
/**
@@ -793,7 +794,7 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest {
deploymentManagement.findActionsByTarget(controllerId, PAGE).forEach(action -> {
assertThat(action.getDistributionSet().getId()).isIn(distributionSet.getId());
assertThat(action.getInitiatedBy())
.as("Should be Initiated by current user").isEqualTo(tenantAware.getCurrentUsername());
.as("Should be Initiated by current user").isEqualTo(AccessContext.actor());
if (confirmationRequired) {
assertThat(action.getStatus()).isEqualTo(Status.WAIT_FOR_CONFIRMATION);
} else {
@@ -906,7 +907,7 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest {
deploymentManagement.findActionsByTarget(controllerId, PAGE).forEach(action -> {
assertThat(action.getDistributionSet().getId()).isIn(distributionSet.getId());
assertThat(action.getInitiatedBy())
.as("Should be Initiated by current user").isEqualTo(tenantAware.getCurrentUsername());
.as("Should be Initiated by current user").isEqualTo(AccessContext.actor());
assertThat(action.getStatus()).isEqualTo(RUNNING);
}));
}
@@ -930,13 +931,13 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest {
final String targetId = testdataFactory.createTarget().getControllerId();
final Long dsId = testdataFactory.createDistributionSet().getId();
final List<DeploymentRequest> twoEqualAssignments = Collections.nCopies(2, DeploymentRequest.builder(targetId, dsId).build());
assertThat(getResultingActionCount(deploymentManagement.assignDistributionSets(twoEqualAssignments))).isEqualTo(1);
assertThat(getResultingActionCount(deploymentManagement.assignDistributionSets(twoEqualAssignments, null))).isEqualTo(1);
enableMultiAssignments();
final List<DeploymentRequest> twoEqualAssignmentsWithWeight = Collections.nCopies(
2, DeploymentRequest.builder(targetId, dsId).weight(555).build());
assertThat(getResultingActionCount(deploymentManagement.assignDistributionSets(twoEqualAssignmentsWithWeight))).isEqualTo(1);
assertThat(getResultingActionCount(deploymentManagement.assignDistributionSets(twoEqualAssignmentsWithWeight, null))).isEqualTo(1);
}
/**
@@ -965,7 +966,7 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest {
enableMultiAssignments();
Assertions.assertThatExceptionOfType(AssignmentQuotaExceededException.class)
.isThrownBy(() -> deploymentManagement.assignDistributionSets(deploymentRequests));
.isThrownBy(() -> deploymentManagement.assignDistributionSets(deploymentRequests, null));
assertThat(actionRepository.countByTargetControllerId(controllerId)).isZero();
}
@@ -981,7 +982,7 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest {
final DeploymentRequest assignWithWeight = DeploymentRequest.builder(targetId, dsId).weight(567).build();
enableMultiAssignments();
assertThat(deploymentManagement.assignDistributionSets(List.of(assignWithoutWeight, assignWithWeight))).isNotNull();
assertThat(deploymentManagement.assignDistributionSets(List.of(assignWithoutWeight, assignWithWeight), null)).isNotNull();
}
/**
@@ -993,7 +994,7 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest {
final Long dsId = testdataFactory.createDistributionSet().getId();
final DeploymentRequest assignWithoutWeight = DeploymentRequest.builder(targetId, dsId).weight(456).build();
assertThat(deploymentManagement.assignDistributionSets(Collections.singletonList(assignWithoutWeight))).isNotNull().size().isEqualTo(1);
assertThat(deploymentManagement.assignDistributionSets(Collections.singletonList(assignWithoutWeight), null)).isNotNull().size().isEqualTo(1);
}
/**
@@ -1020,14 +1021,14 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest {
enableMultiAssignments();
final List<DeploymentRequest> deploymentRequestsTooLow = Collections.singletonList(weightTooLow);
Assertions.assertThatExceptionOfType(ConstraintViolationException.class)
.isThrownBy(() -> deploymentManagement.assignDistributionSets(deploymentRequestsTooLow));
.isThrownBy(() -> deploymentManagement.assignDistributionSets(deploymentRequestsTooLow, null));
final List<DeploymentRequest> deploymentRequestsTooHigh = Collections.singletonList(weightTooHigh);
Assertions.assertThatExceptionOfType(ConstraintViolationException.class).isThrownBy(
() -> deploymentManagement.assignDistributionSets(deploymentRequestsTooHigh));
() -> deploymentManagement.assignDistributionSets(deploymentRequestsTooHigh, null));
final Long validActionId1 = getFirstAssignedAction(
deploymentManagement.assignDistributionSets(Collections.singletonList(validRequest1)).get(0)).getId();
deploymentManagement.assignDistributionSets(Collections.singletonList(validRequest1), null).get(0)).getId();
final Long validActionId2 = getFirstAssignedAction(
deploymentManagement.assignDistributionSets(Collections.singletonList(validRequest2)).get(0)).getId();
deploymentManagement.assignDistributionSets(Collections.singletonList(validRequest2), null).get(0)).getId();
assertThat(actionRepository.findById(validActionId1).get().getWeight()).get().isEqualTo(Action.WEIGHT_MAX);
assertThat(actionRepository.findById(validActionId2).get().getWeight()).get().isEqualTo(Action.WEIGHT_MIN);
}
@@ -1062,7 +1063,7 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest {
final Page<JpaAction> actions = actionRepository.findAll(PAGE);
assertThat(actions.getNumberOfElements()).as("wrong size of actions").isEqualTo(20);
assertThat(actions).as("Actions should be initiated by current user")
.allMatch(a -> a.getInitiatedBy().equals(tenantAware.getCurrentUsername()));
.allMatch(a -> a.getInitiatedBy().equals(AccessContext.actor()));
final Iterable<? extends Target> allFoundTargets = targetManagement.findAll(PAGE).getContent();
@@ -1161,7 +1162,7 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest {
// retrieving all Actions created by the assignDistributionSet call
final Page<JpaAction> page = actionRepository.findAll(PAGE);
assertThat(page).as("Actions should be initiated by current user")
.allMatch(a -> a.getInitiatedBy().equals(tenantAware.getCurrentUsername()));
.allMatch(a -> a.getInitiatedBy().equals(AccessContext.actor()));
// and verify the number
assertThat(page.getTotalElements()).as("wrong size of actions")
.isEqualTo(noOfDeployedTargets * noOfDistributionSets);
@@ -1556,7 +1557,7 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest {
deploymentRequests.add(deployment);
}
deploymentManagement.assignDistributionSets(deploymentRequests);
deploymentManagement.assignDistributionSets(deploymentRequests, null);
implicitLock(ds);
final List<? extends Target> content = targetManagement.findAll(Pageable.unpaged()).getContent();
@@ -1579,7 +1580,7 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest {
final DeploymentRequest deployment2 = DeploymentRequest.builder(target2.getControllerId(), ds.getId()).build();
final List<DeploymentRequest> deploymentRequests = Arrays.asList(deployment1, deployment2);
deploymentManagement.assignDistributionSets(deploymentRequests);
deploymentManagement.assignDistributionSets(deploymentRequests, null);
implicitLock(ds);
final DistributionSet assignedDsTarget1 = ((JpaTarget) targetManagement
@@ -1605,7 +1606,7 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest {
final List<DeploymentRequest> deploymentRequests = List.of(deploymentRequest);
assertThatExceptionOfType(IncompatibleTargetTypeException.class)
.isThrownBy(() -> deploymentManagement.assignDistributionSets(deploymentRequests));
.isThrownBy(() -> deploymentManagement.assignDistributionSets(deploymentRequests, null));
}
/**
@@ -1621,7 +1622,7 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest {
.builder(targetWithEmptyType.getControllerId(), ds.getId()).build();
final List<DeploymentRequest> deploymentRequests = Collections.singletonList(deploymentRequestWithEmptyType);
assertThatExceptionOfType(IncompatibleTargetTypeException.class)
.isThrownBy(() -> deploymentManagement.assignDistributionSets(deploymentRequests));
.isThrownBy(() -> deploymentManagement.assignDistributionSets(deploymentRequests, null));
}
@Test
@@ -1648,7 +1649,7 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest {
() -> assignDistributionSet(exceededQuotaDsAssign.getId(), target.getControllerId()));
// set purge config to 25 %
tenantConfigurationManagement.addOrUpdateConfiguration(TenantConfigurationKey.ACTION_CLEANUP_ON_QUOTA_HIT_PERCENTAGE, 25);
tenantConfigurationManagement().addOrUpdateConfiguration(TenantConfigurationKey.ACTION_CLEANUP_ON_QUOTA_HIT_PERCENTAGE, 25);
// assign again
assignDistributionSet(exceededQuotaDsAssign.getId(), target.getControllerId());
@@ -1687,7 +1688,7 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest {
assertEquals(20, deploymentManagement.countActionsByTarget(target.getControllerId()));
// set purge config to 25 %
tenantConfigurationManagement.addOrUpdateConfiguration(TenantConfigurationKey.ACTION_CLEANUP_ON_QUOTA_HIT_PERCENTAGE, 25);
tenantConfigurationManagement().addOrUpdateConfiguration(TenantConfigurationKey.ACTION_CLEANUP_ON_QUOTA_HIT_PERCENTAGE, 25);
rolloutHandler.handleAll();
assertEquals(16, deploymentManagement.countActionsByTarget(target.getControllerId()));
@@ -1708,7 +1709,7 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest {
rolloutHandler.handleAll();
}
tenantConfigurationManagement.addOrUpdateConfiguration(TenantConfigurationKey.ACTION_CLEANUP_ON_QUOTA_HIT_PERCENTAGE, 25);
tenantConfigurationManagement().addOrUpdateConfiguration(TenantConfigurationKey.ACTION_CLEANUP_ON_QUOTA_HIT_PERCENTAGE, 25);
deploymentManagement.handleMaxAssignmentsExceeded(target.getId(), 5L, new AssignmentQuotaExceededException());
// only 3 actions should be deleted in such case :
assertEquals(15, deploymentManagement.countActionsByTarget(target.getControllerId()));
@@ -1753,7 +1754,7 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest {
private void assertDsExclusivelyAssignedToTargets(final List<Target> targets, final long dsId, final boolean active, final Status status) {
final List<Action> assignment = findActionsByDistributionSet(PAGE, dsId).getContent();
final String currentUsername = tenantAware.getCurrentUsername();
final String currentUsername = AccessContext.actor();
assertThat(assignment).hasSize(10).allMatch(action -> action.isActive() == active)
.as("Is assigned to DS " + dsId).allMatch(action -> action.getDistributionSet().getId().equals(dsId))
@@ -1771,7 +1772,7 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest {
deploymentRequests.add(new DeploymentRequest(controllerId, distributionSet.getId(), ActionType.FORCED, 0,
null, null, null, null, confirmationRequired));
}
return deploymentManagement.assignDistributionSets(deploymentRequests);
return deploymentManagement.assignDistributionSets(deploymentRequests, null);
}
private int getResultingActionCount(final List<DistributionSetAssignmentResult> results) {

View File

@@ -11,6 +11,7 @@ package org.eclipse.hawkbit.repository.jpa.management;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.eclipse.hawkbit.context.AccessContext.asSystem;
import java.util.Collection;
import java.util.Collections;
@@ -185,11 +186,9 @@ class DistributionSetInvalidationManagementTest extends AbstractJpaIntegrationTe
@Test
@WithUser(authorities = { "READ_DISTRIBUTION_SET", "UPDATE_DISTRIBUTION_SET" })
void verifyInvalidateWithReadAndUpdateRepoAuthority() {
final InvalidationTestData invalidationTestData = systemSecurityContext
.runAsSystem(() -> createInvalidationTestData("verifyInvalidateWithUpdateRepoAuthority"));
final InvalidationTestData invalidationTestData = asSystem(() -> createInvalidationTestData("verifyInvalidateWithUpdateRepoAuthority"));
distributionSetInvalidationManagement.invalidateDistributionSet(new DistributionSetInvalidation(
Collections.singletonList(invalidationTestData.distributionSet().getId()), ActionCancellationType.NONE));
List.of(invalidationTestData.distributionSet().getId()), ActionCancellationType.NONE));
assertThat(distributionSetRepository.findById(invalidationTestData.distributionSet().getId()).orElseThrow().isValid()).isFalse();
}
@@ -199,7 +198,7 @@ class DistributionSetInvalidationManagementTest extends AbstractJpaIntegrationTe
@Test
@WithUser(authorities = { "READ_DISTRIBUTION_SET", "UPDATE_DISTRIBUTION_SET", "UPDATE_TARGET" })
void verifyInvalidateWithReadAndUpdateRepoAndUpdateTargetAuthority() {
final InvalidationTestData invalidationTestData = systemSecurityContext.runAsSystem(
final InvalidationTestData invalidationTestData = asSystem(
() -> createInvalidationTestData("verifyInvalidateWithUpdateRepoAndUpdateTargetAuthority"));
final DistributionSetInvalidation distributionSetInvalidation = new DistributionSetInvalidation(
@@ -219,7 +218,7 @@ class DistributionSetInvalidationManagementTest extends AbstractJpaIntegrationTe
@Test
@WithUser(authorities = { "READ_DISTRIBUTION_SET", "UPDATE_DISTRIBUTION_SET", "UPDATE_TARGET", "UPDATE_ROLLOUT" })
void verifyInvalidateWithReadAndUpdateRepoAndUpdateTargetAndUpdateRolloutAuthority() {
final InvalidationTestData invalidationTestData = systemSecurityContext.runAsSystem(
final InvalidationTestData invalidationTestData = asSystem(
() -> createInvalidationTestData("verifyInvalidateWithUpdateRepoAndUpdateTargetAuthority"));
distributionSetInvalidationManagement.invalidateDistributionSet(new DistributionSetInvalidation(
@@ -241,7 +240,7 @@ class DistributionSetInvalidationManagementTest extends AbstractJpaIntegrationTe
// if implicitly locked - the old distribution set becomes stale
distributionSet = assignDistributionSet(distributionSet, targets).getDistributionSet();
final TargetFilterQuery targetFilterQuery = targetFilterQueryManagement.create(TargetFilterQueryManagement.Create.builder()
.name(testName).query("name==*").autoAssignDistributionSet(distributionSet).build());
.name(testName).query("name==*").autoAssignDistributionSet(distributionSet).build());
final Rollout rollout = testdataFactory.createRolloutByVariables(testName, "desc", 2, "name==*", distributionSet, "50", "80");
return new InvalidationTestData(distributionSet, targets, targetFilterQuery, rollout);
@@ -260,9 +259,11 @@ class DistributionSetInvalidationManagementTest extends AbstractJpaIntegrationTe
}
private DistributionSetInvalidationCount countEntitiesForInvalidation(final DistributionSetInvalidation distributionSetInvalidation) {
return systemSecurityContext.runAsSystem(() -> {
return asSystem(() -> {
final Collection<Long> setIds = distributionSetInvalidation.getDistributionSetIds();
final long rolloutsCount = distributionSetInvalidation.getActionCancellationType() != ActionCancellationType.NONE ? countRolloutsForInvalidation(setIds) : 0;
final long rolloutsCount = distributionSetInvalidation.getActionCancellationType() != ActionCancellationType.NONE
? countRolloutsForInvalidation(setIds)
: 0;
final long autoAssignmentsCount = countAutoAssignmentsForInvalidation(setIds);
final long actionsCount = countActionsForInvalidation(setIds, distributionSetInvalidation.getActionCancellationType());

View File

@@ -38,8 +38,9 @@ import io.github.classgraph.ClassInfo;
import io.github.classgraph.ScanResult;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions;
import org.eclipse.hawkbit.auth.SpringEvalExpressions;
import org.eclipse.hawkbit.repository.PermissionSupport;
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
import org.eclipse.hawkbit.repository.TenantStatsManagement;
import org.eclipse.hawkbit.repository.exception.InsufficientPermissionException;
import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest;
@@ -74,6 +75,8 @@ class ManagementSecurityTest extends AbstractJpaIntegrationTest {
@Autowired
protected TenantStatsManagement tenantStatsManagement;
@Autowired
protected TenantConfigurationManagement tenantConfigurationManagement;
@Override
@BeforeEach
@@ -86,19 +89,21 @@ class ManagementSecurityTest extends AbstractJpaIntegrationTest {
void testMethod(final Class<?> managementInterface, final Method managementInterfaceMethod) {
final Object managementObject = TenantStatsManagement.class == managementInterface
? tenantStatsManagement // it's not a field of AbstractIntegrationTest, so we need to use the autowired instance
: Stream
.of(AbstractIntegrationTest.class.getDeclaredFields())
.filter(field -> managementInterface.isAssignableFrom(field.getType()))
.findFirst()
.map(field -> {
field.setAccessible(true);
try {
return field.get(this);
} catch (final IllegalAccessException e) {
throw new AssertionError("Could not access field " + field.getName(), e);
}
})
.orElseThrow(() -> new AssertionError("No management implementation found for " + managementInterface));
: TenantConfigurationManagement.class == managementInterface
? tenantConfigurationManagement // it's not a field of AbstractIntegrationTest, so we need to use the autowired instance
: Stream
.of(AbstractIntegrationTest.class.getDeclaredFields())
.filter(field -> managementInterface.isAssignableFrom(field.getType()))
.findFirst()
.map(field -> {
field.setAccessible(true);
try {
return field.get(this);
} catch (final IllegalAccessException e) {
throw new AssertionError("Could not access field " + field.getName(), e);
}
})
.orElseThrow(() -> new AssertionError("No management implementation found for " + managementInterface));
final Class<?> managedClass = ClassUtils.getUserClass(managementObject); // managed class is a proxy
final Method implementationMethod = findImplementationMethod(managedClass, managementInterfaceMethod);
if (implementationMethod == null) {

View File

@@ -27,11 +27,8 @@ import org.eclipse.hawkbit.repository.model.Rollout;
import org.eclipse.hawkbit.repository.model.Rollout.RolloutStatus;
import org.eclipse.hawkbit.repository.model.RolloutGroup;
import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupStatus;
import org.eclipse.hawkbit.security.SecurityContextSerializer;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.test.context.TestPropertySource;
@@ -45,15 +42,6 @@ import org.springframework.test.context.TestPropertySource;
@TestPropertySource(properties = { "hawkbit.server.repository.dynamicRolloutsMinInvolvePeriodMS=-1" })
class RolloutManagementFlowTest extends AbstractJpaIntegrationTest {
@Configuration
static class Config {
@Bean
SecurityContextSerializer securityContextSerializer() {
return SecurityContextSerializer.JSON_SERIALIZATION;
}
}
@BeforeEach
void reset() {
this.approvalStrategy.setApprovalNeeded(false);

View File

@@ -27,8 +27,8 @@ import jakarta.validation.ValidationException;
import org.assertj.core.api.Assertions;
import org.assertj.core.api.Condition;
import org.eclipse.hawkbit.im.authentication.SpPermission;
import org.eclipse.hawkbit.im.authentication.SpRole;
import org.eclipse.hawkbit.auth.SpPermission;
import org.eclipse.hawkbit.auth.SpRole;
import org.eclipse.hawkbit.repository.Identifiable;
import org.eclipse.hawkbit.repository.OffsetBasedPageRequest;
import org.eclipse.hawkbit.repository.RolloutManagement.Create;
@@ -243,8 +243,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
*/
@Test
void rolloutAssignsNewDistributionSetAndAutoCloseActiveActions() {
tenantConfigurationManagement
.addOrUpdateConfiguration(TenantConfigurationKey.REPOSITORY_ACTIONS_AUTOCLOSE_ENABLED, true);
tenantConfigurationManagement().addOrUpdateConfiguration(TenantConfigurationKey.REPOSITORY_ACTIONS_AUTOCLOSE_ENABLED, true);
try {
// manually assign distribution set to target
@@ -277,8 +276,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
.filter(action -> !action.getId().equals(manuallyAssignedActionId)).findAny().get();
assertThat(rolloutCreatedAction.getStatus()).isEqualTo(Status.RUNNING);
} finally {
tenantConfigurationManagement
.addOrUpdateConfiguration(TenantConfigurationKey.REPOSITORY_ACTIONS_AUTOCLOSE_ENABLED, false);
tenantConfigurationManagement().addOrUpdateConfiguration(TenantConfigurationKey.REPOSITORY_ACTIONS_AUTOCLOSE_ENABLED, false);
}
}

View File

@@ -25,6 +25,7 @@ import java.util.Set;
import jakarta.validation.ConstraintViolationException;
import org.eclipse.hawkbit.artifact.exception.ArtifactBinaryNotFoundException;
import org.eclipse.hawkbit.context.AccessContext;
import org.eclipse.hawkbit.repository.DistributionSetManagement;
import org.eclipse.hawkbit.repository.SoftwareModuleManagement;
import org.eclipse.hawkbit.repository.SoftwareModuleManagement.Create;
@@ -481,13 +482,13 @@ class SoftwareModuleManagementTest
assertThat(artifactRepository.findAll()).hasSize(results.length);
for (final Artifact result : results) {
assertThat(result.getId()).isNotNull();
assertThat(artifactStorage.getBySha1(tenantAware.getCurrentTenant(), result.getSha1Hash())).isNotNull();
assertThat(artifactStorage.getBySha1(AccessContext.tenant(), result.getSha1Hash())).isNotNull();
}
}
private void assertArtifactDoesntExist(final Artifact... results) {
for (final Artifact result : results) {
final String currentTenant = tenantAware.getCurrentTenant();
final String currentTenant = AccessContext.tenant();
final String sha1Hash = result.getSha1Hash();
assertThatExceptionOfType(ArtifactBinaryNotFoundException.class)
.isThrownBy(() -> artifactStorage.getBySha1(currentTenant, sha1Hash));

View File

@@ -14,13 +14,12 @@ import static org.assertj.core.api.Assertions.assertThat;
import java.io.ByteArrayInputStream;
import java.util.List;
import org.eclipse.hawkbit.im.authentication.SpRole;
import org.eclipse.hawkbit.auth.SpRole;
import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest;
import org.eclipse.hawkbit.repository.model.ArtifactUpload;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.report.TenantUsage;
import org.eclipse.hawkbit.repository.test.util.DisposableSqlTestDatabaseExtension;
import org.eclipse.hawkbit.repository.test.util.SecurityContextSwitch;
import org.junit.jupiter.api.Test;
@@ -45,89 +44,6 @@ class SystemManagementTest extends AbstractJpaIntegrationTest {
assertThat(systemManagement.findTenants(PAGE).getContent()).hasSize(3);
}
/**
* Ensures that getSystemUsageStatisticsWithTenants returns the usage of all tenants and not only the first 1000 (max page size).
*/
@Test
void systemUsageReportCollectsStatisticsOfManyTenants() {
// Prepare tenants
createTestTenantsForSystemStatistics(1050, 0, 0, 0);
final List<TenantUsage> tenants = systemManagement.getSystemUsageStatisticsWithTenants().getTenants();
assertThat(tenants).hasSize(1051); // +1 from the setup
}
/**
* Checks that the system report calculates correctly the artifact size of all tenants in the system. It ignores deleted software modules with their artifacts.
*/
@Test
void systemUsageReportCollectsArtifactsOfAllTenants() {
// Prepare tenants
createTestTenantsForSystemStatistics(2, 1234, 0, 0);
// overall data
assertThat(systemManagement.getSystemUsageStatistics().getOverallArtifacts()).isEqualTo(2);
assertThat(systemManagement.getSystemUsageStatistics().getOverallArtifactVolumeInBytes()).isEqualTo(1234 * 2);
// per tenant data
final List<TenantUsage> tenants = systemManagement.getSystemUsageStatisticsWithTenants().getTenants();
assertThat(tenants).hasSize(3);
final TenantUsage tenantUsage0 = new TenantUsage("TENANT0");
tenantUsage0.setArtifacts(1);
tenantUsage0.setOverallArtifactVolumeInBytes(1234);
final TenantUsage tenantUsage1 = new TenantUsage("TENANT1");
tenantUsage1.setArtifacts(1);
tenantUsage1.setOverallArtifactVolumeInBytes(1234);
assertThat(tenants).containsOnly(new TenantUsage("DEFAULT"),
tenantUsage0,
tenantUsage1);
}
/**
* Checks that the system report calculates correctly the targets size of all tenants in the system
*/
@Test
void systemUsageReportCollectsTargetsOfAllTenants() {
// Prepare tenants
createTestTenantsForSystemStatistics(2, 0, 100, 0);
// overall data
assertThat(systemManagement.getSystemUsageStatistics().getOverallTargets()).isEqualTo(200);
assertThat(systemManagement.getSystemUsageStatistics().getOverallActions()).isZero();
// per tenant data
final List<TenantUsage> tenants = systemManagement.getSystemUsageStatisticsWithTenants().getTenants();
assertThat(tenants).hasSize(3);
final TenantUsage tenantUsage0 = new TenantUsage("TENANT0");
tenantUsage0.setTargets(100);
final TenantUsage tenantUsage1 = new TenantUsage("TENANT1");
tenantUsage1.setTargets(100);
assertThat(tenants).containsOnly(new TenantUsage("DEFAULT"), tenantUsage0, tenantUsage1);
}
/**
* Checks that the system report calculates correctly the actions size of all tenants in the system
*/
@Test
void systemUsageReportCollectsActionsOfAllTenants() {
// Prepare tenants
createTestTenantsForSystemStatistics(2, 0, 20, 2);
// 2 tenants, 100 targets each, 2 deployments per target => 400
assertThat(systemManagement.getSystemUsageStatistics().getOverallActions()).isEqualTo(80);
// per tenant data
final List<TenantUsage> tenants = systemManagement.getSystemUsageStatisticsWithTenants().getTenants();
assertThat(tenants).hasSize(3);
final TenantUsage tenantUsage0 = new TenantUsage("TENANT0");
tenantUsage0.setTargets(20);
tenantUsage0.setActions(40);
final TenantUsage tenantUsage1 = new TenantUsage("TENANT1");
tenantUsage1.setTargets(20);
tenantUsage1.setActions(40);
assertThat(tenants).containsOnly(new TenantUsage("DEFAULT"), tenantUsage0, tenantUsage1);
}
private void createTestTenantsForSystemStatistics(final int tenants, final int artifactSize, final int targets, final int updates) {
final byte[] random = new byte[artifactSize];
RND.nextBytes(random);

View File

@@ -20,7 +20,6 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.function.Supplier;
import jakarta.validation.ConstraintViolationException;

View File

@@ -12,6 +12,7 @@ package org.eclipse.hawkbit.repository.jpa.management;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.fail;
import static org.eclipse.hawkbit.context.AccessContext.asSystem;
import java.net.URI;
import java.util.ArrayList;
@@ -31,8 +32,8 @@ import jakarta.persistence.criteria.Root;
import jakarta.persistence.criteria.SetJoin;
import jakarta.validation.ConstraintViolationException;
import org.eclipse.hawkbit.im.authentication.SpPermission;
import org.eclipse.hawkbit.im.authentication.SpRole;
import org.eclipse.hawkbit.auth.SpPermission;
import org.eclipse.hawkbit.auth.SpRole;
import org.eclipse.hawkbit.repository.Identifiable;
import org.eclipse.hawkbit.repository.MetadataSupport;
import org.eclipse.hawkbit.repository.TargetManagement.Create;
@@ -145,7 +146,7 @@ class TargetManagementTest extends AbstractRepositoryManagementWithMetadataTest<
createdTarget::getSecurityToken);
// retrieve security token as system code execution
final String securityTokenAsSystemCode = systemSecurityContext.runAsSystem(createdTarget::getSecurityToken);
final String securityToken = asSystem(createdTarget::getSecurityToken);
// retrieve security token without any permissions
final String securityTokenWithoutPermission = SecurityContextSwitch
@@ -155,7 +156,7 @@ class TargetManagementTest extends AbstractRepositoryManagementWithMetadataTest<
assertThat(securityTokenWithReadPermission).isNotNull();
assertThat(securityTokenWithTargetAdminPermission).isNotNull();
assertThat(securityTokenWithTenantAdminPermission).isNotNull();
assertThat(securityTokenAsSystemCode).isNotNull();
assertThat(securityToken).isNotNull();
assertThat(securityTokenWithoutPermission).isNull();
}
@@ -216,7 +217,7 @@ class TargetManagementTest extends AbstractRepositoryManagementWithMetadataTest<
createTargetWithAttributes("4711");
final long current = System.currentTimeMillis();
final long current = java.lang.System.currentTimeMillis();
controllerManagement.findOrRegisterTargetIfItDoesNotExist("4711", LOCALHOST);
final DistributionSetAssignmentResult result = assignDistributionSet(testDs1.getId(), "4711");

View File

@@ -31,7 +31,7 @@ import org.springframework.core.env.Environment;
/**
* Feature: Component Tests - Repository<br/>
* Story: Tenant Configuration Management
* Story: AccessContext Configuration Management
*/
class TenantConfigurationManagementTest extends AbstractJpaIntegrationTest implements EnvironmentAware {
@@ -51,7 +51,7 @@ class TenantConfigurationManagementTest extends AbstractJpaIntegrationTest imple
assertThat(envPropertyDefault).isNotNull();
// get the configuration from the system management
final TenantConfigurationValue<String> defaultConfigValue = tenantConfigurationManagement.getConfigurationValue(
final TenantConfigurationValue<String> defaultConfigValue = tenantConfigurationManagement().getConfigurationValue(
TenantConfigurationKey.AUTHENTICATION_GATEWAY_SECURITY_TOKEN_KEY, String.class);
assertThat(defaultConfigValue.isGlobal()).isTrue();
@@ -60,11 +60,11 @@ class TenantConfigurationManagementTest extends AbstractJpaIntegrationTest imple
// update the tenant specific configuration, create
final String newConfigurationValue = "thisIsAnotherTokenName";
assertThat(newConfigurationValue).isNotEqualTo(defaultConfigValue.getValue());
tenantConfigurationManagement.addOrUpdateConfiguration(
tenantConfigurationManagement().addOrUpdateConfiguration(
TenantConfigurationKey.AUTHENTICATION_GATEWAY_SECURITY_TOKEN_KEY, newConfigurationValue);
// verify that new configuration value is used
final TenantConfigurationValue<String> updatedConfigurationValue = tenantConfigurationManagement
final TenantConfigurationValue<String> updatedConfigurationValue = tenantConfigurationManagement()
.getConfigurationValue(TenantConfigurationKey.AUTHENTICATION_GATEWAY_SECURITY_TOKEN_KEY, String.class);
assertThat(updatedConfigurationValue.isGlobal()).isFalse();
@@ -73,16 +73,16 @@ class TenantConfigurationManagementTest extends AbstractJpaIntegrationTest imple
// update the tenant specific configuration, create
final String newConfigurationValue2 = "thisIsAnotherTokenName2";
assertThat(newConfigurationValue2).isNotEqualTo(updatedConfigurationValue.getValue());
tenantConfigurationManagement.addOrUpdateConfiguration(
tenantConfigurationManagement().addOrUpdateConfiguration(
TenantConfigurationKey.AUTHENTICATION_GATEWAY_SECURITY_TOKEN_KEY, newConfigurationValue2);
// verify that new configuration value is used
final TenantConfigurationValue<String> updatedConfigurationValue2 = tenantConfigurationManagement
final TenantConfigurationValue<String> updatedConfigurationValue2 = tenantConfigurationManagement()
.getConfigurationValue(TenantConfigurationKey.AUTHENTICATION_GATEWAY_SECURITY_TOKEN_KEY, String.class);
assertThat(updatedConfigurationValue2.isGlobal()).isFalse();
assertThat(updatedConfigurationValue2.getValue()).isEqualTo(newConfigurationValue2);
// assertThat(tenantConfigurationManagement.getTenantConfigurations()).hasSize(1);
// assertThat(tenantConfigurationManagement().getTenantConfigurations()).hasSize(1);
}
/**
@@ -95,12 +95,12 @@ class TenantConfigurationManagementTest extends AbstractJpaIntegrationTest imple
final String value2 = "secondValue";
// add value first
tenantConfigurationManagement.addOrUpdateConfiguration(configKey, value1);
assertThat(tenantConfigurationManagement.getConfigurationValue(configKey, String.class).getValue()).isEqualTo(value1);
tenantConfigurationManagement().addOrUpdateConfiguration(configKey, value1);
assertThat(tenantConfigurationManagement().getConfigurationValue(configKey, String.class).getValue()).isEqualTo(value1);
// update to value second
tenantConfigurationManagement.addOrUpdateConfiguration(configKey, value2);
assertThat(tenantConfigurationManagement.getConfigurationValue(configKey, String.class).getValue()).isEqualTo(value2);
tenantConfigurationManagement().addOrUpdateConfiguration(configKey, value2);
assertThat(tenantConfigurationManagement().getConfigurationValue(configKey, String.class).getValue()).isEqualTo(value2);
}
/**
@@ -114,12 +114,12 @@ class TenantConfigurationManagementTest extends AbstractJpaIntegrationTest imple
}};
// add value first
tenantConfigurationManagement.addOrUpdateConfiguration(configuration);
assertThat(tenantConfigurationManagement.getConfigurationValue(
tenantConfigurationManagement().addOrUpdateConfiguration(configuration);
assertThat(tenantConfigurationManagement().getConfigurationValue(
TenantConfigurationKey.AUTHENTICATION_GATEWAY_SECURITY_TOKEN_KEY, String.class).getValue())
.isEqualTo("token_123");
assertThat(
tenantConfigurationManagement.getConfigurationValue(TenantConfigurationKey.ROLLOUT_APPROVAL_ENABLED, Boolean.class).getValue())
tenantConfigurationManagement().getConfigurationValue(TenantConfigurationKey.ROLLOUT_APPROVAL_ENABLED, Boolean.class).getValue())
.isTrue();
}
@@ -130,11 +130,11 @@ class TenantConfigurationManagementTest extends AbstractJpaIntegrationTest imple
void storeAndUpdateTenantSpecificConfigurationAsBoolean() {
final String configKey = TenantConfigurationKey.AUTHENTICATION_HEADER_ENABLED;
final Boolean value1 = true;
tenantConfigurationManagement.addOrUpdateConfiguration(configKey, value1);
assertThat(tenantConfigurationManagement.getConfigurationValue(configKey, Boolean.class).getValue()).isEqualTo(value1);
tenantConfigurationManagement().addOrUpdateConfiguration(configKey, value1);
assertThat(tenantConfigurationManagement().getConfigurationValue(configKey, Boolean.class).getValue()).isEqualTo(value1);
final Boolean value2 = false;
tenantConfigurationManagement.addOrUpdateConfiguration(configKey, value2);
assertThat(tenantConfigurationManagement.getConfigurationValue(configKey, Boolean.class).getValue()).isEqualTo(value2);
tenantConfigurationManagement().addOrUpdateConfiguration(configKey, value2);
assertThat(tenantConfigurationManagement().getConfigurationValue(configKey, Boolean.class).getValue()).isEqualTo(value2);
}
/**
@@ -146,7 +146,7 @@ class TenantConfigurationManagementTest extends AbstractJpaIntegrationTest imple
final String value1 = "thisIsNotABoolean";
// add value as String
assertThatThrownBy(() -> tenantConfigurationManagement.addOrUpdateConfiguration(configKey, value1))
assertThatThrownBy(() -> tenantConfigurationManagement().addOrUpdateConfiguration(configKey, value1))
.as("Should not have worked as value is not a boolean")
.isInstanceOf(TenantConfigurationValidatorException.class);
}
@@ -163,15 +163,15 @@ class TenantConfigurationManagementTest extends AbstractJpaIntegrationTest imple
}};
try {
tenantConfigurationManagement.addOrUpdateConfiguration(configuration);
tenantConfigurationManagement().addOrUpdateConfiguration(configuration);
fail("should not have worked as type is wrong");
} catch (final TenantConfigurationValidatorException e) {
assertThat(
tenantConfigurationManagement.getConfigurationValue(
tenantConfigurationManagement().getConfigurationValue(
TenantConfigurationKey.AUTHENTICATION_GATEWAY_SECURITY_TOKEN_KEY, String.class).getValue())
.isNotEqualTo("token_123");
assertThat(
tenantConfigurationManagement.getConfigurationValue(
tenantConfigurationManagement().getConfigurationValue(
TenantConfigurationKey.ROLLOUT_APPROVAL_ENABLED, Boolean.class).getValue())
.isNotEqualTo(true);
}
@@ -185,22 +185,22 @@ class TenantConfigurationManagementTest extends AbstractJpaIntegrationTest imple
final String configKey = TenantConfigurationKey.AUTHENTICATION_GATEWAY_SECURITY_TOKEN_KEY;
// gateway token does not have default value so no configuration value should be available
final String defaultConfigValue = tenantConfigurationManagement.getConfigurationValue(configKey, String.class).getValue();
final String defaultConfigValue = tenantConfigurationManagement().getConfigurationValue(configKey, String.class).getValue();
assertThat(defaultConfigValue).isEmpty();
// update the tenant specific configuration
final String newConfigurationValue = "thisIsAnotherValueForPolling";
assertThat(newConfigurationValue).isNotEqualTo(defaultConfigValue);
tenantConfigurationManagement.addOrUpdateConfiguration(configKey, newConfigurationValue);
tenantConfigurationManagement().addOrUpdateConfiguration(configKey, newConfigurationValue);
// verify that new configuration value is used
final String updatedConfigurationValue = tenantConfigurationManagement.getConfigurationValue(configKey, String.class).getValue();
final String updatedConfigurationValue = tenantConfigurationManagement().getConfigurationValue(configKey, String.class).getValue();
assertThat(updatedConfigurationValue).isEqualTo(newConfigurationValue);
// delete the tenant specific configuration
tenantConfigurationManagement.deleteConfiguration(configKey);
tenantConfigurationManagement().deleteConfiguration(configKey);
// ensure that now gateway token is set again, because is deleted and must be empty now
assertThat(tenantConfigurationManagement.getConfigurationValue(configKey, String.class).getValue()).isEmpty();
assertThat(tenantConfigurationManagement().getConfigurationValue(configKey, String.class).getValue()).isEmpty();
}
/**
@@ -210,7 +210,7 @@ class TenantConfigurationManagementTest extends AbstractJpaIntegrationTest imple
void storesIntegerWhenStringIsExpected() {
final String configKey = TenantConfigurationKey.AUTHENTICATION_GATEWAY_SECURITY_TOKEN_KEY;
final Integer wrongDatType = 123;
assertThatThrownBy(() -> tenantConfigurationManagement.addOrUpdateConfiguration(configKey, wrongDatType))
assertThatThrownBy(() -> tenantConfigurationManagement().addOrUpdateConfiguration(configKey, wrongDatType))
.as("Should not have worked as integer is not a string")
.isInstanceOf(TenantConfigurationValidatorException.class);
}
@@ -222,7 +222,7 @@ class TenantConfigurationManagementTest extends AbstractJpaIntegrationTest imple
void storesIntegerWhenBooleanIsExpected() {
final String configKey = TenantConfigurationKey.AUTHENTICATION_GATEWAY_SECURITY_TOKEN_ENABLED;
final Integer wrongDataType = 123;
assertThatThrownBy(() -> tenantConfigurationManagement.addOrUpdateConfiguration(configKey, wrongDataType))
assertThatThrownBy(() -> tenantConfigurationManagement().addOrUpdateConfiguration(configKey, wrongDataType))
.as("Should not have worked as integer is not a boolean")
.isInstanceOf(TenantConfigurationValidatorException.class);
}
@@ -234,7 +234,7 @@ class TenantConfigurationManagementTest extends AbstractJpaIntegrationTest imple
void storesIntegerWhenPollingIntervalIsExpected() {
final String configKey = TenantConfigurationKey.POLLING_TIME;
final Integer wrongDataType = 123;
assertThatThrownBy(() -> tenantConfigurationManagement.addOrUpdateConfiguration(configKey, wrongDataType))
assertThatThrownBy(() -> tenantConfigurationManagement().addOrUpdateConfiguration(configKey, wrongDataType))
.as("Should not have worked as integer is not a time field")
.isInstanceOf(TenantConfigurationValidatorException.class);
}
@@ -246,7 +246,7 @@ class TenantConfigurationManagementTest extends AbstractJpaIntegrationTest imple
void storesWrongFormattedStringAsPollingInterval() {
final String configKey = TenantConfigurationKey.POLLING_TIME;
final String wrongFormatted = "wrongFormatted";
assertThatThrownBy(() -> tenantConfigurationManagement.addOrUpdateConfiguration(configKey, wrongFormatted))
assertThatThrownBy(() -> tenantConfigurationManagement().addOrUpdateConfiguration(configKey, wrongFormatted))
.as("should not have worked as string is not a time field")
.isInstanceOf(TenantConfigurationValidatorException.class);
}
@@ -259,7 +259,7 @@ class TenantConfigurationManagementTest extends AbstractJpaIntegrationTest imple
final String configKey = TenantConfigurationKey.POLLING_TIME;
final String tooSmallDuration = DurationHelper.toString(getDurationByTimeValues(0, 0, 1));
assertThatThrownBy(() -> tenantConfigurationManagement.addOrUpdateConfiguration(configKey, tooSmallDuration))
assertThatThrownBy(() -> tenantConfigurationManagement().addOrUpdateConfiguration(configKey, tooSmallDuration))
.as("Should not have worked as string has an invalid format")
.isInstanceOf(TenantConfigurationValidatorException.class);
}
@@ -274,9 +274,9 @@ class TenantConfigurationManagementTest extends AbstractJpaIntegrationTest imple
final Duration duration = getDurationByTimeValues(1, 2, 0);
assertThat(duration).isEqualTo(Duration.ofHours(1).plusMinutes(2));
tenantConfigurationManagement.addOrUpdateConfiguration(configKey, DurationHelper.toString(duration));
tenantConfigurationManagement().addOrUpdateConfiguration(configKey, DurationHelper.toString(duration));
final String storedDurationString = tenantConfigurationManagement.getConfigurationValue(configKey, String.class).getValue();
final String storedDurationString = tenantConfigurationManagement().getConfigurationValue(configKey, String.class).getValue();
assertThat(duration).isEqualTo(DurationHelper.fromString(storedDurationString));
}
@@ -285,7 +285,7 @@ class TenantConfigurationManagementTest extends AbstractJpaIntegrationTest imple
*/
@Test
void requestConfigValueWithWrongType() {
assertThatThrownBy(() -> tenantConfigurationManagement.getConfigurationValue(
assertThatThrownBy(() -> tenantConfigurationManagement().getConfigurationValue(
TenantConfigurationKey.POLLING_TIME, Serializable.class))
.isInstanceOf(TenantConfigurationValidatorException.class);
}
@@ -314,12 +314,12 @@ class TenantConfigurationManagementTest extends AbstractJpaIntegrationTest imple
}
/**
* Tenant configuration which is not declared throws exception
* AccessContext configuration which is not declared throws exception
*/
@Test
void storeTenantConfigurationWhichIsNotDeclaredThrowsException() {
final String configKeyWhichDoesNotExists = "configKeyWhichDoesNotExists";
assertThatThrownBy(() -> tenantConfigurationManagement.addOrUpdateConfiguration(configKeyWhichDoesNotExists, "value"))
assertThatThrownBy(() -> tenantConfigurationManagement().addOrUpdateConfiguration(configKeyWhichDoesNotExists, "value"))
.as("Expected InvalidTenantConfigurationKeyException for tenant configuration key which is not declared")
.isInstanceOf(InvalidTenantConfigurationKeyException.class);
}
@@ -328,16 +328,16 @@ class TenantConfigurationManagementTest extends AbstractJpaIntegrationTest imple
void storeTenantConfigNumberValue() {
final String configKey = TenantConfigurationKey.ACTION_CLEANUP_AUTO_EXPIRY;
// set auto cleanup for 1 day in Integer ms
tenantConfigurationManagement.addOrUpdateConfiguration(configKey, 86400000);
tenantConfigurationManagement().addOrUpdateConfiguration(configKey, 86400000);
// expect long
Long autoCleanupDaysInMs = tenantConfigurationManagement.getConfigurationValue(configKey, Long.class).getValue();
Long autoCleanupDaysInMs = tenantConfigurationManagement().getConfigurationValue(configKey, Long.class).getValue();
Assertions.assertEquals(86400000, autoCleanupDaysInMs);
tenantConfigurationManagement.addOrUpdateConfiguration(configKey, 86400000);
tenantConfigurationManagement().addOrUpdateConfiguration(configKey, 86400000);
// 30 days 2,592,000,000 ms as Long
tenantConfigurationManagement.addOrUpdateConfiguration(configKey, 2592000000L);
autoCleanupDaysInMs = tenantConfigurationManagement.getConfigurationValue(configKey, Long.class).getValue();
tenantConfigurationManagement().addOrUpdateConfiguration(configKey, 2592000000L);
autoCleanupDaysInMs = tenantConfigurationManagement().getConfigurationValue(configKey, Long.class).getValue();
Assertions.assertEquals(2592000000L, autoCleanupDaysInMs);
}
@@ -346,7 +346,7 @@ class TenantConfigurationManagementTest extends AbstractJpaIntegrationTest imple
final String configKey = TenantConfigurationKey.ACTION_CLEANUP_AUTO_EXPIRY;
// set auto cleanup for 1 day in String ms
assertThatThrownBy(() ->
tenantConfigurationManagement.addOrUpdateConfiguration(configKey, "86400000"))
tenantConfigurationManagement().addOrUpdateConfiguration(configKey, "86400000"))
.as("Cannot convert the value 86400000 of type String to the type Long defined by the configuration key.")
.isInstanceOf(TenantConfigurationValidatorException.class);
}

View File

@@ -64,9 +64,7 @@ class AutoAssignExecutorIntTest extends AbstractJpaIntegrationTest {
*/
@Test
void autoAssignDistributionSetAndAutoCloseOldActions() {
tenantConfigurationManagement
.addOrUpdateConfiguration(TenantConfigurationKey.REPOSITORY_ACTIONS_AUTOCLOSE_ENABLED, true);
tenantConfigurationManagement().addOrUpdateConfiguration(TenantConfigurationKey.REPOSITORY_ACTIONS_AUTOCLOSE_ENABLED, true);
try {
final String knownControllerId = "controller12345";
@@ -100,8 +98,7 @@ class AutoAssignExecutorIntTest extends AbstractJpaIntegrationTest {
assertThat(rolloutCreatedAction.getStatus()).isEqualTo(Status.RUNNING);
assertThat(rolloutCreatedAction.getActionType()).isEqualTo(ActionType.FORCED);
} finally {
tenantConfigurationManagement
.addOrUpdateConfiguration(TenantConfigurationKey.REPOSITORY_ACTIONS_AUTOCLOSE_ENABLED, false);
tenantConfigurationManagement().addOrUpdateConfiguration(TenantConfigurationKey.REPOSITORY_ACTIONS_AUTOCLOSE_ENABLED, false);
}
}

View File

@@ -10,8 +10,6 @@
package org.eclipse.hawkbit.repository.jpa.scheduler;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
@@ -22,7 +20,6 @@ import java.util.List;
import java.util.UUID;
import java.util.concurrent.ThreadLocalRandom;
import org.eclipse.hawkbit.ContextAware;
import org.eclipse.hawkbit.repository.DeploymentManagement;
import org.eclipse.hawkbit.repository.TargetFilterQueryManagement;
import org.eclipse.hawkbit.repository.TargetManagement;
@@ -55,15 +52,13 @@ class AutoAssignExecutorTest {
private DeploymentManagement deploymentManagement;
@Mock
private PlatformTransactionManager transactionManager;
@Mock
private ContextAware contextAware;
private JpaAutoAssignExecutor autoAssignChecker;
@BeforeEach
void before() {
autoAssignChecker = new JpaAutoAssignExecutor(
targetFilterQueryManagement, targetManagement, deploymentManagement, transactionManager, contextAware);
targetFilterQueryManagement, targetManagement, deploymentManagement, transactionManager);
}
/**
@@ -71,7 +66,6 @@ class AutoAssignExecutorTest {
*/
@Test
void checkForDevice() {
mockRunningAsNonSystem();
final String target = getRandomString();
final long ds = getRandomLong();
final TargetFilterQuery matching = mockFilterQuery(ds);
@@ -83,8 +77,7 @@ class AutoAssignExecutorTest {
autoAssignChecker.checkSingleTarget(target);
verify(deploymentManagement).assignDistributionSets(
eq(matching.getAutoAssignInitiatedBy()), Mockito.argThat(deployReqMatcher(target, ds)), any());
verify(deploymentManagement).assignDistributionSets(Mockito.argThat(deployReqMatcher(target, ds)), any());
Mockito.verifyNoMoreInteractions(deploymentManagement);
}
@@ -113,12 +106,4 @@ class AutoAssignExecutorTest {
return requests.size() == 1 && request.getDistributionSetId() == ds && request.getControllerId() == target;
};
}
private void mockRunningAsNonSystem() {
when(contextAware.getCurrentTenant()).thenReturn(getRandomString());
doAnswer(i -> {
((Runnable) i.getArgument(2)).run();
return null;
}).when(contextAware).runAsTenantAsUser(any(String.class), any(String.class), any(Runnable.class));
}
}

View File

@@ -112,7 +112,7 @@ class MultiTenancyEntityTest extends AbstractJpaIntegrationTest {
// logged in tenant mytenant - check if tenant default data is
// autogenerated
assertThat(distributionSetTypeManagement.findAll(PAGE)).isEmpty();
SecurityContextSwitch.callAsPrivileged(() ->
SecurityContextSwitch.asPrivileged(() ->
assertThat(systemManagement.createTenantMetadata("mytenant").getTenant().toUpperCase()).isEqualTo("mytenant".toUpperCase()));
assertThat(distributionSetTypeManagement.findAll(PAGE)).isNotEmpty();