[#2845] Bump Spring boot to 4.x (#2941)

Notes:
1. (!) Eclipselink shall be migrated to 5.0 (in 4.0.8 there are incompatible classes, e.g EJBQueryImpl doesn't implement some newer methods). In the moment is with beta (5.0.0-B12) - JUST for testing!
2. (!) Ethlo plugin doesn't work with Eclipselink 5.0, it builds with Eclipselink 4.0.8 (could be a problem)
3. Dependencies - new starters, test starters changes, some dependencies refactoring
4. Auto-configs split - package changes, some properties classes changes
5. Spring nullable org.springframework.lang.Nullable/NonNull are depecated and replaced with jspcify -> org.jspecify.annotations.Nullable/NonNull (NullMarked)
6. Lombok config - adding lombok.addNullAnnotations=jspecify - to do not mess annotations
7. Distributed lock table changes - SP_LOCK table db migration
8. Spring Retry replaced with Spring Core Retry - does repace retry in hawkbit
9. Specifications -> added Update/Delete(/Predicate) Specifications and JpaSpecificationExecutor changed
10. HawkbitBaseRepositoryFactoryBean modified to register properly
11. Jackson - 2 -> 3, package migrations, finals are not deserialized by default(enable finals deserialization, consider make non-final), too ‘smart’ tries to set complex objects instead of using non args constructor (-> @JsonIgnore), some other default configs made

Signed-off-by: Avgustin Marinov <Avgustin.Marinov@bosch.com>
This commit is contained in:
Avgustin Marinov
2026-04-14 11:31:41 +03:00
committed by GitHub
parent 23cd368e00
commit 1be473b22c
172 changed files with 1254 additions and 1045 deletions

View File

@@ -9,15 +9,17 @@
*/
package org.eclipse.hawkbit.repository.event.remote;
import static org.springframework.messaging.MessageHeaders.CONTENT_TYPE;
import java.util.Map;
import org.eclipse.hawkbit.event.EventJacksonMessageConverter;
import org.eclipse.hawkbit.event.EventProtoStuffMessageConverter;
import org.eclipse.hawkbit.repository.event.TenantAwareEvent;
import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.integration.support.MutableMessageHeaders;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHeaders;
import tools.jackson.databind.json.JsonMapper;
/**
* Test the remote entity events.
@@ -25,33 +27,27 @@ import org.springframework.messaging.MessageHeaders;
@SuppressWarnings("java:S6813") // constructor injects are not possible for test classes
public abstract class AbstractRemoteEventTest extends AbstractJpaIntegrationTest {
private EventProtoStuffMessageConverter eventProtoStuffMessageConverter = new EventProtoStuffMessageConverter();
private EventJacksonMessageConverter jacksonMessageConverter = new EventJacksonMessageConverter();
private final EventProtoStuffMessageConverter eventProtoStuffMessageConverter = new EventProtoStuffMessageConverter();
private EventJacksonMessageConverter jacksonMessageConverter;
@Autowired
void setJsonMapper(final JsonMapper jsonMapper) {
jacksonMessageConverter = new EventJacksonMessageConverter(jsonMapper);
}
@SuppressWarnings("unchecked")
protected <T extends TenantAwareEvent> T createJacksonEvent(final T event) {
final Message<?> message = createJsonMessage(event);
return (T) jacksonMessageConverter.fromMessage(message, event.getClass());
return (T) jacksonMessageConverter.fromMessage(
jacksonMessageConverter.toMessage
(event, new MutableMessageHeaders(Map.of(CONTENT_TYPE, EventJacksonMessageConverter.APPLICATION_REMOTE_EVENT_JSON))),
event.getClass());
}
@SuppressWarnings("unchecked")
protected <T extends TenantAwareEvent> T createProtoStuffEvent(final T event) {
final Message<?> message = createProtoStuffMessage(event);
return (T) eventProtoStuffMessageConverter.fromMessage(message, event.getClass());
return (T) eventProtoStuffMessageConverter.fromMessage(
eventProtoStuffMessageConverter.toMessage(
event, new MutableMessageHeaders(Map.of(CONTENT_TYPE, EventProtoStuffMessageConverter.APPLICATION_BINARY_PROTOSTUFF))),
event.getClass());
}
private Message<?> createProtoStuffMessage(final TenantAwareEvent event) {
return eventProtoStuffMessageConverter.toMessage(
event, new MutableMessageHeaders(Map.of(MessageHeaders.CONTENT_TYPE,
EventProtoStuffMessageConverter.APPLICATION_BINARY_PROTOSTUFF))
);
}
private Message<?> createJsonMessage(final Object event) {
return jacksonMessageConverter.toMessage(event, new MutableMessageHeaders(Map.of(MessageHeaders.CONTENT_TYPE,
EventJacksonMessageConverter.APPLICATION_REMOTE_EVENT_JSON)));
}
}

View File

@@ -58,7 +58,7 @@ import org.eclipse.hawkbit.repository.test.util.AbstractIntegrationTest;
import org.eclipse.hawkbit.repository.test.util.RolloutTestApprovalStrategy;
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
import org.springframework.boot.jpa.autoconfigure.JpaProperties;
import org.springframework.data.domain.Page;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.orm.jpa.vendor.Database;

View File

@@ -109,7 +109,7 @@ class SystemExecutionTest extends AbstractAccessControllerManagementTest {
for (final Operation operation : Operation.values()) {
accessController.appendAccessRules(operation, mock);
}
verify(mock, times(times)).and(any()); // once for every access controller is scoped only
verify(mock, times(times)).and(any(Specification.class)); // once for every access controller is scoped only
final Specification mockAsSystem = mock(Specification.class);
for (final Operation operation : Operation.values()) {

View File

@@ -11,11 +11,12 @@ 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.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
@@ -25,7 +26,6 @@ import java.util.concurrent.Callable;
import jakarta.validation.ConstraintViolationException;
import org.apache.commons.io.IOUtils;
import org.eclipse.hawkbit.artifact.exception.ArtifactBinaryNotFoundException;
import org.eclipse.hawkbit.artifact.exception.FileSizeQuotaExceededException;
import org.eclipse.hawkbit.artifact.exception.StorageQuotaExceededException;
@@ -81,12 +81,12 @@ class ArtifactManagementTest extends AbstractJpaIntegrationTest {
final int artifactSize = artifactData.length();
verifyThrownExceptionBy(
() -> artifactManagement.create(new ArtifactUpload(
IOUtils.toInputStream(artifactData, "UTF-8"),
new ByteArrayInputStream(artifactData.getBytes(StandardCharsets.UTF_8)),
null, artifactSize, null, NOT_EXIST_IDL, "xxx", false)), "SoftwareModule");
verifyThrownExceptionBy(
() -> artifactManagement.create(new ArtifactUpload(
IOUtils.toInputStream(artifactData, "UTF-8"),
new ByteArrayInputStream(artifactData.getBytes(StandardCharsets.UTF_8)),
null, artifactSize, null, NOT_EXIST_IDL, "xxx", false)), "SoftwareModule");
verifyThrownExceptionBy(() -> artifactManagement.delete(NOT_EXIST_IDL), "Artifact");
@@ -143,7 +143,8 @@ class ArtifactManagementTest extends AbstractJpaIntegrationTest {
final long smID = softwareModuleRepository.save(new JpaSoftwareModule(osType, "smIllegalFilenameTest", "1.0")).getId();
final ArtifactUpload artifactUpload = new ArtifactUpload(
IOUtils.toInputStream(artifactData, "UTF-8"), null, artifactSize, null, smID, illegalFilename, false);
new ByteArrayInputStream(artifactData.getBytes(StandardCharsets.UTF_8)), null, artifactSize, null, smID, illegalFilename,
false);
assertThatExceptionOfType(ConstraintViolationException.class).isThrownBy(() -> artifactManagement.create(artifactUpload));
assertThat(softwareModuleManagement.get(smID).getArtifacts()).isEmpty();
}
@@ -542,9 +543,7 @@ class ArtifactManagementTest extends AbstractJpaIntegrationTest {
private void assertEqualFileContents(final ArtifactStream artifact, final byte[] randomBytes) {
try (final InputStream inputStream = artifact) {
assertTrue(
IOUtils.contentEquals(new ByteArrayInputStream(randomBytes), inputStream),
"The stored binary matches the given binary");
assertArrayEquals(inputStream.readAllBytes(), randomBytes);
} catch (final IOException e) {
throw new AssertionError(e);
}

View File

@@ -14,7 +14,6 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.assertThatNoException;
import static org.eclipse.hawkbit.auth.SpRole.CONTROLLER_ROLE;
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;
import static org.eclipse.hawkbit.repository.test.util.TestdataFactory.DEFAULT_CONTROLLER_ID;
@@ -37,6 +36,7 @@ import jakarta.validation.ConstraintViolationException;
import org.assertj.core.api.Assertions;
import org.eclipse.hawkbit.auth.SpPermission;
import org.eclipse.hawkbit.ql.jpa.SpecificationBuilder;
import org.eclipse.hawkbit.repository.RepositoryProperties;
import org.eclipse.hawkbit.repository.TargetTypeManagement;
import org.eclipse.hawkbit.repository.UpdateMode;
@@ -85,6 +85,7 @@ import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.ConcurrencyFailureException;
import org.springframework.data.jpa.domain.Specification;
/**
* Feature: Component Tests - Repository<br/>
@@ -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(java.lang.System.currentTimeMillis()).messages(List.of("proceeding message 1"))
.status(Action.Status.RUNNING).timestamp(System.currentTimeMillis()).messages(List.of("proceeding message 1"))
.build());
waitNextMillis();
controllerManagement.addUpdateActionStatus(ActionStatusCreate.builder().actionId(actionId)
.status(Action.Status.RUNNING).timestamp(java.lang.System.currentTimeMillis()).messages(List.of("proceeding message 2"))
.status(Action.Status.RUNNING).timestamp(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(java.lang.System.currentTimeMillis()).build());
controllerManagement.addInformationalActionStatus(status.messages(List.of("Msg " + i)).timestamp(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(java.lang.System.currentTimeMillis()).build());
controllerManagement.addUpdateActionStatus(statusWarning.messages(List.of("Msg " + i)).timestamp(System.currentTimeMillis()).build());
}
final ActionStatusCreate actionStatusCreateQE = statusWarning.build();
assertThatExceptionOfType(AssignmentQuotaExceededException.class)
@@ -858,7 +859,7 @@ class ControllerManagementTest extends AbstractJpaIntegrationTest {
@Test
void findOrRegisterTargetIfItDoesNotExistThrowsExceptionAfterMaxRetries() {
final TargetRepository mockTargetRepository = Mockito.mock(TargetRepository.class);
when(mockTargetRepository.findOne(any())).thenThrow(ConcurrencyFailureException.class);
when(mockTargetRepository.findOne(any(Specification.class))).thenThrow(ConcurrencyFailureException.class);
((JpaControllerManagement) controllerManagement).setTargetRepository(mockTargetRepository);
try {
@@ -866,7 +867,7 @@ class ControllerManagementTest extends AbstractJpaIntegrationTest {
.as("Expected an ConcurrencyFailureException to be thrown!")
.isThrownBy(() -> controllerManagement.findOrRegisterTargetIfItDoesNotExist("AA", LOCALHOST));
verify(mockTargetRepository, times(TX_RT_MAX)).findOne(any());
verify(mockTargetRepository, times(10 /* default retry max */+ 1)).findOne(any(Specification.class));
} finally {
// revert
((JpaControllerManagement) controllerManagement).setTargetRepository(targetRepository);
@@ -887,14 +888,14 @@ class ControllerManagementTest extends AbstractJpaIntegrationTest {
((JpaControllerManagement) controllerManagement).setTargetRepository(mockTargetRepository);
final Target target = testdataFactory.createTarget();
when(mockTargetRepository.findOne(any())).thenThrow(ConcurrencyFailureException.class)
when(mockTargetRepository.findOne(any(Specification.class))).thenThrow(ConcurrencyFailureException.class)
.thenThrow(ConcurrencyFailureException.class).thenReturn(Optional.of((JpaTarget) target));
when(mockTargetRepository.save(any())).thenReturn(target);
try {
final Target targetFromControllerManagement = controllerManagement
.findOrRegisterTargetIfItDoesNotExist(target.getControllerId(), LOCALHOST);
verify(mockTargetRepository, times(3)).findOne(any());
verify(mockTargetRepository, times(3)).findOne(any(Specification.class));
verify(mockTargetRepository, times(1)).save(any());
assertThat(target).isEqualTo(targetFromControllerManagement);
} finally {
@@ -937,14 +938,14 @@ class ControllerManagementTest extends AbstractJpaIntegrationTest {
final TargetRepository mockTargetRepository = Mockito.mock(TargetRepository.class);
((JpaControllerManagement) controllerManagement).setTargetRepository(mockTargetRepository);
when(mockTargetRepository.findOne(any())).thenReturn(Optional.empty());
when(mockTargetRepository.findOne(any(Specification.class))).thenReturn(Optional.empty());
when(mockTargetRepository.save(any())).thenThrow(EntityAlreadyExistsException.class);
try {
assertThatExceptionOfType(EntityAlreadyExistsException.class)
.as("Expected an EntityAlreadyExistsException to be thrown!")
.isThrownBy(() -> controllerManagement.findOrRegisterTargetIfItDoesNotExist("1234", LOCALHOST));
verify(mockTargetRepository, times(1)).findOne(any());
verify(mockTargetRepository, times(1)).findOne(any(Specification.class));
verify(mockTargetRepository, times(1)).save(any());
} finally {
// revert
@@ -962,13 +963,13 @@ class ControllerManagementTest extends AbstractJpaIntegrationTest {
final TargetRepository mockTargetRepository = Mockito.mock(TargetRepository.class);
((JpaControllerManagement) controllerManagement).setTargetRepository(mockTargetRepository);
when(mockTargetRepository.findOne(any())).thenThrow(RuntimeException.class);
when(mockTargetRepository.findOne(any(Specification.class))).thenThrow(RuntimeException.class);
try {
assertThatExceptionOfType(RuntimeException.class).as("Expected a RuntimeException to be thrown!")
.isThrownBy(() -> controllerManagement.findOrRegisterTargetIfItDoesNotExist("aControllerId",
LOCALHOST));
verify(mockTargetRepository, times(1)).findOne(any());
verify(mockTargetRepository, times(1)).findOne(any(Specification.class));
} finally {
// revert
((JpaControllerManagement) controllerManagement).setTargetRepository(targetRepository);

View File

@@ -211,7 +211,6 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest {
*/
@Test
void assertMaxActionsPerTargetQuotaIsEnforced() {
final int maxActions = quotaManagement.getMaxActionsPerTarget();
final Target testTarget = testdataFactory.createTarget();
final List<Long> dsIds = new ArrayList<>();

View File

@@ -25,7 +25,6 @@ import java.util.stream.Stream;
import jakarta.validation.ConstraintViolationException;
import jakarta.validation.ValidationException;
import lombok.extern.slf4j.Slf4j;
import org.assertj.core.api.Assertions;
import org.assertj.core.api.Condition;
import org.eclipse.hawkbit.auth.SpPermission;
@@ -118,7 +117,8 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
testdataFactory.createTargets(targetPrefix, 0, amountGroups * 2);
final Rollout dynamicRollout = testdataFactory.createRolloutByVariables("dynamic", "static rollout", amountGroups,
"controllerid==" + targetPrefix + "*", distributionSet, "0", RolloutGroup.RolloutGroupSuccessAction.NEXTGROUP, "30", ActionType.FORCED, 1000, false, true);
"controllerid==" + targetPrefix + "*", distributionSet, "0", RolloutGroup.RolloutGroupSuccessAction.NEXTGROUP, "30",
ActionType.FORCED, 1000, false, true);
rolloutManagement.start(dynamicRollout.getId());
rolloutHandler.handleAll();
assertRollout(dynamicRollout, true, RolloutStatus.RUNNING, amountGroups + 1, amountGroups * 2);
@@ -153,7 +153,8 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
testdataFactory.createTargets(targetPrefix, amountGroups * 2, amountGroups);
final Rollout staticRollout = testdataFactory.createRolloutByVariables("static", "static rollout", amountGroups,
"controllerid==" + targetPrefix + "*", distributionSet, "0", RolloutGroup.RolloutGroupSuccessAction.NEXTGROUP,"30", ActionType.FORCED, 0, false, false);
"controllerid==" + targetPrefix + "*", distributionSet, "0", RolloutGroup.RolloutGroupSuccessAction.NEXTGROUP, "30",
ActionType.FORCED, 0, false, false);
rolloutManagement.start(staticRollout.getId());
rolloutHandler.handleAll();
assertRollout(staticRollout, false, RolloutStatus.RUNNING, amountGroups, amountGroups * 3);

View File

@@ -217,7 +217,7 @@ class TargetManagementTest extends AbstractRepositoryManagementWithMetadataTest<
createTargetWithAttributes("4711");
final long current = java.lang.System.currentTimeMillis();
final long current = System.currentTimeMillis();
controllerManagement.findOrRegisterTargetIfItDoesNotExist("4711", LOCALHOST);
final DistributionSetAssignmentResult result = assignDistributionSet(testDs1.getId(), "4711");

View File

@@ -34,6 +34,7 @@ import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
import org.eclipse.hawkbit.repository.model.TargetType;
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey;
import org.jspecify.annotations.NonNull;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
@@ -185,23 +186,20 @@ class AutoAssignHandlerIntTest extends AbstractJpaIntegrationTest {
*/
@ParameterizedTest
@MethodSource("confirmationOptions")
void checkAutoAssignWithConfirmationOptions(final boolean confirmationFlowActive, final boolean confirmationRequired,
final Action.Status expectedStatus) {
final DistributionSet distributionSet = testdataFactory.createDistributionSet("dsA");
void checkAutoAssignWithConfirmationOptions(
final boolean confirmationFlowActive, final boolean confirmationRequired, final Action.Status expectedStatus) {
if (confirmationFlowActive) {
enableConfirmationFlow();
}
final DistributionSet distributionSet = testdataFactory.createDistributionSet("dsA");
targetFilterQueryManagement.updateAutoAssignDS(
new AutoAssignDistributionSetUpdate(targetFilterQueryManagement
.create(Create.builder().name("filterA").query("name==*").build()).getId())
.ds(distributionSet.getId()).confirmationRequired(confirmationRequired));
final String targetDsAIdPref = "targ";
final List<Target> targets = testdataFactory.createTargets(20, targetDsAIdPref,
targetDsAIdPref.concat(SPACE_AND_DESCRIPTION));
final List<Target> targets = testdataFactory.createTargets(20, targetDsAIdPref, targetDsAIdPref.concat(SPACE_AND_DESCRIPTION));
// Run the check
autoAssignChecker.handleAll();
@@ -214,15 +212,13 @@ class AutoAssignHandlerIntTest extends AbstractJpaIntegrationTest {
*/
@ParameterizedTest
@MethodSource("confirmationOptions")
void checkAutoAssignmentForDeviceWithConfirmationRequired(final boolean confirmationFlowActive,
final boolean confirmationRequired, final Action.Status expectedStatus) {
final DistributionSet toAssignDs = testdataFactory.createDistributionSet();
void checkAutoAssignmentForDeviceWithConfirmationRequired(
final boolean confirmationFlowActive, final boolean confirmationRequired, final Action.Status expectedStatus) {
if (confirmationFlowActive) {
enableConfirmationFlow();
}
final DistributionSet toAssignDs = testdataFactory.createDistributionSet();
// target filter query that matches all targets
targetFilterQueryManagement.updateAutoAssignDS(
new AutoAssignDistributionSetUpdate(targetFilterQueryManagement
@@ -243,7 +239,6 @@ class AutoAssignHandlerIntTest extends AbstractJpaIntegrationTest {
*/
@Test
void checkAutoAssignWithFailures() {
// incomplete distribution set that will be assigned
final DistributionSet setF = distributionSetManagement.create(DistributionSetManagement.Create.builder()
.type(testdataFactory.findOrCreateDefaultTestDsType())
@@ -255,23 +250,21 @@ class AutoAssignHandlerIntTest extends AbstractJpaIntegrationTest {
final String targetDsAIdPref = "targA";
final String targetDsFIdPref = "targB";
final Long filterId = targetFilterQueryManagement.create(
Create.builder().name("filterA").query("id==" + targetDsFIdPref + "*").build())
.getId();
final Long filterId = targetFilterQueryManagement
.create(Create.builder().name("filterA").query("id==" + targetDsFIdPref + "*").build()).getId();
final AutoAssignDistributionSetUpdate targetFilterQuery = new AutoAssignDistributionSetUpdate(filterId).ds(setF.getId());
// target filter query that matches first bunch of targets, that should fail
assertThatExceptionOfType(IncompleteDistributionSetException.class).isThrownBy(
() -> targetFilterQueryManagement.updateAutoAssignDS(targetFilterQuery));
assertThatExceptionOfType(IncompleteDistributionSetException.class)
.isThrownBy(() -> targetFilterQueryManagement.updateAutoAssignDS(targetFilterQuery));
// target filter query that matches failed bunch of targets
targetFilterQueryManagement.create(Create.builder().name("filterB")
.query("id==" + targetDsAIdPref + "*").autoAssignDistributionSet(setA).build());
targetFilterQueryManagement.create(Create.builder()
.name("filterB").query("id==" + targetDsAIdPref + "*").autoAssignDistributionSet(setA)
.build());
implicitLock(setA);
final List<Target> targetsF = testdataFactory.createTargets(10, targetDsFIdPref,
targetDsFIdPref.concat(SPACE_AND_DESCRIPTION));
final List<Target> targetsF = testdataFactory.createTargets(10, targetDsFIdPref, targetDsFIdPref.concat(SPACE_AND_DESCRIPTION));
final List<Target> targetsA = testdataFactory.createTargets(10, targetDsAIdPref,
targetDsAIdPref.concat(SPACE_AND_DESCRIPTION));
final List<Target> targetsA = testdataFactory.createTargets(10, targetDsAIdPref, targetDsAIdPref.concat(SPACE_AND_DESCRIPTION));
final int targetsCount = targetsA.size() + targetsF.size();
@@ -288,7 +281,6 @@ class AutoAssignHandlerIntTest extends AbstractJpaIntegrationTest {
// all targets of A group should have received setA
verifyThatTargetsHaveDistributionSetAssignment(setA, targetsA, targetsCount);
}
/**
@@ -448,16 +440,13 @@ class AutoAssignHandlerIntTest extends AbstractJpaIntegrationTest {
.isEqualTo(targetFilterQuery.getAutoAssignInitiatedBy()));
}
private List<Target> createTargetsAndAutoAssignDistSet(final String prefix, final int targetCount,
final DistributionSet distributionSet, final ActionType actionType) {
final List<Target> targets = testdataFactory.createTargets(targetCount, "target" + prefix,
prefix.concat(SPACE_AND_DESCRIPTION));
private List<Target> createTargetsAndAutoAssignDistSet(
final String prefix, final int targetCount, final DistributionSet distributionSet, final ActionType actionType) {
final List<Target> targets = testdataFactory.createTargets(targetCount, "target" + prefix, prefix.concat(SPACE_AND_DESCRIPTION));
targetFilterQueryManagement.create(Create.builder()
.name("filter" + prefix).query("id==target" + prefix + "*")
.autoAssignDistributionSet(distributionSet).autoAssignActionType(actionType)
.build());
return targets;
}
@@ -466,12 +455,12 @@ class AutoAssignHandlerIntTest extends AbstractJpaIntegrationTest {
.map(Target::getControllerId)
.flatMap(controllerId -> deploymentManagement.findActionsByTarget(controllerId, PAGE).getContent().stream())
.toList();
assertThat(actions).hasSize(targets.size());
assertThat(actions).allMatch(action -> action.getActionType().equals(actionType));
}
private Slice<Action> findActionsByDistributionSet(final Pageable pageable, final long distributionSetId) {
private Slice<@NonNull Action> findActionsByDistributionSet(final Pageable pageable, final long distributionSetId) {
return actionRepository
.findAll(byDistributionSetId(distributionSetId), pageable)
.map(Action.class::cast);

View File

@@ -58,8 +58,8 @@ logging.level.org.eclipse.persistence=${NOISE_SUPPRESS_LEVEL}
## enable / disable case sensitiveness of the DB when playing around
#hawkbit.ql.case-insensitive-db=true
hawkbit.repository.cluster.lock.ttl=3000
hawkbit.repository.cluster.lock.refreshOnRemainMS=2000
hawkbit.repository.cluster.lock.ttl=1000
hawkbit.repository.cluster.lock.refreshOnRemainMS=200
hawkbit.repository.cluster.lock.refreshOnRemainPercent=10
## reduce scheduler tic period to speed up tests
hawkbit.repository.cluster.lock.ticPeriodMS=10