diff --git a/hawkbit-repository/hawkbit-repository-jpa-ql/src/main/java/org/eclipse/hawkbit/repository/jpa/ql/utils/HawkbitQlToSql.java b/hawkbit-repository/hawkbit-repository-jpa-ql/src/main/java/org/eclipse/hawkbit/repository/jpa/ql/utils/HawkbitQlToSql.java index 6e2a785cc..6d724a00c 100644 --- a/hawkbit-repository/hawkbit-repository-jpa-ql/src/main/java/org/eclipse/hawkbit/repository/jpa/ql/utils/HawkbitQlToSql.java +++ b/hawkbit-repository/hawkbit-repository-jpa-ql/src/main/java/org/eclipse/hawkbit/repository/jpa/ql/utils/HawkbitQlToSql.java @@ -19,13 +19,10 @@ import jakarta.persistence.criteria.CriteriaQuery; import org.eclipse.hawkbit.repository.RsqlQueryField; import org.eclipse.hawkbit.repository.jpa.rsql.RsqlUtility; -import org.eclipse.hawkbit.repository.jpa.rsql.RsqlConfigHolder; -import org.eclipse.hawkbit.repository.jpa.rsql.RsqlConfigHolder.RsqlToSpecBuilder; -import org.springframework.orm.jpa.vendor.Database; +import org.eclipse.hawkbit.repository.jpa.rsql.RsqlUtility.RsqlToSpecBuilder; public class HawkbitQlToSql { - private static final Database DATABASE = Database.H2; private final EntityManager entityManager; private final boolean isEclipselink; @@ -61,16 +58,16 @@ public class HawkbitQlToSql { final Class domainClass, final Class fieldsClass, final String rsql, final RsqlToSpecBuilder rsqlToSpecBuilder) { final CriteriaQuery query = entityManager.getCriteriaBuilder().createQuery(domainClass); final CriteriaBuilder cb = entityManager.getCriteriaBuilder(); - final RsqlToSpecBuilder defaultRsqlToSpecBuilder = RsqlConfigHolder.getInstance().getRsqlToSpecBuilder(); + final RsqlToSpecBuilder defaultRsqlToSpecBuilder = RsqlUtility.getInstance().getRsqlToSpecBuilder(); if (defaultRsqlToSpecBuilder != rsqlToSpecBuilder) { - RsqlConfigHolder.getInstance().setRsqlToSpecBuilder(rsqlToSpecBuilder); + RsqlUtility.getInstance().setRsqlToSpecBuilder(rsqlToSpecBuilder); } try { - return query.where(RsqlUtility. buildRsqlSpecification(rsql, fieldsClass, null, DATABASE) + return query.where(RsqlUtility.getInstance(). buildRsqlSpecification(rsql, fieldsClass) .toPredicate(query.from(domainClass), cb.createQuery(domainClass), cb)); } finally { if (defaultRsqlToSpecBuilder != rsqlToSpecBuilder) { - RsqlConfigHolder.getInstance().setRsqlToSpecBuilder(defaultRsqlToSpecBuilder); + RsqlUtility.getInstance().setRsqlToSpecBuilder(defaultRsqlToSpecBuilder); } } } diff --git a/hawkbit-repository/hawkbit-repository-jpa-ql/src/main/java/org/eclipse/hawkbit/repository/jpa/rsql/RsqlConfigHolder.java b/hawkbit-repository/hawkbit-repository-jpa-ql/src/main/java/org/eclipse/hawkbit/repository/jpa/rsql/RsqlConfigHolder.java deleted file mode 100644 index fdceaf77b..000000000 --- a/hawkbit-repository/hawkbit-repository-jpa-ql/src/main/java/org/eclipse/hawkbit/repository/jpa/rsql/RsqlConfigHolder.java +++ /dev/null @@ -1,61 +0,0 @@ -/** - * Copyright (c) 2025 Contributors to the Eclipse Foundation - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.repository.jpa.rsql; - -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; -import org.springframework.beans.factory.annotation.Value; - -/** - * Helper class providing static access to the RSQL configuration as managed bean. - */ -@NoArgsConstructor(access = lombok.AccessLevel.PRIVATE) -@Getter -@SuppressWarnings("java:S6548") // singleton holder ensures static access to spring resources in some places -public final class RsqlConfigHolder { - - private static final RsqlConfigHolder SINGLETON = new RsqlConfigHolder(); - - public enum RsqlToSpecBuilder { - LEGACY_G1, // legacy RSQL visitor - LEGACY_G2, // G2 RSQL visitor - G3 // G3 RSQL visitor - still experimental / yet default - } - /** - * If RSQL comparison operators shall ignore the case. If ignore case is true "x == ax" will match "x == aX" - */ - @Value("${hawkbit.rsql.ignore-case:true}") - private boolean ignoreCase; - /** - * Declares if the database is case-insensitive, by default assumes false. In case it is case-sensitive and, - * {@link #ignoreCase} is set to true the SQL queries use upper case comparisons to ignore case. - * - * If the database is declared as case-sensitive and ignoreCase is set to false the RSQL queries shall use strict - * syntax - i.e. 'and' instead of 'AND' / 'aND'. Otherwise, the queries would be case-insensitive regarding operators. - */ - @Value("${hawkbit.rsql.case-insensitive-db:false}") - private boolean caseInsensitiveDB; - - /** - * @deprecated in favour fixed final visitor / spec builder of G2 RSQL visitor / G3 spec builder. since 0.6.0 - */ - @Setter // for tests only - @Deprecated(forRemoval = true, since = "0.6.0") - @Value("${hawkbit.rsql.rsql-to-spec-builder:G3}") // - private RsqlToSpecBuilder rsqlToSpecBuilder; - - /** - * @return The holder singleton instance. - */ - public static RsqlConfigHolder getInstance() { - return SINGLETON; - } -} \ No newline at end of file diff --git a/hawkbit-repository/hawkbit-repository-jpa-ql/src/main/java/org/eclipse/hawkbit/repository/jpa/rsql/RsqlUtility.java b/hawkbit-repository/hawkbit-repository-jpa-ql/src/main/java/org/eclipse/hawkbit/repository/jpa/rsql/RsqlUtility.java index 7d926d06d..8cf6c67dc 100644 --- a/hawkbit-repository/hawkbit-repository-jpa-ql/src/main/java/org/eclipse/hawkbit/repository/jpa/rsql/RsqlUtility.java +++ b/hawkbit-repository/hawkbit-repository-jpa-ql/src/main/java/org/eclipse/hawkbit/repository/jpa/rsql/RsqlUtility.java @@ -9,15 +9,15 @@ */ package org.eclipse.hawkbit.repository.jpa.rsql; -import static org.eclipse.hawkbit.repository.jpa.rsql.RsqlConfigHolder.RsqlToSpecBuilder.G3; - import jakarta.persistence.EntityManager; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.CriteriaQuery; import cz.jirutka.rsql.parser.RSQLParserException; import lombok.AccessLevel; +import lombok.Getter; import lombok.NoArgsConstructor; +import lombok.Setter; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.text.StrLookup; import org.eclipse.hawkbit.repository.RsqlQueryField; @@ -27,6 +27,9 @@ import org.eclipse.hawkbit.repository.jpa.ql.SpecificationBuilder; import org.eclipse.hawkbit.repository.jpa.rsql.legacy.SpecificationBuilderLegacy; import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer; import org.eclipse.hawkbit.repository.rsql.VirtualPropertyResolver; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties; import org.springframework.data.jpa.domain.Specification; import org.springframework.orm.jpa.vendor.Database; @@ -64,8 +67,66 @@ import org.springframework.orm.jpa.vendor.Database; * $${OVERDUE_TS} would prevent the ${OVERDUE_TS} token from being expanded. */ @Slf4j +@Getter @NoArgsConstructor(access = AccessLevel.PRIVATE) -public final class RsqlUtility { +public class RsqlUtility { + + private static final RsqlUtility SINGLETON = new RsqlUtility(); + + public enum RsqlToSpecBuilder { + LEGACY_G1, // legacy RSQL visitor + LEGACY_G2, // G2 RSQL visitor + G3 // G3 RSQL visitor - still experimental / yet default + } + + /** + * If RSQL comparison operators shall ignore the case. If ignore case is true "x == ax" will match "x == aX" + */ + @Value("${hawkbit.rsql.ignore-case:true}") + private boolean ignoreCase; + /** + * Declares if the database is case-insensitive, by default assumes false. In case it is case-sensitive and, + * {@link #ignoreCase} is set to true the SQL queries use upper case comparisons to ignore case. + *

+ * If the database is declared as case-sensitive and ignoreCase is set to false the RSQL queries shall use strict + * syntax - i.e. 'and' instead of 'AND' / 'aND'. Otherwise, the queries would be case-insensitive regarding operators. + */ + @Value("${hawkbit.rsql.case-insensitive-db:false}") + private boolean caseInsensitiveDB; + + /** + * @deprecated in favour fixed final visitor / spec builder of G2 RSQL visitor / G3 spec builder. since 0.6.0 + */ + @Setter // for tests only + @Deprecated(forRemoval = true, since = "0.6.0") + @Value("${hawkbit.rsql.rsql-to-spec-builder:G3}") // + private RsqlToSpecBuilder rsqlToSpecBuilder; + + private VirtualPropertyReplacer virtualPropertyReplacer; + private Database database; + private EntityManager entityManager; + + /** + * @return The holder singleton instance. + */ + public static RsqlUtility getInstance() { + return SINGLETON; + } + + @Autowired(required = false) + void setVirtualPropertyReplacer(final VirtualPropertyReplacer virtualPropertyReplacer) { + this.virtualPropertyReplacer = virtualPropertyReplacer; + } + + @Autowired + void setDatabase(final JpaProperties jpaProperties) { + database = jpaProperties.getDatabase(); + } + + @Autowired + void setEntityManager(final EntityManager entityManager) { + this.entityManager = entityManager; + } /** * Builds a JPA {@link Specification} which corresponds with the given RSQL query. The specification can be used to filter for JPA entities @@ -73,25 +134,16 @@ public final class RsqlUtility { * * @param rsql the rsql query to be parsed * @param rsqlQueryFieldType the enum class type which implements the {@link RsqlQueryField} - * @param virtualPropertyReplacer holds the logic how the known macros have to be resolved; may be null - * @param database database in use * @return a specification which can be used with JPA * @throws RSQLParameterUnsupportedFieldException if a field in the RSQL string is used but not provided by the * given {@code fieldNameProvider} * @throws RSQLParameterSyntaxException if the RSQL syntax is wrong */ - public static & RsqlQueryField, T> Specification buildRsqlSpecification( - final String rsql, final Class rsqlQueryFieldType, - final VirtualPropertyReplacer virtualPropertyReplacer, final Database database) { - if (RsqlConfigHolder.getInstance().getRsqlToSpecBuilder() == G3) { - return new SpecificationBuilder( - virtualPropertyReplacer, - !RsqlConfigHolder.getInstance().isCaseInsensitiveDB() && RsqlConfigHolder.getInstance().isIgnoreCase(), - database) - .specification(RsqlParser.parse( - RsqlConfigHolder.getInstance().isCaseInsensitiveDB() || RsqlConfigHolder.getInstance().isIgnoreCase() - ? rsql.toLowerCase() : rsql, - rsqlQueryFieldType)); + public & RsqlQueryField, T> Specification buildRsqlSpecification( + final String rsql, final Class rsqlQueryFieldType) { + if (rsqlToSpecBuilder == RsqlToSpecBuilder.G3) { + return new SpecificationBuilder(virtualPropertyReplacer, !caseInsensitiveDB && ignoreCase, database) + .specification(RsqlParser.parse(caseInsensitiveDB || ignoreCase ? rsql.toLowerCase() : rsql, rsqlQueryFieldType)); } else { return new SpecificationBuilderLegacy(rsqlQueryFieldType, virtualPropertyReplacer, database).specification(rsql); } @@ -101,18 +153,16 @@ public final class RsqlUtility { * Validates the RSQL string * * @param rsql RSQL string to validate - * @param rsqlQueryFieldType + * @param rsqlQueryFieldType the enum class type which implements the {@link RsqlQueryField} + * @param jpaType the JPA entity type to validate against * @throws RSQLParserException if RSQL syntax is invalid * @throws RSQLParameterUnsupportedFieldException if RSQL key is not allowed */ @SuppressWarnings({ "unchecked", "rawtypes" }) - public static & RsqlQueryField> void validateRsqlFor( - final String rsql, final Class rsqlQueryFieldType, - final Class jpaType, - final VirtualPropertyReplacer virtualPropertyReplacer, final EntityManager entityManager) { + public & RsqlQueryField> void validateRsqlFor( + final String rsql, final Class rsqlQueryFieldType, final Class jpaType) { final CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder(); final CriteriaQuery criteriaQuery = criteriaBuilder.createQuery(jpaType); - buildRsqlSpecification(rsql, rsqlQueryFieldType, virtualPropertyReplacer, null) - .toPredicate(criteriaQuery.from((Class) jpaType), criteriaQuery, criteriaBuilder); + buildRsqlSpecification(rsql, rsqlQueryFieldType).toPredicate(criteriaQuery.from((Class) jpaType), criteriaQuery, criteriaBuilder); } } \ No newline at end of file diff --git a/hawkbit-repository/hawkbit-repository-jpa-ql/src/main/java/org/eclipse/hawkbit/repository/jpa/rsql/legacy/SpecificationBuilderLegacy.java b/hawkbit-repository/hawkbit-repository-jpa-ql/src/main/java/org/eclipse/hawkbit/repository/jpa/rsql/legacy/SpecificationBuilderLegacy.java index 911116da2..54b696cd9 100644 --- a/hawkbit-repository/hawkbit-repository-jpa-ql/src/main/java/org/eclipse/hawkbit/repository/jpa/rsql/legacy/SpecificationBuilderLegacy.java +++ b/hawkbit-repository/hawkbit-repository-jpa-ql/src/main/java/org/eclipse/hawkbit/repository/jpa/rsql/legacy/SpecificationBuilderLegacy.java @@ -10,7 +10,7 @@ package org.eclipse.hawkbit.repository.jpa.rsql.legacy; import static org.eclipse.hawkbit.repository.jpa.rsql.legacy.AbstractRSQLVisitor.OPERATORS; -import static org.eclipse.hawkbit.repository.jpa.rsql.RsqlConfigHolder.RsqlToSpecBuilder.LEGACY_G1; +import static org.eclipse.hawkbit.repository.jpa.rsql.RsqlUtility.RsqlToSpecBuilder.LEGACY_G1; import java.util.List; @@ -24,7 +24,7 @@ import lombok.extern.slf4j.Slf4j; import org.eclipse.hawkbit.repository.RsqlQueryField; import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException; import org.eclipse.hawkbit.repository.jpa.ql.SpecificationBuilder; -import org.eclipse.hawkbit.repository.jpa.rsql.RsqlConfigHolder; +import org.eclipse.hawkbit.repository.jpa.rsql.RsqlUtility; import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer; import org.springframework.data.jpa.domain.Specification; import org.springframework.orm.jpa.vendor.Database; @@ -50,14 +50,14 @@ public class SpecificationBuilderLegacy & RsqlQueryField, T> { public Specification specification(final String rsql) { return (root, query, cb) -> { - final RsqlConfigHolder rsqlConfigHolder = RsqlConfigHolder.getInstance(); + final RsqlUtility rsqlUtility = RsqlUtility.getInstance(); - final Node rootNode = parseRsql(rsql, rsqlConfigHolder); + final Node rootNode = parseRsql(rsql, rsqlUtility); query.distinct(true); - final boolean ensureIgnoreCase = !rsqlConfigHolder.isCaseInsensitiveDB() && rsqlConfigHolder.isIgnoreCase(); + final boolean ensureIgnoreCase = !rsqlUtility.isCaseInsensitiveDB() && rsqlUtility.isIgnoreCase(); final RSQLVisitor, String> jpqQueryRSQLVisitor = - rsqlConfigHolder.getRsqlToSpecBuilder() == LEGACY_G1 + rsqlUtility.getRsqlToSpecBuilder() == LEGACY_G1 ? new JpaQueryRsqlVisitor<>(root, cb, rsqlQueryFieldType, virtualPropertyReplacer, database, query, ensureIgnoreCase) : new JpaQueryRsqlVisitorG2<>(rsqlQueryFieldType, root, query, cb, database, virtualPropertyReplacer, ensureIgnoreCase); final List accept = rootNode.accept(jpqQueryRSQLVisitor); @@ -70,10 +70,10 @@ public class SpecificationBuilderLegacy & RsqlQueryField, T> { }; } - private static Node parseRsql(final String rsql, final RsqlConfigHolder rsqlConfigHolder) { + private static Node parseRsql(final String rsql, final RsqlUtility rsqlUtility) { log.debug("Parsing rsql string {}", rsql); try { - return new RSQLParser(OPERATORS).parse(rsqlConfigHolder.isCaseInsensitiveDB() || rsqlConfigHolder.isIgnoreCase() ? rsql.toLowerCase() : rsql); + return new RSQLParser(OPERATORS).parse(rsqlUtility.isCaseInsensitiveDB() || rsqlUtility.isIgnoreCase() ? rsql.toLowerCase() : rsql); } catch (final IllegalArgumentException e) { throw new RSQLParameterSyntaxException("RSQL filter must not be null", e); } catch (final RSQLParserException e) { diff --git a/hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/sa/Root.java b/hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/ql/Root.java similarity index 97% rename from hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/sa/Root.java rename to hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/ql/Root.java index c03369dca..9d0d3f156 100644 --- a/hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/sa/Root.java +++ b/hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/ql/Root.java @@ -7,7 +7,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.eclipse.hawkbit.repository.jpa.rsql.sa; +package org.eclipse.hawkbit.repository.jpa.ql; import java.util.Map; import java.util.Set; diff --git a/hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/sa/RootRepository.java b/hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/ql/RootRepository.java similarity index 91% rename from hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/sa/RootRepository.java rename to hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/ql/RootRepository.java index c6f08e474..c4f994b59 100644 --- a/hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/sa/RootRepository.java +++ b/hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/ql/RootRepository.java @@ -7,7 +7,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.eclipse.hawkbit.repository.jpa.rsql.sa; +package org.eclipse.hawkbit.repository.jpa.ql; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.repository.CrudRepository; diff --git a/hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/sa/SpecificationBuilderLegacyTest.java b/hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/ql/SpecificationBuilderLegacyTest.java similarity index 84% rename from hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/sa/SpecificationBuilderLegacyTest.java rename to hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/ql/SpecificationBuilderLegacyTest.java index 6e50a4d9a..2dbf27cb6 100644 --- a/hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/sa/SpecificationBuilderLegacyTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/ql/SpecificationBuilderLegacyTest.java @@ -7,10 +7,10 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.eclipse.hawkbit.repository.jpa.rsql.sa; +package org.eclipse.hawkbit.repository.jpa.ql; -import static org.eclipse.hawkbit.repository.jpa.rsql.RsqlConfigHolder.RsqlToSpecBuilder.LEGACY_G1; -import static org.eclipse.hawkbit.repository.jpa.rsql.RsqlConfigHolder.RsqlToSpecBuilder.LEGACY_G2; +import static org.eclipse.hawkbit.repository.jpa.rsql.RsqlUtility.RsqlToSpecBuilder.LEGACY_G1; +import static org.eclipse.hawkbit.repository.jpa.rsql.RsqlUtility.RsqlToSpecBuilder.LEGACY_G2; import java.util.Arrays; import java.util.List; @@ -18,9 +18,9 @@ import java.util.List; import lombok.Getter; import lombok.extern.slf4j.Slf4j; import org.eclipse.hawkbit.repository.RsqlQueryField; +import org.eclipse.hawkbit.repository.jpa.rsql.RsqlUtility; +import org.eclipse.hawkbit.repository.jpa.rsql.RsqlUtility.RsqlToSpecBuilder; import org.eclipse.hawkbit.repository.jpa.rsql.legacy.SpecificationBuilderLegacy; -import org.eclipse.hawkbit.repository.jpa.rsql.RsqlConfigHolder; -import org.eclipse.hawkbit.repository.jpa.rsql.RsqlConfigHolder.RsqlToSpecBuilder; import org.junit.jupiter.api.Test; import org.springframework.data.jpa.domain.Specification; import org.springframework.orm.jpa.vendor.Database; @@ -32,12 +32,12 @@ class SpecificationBuilderLegacyTest extends SpecificationBuilderTest { private final SpecificationBuilderLegacy builder = new SpecificationBuilderLegacy<>(RootField.class, null, Database.H2); private static void runWithRsqlToSpecBuilder(final Runnable runnable, final RsqlToSpecBuilder rsqlToSpecBuilder) { - final RsqlToSpecBuilder defaultBuilder = RsqlConfigHolder.getInstance().getRsqlToSpecBuilder(); - RsqlConfigHolder.getInstance().setRsqlToSpecBuilder(rsqlToSpecBuilder); + final RsqlToSpecBuilder defaultBuilder = RsqlUtility.getInstance().getRsqlToSpecBuilder(); + RsqlUtility.getInstance().setRsqlToSpecBuilder(rsqlToSpecBuilder); try { runnable.run(); } finally { - RsqlConfigHolder.getInstance().setRsqlToSpecBuilder(defaultBuilder); + RsqlUtility.getInstance().setRsqlToSpecBuilder(defaultBuilder); } } diff --git a/hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/sa/SpecificationBuilderTest.java b/hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/ql/SpecificationBuilderTest.java similarity index 98% rename from hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/sa/SpecificationBuilderTest.java rename to hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/ql/SpecificationBuilderTest.java index 9dec4a9ff..d416e6778 100644 --- a/hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/sa/SpecificationBuilderTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/ql/SpecificationBuilderTest.java @@ -7,12 +7,12 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.eclipse.hawkbit.repository.jpa.rsql.sa; +package org.eclipse.hawkbit.repository.jpa.ql; import static org.assertj.core.api.Assertions.assertThat; -import static org.eclipse.hawkbit.repository.jpa.rsql.RsqlConfigHolder.RsqlToSpecBuilder.G3; -import static org.eclipse.hawkbit.repository.jpa.rsql.RsqlConfigHolder.RsqlToSpecBuilder.LEGACY_G1; -import static org.eclipse.hawkbit.repository.jpa.rsql.RsqlConfigHolder.RsqlToSpecBuilder.LEGACY_G2; +import static org.eclipse.hawkbit.repository.jpa.rsql.RsqlUtility.RsqlToSpecBuilder.G3; +import static org.eclipse.hawkbit.repository.jpa.rsql.RsqlUtility.RsqlToSpecBuilder.LEGACY_G1; +import static org.eclipse.hawkbit.repository.jpa.rsql.RsqlUtility.RsqlToSpecBuilder.LEGACY_G2; import java.util.List; import java.util.Map; @@ -22,11 +22,9 @@ import java.util.stream.StreamSupport; import jakarta.persistence.EntityManager; import lombok.extern.slf4j.Slf4j; -import org.eclipse.hawkbit.repository.jpa.ql.EntityMatcher; import org.eclipse.hawkbit.repository.jpa.ql.utils.HawkbitQlToSql; import org.eclipse.hawkbit.repository.jpa.rsql.RsqlParser; -import org.eclipse.hawkbit.repository.jpa.ql.SpecificationBuilder; -import org.eclipse.hawkbit.repository.jpa.rsql.RsqlConfigHolder; +import org.eclipse.hawkbit.repository.jpa.rsql.RsqlUtility; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringBootConfiguration; @@ -491,8 +489,8 @@ class SpecificationBuilderTest { return builder.specification(RsqlParser.parse(rsql)); } - private static RsqlConfigHolder.RsqlToSpecBuilder getRsqlToSpecBuilder() { - return RsqlConfigHolder.getInstance().getRsqlToSpecBuilder(); + private static RsqlUtility.RsqlToSpecBuilder getRsqlToSpecBuilder() { + return RsqlUtility.getInstance().getRsqlToSpecBuilder(); } @SpringBootConfiguration diff --git a/hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/sa/Sub.java b/hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/ql/Sub.java similarity index 83% rename from hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/sa/Sub.java rename to hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/ql/Sub.java index 6f4b8ceeb..7bf12e49a 100644 --- a/hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/sa/Sub.java +++ b/hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/ql/Sub.java @@ -7,16 +7,13 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.eclipse.hawkbit.repository.jpa.rsql.sa; +package org.eclipse.hawkbit.repository.jpa.ql; import jakarta.persistence.Entity; -import jakarta.persistence.FetchType; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; import jakarta.persistence.ManyToOne; -import jakarta.persistence.OneToMany; -import jakarta.persistence.OneToOne; import lombok.Data; import lombok.experimental.Accessors; diff --git a/hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/sa/SubRepository.java b/hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/ql/SubRepository.java similarity index 91% rename from hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/sa/SubRepository.java rename to hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/ql/SubRepository.java index bdf56eacc..d77bb2142 100644 --- a/hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/sa/SubRepository.java +++ b/hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/ql/SubRepository.java @@ -7,7 +7,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.eclipse.hawkbit.repository.jpa.rsql.sa; +package org.eclipse.hawkbit.repository.jpa.ql; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.repository.CrudRepository; diff --git a/hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/sa/SubSub.java b/hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/ql/SubSub.java similarity index 93% rename from hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/sa/SubSub.java rename to hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/ql/SubSub.java index 8dfd88b51..f9ecd4a72 100644 --- a/hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/sa/SubSub.java +++ b/hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/ql/SubSub.java @@ -7,7 +7,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.eclipse.hawkbit.repository.jpa.rsql.sa; +package org.eclipse.hawkbit.repository.jpa.ql; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; diff --git a/hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/sa/SubSubRepository.java b/hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/ql/SubSubRepository.java similarity index 92% rename from hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/sa/SubSubRepository.java rename to hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/ql/SubSubRepository.java index 8bede04b2..f491b1570 100644 --- a/hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/sa/SubSubRepository.java +++ b/hawkbit-repository/hawkbit-repository-jpa-ql/src/test/java/org/eclipse/hawkbit/repository/jpa/ql/SubSubRepository.java @@ -7,7 +7,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.eclipse.hawkbit.repository.jpa.rsql.sa; +package org.eclipse.hawkbit.repository.jpa.ql; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.repository.CrudRepository; diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/RepositoryApplicationConfiguration.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/RepositoryApplicationConfiguration.java index 064edad31..1983447dc 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/RepositoryApplicationConfiguration.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/RepositoryApplicationConfiguration.java @@ -154,7 +154,7 @@ import org.eclipse.hawkbit.repository.model.TargetFilterQuery; import org.eclipse.hawkbit.repository.model.TargetType; import org.eclipse.hawkbit.repository.model.helper.SystemSecurityContextHolder; import org.eclipse.hawkbit.repository.model.helper.TenantConfigurationManagementHolder; -import org.eclipse.hawkbit.repository.jpa.rsql.RsqlConfigHolder; +import org.eclipse.hawkbit.repository.jpa.rsql.RsqlUtility; import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer; import org.eclipse.hawkbit.security.HawkbitSecurityProperties; import org.eclipse.hawkbit.security.SecurityTokenGenerator; @@ -538,15 +538,13 @@ public class RepositoryApplicationConfiguration { final TargetRepository targetRepository, final TargetFilterQueryRepository targetFilterQueryRepository, final ActionRepository actionRepository, final SystemSecurityContext systemSecurityContext, final TenantConfigurationManagement tenantConfigurationManagement, - final VirtualPropertyReplacer virtualPropertyReplacer, final SoftwareModuleRepository softwareModuleRepository, - final DistributionSetTagRepository distributionSetTagRepository, - final JpaProperties properties, final RepositoryProperties repositoryProperties) { + final SoftwareModuleRepository softwareModuleRepository, + final DistributionSetTagRepository distributionSetTagRepository, final RepositoryProperties repositoryProperties) { return new JpaDistributionSetManagement(entityManager, distributionSetRepository, distributionSetTagManagement, systemManagement, distributionSetTypeManagement, quotaManagement, targetRepository, targetFilterQueryRepository, actionRepository, TenantConfigHelper.usingContext(systemSecurityContext, tenantConfigurationManagement), - virtualPropertyReplacer, softwareModuleRepository, distributionSetTagRepository, - properties.getDatabase(), repositoryProperties); + softwareModuleRepository, distributionSetTagRepository, repositoryProperties); } /** @@ -560,11 +558,9 @@ public class RepositoryApplicationConfiguration { final DistributionSetTypeRepository distributionSetTypeRepository, final SoftwareModuleTypeRepository softwareModuleTypeRepository, final DistributionSetRepository distributionSetRepository, final TargetTypeRepository targetTypeRepository, - final VirtualPropertyReplacer virtualPropertyReplacer, final JpaProperties properties, final QuotaManagement quotaManagement) { return new JpaDistributionSetTypeManagement(distributionSetTypeRepository, softwareModuleTypeRepository, - distributionSetRepository, targetTypeRepository, virtualPropertyReplacer, properties.getDatabase(), - quotaManagement); + distributionSetRepository, targetTypeRepository, quotaManagement); } /** @@ -576,10 +572,8 @@ public class RepositoryApplicationConfiguration { @ConditionalOnMissingBean TargetTypeManagement targetTypeManagement(final TargetTypeRepository targetTypeRepository, final TargetRepository targetRepository, final DistributionSetTypeRepository distributionSetTypeRepository, - final VirtualPropertyReplacer virtualPropertyReplacer, final JpaProperties properties, final QuotaManagement quotaManagement) { - return new JpaTargetTypeManagement(targetTypeRepository, targetRepository, distributionSetTypeRepository, - virtualPropertyReplacer, properties.getDatabase(), quotaManagement); + return new JpaTargetTypeManagement(targetTypeRepository, targetRepository, distributionSetTypeRepository, quotaManagement); } /** @@ -618,18 +612,16 @@ public class RepositoryApplicationConfiguration { */ @Bean @ConditionalOnMissingBean - TargetManagement targetManagement(final EntityManager entityManager, final QuotaManagement quotaManagement, + TargetManagement targetManagement( + final EntityManager entityManager, final QuotaManagement quotaManagement, final TargetRepository targetRepository, final RolloutGroupRepository rolloutGroupRepository, final TargetFilterQueryRepository targetFilterQueryRepository, final TargetTypeRepository targetTypeRepository, final TargetTagRepository targetTagRepository, - final TenantAware tenantAware, - final VirtualPropertyReplacer virtualPropertyReplacer, - final JpaProperties properties, final DistributionSetManagement distributionSetManagement) { + final TenantAware tenantAware, final DistributionSetManagement distributionSetManagement) { return new JpaTargetManagement(entityManager, distributionSetManagement, quotaManagement, targetRepository, targetTypeRepository, rolloutGroupRepository, targetFilterQueryRepository, - targetTagRepository, tenantAware, virtualPropertyReplacer, - properties.getDatabase()); + targetTagRepository, tenantAware); } /** @@ -637,25 +629,20 @@ public class RepositoryApplicationConfiguration { * * @param targetFilterQueryRepository holding {@link TargetFilterQuery} entities * @param targetManagement managing {@link Target} entities - * @param virtualPropertyReplacer for RSQL handling * @param distributionSetManagement for auto assign DS access * @param quotaManagement to access quotas - * @param properties JPA properties * @return a new {@link TargetFilterQueryManagement} */ @Bean @ConditionalOnMissingBean TargetFilterQueryManagement targetFilterQueryManagement( final TargetFilterQueryRepository targetFilterQueryRepository, final TargetManagement targetManagement, - final VirtualPropertyReplacer virtualPropertyReplacer, final DistributionSetManagement distributionSetManagement, final QuotaManagement quotaManagement, - final JpaProperties properties, final TenantConfigurationManagement tenantConfigurationManagement, - final RepositoryProperties repositoryProperties, - final SystemSecurityContext systemSecurityContext, final ContextAware contextAware, final AuditorAware auditorAware, - final EntityManager entityManager) { + final TenantConfigurationManagement tenantConfigurationManagement, final RepositoryProperties repositoryProperties, + final SystemSecurityContext systemSecurityContext, final ContextAware contextAware, final AuditorAware auditorAware) { return new JpaTargetFilterQueryManagement(targetFilterQueryRepository, targetManagement, - virtualPropertyReplacer, distributionSetManagement, quotaManagement, properties.getDatabase(), - tenantConfigurationManagement, repositoryProperties, systemSecurityContext, contextAware, auditorAware, entityManager); + distributionSetManagement, quotaManagement, tenantConfigurationManagement, repositoryProperties, + systemSecurityContext, contextAware, auditorAware); } /** @@ -665,11 +652,8 @@ public class RepositoryApplicationConfiguration { */ @Bean @ConditionalOnMissingBean - TargetTagManagement targetTagManagement(final TargetTagRepository targetTagRepository, - final VirtualPropertyReplacer virtualPropertyReplacer, - final JpaProperties properties) { - return new JpaTargetTagManagement(targetTagRepository, virtualPropertyReplacer, - properties.getDatabase()); + TargetTagManagement targetTagManagement(final TargetTagRepository targetTagRepository) { + return new JpaTargetTagManagement(targetTagRepository); } /** @@ -681,10 +665,9 @@ public class RepositoryApplicationConfiguration { @ConditionalOnMissingBean DistributionSetTagManagement distributionSetTagManagement( final DistributionSetTagRepository distributionSetTagRepository, - final DistributionSetRepository distributionSetRepository, - final VirtualPropertyReplacer virtualPropertyReplacer, final JpaProperties properties) { + final DistributionSetRepository distributionSetRepository) { return new JpaDistributionSetTagManagement( - distributionSetTagRepository, distributionSetRepository, virtualPropertyReplacer, properties.getDatabase()); + distributionSetTagRepository, distributionSetRepository); } /** @@ -699,13 +682,9 @@ public class RepositoryApplicationConfiguration { final SoftwareModuleRepository softwareModuleRepository, final SoftwareModuleMetadataRepository softwareModuleMetadataRepository, final SoftwareModuleTypeRepository softwareModuleTypeRepository, final AuditorAware auditorProvider, - final ArtifactManagement artifactManagement, final QuotaManagement quotaManagement, - final VirtualPropertyReplacer virtualPropertyReplacer, - final JpaProperties properties) { + final ArtifactManagement artifactManagement, final QuotaManagement quotaManagement) { return new JpaSoftwareModuleManagement(entityManager, distributionSetRepository, softwareModuleRepository, - softwareModuleMetadataRepository, softwareModuleTypeRepository, auditorProvider, artifactManagement, - quotaManagement, virtualPropertyReplacer, - properties.getDatabase()); + softwareModuleMetadataRepository, softwareModuleTypeRepository, auditorProvider, artifactManagement, quotaManagement); } /** @@ -718,11 +697,8 @@ public class RepositoryApplicationConfiguration { SoftwareModuleTypeManagement softwareModuleTypeManagement( final DistributionSetTypeRepository distributionSetTypeRepository, final SoftwareModuleTypeRepository softwareModuleTypeRepository, - final VirtualPropertyReplacer virtualPropertyReplacer, - final SoftwareModuleRepository softwareModuleRepository, - final JpaProperties properties) { - return new JpaSoftwareModuleTypeManagement(distributionSetTypeRepository, softwareModuleTypeRepository, - virtualPropertyReplacer, softwareModuleRepository, properties.getDatabase()); + final SoftwareModuleRepository softwareModuleRepository) { + return new JpaSoftwareModuleTypeManagement(distributionSetTypeRepository, softwareModuleTypeRepository, softwareModuleRepository); } @Bean @@ -765,14 +741,12 @@ public class RepositoryApplicationConfiguration { final TenantConfigurationManagement tenantConfigurationManagement, final QuotaManagement quotaManagement, final AfterTransactionCommitExecutor afterCommit, - final VirtualPropertyReplacer virtualPropertyReplacer, - final SystemSecurityContext systemSecurityContext, final ContextAware contextAware, final JpaProperties properties, + final SystemSecurityContext systemSecurityContext, final ContextAware contextAware, final RepositoryProperties repositoryProperties) { return new JpaRolloutManagement(rolloutRepository, rolloutGroupRepository, rolloutApprovalStrategy, startNextRolloutGroupAction, rolloutStatusCache, actionRepository, targetManagement, distributionSetManagement, tenantConfigurationManagement, quotaManagement, afterCommit, - virtualPropertyReplacer, systemSecurityContext, contextAware, properties.getDatabase(), - repositoryProperties); + systemSecurityContext, contextAware, repositoryProperties); } /** @@ -798,11 +772,9 @@ public class RepositoryApplicationConfiguration { @ConditionalOnMissingBean RolloutGroupManagement rolloutGroupManagement(final RolloutGroupRepository rolloutGroupRepository, final RolloutRepository rolloutRepository, final ActionRepository actionRepository, - final TargetRepository targetRepository, final EntityManager entityManager, - final VirtualPropertyReplacer virtualPropertyReplacer, final RolloutStatusCache rolloutStatusCache, - final JpaProperties properties) { + final TargetRepository targetRepository, final EntityManager entityManager, final RolloutStatusCache rolloutStatusCache) { return new JpaRolloutGroupManagement(rolloutGroupRepository, rolloutRepository, actionRepository, - targetRepository, entityManager, virtualPropertyReplacer, rolloutStatusCache, properties.getDatabase()); + targetRepository, entityManager, rolloutStatusCache); } /** @@ -816,14 +788,13 @@ public class RepositoryApplicationConfiguration { final ActionRepository actionRepository, final DistributionSetManagement distributionSetManagement, final TargetRepository targetRepository, final ActionStatusRepository actionStatusRepository, final AuditorAware auditorProvider, - final AfterTransactionCommitExecutor afterCommit, - final VirtualPropertyReplacer virtualPropertyReplacer, final PlatformTransactionManager txManager, + final AfterTransactionCommitExecutor afterCommit, final PlatformTransactionManager txManager, final TenantConfigurationManagement tenantConfigurationManagement, final QuotaManagement quotaManagement, final SystemSecurityContext systemSecurityContext, final TenantAware tenantAware, final AuditorAware auditorAware, final JpaProperties properties, final RepositoryProperties repositoryProperties) { return new JpaDeploymentManagement(entityManager, actionRepository, distributionSetManagement, targetRepository, actionStatusRepository, auditorProvider, - afterCommit, virtualPropertyReplacer, txManager, tenantConfigurationManagement, + afterCommit, txManager, tenantConfigurationManagement, quotaManagement, systemSecurityContext, tenantAware, auditorAware, properties.getDatabase(), repositoryProperties); } @@ -1010,13 +981,13 @@ public class RepositoryApplicationConfiguration { } /** - * Obtains the {@link RsqlConfigHolder} bean. + * Register the {@link RsqlUtility} bean to force Spring to inject values and auto-wired fields. * - * @return The {@link RsqlConfigHolder} singleton. + * @return The {@link RsqlUtility} singleton. */ @Bean - RsqlConfigHolder rsqlConfigHolder() { - return RsqlConfigHolder.getInstance(); + RsqlUtility rsqlUtility() { + return RsqlUtility.getInstance(); } /** diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaDeploymentManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaDeploymentManagement.java index 9401c119f..4bf2c8054 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaDeploymentManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaDeploymentManagement.java @@ -86,7 +86,6 @@ import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.repository.model.TargetType; import org.eclipse.hawkbit.repository.model.TargetUpdateStatus; import org.eclipse.hawkbit.repository.model.TargetWithActionType; -import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer; import org.eclipse.hawkbit.security.SystemSecurityContext; import org.eclipse.hawkbit.tenancy.TenantAware; import org.eclipse.hawkbit.utils.TenantConfigHelper; @@ -150,7 +149,6 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl private final DistributionSetManagement distributionSetManagement; private final TargetRepository targetRepository; private final AuditorAware auditorProvider; - private final VirtualPropertyReplacer virtualPropertyReplacer; private final PlatformTransactionManager txManager; private final OnlineDsAssignmentStrategy onlineDsAssignmentStrategy; private final OfflineDsAssignmentStrategy offlineDsAssignmentStrategy; @@ -166,8 +164,7 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl final EntityManager entityManager, final ActionRepository actionRepository, final DistributionSetManagement distributionSetManagement, final TargetRepository targetRepository, final ActionStatusRepository actionStatusRepository, final AuditorAware auditorProvider, - final AfterTransactionCommitExecutor afterCommit, - final VirtualPropertyReplacer virtualPropertyReplacer, final PlatformTransactionManager txManager, + final AfterTransactionCommitExecutor afterCommit, final PlatformTransactionManager txManager, final TenantConfigurationManagement tenantConfigurationManagement, final QuotaManagement quotaManagement, final SystemSecurityContext systemSecurityContext, final TenantAware tenantAware, final AuditorAware auditorAware, final Database database, final RepositoryProperties repositoryProperties) { @@ -176,7 +173,6 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl this.distributionSetManagement = distributionSetManagement; this.targetRepository = targetRepository; this.auditorProvider = auditorProvider; - this.virtualPropertyReplacer = virtualPropertyReplacer; this.txManager = txManager; onlineDsAssignmentStrategy = new OnlineDsAssignmentStrategy(targetRepository, afterCommit, actionRepository, actionStatusRepository, quotaManagement, this::isMultiAssignmentsEnabled, @@ -274,7 +270,7 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl assertTargetReadAllowed(controllerId); final List> specList = Arrays.asList( - RsqlUtility.buildRsqlSpecification(rsql, ActionFields.class, virtualPropertyReplacer, database), + RsqlUtility.getInstance().buildRsqlSpecification(rsql, ActionFields.class), ActionSpecifications.byTargetControllerId(controllerId)); return JpaManagementHelper.countBySpec(actionRepository, specList); @@ -287,8 +283,7 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl @Override public long countActions(final String rsql) { - final List> specList = List.of( - RsqlUtility.buildRsqlSpecification(rsql, ActionFields.class, virtualPropertyReplacer, database)); + final List> specList = List.of(RsqlUtility.getInstance().buildRsqlSpecification(rsql, ActionFields.class)); return JpaManagementHelper.countBySpec(actionRepository, specList); } @@ -312,8 +307,7 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl @Override public Slice findActions(final String rsql, final Pageable pageable) { - final List> specList = List.of( - RsqlUtility.buildRsqlSpecification(rsql, ActionFields.class, virtualPropertyReplacer, database)); + final List> specList = List.of(RsqlUtility.getInstance().buildRsqlSpecification(rsql, ActionFields.class)); return JpaManagementHelper.findAllWithoutCountBySpec(actionRepository, specList, pageable); } @@ -322,7 +316,7 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl assertTargetReadAllowed(controllerId); final List> specList = Arrays.asList( - RsqlUtility.buildRsqlSpecification(rsql, ActionFields.class, virtualPropertyReplacer, database), + RsqlUtility.getInstance().buildRsqlSpecification(rsql, ActionFields.class), ActionSpecifications.byTargetControllerId(controllerId)); return JpaManagementHelper.findAllWithCountBySpec(actionRepository, specList, pageable); diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaDistributionSetManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaDistributionSetManagement.java index 63ecf112e..8dd1a4fd1 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaDistributionSetManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaDistributionSetManagement.java @@ -73,14 +73,12 @@ import org.eclipse.hawkbit.repository.model.DistributionSetTag; import org.eclipse.hawkbit.repository.model.DistributionSetType; import org.eclipse.hawkbit.repository.model.SoftwareModule; import org.eclipse.hawkbit.repository.model.Statistic; -import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer; import org.eclipse.hawkbit.utils.TenantConfigHelper; import org.springframework.dao.ConcurrencyFailureException; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Slice; import org.springframework.data.jpa.domain.Specification; -import org.springframework.orm.jpa.vendor.Database; import org.springframework.retry.annotation.Backoff; import org.springframework.retry.annotation.Retryable; import org.springframework.transaction.annotation.Transactional; @@ -105,10 +103,8 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { private final TargetFilterQueryRepository targetFilterQueryRepository; private final ActionRepository actionRepository; private final TenantConfigHelper tenantConfigHelper; - private final VirtualPropertyReplacer virtualPropertyReplacer; private final SoftwareModuleRepository softwareModuleRepository; private final DistributionSetTagRepository distributionSetTagRepository; - private final Database database; private final RepositoryProperties repositoryProperties; @SuppressWarnings("java:S107") @@ -120,10 +116,8 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { final TargetRepository targetRepository, final TargetFilterQueryRepository targetFilterQueryRepository, final ActionRepository actionRepository, final TenantConfigHelper tenantConfigHelper, - final VirtualPropertyReplacer virtualPropertyReplacer, final SoftwareModuleRepository softwareModuleRepository, final DistributionSetTagRepository distributionSetTagRepository, - final Database database, final RepositoryProperties repositoryProperties) { this.entityManager = entityManager; this.distributionSetRepository = distributionSetRepository; @@ -135,10 +129,8 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { this.targetFilterQueryRepository = targetFilterQueryRepository; this.actionRepository = actionRepository; this.tenantConfigHelper = tenantConfigHelper; - this.virtualPropertyReplacer = virtualPropertyReplacer; this.softwareModuleRepository = softwareModuleRepository; this.distributionSetTagRepository = distributionSetTagRepository; - this.database = database; this.repositoryProperties = repositoryProperties; } @@ -282,7 +274,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { @Override public Page findByRsql(final String rsql, final Pageable pageable) { return JpaManagementHelper.findAllWithCountBySpec(distributionSetRepository, List.of( - RsqlUtility.buildRsqlSpecification(rsql, DistributionSetFields.class, virtualPropertyReplacer, database), + RsqlUtility.getInstance().buildRsqlSpecification(rsql, DistributionSetFields.class), DistributionSetSpecification.isNotDeleted()), pageable); } @@ -551,8 +543,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { assertDsTagExists(tagId); return JpaManagementHelper.findAllWithCountBySpec(distributionSetRepository, List.of( - RsqlUtility.buildRsqlSpecification(rsql, DistributionSetFields.class, virtualPropertyReplacer, - database), + RsqlUtility.getInstance().buildRsqlSpecification(rsql, DistributionSetFields.class), DistributionSetSpecification.hasTag(tagId), DistributionSetSpecification.isNotDeleted()), pageable); } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaDistributionSetTagManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaDistributionSetTagManagement.java index 316c5a66d..c3533812c 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaDistributionSetTagManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaDistributionSetTagManagement.java @@ -33,13 +33,11 @@ import org.eclipse.hawkbit.repository.jpa.specifications.DistributionSetTagSpeci import org.eclipse.hawkbit.repository.jpa.specifications.TagSpecification; import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.DistributionSetTag; -import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer; import org.springframework.dao.ConcurrencyFailureException; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Slice; import org.springframework.data.jpa.domain.Specification; -import org.springframework.orm.jpa.vendor.Database; import org.springframework.retry.annotation.Backoff; import org.springframework.retry.annotation.Retryable; import org.springframework.transaction.annotation.Transactional; @@ -54,17 +52,12 @@ public class JpaDistributionSetTagManagement implements DistributionSetTagManage private final DistributionSetTagRepository distributionSetTagRepository; private final DistributionSetRepository distributionSetRepository; - private final VirtualPropertyReplacer virtualPropertyReplacer; - private final Database database; public JpaDistributionSetTagManagement( final DistributionSetTagRepository distributionSetTagRepository, - final DistributionSetRepository distributionSetRepository, - final VirtualPropertyReplacer virtualPropertyReplacer, final Database database) { + final DistributionSetRepository distributionSetRepository) { this.distributionSetTagRepository = distributionSetTagRepository; this.distributionSetRepository = distributionSetRepository; - this.virtualPropertyReplacer = virtualPropertyReplacer; - this.database = database; } @Override @@ -155,8 +148,7 @@ public class JpaDistributionSetTagManagement implements DistributionSetTagManage @Override public Page findByRsql(final String rsql, final Pageable pageable) { - final Specification spec = RsqlUtility.buildRsqlSpecification( - rsql, DistributionSetTagFields.class, virtualPropertyReplacer, database); + final Specification spec = RsqlUtility.getInstance().buildRsqlSpecification(rsql, DistributionSetTagFields.class); return JpaManagementHelper.findAllWithCountBySpec(distributionSetTagRepository, Collections.singletonList(spec), pageable); } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaDistributionSetTypeManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaDistributionSetTypeManagement.java index 1274cd16a..40cdc4154 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaDistributionSetTypeManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaDistributionSetTypeManagement.java @@ -44,12 +44,10 @@ import org.eclipse.hawkbit.repository.jpa.specifications.DistributionSetTypeSpec import org.eclipse.hawkbit.repository.jpa.utils.QuotaHelper; import org.eclipse.hawkbit.repository.model.DistributionSetType; import org.eclipse.hawkbit.repository.model.SoftwareModuleType; -import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer; import org.springframework.dao.ConcurrencyFailureException; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Slice; -import org.springframework.orm.jpa.vendor.Database; import org.springframework.retry.annotation.Backoff; import org.springframework.retry.annotation.Retryable; import org.springframework.transaction.annotation.Transactional; @@ -67,22 +65,17 @@ public class JpaDistributionSetTypeManagement implements DistributionSetTypeMana private final SoftwareModuleTypeRepository softwareModuleTypeRepository; private final DistributionSetRepository distributionSetRepository; private final TargetTypeRepository targetTypeRepository; - private final VirtualPropertyReplacer virtualPropertyReplacer; - private final Database database; private final QuotaManagement quotaManagement; public JpaDistributionSetTypeManagement( final DistributionSetTypeRepository distributionSetTypeRepository, final SoftwareModuleTypeRepository softwareModuleTypeRepository, final DistributionSetRepository distributionSetRepository, final TargetTypeRepository targetTypeRepository, - final VirtualPropertyReplacer virtualPropertyReplacer, final Database database, final QuotaManagement quotaManagement) { this.distributionSetTypeRepository = distributionSetTypeRepository; this.softwareModuleTypeRepository = softwareModuleTypeRepository; this.distributionSetRepository = distributionSetRepository; this.targetTypeRepository = targetTypeRepository; - this.virtualPropertyReplacer = virtualPropertyReplacer; - this.database = database; this.quotaManagement = quotaManagement; } @@ -198,7 +191,7 @@ public class JpaDistributionSetTypeManagement implements DistributionSetTypeMana @Override public Page findByRsql(final String rsql, final Pageable pageable) { return JpaManagementHelper.findAllWithCountBySpec(distributionSetTypeRepository, List.of( - RsqlUtility.buildRsqlSpecification(rsql, DistributionSetTypeFields.class, virtualPropertyReplacer, database), + RsqlUtility.getInstance().buildRsqlSpecification(rsql, DistributionSetTypeFields.class), DistributionSetTypeSpecification.isNotDeleted()), pageable); } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaRolloutGroupManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaRolloutGroupManagement.java index 36738d8e8..b95e70018 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaRolloutGroupManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaRolloutGroupManagement.java @@ -48,12 +48,10 @@ import org.eclipse.hawkbit.repository.model.RolloutGroup; import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.repository.model.TotalTargetCountActionStatus; import org.eclipse.hawkbit.repository.model.TotalTargetCountStatus; -import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.domain.Specification; -import org.springframework.orm.jpa.vendor.Database; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; import org.springframework.validation.annotation.Validated; @@ -70,24 +68,18 @@ public class JpaRolloutGroupManagement implements RolloutGroupManagement { private final ActionRepository actionRepository; private final TargetRepository targetRepository; private final EntityManager entityManager; - private final VirtualPropertyReplacer virtualPropertyReplacer; private final RolloutStatusCache rolloutStatusCache; - private final Database database; @SuppressWarnings("java:S107") public JpaRolloutGroupManagement(final RolloutGroupRepository rolloutGroupRepository, final RolloutRepository rolloutRepository, final ActionRepository actionRepository, - final TargetRepository targetRepository, final EntityManager entityManager, - final VirtualPropertyReplacer virtualPropertyReplacer, final RolloutStatusCache rolloutStatusCache, - final Database database) { + final TargetRepository targetRepository, final EntityManager entityManager, final RolloutStatusCache rolloutStatusCache) { this.rolloutGroupRepository = rolloutGroupRepository; this.rolloutRepository = rolloutRepository; this.actionRepository = actionRepository; this.targetRepository = targetRepository; this.entityManager = entityManager; - this.virtualPropertyReplacer = virtualPropertyReplacer; this.rolloutStatusCache = rolloutStatusCache; - this.database = database; } @Override @@ -122,8 +114,7 @@ public class JpaRolloutGroupManagement implements RolloutGroupManagement { throwEntityNotFoundExceptionIfRolloutDoesNotExist(rolloutId); final List> specList = Arrays.asList( - RsqlUtility.buildRsqlSpecification(rsql, RolloutGroupFields.class, virtualPropertyReplacer, - database), + RsqlUtility.getInstance().buildRsqlSpecification(rsql, RolloutGroupFields.class), (root, query, cb) -> cb.equal(root.get(JpaRolloutGroup_.rollout).get(AbstractJpaBaseEntity_.id), rolloutId)); return JpaManagementHelper.findAllWithCountBySpec(rolloutGroupRepository, specList, pageable); @@ -189,7 +180,7 @@ public class JpaRolloutGroupManagement implements RolloutGroupManagement { throwExceptionIfRolloutGroupDoesNotExist(rolloutGroupId); final List> specList = Arrays.asList( - RsqlUtility.buildRsqlSpecification(rsql, TargetFields.class, virtualPropertyReplacer, database), + RsqlUtility.getInstance().buildRsqlSpecification(rsql, TargetFields.class), (root, query, cb) -> { final ListJoin rolloutTargetJoin = root.join(JpaTarget_.rolloutTargetGroup); return cb.equal(rolloutTargetJoin.get(RolloutTargetGroup_.rolloutGroup).get(AbstractJpaBaseEntity_.id), rolloutGroupId); diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaRolloutManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaRolloutManagement.java index 7bf632abf..0633d929a 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaRolloutManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaRolloutManagement.java @@ -78,7 +78,6 @@ import org.eclipse.hawkbit.repository.model.RolloutGroupsValidation; import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.repository.model.TotalTargetCountActionStatus; import org.eclipse.hawkbit.repository.model.TotalTargetCountStatus; -import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer; import org.eclipse.hawkbit.security.SystemSecurityContext; import org.springframework.dao.ConcurrencyFailureException; import org.springframework.data.domain.Page; @@ -86,7 +85,6 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort.Direction; import org.springframework.data.jpa.domain.Specification; -import org.springframework.orm.jpa.vendor.Database; import org.springframework.retry.annotation.Backoff; import org.springframework.retry.annotation.Retryable; import org.springframework.scheduling.annotation.Async; @@ -120,10 +118,8 @@ public class JpaRolloutManagement implements RolloutManagement { private final TenantConfigurationManagement tenantConfigurationManagement; private final QuotaManagement quotaManagement; private final AfterTransactionCommitExecutor afterCommit; - private final VirtualPropertyReplacer virtualPropertyReplacer; private final SystemSecurityContext systemSecurityContext; private final ContextAware contextAware; - private final Database database; private final RepositoryProperties repositoryProperties; @SuppressWarnings("java:S107") @@ -139,8 +135,7 @@ public class JpaRolloutManagement implements RolloutManagement { final TenantConfigurationManagement tenantConfigurationManagement, final QuotaManagement quotaManagement, final AfterTransactionCommitExecutor afterCommit, - final VirtualPropertyReplacer virtualPropertyReplacer, - final SystemSecurityContext systemSecurityContext, final ContextAware contextAware, final Database database, + final SystemSecurityContext systemSecurityContext, final ContextAware contextAware, final RepositoryProperties repositoryProperties) { this.rolloutRepository = rolloutRepository; this.rolloutGroupRepository = rolloutGroupRepository; @@ -153,10 +148,8 @@ public class JpaRolloutManagement implements RolloutManagement { this.tenantConfigurationManagement = tenantConfigurationManagement; this.quotaManagement = quotaManagement; this.afterCommit = afterCommit; - this.virtualPropertyReplacer = virtualPropertyReplacer; this.systemSecurityContext = systemSecurityContext; this.contextAware = contextAware; - this.database = database; this.repositoryProperties = repositoryProperties; } @@ -273,7 +266,7 @@ public class JpaRolloutManagement implements RolloutManagement { @Override public Page findByRsql(final String rsql, final boolean deleted, final Pageable pageable) { final List> specList = List.of( - RsqlUtility.buildRsqlSpecification(rsql, RolloutFields.class, virtualPropertyReplacer, database), + RsqlUtility.getInstance().buildRsqlSpecification(rsql, RolloutFields.class), RolloutSpecification.isDeleted(deleted, pageable.getSort())); return JpaManagementHelper.convertPage(rolloutRepository.findAll(JpaManagementHelper.combineWithAnd(specList), pageable), pageable); } @@ -281,7 +274,7 @@ public class JpaRolloutManagement implements RolloutManagement { @Override public Page findByRsqlWithDetailedStatus(final String rsql, final boolean deleted, final Pageable pageable) { final List> specList = List.of( - RsqlUtility.buildRsqlSpecification(rsql, RolloutFields.class, virtualPropertyReplacer, database), + RsqlUtility.getInstance().buildRsqlSpecification(rsql, RolloutFields.class), RolloutSpecification.isDeleted(deleted, pageable.getSort())); return appendStatusDetails(JpaManagementHelper.convertPage( rolloutRepository.findAll(JpaManagementHelper.combineWithAnd(specList), JpaRollout_.GRAPH_ROLLOUT_DS, pageable), pageable)); diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaSoftwareModuleManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaSoftwareModuleManagement.java index 528438ff5..6a178ab7b 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaSoftwareModuleManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaSoftwareModuleManagement.java @@ -58,7 +58,6 @@ import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.SoftwareModule; import org.eclipse.hawkbit.repository.model.SoftwareModuleMetadata; import org.eclipse.hawkbit.repository.model.SoftwareModuleType; -import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer; import org.springframework.dao.ConcurrencyFailureException; import org.springframework.data.domain.AuditorAware; import org.springframework.data.domain.Page; @@ -66,7 +65,6 @@ import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Slice; import org.springframework.data.jpa.domain.Specification; -import org.springframework.orm.jpa.vendor.Database; import org.springframework.retry.annotation.Backoff; import org.springframework.retry.annotation.Retryable; import org.springframework.transaction.annotation.Transactional; @@ -89,8 +87,6 @@ public class JpaSoftwareModuleManagement implements SoftwareModuleManagement { private final AuditorAware auditorProvider; private final ArtifactManagement artifactManagement; private final QuotaManagement quotaManagement; - private final VirtualPropertyReplacer virtualPropertyReplacer; - private final Database database; @SuppressWarnings("java:S107") public JpaSoftwareModuleManagement(final EntityManager entityManager, @@ -98,9 +94,7 @@ public class JpaSoftwareModuleManagement implements SoftwareModuleManagement { final SoftwareModuleRepository softwareModuleRepository, final SoftwareModuleMetadataRepository softwareModuleMetadataRepository, final SoftwareModuleTypeRepository softwareModuleTypeRepository, final AuditorAware auditorProvider, - final ArtifactManagement artifactManagement, final QuotaManagement quotaManagement, - final VirtualPropertyReplacer virtualPropertyReplacer, - final Database database) { + final ArtifactManagement artifactManagement, final QuotaManagement quotaManagement) { this.entityManager = entityManager; this.distributionSetRepository = distributionSetRepository; this.softwareModuleRepository = softwareModuleRepository; @@ -109,8 +103,6 @@ public class JpaSoftwareModuleManagement implements SoftwareModuleManagement { this.auditorProvider = auditorProvider; this.artifactManagement = artifactManagement; this.quotaManagement = quotaManagement; - this.virtualPropertyReplacer = virtualPropertyReplacer; - this.database = database; } @Override @@ -261,8 +253,7 @@ public class JpaSoftwareModuleManagement implements SoftwareModuleManagement { @Override public Page findByRsql(final String rsql, final Pageable pageable) { return JpaManagementHelper.findAllWithCountBySpec(softwareModuleRepository, List.of( - RsqlUtility.buildRsqlSpecification(rsql, SoftwareModuleFields.class, virtualPropertyReplacer, - database), + RsqlUtility.getInstance().buildRsqlSpecification(rsql, SoftwareModuleFields.class), SoftwareModuleSpecification.isNotDeleted()), pageable); } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaSoftwareModuleTypeManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaSoftwareModuleTypeManagement.java index d9feb1dba..9acb5fbad 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaSoftwareModuleTypeManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaSoftwareModuleTypeManagement.java @@ -31,12 +31,10 @@ import org.eclipse.hawkbit.repository.jpa.repository.SoftwareModuleTypeRepositor import org.eclipse.hawkbit.repository.jpa.rsql.RsqlUtility; import org.eclipse.hawkbit.repository.jpa.specifications.SoftwareModuleTypeSpecification; import org.eclipse.hawkbit.repository.model.SoftwareModuleType; -import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer; import org.springframework.dao.ConcurrencyFailureException; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Slice; -import org.springframework.orm.jpa.vendor.Database; import org.springframework.retry.annotation.Backoff; import org.springframework.retry.annotation.Retryable; import org.springframework.transaction.annotation.Transactional; @@ -51,20 +49,15 @@ public class JpaSoftwareModuleTypeManagement implements SoftwareModuleTypeManage private final DistributionSetTypeRepository distributionSetTypeRepository; private final SoftwareModuleTypeRepository softwareModuleTypeRepository; - private final VirtualPropertyReplacer virtualPropertyReplacer; private final SoftwareModuleRepository softwareModuleRepository; - private final Database database; - public JpaSoftwareModuleTypeManagement(final DistributionSetTypeRepository distributionSetTypeRepository, + public JpaSoftwareModuleTypeManagement( + final DistributionSetTypeRepository distributionSetTypeRepository, final SoftwareModuleTypeRepository softwareModuleTypeRepository, - final VirtualPropertyReplacer virtualPropertyReplacer, - final SoftwareModuleRepository softwareModuleRepository, - final Database database) { + final SoftwareModuleRepository softwareModuleRepository) { this.distributionSetTypeRepository = distributionSetTypeRepository; this.softwareModuleTypeRepository = softwareModuleTypeRepository; - this.virtualPropertyReplacer = virtualPropertyReplacer; this.softwareModuleRepository = softwareModuleRepository; - this.database = database; } @Override @@ -144,8 +137,7 @@ public class JpaSoftwareModuleTypeManagement implements SoftwareModuleTypeManage @Override public Page findByRsql(final String rsql, final Pageable pageable) { return JpaManagementHelper.findAllWithCountBySpec(softwareModuleTypeRepository, List.of( - RsqlUtility.buildRsqlSpecification(rsql, SoftwareModuleTypeFields.class, - virtualPropertyReplacer, database), + RsqlUtility.getInstance().buildRsqlSpecification(rsql, SoftwareModuleTypeFields.class), SoftwareModuleTypeSpecification.isNotDeleted()), pageable ); } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaTargetFilterQueryManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaTargetFilterQueryManagement.java index 215c746f1..4468bbab3 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaTargetFilterQueryManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaTargetFilterQueryManagement.java @@ -14,7 +14,6 @@ import java.util.Collections; import java.util.List; import java.util.Optional; -import jakarta.persistence.EntityManager; import jakarta.validation.constraints.NotNull; import cz.jirutka.rsql.parser.RSQLParserException; @@ -51,7 +50,6 @@ import org.eclipse.hawkbit.repository.model.Action.ActionType; import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.repository.model.TargetFilterQuery; -import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer; import org.eclipse.hawkbit.security.SystemSecurityContext; import org.eclipse.hawkbit.utils.TenantConfigHelper; import org.springframework.dao.ConcurrencyFailureException; @@ -60,7 +58,6 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Slice; import org.springframework.data.jpa.domain.Specification; -import org.springframework.orm.jpa.vendor.Database; import org.springframework.retry.annotation.Backoff; import org.springframework.retry.annotation.Retryable; import org.springframework.transaction.annotation.Transactional; @@ -77,7 +74,6 @@ public class JpaTargetFilterQueryManagement implements TargetFilterQueryManageme private final TargetFilterQueryRepository targetFilterQueryRepository; private final TargetManagement targetManagement; - private final VirtualPropertyReplacer virtualPropertyReplacer; private final DistributionSetManagement distributionSetManagement; private final QuotaManagement quotaManagement; private final TenantConfigurationManagement tenantConfigurationManagement; @@ -85,29 +81,23 @@ public class JpaTargetFilterQueryManagement implements TargetFilterQueryManageme private final SystemSecurityContext systemSecurityContext; private final ContextAware contextAware; private final AuditorAware auditorAware; - private final EntityManager entityManager; - private final Database database; @SuppressWarnings("java:S107") - public JpaTargetFilterQueryManagement(final TargetFilterQueryRepository targetFilterQueryRepository, - final TargetManagement targetManagement, final VirtualPropertyReplacer virtualPropertyReplacer, - final DistributionSetManagement distributionSetManagement, final QuotaManagement quotaManagement, - final Database database, final TenantConfigurationManagement tenantConfigurationManagement, + public JpaTargetFilterQueryManagement( + final TargetFilterQueryRepository targetFilterQueryRepository, + final TargetManagement targetManagement, final DistributionSetManagement distributionSetManagement, + final QuotaManagement quotaManagement, final TenantConfigurationManagement tenantConfigurationManagement, final RepositoryProperties repositoryProperties, - final SystemSecurityContext systemSecurityContext, final ContextAware contextAware, final AuditorAware auditorAware, - final EntityManager entityManager) { + final SystemSecurityContext systemSecurityContext, final ContextAware contextAware, final AuditorAware auditorAware) { this.targetFilterQueryRepository = targetFilterQueryRepository; this.targetManagement = targetManagement; - this.virtualPropertyReplacer = virtualPropertyReplacer; this.distributionSetManagement = distributionSetManagement; this.quotaManagement = quotaManagement; - this.database = database; this.tenantConfigurationManagement = tenantConfigurationManagement; this.repositoryProperties = repositoryProperties; this.systemSecurityContext = systemSecurityContext; this.contextAware = contextAware; this.auditorAware = auditorAware; - this.entityManager = entityManager; } @Override @@ -119,7 +109,7 @@ public class JpaTargetFilterQueryManagement implements TargetFilterQueryManageme create.getQuery().ifPresent(query -> { // validate the RSQL query syntax - RsqlUtility.validateRsqlFor(query, TargetFields.class, JpaTarget.class, virtualPropertyReplacer, entityManager); + RsqlUtility.getInstance().validateRsqlFor(query, TargetFields.class, JpaTarget.class); // enforce the 'max targets per auto assign' quota right here even // if the result of the filter query can vary over time @@ -148,7 +138,7 @@ public class JpaTargetFilterQueryManagement implements TargetFilterQueryManageme @Override public boolean verifyTargetFilterQuerySyntax(final String query) { try { - RsqlUtility.validateRsqlFor(query, TargetFields.class, JpaTarget.class, virtualPropertyReplacer, entityManager); + RsqlUtility.getInstance().validateRsqlFor(query, TargetFields.class, JpaTarget.class); return true; } catch (final RSQLParserException | RSQLParameterUnsupportedFieldException e) { log.debug("The RSQL query '{}}' is invalid.", query, e); @@ -195,8 +185,7 @@ public class JpaTargetFilterQueryManagement implements TargetFilterQueryManageme @Override public Page findByRsql(final String rsqlFilter, final Pageable pageable) { final List> specList = !ObjectUtils.isEmpty(rsqlFilter) - ? Collections.singletonList(RsqlUtility.buildRsqlSpecification(rsqlFilter, - TargetFilterQueryFields.class, virtualPropertyReplacer, database)) + ? Collections.singletonList(RsqlUtility.getInstance().buildRsqlSpecification(rsqlFilter, TargetFilterQueryFields.class)) : Collections.emptyList(); return JpaManagementHelper.findAllWithCountBySpec(targetFilterQueryRepository, specList, pageable); @@ -227,8 +216,7 @@ public class JpaTargetFilterQueryManagement implements TargetFilterQueryManageme final List> specList = new ArrayList<>(2); specList.add(TargetFilterQuerySpecification.byAutoAssignDS(distributionSet)); if (!ObjectUtils.isEmpty(rsql)) { - specList.add(RsqlUtility.buildRsqlSpecification(rsql, TargetFilterQueryFields.class, - virtualPropertyReplacer, database)); + specList.add(RsqlUtility.getInstance().buildRsqlSpecification(rsql, TargetFilterQueryFields.class)); } return JpaManagementHelper.findAllWithCountBySpec(targetFilterQueryRepository, specList, pageable); diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaTargetManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaTargetManagement.java index a595984b6..f58f0b2fb 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaTargetManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaTargetManagement.java @@ -74,14 +74,12 @@ import org.eclipse.hawkbit.repository.model.TargetTag; import org.eclipse.hawkbit.repository.model.TargetType; import org.eclipse.hawkbit.repository.model.TargetTypeAssignmentResult; import org.eclipse.hawkbit.repository.model.TargetUpdateStatus; -import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer; import org.eclipse.hawkbit.tenancy.TenantAware; import org.springframework.dao.ConcurrencyFailureException; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Slice; import org.springframework.data.jpa.domain.Specification; -import org.springframework.orm.jpa.vendor.Database; import org.springframework.retry.annotation.Backoff; import org.springframework.retry.annotation.Retryable; import org.springframework.transaction.annotation.Transactional; @@ -104,8 +102,6 @@ public class JpaTargetManagement implements TargetManagement { private final TargetFilterQueryRepository targetFilterQueryRepository; private final TargetTagRepository targetTagRepository; private final TenantAware tenantAware; - private final VirtualPropertyReplacer virtualPropertyReplacer; - private final Database database; @SuppressWarnings("java:S107") public JpaTargetManagement(final EntityManager entityManager, @@ -114,8 +110,7 @@ public class JpaTargetManagement implements TargetManagement { final RolloutGroupRepository rolloutGroupRepository, final TargetFilterQueryRepository targetFilterQueryRepository, final TargetTagRepository targetTagRepository, - final TenantAware tenantAware, final VirtualPropertyReplacer virtualPropertyReplacer, - final Database database) { + final TenantAware tenantAware) { this.entityManager = entityManager; this.distributionSetManagement = distributionSetManagement; this.quotaManagement = quotaManagement; @@ -125,8 +120,6 @@ public class JpaTargetManagement implements TargetManagement { this.targetFilterQueryRepository = targetFilterQueryRepository; this.targetTagRepository = targetTagRepository; this.tenantAware = tenantAware; - this.virtualPropertyReplacer = virtualPropertyReplacer; - this.database = database; } @Override @@ -157,22 +150,20 @@ public class JpaTargetManagement implements TargetManagement { public long countByRsql(final String rsql) { return JpaManagementHelper.countBySpec( targetRepository, - List.of(RsqlUtility.buildRsqlSpecification(rsql, TargetFields.class, virtualPropertyReplacer, database))); + List.of(RsqlUtility.getInstance().buildRsqlSpecification(rsql, TargetFields.class))); } @Override public long countByRsqlAndUpdatable(String rsql) { final List> specList = List.of( - RsqlUtility.buildRsqlSpecification(rsql, TargetFields.class, virtualPropertyReplacer, database)); - return targetRepository.count( - AccessController.Operation.UPDATE, - combineWithAnd(specList)); + RsqlUtility.getInstance().buildRsqlSpecification(rsql, TargetFields.class)); + return targetRepository.count(AccessController.Operation.UPDATE, combineWithAnd(specList)); } @Override public long countByRsqlAndCompatible(final String rsql, final Long distributionSetIdTypeId) { final List> specList = List.of( - RsqlUtility.buildRsqlSpecification(rsql, TargetFields.class, virtualPropertyReplacer, database), + RsqlUtility.getInstance().buildRsqlSpecification(rsql, TargetFields.class), TargetSpecifications.isCompatibleWithDistributionSetType(distributionSetIdTypeId)); return JpaManagementHelper.countBySpec(targetRepository, specList); } @@ -180,7 +171,7 @@ public class JpaTargetManagement implements TargetManagement { @Override public long countByRsqlAndCompatibleAndUpdatable(String rsql, Long distributionSetIdTypeId) { final List> specList = List.of( - RsqlUtility.buildRsqlSpecification(rsql, TargetFields.class, virtualPropertyReplacer, database), + RsqlUtility.getInstance().buildRsqlSpecification(rsql, TargetFields.class), TargetSpecifications.isCompatibleWithDistributionSetType(distributionSetIdTypeId)); return targetRepository.count(AccessController.Operation.UPDATE, combineWithAnd(specList)); } @@ -253,7 +244,7 @@ public class JpaTargetManagement implements TargetManagement { .findAllWithoutCount( AccessController.Operation.UPDATE, combineWithAnd(List.of( - RsqlUtility.buildRsqlSpecification(rsql, TargetFields.class, virtualPropertyReplacer, database), + RsqlUtility.getInstance().buildRsqlSpecification(rsql, TargetFields.class), TargetSpecifications.hasNotDistributionSetInActions(distributionSetId), TargetSpecifications.isCompatibleWithDistributionSetType(distSetTypeId))), pageable) @@ -268,8 +259,7 @@ public class JpaTargetManagement implements TargetManagement { return targetRepository.count( AccessController.Operation.UPDATE, combineWithAnd(List.of( - RsqlUtility.buildRsqlSpecification( - rsql, TargetFields.class, virtualPropertyReplacer, database), + RsqlUtility.getInstance().buildRsqlSpecification(rsql, TargetFields.class), TargetSpecifications.hasNotDistributionSetInActions(distributionSetId), TargetSpecifications.isCompatibleWithDistributionSetType(distSetTypeId)))); } @@ -280,7 +270,7 @@ public class JpaTargetManagement implements TargetManagement { return targetRepository .findAllWithoutCount(AccessController.Operation.UPDATE, combineWithAnd(List.of( - RsqlUtility.buildRsqlSpecification(rsql, TargetFields.class, virtualPropertyReplacer, database), + RsqlUtility.getInstance().buildRsqlSpecification(rsql, TargetFields.class), TargetSpecifications.isNotInRolloutGroups(groups), TargetSpecifications.isCompatibleWithDistributionSetType(dsType.getId()))), pageable) @@ -292,7 +282,7 @@ public class JpaTargetManagement implements TargetManagement { final String rsql, final Collection groups, final DistributionSetType dsType) { return targetRepository.count(AccessController.Operation.UPDATE, combineWithAnd(List.of( - RsqlUtility.buildRsqlSpecification(rsql, TargetFields.class, virtualPropertyReplacer, database), + RsqlUtility.getInstance().buildRsqlSpecification(rsql, TargetFields.class), TargetSpecifications.isNotInRolloutGroups(groups), TargetSpecifications.isCompatibleWithDistributionSetType(dsType.getId())))); } @@ -319,7 +309,7 @@ public class JpaTargetManagement implements TargetManagement { return targetRepository .findAllWithoutCount(AccessController.Operation.UPDATE, combineWithAnd(List.of( - RsqlUtility.buildRsqlSpecification(rsql, TargetFields.class, virtualPropertyReplacer, database), + RsqlUtility.getInstance().buildRsqlSpecification(rsql, TargetFields.class), TargetSpecifications.hasNoOverridingActionsAndNotInRollout(rolloutId), TargetSpecifications.isCompatibleWithDistributionSetType(distributionSetType.getId()))), pageable) @@ -355,7 +345,7 @@ public class JpaTargetManagement implements TargetManagement { final DistributionSet validDistSet = distributionSetManagement.getOrElseThrowException(distributionSetId); final List> specList = List.of( - RsqlUtility.buildRsqlSpecification(rsql, TargetFields.class, virtualPropertyReplacer, database), + RsqlUtility.getInstance().buildRsqlSpecification(rsql, TargetFields.class), TargetSpecifications.hasAssignedDistributionSet(validDistSet.getId())); return JpaManagementHelper.findAllWithCountBySpec(targetRepository, specList, pageable); @@ -395,7 +385,7 @@ public class JpaTargetManagement implements TargetManagement { final DistributionSet validDistSet = distributionSetManagement.getOrElseThrowException(distributionSetId); final List> specList = List.of( - RsqlUtility.buildRsqlSpecification(rsql, TargetFields.class, virtualPropertyReplacer, database), + RsqlUtility.getInstance().buildRsqlSpecification(rsql, TargetFields.class), TargetSpecifications.hasInstalledDistributionSet(validDistSet.getId())); return JpaManagementHelper.findAllWithCountBySpec(targetRepository, specList, pageable); @@ -416,7 +406,7 @@ public class JpaTargetManagement implements TargetManagement { public Slice findByRsql(final String rsql, final Pageable pageable) { return JpaManagementHelper.findAllWithoutCountBySpec( targetRepository, - List.of(RsqlUtility.buildRsqlSpecification(rsql, TargetFields.class, virtualPropertyReplacer, database)), pageable + List.of(RsqlUtility.getInstance().buildRsqlSpecification(rsql, TargetFields.class)), pageable ); } @@ -426,8 +416,8 @@ public class JpaTargetManagement implements TargetManagement { .orElseThrow(() -> new EntityNotFoundException(TargetFilterQuery.class, targetFilterQueryId)); return JpaManagementHelper.findAllWithoutCountBySpec( - targetRepository, List.of(RsqlUtility.buildRsqlSpecification( - targetFilterQuery.getQuery(), TargetFields.class, virtualPropertyReplacer, database)), pageable + targetRepository, List.of(RsqlUtility.getInstance().buildRsqlSpecification( + targetFilterQuery.getQuery(), TargetFields.class)), pageable ); } @@ -442,7 +432,7 @@ public class JpaTargetManagement implements TargetManagement { throwEntityNotFoundExceptionIfTagDoesNotExist(tagId); final List> specList = List.of( - RsqlUtility.buildRsqlSpecification(rsql, TargetFields.class, virtualPropertyReplacer, database), + RsqlUtility.getInstance().buildRsqlSpecification(rsql, TargetFields.class), TargetSpecifications.hasTag(tagId)); return JpaManagementHelper.findAllWithCountBySpec(targetRepository, specList, pageable); @@ -611,12 +601,12 @@ public class JpaTargetManagement implements TargetManagement { @Override public boolean isTargetMatchingQueryAndDSNotAssignedAndCompatibleAndUpdatable( final String controllerId, final long distributionSetId, final String targetFilterQuery) { - RsqlUtility.validateRsqlFor(targetFilterQuery, TargetFields.class, JpaTarget.class, virtualPropertyReplacer, entityManager); + RsqlUtility.getInstance().validateRsqlFor(targetFilterQuery, TargetFields.class, JpaTarget.class); final DistributionSet ds = distributionSetManagement.get(distributionSetId) .orElseThrow(() -> new EntityNotFoundException(DistributionSet.class, distributionSetId)); final Long distSetTypeId = ds.getType().getId(); final List> specList = List.of( - RsqlUtility.buildRsqlSpecification(targetFilterQuery, TargetFields.class, virtualPropertyReplacer, database), + RsqlUtility.getInstance().buildRsqlSpecification(targetFilterQuery, TargetFields.class), TargetSpecifications.hasNotDistributionSetInActions(distributionSetId), TargetSpecifications.isCompatibleWithDistributionSetType(distSetTypeId), TargetSpecifications.hasControllerId(controllerId)); diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaTargetTagManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaTargetTagManagement.java index 941e67fd6..8ae119f84 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaTargetTagManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaTargetTagManagement.java @@ -29,11 +29,9 @@ import org.eclipse.hawkbit.repository.jpa.model.JpaTargetTag; import org.eclipse.hawkbit.repository.jpa.repository.TargetTagRepository; import org.eclipse.hawkbit.repository.jpa.rsql.RsqlUtility; import org.eclipse.hawkbit.repository.model.TargetTag; -import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer; import org.springframework.dao.ConcurrencyFailureException; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; -import org.springframework.orm.jpa.vendor.Database; import org.springframework.retry.annotation.Backoff; import org.springframework.retry.annotation.Retryable; import org.springframework.transaction.annotation.Transactional; @@ -48,16 +46,8 @@ public class JpaTargetTagManagement implements TargetTagManagement { private final TargetTagRepository targetTagRepository; - private final VirtualPropertyReplacer virtualPropertyReplacer; - private final Database database; - - public JpaTargetTagManagement( - final TargetTagRepository targetTagRepository, - final VirtualPropertyReplacer virtualPropertyReplacer, - final Database database) { - this.targetTagRepository = targetTagRepository; - this.virtualPropertyReplacer = virtualPropertyReplacer; - this.database = database; + public JpaTargetTagManagement(final TargetTagRepository targetTagRepository) { + this.targetTagRepository = targetTagRepository;; } @Override @@ -105,7 +95,7 @@ public class JpaTargetTagManagement implements TargetTagManagement { @Override public Page findByRsql(final String rsql, final Pageable pageable) { return JpaManagementHelper.findAllWithCountBySpec(targetTagRepository, Collections.singletonList( - RsqlUtility.buildRsqlSpecification(rsql, TargetTagFields.class, virtualPropertyReplacer, database)), pageable); + RsqlUtility.getInstance().buildRsqlSpecification(rsql, TargetTagFields.class)), pageable); } @Override diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaTargetTypeManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaTargetTypeManagement.java index 41f813670..0334d2ce4 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaTargetTypeManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaTargetTypeManagement.java @@ -38,12 +38,10 @@ import org.eclipse.hawkbit.repository.jpa.specifications.TargetTypeSpecification import org.eclipse.hawkbit.repository.jpa.utils.QuotaHelper; import org.eclipse.hawkbit.repository.model.DistributionSetType; import org.eclipse.hawkbit.repository.model.TargetType; -import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer; import org.springframework.dao.ConcurrencyFailureException; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Slice; -import org.springframework.orm.jpa.vendor.Database; import org.springframework.retry.annotation.Backoff; import org.springframework.retry.annotation.Retryable; import org.springframework.transaction.annotation.Transactional; @@ -60,9 +58,6 @@ public class JpaTargetTypeManagement implements TargetTypeManagement { private final TargetRepository targetRepository; private final DistributionSetTypeRepository distributionSetTypeRepository; - private final VirtualPropertyReplacer virtualPropertyReplacer; - - private final Database database; private final QuotaManagement quotaManagement; /** @@ -70,18 +65,13 @@ public class JpaTargetTypeManagement implements TargetTypeManagement { * * @param targetTypeRepository Target type repository * @param targetRepository Target repository - * @param virtualPropertyReplacer replacer - * @param database database */ public JpaTargetTypeManagement(final TargetTypeRepository targetTypeRepository, final TargetRepository targetRepository, final DistributionSetTypeRepository distributionSetTypeRepository, - final VirtualPropertyReplacer virtualPropertyReplacer, final Database database, final QuotaManagement quotaManagement) { this.targetTypeRepository = targetTypeRepository; this.targetRepository = targetRepository; this.distributionSetTypeRepository = distributionSetTypeRepository; - this.virtualPropertyReplacer = virtualPropertyReplacer; - this.database = database; this.quotaManagement = quotaManagement; } @@ -145,10 +135,10 @@ public class JpaTargetTypeManagement implements TargetTypeManagement { @Override public Page findByRsql(final String rsql, final Pageable pageable) { - return JpaManagementHelper.findAllWithCountBySpec(targetTypeRepository, List.of( - RsqlUtility.buildRsqlSpecification( - rsql, TargetTypeFields.class, virtualPropertyReplacer, database)), pageable - ); + return JpaManagementHelper.findAllWithCountBySpec( + targetTypeRepository, + List.of(RsqlUtility.getInstance().buildRsqlSpecification(rsql, TargetTypeFields.class)), + pageable); } @Override diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/TargetManagementTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/TargetManagementTest.java index 3637dbe5f..a2106d704 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/TargetManagementTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/TargetManagementTest.java @@ -12,7 +12,7 @@ package org.eclipse.hawkbit.repository.jpa.management; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.assertj.core.api.Assertions.fail; -import static org.eclipse.hawkbit.repository.jpa.rsql.RsqlConfigHolder.RsqlToSpecBuilder.LEGACY_G1; +import static org.eclipse.hawkbit.repository.jpa.rsql.RsqlUtility.RsqlToSpecBuilder.LEGACY_G1; import java.net.URI; import java.util.ArrayList; @@ -69,7 +69,7 @@ import org.eclipse.hawkbit.repository.model.TargetTag; import org.eclipse.hawkbit.repository.model.TargetType; import org.eclipse.hawkbit.repository.model.TargetTypeAssignmentResult; import org.eclipse.hawkbit.repository.model.TargetUpdateStatus; -import org.eclipse.hawkbit.repository.jpa.rsql.RsqlConfigHolder; +import org.eclipse.hawkbit.repository.jpa.rsql.RsqlUtility; import org.eclipse.hawkbit.repository.test.matcher.Expect; import org.eclipse.hawkbit.repository.test.matcher.ExpectEvents; import org.eclipse.hawkbit.repository.test.util.SecurityContextSwitch; @@ -1091,7 +1091,7 @@ class TargetManagementTest extends AbstractJpaIntegrationTest { */ @Test void findTargetsByRsqlWithTypeAndMetadata() { - if (RsqlConfigHolder.getInstance().getRsqlToSpecBuilder() == LEGACY_G1) { + if (RsqlUtility.getInstance().getRsqlToSpecBuilder() == LEGACY_G1) { // legacy visitor fail with that return; } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RsqlTargetFieldTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RsqlTargetFieldTest.java index e720145c9..a9e7d209d 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RsqlTargetFieldTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RsqlTargetFieldTest.java @@ -11,14 +11,12 @@ package org.eclipse.hawkbit.repository.jpa.rsql; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; -import static org.eclipse.hawkbit.repository.jpa.rsql.RsqlConfigHolder.RsqlToSpecBuilder.LEGACY_G2; -import static org.eclipse.hawkbit.repository.jpa.rsql.RsqlConfigHolder.RsqlToSpecBuilder.LEGACY_G1; +import static org.eclipse.hawkbit.repository.jpa.rsql.RsqlUtility.RsqlToSpecBuilder.LEGACY_G2; +import static org.eclipse.hawkbit.repository.jpa.rsql.RsqlUtility.RsqlToSpecBuilder.LEGACY_G1; import java.util.Arrays; import java.util.Map; -import jakarta.persistence.EntityManager; - import org.eclipse.hawkbit.repository.TargetFields; import org.eclipse.hawkbit.repository.TargetTypeFields; import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException; @@ -28,11 +26,9 @@ import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.repository.model.TargetTag; import org.eclipse.hawkbit.repository.model.TargetType; -import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer; import org.eclipse.hawkbit.repository.test.util.TestdataFactory; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Slice; /** @@ -45,11 +41,6 @@ class RsqlTargetFieldTest extends AbstractJpaIntegrationTest { private static final String OR = ","; private static final String AND = ";"; - @Autowired - protected VirtualPropertyReplacer virtualPropertyReplacer; - @Autowired - protected EntityManager entityManager; - private Target target; private Target target2; private TargetType targetType1; @@ -189,7 +180,7 @@ class RsqlTargetFieldTest extends AbstractJpaIntegrationTest { assertRSQLQuery(TargetFields.ATTRIBUTE.name() + ".test.null==null", 1); // "null" check assertRSQLQuery(TargetFields.ATTRIBUTE.name() + ".test.n/a==null", 0); // "null" check - if (RsqlConfigHolder.getInstance().getRsqlToSpecBuilder() != LEGACY_G1) { + if (RsqlUtility.getInstance().getRsqlToSpecBuilder() != LEGACY_G1) { assertRSQLQuery(TargetFields.ATTRIBUTE.name() + ".test.dot=is=value.dot", 1); assertRSQLQuery(TargetFields.ATTRIBUTE.name() + ".test.null=is=null", 5); // null check assertRSQLQuery(TargetFields.ATTRIBUTE.name() + ".test.n/a=is=null", 1 + 5); // null check @@ -203,22 +194,22 @@ class RsqlTargetFieldTest extends AbstractJpaIntegrationTest { assertRSQLQuery(TargetFields.ATTRIBUTE.name() + ".test.null!=null2", 1); // value check assertRSQLQuery(TargetFields.ATTRIBUTE.name() + ".test.n/a!=null", 0); // "null" check - if (RsqlConfigHolder.getInstance().getRsqlToSpecBuilder() != LEGACY_G1) { + if (RsqlUtility.getInstance().getRsqlToSpecBuilder() != LEGACY_G1) { assertRSQLQuery( TargetFields.ATTRIBUTE.name() + ".test.dot=not=value.dot", - RsqlConfigHolder.getInstance().getRsqlToSpecBuilder() == LEGACY_G2 ? 5 : 0); + RsqlUtility.getInstance().getRsqlToSpecBuilder() == LEGACY_G2 ? 5 : 0); assertRSQLQuery(TargetFields.ATTRIBUTE.name() + ".test.null=not=null", 1); // null check assertRSQLQuery( TargetFields.ATTRIBUTE.name() + ".test.null=not=null2", - 1 + (RsqlConfigHolder.getInstance().getRsqlToSpecBuilder() == LEGACY_G2 ? 5 : 0)); // value check + 1 + (RsqlUtility.getInstance().getRsqlToSpecBuilder() == LEGACY_G2 ? 5 : 0)); // value check assertRSQLQuery(TargetFields.ATTRIBUTE.name() + ".test.n/a=not=null", 0); // null check assertRSQLQuery( TargetFields.ATTRIBUTE.name() + ".test.dot=ne=value.dot", - RsqlConfigHolder.getInstance().getRsqlToSpecBuilder() == LEGACY_G2 ? 5 : 0); + RsqlUtility.getInstance().getRsqlToSpecBuilder() == LEGACY_G2 ? 5 : 0); assertRSQLQuery(TargetFields.ATTRIBUTE.name() + ".test.null=ne=null", 1); // null check assertRSQLQuery( TargetFields.ATTRIBUTE.name() + ".test.null=ne=null2", - 1 + (RsqlConfigHolder.getInstance().getRsqlToSpecBuilder() == LEGACY_G2 ? 5 : 0)); // value check + 1 + (RsqlUtility.getInstance().getRsqlToSpecBuilder() == LEGACY_G2 ? 5 : 0)); // value check assertRSQLQuery(TargetFields.ATTRIBUTE.name() + ".test.n/a=ne=null", 0); // null check } @@ -315,7 +306,7 @@ class RsqlTargetFieldTest extends AbstractJpaIntegrationTest { assertRSQLQuery(TargetFields.METADATA.name() + ".metaKey==noExist*", 0); assertRSQLQuery(TargetFields.METADATA.name() + ".notExist==metaValue", 0); - if (RsqlConfigHolder.getInstance().getRsqlToSpecBuilder() != LEGACY_G1) { + if (RsqlUtility.getInstance().getRsqlToSpecBuilder() != LEGACY_G1) { assertRSQLQuery(TargetFields.METADATA.name() + ".metaKey=is=metaValue", 1); assertRSQLQuery(TargetFields.METADATA.name() + ".metaKey=is=null", 4); // null check (1 of the initial five has) assertRSQLQuery(TargetFields.METADATA.name() + ".metaKey=is=*v*", 2); @@ -333,27 +324,27 @@ class RsqlTargetFieldTest extends AbstractJpaIntegrationTest { assertRSQLQuery(TargetFields.METADATA.name() + ".notExist!=metaValue", 0); assertRSQLQuery(TargetFields.METADATA.name() + ".metaKey!=notExist", 2); - if (RsqlConfigHolder.getInstance().getRsqlToSpecBuilder() != LEGACY_G1) { + if (RsqlUtility.getInstance().getRsqlToSpecBuilder() != LEGACY_G1) { assertRSQLQuery( TargetFields.METADATA.name() + ".metaKey=not=metaValue", - RsqlConfigHolder.getInstance().getRsqlToSpecBuilder() == LEGACY_G2 ? 1 + 4 : 1); + RsqlUtility.getInstance().getRsqlToSpecBuilder() == LEGACY_G2 ? 1 + 4 : 1); assertRSQLQuery(TargetFields.METADATA.name() + ".metaKey=not=null", 2); // null check (2 of the initial five) assertRSQLQuery( TargetFields.METADATA.name() + ".notExist=not=metaValue", - RsqlConfigHolder.getInstance().getRsqlToSpecBuilder() == LEGACY_G2 ? 1 + 5 : 0); + RsqlUtility.getInstance().getRsqlToSpecBuilder() == LEGACY_G2 ? 1 + 5 : 0); assertRSQLQuery( TargetFields.METADATA.name() + ".metaKey=not=notExist", - RsqlConfigHolder.getInstance().getRsqlToSpecBuilder() == LEGACY_G2 ? 2 + 4 : 2); + RsqlUtility.getInstance().getRsqlToSpecBuilder() == LEGACY_G2 ? 2 + 4 : 2); assertRSQLQuery( TargetFields.METADATA.name() + ".metaKey=ne=metaValue", - RsqlConfigHolder.getInstance().getRsqlToSpecBuilder() == LEGACY_G2 ? 1 + 4 : 1); + RsqlUtility.getInstance().getRsqlToSpecBuilder() == LEGACY_G2 ? 1 + 4 : 1); assertRSQLQuery(TargetFields.METADATA.name() + ".metaKey=ne=null", 2); // null check (2 of the initial five) assertRSQLQuery( TargetFields.METADATA.name() + ".notExist=ne=metaValue", - RsqlConfigHolder.getInstance().getRsqlToSpecBuilder() == LEGACY_G2 ? 1 + 5 : 0); + RsqlUtility.getInstance().getRsqlToSpecBuilder() == LEGACY_G2 ? 1 + 5 : 0); assertRSQLQuery( TargetFields.METADATA.name() + ".metaKey=ne=notExist", - RsqlConfigHolder.getInstance().getRsqlToSpecBuilder() == LEGACY_G2 ? 2 + 4 : 2); + RsqlUtility.getInstance().getRsqlToSpecBuilder() == LEGACY_G2 ? 2 + 4 : 2); } assertRSQLQuery(TargetFields.METADATA.name() + ".metaKey=in=(metaValue,notexist)", 1); @@ -386,28 +377,26 @@ class RsqlTargetFieldTest extends AbstractJpaIntegrationTest { */ @Test void rsqlValidTargetFields() { - RsqlUtility.validateRsqlFor( + RsqlUtility.getInstance().validateRsqlFor( "ID == '0123' and NAME == abcd and DESCRIPTION == absd and CREATEDAT =lt= 0123 and LASTMODIFIEDAT =gt= 0123" + " and CONTROLLERID == 0123 and UPDATESTATUS == PENDING and IPADDRESS == 0123 and LASTCONTROLLERREQUESTAT == 0123" + " and tag == beta", - TargetFields.class, JpaTarget.class, virtualPropertyReplacer, entityManager); - RsqlUtility.validateRsqlFor( + TargetFields.class, JpaTarget.class); + RsqlUtility.getInstance().validateRsqlFor( "ASSIGNEDDS.name == abcd and ASSIGNEDDS.version == 0123 and INSTALLEDDS.name == abcd and INSTALLEDDS.version == 0123", - TargetFields.class, JpaTarget.class, virtualPropertyReplacer, entityManager); - RsqlUtility.validateRsqlFor( + TargetFields.class, JpaTarget.class); + RsqlUtility.getInstance().validateRsqlFor( "ATTRIBUTE.subkey1 == test and ATTRIBUTE.subkey2 == test and METADATA.metakey1 == abcd and METADATA.metavalue2 == asdfg", - TargetFields.class, JpaTarget.class, virtualPropertyReplacer, entityManager); - RsqlUtility.validateRsqlFor( + TargetFields.class, JpaTarget.class); + RsqlUtility.getInstance().validateRsqlFor( "CREATEDAT =lt= ${NOW_TS} and LASTMODIFIEDAT =ge= ${OVERDUE_TS}", - TargetFields.class, JpaTarget.class, virtualPropertyReplacer, entityManager); - RsqlUtility.validateRsqlFor( + TargetFields.class, JpaTarget.class); + RsqlUtility.getInstance().validateRsqlFor( "ATTRIBUTE.test.dot == test and ATTRIBUTE.subkey2 == test and METADATA.test.dot == abcd and METADATA.metavalue2 == asdfg", - TargetFields.class, JpaTarget.class, virtualPropertyReplacer, entityManager); + TargetFields.class, JpaTarget.class); assertThatExceptionOfType(RSQLParameterUnsupportedFieldException.class) - .isThrownBy(() -> RsqlUtility.validateRsqlFor( - "wrongfield == abcd", - TargetFields.class, JpaTarget.class, virtualPropertyReplacer, entityManager)); + .isThrownBy(() -> RsqlUtility.getInstance().validateRsqlFor("wrongfield == abcd", TargetFields.class, JpaTarget.class)); } /** @@ -452,7 +441,6 @@ class RsqlTargetFieldTest extends AbstractJpaIntegrationTest { private void assertRSQLQueryThrowsException(final String rsql) { assertThatExceptionOfType(RSQLParameterUnsupportedFieldException.class) - .isThrownBy(() -> RsqlUtility.validateRsqlFor( - rsql, TargetFields.class, JpaTarget.class, virtualPropertyReplacer, entityManager)); + .isThrownBy(() -> RsqlUtility.getInstance().validateRsqlFor(rsql, TargetFields.class, JpaTarget.class)); } } \ No newline at end of file diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RsqlToSqlTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RsqlToSqlTest.java index 566159167..55a7e5eca 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RsqlToSqlTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RsqlToSqlTest.java @@ -9,9 +9,9 @@ */ package org.eclipse.hawkbit.repository.jpa.rsql; -import static org.eclipse.hawkbit.repository.jpa.rsql.RsqlConfigHolder.RsqlToSpecBuilder.LEGACY_G2; -import static org.eclipse.hawkbit.repository.jpa.rsql.RsqlConfigHolder.RsqlToSpecBuilder.G3; -import static org.eclipse.hawkbit.repository.jpa.rsql.RsqlConfigHolder.RsqlToSpecBuilder.LEGACY_G1; +import static org.eclipse.hawkbit.repository.jpa.rsql.RsqlUtility.RsqlToSpecBuilder.LEGACY_G2; +import static org.eclipse.hawkbit.repository.jpa.rsql.RsqlUtility.RsqlToSpecBuilder.G3; +import static org.eclipse.hawkbit.repository.jpa.rsql.RsqlUtility.RsqlToSpecBuilder.LEGACY_G1; import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.NONE; import jakarta.persistence.EntityManager; diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RsqlUtilityTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RsqlUtilityTest.java deleted file mode 100644 index 56934960d..000000000 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RsqlUtilityTest.java +++ /dev/null @@ -1,497 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.repository.jpa.rsql; - -import static org.assertj.core.api.Assertions.assertThatExceptionOfType; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.reset; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.Callable; - -import jakarta.persistence.criteria.CriteriaBuilder; -import jakarta.persistence.criteria.CriteriaQuery; -import jakarta.persistence.criteria.Expression; -import jakarta.persistence.criteria.Path; -import jakarta.persistence.criteria.Predicate; -import jakarta.persistence.criteria.Root; -import jakarta.persistence.criteria.Subquery; -import jakarta.persistence.metamodel.Attribute; -import jakarta.persistence.metamodel.EntityType; -import jakarta.persistence.metamodel.SingularAttribute; -import jakarta.persistence.metamodel.Type; - -import org.eclipse.hawkbit.repository.DistributionSetFields; -import org.eclipse.hawkbit.repository.RsqlQueryField; -import org.eclipse.hawkbit.repository.SoftwareModuleFields; -import org.eclipse.hawkbit.repository.TargetFields; -import org.eclipse.hawkbit.repository.TenantConfigurationManagement; -import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException; -import org.eclipse.hawkbit.repository.model.SoftwareModule; -import org.eclipse.hawkbit.repository.model.TenantConfigurationValue; -import org.eclipse.hawkbit.repository.model.helper.SystemSecurityContextHolder; -import org.eclipse.hawkbit.repository.model.helper.TenantConfigurationManagementHolder; -import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer; -import org.eclipse.hawkbit.repository.rsql.VirtualPropertyResolver; -import org.eclipse.hawkbit.security.SystemSecurityContext; -import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -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; - -@ExtendWith(SpringExtension.class) -/** - * Feature: Component Tests - Repository
- * Story: RSQL search utility - */ -@Disabled -// TODO: fully document tests -> description for long text and reasonable -// method name as short text -class RsqlUtilityTest { - - private static final TenantConfigurationValue TEST_POLLING_TIME_INTERVAL = - TenantConfigurationValue. builder().value("00:05:00").build(); - private static final TenantConfigurationValue TEST_POLLING_OVERDUE_TIME_INTERVAL = - TenantConfigurationValue. builder().value("00:07:37").build(); - - @Spy - private final VirtualPropertyResolver macroResolver = new VirtualPropertyResolver(); - private final Database testDb = Database.H2; - @MockitoBean - private TenantConfigurationManagement confMgmt; - @MockitoBean - private SystemSecurityContext securityContext; - @Mock - private Root baseSoftwareModuleRootMock; - @Mock - private CriteriaQuery criteriaQueryMock; - @Mock - private CriteriaBuilder criteriaBuilderMock; - @Mock - private Subquery subqueryMock; - @Mock - private Root subqueryRootMock; - @Mock - private Attribute attribute; - - @BeforeEach - void beforeEach() { - setupRoot(baseSoftwareModuleRootMock); - setupRoot(subqueryRootMock); - } - - @Test - void wrongFieldThrowUnsupportedFieldException() { - when(baseSoftwareModuleRootMock.getJavaType()).thenReturn((Class) SoftwareModule.class); - final Specification 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() { - final Specification 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)); - - final Specification 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)); - - final Specification 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 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() { - final Specification 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)); - - final Specification 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)); - - final Specification 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 - void correctRsqlBuildsPredicate() { - reset0(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock); - final String correctRsql = "name==abc;version==1.2"; - when(baseSoftwareModuleRootMock.get("name")).thenReturn(baseSoftwareModuleRootMock); - when(baseSoftwareModuleRootMock.get("version")).thenReturn(baseSoftwareModuleRootMock); - when(baseSoftwareModuleRootMock.getJavaType()).thenReturn((Class) SoftwareModule.class); - 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)); - - // test - RsqlUtility.buildRsqlSpecification(correctRsql, SoftwareModuleFields.class, null, testDb) - .toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock); - - // verification - verify(criteriaBuilderMock, times(1)).and(any(Predicate.class)); - } - - @Test - void correctRsqlBuildsSimpleNotEqualPredicate() { - reset0(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock); - final String correctRsql = "name!=abc"; - when(baseSoftwareModuleRootMock.get("name")).thenReturn(baseSoftwareModuleRootMock); - 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(pathOfString(baseSoftwareModuleRootMock))).thenReturn(pathOfString(baseSoftwareModuleRootMock)); - - // test - RsqlUtility.buildRsqlSpecification(correctRsql, SoftwareModuleFields.class, null, testDb) - .toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock); - - // verification - verify(criteriaBuilderMock, times(1)).or(any(Predicate.class), any(Predicate.class)); - verify(criteriaBuilderMock, times(1)).isNull(pathOfString(baseSoftwareModuleRootMock)); - verify(criteriaBuilderMock, times(1)).notEqual(pathOfString(baseSoftwareModuleRootMock), "abc".toUpperCase()); - } - - @Test - void correctRsqlBuildsSimpleNotLikePredicate() { - reset0(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock); - final String correctRsql = "name!=abc*"; - when(baseSoftwareModuleRootMock.get("name")).thenReturn(baseSoftwareModuleRootMock); - when(baseSoftwareModuleRootMock.getJavaType()).thenReturn((Class) String.class); - - 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(pathOfString(baseSoftwareModuleRootMock))).thenReturn(pathOfString(baseSoftwareModuleRootMock)); - - // test - RsqlUtility.buildRsqlSpecification(correctRsql, SoftwareModuleFields.class, null, testDb) - .toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock); - - // verification - verify(criteriaBuilderMock, times(1)).or(any(Predicate.class), any(Predicate.class)); - verify(criteriaBuilderMock, times(1)).isNull(pathOfString(baseSoftwareModuleRootMock)); - verify(criteriaBuilderMock, times(1)).notLike(pathOfString(baseSoftwareModuleRootMock), "abc%".toUpperCase(), '\\'); - } - - @Test - void correctRsqlBuildsNotSimpleNotLikePredicate() { - reset0(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock); - // with this query a subquery has to be made, so it is no simple query - final String correctRsql = "type!=abc"; - when(baseSoftwareModuleRootMock.get(anyString())).thenReturn(baseSoftwareModuleRootMock); - when(baseSoftwareModuleRootMock.getJavaType()).thenReturn((Class) SoftwareModule.class); - - final Path pathMock = mock(Path.class); - when(pathMock.get(anyString())).thenReturn(pathMock); - when(subqueryRootMock.get(anyString())).thenReturn(pathMock); - - when(criteriaBuilderMock.and(any(), any())).thenReturn(mock(Predicate.class)); - - when(criteriaQueryMock.subquery(SoftwareModule.class)).thenReturn(subqueryMock); - - when(subqueryMock.from(SoftwareModule.class)).thenReturn(subqueryRootMock); - when(subqueryMock.select(subqueryRootMock)).thenReturn(subqueryMock); - when(subqueryMock.where(any(Expression.class))).thenReturn(subqueryMock); - - // test - RsqlUtility.buildRsqlSpecification(correctRsql, SoftwareModuleFields.class, null, testDb) - .toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock); - - // verification - verify(criteriaBuilderMock, times(1)).not(criteriaBuilderMock.exists(eq(subqueryMock))); - } - - @Test - void correctRsqlBuildsEqualPredicateWithPercentage() { - reset0(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock); - final String correctRsql = "name==a%"; - 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.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(pathOfString(baseSoftwareModuleRootMock), "a%".toUpperCase()); - } - - @Test - void correctRsqlBuildsLikePredicateWithPercentage() { - reset0(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock); - final String correctRsql = "name==a%*"; - 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.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(pathOfString(baseSoftwareModuleRootMock), "a\\%%".toUpperCase(), '\\'); - } - - // MsSQL is not officially supported - // thought it may be available through configuration and adding necessarily dependencies - // so we keep RSQL compatibility testing - @Test - void correctRsqlBuildsLikePredicateWithPercentageSQLServer() { - reset0(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock); - final String correctRsql = "name==a%*"; - when(baseSoftwareModuleRootMock.get("name")).thenReturn(baseSoftwareModuleRootMock); - when(baseSoftwareModuleRootMock.getJavaType()).thenReturn((Class) String.class); - when(criteriaBuilderMock.upper(pathOfString(baseSoftwareModuleRootMock))).thenReturn(pathOfString(baseSoftwareModuleRootMock)); - when(criteriaBuilderMock.like(any(Expression.class), anyString(), eq('\\'))).thenReturn(mock(Predicate.class)); - when(criteriaBuilderMock. greaterThanOrEqualTo(any(Expression.class), any(String.class))).thenReturn(mock(Predicate.class)); - - // test - RsqlUtility.buildRsqlSpecification(correctRsql, SoftwareModuleFields.class, null, Database.SQL_SERVER) - .toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock); - - // verification - verify(criteriaBuilderMock, times(1)).and(any(Predicate.class)); - verify(criteriaBuilderMock, times(1)).like(pathOfString(baseSoftwareModuleRootMock), "a[%]%".toUpperCase(), '\\'); - } - - @Test - void correctRsqlBuildsLessThanPredicate() { - reset0(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock); - final String correctRsql = "name=lt=abc"; - when(baseSoftwareModuleRootMock.get("name")).thenReturn(baseSoftwareModuleRootMock); - when(baseSoftwareModuleRootMock.getJavaType()).thenReturn((Class) SoftwareModule.class); - when(criteriaBuilderMock.lessThan(any(Expression.class), anyString())).thenReturn(mock(Predicate.class)); - when(criteriaBuilderMock. greaterThanOrEqualTo(any(Expression.class), any(String.class))) - .thenReturn(mock(Predicate.class)); - // test - RsqlUtility.buildRsqlSpecification(correctRsql, SoftwareModuleFields.class, null, testDb) - .toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock); - - // verification - verify(criteriaBuilderMock, times(1)).and(any(Predicate.class)); - verify(criteriaBuilderMock, times(1)).lessThan(pathOfString(baseSoftwareModuleRootMock), "abc"); - } - - @Test - void correctRsqlWithEnumValue() { - reset0(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock); - final String correctRsql = "testfield==bumlux"; - when(baseSoftwareModuleRootMock.get("testfield")).thenReturn(baseSoftwareModuleRootMock); - when(baseSoftwareModuleRootMock.getJavaType()).thenReturn((Class) TestValueEnum.class); - when(criteriaBuilderMock.equal(any(Root.class), any(TestValueEnum.class))).thenReturn(mock(Predicate.class)); - - // test - RsqlUtility.buildRsqlSpecification(correctRsql, TestFieldEnum.class, null, testDb) - .toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock); - - // verification - verify(criteriaBuilderMock, times(1)).and(any(Predicate.class)); - verify(criteriaBuilderMock, times(1)).equal(baseSoftwareModuleRootMock, TestValueEnum.BUMLUX); - } - - @Test - void wrongRsqlWithWrongEnumValue() { - reset0(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock); - final String correctRsql = "testfield==unknownValue"; - when(baseSoftwareModuleRootMock.get("testfield")).thenReturn(baseSoftwareModuleRootMock); - when(baseSoftwareModuleRootMock.getJavaType()).thenReturn((Class) TestValueEnum.class); - when(criteriaBuilderMock.equal(any(Root.class), anyString())).thenReturn(mock(Predicate.class)); - - final Specification rsqlSpecification = RsqlUtility.buildRsqlSpecification(correctRsql, TestFieldEnum.class, null, testDb); - assertThatExceptionOfType(RSQLParameterUnsupportedFieldException.class) - .as("RSQLParameterUnsupportedFieldException for wrong enum value") - .isThrownBy(() -> rsqlSpecification.toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock)); - } - - /** - * Tests the resolution of overdue_ts placeholder in context of a RSQL expression. - */ - @Test - void correctRsqlWithOverdueMacro() { - reset0(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock); - final String overdueProp = "overdue_ts"; - final String overduePropPlaceholder = "${" + overdueProp + "}"; - final String correctRsql = "testfield=le=" + overduePropPlaceholder; - when(baseSoftwareModuleRootMock.get("testfield")).thenReturn(baseSoftwareModuleRootMock); - when(baseSoftwareModuleRootMock.getJavaType()).thenReturn((Class) String.class); - when(criteriaBuilderMock.upper(pathOfString(baseSoftwareModuleRootMock))).thenReturn(pathOfString(baseSoftwareModuleRootMock)); - when(criteriaBuilderMock.like(any(Expression.class), anyString(), eq('\\'))).thenReturn(mock(Predicate.class)); - when(criteriaBuilderMock.lessThanOrEqualTo(any(Expression.class), eq(overduePropPlaceholder))).thenReturn(mock(Predicate.class)); - - // test - RsqlUtility.buildRsqlSpecification(correctRsql, TestFieldEnum.class, setupMacroLookup(), testDb) - .toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock); - - // verification - // the macro is already replaced when passed to #lessThanOrEqualTo -> the method is never invoked with the placeholder: - verify(criteriaBuilderMock, never()).lessThanOrEqualTo(pathOfString(baseSoftwareModuleRootMock), overduePropPlaceholder); - } - - /** - * Tests RSQL expression with an unknown placeholder. - */ - @Test - void correctRsqlWithUnknownMacro() { - reset0(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock); - final String overdueProp = "unknown"; - final String overduePropPlaceholder = "${" + overdueProp + "}"; - final String correctRsql = "testfield=le=" + overduePropPlaceholder; - when(baseSoftwareModuleRootMock.get("testfield")).thenReturn(baseSoftwareModuleRootMock); - when(baseSoftwareModuleRootMock.getJavaType()).thenReturn((Class) String.class); - when(criteriaBuilderMock.equal(any(Root.class), anyString())).thenReturn(mock(Predicate.class)); - when(criteriaBuilderMock. lessThanOrEqualTo(any(Expression.class), eq(overduePropPlaceholder))) - .thenReturn(mock(Predicate.class)); - - // test - RsqlUtility.buildRsqlSpecification(correctRsql, TestFieldEnum.class, setupMacroLookup(), testDb) - .toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock); - - // verification - // the macro is unknown and hence never replaced -> #lessThanOrEqualTo is invoked with the placeholder: - verify(criteriaBuilderMock).lessThanOrEqualTo(pathOfString(baseSoftwareModuleRootMock), overduePropPlaceholder); - } - - VirtualPropertyReplacer setupMacroLookup() { - when(securityContext.runAsSystem(Mockito.any())).thenAnswer(a -> ((Callable) a.getArgument(0)).call()); - - when(confMgmt.getConfigurationValue(TenantConfigurationKey.POLLING_TIME, String.class)) - .thenReturn(TEST_POLLING_TIME_INTERVAL); - when(confMgmt.getConfigurationValue(TenantConfigurationKey.POLLING_OVERDUE_TIME, String.class)) - .thenReturn(TEST_POLLING_OVERDUE_TIME_INTERVAL); - - return macroResolver; - } - - @SuppressWarnings("unchecked") - private Path pathOfString(final Path path) { - return (Path) path; - } - - private void reset0(final Object... mocks) { - reset(mocks); - if (Arrays.asList(mocks).contains(baseSoftwareModuleRootMock)) { - setupRoot(baseSoftwareModuleRootMock); - } - if (Arrays.asList(mocks).contains(subqueryRootMock)) { - setupRoot(subqueryRootMock); - } - } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - private void setupRoot(final Root root) { - final Type type = Mockito.mock(Type.class); - when(type.getPersistenceType()).thenReturn(Type.PersistenceType.BASIC); - final SingularAttribute singularAttribute = Mockito.mock(SingularAttribute.class); - when(singularAttribute.getType()).thenReturn(type); - final EntityType entityType = Mockito.mock(EntityType.class); - when(entityType.getAttribute(any())).thenReturn(singularAttribute); - when(entityType.getPersistenceType()).thenReturn(Type.PersistenceType.BASIC); - when(root.getModel()).thenReturn(entityType); - } - - private enum TestFieldEnum implements RsqlQueryField { - TESTFIELD("testfield"), TESTFIELD_WITH_SUB_ENTITIES("testfieldWithSubEntities", "subentity11", "subentity22"); - - private final String fieldName; - private final List subEntityAttributes; - - TestFieldEnum(final String fieldName) { - this(fieldName, new String[0]); - } - - TestFieldEnum(final String fieldName, final String... subEntityAttributes) { - this.fieldName = fieldName; - this.subEntityAttributes = (Arrays.asList(subEntityAttributes)); - } - - @Override - public String getJpaEntityFieldName() { - return this.fieldName; - } - - @Override - public List getSubEntityAttributes() { - return subEntityAttributes; - } - } - - private enum TestValueEnum { - BUMLUX; - } - - @Configuration - static class Config { - - @Bean - TenantConfigurationManagementHolder tenantConfigurationManagementHolder() { - return TenantConfigurationManagementHolder.getInstance(); - } - - @Bean - SystemSecurityContextHolder systemSecurityContextHolder() { - return SystemSecurityContextHolder.getInstance(); - } - - @Bean - RsqlConfigHolder rsqlConfigHolder() { - return RsqlConfigHolder.getInstance(); - } - } -} \ No newline at end of file