Sonar Fixes (#2234)

Signed-off-by: Avgustin Marinov <Avgustin.Marinov@bosch.com>
This commit is contained in:
Avgustin Marinov
2025-01-24 17:22:34 +02:00
committed by GitHub
parent a61e9cd6ae
commit ef4c0c6d18
21 changed files with 213 additions and 285 deletions

View File

@@ -12,7 +12,6 @@ package org.eclipse.hawkbit.mgmt.rest.resource.util;
import java.io.IOException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.eclipse.hawkbit.mgmt.json.model.PagedList;
import org.eclipse.hawkbit.mgmt.json.model.artifact.MgmtArtifact;
import org.eclipse.hawkbit.rest.json.model.ExceptionInfo;
@@ -30,8 +29,4 @@ public final class ResourceUtility {
public static MgmtArtifact convertArtifactResponse(final String jsonResponse) throws IOException {
return OBJECT_MAPPER.readValue(jsonResponse, MgmtArtifact.class);
}
public static <T> PagedList<T> mapResponse(final Class<T> clazz, final String responseBody) throws IOException {
return OBJECT_MAPPER.readValue(responseBody, PagedList.class);
}
}

View File

@@ -45,7 +45,7 @@ public class RemoteTenantAwareEvent extends RemoteApplicationEvent implements Te
*/
public RemoteTenantAwareEvent(final Object source, final String tenant, final String applicationId) {
// due to a bug in Spring Cloud, we cannot pass null for applicationId
super(source, applicationId != null ? applicationId : StringUtils.EMPTY);
super(source, applicationId != null ? applicationId : StringUtils.EMPTY, DEFAULT_DESTINATION_FACTORY.getDestination(null));
this.tenant = tenant;
}
}

View File

@@ -14,6 +14,7 @@ import java.util.Optional;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.AccessLevel;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.hawkbit.repository.event.remote.EventEntityManagerHolder;
@@ -26,6 +27,7 @@ import org.eclipse.hawkbit.repository.model.TenantAwareBaseEntity;
* @param <E> the type of the entity
*/
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@EqualsAndHashCode(callSuper = true)
@Slf4j
public class RemoteEntityEvent<E extends TenantAwareBaseEntity> extends RemoteIdEvent {

View File

@@ -40,9 +40,14 @@ public final class RsqlConfigHolder {
*/
@Value("${hawkbit.rsql.caseInsensitiveDB:false}")
private boolean caseInsensitiveDB;
@Autowired
private RsqlVisitorFactory rsqlVisitorFactory;
@Autowired
public void setRsqlVisitorFactory(final RsqlVisitorFactory rsqlVisitorFactory) {
this.rsqlVisitorFactory = rsqlVisitorFactory;
}
/**
* @deprecated in favour of G2 RSQL visitor. since 0.6.0
*/

View File

@@ -19,7 +19,7 @@ import org.junit.jupiter.api.Test;
@Feature("Unit Tests - Repository")
@Story("Regular expression helper")
public class RegexCharTest {
class RegexCharTest {
private static final int INDEX_FIRST_PRINTABLE_ASCII_CHAR = 32;
private static final int INDEX_LAST_PRINTABLE_ASCII_CHAR = 127;
@@ -27,7 +27,7 @@ public class RegexCharTest {
@Test
@Description("Verifies every RegexChar can be used to exclusively find the desired characters in a String.")
public void allRegexCharsOnlyFindExpectedChars() {
void allRegexCharsOnlyFindExpectedChars() {
for (final RegexChar character : RegexChar.values()) {
switch (character) {
case DIGITS:
@@ -51,7 +51,7 @@ public class RegexCharTest {
@Test
@Description("Verifies that combinations of RegexChars can be used to find the desired characters in a String.")
public void combinedRegexCharsFindExpectedChars() {
void combinedRegexCharsFindExpectedChars() {
final RegexCharacterCollection greaterAndLessThan = new RegexCharacterCollection(RegexChar.GREATER_THAN,
RegexChar.LESS_THAN);
final RegexCharacterCollection equalsAndQuestionMark = new RegexCharacterCollection(RegexChar.EQUALS_SYMBOL,

View File

@@ -28,14 +28,14 @@ import org.springframework.security.access.prepost.PreAuthorize;
@Feature("Unit Tests - Repository")
@Story("Security Test")
public class RepositoryManagementMethodPreAuthorizeAnnotatedTest {
class RepositoryManagementMethodPreAuthorizeAnnotatedTest {
// if some methods are to be excluded
private static final Set<Method> METHOD_SECURITY_EXCLUSION = new HashSet<>();
@Test
@Description("Verifies that repository methods are @PreAuthorize annotated")
public void repositoryManagementMethodsArePreAuthorizedAnnotated() {
void repositoryManagementMethodsArePreAuthorizedAnnotated() {
final String packageName = getClass().getPackage().getName();
try (final ScanResult scanResult = new ClassGraph().acceptPackages(packageName).scan()) {
final List<? extends Class<?>> matchingClasses = scanResult.getAllClasses()
@@ -59,7 +59,7 @@ public class RepositoryManagementMethodPreAuthorizeAnnotatedTest {
* checked. The following methods are excluded due inherited from
* {@link Object}, like equals() or toString().
*
* @param clazz the class to retrieve the public declared methods
* @param clazz the class to retrieve the declared methods
*/
private static void assertDeclaredMethodsContainsPreAuthorizeAnnotations(final Class<?> clazz) {
final Method[] declaredMethods = clazz.getDeclaredMethods();
@@ -72,7 +72,7 @@ public class RepositoryManagementMethodPreAuthorizeAnnotatedTest {
}
final PreAuthorize annotation = method.getAnnotation(PreAuthorize.class);
assertThat(annotation)
.as("The public method " + method.getName() + " in class " + clazz.getName() +
.as("The method " + method.getName() + " in class " + clazz.getName() +
" is not annotated with @PreAuthorize, security leak?")
.isNotNull();
}

View File

@@ -23,7 +23,7 @@ import org.eclipse.hawkbit.repository.exception.RolloutIllegalStateException;
import org.eclipse.hawkbit.repository.model.Rollout;
import org.eclipse.hawkbit.repository.model.RolloutGroup;
import org.eclipse.hawkbit.repository.model.RolloutGroupConditions;
import org.springframework.util.StringUtils;
import org.springframework.util.ObjectUtils;
/**
* A collection of static helper methods for the {@link RolloutManagement}
@@ -135,10 +135,10 @@ public final class RolloutHelper {
* @param group the group to add
* @return list of groups
*/
public static List<Long> getGroupsByStatusIncludingGroup(final List<RolloutGroup> groups,
final RolloutGroup.RolloutGroupStatus status, final RolloutGroup group) {
public static List<Long> getGroupsByStatusIncludingGroup(
final List<RolloutGroup> groups, final RolloutGroup.RolloutGroupStatus status, final RolloutGroup group) {
return groups.stream().filter(innerGroup -> innerGroup.getStatus() == status || innerGroup.equals(group))
.map(RolloutGroup::getId).collect(Collectors.toList());
.map(RolloutGroup::getId).toList();
}
/**
@@ -149,7 +149,7 @@ public final class RolloutHelper {
* @return RSQL string without base filter of the Rollout. Can be an empty string.
*/
public static String getAllGroupsTargetFilter(final List<RolloutGroup> groups) {
if (groups.stream().anyMatch(group -> StringUtils.isEmpty(group.getTargetFilterQuery()))) {
if (groups.stream().anyMatch(group -> ObjectUtils.isEmpty(group.getTargetFilterQuery()))) {
return "";
}
@@ -175,13 +175,13 @@ public final class RolloutHelper {
return concatAndTargetFilters(baseFilter, groupFilter);
}
final String previousGroupFilters = getAllGroupsTargetFilter(groups);
if (!StringUtils.isEmpty(previousGroupFilters)) {
if (!StringUtils.isEmpty(groupFilter)) {
if (!ObjectUtils.isEmpty(previousGroupFilters)) {
if (!ObjectUtils.isEmpty(groupFilter)) {
return concatAndTargetFilters(baseFilter, groupFilter, previousGroupFilters);
}
return concatAndTargetFilters(baseFilter, previousGroupFilters);
}
if (!StringUtils.isEmpty(groupFilter)) {
if (!ObjectUtils.isEmpty(groupFilter)) {
return concatAndTargetFilters(baseFilter, groupFilter);
}
return baseFilter;
@@ -193,7 +193,7 @@ public final class RolloutHelper {
* @return the final target filter query for a rollout group
*/
public static String getGroupTargetFilter(final String baseFilter, final RolloutGroup group) {
if (StringUtils.isEmpty(group.getTargetFilterQuery())) {
if (ObjectUtils.isEmpty(group.getTargetFilterQuery())) {
return baseFilter;
}
return concatAndTargetFilters(baseFilter, group.getTargetFilterQuery());
@@ -246,8 +246,8 @@ public final class RolloutHelper {
}
private static boolean isTargetFilterInGroups(final String groupFilter, final List<RolloutGroup> groups) {
return !StringUtils.isEmpty(groupFilter)
&& groups.stream().anyMatch(prevGroup -> !StringUtils.isEmpty(prevGroup.getTargetFilterQuery())
return !ObjectUtils.isEmpty(groupFilter)
&& groups.stream().anyMatch(prevGroup -> !ObjectUtils.isEmpty(prevGroup.getTargetFilterQuery())
&& prevGroup.getTargetFilterQuery().equals(groupFilter));
}

View File

@@ -203,7 +203,7 @@ public class RolloutStatusCache {
return ids.stream()
.map(id -> cache.get(id, CachedTotalTargetCountActionStatus.class))
.filter(Objects::nonNull)
.collect(Collectors.toMap(CachedTotalTargetCountActionStatus::getId, CachedTotalTargetCountActionStatus::getStatus));
.collect(Collectors.toMap(CachedTotalTargetCountActionStatus::id, CachedTotalTargetCountActionStatus::status));
}
private List<TotalTargetCountActionStatus> retrieveFromCache(final Long id, @NotNull final Cache cache) {
@@ -213,7 +213,7 @@ public class RolloutStatusCache {
return Collections.emptyList();
}
return cacheItem.getStatus();
return cacheItem.status();
}
private void putIntoCache(final Long id, final List<TotalTargetCountActionStatus> status,
@@ -233,22 +233,5 @@ public class RolloutStatusCache {
return Objects.requireNonNull(cacheManager.getCache(CACHE_GR_NAME), "Cache '" + CACHE_RO_NAME + "' is null!");
}
private static final class CachedTotalTargetCountActionStatus {
private final long id;
private final List<TotalTargetCountActionStatus> status;
private CachedTotalTargetCountActionStatus(final long id, final List<TotalTargetCountActionStatus> status) {
this.id = id;
this.status = status;
}
public long getId() {
return id;
}
public List<TotalTargetCountActionStatus> getStatus() {
return status;
}
}
private record CachedTotalTargetCountActionStatus(long id, List<TotalTargetCountActionStatus> status) {}
}

View File

@@ -52,6 +52,7 @@ import org.springframework.util.CollectionUtils;
@Slf4j
public class RsqlParserValidationOracle implements RsqlValidationOracle {
@SuppressWarnings("java:S1872") // intentionally don't use class but name - class could be unavailable
@Override
public ValidationOracleContext suggest(final String rsqlQuery, final int cursorPosition) {
final List<SuggestToken> expectedTokens = new ArrayList<>();
@@ -149,7 +150,7 @@ public class RsqlParserValidationOracle implements RsqlValidationOracle {
final int currentQueryLength = rsqlQuery.length() - 1;
final Collection<String> tokenImages = TokenDescription.getTokenImage(TokenDescription.COMPARATOR);
return tokenImages.stream().map(tokenImage -> new SuggestToken(currentQueryLength,
currentQueryLength + tokenImage.length(), null, tokenImage)).collect(Collectors.toList());
currentQueryLength + tokenImage.length(), null, tokenImage)).toList();
}
return Collections.emptyList();
@@ -213,8 +214,8 @@ public class RsqlParserValidationOracle implements RsqlValidationOracle {
}
private static ParseException findParseException(final Throwable e) {
if (e instanceof ParseException) {
return (ParseException) e;
if (e instanceof ParseException parseException) {
return parseException;
} else if (e.getCause() != null) {
return findParseException(e.getCause());
}
@@ -306,15 +307,15 @@ public class RsqlParserValidationOracle implements RsqlValidationOracle {
final String tokenImageName) {
return FIELD_NAMES.stream()
.map(field -> new SuggestToken(beginToken, endToken, tokenImageName, field.toLowerCase()))
.collect(Collectors.toList());
.toList();
}
private static List<SuggestToken> toSubSuggestToken(final int beginToken, final int endToken,
final String topToken, final String tokenImageName) {
return Arrays.stream(TargetFields.values()).filter(field -> field.toString().equalsIgnoreCase(topToken))
.map(TargetFields::getSubEntityAttributes).flatMap(List::stream)
.map(subentity -> new SuggestToken(beginToken, endToken, tokenImageName, subentity))
.collect(Collectors.toList());
.map(subEntity -> new SuggestToken(beginToken, endToken, tokenImageName, subEntity))
.toList();
}
private static boolean containsValue(final String imageName) {

View File

@@ -11,6 +11,9 @@ package org.eclipse.hawkbit.repository.jpa.specifications;
import jakarta.persistence.criteria.Predicate;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.eclipse.hawkbit.repository.jpa.model.AbstractJpaNamedEntity_;
import org.eclipse.hawkbit.repository.jpa.model.JpaRollout;
import org.eclipse.hawkbit.repository.jpa.model.JpaRollout_;
import org.eclipse.hawkbit.repository.model.Rollout;
@@ -19,15 +22,11 @@ import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.query.QueryUtils;
/**
* Specifications class for {@link Rollout}s. The class provides Spring Data
* JPQL Specifications.
* Specifications class for {@link Rollout}s. The class provides Spring Data JPQL Specifications.
*/
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class RolloutSpecification {
private RolloutSpecification() {
// utility class
}
/**
* {@link Specification} for retrieving {@link Rollout}s by its <code>deleted</code> attribute.
*
@@ -54,7 +53,7 @@ public final class RolloutSpecification {
return (rolloutRoot, query, criteriaBuilder) -> {
final String searchTextToLower = searchText.toLowerCase();
return criteriaBuilder.and(
criteriaBuilder.like(criteriaBuilder.lower(rolloutRoot.get(JpaRollout_.name)), searchTextToLower),
criteriaBuilder.like(criteriaBuilder.lower(rolloutRoot.get(AbstractJpaNamedEntity_.name)), searchTextToLower),
criteriaBuilder.equal(rolloutRoot.get(JpaRollout_.deleted), isDeleted));
};
}

View File

@@ -27,35 +27,30 @@ import org.junit.jupiter.api.Test;
*/
@Feature("Component Tests - Repository")
@Story("Entity Id Events")
public class RemoteIdEventTest extends AbstractRemoteEventTest {
class RemoteIdEventTest extends AbstractRemoteEventTest {
private static final long ENTITY_ID = 1L;
private static String TENANT = "tenant";
private static Class<? extends TenantAwareBaseEntity> ENTITY_CLASS = JpaAction.class;
private static String NODE = "Node";
private static String CONTROLLER_ID = "controller911";
private static String ADDRESS = "amqp://anyhost";
private static final String TENANT = "tenant";
private static final Class<? extends TenantAwareBaseEntity> ENTITY_CLASS = JpaAction.class;
private static final String NODE = "Node";
private static final String CONTROLLER_ID = "controller911";
private static final String ADDRESS = "amqp://anyhost";
@Test
@Description("Verifies that the ds id is correct reloaded")
public void testDistributionSetDeletedEvent() {
void testDistributionSetDeletedEvent() {
assertAndCreateRemoteEvent(DistributionSetDeletedEvent.class);
}
@Test
@Description("Verifies that the ds tag id is correct reloaded")
public void testDistributionSetTagDeletedEvent() {
void testDistributionSetTagDeletedEvent() {
assertAndCreateRemoteEvent(DistributionSetTagDeletedEvent.class);
}
@Test
@Description("Verifies that the target id is correct reloaded")
public void testTargetDeletedEvent() {
void testTargetDeletedEvent() {
final TargetDeletedEvent deletedEvent = new TargetDeletedEvent(TENANT, ENTITY_ID, CONTROLLER_ID, ADDRESS,
ENTITY_CLASS, NODE);
assertEntity(deletedEvent);
@@ -63,19 +58,19 @@ public class RemoteIdEventTest extends AbstractRemoteEventTest {
@Test
@Description("Verifies that the target tag id is correct reloaded")
public void testTargetTagDeletedEvent() {
void testTargetTagDeletedEvent() {
assertAndCreateRemoteEvent(TargetTagDeletedEvent.class);
}
@Test
@Description("Verifies that the software module id is correct reloaded")
public void testSoftwareModuleDeletedEvent() {
void testSoftwareModuleDeletedEvent() {
assertAndCreateRemoteEvent(SoftwareModuleDeletedEvent.class);
}
@Test
@Description("Verifies that the rollout id is correct reloaded")
public void testRolloutDeletedEvent() {
void testRolloutDeletedEvent() {
assertAndCreateRemoteEvent(RolloutDeletedEvent.class);
}
@@ -105,6 +100,6 @@ public class RemoteIdEventTest extends AbstractRemoteEventTest {
private void assertDeserializeEvent(final RemoteIdEvent underTestCreatedEvent, final RemoteIdEvent event) {
// gets added because events inherit from of java.util.EventObject
assertThat(underTestCreatedEvent).isEqualToIgnoringGivenFields(event, "source");
assertThat(underTestCreatedEvent).usingRecursiveComparison().ignoringFields("source").isEqualTo(event);
}
}

View File

@@ -11,9 +11,7 @@ package org.eclipse.hawkbit.repository.event.remote;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import io.qameta.allure.Description;
import io.qameta.allure.Feature;
@@ -28,17 +26,16 @@ import org.junit.jupiter.api.Test;
@Feature("Component Tests - Repository")
@Story("RemoteTenantAwareEvent Tests")
public class RemoteTenantAwareEventTest extends AbstractRemoteEventTest {
class RemoteTenantAwareEventTest extends AbstractRemoteEventTest {
private static final String TENANT_DEFAULT = "DEFAULT";
private static final String APPLICATION_ID_DEFAULT = "Node";
@Test
@Description("Verifies that a testMultiActionAssignEvent can be properly serialized and deserialized")
public void testMultiActionAssignEvent() {
final List<String> controllerIds = Arrays.asList("id0", "id1", "id2", "id3",
"id4loooooooooooooooooooooooooooooooooooonnnnnnnnnnnnnnnnnng");
final List<Action> actions = controllerIds.stream().map(this::createAction).collect(Collectors.toList());
void testMultiActionAssignEvent() {
final List<String> controllerIds = List.of("id0", "id1", "id2", "id3", "id4loooooooooooooooooooooooooooooooooooonnnnnnnnnnnnnnnnnng");
final List<Action> actions = controllerIds.stream().map(this::createAction).toList();
final MultiActionAssignEvent assignEvent = new MultiActionAssignEvent(TENANT_DEFAULT, APPLICATION_ID_DEFAULT,
actions);
@@ -54,10 +51,9 @@ public class RemoteTenantAwareEventTest extends AbstractRemoteEventTest {
@Test
@Description("Verifies that a MultiActionCancelEvent can be properly serialized and deserialized")
public void testMultiActionCancelEvent() {
final List<String> controllerIds = Arrays.asList("id0", "id1", "id2", "id3",
"id4loooooooooooooooooooooooooooooooooooonnnnnnnnnnnnnnnnnng");
final List<Action> actions = controllerIds.stream().map(this::createAction).collect(Collectors.toList());
void testMultiActionCancelEvent() {
final List<String> controllerIds = List.of("id0", "id1", "id2", "id3", "id4loooooooooooooooooooooooooooooooooooonnnnnnnnnnnnnnnnnng");
final List<Action> actions = controllerIds.stream().map(this::createAction).toList();
final MultiActionCancelEvent cancelEvent = new MultiActionCancelEvent(TENANT_DEFAULT, APPLICATION_ID_DEFAULT,
actions);
@@ -73,7 +69,7 @@ public class RemoteTenantAwareEventTest extends AbstractRemoteEventTest {
@Test
@Description("Verifies that a DownloadProgressEvent can be properly serialized and deserialized")
public void reloadDownloadProgessByRemoteEvent() {
void reloadDownloadProgressByRemoteEvent() {
final DownloadProgressEvent downloadProgressEvent = new DownloadProgressEvent(TENANT_DEFAULT, 1L, 3L,
APPLICATION_ID_DEFAULT);
@@ -86,7 +82,7 @@ public class RemoteTenantAwareEventTest extends AbstractRemoteEventTest {
@Test
@Description("Verifies that a TargetAssignDistributionSetEvent can be properly serialized and deserialized")
public void testTargetAssignDistributionSetEvent() {
void testTargetAssignDistributionSetEvent() {
final DistributionSet dsA = testdataFactory.createDistributionSet("");
@@ -101,7 +97,7 @@ public class RemoteTenantAwareEventTest extends AbstractRemoteEventTest {
final Action action = actionRepository.save(generateAction);
final TargetAssignDistributionSetEvent assignmentEvent = new TargetAssignDistributionSetEvent(
action.getTenant(), dsA.getId(), Arrays.asList(action), serviceMatcher.getBusId(),
action.getTenant(), dsA.getId(), List.of(action), serviceMatcher.getBusId(),
action.isMaintenanceWindowAvailable());
final TargetAssignDistributionSetEvent remoteEventProtoStuff = createProtoStuffEvent(assignmentEvent);
@@ -113,7 +109,7 @@ public class RemoteTenantAwareEventTest extends AbstractRemoteEventTest {
@Test
@Description("Verifies that a TargetAssignDistributionSetEvent can be properly serialized and deserialized")
public void testCancelTargetAssignmentEvent() {
void testCancelTargetAssignmentEvent() {
final DistributionSet dsA = testdataFactory.createDistributionSet("");
@@ -138,9 +134,8 @@ public class RemoteTenantAwareEventTest extends AbstractRemoteEventTest {
}
private Action createAction(final String controllerId) {
long id = 1;
final JpaAction generateAction = new JpaAction();
generateAction.setId(id++);
generateAction.setId(1L);
generateAction.setActionType(ActionType.FORCED);
generateAction.setTarget(testdataFactory.createTarget(controllerId));
generateAction.setStatus(Status.RUNNING);
@@ -150,18 +145,18 @@ public class RemoteTenantAwareEventTest extends AbstractRemoteEventTest {
private void assertTargetAssignDistributionSetEvent(final Action action,
final TargetAssignDistributionSetEvent underTest) {
assertThat(underTest.getActions().size()).isEqualTo(1);
assertThat(underTest.getActions()).hasSize(1);
final ActionProperties actionProperties = underTest.getActions().get(action.getTarget().getControllerId());
assertThat(actionProperties).isNotNull();
assertThat(actionProperties).isEqualToComparingFieldByField(new ActionProperties(action));
assertThat(actionProperties).usingRecursiveComparison().comparingOnlyFields().isEqualTo(new ActionProperties(action));
assertThat(underTest.getDistributionSetId()).isEqualTo(action.getDistributionSet().getId());
}
private void assertCancelTargetAssignmentEvent(final Action action, final CancelTargetAssignmentEvent underTest) {
assertThat(underTest.getActions().size()).isEqualTo(1);
assertThat(underTest.getActions()).hasSize(1);
final ActionProperties actionProperties = underTest.getActions().get(action.getTarget().getControllerId());
assertThat(actionProperties).isNotNull();
assertThat(actionProperties).isEqualToComparingFieldByField(new ActionProperties(action));
assertThat(actionProperties).usingRecursiveComparison().comparingOnlyFields().isEqualTo(new ActionProperties(action));
assertThat(underTest.getActionPropertiesForController(action.getTarget().getControllerId())).isPresent();
}
}

View File

@@ -26,11 +26,11 @@ import org.junit.jupiter.api.Test;
*/
@Feature("Component Tests - Repository")
@Story("Test RolloutUpdatedEvent")
public class RolloutEventTest extends AbstractRemoteEntityEventTest<Rollout> {
class RolloutEventTest extends AbstractRemoteEntityEventTest<Rollout> {
@Test
@Description("Verifies that the rollout entity reloading by remote updated event works")
public void testRolloutUpdatedEvent() {
void testRolloutUpdatedEvent() {
assertAndCreateRemoteEvent(RolloutUpdatedEvent.class);
}

View File

@@ -30,11 +30,11 @@ import org.junit.jupiter.api.Test;
*/
@Feature("Component Tests - Repository")
@Story("Test RolloutGroupCreatedEvent and RolloutGroupUpdatedEvent")
public class RolloutGroupEventTest extends AbstractRemoteEntityEventTest<RolloutGroup> {
class RolloutGroupEventTest extends AbstractRemoteEntityEventTest<RolloutGroup> {
@Test
@Description("Verifies that the rollout group entity reloading by remote created event works")
public void testRolloutGroupCreatedEvent() {
void testRolloutGroupCreatedEvent() {
final RolloutGroupCreatedEvent createdEvent = (RolloutGroupCreatedEvent) assertAndCreateRemoteEvent(
RolloutGroupCreatedEvent.class);
assertThat(createdEvent.getRolloutId()).isNotNull();
@@ -42,7 +42,7 @@ public class RolloutGroupEventTest extends AbstractRemoteEntityEventTest<Rollout
@Test
@Description("Verifies that the rollout group entity reloading by remote updated event works")
public void testRolloutGroupUpdatedEvent() {
void testRolloutGroupUpdatedEvent() {
assertAndCreateRemoteEvent(RolloutGroupUpdatedEvent.class);
}

View File

@@ -51,19 +51,19 @@ import org.springframework.context.event.EventListener;
@Story("Entity Events")
@SpringBootTest(classes = { RepositoryTestConfiguration.class }, webEnvironment = SpringBootTest.WebEnvironment.NONE)
@SuppressWarnings("java:S6813") // constructor injects are not possible for test classes
public class RepositoryEntityEventTest extends AbstractJpaIntegrationTest {
class RepositoryEntityEventTest extends AbstractJpaIntegrationTest {
@Autowired
private MyEventListener eventListener;
@BeforeEach
public void beforeTest() {
void beforeTest() {
eventListener.queue.clear();
}
@Test
@Description("Verifies that the target created event is published when a target has been created")
public void targetCreatedEventIsPublished() throws InterruptedException {
void targetCreatedEventIsPublished() throws InterruptedException {
final Target createdTarget = testdataFactory.createTarget("12345");
final TargetCreatedEvent targetCreatedEvent = eventListener.waitForEvent(TargetCreatedEvent.class);
@@ -73,7 +73,7 @@ public class RepositoryEntityEventTest extends AbstractJpaIntegrationTest {
@Test
@Description("Verifies that the target update event is published when a target has been updated")
public void targetUpdateEventIsPublished() throws InterruptedException {
void targetUpdateEventIsPublished() throws InterruptedException {
final Target createdTarget = testdataFactory.createTarget("12345");
targetManagement.update(entityFactory.target().update(createdTarget.getControllerId()).name("updateName"));
@@ -84,7 +84,7 @@ public class RepositoryEntityEventTest extends AbstractJpaIntegrationTest {
@Test
@Description("Verifies that the target deleted event is published when a target has been deleted")
public void targetDeletedEventIsPublished() throws InterruptedException {
void targetDeletedEventIsPublished() throws InterruptedException {
final Target createdTarget = testdataFactory.createTarget("12345");
targetManagement.deleteByControllerID("12345");
@@ -96,7 +96,7 @@ public class RepositoryEntityEventTest extends AbstractJpaIntegrationTest {
@Test
@Description("Verifies that the target type created event is published when a target type has been created")
public void targetTypeCreatedEventIsPublished() throws InterruptedException {
void targetTypeCreatedEventIsPublished() throws InterruptedException {
final TargetType createdTargetType = testdataFactory.findOrCreateTargetType("targettype");
final TargetTypeCreatedEvent targetTypeCreatedEvent = eventListener.waitForEvent(TargetTypeCreatedEvent.class);
@@ -106,7 +106,7 @@ public class RepositoryEntityEventTest extends AbstractJpaIntegrationTest {
@Test
@Description("Verifies that the target type updated event is published when a target type has been updated")
public void targetTypeUpdatedEventIsPublished() throws InterruptedException {
void targetTypeUpdatedEventIsPublished() throws InterruptedException {
final TargetType createdTargetType = testdataFactory.findOrCreateTargetType("targettype");
targetTypeManagement
.update(entityFactory.targetType().update(createdTargetType.getId()).name("updatedtargettype"));
@@ -118,7 +118,7 @@ public class RepositoryEntityEventTest extends AbstractJpaIntegrationTest {
@Test
@Description("Verifies that the target type deleted event is published when a target type has been deleted")
public void targetTypeDeletedEventIsPublished() throws InterruptedException {
void targetTypeDeletedEventIsPublished() throws InterruptedException {
final TargetType createdTargetType = testdataFactory.findOrCreateTargetType("targettype");
targetTypeManagement.delete(createdTargetType.getId());
@@ -129,7 +129,7 @@ public class RepositoryEntityEventTest extends AbstractJpaIntegrationTest {
@Test
@Description("Verifies that the rollout deleted event is published when a rollout has been deleted")
public void rolloutDeletedEventIsPublished() throws InterruptedException {
void rolloutDeletedEventIsPublished() throws InterruptedException {
final int amountTargetsForRollout = 50;
final int amountGroups = 5;
final String successCondition = "50";
@@ -152,7 +152,7 @@ public class RepositoryEntityEventTest extends AbstractJpaIntegrationTest {
@Test
@Description("Verifies that the distribution set created event is published when a distribution set has been created")
public void distributionSetCreatedEventIsPublished() throws InterruptedException {
void distributionSetCreatedEventIsPublished() throws InterruptedException {
final DistributionSet createDistributionSet = testdataFactory.createDistributionSet();
final DistributionSetCreatedEvent dsCreatedEvent = eventListener
@@ -163,7 +163,7 @@ public class RepositoryEntityEventTest extends AbstractJpaIntegrationTest {
@Test
@Description("Verifies that the distribution set deleted event is published when a distribution set has been deleted")
public void distributionSetDeletedEventIsPublished() throws InterruptedException {
void distributionSetDeletedEventIsPublished() throws InterruptedException {
final DistributionSet createDistributionSet = testdataFactory.createDistributionSet();
distributionSetManagement.delete(createDistributionSet.getId());
@@ -176,7 +176,7 @@ public class RepositoryEntityEventTest extends AbstractJpaIntegrationTest {
@Test
@Description("Verifies that the software module created event is published when a software module has been created")
public void softwareModuleCreatedEventIsPublished() throws InterruptedException {
void softwareModuleCreatedEventIsPublished() throws InterruptedException {
final SoftwareModule softwareModule = testdataFactory.createSoftwareModuleApp();
final SoftwareModuleCreatedEvent softwareModuleCreatedEvent = eventListener
@@ -187,7 +187,7 @@ public class RepositoryEntityEventTest extends AbstractJpaIntegrationTest {
@Test
@Description("Verifies that the software module update event is published when a software module has been updated")
public void softwareModuleUpdateEventIsPublished() throws InterruptedException {
void softwareModuleUpdateEventIsPublished() throws InterruptedException {
final SoftwareModule softwareModule = testdataFactory.createSoftwareModuleApp();
softwareModuleManagement
.update(entityFactory.softwareModule().update(softwareModule.getId()).description("New"));
@@ -200,7 +200,7 @@ public class RepositoryEntityEventTest extends AbstractJpaIntegrationTest {
@Test
@Description("Verifies that the software module deleted event is published when a software module has been deleted")
public void softwareModuleDeletedEventIsPublished() throws InterruptedException {
void softwareModuleDeletedEventIsPublished() throws InterruptedException {
final SoftwareModule softwareModule = testdataFactory.createSoftwareModuleApp();
softwareModuleManagement.delete(softwareModule.getId());
@@ -215,10 +215,10 @@ public class RepositoryEntityEventTest extends AbstractJpaIntegrationTest {
return event.getEntity().get().getId();
}
public static class RepositoryTestConfiguration {
static class RepositoryTestConfiguration {
@Bean
public MyEventListener myEventListenerBean() {
MyEventListener myEventListenerBean() {
return new MyEventListener();
}
@@ -229,11 +229,11 @@ public class RepositoryEntityEventTest extends AbstractJpaIntegrationTest {
private final BlockingQueue<TenantAwareEvent> queue = new LinkedBlockingQueue<>();
@EventListener(classes = TenantAwareEvent.class)
public void onEvent(final TenantAwareEvent event) {
void onEvent(final TenantAwareEvent event) {
queue.offer(event);
}
public <T> T waitForEvent(final Class<T> eventType) throws InterruptedException {
<T> T waitForEvent(final Class<T> eventType) throws InterruptedException {
TenantAwareEvent event = null;
while ((event = queue.poll(5, TimeUnit.SECONDS)) != null) {
if (event.getClass().isAssignableFrom(eventType)) {

View File

@@ -20,7 +20,7 @@ import org.junit.jupiter.api.Test;
@Feature("SecurityTests - RolloutGroupManagement")
@Story("SecurityTests RolloutGroupManagement")
public class RolloutGroupManagementSecurityTest extends AbstractJpaIntegrationTest {
class RolloutGroupManagementSecurityTest extends AbstractJpaIntegrationTest {
@Test
@Description("Tests ManagementAPI PreAuthorized method with correct and insufficient permissions.")

View File

@@ -191,7 +191,7 @@ class RolloutManagementFlowTest extends AbstractJpaIntegrationTest {
rolloutHandler.handleAll();
assertThat(rolloutGroupManagement.findByRollout(
rollout.getId(), new OffsetBasedPageRequest(0, amountGroups + 10, Sort.by(Direction.ASC, "id"))
).getContent().size()).isEqualTo(amountGroups + 3);
).getContent()).hasSize(amountGroups + 3);
executeAllFromGroup(rollout, dynamic1, 1);
executeAllFromGroup(rollout, dynamic2, 3);
assertAndGetRunning(rollout, 0);
@@ -453,7 +453,7 @@ class RolloutManagementFlowTest extends AbstractJpaIntegrationTest {
actionRepository.findByRolloutIdAndStatus(PAGE, rollout.getId(), Action.Status.RUNNING).getContent()
.stream().filter(action -> action.getRolloutGroup().getId().equals(group.getId())).toList();
if (count >= 0) {
assertThat(running.size()).as("Action count").isEqualTo(count);
assertThat(running).as("Action count").hasSize(count);
}
running.forEach(this::finishAction);
}
@@ -466,7 +466,7 @@ class RolloutManagementFlowTest extends AbstractJpaIntegrationTest {
actionRepository.findByRolloutIdAndStatus(PAGE, rollout.getId(), Action.Status.RUNNING).getContent()
.stream().filter(action -> action.getRolloutGroup().getId().equals(group.getId())).toList();
if (count >= 0) {
assertThat(running.size()).as("Action count").isEqualTo(count);
assertThat(running).as("Action count").hasSize(count);
}
// skip on from the last group only

View File

@@ -34,7 +34,7 @@ import org.springframework.data.domain.PageImpl;
@Slf4j
@Feature("SecurityTests - RolloutManagement")
@Story("SecurityTests RolloutManagement")
public class RolloutManagementSecurityTest extends AbstractJpaIntegrationTest {
class RolloutManagementSecurityTest extends AbstractJpaIntegrationTest {
@Test
@Description("Tests ManagementAPI PreAuthorized method with correct and insufficient permissions.")

View File

@@ -16,14 +16,13 @@ import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.EnumMap;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import jakarta.validation.ConstraintViolationException;
@@ -111,7 +110,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
*/
@Test
@Description("Dynamic group doesn't override newer static group assignments")
public void dynamicGroupDoesntOverrideItsOrNewerStaticGroups() {
void dynamicGroupDoesntOverrideItsOrNewerStaticGroups() {
final int amountGroups = 1; // static only
final String targetPrefix = "controller-dynamic-rollout-";
final DistributionSet distributionSet = testdataFactory.createDistributionSet("ds");
@@ -800,7 +799,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
createdRollout = reloadRollout(createdRollout);
// 5 targets are running
final List<Action> runningActions = findActionsByRolloutAndStatus(createdRollout, Status.RUNNING);
assertThat(runningActions.size()).isEqualTo(5);
assertThat(runningActions).hasSize(5);
// 5 targets are in the group and the DS has been assigned
final List<RolloutGroup> rolloutGroups = rolloutGroupManagement.findByRollout(createdRollout.getId(), PAGE)
@@ -808,7 +807,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
final Page<Target> targets = rolloutGroupManagement.findTargetsOfRolloutGroup(rolloutGroups.get(0).getId(), PAGE
);
final List<Target> targetList = targets.getContent();
assertThat(targetList.size()).isEqualTo(5);
assertThat(targetList).hasSize(5);
targets.getContent().stream().map(Target::getControllerId).map(deploymentManagement::getAssignedDistributionSet)
.forEach(d -> assertThat(d.get().getId()).isEqualTo(ds.getId()));
@@ -923,7 +922,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
final Page<Target> targetPage = targetManagement.findByUpdateStatus(PAGE, TargetUpdateStatus.IN_SYNC);
final List<Target> targetList = targetPage.getContent();
// 15 targets in finished/IN_SYNC status and same DS assigned
assertThat(targetList.size()).isEqualTo(amountTargetsForRollout);
assertThat(targetList).hasSize(amountTargetsForRollout);
targetList.stream().map(Target::getControllerId).map(deploymentManagement::getAssignedDistributionSet)
.forEach(d -> assertThat(d).contains(distributionSet));
}
@@ -1136,7 +1135,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
final Slice<Rollout> rollout = rolloutManagement.findByFiltersWithDetailedStatus(
new OffsetBasedPageRequest(0, 100, Sort.by(Direction.ASC, "name")), "Rollout%", false);
final List<Rollout> rolloutList = rollout.getContent();
assertThat(rolloutList.size()).isEqualTo(5);
assertThat(rolloutList).hasSize(5);
int i = 1;
for (final Rollout r : rolloutList) {
assertThat(r.getName()).isEqualTo("Rollout" + i);
@@ -1239,23 +1238,22 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
Page<Target> targetPage = rolloutGroupManagement.findTargetsOfRolloutGroupByRsql(
new OffsetBasedPageRequest(0, 100), rolloutGroups.get(0).getId(), rsqlParam);
final List<Target> targetlistGroup1 = targetPage.getContent();
assertThat(targetlistGroup1.size()).isEqualTo(5);
assertThat(targetlistGroup1.stream().map(Target::getControllerId).collect(Collectors.toList()))
assertThat(targetlistGroup1).hasSize(5);
assertThat(targetlistGroup1.stream().map(Target::getControllerId).toList())
.are(targetBelongsInRollout);
targetPage = rolloutGroupManagement.findTargetsOfRolloutGroupByRsql(new OffsetBasedPageRequest(0, 100),
rolloutGroups.get(1).getId(), rsqlParam);
final List<Target> targetlistGroup2 = targetPage.getContent();
assertThat(targetlistGroup2.size()).isEqualTo(5);
assertThat(targetlistGroup2.stream().map(Target::getControllerId).collect(Collectors.toList()))
assertThat(targetlistGroup2).hasSize(5);
assertThat(targetlistGroup2.stream().map(Target::getControllerId).toList())
.are(targetBelongsInRollout);
targetPage = rolloutGroupManagement.findTargetsOfRolloutGroupByRsql(new OffsetBasedPageRequest(0, 100),
rolloutGroups.get(2).getId(), rsqlParam);
final List<Target> targetlistGroup3 = targetPage.getContent();
assertThat(targetlistGroup3.size()).isEqualTo(5);
assertThat(targetlistGroup3.stream().map(Target::getControllerId).collect(Collectors.toList()))
.are(targetBelongsInRollout);
assertThat(targetlistGroup3).hasSize(5);
assertThat(targetlistGroup3.stream().map(Target::getControllerId).toList()).are(targetBelongsInRollout);
}
@@ -1424,27 +1422,23 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
final RolloutGroupCreate group2 = entityFactory.rolloutGroup().create().conditions(conditions).name("group2").targetPercentage(50.0F);
// group1 exceeds the quota
final RolloutCreate rolloutCreate = entityFactory.rollout().create()
.name(rolloutName)
.description(rolloutName)
.targetFilterQuery("controllerId==" + rolloutName + "-*")
.distributionSetId(distributionSet);
final List<RolloutGroupCreate> groups = List.of(group1, group2);
assertThatExceptionOfType(AssignmentQuotaExceededException.class)
.isThrownBy(() -> rolloutManagement.create(
entityFactory.rollout().create()
.name(rolloutName)
.description(rolloutName)
.targetFilterQuery("controllerId==" + rolloutName + "-*")
.distributionSetId(distributionSet),
Arrays.asList(group1, group2), conditions));
.isThrownBy(() -> rolloutManagement.create(rolloutCreate, groups, conditions));
// create group definitions
final RolloutGroupCreate group3 = entityFactory.rolloutGroup().create().conditions(conditions).name("group3").targetPercentage(1.0F);
final RolloutGroupCreate group4 = entityFactory.rolloutGroup().create().conditions(conditions).name("group4").targetPercentage(100.0F);
// group4 exceeds the quota
assertThatExceptionOfType(AssignmentQuotaExceededException.class).isThrownBy(() -> rolloutManagement.create(
entityFactory.rollout().create()
.name(rolloutName)
.description(rolloutName)
.targetFilterQuery("controllerId==" + rolloutName + "-*")
.distributionSetId(distributionSet),
Arrays.asList(group3, group4), conditions));
final List<RolloutGroupCreate> groups2 = List.of(group3, group4);
assertThatExceptionOfType(AssignmentQuotaExceededException.class)
.isThrownBy(() -> rolloutManagement.create(rolloutCreate, groups2, conditions));
// create group definitions
final RolloutGroupCreate group5 = entityFactory.rolloutGroup().create().conditions(conditions).name("group5").targetPercentage(33.3F);
@@ -1453,11 +1447,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
// should work fine
assertThat(rolloutManagement.create(
entityFactory.rollout().create()
.name(rolloutName)
.description(rolloutName)
.targetFilterQuery("controllerId==" + rolloutName + "-*")
.distributionSetId(distributionSet),
rolloutCreate,
Arrays.asList(group5, group6, group7), conditions)).isNotNull();
}
@@ -1590,7 +1580,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
// verify created rollout groups
final List<Long> rolloutGroupIds = rolloutGroupManagement.findByRollout(rolloutId, PAGE).getContent().stream()
.map(Identifiable::getId).collect(Collectors.toList());
.map(Identifiable::getId).toList();
assertThat(rolloutGroupIds).hasSize(2);
assertRolloutGroup(rolloutGroupIds.get(0), RolloutGroupStatus.READY, true, amountTargetsInGroup1, null);
assertRolloutGroup(rolloutGroupIds.get(1), RolloutGroupStatus.READY, false, amountTargetsInGroup2, null);
@@ -1930,12 +1920,17 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
testdataFactory.createTargets(4, targetPrefix);
enableMultiAssignments();
final String rolloutName = UUID.randomUUID().toString();
final String targetPrefixName = UUID.randomUUID().toString();
Assertions.assertThatExceptionOfType(ConstraintViolationException.class)
.isThrownBy(() -> createTestRolloutWithTargetsAndDistributionSet(4, 2, "50", "80",
UUID.randomUUID().toString(), UUID.randomUUID().toString(), Action.WEIGHT_MAX + 1));
rolloutName, targetPrefixName, Action.WEIGHT_MAX + 1));
final String rolloutName2 = UUID.randomUUID().toString();
final String targetPrefixName2 = UUID.randomUUID().toString();
Assertions.assertThatExceptionOfType(ConstraintViolationException.class)
.isThrownBy(() -> createTestRolloutWithTargetsAndDistributionSet(4, 2, "50", "80",
UUID.randomUUID().toString(), UUID.randomUUID().toString(), Action.WEIGHT_MIN - 1));
rolloutName2, targetPrefixName2, Action.WEIGHT_MIN - 1));
final Rollout createdRollout1 = createTestRolloutWithTargetsAndDistributionSet(4, 2, "50", "80",
UUID.randomUUID().toString(), UUID.randomUUID().toString(), Action.WEIGHT_MAX);
final Rollout createdRollout2 = createTestRolloutWithTargetsAndDistributionSet(4, 2, "50", "80",
@@ -2126,14 +2121,15 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
amountOtherTargets, amountGroups, successCondition, errorCondition);
// check CREATING state
final Long createdRolloutId = createdRollout.getId();
assertThatExceptionOfType(RolloutIllegalStateException.class)
.isThrownBy(() -> rolloutManagement.triggerNextGroup(createdRollout.getId()))
.isThrownBy(() -> rolloutManagement.triggerNextGroup(createdRolloutId))
.withMessageContaining(errorMessage);
rolloutManagement.start(createdRollout.getId());
rolloutManagement.start(createdRolloutId);
// check STARTING state
assertThatExceptionOfType(RolloutIllegalStateException.class)
.isThrownBy(() -> rolloutManagement.triggerNextGroup(createdRollout.getId()))
.isThrownBy(() -> rolloutManagement.triggerNextGroup(createdRolloutId))
.withMessageContaining(errorMessage);
// Run here, because scheduler is disabled during tests
@@ -2144,16 +2140,16 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
// check STOPPED state
assertThatExceptionOfType(RolloutIllegalStateException.class)
.isThrownBy(() -> rolloutManagement.triggerNextGroup(createdRollout.getId()))
.isThrownBy(() -> rolloutManagement.triggerNextGroup(createdRolloutId))
.withMessageContaining(errorMessage);
final Slice<JpaAction> runningActionsSlice = actionRepository.findByRolloutIdAndStatus(PAGE,
createdRollout.getId(), Status.RUNNING);
createdRolloutId, Status.RUNNING);
runningActionsSlice.getContent().forEach(this::finishAction);
// check FINISHED state
assertThatExceptionOfType(RolloutIllegalStateException.class)
.isThrownBy(() -> rolloutManagement.triggerNextGroup(createdRollout.getId()))
.isThrownBy(() -> rolloutManagement.triggerNextGroup(createdRolloutId))
.withMessageContaining(errorMessage);
}
@@ -2165,7 +2161,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
}
private static Map<TotalTargetCountStatus.Status, Long> createInitStatusMap() {
final Map<TotalTargetCountStatus.Status, Long> map = new HashMap<>();
final Map<TotalTargetCountStatus.Status, Long> map = new EnumMap<>(TotalTargetCountStatus.Status.class);
for (final TotalTargetCountStatus.Status status : TotalTargetCountStatus.Status.values()) {
map.put(status, 0L);
}
@@ -2345,7 +2341,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
private int changeStatusForRunningActions(final Rollout rollout, final Status status,
final int amountOfTargetsToGetChanged) {
final List<Action> runningActions = findActionsByRolloutAndStatus(rollout, Status.RUNNING);
assertThat(runningActions.size()).isGreaterThanOrEqualTo(amountOfTargetsToGetChanged);
assertThat(runningActions).hasSizeGreaterThanOrEqualTo(amountOfTargetsToGetChanged);
for (int i = 0; i < amountOfTargetsToGetChanged; i++) {
controllerManagement.addUpdateActionStatus(
entityFactory.actionStatus().create(runningActions.get(i).getId()).status(status));

View File

@@ -10,7 +10,6 @@
package org.eclipse.hawkbit.repository.jpa.rsql;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.junit.jupiter.api.Assertions.fail;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
@@ -65,6 +64,7 @@ import org.mockito.Mockito;
import org.mockito.Spy;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.orm.jpa.vendor.Database;
import org.springframework.test.context.bean.override.mockito.MockitoBean;
import org.springframework.test.context.junit.jupiter.SpringExtension;
@@ -153,96 +153,74 @@ class RSQLUtilityTest {
@Test
@Description("Verify that RSQL expressions are validated case insensitive")
void mixedCaseRsqlFieldValidation() {
when(rsqlVisitorFactory.validationRsqlVisitor(eq(TargetFields.class))).thenReturn(new FieldValidationRsqlVisitor<>(TargetFields.class));
when(rsqlVisitorFactory.validationRsqlVisitor(TargetFields.class)).thenReturn(new FieldValidationRsqlVisitor<>(TargetFields.class));
final String rsqlWithMixedCase = "name==b And name==c aND Name==d OR NAME=iN=y oR nAme=IN=z";
RSQLUtility.validateRsqlFor(rsqlWithMixedCase, TargetFields.class);
}
@Test
void wrongRsqlSyntaxThrowSyntaxException() {
final String wrongRSQL = "name==abc;d";
try {
RSQLUtility.buildRsqlSpecification(wrongRSQL, SoftwareModuleFields.class, null, testDb)
.toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock);
fail("Missing expected RSQLParameterSyntaxException because of wrong RSQL syntax");
} catch (final RSQLParameterSyntaxException e) {
}
final Specification<Object> rsqlSpecification = RSQLUtility.buildRsqlSpecification("name==abc;d", SoftwareModuleFields.class, null, testDb);
assertThatExceptionOfType(RSQLParameterSyntaxException.class)
.as("RSQLParameterSyntaxException because of wrong RSQL syntax")
.isThrownBy(() -> rsqlSpecification.toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock));
}
@Test
void wrongFieldThrowUnsupportedFieldException() {
final String wrongRSQL = "unknownField==abc";
when(baseSoftwareModuleRootMock.getJavaType()).thenReturn((Class) SoftwareModule.class);
try {
RSQLUtility.buildRsqlSpecification(wrongRSQL, SoftwareModuleFields.class, null, testDb)
.toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock);
fail("Missing an expected RSQLParameterUnsupportedFieldException because of unknown RSQL field");
} catch (final RSQLParameterUnsupportedFieldException e) {
}
final Specification<Object> rsqlSpecification = RSQLUtility.buildRsqlSpecification("unknownField==abc", SoftwareModuleFields.class, null, testDb);
assertThatExceptionOfType(RSQLParameterUnsupportedFieldException.class)
.as("RSQLParameterUnsupportedFieldException because of unknown RSQL field")
.isThrownBy(() -> rsqlSpecification.toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock));
}
@Test
void wrongRsqlMapSyntaxThrowSyntaxException() {
String wrongRSQL = TargetFields.ATTRIBUTE + "==abc";
try {
RSQLUtility.buildRsqlSpecification(wrongRSQL, TargetFields.class, null, testDb)
.toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock);
fail("Missing expected RSQLParameterSyntaxException for target attributes map, caused by wrong RSQL syntax (key was not present)");
} catch (final RSQLParameterUnsupportedFieldException e) {
}
final Specification<Object> rsqlSpecification =
RSQLUtility.buildRsqlSpecification(TargetFields.ATTRIBUTE + "==abc", TargetFields.class, null, testDb);
assertThatExceptionOfType(RSQLParameterUnsupportedFieldException.class)
.as("RSQLParameterSyntaxException for target attributes map, caused by wrong RSQL syntax (key was not present)")
.isThrownBy(() -> rsqlSpecification.toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock));
wrongRSQL = TargetFields.ATTRIBUTE + ".unknown.wrong==abc";
try {
RSQLUtility.buildRsqlSpecification(wrongRSQL, TargetFields.class, null, testDb)
.toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock);
fail("Missing expected RSQLParameterSyntaxException for target attributes map, caused by wrong RSQL syntax (key includes dots)");
} catch (final RSQLParameterUnsupportedFieldException e) {
}
final Specification<Object> rsqlSpecification2 =
RSQLUtility.buildRsqlSpecification(TargetFields.ATTRIBUTE + ".unknown.wrong==abc", TargetFields.class, null, testDb);
assertThatExceptionOfType(RSQLParameterUnsupportedFieldException.class)
.as("RSQLParameterSyntaxException for target attributes map, caused by wrong RSQL syntax (key includes dots)")
.isThrownBy(() -> rsqlSpecification2.toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock));
wrongRSQL = TargetFields.METADATA + ".unknown.wrong==abc";
try {
RSQLUtility.buildRsqlSpecification(wrongRSQL, TargetFields.class, null, testDb)
.toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock);
fail("Missing expected RSQLParameterSyntaxException for target metadata map, caused by wrong RSQL syntax (key includes dots)");
} catch (final RSQLParameterUnsupportedFieldException e) {
}
wrongRSQL = DistributionSetFields.METADATA + "==abc";
try {
RSQLUtility.buildRsqlSpecification(wrongRSQL, DistributionSetFields.class, null, testDb)
.toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock);
fail("Missing expected RSQLParameterSyntaxException for distribution set metadata map, caused by wrong RSQL syntax (key was not present)");
} catch (final RSQLParameterUnsupportedFieldException e) {
}
final Specification<Object> rsqlSpecification3 =
RSQLUtility.buildRsqlSpecification(TargetFields.METADATA + ".unknown.wrong==abc", TargetFields.class, null, testDb);
assertThatExceptionOfType(RSQLParameterUnsupportedFieldException.class)
.as("RSQLParameterSyntaxException for target metadata map, caused by wrong RSQL syntax (key includes dots)")
.isThrownBy(() -> rsqlSpecification3.toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock));
final Specification<Object> rsqlSpecification4 =
RSQLUtility.buildRsqlSpecification(DistributionSetFields.METADATA + "==abc", TargetFields.class, null, testDb);
assertThatExceptionOfType(RSQLParameterUnsupportedFieldException.class)
.as("RSQLParameterSyntaxException for distribution set metadata map, caused by wrong RSQL syntax (key was not present)\"")
.isThrownBy(() -> rsqlSpecification4.toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock));
}
@Test
void wrongRsqlSubEntitySyntaxThrowSyntaxException() {
String wrongRSQL = TargetFields.ASSIGNEDDS + "==abc";
try {
RSQLUtility.buildRsqlSpecification(wrongRSQL, TargetFields.class, null, testDb)
.toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock);
fail("Missing expected RSQLParameterSyntaxException because of wrong RSQL syntax");
} catch (final RSQLParameterUnsupportedFieldException e) {
}
final Specification<Object> rsqlSpecification =
RSQLUtility.buildRsqlSpecification(TargetFields.ASSIGNEDDS + "==abc", TargetFields.class, null, testDb);
assertThatExceptionOfType(RSQLParameterUnsupportedFieldException.class)
.as("RSQLParameterSyntaxException because of wrong RSQL syntax")
.isThrownBy(() -> rsqlSpecification.toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock));
wrongRSQL = TargetFields.ASSIGNEDDS + ".unknownField==abc";
try {
RSQLUtility.buildRsqlSpecification(wrongRSQL, TargetFields.class, null, testDb)
.toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock);
fail("Missing expected RSQLParameterSyntaxException because of wrong RSQL syntax");
} catch (final RSQLParameterUnsupportedFieldException e) {
}
final Specification<Object> rsqlSpecification2 =
RSQLUtility.buildRsqlSpecification(TargetFields.ASSIGNEDDS + ".unknownField==abc", TargetFields.class, null, testDb);
assertThatExceptionOfType(RSQLParameterUnsupportedFieldException.class)
.as("RSQLParameterSyntaxException because of wrong RSQL syntax")
.isThrownBy(() -> rsqlSpecification2.toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock));
wrongRSQL = TargetFields.ASSIGNEDDS + ".unknownField.ToMuch==abc";
try {
RSQLUtility.buildRsqlSpecification(wrongRSQL, TargetFields.class, null, testDb)
.toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock);
fail("Missing expected RSQLParameterSyntaxException because of wrong RSQL syntax");
} catch (final RSQLParameterUnsupportedFieldException e) {
}
final Specification<Object> rsqlSpecification3 =
RSQLUtility.buildRsqlSpecification(TargetFields.ASSIGNEDDS + ".unknownField.ToMuch==abc", TargetFields.class, null, testDb);
assertThatExceptionOfType(RSQLParameterUnsupportedFieldException.class)
.as("RSQLParameterSyntaxException because of wrong RSQL syntax")
.isThrownBy(() -> rsqlSpecification3.toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock));
}
@Test
@@ -252,8 +230,7 @@ class RSQLUtilityTest {
when(baseSoftwareModuleRootMock.get("name")).thenReturn(baseSoftwareModuleRootMock);
when(baseSoftwareModuleRootMock.get("version")).thenReturn(baseSoftwareModuleRootMock);
when(baseSoftwareModuleRootMock.getJavaType()).thenReturn((Class) SoftwareModule.class);
when(criteriaBuilderMock.upper(eq(pathOfString(baseSoftwareModuleRootMock))))
.thenReturn(pathOfString(baseSoftwareModuleRootMock));
when(criteriaBuilderMock.upper(pathOfString(baseSoftwareModuleRootMock))).thenReturn(pathOfString(baseSoftwareModuleRootMock));
when(criteriaBuilderMock.like(any(Expression.class), anyString(), eq('\\'))).thenReturn(mock(Predicate.class));
when(criteriaBuilderMock.equal(any(Expression.class), any(String.class))).thenReturn(mock(Predicate.class));
when(criteriaBuilderMock.and(any(Predicate[].class))).thenReturn(mock(Predicate.class));
@@ -274,10 +251,8 @@ class RSQLUtilityTest {
when(baseSoftwareModuleRootMock.getJavaType()).thenReturn((Class) String.class);
when(criteriaBuilderMock.isNull(any(Expression.class))).thenReturn(mock(Predicate.class));
when(criteriaBuilderMock.notEqual(any(Expression.class), anyString()))
.thenReturn(mock(Predicate.class));
when(criteriaBuilderMock.upper(eq(pathOfString(baseSoftwareModuleRootMock))))
.thenReturn(pathOfString(baseSoftwareModuleRootMock));
when(criteriaBuilderMock.notEqual(any(Expression.class), anyString())).thenReturn(mock(Predicate.class));
when(criteriaBuilderMock.upper(pathOfString(baseSoftwareModuleRootMock))).thenReturn(pathOfString(baseSoftwareModuleRootMock));
// test
RSQLUtility.buildRsqlSpecification(correctRsql, SoftwareModuleFields.class, null, testDb)
@@ -285,8 +260,8 @@ class RSQLUtilityTest {
// verification
verify(criteriaBuilderMock, times(1)).or(any(Predicate.class), any(Predicate.class));
verify(criteriaBuilderMock, times(1)).isNull(eq(pathOfString(baseSoftwareModuleRootMock)));
verify(criteriaBuilderMock, times(1)).notEqual(eq(pathOfString(baseSoftwareModuleRootMock)), eq("abc".toUpperCase()));
verify(criteriaBuilderMock, times(1)).isNull(pathOfString(baseSoftwareModuleRootMock));
verify(criteriaBuilderMock, times(1)).notEqual(pathOfString(baseSoftwareModuleRootMock), "abc".toUpperCase());
}
@Test
@@ -299,8 +274,7 @@ class RSQLUtilityTest {
when(criteriaBuilderMock.isNull(any(Expression.class))).thenReturn(mock(Predicate.class));
when(criteriaBuilderMock.notLike(any(Expression.class), anyString(), eq('\\')))
.thenReturn(mock(Predicate.class));
when(criteriaBuilderMock.upper(eq(pathOfString(baseSoftwareModuleRootMock))))
.thenReturn(pathOfString(baseSoftwareModuleRootMock));
when(criteriaBuilderMock.upper(pathOfString(baseSoftwareModuleRootMock))).thenReturn(pathOfString(baseSoftwareModuleRootMock));
// test
RSQLUtility.buildRsqlSpecification(correctRsql, SoftwareModuleFields.class, null, testDb)
@@ -308,9 +282,8 @@ class RSQLUtilityTest {
// verification
verify(criteriaBuilderMock, times(1)).or(any(Predicate.class), any(Predicate.class));
verify(criteriaBuilderMock, times(1)).isNull(eq(pathOfString(baseSoftwareModuleRootMock)));
verify(criteriaBuilderMock, times(1)).notLike(eq(pathOfString(baseSoftwareModuleRootMock)),
eq("abc%".toUpperCase()), eq('\\'));
verify(criteriaBuilderMock, times(1)).isNull(pathOfString(baseSoftwareModuleRootMock));
verify(criteriaBuilderMock, times(1)).notLike(pathOfString(baseSoftwareModuleRootMock), "abc%".toUpperCase(), '\\');
}
@Test
@@ -348,18 +321,15 @@ class RSQLUtilityTest {
when(baseSoftwareModuleRootMock.get("name")).thenReturn(baseSoftwareModuleRootMock);
when(baseSoftwareModuleRootMock.getJavaType()).thenReturn((Class) String.class);
when(criteriaBuilderMock.equal(any(Expression.class), anyString())).thenReturn(mock(Predicate.class));
when(criteriaBuilderMock.<String> greaterThanOrEqualTo(any(Expression.class), any(String.class)))
.thenReturn(mock(Predicate.class));
when(criteriaBuilderMock.upper(eq(pathOfString(baseSoftwareModuleRootMock))))
.thenReturn(pathOfString(baseSoftwareModuleRootMock));
when(criteriaBuilderMock.greaterThanOrEqualTo(any(Expression.class), any(String.class))).thenReturn(mock(Predicate.class));
when(criteriaBuilderMock.upper(pathOfString(baseSoftwareModuleRootMock))).thenReturn(pathOfString(baseSoftwareModuleRootMock));
// test
RSQLUtility.buildRsqlSpecification(correctRsql, SoftwareModuleFields.class, null, Database.H2)
.toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock);
// verification
verify(criteriaBuilderMock, times(1)).and(any(Predicate.class));
verify(criteriaBuilderMock, times(1)).equal(eq(pathOfString(baseSoftwareModuleRootMock)),
eq("a%".toUpperCase()));
verify(criteriaBuilderMock, times(1)).equal(pathOfString(baseSoftwareModuleRootMock), "a%".toUpperCase());
}
@Test
@@ -369,18 +339,15 @@ class RSQLUtilityTest {
when(baseSoftwareModuleRootMock.get("name")).thenReturn(baseSoftwareModuleRootMock);
when(baseSoftwareModuleRootMock.getJavaType()).thenReturn((Class) String.class);
when(criteriaBuilderMock.like(any(Expression.class), anyString(), eq('\\'))).thenReturn(mock(Predicate.class));
when(criteriaBuilderMock.<String> greaterThanOrEqualTo(any(Expression.class), any(String.class)))
.thenReturn(mock(Predicate.class));
when(criteriaBuilderMock.upper(eq(pathOfString(baseSoftwareModuleRootMock))))
.thenReturn(pathOfString(baseSoftwareModuleRootMock));
when(criteriaBuilderMock.greaterThanOrEqualTo(any(Expression.class), any(String.class))).thenReturn(mock(Predicate.class));
when(criteriaBuilderMock.upper(pathOfString(baseSoftwareModuleRootMock))).thenReturn(pathOfString(baseSoftwareModuleRootMock));
// test
RSQLUtility.buildRsqlSpecification(correctRsql, SoftwareModuleFields.class, null, Database.H2)
.toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock);
// verification
verify(criteriaBuilderMock, times(1)).and(any(Predicate.class));
verify(criteriaBuilderMock, times(1)).like(eq(pathOfString(baseSoftwareModuleRootMock)),
eq("a\\%%".toUpperCase()), eq('\\'));
verify(criteriaBuilderMock, times(1)).like(pathOfString(baseSoftwareModuleRootMock), "a\\%%".toUpperCase(), '\\');
}
@Test
@@ -389,8 +356,7 @@ class RSQLUtilityTest {
final String correctRsql = "name==a%*";
when(baseSoftwareModuleRootMock.get("name")).thenReturn(baseSoftwareModuleRootMock);
when(baseSoftwareModuleRootMock.getJavaType()).thenReturn((Class) String.class);
when(criteriaBuilderMock.upper(eq(pathOfString(baseSoftwareModuleRootMock))))
.thenReturn(pathOfString(baseSoftwareModuleRootMock));
when(criteriaBuilderMock.upper(pathOfString(baseSoftwareModuleRootMock))).thenReturn(pathOfString(baseSoftwareModuleRootMock));
when(criteriaBuilderMock.like(any(Expression.class), anyString(), eq('\\'))).thenReturn(mock(Predicate.class));
when(criteriaBuilderMock.<String> greaterThanOrEqualTo(any(Expression.class), any(String.class)))
.thenReturn(mock(Predicate.class));
@@ -401,8 +367,7 @@ class RSQLUtilityTest {
// verification
verify(criteriaBuilderMock, times(1)).and(any(Predicate.class));
verify(criteriaBuilderMock, times(1)).like(eq(pathOfString(baseSoftwareModuleRootMock)),
eq("a[%]%".toUpperCase()), eq('\\'));
verify(criteriaBuilderMock, times(1)).like(pathOfString(baseSoftwareModuleRootMock), "a[%]%".toUpperCase(), '\\');
}
@Test
@@ -420,7 +385,7 @@ class RSQLUtilityTest {
// verification
verify(criteriaBuilderMock, times(1)).and(any(Predicate.class));
verify(criteriaBuilderMock, times(1)).lessThan(eq(pathOfString(baseSoftwareModuleRootMock)), eq("abc"));
verify(criteriaBuilderMock, times(1)).lessThan(pathOfString(baseSoftwareModuleRootMock), "abc");
}
@Test
@@ -437,7 +402,7 @@ class RSQLUtilityTest {
// verification
verify(criteriaBuilderMock, times(1)).and(any(Predicate.class));
verify(criteriaBuilderMock, times(1)).equal(eq(baseSoftwareModuleRootMock), eq(TestValueEnum.BUMLUX));
verify(criteriaBuilderMock, times(1)).equal(baseSoftwareModuleRootMock, TestValueEnum.BUMLUX);
}
@Test
@@ -448,14 +413,10 @@ class RSQLUtilityTest {
when(baseSoftwareModuleRootMock.getJavaType()).thenReturn((Class) TestValueEnum.class);
when(criteriaBuilderMock.equal(any(Root.class), anyString())).thenReturn(mock(Predicate.class));
try {
// test
RSQLUtility.buildRsqlSpecification(correctRsql, TestFieldEnum.class, null, testDb)
.toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock);
fail("missing RSQLParameterUnsupportedFieldException for wrong enum value");
} catch (final RSQLParameterUnsupportedFieldException e) {
// nope expected
}
final Specification<Object> rsqlSpecification = RSQLUtility.buildRsqlSpecification(correctRsql, TestFieldEnum.class, null, testDb);
assertThatExceptionOfType(RSQLParameterUnsupportedFieldException.class)
.as("RSQLParameterUnsupportedFieldException for wrong enum value")
.isThrownBy(() -> rsqlSpecification.toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock));
}
@Test
@@ -467,11 +428,9 @@ class RSQLUtilityTest {
final String correctRsql = "testfield=le=" + overduePropPlaceholder;
when(baseSoftwareModuleRootMock.get("testfield")).thenReturn(baseSoftwareModuleRootMock);
when(baseSoftwareModuleRootMock.getJavaType()).thenReturn((Class) String.class);
when(criteriaBuilderMock.upper(eq(pathOfString(baseSoftwareModuleRootMock))))
.thenReturn(pathOfString(baseSoftwareModuleRootMock));
when(criteriaBuilderMock.upper(pathOfString(baseSoftwareModuleRootMock))).thenReturn(pathOfString(baseSoftwareModuleRootMock));
when(criteriaBuilderMock.like(any(Expression.class), anyString(), eq('\\'))).thenReturn(mock(Predicate.class));
when(criteriaBuilderMock.<String> lessThanOrEqualTo(any(Expression.class), eq(overduePropPlaceholder)))
.thenReturn(mock(Predicate.class));
when(criteriaBuilderMock.lessThanOrEqualTo(any(Expression.class), eq(overduePropPlaceholder))).thenReturn(mock(Predicate.class));
// test
RSQLUtility.buildRsqlSpecification(correctRsql, TestFieldEnum.class, setupMacroLookup(), testDb)
@@ -482,8 +441,7 @@ class RSQLUtilityTest {
// the macro is already replaced when passed to #lessThanOrEqualTo ->
// the method is never invoked with the
// placeholder:
verify(criteriaBuilderMock, never()).lessThanOrEqualTo(eq(pathOfString(baseSoftwareModuleRootMock)),
eq(overduePropPlaceholder));
verify(criteriaBuilderMock, never()).lessThanOrEqualTo(pathOfString(baseSoftwareModuleRootMock), overduePropPlaceholder);
}
@Test
@@ -507,8 +465,7 @@ class RSQLUtilityTest {
verify(macroResolver).lookup(overdueProp);
// the macro is unknown and hence never replaced -> #lessThanOrEqualTo
// is invoked with the placeholder:
verify(criteriaBuilderMock).lessThanOrEqualTo(eq(pathOfString(baseSoftwareModuleRootMock)),
eq(overduePropPlaceholder));
verify(criteriaBuilderMock).lessThanOrEqualTo(pathOfString(baseSoftwareModuleRootMock), overduePropPlaceholder);
}
VirtualPropertyReplacer setupMacroLookup() {
@@ -528,7 +485,7 @@ class RSQLUtilityTest {
}
private void validateRsqlForTestFields(final String rsql) {
when(rsqlVisitorFactory.validationRsqlVisitor(eq(TestFieldEnum.class))).thenReturn(
when(rsqlVisitorFactory.validationRsqlVisitor(TestFieldEnum.class)).thenReturn(
new FieldValidationRsqlVisitor<>(TestFieldEnum.class));
RSQLUtility.validateRsqlFor(rsql, TestFieldEnum.class);
}

View File

@@ -59,7 +59,7 @@ public class ResponseList<T> extends RepresentationModel<ResponseList<T>> implem
}
@Override
public <T> T[] toArray(final T[] a) {
public <C> C[] toArray(final C[] a) {
return content.toArray(a);
}