Refactor RSQL Utility - make it singleton and injectable (#2536)
Signed-off-by: Avgustin Marinov <Avgustin.Marinov@bosch.com>
This commit is contained in:
@@ -19,13 +19,10 @@ import jakarta.persistence.criteria.CriteriaQuery;
|
|||||||
|
|
||||||
import org.eclipse.hawkbit.repository.RsqlQueryField;
|
import org.eclipse.hawkbit.repository.RsqlQueryField;
|
||||||
import org.eclipse.hawkbit.repository.jpa.rsql.RsqlUtility;
|
import org.eclipse.hawkbit.repository.jpa.rsql.RsqlUtility;
|
||||||
import org.eclipse.hawkbit.repository.jpa.rsql.RsqlConfigHolder;
|
import org.eclipse.hawkbit.repository.jpa.rsql.RsqlUtility.RsqlToSpecBuilder;
|
||||||
import org.eclipse.hawkbit.repository.jpa.rsql.RsqlConfigHolder.RsqlToSpecBuilder;
|
|
||||||
import org.springframework.orm.jpa.vendor.Database;
|
|
||||||
|
|
||||||
public class HawkbitQlToSql {
|
public class HawkbitQlToSql {
|
||||||
|
|
||||||
private static final Database DATABASE = Database.H2;
|
|
||||||
private final EntityManager entityManager;
|
private final EntityManager entityManager;
|
||||||
private final boolean isEclipselink;
|
private final boolean isEclipselink;
|
||||||
|
|
||||||
@@ -61,16 +58,16 @@ public class HawkbitQlToSql {
|
|||||||
final Class<T> domainClass, final Class<A> fieldsClass, final String rsql, final RsqlToSpecBuilder rsqlToSpecBuilder) {
|
final Class<T> domainClass, final Class<A> fieldsClass, final String rsql, final RsqlToSpecBuilder rsqlToSpecBuilder) {
|
||||||
final CriteriaQuery<T> query = entityManager.getCriteriaBuilder().createQuery(domainClass);
|
final CriteriaQuery<T> query = entityManager.getCriteriaBuilder().createQuery(domainClass);
|
||||||
final CriteriaBuilder cb = entityManager.getCriteriaBuilder();
|
final CriteriaBuilder cb = entityManager.getCriteriaBuilder();
|
||||||
final RsqlToSpecBuilder defaultRsqlToSpecBuilder = RsqlConfigHolder.getInstance().getRsqlToSpecBuilder();
|
final RsqlToSpecBuilder defaultRsqlToSpecBuilder = RsqlUtility.getInstance().getRsqlToSpecBuilder();
|
||||||
if (defaultRsqlToSpecBuilder != rsqlToSpecBuilder) {
|
if (defaultRsqlToSpecBuilder != rsqlToSpecBuilder) {
|
||||||
RsqlConfigHolder.getInstance().setRsqlToSpecBuilder(rsqlToSpecBuilder);
|
RsqlUtility.getInstance().setRsqlToSpecBuilder(rsqlToSpecBuilder);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
return query.where(RsqlUtility.<A, T> buildRsqlSpecification(rsql, fieldsClass, null, DATABASE)
|
return query.where(RsqlUtility.getInstance().<A, T> buildRsqlSpecification(rsql, fieldsClass)
|
||||||
.toPredicate(query.from(domainClass), cb.createQuery(domainClass), cb));
|
.toPredicate(query.from(domainClass), cb.createQuery(domainClass), cb));
|
||||||
} finally {
|
} finally {
|
||||||
if (defaultRsqlToSpecBuilder != rsqlToSpecBuilder) {
|
if (defaultRsqlToSpecBuilder != rsqlToSpecBuilder) {
|
||||||
RsqlConfigHolder.getInstance().setRsqlToSpecBuilder(defaultRsqlToSpecBuilder);
|
RsqlUtility.getInstance().setRsqlToSpecBuilder(defaultRsqlToSpecBuilder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 <code>true</code> "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 <code>false</code>. In case it is case-sensitive and,
|
|
||||||
* {@link #ignoreCase} is set to <code>true</code> the SQL queries use upper case comparisons to ignore case.
|
|
||||||
*
|
|
||||||
* If the database is declared as case-sensitive and ignoreCase is set to <code>false</code> 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -9,15 +9,15 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.repository.jpa.rsql;
|
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.EntityManager;
|
||||||
import jakarta.persistence.criteria.CriteriaBuilder;
|
import jakarta.persistence.criteria.CriteriaBuilder;
|
||||||
import jakarta.persistence.criteria.CriteriaQuery;
|
import jakarta.persistence.criteria.CriteriaQuery;
|
||||||
|
|
||||||
import cz.jirutka.rsql.parser.RSQLParserException;
|
import cz.jirutka.rsql.parser.RSQLParserException;
|
||||||
import lombok.AccessLevel;
|
import lombok.AccessLevel;
|
||||||
|
import lombok.Getter;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.Setter;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.text.StrLookup;
|
import org.apache.commons.lang3.text.StrLookup;
|
||||||
import org.eclipse.hawkbit.repository.RsqlQueryField;
|
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.jpa.rsql.legacy.SpecificationBuilderLegacy;
|
||||||
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
|
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
|
||||||
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyResolver;
|
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.data.jpa.domain.Specification;
|
||||||
import org.springframework.orm.jpa.vendor.Database;
|
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.
|
* $${OVERDUE_TS} would prevent the ${OVERDUE_TS} token from being expanded.
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@Getter
|
||||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
@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 <code>true</code> "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 <code>false</code>. In case it is case-sensitive and,
|
||||||
|
* {@link #ignoreCase} is set to <code>true</code> the SQL queries use upper case comparisons to ignore case.
|
||||||
|
* <p/>
|
||||||
|
* If the database is declared as case-sensitive and ignoreCase is set to <code>false</code> 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
|
* 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 rsql the rsql query to be parsed
|
||||||
* @param rsqlQueryFieldType the enum class type which implements the {@link RsqlQueryField}
|
* @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 <code>null</code>
|
|
||||||
* @param database database in use
|
|
||||||
* @return a specification which can be used with JPA
|
* @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
|
* @throws RSQLParameterUnsupportedFieldException if a field in the RSQL string is used but not provided by the
|
||||||
* given {@code fieldNameProvider}
|
* given {@code fieldNameProvider}
|
||||||
* @throws RSQLParameterSyntaxException if the RSQL syntax is wrong
|
* @throws RSQLParameterSyntaxException if the RSQL syntax is wrong
|
||||||
*/
|
*/
|
||||||
public static <A extends Enum<A> & RsqlQueryField, T> Specification<T> buildRsqlSpecification(
|
public <A extends Enum<A> & RsqlQueryField, T> Specification<T> buildRsqlSpecification(
|
||||||
final String rsql, final Class<A> rsqlQueryFieldType,
|
final String rsql, final Class<A> rsqlQueryFieldType) {
|
||||||
final VirtualPropertyReplacer virtualPropertyReplacer, final Database database) {
|
if (rsqlToSpecBuilder == RsqlToSpecBuilder.G3) {
|
||||||
if (RsqlConfigHolder.getInstance().getRsqlToSpecBuilder() == G3) {
|
return new SpecificationBuilder<T>(virtualPropertyReplacer, !caseInsensitiveDB && ignoreCase, database)
|
||||||
return new SpecificationBuilder<T>(
|
.specification(RsqlParser.parse(caseInsensitiveDB || ignoreCase ? rsql.toLowerCase() : rsql, rsqlQueryFieldType));
|
||||||
virtualPropertyReplacer,
|
|
||||||
!RsqlConfigHolder.getInstance().isCaseInsensitiveDB() && RsqlConfigHolder.getInstance().isIgnoreCase(),
|
|
||||||
database)
|
|
||||||
.specification(RsqlParser.parse(
|
|
||||||
RsqlConfigHolder.getInstance().isCaseInsensitiveDB() || RsqlConfigHolder.getInstance().isIgnoreCase()
|
|
||||||
? rsql.toLowerCase() : rsql,
|
|
||||||
rsqlQueryFieldType));
|
|
||||||
} else {
|
} else {
|
||||||
return new SpecificationBuilderLegacy<A, T>(rsqlQueryFieldType, virtualPropertyReplacer, database).specification(rsql);
|
return new SpecificationBuilderLegacy<A, T>(rsqlQueryFieldType, virtualPropertyReplacer, database).specification(rsql);
|
||||||
}
|
}
|
||||||
@@ -101,18 +153,16 @@ public final class RsqlUtility {
|
|||||||
* Validates the RSQL string
|
* Validates the RSQL string
|
||||||
*
|
*
|
||||||
* @param rsql RSQL string to validate
|
* @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 RSQLParserException if RSQL syntax is invalid
|
||||||
* @throws RSQLParameterUnsupportedFieldException if RSQL key is not allowed
|
* @throws RSQLParameterUnsupportedFieldException if RSQL key is not allowed
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||||
public static <A extends Enum<A> & RsqlQueryField> void validateRsqlFor(
|
public <A extends Enum<A> & RsqlQueryField> void validateRsqlFor(
|
||||||
final String rsql, final Class<A> rsqlQueryFieldType,
|
final String rsql, final Class<A> rsqlQueryFieldType, final Class<?> jpaType) {
|
||||||
final Class<?> jpaType,
|
|
||||||
final VirtualPropertyReplacer virtualPropertyReplacer, final EntityManager entityManager) {
|
|
||||||
final CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
|
final CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
|
||||||
final CriteriaQuery<?> criteriaQuery = criteriaBuilder.createQuery(jpaType);
|
final CriteriaQuery<?> criteriaQuery = criteriaBuilder.createQuery(jpaType);
|
||||||
buildRsqlSpecification(rsql, rsqlQueryFieldType, virtualPropertyReplacer, null)
|
buildRsqlSpecification(rsql, rsqlQueryFieldType).toPredicate(criteriaQuery.from((Class) jpaType), criteriaQuery, criteriaBuilder);
|
||||||
.toPredicate(criteriaQuery.from((Class) jpaType), criteriaQuery, criteriaBuilder);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
package org.eclipse.hawkbit.repository.jpa.rsql.legacy;
|
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.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;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -24,7 +24,7 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
import org.eclipse.hawkbit.repository.RsqlQueryField;
|
import org.eclipse.hawkbit.repository.RsqlQueryField;
|
||||||
import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException;
|
import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException;
|
||||||
import org.eclipse.hawkbit.repository.jpa.ql.SpecificationBuilder;
|
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.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
|
||||||
import org.springframework.data.jpa.domain.Specification;
|
import org.springframework.data.jpa.domain.Specification;
|
||||||
import org.springframework.orm.jpa.vendor.Database;
|
import org.springframework.orm.jpa.vendor.Database;
|
||||||
@@ -50,14 +50,14 @@ public class SpecificationBuilderLegacy<A extends Enum<A> & RsqlQueryField, T> {
|
|||||||
|
|
||||||
public Specification<T> specification(final String rsql) {
|
public Specification<T> specification(final String rsql) {
|
||||||
return (root, query, cb) -> {
|
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);
|
query.distinct(true);
|
||||||
|
|
||||||
final boolean ensureIgnoreCase = !rsqlConfigHolder.isCaseInsensitiveDB() && rsqlConfigHolder.isIgnoreCase();
|
final boolean ensureIgnoreCase = !rsqlUtility.isCaseInsensitiveDB() && rsqlUtility.isIgnoreCase();
|
||||||
final RSQLVisitor<List<Predicate>, String> jpqQueryRSQLVisitor =
|
final RSQLVisitor<List<Predicate>, String> jpqQueryRSQLVisitor =
|
||||||
rsqlConfigHolder.getRsqlToSpecBuilder() == LEGACY_G1
|
rsqlUtility.getRsqlToSpecBuilder() == LEGACY_G1
|
||||||
? new JpaQueryRsqlVisitor<>(root, cb, rsqlQueryFieldType, virtualPropertyReplacer, database, query, ensureIgnoreCase)
|
? new JpaQueryRsqlVisitor<>(root, cb, rsqlQueryFieldType, virtualPropertyReplacer, database, query, ensureIgnoreCase)
|
||||||
: new JpaQueryRsqlVisitorG2<>(rsqlQueryFieldType, root, query, cb, database, virtualPropertyReplacer, ensureIgnoreCase);
|
: new JpaQueryRsqlVisitorG2<>(rsqlQueryFieldType, root, query, cb, database, virtualPropertyReplacer, ensureIgnoreCase);
|
||||||
final List<Predicate> accept = rootNode.accept(jpqQueryRSQLVisitor);
|
final List<Predicate> accept = rootNode.accept(jpqQueryRSQLVisitor);
|
||||||
@@ -70,10 +70,10 @@ public class SpecificationBuilderLegacy<A extends Enum<A> & 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);
|
log.debug("Parsing rsql string {}", rsql);
|
||||||
try {
|
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) {
|
} catch (final IllegalArgumentException e) {
|
||||||
throw new RSQLParameterSyntaxException("RSQL filter must not be null", e);
|
throw new RSQLParameterSyntaxException("RSQL filter must not be null", e);
|
||||||
} catch (final RSQLParserException e) {
|
} catch (final RSQLParserException e) {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* 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.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* 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.jpa.repository.JpaSpecificationExecutor;
|
||||||
import org.springframework.data.repository.CrudRepository;
|
import org.springframework.data.repository.CrudRepository;
|
||||||
@@ -7,10 +7,10 @@
|
|||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* 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.RsqlUtility.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_G2;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -18,9 +18,9 @@ import java.util.List;
|
|||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.eclipse.hawkbit.repository.RsqlQueryField;
|
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.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.junit.jupiter.api.Test;
|
||||||
import org.springframework.data.jpa.domain.Specification;
|
import org.springframework.data.jpa.domain.Specification;
|
||||||
import org.springframework.orm.jpa.vendor.Database;
|
import org.springframework.orm.jpa.vendor.Database;
|
||||||
@@ -32,12 +32,12 @@ class SpecificationBuilderLegacyTest extends SpecificationBuilderTest {
|
|||||||
private final SpecificationBuilderLegacy<RootField, Root> builder = new SpecificationBuilderLegacy<>(RootField.class, null, Database.H2);
|
private final SpecificationBuilderLegacy<RootField, Root> builder = new SpecificationBuilderLegacy<>(RootField.class, null, Database.H2);
|
||||||
|
|
||||||
private static void runWithRsqlToSpecBuilder(final Runnable runnable, final RsqlToSpecBuilder rsqlToSpecBuilder) {
|
private static void runWithRsqlToSpecBuilder(final Runnable runnable, final RsqlToSpecBuilder rsqlToSpecBuilder) {
|
||||||
final RsqlToSpecBuilder defaultBuilder = RsqlConfigHolder.getInstance().getRsqlToSpecBuilder();
|
final RsqlToSpecBuilder defaultBuilder = RsqlUtility.getInstance().getRsqlToSpecBuilder();
|
||||||
RsqlConfigHolder.getInstance().setRsqlToSpecBuilder(rsqlToSpecBuilder);
|
RsqlUtility.getInstance().setRsqlToSpecBuilder(rsqlToSpecBuilder);
|
||||||
try {
|
try {
|
||||||
runnable.run();
|
runnable.run();
|
||||||
} finally {
|
} finally {
|
||||||
RsqlConfigHolder.getInstance().setRsqlToSpecBuilder(defaultBuilder);
|
RsqlUtility.getInstance().setRsqlToSpecBuilder(defaultBuilder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -7,12 +7,12 @@
|
|||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* 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.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.eclipse.hawkbit.repository.jpa.rsql.RsqlConfigHolder.RsqlToSpecBuilder.G3;
|
import static org.eclipse.hawkbit.repository.jpa.rsql.RsqlUtility.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_G1;
|
||||||
import static org.eclipse.hawkbit.repository.jpa.rsql.RsqlConfigHolder.RsqlToSpecBuilder.LEGACY_G2;
|
import static org.eclipse.hawkbit.repository.jpa.rsql.RsqlUtility.RsqlToSpecBuilder.LEGACY_G2;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -22,11 +22,9 @@ import java.util.stream.StreamSupport;
|
|||||||
import jakarta.persistence.EntityManager;
|
import jakarta.persistence.EntityManager;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
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.ql.utils.HawkbitQlToSql;
|
||||||
import org.eclipse.hawkbit.repository.jpa.rsql.RsqlParser;
|
import org.eclipse.hawkbit.repository.jpa.rsql.RsqlParser;
|
||||||
import org.eclipse.hawkbit.repository.jpa.ql.SpecificationBuilder;
|
import org.eclipse.hawkbit.repository.jpa.rsql.RsqlUtility;
|
||||||
import org.eclipse.hawkbit.repository.jpa.rsql.RsqlConfigHolder;
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.SpringBootConfiguration;
|
import org.springframework.boot.SpringBootConfiguration;
|
||||||
@@ -491,8 +489,8 @@ class SpecificationBuilderTest {
|
|||||||
return builder.specification(RsqlParser.parse(rsql));
|
return builder.specification(RsqlParser.parse(rsql));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static RsqlConfigHolder.RsqlToSpecBuilder getRsqlToSpecBuilder() {
|
private static RsqlUtility.RsqlToSpecBuilder getRsqlToSpecBuilder() {
|
||||||
return RsqlConfigHolder.getInstance().getRsqlToSpecBuilder();
|
return RsqlUtility.getInstance().getRsqlToSpecBuilder();
|
||||||
}
|
}
|
||||||
|
|
||||||
@SpringBootConfiguration
|
@SpringBootConfiguration
|
||||||
@@ -7,16 +7,13 @@
|
|||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* 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.Entity;
|
||||||
import jakarta.persistence.FetchType;
|
|
||||||
import jakarta.persistence.GeneratedValue;
|
import jakarta.persistence.GeneratedValue;
|
||||||
import jakarta.persistence.GenerationType;
|
import jakarta.persistence.GenerationType;
|
||||||
import jakarta.persistence.Id;
|
import jakarta.persistence.Id;
|
||||||
import jakarta.persistence.ManyToOne;
|
import jakarta.persistence.ManyToOne;
|
||||||
import jakarta.persistence.OneToMany;
|
|
||||||
import jakarta.persistence.OneToOne;
|
|
||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.experimental.Accessors;
|
import lombok.experimental.Accessors;
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* 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.jpa.repository.JpaSpecificationExecutor;
|
||||||
import org.springframework.data.repository.CrudRepository;
|
import org.springframework.data.repository.CrudRepository;
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* 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.Entity;
|
||||||
import jakarta.persistence.GeneratedValue;
|
import jakarta.persistence.GeneratedValue;
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* 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.jpa.repository.JpaSpecificationExecutor;
|
||||||
import org.springframework.data.repository.CrudRepository;
|
import org.springframework.data.repository.CrudRepository;
|
||||||
@@ -154,7 +154,7 @@ import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
|
|||||||
import org.eclipse.hawkbit.repository.model.TargetType;
|
import org.eclipse.hawkbit.repository.model.TargetType;
|
||||||
import org.eclipse.hawkbit.repository.model.helper.SystemSecurityContextHolder;
|
import org.eclipse.hawkbit.repository.model.helper.SystemSecurityContextHolder;
|
||||||
import org.eclipse.hawkbit.repository.model.helper.TenantConfigurationManagementHolder;
|
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.repository.rsql.VirtualPropertyReplacer;
|
||||||
import org.eclipse.hawkbit.security.HawkbitSecurityProperties;
|
import org.eclipse.hawkbit.security.HawkbitSecurityProperties;
|
||||||
import org.eclipse.hawkbit.security.SecurityTokenGenerator;
|
import org.eclipse.hawkbit.security.SecurityTokenGenerator;
|
||||||
@@ -538,15 +538,13 @@ public class RepositoryApplicationConfiguration {
|
|||||||
final TargetRepository targetRepository,
|
final TargetRepository targetRepository,
|
||||||
final TargetFilterQueryRepository targetFilterQueryRepository, final ActionRepository actionRepository,
|
final TargetFilterQueryRepository targetFilterQueryRepository, final ActionRepository actionRepository,
|
||||||
final SystemSecurityContext systemSecurityContext, final TenantConfigurationManagement tenantConfigurationManagement,
|
final SystemSecurityContext systemSecurityContext, final TenantConfigurationManagement tenantConfigurationManagement,
|
||||||
final VirtualPropertyReplacer virtualPropertyReplacer, final SoftwareModuleRepository softwareModuleRepository,
|
final SoftwareModuleRepository softwareModuleRepository,
|
||||||
final DistributionSetTagRepository distributionSetTagRepository,
|
final DistributionSetTagRepository distributionSetTagRepository, final RepositoryProperties repositoryProperties) {
|
||||||
final JpaProperties properties, final RepositoryProperties repositoryProperties) {
|
|
||||||
return new JpaDistributionSetManagement(entityManager, distributionSetRepository, distributionSetTagManagement,
|
return new JpaDistributionSetManagement(entityManager, distributionSetRepository, distributionSetTagManagement,
|
||||||
systemManagement, distributionSetTypeManagement, quotaManagement,
|
systemManagement, distributionSetTypeManagement, quotaManagement,
|
||||||
targetRepository, targetFilterQueryRepository, actionRepository,
|
targetRepository, targetFilterQueryRepository, actionRepository,
|
||||||
TenantConfigHelper.usingContext(systemSecurityContext, tenantConfigurationManagement),
|
TenantConfigHelper.usingContext(systemSecurityContext, tenantConfigurationManagement),
|
||||||
virtualPropertyReplacer, softwareModuleRepository, distributionSetTagRepository,
|
softwareModuleRepository, distributionSetTagRepository, repositoryProperties);
|
||||||
properties.getDatabase(), repositoryProperties);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -560,11 +558,9 @@ public class RepositoryApplicationConfiguration {
|
|||||||
final DistributionSetTypeRepository distributionSetTypeRepository,
|
final DistributionSetTypeRepository distributionSetTypeRepository,
|
||||||
final SoftwareModuleTypeRepository softwareModuleTypeRepository,
|
final SoftwareModuleTypeRepository softwareModuleTypeRepository,
|
||||||
final DistributionSetRepository distributionSetRepository, final TargetTypeRepository targetTypeRepository,
|
final DistributionSetRepository distributionSetRepository, final TargetTypeRepository targetTypeRepository,
|
||||||
final VirtualPropertyReplacer virtualPropertyReplacer, final JpaProperties properties,
|
|
||||||
final QuotaManagement quotaManagement) {
|
final QuotaManagement quotaManagement) {
|
||||||
return new JpaDistributionSetTypeManagement(distributionSetTypeRepository, softwareModuleTypeRepository,
|
return new JpaDistributionSetTypeManagement(distributionSetTypeRepository, softwareModuleTypeRepository,
|
||||||
distributionSetRepository, targetTypeRepository, virtualPropertyReplacer, properties.getDatabase(),
|
distributionSetRepository, targetTypeRepository, quotaManagement);
|
||||||
quotaManagement);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -576,10 +572,8 @@ public class RepositoryApplicationConfiguration {
|
|||||||
@ConditionalOnMissingBean
|
@ConditionalOnMissingBean
|
||||||
TargetTypeManagement targetTypeManagement(final TargetTypeRepository targetTypeRepository,
|
TargetTypeManagement targetTypeManagement(final TargetTypeRepository targetTypeRepository,
|
||||||
final TargetRepository targetRepository, final DistributionSetTypeRepository distributionSetTypeRepository,
|
final TargetRepository targetRepository, final DistributionSetTypeRepository distributionSetTypeRepository,
|
||||||
final VirtualPropertyReplacer virtualPropertyReplacer, final JpaProperties properties,
|
|
||||||
final QuotaManagement quotaManagement) {
|
final QuotaManagement quotaManagement) {
|
||||||
return new JpaTargetTypeManagement(targetTypeRepository, targetRepository, distributionSetTypeRepository,
|
return new JpaTargetTypeManagement(targetTypeRepository, targetRepository, distributionSetTypeRepository, quotaManagement);
|
||||||
virtualPropertyReplacer, properties.getDatabase(), quotaManagement);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -618,18 +612,16 @@ public class RepositoryApplicationConfiguration {
|
|||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnMissingBean
|
@ConditionalOnMissingBean
|
||||||
TargetManagement targetManagement(final EntityManager entityManager, final QuotaManagement quotaManagement,
|
TargetManagement targetManagement(
|
||||||
|
final EntityManager entityManager, final QuotaManagement quotaManagement,
|
||||||
final TargetRepository targetRepository,
|
final TargetRepository targetRepository,
|
||||||
final RolloutGroupRepository rolloutGroupRepository,
|
final RolloutGroupRepository rolloutGroupRepository,
|
||||||
final TargetFilterQueryRepository targetFilterQueryRepository,
|
final TargetFilterQueryRepository targetFilterQueryRepository,
|
||||||
final TargetTypeRepository targetTypeRepository, final TargetTagRepository targetTagRepository,
|
final TargetTypeRepository targetTypeRepository, final TargetTagRepository targetTagRepository,
|
||||||
final TenantAware tenantAware,
|
final TenantAware tenantAware, final DistributionSetManagement distributionSetManagement) {
|
||||||
final VirtualPropertyReplacer virtualPropertyReplacer,
|
|
||||||
final JpaProperties properties, final DistributionSetManagement distributionSetManagement) {
|
|
||||||
return new JpaTargetManagement(entityManager, distributionSetManagement, quotaManagement, targetRepository,
|
return new JpaTargetManagement(entityManager, distributionSetManagement, quotaManagement, targetRepository,
|
||||||
targetTypeRepository, rolloutGroupRepository, targetFilterQueryRepository,
|
targetTypeRepository, rolloutGroupRepository, targetFilterQueryRepository,
|
||||||
targetTagRepository, tenantAware, virtualPropertyReplacer,
|
targetTagRepository, tenantAware);
|
||||||
properties.getDatabase());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -637,25 +629,20 @@ public class RepositoryApplicationConfiguration {
|
|||||||
*
|
*
|
||||||
* @param targetFilterQueryRepository holding {@link TargetFilterQuery} entities
|
* @param targetFilterQueryRepository holding {@link TargetFilterQuery} entities
|
||||||
* @param targetManagement managing {@link Target} entities
|
* @param targetManagement managing {@link Target} entities
|
||||||
* @param virtualPropertyReplacer for RSQL handling
|
|
||||||
* @param distributionSetManagement for auto assign DS access
|
* @param distributionSetManagement for auto assign DS access
|
||||||
* @param quotaManagement to access quotas
|
* @param quotaManagement to access quotas
|
||||||
* @param properties JPA properties
|
|
||||||
* @return a new {@link TargetFilterQueryManagement}
|
* @return a new {@link TargetFilterQueryManagement}
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnMissingBean
|
@ConditionalOnMissingBean
|
||||||
TargetFilterQueryManagement targetFilterQueryManagement(
|
TargetFilterQueryManagement targetFilterQueryManagement(
|
||||||
final TargetFilterQueryRepository targetFilterQueryRepository, final TargetManagement targetManagement,
|
final TargetFilterQueryRepository targetFilterQueryRepository, final TargetManagement targetManagement,
|
||||||
final VirtualPropertyReplacer virtualPropertyReplacer,
|
|
||||||
final DistributionSetManagement distributionSetManagement, final QuotaManagement quotaManagement,
|
final DistributionSetManagement distributionSetManagement, final QuotaManagement quotaManagement,
|
||||||
final JpaProperties properties, final TenantConfigurationManagement tenantConfigurationManagement,
|
final TenantConfigurationManagement tenantConfigurationManagement, final RepositoryProperties repositoryProperties,
|
||||||
final RepositoryProperties repositoryProperties,
|
final SystemSecurityContext systemSecurityContext, final ContextAware contextAware, final AuditorAware<String> auditorAware) {
|
||||||
final SystemSecurityContext systemSecurityContext, final ContextAware contextAware, final AuditorAware<String> auditorAware,
|
|
||||||
final EntityManager entityManager) {
|
|
||||||
return new JpaTargetFilterQueryManagement(targetFilterQueryRepository, targetManagement,
|
return new JpaTargetFilterQueryManagement(targetFilterQueryRepository, targetManagement,
|
||||||
virtualPropertyReplacer, distributionSetManagement, quotaManagement, properties.getDatabase(),
|
distributionSetManagement, quotaManagement, tenantConfigurationManagement, repositoryProperties,
|
||||||
tenantConfigurationManagement, repositoryProperties, systemSecurityContext, contextAware, auditorAware, entityManager);
|
systemSecurityContext, contextAware, auditorAware);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -665,11 +652,8 @@ public class RepositoryApplicationConfiguration {
|
|||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnMissingBean
|
@ConditionalOnMissingBean
|
||||||
TargetTagManagement targetTagManagement(final TargetTagRepository targetTagRepository,
|
TargetTagManagement targetTagManagement(final TargetTagRepository targetTagRepository) {
|
||||||
final VirtualPropertyReplacer virtualPropertyReplacer,
|
return new JpaTargetTagManagement(targetTagRepository);
|
||||||
final JpaProperties properties) {
|
|
||||||
return new JpaTargetTagManagement(targetTagRepository, virtualPropertyReplacer,
|
|
||||||
properties.getDatabase());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -681,10 +665,9 @@ public class RepositoryApplicationConfiguration {
|
|||||||
@ConditionalOnMissingBean
|
@ConditionalOnMissingBean
|
||||||
DistributionSetTagManagement distributionSetTagManagement(
|
DistributionSetTagManagement distributionSetTagManagement(
|
||||||
final DistributionSetTagRepository distributionSetTagRepository,
|
final DistributionSetTagRepository distributionSetTagRepository,
|
||||||
final DistributionSetRepository distributionSetRepository,
|
final DistributionSetRepository distributionSetRepository) {
|
||||||
final VirtualPropertyReplacer virtualPropertyReplacer, final JpaProperties properties) {
|
|
||||||
return new JpaDistributionSetTagManagement(
|
return new JpaDistributionSetTagManagement(
|
||||||
distributionSetTagRepository, distributionSetRepository, virtualPropertyReplacer, properties.getDatabase());
|
distributionSetTagRepository, distributionSetRepository);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -699,13 +682,9 @@ public class RepositoryApplicationConfiguration {
|
|||||||
final SoftwareModuleRepository softwareModuleRepository,
|
final SoftwareModuleRepository softwareModuleRepository,
|
||||||
final SoftwareModuleMetadataRepository softwareModuleMetadataRepository,
|
final SoftwareModuleMetadataRepository softwareModuleMetadataRepository,
|
||||||
final SoftwareModuleTypeRepository softwareModuleTypeRepository, final AuditorAware<String> auditorProvider,
|
final SoftwareModuleTypeRepository softwareModuleTypeRepository, final AuditorAware<String> auditorProvider,
|
||||||
final ArtifactManagement artifactManagement, final QuotaManagement quotaManagement,
|
final ArtifactManagement artifactManagement, final QuotaManagement quotaManagement) {
|
||||||
final VirtualPropertyReplacer virtualPropertyReplacer,
|
|
||||||
final JpaProperties properties) {
|
|
||||||
return new JpaSoftwareModuleManagement(entityManager, distributionSetRepository, softwareModuleRepository,
|
return new JpaSoftwareModuleManagement(entityManager, distributionSetRepository, softwareModuleRepository,
|
||||||
softwareModuleMetadataRepository, softwareModuleTypeRepository, auditorProvider, artifactManagement,
|
softwareModuleMetadataRepository, softwareModuleTypeRepository, auditorProvider, artifactManagement, quotaManagement);
|
||||||
quotaManagement, virtualPropertyReplacer,
|
|
||||||
properties.getDatabase());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -718,11 +697,8 @@ public class RepositoryApplicationConfiguration {
|
|||||||
SoftwareModuleTypeManagement softwareModuleTypeManagement(
|
SoftwareModuleTypeManagement softwareModuleTypeManagement(
|
||||||
final DistributionSetTypeRepository distributionSetTypeRepository,
|
final DistributionSetTypeRepository distributionSetTypeRepository,
|
||||||
final SoftwareModuleTypeRepository softwareModuleTypeRepository,
|
final SoftwareModuleTypeRepository softwareModuleTypeRepository,
|
||||||
final VirtualPropertyReplacer virtualPropertyReplacer,
|
final SoftwareModuleRepository softwareModuleRepository) {
|
||||||
final SoftwareModuleRepository softwareModuleRepository,
|
return new JpaSoftwareModuleTypeManagement(distributionSetTypeRepository, softwareModuleTypeRepository, softwareModuleRepository);
|
||||||
final JpaProperties properties) {
|
|
||||||
return new JpaSoftwareModuleTypeManagement(distributionSetTypeRepository, softwareModuleTypeRepository,
|
|
||||||
virtualPropertyReplacer, softwareModuleRepository, properties.getDatabase());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@@ -765,14 +741,12 @@ public class RepositoryApplicationConfiguration {
|
|||||||
final TenantConfigurationManagement tenantConfigurationManagement,
|
final TenantConfigurationManagement tenantConfigurationManagement,
|
||||||
final QuotaManagement quotaManagement,
|
final QuotaManagement quotaManagement,
|
||||||
final AfterTransactionCommitExecutor afterCommit,
|
final AfterTransactionCommitExecutor afterCommit,
|
||||||
final VirtualPropertyReplacer virtualPropertyReplacer,
|
final SystemSecurityContext systemSecurityContext, final ContextAware contextAware,
|
||||||
final SystemSecurityContext systemSecurityContext, final ContextAware contextAware, final JpaProperties properties,
|
|
||||||
final RepositoryProperties repositoryProperties) {
|
final RepositoryProperties repositoryProperties) {
|
||||||
return new JpaRolloutManagement(rolloutRepository, rolloutGroupRepository, rolloutApprovalStrategy,
|
return new JpaRolloutManagement(rolloutRepository, rolloutGroupRepository, rolloutApprovalStrategy,
|
||||||
startNextRolloutGroupAction, rolloutStatusCache, actionRepository, targetManagement,
|
startNextRolloutGroupAction, rolloutStatusCache, actionRepository, targetManagement,
|
||||||
distributionSetManagement, tenantConfigurationManagement, quotaManagement, afterCommit,
|
distributionSetManagement, tenantConfigurationManagement, quotaManagement, afterCommit,
|
||||||
virtualPropertyReplacer, systemSecurityContext, contextAware, properties.getDatabase(),
|
systemSecurityContext, contextAware, repositoryProperties);
|
||||||
repositoryProperties);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -798,11 +772,9 @@ public class RepositoryApplicationConfiguration {
|
|||||||
@ConditionalOnMissingBean
|
@ConditionalOnMissingBean
|
||||||
RolloutGroupManagement rolloutGroupManagement(final RolloutGroupRepository rolloutGroupRepository,
|
RolloutGroupManagement rolloutGroupManagement(final RolloutGroupRepository rolloutGroupRepository,
|
||||||
final RolloutRepository rolloutRepository, final ActionRepository actionRepository,
|
final RolloutRepository rolloutRepository, final ActionRepository actionRepository,
|
||||||
final TargetRepository targetRepository, final EntityManager entityManager,
|
final TargetRepository targetRepository, final EntityManager entityManager, final RolloutStatusCache rolloutStatusCache) {
|
||||||
final VirtualPropertyReplacer virtualPropertyReplacer, final RolloutStatusCache rolloutStatusCache,
|
|
||||||
final JpaProperties properties) {
|
|
||||||
return new JpaRolloutGroupManagement(rolloutGroupRepository, rolloutRepository, actionRepository,
|
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 ActionRepository actionRepository,
|
||||||
final DistributionSetManagement distributionSetManagement, final TargetRepository targetRepository,
|
final DistributionSetManagement distributionSetManagement, final TargetRepository targetRepository,
|
||||||
final ActionStatusRepository actionStatusRepository, final AuditorAware<String> auditorProvider,
|
final ActionStatusRepository actionStatusRepository, final AuditorAware<String> auditorProvider,
|
||||||
final AfterTransactionCommitExecutor afterCommit,
|
final AfterTransactionCommitExecutor afterCommit, final PlatformTransactionManager txManager,
|
||||||
final VirtualPropertyReplacer virtualPropertyReplacer, final PlatformTransactionManager txManager,
|
|
||||||
final TenantConfigurationManagement tenantConfigurationManagement, final QuotaManagement quotaManagement,
|
final TenantConfigurationManagement tenantConfigurationManagement, final QuotaManagement quotaManagement,
|
||||||
final SystemSecurityContext systemSecurityContext, final TenantAware tenantAware, final AuditorAware<String> auditorAware,
|
final SystemSecurityContext systemSecurityContext, final TenantAware tenantAware, final AuditorAware<String> auditorAware,
|
||||||
final JpaProperties properties, final RepositoryProperties repositoryProperties) {
|
final JpaProperties properties, final RepositoryProperties repositoryProperties) {
|
||||||
return new JpaDeploymentManagement(entityManager, actionRepository, distributionSetManagement, targetRepository, actionStatusRepository,
|
return new JpaDeploymentManagement(entityManager, actionRepository, distributionSetManagement, targetRepository, actionStatusRepository,
|
||||||
auditorProvider,
|
auditorProvider,
|
||||||
afterCommit, virtualPropertyReplacer, txManager, tenantConfigurationManagement,
|
afterCommit, txManager, tenantConfigurationManagement,
|
||||||
quotaManagement, systemSecurityContext, tenantAware, auditorAware, properties.getDatabase(), repositoryProperties);
|
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
|
@Bean
|
||||||
RsqlConfigHolder rsqlConfigHolder() {
|
RsqlUtility rsqlUtility() {
|
||||||
return RsqlConfigHolder.getInstance();
|
return RsqlUtility.getInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -86,7 +86,6 @@ import org.eclipse.hawkbit.repository.model.Target;
|
|||||||
import org.eclipse.hawkbit.repository.model.TargetType;
|
import org.eclipse.hawkbit.repository.model.TargetType;
|
||||||
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
|
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
|
||||||
import org.eclipse.hawkbit.repository.model.TargetWithActionType;
|
import org.eclipse.hawkbit.repository.model.TargetWithActionType;
|
||||||
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
|
|
||||||
import org.eclipse.hawkbit.security.SystemSecurityContext;
|
import org.eclipse.hawkbit.security.SystemSecurityContext;
|
||||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
import org.eclipse.hawkbit.tenancy.TenantAware;
|
||||||
import org.eclipse.hawkbit.utils.TenantConfigHelper;
|
import org.eclipse.hawkbit.utils.TenantConfigHelper;
|
||||||
@@ -150,7 +149,6 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl
|
|||||||
private final DistributionSetManagement distributionSetManagement;
|
private final DistributionSetManagement distributionSetManagement;
|
||||||
private final TargetRepository targetRepository;
|
private final TargetRepository targetRepository;
|
||||||
private final AuditorAware<String> auditorProvider;
|
private final AuditorAware<String> auditorProvider;
|
||||||
private final VirtualPropertyReplacer virtualPropertyReplacer;
|
|
||||||
private final PlatformTransactionManager txManager;
|
private final PlatformTransactionManager txManager;
|
||||||
private final OnlineDsAssignmentStrategy onlineDsAssignmentStrategy;
|
private final OnlineDsAssignmentStrategy onlineDsAssignmentStrategy;
|
||||||
private final OfflineDsAssignmentStrategy offlineDsAssignmentStrategy;
|
private final OfflineDsAssignmentStrategy offlineDsAssignmentStrategy;
|
||||||
@@ -166,8 +164,7 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl
|
|||||||
final EntityManager entityManager, final ActionRepository actionRepository,
|
final EntityManager entityManager, final ActionRepository actionRepository,
|
||||||
final DistributionSetManagement distributionSetManagement, final TargetRepository targetRepository,
|
final DistributionSetManagement distributionSetManagement, final TargetRepository targetRepository,
|
||||||
final ActionStatusRepository actionStatusRepository, final AuditorAware<String> auditorProvider,
|
final ActionStatusRepository actionStatusRepository, final AuditorAware<String> auditorProvider,
|
||||||
final AfterTransactionCommitExecutor afterCommit,
|
final AfterTransactionCommitExecutor afterCommit, final PlatformTransactionManager txManager,
|
||||||
final VirtualPropertyReplacer virtualPropertyReplacer, final PlatformTransactionManager txManager,
|
|
||||||
final TenantConfigurationManagement tenantConfigurationManagement, final QuotaManagement quotaManagement,
|
final TenantConfigurationManagement tenantConfigurationManagement, final QuotaManagement quotaManagement,
|
||||||
final SystemSecurityContext systemSecurityContext, final TenantAware tenantAware, final AuditorAware<String> auditorAware,
|
final SystemSecurityContext systemSecurityContext, final TenantAware tenantAware, final AuditorAware<String> auditorAware,
|
||||||
final Database database, final RepositoryProperties repositoryProperties) {
|
final Database database, final RepositoryProperties repositoryProperties) {
|
||||||
@@ -176,7 +173,6 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl
|
|||||||
this.distributionSetManagement = distributionSetManagement;
|
this.distributionSetManagement = distributionSetManagement;
|
||||||
this.targetRepository = targetRepository;
|
this.targetRepository = targetRepository;
|
||||||
this.auditorProvider = auditorProvider;
|
this.auditorProvider = auditorProvider;
|
||||||
this.virtualPropertyReplacer = virtualPropertyReplacer;
|
|
||||||
this.txManager = txManager;
|
this.txManager = txManager;
|
||||||
onlineDsAssignmentStrategy = new OnlineDsAssignmentStrategy(targetRepository, afterCommit,
|
onlineDsAssignmentStrategy = new OnlineDsAssignmentStrategy(targetRepository, afterCommit,
|
||||||
actionRepository, actionStatusRepository, quotaManagement, this::isMultiAssignmentsEnabled,
|
actionRepository, actionStatusRepository, quotaManagement, this::isMultiAssignmentsEnabled,
|
||||||
@@ -274,7 +270,7 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl
|
|||||||
assertTargetReadAllowed(controllerId);
|
assertTargetReadAllowed(controllerId);
|
||||||
|
|
||||||
final List<Specification<JpaAction>> specList = Arrays.asList(
|
final List<Specification<JpaAction>> specList = Arrays.asList(
|
||||||
RsqlUtility.buildRsqlSpecification(rsql, ActionFields.class, virtualPropertyReplacer, database),
|
RsqlUtility.getInstance().buildRsqlSpecification(rsql, ActionFields.class),
|
||||||
ActionSpecifications.byTargetControllerId(controllerId));
|
ActionSpecifications.byTargetControllerId(controllerId));
|
||||||
|
|
||||||
return JpaManagementHelper.countBySpec(actionRepository, specList);
|
return JpaManagementHelper.countBySpec(actionRepository, specList);
|
||||||
@@ -287,8 +283,7 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long countActions(final String rsql) {
|
public long countActions(final String rsql) {
|
||||||
final List<Specification<JpaAction>> specList = List.of(
|
final List<Specification<JpaAction>> specList = List.of(RsqlUtility.getInstance().buildRsqlSpecification(rsql, ActionFields.class));
|
||||||
RsqlUtility.buildRsqlSpecification(rsql, ActionFields.class, virtualPropertyReplacer, database));
|
|
||||||
return JpaManagementHelper.countBySpec(actionRepository, specList);
|
return JpaManagementHelper.countBySpec(actionRepository, specList);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -312,8 +307,7 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Slice<Action> findActions(final String rsql, final Pageable pageable) {
|
public Slice<Action> findActions(final String rsql, final Pageable pageable) {
|
||||||
final List<Specification<JpaAction>> specList = List.of(
|
final List<Specification<JpaAction>> specList = List.of(RsqlUtility.getInstance().buildRsqlSpecification(rsql, ActionFields.class));
|
||||||
RsqlUtility.buildRsqlSpecification(rsql, ActionFields.class, virtualPropertyReplacer, database));
|
|
||||||
return JpaManagementHelper.findAllWithoutCountBySpec(actionRepository, specList, pageable);
|
return JpaManagementHelper.findAllWithoutCountBySpec(actionRepository, specList, pageable);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -322,7 +316,7 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl
|
|||||||
assertTargetReadAllowed(controllerId);
|
assertTargetReadAllowed(controllerId);
|
||||||
|
|
||||||
final List<Specification<JpaAction>> specList = Arrays.asList(
|
final List<Specification<JpaAction>> specList = Arrays.asList(
|
||||||
RsqlUtility.buildRsqlSpecification(rsql, ActionFields.class, virtualPropertyReplacer, database),
|
RsqlUtility.getInstance().buildRsqlSpecification(rsql, ActionFields.class),
|
||||||
ActionSpecifications.byTargetControllerId(controllerId));
|
ActionSpecifications.byTargetControllerId(controllerId));
|
||||||
|
|
||||||
return JpaManagementHelper.findAllWithCountBySpec(actionRepository, specList, pageable);
|
return JpaManagementHelper.findAllWithCountBySpec(actionRepository, specList, pageable);
|
||||||
|
|||||||
@@ -73,14 +73,12 @@ import org.eclipse.hawkbit.repository.model.DistributionSetTag;
|
|||||||
import org.eclipse.hawkbit.repository.model.DistributionSetType;
|
import org.eclipse.hawkbit.repository.model.DistributionSetType;
|
||||||
import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
||||||
import org.eclipse.hawkbit.repository.model.Statistic;
|
import org.eclipse.hawkbit.repository.model.Statistic;
|
||||||
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
|
|
||||||
import org.eclipse.hawkbit.utils.TenantConfigHelper;
|
import org.eclipse.hawkbit.utils.TenantConfigHelper;
|
||||||
import org.springframework.dao.ConcurrencyFailureException;
|
import org.springframework.dao.ConcurrencyFailureException;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.data.domain.Slice;
|
import org.springframework.data.domain.Slice;
|
||||||
import org.springframework.data.jpa.domain.Specification;
|
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.Backoff;
|
||||||
import org.springframework.retry.annotation.Retryable;
|
import org.springframework.retry.annotation.Retryable;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
@@ -105,10 +103,8 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
|
|||||||
private final TargetFilterQueryRepository targetFilterQueryRepository;
|
private final TargetFilterQueryRepository targetFilterQueryRepository;
|
||||||
private final ActionRepository actionRepository;
|
private final ActionRepository actionRepository;
|
||||||
private final TenantConfigHelper tenantConfigHelper;
|
private final TenantConfigHelper tenantConfigHelper;
|
||||||
private final VirtualPropertyReplacer virtualPropertyReplacer;
|
|
||||||
private final SoftwareModuleRepository softwareModuleRepository;
|
private final SoftwareModuleRepository softwareModuleRepository;
|
||||||
private final DistributionSetTagRepository distributionSetTagRepository;
|
private final DistributionSetTagRepository distributionSetTagRepository;
|
||||||
private final Database database;
|
|
||||||
private final RepositoryProperties repositoryProperties;
|
private final RepositoryProperties repositoryProperties;
|
||||||
|
|
||||||
@SuppressWarnings("java:S107")
|
@SuppressWarnings("java:S107")
|
||||||
@@ -120,10 +116,8 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
|
|||||||
final TargetRepository targetRepository,
|
final TargetRepository targetRepository,
|
||||||
final TargetFilterQueryRepository targetFilterQueryRepository, final ActionRepository actionRepository,
|
final TargetFilterQueryRepository targetFilterQueryRepository, final ActionRepository actionRepository,
|
||||||
final TenantConfigHelper tenantConfigHelper,
|
final TenantConfigHelper tenantConfigHelper,
|
||||||
final VirtualPropertyReplacer virtualPropertyReplacer,
|
|
||||||
final SoftwareModuleRepository softwareModuleRepository,
|
final SoftwareModuleRepository softwareModuleRepository,
|
||||||
final DistributionSetTagRepository distributionSetTagRepository,
|
final DistributionSetTagRepository distributionSetTagRepository,
|
||||||
final Database database,
|
|
||||||
final RepositoryProperties repositoryProperties) {
|
final RepositoryProperties repositoryProperties) {
|
||||||
this.entityManager = entityManager;
|
this.entityManager = entityManager;
|
||||||
this.distributionSetRepository = distributionSetRepository;
|
this.distributionSetRepository = distributionSetRepository;
|
||||||
@@ -135,10 +129,8 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
|
|||||||
this.targetFilterQueryRepository = targetFilterQueryRepository;
|
this.targetFilterQueryRepository = targetFilterQueryRepository;
|
||||||
this.actionRepository = actionRepository;
|
this.actionRepository = actionRepository;
|
||||||
this.tenantConfigHelper = tenantConfigHelper;
|
this.tenantConfigHelper = tenantConfigHelper;
|
||||||
this.virtualPropertyReplacer = virtualPropertyReplacer;
|
|
||||||
this.softwareModuleRepository = softwareModuleRepository;
|
this.softwareModuleRepository = softwareModuleRepository;
|
||||||
this.distributionSetTagRepository = distributionSetTagRepository;
|
this.distributionSetTagRepository = distributionSetTagRepository;
|
||||||
this.database = database;
|
|
||||||
this.repositoryProperties = repositoryProperties;
|
this.repositoryProperties = repositoryProperties;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -282,7 +274,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
|
|||||||
@Override
|
@Override
|
||||||
public Page<DistributionSet> findByRsql(final String rsql, final Pageable pageable) {
|
public Page<DistributionSet> findByRsql(final String rsql, final Pageable pageable) {
|
||||||
return JpaManagementHelper.findAllWithCountBySpec(distributionSetRepository, List.of(
|
return JpaManagementHelper.findAllWithCountBySpec(distributionSetRepository, List.of(
|
||||||
RsqlUtility.buildRsqlSpecification(rsql, DistributionSetFields.class, virtualPropertyReplacer, database),
|
RsqlUtility.getInstance().buildRsqlSpecification(rsql, DistributionSetFields.class),
|
||||||
DistributionSetSpecification.isNotDeleted()), pageable);
|
DistributionSetSpecification.isNotDeleted()), pageable);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -551,8 +543,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
|
|||||||
assertDsTagExists(tagId);
|
assertDsTagExists(tagId);
|
||||||
|
|
||||||
return JpaManagementHelper.findAllWithCountBySpec(distributionSetRepository, List.of(
|
return JpaManagementHelper.findAllWithCountBySpec(distributionSetRepository, List.of(
|
||||||
RsqlUtility.buildRsqlSpecification(rsql, DistributionSetFields.class, virtualPropertyReplacer,
|
RsqlUtility.getInstance().buildRsqlSpecification(rsql, DistributionSetFields.class),
|
||||||
database),
|
|
||||||
DistributionSetSpecification.hasTag(tagId), DistributionSetSpecification.isNotDeleted()), pageable);
|
DistributionSetSpecification.hasTag(tagId), DistributionSetSpecification.isNotDeleted()), pageable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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.jpa.specifications.TagSpecification;
|
||||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||||
import org.eclipse.hawkbit.repository.model.DistributionSetTag;
|
import org.eclipse.hawkbit.repository.model.DistributionSetTag;
|
||||||
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
|
|
||||||
import org.springframework.dao.ConcurrencyFailureException;
|
import org.springframework.dao.ConcurrencyFailureException;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.data.domain.Slice;
|
import org.springframework.data.domain.Slice;
|
||||||
import org.springframework.data.jpa.domain.Specification;
|
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.Backoff;
|
||||||
import org.springframework.retry.annotation.Retryable;
|
import org.springframework.retry.annotation.Retryable;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
@@ -54,17 +52,12 @@ public class JpaDistributionSetTagManagement implements DistributionSetTagManage
|
|||||||
|
|
||||||
private final DistributionSetTagRepository distributionSetTagRepository;
|
private final DistributionSetTagRepository distributionSetTagRepository;
|
||||||
private final DistributionSetRepository distributionSetRepository;
|
private final DistributionSetRepository distributionSetRepository;
|
||||||
private final VirtualPropertyReplacer virtualPropertyReplacer;
|
|
||||||
private final Database database;
|
|
||||||
|
|
||||||
public JpaDistributionSetTagManagement(
|
public JpaDistributionSetTagManagement(
|
||||||
final DistributionSetTagRepository distributionSetTagRepository,
|
final DistributionSetTagRepository distributionSetTagRepository,
|
||||||
final DistributionSetRepository distributionSetRepository,
|
final DistributionSetRepository distributionSetRepository) {
|
||||||
final VirtualPropertyReplacer virtualPropertyReplacer, final Database database) {
|
|
||||||
this.distributionSetTagRepository = distributionSetTagRepository;
|
this.distributionSetTagRepository = distributionSetTagRepository;
|
||||||
this.distributionSetRepository = distributionSetRepository;
|
this.distributionSetRepository = distributionSetRepository;
|
||||||
this.virtualPropertyReplacer = virtualPropertyReplacer;
|
|
||||||
this.database = database;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -155,8 +148,7 @@ public class JpaDistributionSetTagManagement implements DistributionSetTagManage
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Page<DistributionSetTag> findByRsql(final String rsql, final Pageable pageable) {
|
public Page<DistributionSetTag> findByRsql(final String rsql, final Pageable pageable) {
|
||||||
final Specification<JpaDistributionSetTag> spec = RsqlUtility.buildRsqlSpecification(
|
final Specification<JpaDistributionSetTag> spec = RsqlUtility.getInstance().buildRsqlSpecification(rsql, DistributionSetTagFields.class);
|
||||||
rsql, DistributionSetTagFields.class, virtualPropertyReplacer, database);
|
|
||||||
return JpaManagementHelper.findAllWithCountBySpec(distributionSetTagRepository, Collections.singletonList(spec), pageable);
|
return JpaManagementHelper.findAllWithCountBySpec(distributionSetTagRepository, Collections.singletonList(spec), pageable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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.jpa.utils.QuotaHelper;
|
||||||
import org.eclipse.hawkbit.repository.model.DistributionSetType;
|
import org.eclipse.hawkbit.repository.model.DistributionSetType;
|
||||||
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
|
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
|
||||||
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
|
|
||||||
import org.springframework.dao.ConcurrencyFailureException;
|
import org.springframework.dao.ConcurrencyFailureException;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.data.domain.Slice;
|
import org.springframework.data.domain.Slice;
|
||||||
import org.springframework.orm.jpa.vendor.Database;
|
|
||||||
import org.springframework.retry.annotation.Backoff;
|
import org.springframework.retry.annotation.Backoff;
|
||||||
import org.springframework.retry.annotation.Retryable;
|
import org.springframework.retry.annotation.Retryable;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
@@ -67,22 +65,17 @@ public class JpaDistributionSetTypeManagement implements DistributionSetTypeMana
|
|||||||
private final SoftwareModuleTypeRepository softwareModuleTypeRepository;
|
private final SoftwareModuleTypeRepository softwareModuleTypeRepository;
|
||||||
private final DistributionSetRepository distributionSetRepository;
|
private final DistributionSetRepository distributionSetRepository;
|
||||||
private final TargetTypeRepository targetTypeRepository;
|
private final TargetTypeRepository targetTypeRepository;
|
||||||
private final VirtualPropertyReplacer virtualPropertyReplacer;
|
|
||||||
private final Database database;
|
|
||||||
private final QuotaManagement quotaManagement;
|
private final QuotaManagement quotaManagement;
|
||||||
|
|
||||||
public JpaDistributionSetTypeManagement(
|
public JpaDistributionSetTypeManagement(
|
||||||
final DistributionSetTypeRepository distributionSetTypeRepository,
|
final DistributionSetTypeRepository distributionSetTypeRepository,
|
||||||
final SoftwareModuleTypeRepository softwareModuleTypeRepository,
|
final SoftwareModuleTypeRepository softwareModuleTypeRepository,
|
||||||
final DistributionSetRepository distributionSetRepository, final TargetTypeRepository targetTypeRepository,
|
final DistributionSetRepository distributionSetRepository, final TargetTypeRepository targetTypeRepository,
|
||||||
final VirtualPropertyReplacer virtualPropertyReplacer, final Database database,
|
|
||||||
final QuotaManagement quotaManagement) {
|
final QuotaManagement quotaManagement) {
|
||||||
this.distributionSetTypeRepository = distributionSetTypeRepository;
|
this.distributionSetTypeRepository = distributionSetTypeRepository;
|
||||||
this.softwareModuleTypeRepository = softwareModuleTypeRepository;
|
this.softwareModuleTypeRepository = softwareModuleTypeRepository;
|
||||||
this.distributionSetRepository = distributionSetRepository;
|
this.distributionSetRepository = distributionSetRepository;
|
||||||
this.targetTypeRepository = targetTypeRepository;
|
this.targetTypeRepository = targetTypeRepository;
|
||||||
this.virtualPropertyReplacer = virtualPropertyReplacer;
|
|
||||||
this.database = database;
|
|
||||||
this.quotaManagement = quotaManagement;
|
this.quotaManagement = quotaManagement;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,7 +191,7 @@ public class JpaDistributionSetTypeManagement implements DistributionSetTypeMana
|
|||||||
@Override
|
@Override
|
||||||
public Page<DistributionSetType> findByRsql(final String rsql, final Pageable pageable) {
|
public Page<DistributionSetType> findByRsql(final String rsql, final Pageable pageable) {
|
||||||
return JpaManagementHelper.findAllWithCountBySpec(distributionSetTypeRepository, List.of(
|
return JpaManagementHelper.findAllWithCountBySpec(distributionSetTypeRepository, List.of(
|
||||||
RsqlUtility.buildRsqlSpecification(rsql, DistributionSetTypeFields.class, virtualPropertyReplacer, database),
|
RsqlUtility.getInstance().buildRsqlSpecification(rsql, DistributionSetTypeFields.class),
|
||||||
DistributionSetTypeSpecification.isNotDeleted()), pageable);
|
DistributionSetTypeSpecification.isNotDeleted()), pageable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -48,12 +48,10 @@ import org.eclipse.hawkbit.repository.model.RolloutGroup;
|
|||||||
import org.eclipse.hawkbit.repository.model.Target;
|
import org.eclipse.hawkbit.repository.model.Target;
|
||||||
import org.eclipse.hawkbit.repository.model.TotalTargetCountActionStatus;
|
import org.eclipse.hawkbit.repository.model.TotalTargetCountActionStatus;
|
||||||
import org.eclipse.hawkbit.repository.model.TotalTargetCountStatus;
|
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.Page;
|
||||||
import org.springframework.data.domain.PageImpl;
|
import org.springframework.data.domain.PageImpl;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.data.jpa.domain.Specification;
|
import org.springframework.data.jpa.domain.Specification;
|
||||||
import org.springframework.orm.jpa.vendor.Database;
|
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
@@ -70,24 +68,18 @@ public class JpaRolloutGroupManagement implements RolloutGroupManagement {
|
|||||||
private final ActionRepository actionRepository;
|
private final ActionRepository actionRepository;
|
||||||
private final TargetRepository targetRepository;
|
private final TargetRepository targetRepository;
|
||||||
private final EntityManager entityManager;
|
private final EntityManager entityManager;
|
||||||
private final VirtualPropertyReplacer virtualPropertyReplacer;
|
|
||||||
private final RolloutStatusCache rolloutStatusCache;
|
private final RolloutStatusCache rolloutStatusCache;
|
||||||
private final Database database;
|
|
||||||
|
|
||||||
@SuppressWarnings("java:S107")
|
@SuppressWarnings("java:S107")
|
||||||
public JpaRolloutGroupManagement(final RolloutGroupRepository rolloutGroupRepository,
|
public JpaRolloutGroupManagement(final RolloutGroupRepository rolloutGroupRepository,
|
||||||
final RolloutRepository rolloutRepository, final ActionRepository actionRepository,
|
final RolloutRepository rolloutRepository, final ActionRepository actionRepository,
|
||||||
final TargetRepository targetRepository, final EntityManager entityManager,
|
final TargetRepository targetRepository, final EntityManager entityManager, final RolloutStatusCache rolloutStatusCache) {
|
||||||
final VirtualPropertyReplacer virtualPropertyReplacer, final RolloutStatusCache rolloutStatusCache,
|
|
||||||
final Database database) {
|
|
||||||
this.rolloutGroupRepository = rolloutGroupRepository;
|
this.rolloutGroupRepository = rolloutGroupRepository;
|
||||||
this.rolloutRepository = rolloutRepository;
|
this.rolloutRepository = rolloutRepository;
|
||||||
this.actionRepository = actionRepository;
|
this.actionRepository = actionRepository;
|
||||||
this.targetRepository = targetRepository;
|
this.targetRepository = targetRepository;
|
||||||
this.entityManager = entityManager;
|
this.entityManager = entityManager;
|
||||||
this.virtualPropertyReplacer = virtualPropertyReplacer;
|
|
||||||
this.rolloutStatusCache = rolloutStatusCache;
|
this.rolloutStatusCache = rolloutStatusCache;
|
||||||
this.database = database;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -122,8 +114,7 @@ public class JpaRolloutGroupManagement implements RolloutGroupManagement {
|
|||||||
throwEntityNotFoundExceptionIfRolloutDoesNotExist(rolloutId);
|
throwEntityNotFoundExceptionIfRolloutDoesNotExist(rolloutId);
|
||||||
|
|
||||||
final List<Specification<JpaRolloutGroup>> specList = Arrays.asList(
|
final List<Specification<JpaRolloutGroup>> specList = Arrays.asList(
|
||||||
RsqlUtility.buildRsqlSpecification(rsql, RolloutGroupFields.class, virtualPropertyReplacer,
|
RsqlUtility.getInstance().buildRsqlSpecification(rsql, RolloutGroupFields.class),
|
||||||
database),
|
|
||||||
(root, query, cb) -> cb.equal(root.get(JpaRolloutGroup_.rollout).get(AbstractJpaBaseEntity_.id), rolloutId));
|
(root, query, cb) -> cb.equal(root.get(JpaRolloutGroup_.rollout).get(AbstractJpaBaseEntity_.id), rolloutId));
|
||||||
|
|
||||||
return JpaManagementHelper.findAllWithCountBySpec(rolloutGroupRepository, specList, pageable);
|
return JpaManagementHelper.findAllWithCountBySpec(rolloutGroupRepository, specList, pageable);
|
||||||
@@ -189,7 +180,7 @@ public class JpaRolloutGroupManagement implements RolloutGroupManagement {
|
|||||||
throwExceptionIfRolloutGroupDoesNotExist(rolloutGroupId);
|
throwExceptionIfRolloutGroupDoesNotExist(rolloutGroupId);
|
||||||
|
|
||||||
final List<Specification<JpaTarget>> specList = Arrays.asList(
|
final List<Specification<JpaTarget>> specList = Arrays.asList(
|
||||||
RsqlUtility.buildRsqlSpecification(rsql, TargetFields.class, virtualPropertyReplacer, database),
|
RsqlUtility.getInstance().buildRsqlSpecification(rsql, TargetFields.class),
|
||||||
(root, query, cb) -> {
|
(root, query, cb) -> {
|
||||||
final ListJoin<JpaTarget, RolloutTargetGroup> rolloutTargetJoin = root.join(JpaTarget_.rolloutTargetGroup);
|
final ListJoin<JpaTarget, RolloutTargetGroup> rolloutTargetJoin = root.join(JpaTarget_.rolloutTargetGroup);
|
||||||
return cb.equal(rolloutTargetJoin.get(RolloutTargetGroup_.rolloutGroup).get(AbstractJpaBaseEntity_.id), rolloutGroupId);
|
return cb.equal(rolloutTargetJoin.get(RolloutTargetGroup_.rolloutGroup).get(AbstractJpaBaseEntity_.id), rolloutGroupId);
|
||||||
|
|||||||
@@ -78,7 +78,6 @@ import org.eclipse.hawkbit.repository.model.RolloutGroupsValidation;
|
|||||||
import org.eclipse.hawkbit.repository.model.Target;
|
import org.eclipse.hawkbit.repository.model.Target;
|
||||||
import org.eclipse.hawkbit.repository.model.TotalTargetCountActionStatus;
|
import org.eclipse.hawkbit.repository.model.TotalTargetCountActionStatus;
|
||||||
import org.eclipse.hawkbit.repository.model.TotalTargetCountStatus;
|
import org.eclipse.hawkbit.repository.model.TotalTargetCountStatus;
|
||||||
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
|
|
||||||
import org.eclipse.hawkbit.security.SystemSecurityContext;
|
import org.eclipse.hawkbit.security.SystemSecurityContext;
|
||||||
import org.springframework.dao.ConcurrencyFailureException;
|
import org.springframework.dao.ConcurrencyFailureException;
|
||||||
import org.springframework.data.domain.Page;
|
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;
|
||||||
import org.springframework.data.domain.Sort.Direction;
|
import org.springframework.data.domain.Sort.Direction;
|
||||||
import org.springframework.data.jpa.domain.Specification;
|
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.Backoff;
|
||||||
import org.springframework.retry.annotation.Retryable;
|
import org.springframework.retry.annotation.Retryable;
|
||||||
import org.springframework.scheduling.annotation.Async;
|
import org.springframework.scheduling.annotation.Async;
|
||||||
@@ -120,10 +118,8 @@ public class JpaRolloutManagement implements RolloutManagement {
|
|||||||
private final TenantConfigurationManagement tenantConfigurationManagement;
|
private final TenantConfigurationManagement tenantConfigurationManagement;
|
||||||
private final QuotaManagement quotaManagement;
|
private final QuotaManagement quotaManagement;
|
||||||
private final AfterTransactionCommitExecutor afterCommit;
|
private final AfterTransactionCommitExecutor afterCommit;
|
||||||
private final VirtualPropertyReplacer virtualPropertyReplacer;
|
|
||||||
private final SystemSecurityContext systemSecurityContext;
|
private final SystemSecurityContext systemSecurityContext;
|
||||||
private final ContextAware contextAware;
|
private final ContextAware contextAware;
|
||||||
private final Database database;
|
|
||||||
private final RepositoryProperties repositoryProperties;
|
private final RepositoryProperties repositoryProperties;
|
||||||
|
|
||||||
@SuppressWarnings("java:S107")
|
@SuppressWarnings("java:S107")
|
||||||
@@ -139,8 +135,7 @@ public class JpaRolloutManagement implements RolloutManagement {
|
|||||||
final TenantConfigurationManagement tenantConfigurationManagement,
|
final TenantConfigurationManagement tenantConfigurationManagement,
|
||||||
final QuotaManagement quotaManagement,
|
final QuotaManagement quotaManagement,
|
||||||
final AfterTransactionCommitExecutor afterCommit,
|
final AfterTransactionCommitExecutor afterCommit,
|
||||||
final VirtualPropertyReplacer virtualPropertyReplacer,
|
final SystemSecurityContext systemSecurityContext, final ContextAware contextAware,
|
||||||
final SystemSecurityContext systemSecurityContext, final ContextAware contextAware, final Database database,
|
|
||||||
final RepositoryProperties repositoryProperties) {
|
final RepositoryProperties repositoryProperties) {
|
||||||
this.rolloutRepository = rolloutRepository;
|
this.rolloutRepository = rolloutRepository;
|
||||||
this.rolloutGroupRepository = rolloutGroupRepository;
|
this.rolloutGroupRepository = rolloutGroupRepository;
|
||||||
@@ -153,10 +148,8 @@ public class JpaRolloutManagement implements RolloutManagement {
|
|||||||
this.tenantConfigurationManagement = tenantConfigurationManagement;
|
this.tenantConfigurationManagement = tenantConfigurationManagement;
|
||||||
this.quotaManagement = quotaManagement;
|
this.quotaManagement = quotaManagement;
|
||||||
this.afterCommit = afterCommit;
|
this.afterCommit = afterCommit;
|
||||||
this.virtualPropertyReplacer = virtualPropertyReplacer;
|
|
||||||
this.systemSecurityContext = systemSecurityContext;
|
this.systemSecurityContext = systemSecurityContext;
|
||||||
this.contextAware = contextAware;
|
this.contextAware = contextAware;
|
||||||
this.database = database;
|
|
||||||
this.repositoryProperties = repositoryProperties;
|
this.repositoryProperties = repositoryProperties;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -273,7 +266,7 @@ public class JpaRolloutManagement implements RolloutManagement {
|
|||||||
@Override
|
@Override
|
||||||
public Page<Rollout> findByRsql(final String rsql, final boolean deleted, final Pageable pageable) {
|
public Page<Rollout> findByRsql(final String rsql, final boolean deleted, final Pageable pageable) {
|
||||||
final List<Specification<JpaRollout>> specList = List.of(
|
final List<Specification<JpaRollout>> specList = List.of(
|
||||||
RsqlUtility.buildRsqlSpecification(rsql, RolloutFields.class, virtualPropertyReplacer, database),
|
RsqlUtility.getInstance().buildRsqlSpecification(rsql, RolloutFields.class),
|
||||||
RolloutSpecification.isDeleted(deleted, pageable.getSort()));
|
RolloutSpecification.isDeleted(deleted, pageable.getSort()));
|
||||||
return JpaManagementHelper.convertPage(rolloutRepository.findAll(JpaManagementHelper.combineWithAnd(specList), pageable), pageable);
|
return JpaManagementHelper.convertPage(rolloutRepository.findAll(JpaManagementHelper.combineWithAnd(specList), pageable), pageable);
|
||||||
}
|
}
|
||||||
@@ -281,7 +274,7 @@ public class JpaRolloutManagement implements RolloutManagement {
|
|||||||
@Override
|
@Override
|
||||||
public Page<Rollout> findByRsqlWithDetailedStatus(final String rsql, final boolean deleted, final Pageable pageable) {
|
public Page<Rollout> findByRsqlWithDetailedStatus(final String rsql, final boolean deleted, final Pageable pageable) {
|
||||||
final List<Specification<JpaRollout>> specList = List.of(
|
final List<Specification<JpaRollout>> specList = List.of(
|
||||||
RsqlUtility.buildRsqlSpecification(rsql, RolloutFields.class, virtualPropertyReplacer, database),
|
RsqlUtility.getInstance().buildRsqlSpecification(rsql, RolloutFields.class),
|
||||||
RolloutSpecification.isDeleted(deleted, pageable.getSort()));
|
RolloutSpecification.isDeleted(deleted, pageable.getSort()));
|
||||||
return appendStatusDetails(JpaManagementHelper.convertPage(
|
return appendStatusDetails(JpaManagementHelper.convertPage(
|
||||||
rolloutRepository.findAll(JpaManagementHelper.combineWithAnd(specList), JpaRollout_.GRAPH_ROLLOUT_DS, pageable), pageable));
|
rolloutRepository.findAll(JpaManagementHelper.combineWithAnd(specList), JpaRollout_.GRAPH_ROLLOUT_DS, pageable), pageable));
|
||||||
|
|||||||
@@ -58,7 +58,6 @@ import org.eclipse.hawkbit.repository.model.DistributionSet;
|
|||||||
import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
||||||
import org.eclipse.hawkbit.repository.model.SoftwareModuleMetadata;
|
import org.eclipse.hawkbit.repository.model.SoftwareModuleMetadata;
|
||||||
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
|
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
|
||||||
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
|
|
||||||
import org.springframework.dao.ConcurrencyFailureException;
|
import org.springframework.dao.ConcurrencyFailureException;
|
||||||
import org.springframework.data.domain.AuditorAware;
|
import org.springframework.data.domain.AuditorAware;
|
||||||
import org.springframework.data.domain.Page;
|
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.Pageable;
|
||||||
import org.springframework.data.domain.Slice;
|
import org.springframework.data.domain.Slice;
|
||||||
import org.springframework.data.jpa.domain.Specification;
|
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.Backoff;
|
||||||
import org.springframework.retry.annotation.Retryable;
|
import org.springframework.retry.annotation.Retryable;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
@@ -89,8 +87,6 @@ public class JpaSoftwareModuleManagement implements SoftwareModuleManagement {
|
|||||||
private final AuditorAware<String> auditorProvider;
|
private final AuditorAware<String> auditorProvider;
|
||||||
private final ArtifactManagement artifactManagement;
|
private final ArtifactManagement artifactManagement;
|
||||||
private final QuotaManagement quotaManagement;
|
private final QuotaManagement quotaManagement;
|
||||||
private final VirtualPropertyReplacer virtualPropertyReplacer;
|
|
||||||
private final Database database;
|
|
||||||
|
|
||||||
@SuppressWarnings("java:S107")
|
@SuppressWarnings("java:S107")
|
||||||
public JpaSoftwareModuleManagement(final EntityManager entityManager,
|
public JpaSoftwareModuleManagement(final EntityManager entityManager,
|
||||||
@@ -98,9 +94,7 @@ public class JpaSoftwareModuleManagement implements SoftwareModuleManagement {
|
|||||||
final SoftwareModuleRepository softwareModuleRepository,
|
final SoftwareModuleRepository softwareModuleRepository,
|
||||||
final SoftwareModuleMetadataRepository softwareModuleMetadataRepository,
|
final SoftwareModuleMetadataRepository softwareModuleMetadataRepository,
|
||||||
final SoftwareModuleTypeRepository softwareModuleTypeRepository, final AuditorAware<String> auditorProvider,
|
final SoftwareModuleTypeRepository softwareModuleTypeRepository, final AuditorAware<String> auditorProvider,
|
||||||
final ArtifactManagement artifactManagement, final QuotaManagement quotaManagement,
|
final ArtifactManagement artifactManagement, final QuotaManagement quotaManagement) {
|
||||||
final VirtualPropertyReplacer virtualPropertyReplacer,
|
|
||||||
final Database database) {
|
|
||||||
this.entityManager = entityManager;
|
this.entityManager = entityManager;
|
||||||
this.distributionSetRepository = distributionSetRepository;
|
this.distributionSetRepository = distributionSetRepository;
|
||||||
this.softwareModuleRepository = softwareModuleRepository;
|
this.softwareModuleRepository = softwareModuleRepository;
|
||||||
@@ -109,8 +103,6 @@ public class JpaSoftwareModuleManagement implements SoftwareModuleManagement {
|
|||||||
this.auditorProvider = auditorProvider;
|
this.auditorProvider = auditorProvider;
|
||||||
this.artifactManagement = artifactManagement;
|
this.artifactManagement = artifactManagement;
|
||||||
this.quotaManagement = quotaManagement;
|
this.quotaManagement = quotaManagement;
|
||||||
this.virtualPropertyReplacer = virtualPropertyReplacer;
|
|
||||||
this.database = database;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -261,8 +253,7 @@ public class JpaSoftwareModuleManagement implements SoftwareModuleManagement {
|
|||||||
@Override
|
@Override
|
||||||
public Page<SoftwareModule> findByRsql(final String rsql, final Pageable pageable) {
|
public Page<SoftwareModule> findByRsql(final String rsql, final Pageable pageable) {
|
||||||
return JpaManagementHelper.findAllWithCountBySpec(softwareModuleRepository, List.of(
|
return JpaManagementHelper.findAllWithCountBySpec(softwareModuleRepository, List.of(
|
||||||
RsqlUtility.buildRsqlSpecification(rsql, SoftwareModuleFields.class, virtualPropertyReplacer,
|
RsqlUtility.getInstance().buildRsqlSpecification(rsql, SoftwareModuleFields.class),
|
||||||
database),
|
|
||||||
SoftwareModuleSpecification.isNotDeleted()), pageable);
|
SoftwareModuleSpecification.isNotDeleted()), pageable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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.rsql.RsqlUtility;
|
||||||
import org.eclipse.hawkbit.repository.jpa.specifications.SoftwareModuleTypeSpecification;
|
import org.eclipse.hawkbit.repository.jpa.specifications.SoftwareModuleTypeSpecification;
|
||||||
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
|
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
|
||||||
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
|
|
||||||
import org.springframework.dao.ConcurrencyFailureException;
|
import org.springframework.dao.ConcurrencyFailureException;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.data.domain.Slice;
|
import org.springframework.data.domain.Slice;
|
||||||
import org.springframework.orm.jpa.vendor.Database;
|
|
||||||
import org.springframework.retry.annotation.Backoff;
|
import org.springframework.retry.annotation.Backoff;
|
||||||
import org.springframework.retry.annotation.Retryable;
|
import org.springframework.retry.annotation.Retryable;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
@@ -51,20 +49,15 @@ public class JpaSoftwareModuleTypeManagement implements SoftwareModuleTypeManage
|
|||||||
|
|
||||||
private final DistributionSetTypeRepository distributionSetTypeRepository;
|
private final DistributionSetTypeRepository distributionSetTypeRepository;
|
||||||
private final SoftwareModuleTypeRepository softwareModuleTypeRepository;
|
private final SoftwareModuleTypeRepository softwareModuleTypeRepository;
|
||||||
private final VirtualPropertyReplacer virtualPropertyReplacer;
|
|
||||||
private final SoftwareModuleRepository softwareModuleRepository;
|
private final SoftwareModuleRepository softwareModuleRepository;
|
||||||
private final Database database;
|
|
||||||
|
|
||||||
public JpaSoftwareModuleTypeManagement(final DistributionSetTypeRepository distributionSetTypeRepository,
|
public JpaSoftwareModuleTypeManagement(
|
||||||
|
final DistributionSetTypeRepository distributionSetTypeRepository,
|
||||||
final SoftwareModuleTypeRepository softwareModuleTypeRepository,
|
final SoftwareModuleTypeRepository softwareModuleTypeRepository,
|
||||||
final VirtualPropertyReplacer virtualPropertyReplacer,
|
final SoftwareModuleRepository softwareModuleRepository) {
|
||||||
final SoftwareModuleRepository softwareModuleRepository,
|
|
||||||
final Database database) {
|
|
||||||
this.distributionSetTypeRepository = distributionSetTypeRepository;
|
this.distributionSetTypeRepository = distributionSetTypeRepository;
|
||||||
this.softwareModuleTypeRepository = softwareModuleTypeRepository;
|
this.softwareModuleTypeRepository = softwareModuleTypeRepository;
|
||||||
this.virtualPropertyReplacer = virtualPropertyReplacer;
|
|
||||||
this.softwareModuleRepository = softwareModuleRepository;
|
this.softwareModuleRepository = softwareModuleRepository;
|
||||||
this.database = database;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -144,8 +137,7 @@ public class JpaSoftwareModuleTypeManagement implements SoftwareModuleTypeManage
|
|||||||
@Override
|
@Override
|
||||||
public Page<SoftwareModuleType> findByRsql(final String rsql, final Pageable pageable) {
|
public Page<SoftwareModuleType> findByRsql(final String rsql, final Pageable pageable) {
|
||||||
return JpaManagementHelper.findAllWithCountBySpec(softwareModuleTypeRepository, List.of(
|
return JpaManagementHelper.findAllWithCountBySpec(softwareModuleTypeRepository, List.of(
|
||||||
RsqlUtility.buildRsqlSpecification(rsql, SoftwareModuleTypeFields.class,
|
RsqlUtility.getInstance().buildRsqlSpecification(rsql, SoftwareModuleTypeFields.class),
|
||||||
virtualPropertyReplacer, database),
|
|
||||||
SoftwareModuleTypeSpecification.isNotDeleted()), pageable
|
SoftwareModuleTypeSpecification.isNotDeleted()), pageable
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ import java.util.Collections;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
import jakarta.persistence.EntityManager;
|
|
||||||
import jakarta.validation.constraints.NotNull;
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
|
||||||
import cz.jirutka.rsql.parser.RSQLParserException;
|
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.DistributionSet;
|
||||||
import org.eclipse.hawkbit.repository.model.Target;
|
import org.eclipse.hawkbit.repository.model.Target;
|
||||||
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
|
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
|
||||||
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
|
|
||||||
import org.eclipse.hawkbit.security.SystemSecurityContext;
|
import org.eclipse.hawkbit.security.SystemSecurityContext;
|
||||||
import org.eclipse.hawkbit.utils.TenantConfigHelper;
|
import org.eclipse.hawkbit.utils.TenantConfigHelper;
|
||||||
import org.springframework.dao.ConcurrencyFailureException;
|
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.Pageable;
|
||||||
import org.springframework.data.domain.Slice;
|
import org.springframework.data.domain.Slice;
|
||||||
import org.springframework.data.jpa.domain.Specification;
|
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.Backoff;
|
||||||
import org.springframework.retry.annotation.Retryable;
|
import org.springframework.retry.annotation.Retryable;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
@@ -77,7 +74,6 @@ public class JpaTargetFilterQueryManagement implements TargetFilterQueryManageme
|
|||||||
|
|
||||||
private final TargetFilterQueryRepository targetFilterQueryRepository;
|
private final TargetFilterQueryRepository targetFilterQueryRepository;
|
||||||
private final TargetManagement targetManagement;
|
private final TargetManagement targetManagement;
|
||||||
private final VirtualPropertyReplacer virtualPropertyReplacer;
|
|
||||||
private final DistributionSetManagement distributionSetManagement;
|
private final DistributionSetManagement distributionSetManagement;
|
||||||
private final QuotaManagement quotaManagement;
|
private final QuotaManagement quotaManagement;
|
||||||
private final TenantConfigurationManagement tenantConfigurationManagement;
|
private final TenantConfigurationManagement tenantConfigurationManagement;
|
||||||
@@ -85,29 +81,23 @@ public class JpaTargetFilterQueryManagement implements TargetFilterQueryManageme
|
|||||||
private final SystemSecurityContext systemSecurityContext;
|
private final SystemSecurityContext systemSecurityContext;
|
||||||
private final ContextAware contextAware;
|
private final ContextAware contextAware;
|
||||||
private final AuditorAware<String> auditorAware;
|
private final AuditorAware<String> auditorAware;
|
||||||
private final EntityManager entityManager;
|
|
||||||
private final Database database;
|
|
||||||
|
|
||||||
@SuppressWarnings("java:S107")
|
@SuppressWarnings("java:S107")
|
||||||
public JpaTargetFilterQueryManagement(final TargetFilterQueryRepository targetFilterQueryRepository,
|
public JpaTargetFilterQueryManagement(
|
||||||
final TargetManagement targetManagement, final VirtualPropertyReplacer virtualPropertyReplacer,
|
final TargetFilterQueryRepository targetFilterQueryRepository,
|
||||||
final DistributionSetManagement distributionSetManagement, final QuotaManagement quotaManagement,
|
final TargetManagement targetManagement, final DistributionSetManagement distributionSetManagement,
|
||||||
final Database database, final TenantConfigurationManagement tenantConfigurationManagement,
|
final QuotaManagement quotaManagement, final TenantConfigurationManagement tenantConfigurationManagement,
|
||||||
final RepositoryProperties repositoryProperties,
|
final RepositoryProperties repositoryProperties,
|
||||||
final SystemSecurityContext systemSecurityContext, final ContextAware contextAware, final AuditorAware<String> auditorAware,
|
final SystemSecurityContext systemSecurityContext, final ContextAware contextAware, final AuditorAware<String> auditorAware) {
|
||||||
final EntityManager entityManager) {
|
|
||||||
this.targetFilterQueryRepository = targetFilterQueryRepository;
|
this.targetFilterQueryRepository = targetFilterQueryRepository;
|
||||||
this.targetManagement = targetManagement;
|
this.targetManagement = targetManagement;
|
||||||
this.virtualPropertyReplacer = virtualPropertyReplacer;
|
|
||||||
this.distributionSetManagement = distributionSetManagement;
|
this.distributionSetManagement = distributionSetManagement;
|
||||||
this.quotaManagement = quotaManagement;
|
this.quotaManagement = quotaManagement;
|
||||||
this.database = database;
|
|
||||||
this.tenantConfigurationManagement = tenantConfigurationManagement;
|
this.tenantConfigurationManagement = tenantConfigurationManagement;
|
||||||
this.repositoryProperties = repositoryProperties;
|
this.repositoryProperties = repositoryProperties;
|
||||||
this.systemSecurityContext = systemSecurityContext;
|
this.systemSecurityContext = systemSecurityContext;
|
||||||
this.contextAware = contextAware;
|
this.contextAware = contextAware;
|
||||||
this.auditorAware = auditorAware;
|
this.auditorAware = auditorAware;
|
||||||
this.entityManager = entityManager;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -119,7 +109,7 @@ public class JpaTargetFilterQueryManagement implements TargetFilterQueryManageme
|
|||||||
|
|
||||||
create.getQuery().ifPresent(query -> {
|
create.getQuery().ifPresent(query -> {
|
||||||
// validate the RSQL query syntax
|
// 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
|
// enforce the 'max targets per auto assign' quota right here even
|
||||||
// if the result of the filter query can vary over time
|
// if the result of the filter query can vary over time
|
||||||
@@ -148,7 +138,7 @@ public class JpaTargetFilterQueryManagement implements TargetFilterQueryManageme
|
|||||||
@Override
|
@Override
|
||||||
public boolean verifyTargetFilterQuerySyntax(final String query) {
|
public boolean verifyTargetFilterQuerySyntax(final String query) {
|
||||||
try {
|
try {
|
||||||
RsqlUtility.validateRsqlFor(query, TargetFields.class, JpaTarget.class, virtualPropertyReplacer, entityManager);
|
RsqlUtility.getInstance().validateRsqlFor(query, TargetFields.class, JpaTarget.class);
|
||||||
return true;
|
return true;
|
||||||
} catch (final RSQLParserException | RSQLParameterUnsupportedFieldException e) {
|
} catch (final RSQLParserException | RSQLParameterUnsupportedFieldException e) {
|
||||||
log.debug("The RSQL query '{}}' is invalid.", query, e);
|
log.debug("The RSQL query '{}}' is invalid.", query, e);
|
||||||
@@ -195,8 +185,7 @@ public class JpaTargetFilterQueryManagement implements TargetFilterQueryManageme
|
|||||||
@Override
|
@Override
|
||||||
public Page<TargetFilterQuery> findByRsql(final String rsqlFilter, final Pageable pageable) {
|
public Page<TargetFilterQuery> findByRsql(final String rsqlFilter, final Pageable pageable) {
|
||||||
final List<Specification<JpaTargetFilterQuery>> specList = !ObjectUtils.isEmpty(rsqlFilter)
|
final List<Specification<JpaTargetFilterQuery>> specList = !ObjectUtils.isEmpty(rsqlFilter)
|
||||||
? Collections.singletonList(RsqlUtility.buildRsqlSpecification(rsqlFilter,
|
? Collections.singletonList(RsqlUtility.getInstance().buildRsqlSpecification(rsqlFilter, TargetFilterQueryFields.class))
|
||||||
TargetFilterQueryFields.class, virtualPropertyReplacer, database))
|
|
||||||
: Collections.emptyList();
|
: Collections.emptyList();
|
||||||
|
|
||||||
return JpaManagementHelper.findAllWithCountBySpec(targetFilterQueryRepository, specList, pageable);
|
return JpaManagementHelper.findAllWithCountBySpec(targetFilterQueryRepository, specList, pageable);
|
||||||
@@ -227,8 +216,7 @@ public class JpaTargetFilterQueryManagement implements TargetFilterQueryManageme
|
|||||||
final List<Specification<JpaTargetFilterQuery>> specList = new ArrayList<>(2);
|
final List<Specification<JpaTargetFilterQuery>> specList = new ArrayList<>(2);
|
||||||
specList.add(TargetFilterQuerySpecification.byAutoAssignDS(distributionSet));
|
specList.add(TargetFilterQuerySpecification.byAutoAssignDS(distributionSet));
|
||||||
if (!ObjectUtils.isEmpty(rsql)) {
|
if (!ObjectUtils.isEmpty(rsql)) {
|
||||||
specList.add(RsqlUtility.buildRsqlSpecification(rsql, TargetFilterQueryFields.class,
|
specList.add(RsqlUtility.getInstance().buildRsqlSpecification(rsql, TargetFilterQueryFields.class));
|
||||||
virtualPropertyReplacer, database));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return JpaManagementHelper.findAllWithCountBySpec(targetFilterQueryRepository, specList, pageable);
|
return JpaManagementHelper.findAllWithCountBySpec(targetFilterQueryRepository, specList, pageable);
|
||||||
|
|||||||
@@ -74,14 +74,12 @@ import org.eclipse.hawkbit.repository.model.TargetTag;
|
|||||||
import org.eclipse.hawkbit.repository.model.TargetType;
|
import org.eclipse.hawkbit.repository.model.TargetType;
|
||||||
import org.eclipse.hawkbit.repository.model.TargetTypeAssignmentResult;
|
import org.eclipse.hawkbit.repository.model.TargetTypeAssignmentResult;
|
||||||
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
|
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
|
||||||
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
|
|
||||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
import org.eclipse.hawkbit.tenancy.TenantAware;
|
||||||
import org.springframework.dao.ConcurrencyFailureException;
|
import org.springframework.dao.ConcurrencyFailureException;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.data.domain.Slice;
|
import org.springframework.data.domain.Slice;
|
||||||
import org.springframework.data.jpa.domain.Specification;
|
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.Backoff;
|
||||||
import org.springframework.retry.annotation.Retryable;
|
import org.springframework.retry.annotation.Retryable;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
@@ -104,8 +102,6 @@ public class JpaTargetManagement implements TargetManagement {
|
|||||||
private final TargetFilterQueryRepository targetFilterQueryRepository;
|
private final TargetFilterQueryRepository targetFilterQueryRepository;
|
||||||
private final TargetTagRepository targetTagRepository;
|
private final TargetTagRepository targetTagRepository;
|
||||||
private final TenantAware tenantAware;
|
private final TenantAware tenantAware;
|
||||||
private final VirtualPropertyReplacer virtualPropertyReplacer;
|
|
||||||
private final Database database;
|
|
||||||
|
|
||||||
@SuppressWarnings("java:S107")
|
@SuppressWarnings("java:S107")
|
||||||
public JpaTargetManagement(final EntityManager entityManager,
|
public JpaTargetManagement(final EntityManager entityManager,
|
||||||
@@ -114,8 +110,7 @@ public class JpaTargetManagement implements TargetManagement {
|
|||||||
final RolloutGroupRepository rolloutGroupRepository,
|
final RolloutGroupRepository rolloutGroupRepository,
|
||||||
final TargetFilterQueryRepository targetFilterQueryRepository,
|
final TargetFilterQueryRepository targetFilterQueryRepository,
|
||||||
final TargetTagRepository targetTagRepository,
|
final TargetTagRepository targetTagRepository,
|
||||||
final TenantAware tenantAware, final VirtualPropertyReplacer virtualPropertyReplacer,
|
final TenantAware tenantAware) {
|
||||||
final Database database) {
|
|
||||||
this.entityManager = entityManager;
|
this.entityManager = entityManager;
|
||||||
this.distributionSetManagement = distributionSetManagement;
|
this.distributionSetManagement = distributionSetManagement;
|
||||||
this.quotaManagement = quotaManagement;
|
this.quotaManagement = quotaManagement;
|
||||||
@@ -125,8 +120,6 @@ public class JpaTargetManagement implements TargetManagement {
|
|||||||
this.targetFilterQueryRepository = targetFilterQueryRepository;
|
this.targetFilterQueryRepository = targetFilterQueryRepository;
|
||||||
this.targetTagRepository = targetTagRepository;
|
this.targetTagRepository = targetTagRepository;
|
||||||
this.tenantAware = tenantAware;
|
this.tenantAware = tenantAware;
|
||||||
this.virtualPropertyReplacer = virtualPropertyReplacer;
|
|
||||||
this.database = database;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -157,22 +150,20 @@ public class JpaTargetManagement implements TargetManagement {
|
|||||||
public long countByRsql(final String rsql) {
|
public long countByRsql(final String rsql) {
|
||||||
return JpaManagementHelper.countBySpec(
|
return JpaManagementHelper.countBySpec(
|
||||||
targetRepository,
|
targetRepository,
|
||||||
List.of(RsqlUtility.buildRsqlSpecification(rsql, TargetFields.class, virtualPropertyReplacer, database)));
|
List.of(RsqlUtility.getInstance().buildRsqlSpecification(rsql, TargetFields.class)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long countByRsqlAndUpdatable(String rsql) {
|
public long countByRsqlAndUpdatable(String rsql) {
|
||||||
final List<Specification<JpaTarget>> specList = List.of(
|
final List<Specification<JpaTarget>> specList = List.of(
|
||||||
RsqlUtility.buildRsqlSpecification(rsql, TargetFields.class, virtualPropertyReplacer, database));
|
RsqlUtility.getInstance().buildRsqlSpecification(rsql, TargetFields.class));
|
||||||
return targetRepository.count(
|
return targetRepository.count(AccessController.Operation.UPDATE, combineWithAnd(specList));
|
||||||
AccessController.Operation.UPDATE,
|
|
||||||
combineWithAnd(specList));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long countByRsqlAndCompatible(final String rsql, final Long distributionSetIdTypeId) {
|
public long countByRsqlAndCompatible(final String rsql, final Long distributionSetIdTypeId) {
|
||||||
final List<Specification<JpaTarget>> specList = List.of(
|
final List<Specification<JpaTarget>> specList = List.of(
|
||||||
RsqlUtility.buildRsqlSpecification(rsql, TargetFields.class, virtualPropertyReplacer, database),
|
RsqlUtility.getInstance().buildRsqlSpecification(rsql, TargetFields.class),
|
||||||
TargetSpecifications.isCompatibleWithDistributionSetType(distributionSetIdTypeId));
|
TargetSpecifications.isCompatibleWithDistributionSetType(distributionSetIdTypeId));
|
||||||
return JpaManagementHelper.countBySpec(targetRepository, specList);
|
return JpaManagementHelper.countBySpec(targetRepository, specList);
|
||||||
}
|
}
|
||||||
@@ -180,7 +171,7 @@ public class JpaTargetManagement implements TargetManagement {
|
|||||||
@Override
|
@Override
|
||||||
public long countByRsqlAndCompatibleAndUpdatable(String rsql, Long distributionSetIdTypeId) {
|
public long countByRsqlAndCompatibleAndUpdatable(String rsql, Long distributionSetIdTypeId) {
|
||||||
final List<Specification<JpaTarget>> specList = List.of(
|
final List<Specification<JpaTarget>> specList = List.of(
|
||||||
RsqlUtility.buildRsqlSpecification(rsql, TargetFields.class, virtualPropertyReplacer, database),
|
RsqlUtility.getInstance().buildRsqlSpecification(rsql, TargetFields.class),
|
||||||
TargetSpecifications.isCompatibleWithDistributionSetType(distributionSetIdTypeId));
|
TargetSpecifications.isCompatibleWithDistributionSetType(distributionSetIdTypeId));
|
||||||
return targetRepository.count(AccessController.Operation.UPDATE, combineWithAnd(specList));
|
return targetRepository.count(AccessController.Operation.UPDATE, combineWithAnd(specList));
|
||||||
}
|
}
|
||||||
@@ -253,7 +244,7 @@ public class JpaTargetManagement implements TargetManagement {
|
|||||||
.findAllWithoutCount(
|
.findAllWithoutCount(
|
||||||
AccessController.Operation.UPDATE,
|
AccessController.Operation.UPDATE,
|
||||||
combineWithAnd(List.of(
|
combineWithAnd(List.of(
|
||||||
RsqlUtility.buildRsqlSpecification(rsql, TargetFields.class, virtualPropertyReplacer, database),
|
RsqlUtility.getInstance().buildRsqlSpecification(rsql, TargetFields.class),
|
||||||
TargetSpecifications.hasNotDistributionSetInActions(distributionSetId),
|
TargetSpecifications.hasNotDistributionSetInActions(distributionSetId),
|
||||||
TargetSpecifications.isCompatibleWithDistributionSetType(distSetTypeId))),
|
TargetSpecifications.isCompatibleWithDistributionSetType(distSetTypeId))),
|
||||||
pageable)
|
pageable)
|
||||||
@@ -268,8 +259,7 @@ public class JpaTargetManagement implements TargetManagement {
|
|||||||
return targetRepository.count(
|
return targetRepository.count(
|
||||||
AccessController.Operation.UPDATE,
|
AccessController.Operation.UPDATE,
|
||||||
combineWithAnd(List.of(
|
combineWithAnd(List.of(
|
||||||
RsqlUtility.buildRsqlSpecification(
|
RsqlUtility.getInstance().buildRsqlSpecification(rsql, TargetFields.class),
|
||||||
rsql, TargetFields.class, virtualPropertyReplacer, database),
|
|
||||||
TargetSpecifications.hasNotDistributionSetInActions(distributionSetId),
|
TargetSpecifications.hasNotDistributionSetInActions(distributionSetId),
|
||||||
TargetSpecifications.isCompatibleWithDistributionSetType(distSetTypeId))));
|
TargetSpecifications.isCompatibleWithDistributionSetType(distSetTypeId))));
|
||||||
}
|
}
|
||||||
@@ -280,7 +270,7 @@ public class JpaTargetManagement implements TargetManagement {
|
|||||||
return targetRepository
|
return targetRepository
|
||||||
.findAllWithoutCount(AccessController.Operation.UPDATE,
|
.findAllWithoutCount(AccessController.Operation.UPDATE,
|
||||||
combineWithAnd(List.of(
|
combineWithAnd(List.of(
|
||||||
RsqlUtility.buildRsqlSpecification(rsql, TargetFields.class, virtualPropertyReplacer, database),
|
RsqlUtility.getInstance().buildRsqlSpecification(rsql, TargetFields.class),
|
||||||
TargetSpecifications.isNotInRolloutGroups(groups),
|
TargetSpecifications.isNotInRolloutGroups(groups),
|
||||||
TargetSpecifications.isCompatibleWithDistributionSetType(dsType.getId()))),
|
TargetSpecifications.isCompatibleWithDistributionSetType(dsType.getId()))),
|
||||||
pageable)
|
pageable)
|
||||||
@@ -292,7 +282,7 @@ public class JpaTargetManagement implements TargetManagement {
|
|||||||
final String rsql, final Collection<Long> groups, final DistributionSetType dsType) {
|
final String rsql, final Collection<Long> groups, final DistributionSetType dsType) {
|
||||||
return targetRepository.count(AccessController.Operation.UPDATE,
|
return targetRepository.count(AccessController.Operation.UPDATE,
|
||||||
combineWithAnd(List.of(
|
combineWithAnd(List.of(
|
||||||
RsqlUtility.buildRsqlSpecification(rsql, TargetFields.class, virtualPropertyReplacer, database),
|
RsqlUtility.getInstance().buildRsqlSpecification(rsql, TargetFields.class),
|
||||||
TargetSpecifications.isNotInRolloutGroups(groups),
|
TargetSpecifications.isNotInRolloutGroups(groups),
|
||||||
TargetSpecifications.isCompatibleWithDistributionSetType(dsType.getId()))));
|
TargetSpecifications.isCompatibleWithDistributionSetType(dsType.getId()))));
|
||||||
}
|
}
|
||||||
@@ -319,7 +309,7 @@ public class JpaTargetManagement implements TargetManagement {
|
|||||||
return targetRepository
|
return targetRepository
|
||||||
.findAllWithoutCount(AccessController.Operation.UPDATE,
|
.findAllWithoutCount(AccessController.Operation.UPDATE,
|
||||||
combineWithAnd(List.of(
|
combineWithAnd(List.of(
|
||||||
RsqlUtility.buildRsqlSpecification(rsql, TargetFields.class, virtualPropertyReplacer, database),
|
RsqlUtility.getInstance().buildRsqlSpecification(rsql, TargetFields.class),
|
||||||
TargetSpecifications.hasNoOverridingActionsAndNotInRollout(rolloutId),
|
TargetSpecifications.hasNoOverridingActionsAndNotInRollout(rolloutId),
|
||||||
TargetSpecifications.isCompatibleWithDistributionSetType(distributionSetType.getId()))),
|
TargetSpecifications.isCompatibleWithDistributionSetType(distributionSetType.getId()))),
|
||||||
pageable)
|
pageable)
|
||||||
@@ -355,7 +345,7 @@ public class JpaTargetManagement implements TargetManagement {
|
|||||||
final DistributionSet validDistSet = distributionSetManagement.getOrElseThrowException(distributionSetId);
|
final DistributionSet validDistSet = distributionSetManagement.getOrElseThrowException(distributionSetId);
|
||||||
|
|
||||||
final List<Specification<JpaTarget>> specList = List.of(
|
final List<Specification<JpaTarget>> specList = List.of(
|
||||||
RsqlUtility.buildRsqlSpecification(rsql, TargetFields.class, virtualPropertyReplacer, database),
|
RsqlUtility.getInstance().buildRsqlSpecification(rsql, TargetFields.class),
|
||||||
TargetSpecifications.hasAssignedDistributionSet(validDistSet.getId()));
|
TargetSpecifications.hasAssignedDistributionSet(validDistSet.getId()));
|
||||||
|
|
||||||
return JpaManagementHelper.findAllWithCountBySpec(targetRepository, specList, pageable);
|
return JpaManagementHelper.findAllWithCountBySpec(targetRepository, specList, pageable);
|
||||||
@@ -395,7 +385,7 @@ public class JpaTargetManagement implements TargetManagement {
|
|||||||
final DistributionSet validDistSet = distributionSetManagement.getOrElseThrowException(distributionSetId);
|
final DistributionSet validDistSet = distributionSetManagement.getOrElseThrowException(distributionSetId);
|
||||||
|
|
||||||
final List<Specification<JpaTarget>> specList = List.of(
|
final List<Specification<JpaTarget>> specList = List.of(
|
||||||
RsqlUtility.buildRsqlSpecification(rsql, TargetFields.class, virtualPropertyReplacer, database),
|
RsqlUtility.getInstance().buildRsqlSpecification(rsql, TargetFields.class),
|
||||||
TargetSpecifications.hasInstalledDistributionSet(validDistSet.getId()));
|
TargetSpecifications.hasInstalledDistributionSet(validDistSet.getId()));
|
||||||
|
|
||||||
return JpaManagementHelper.findAllWithCountBySpec(targetRepository, specList, pageable);
|
return JpaManagementHelper.findAllWithCountBySpec(targetRepository, specList, pageable);
|
||||||
@@ -416,7 +406,7 @@ public class JpaTargetManagement implements TargetManagement {
|
|||||||
public Slice<Target> findByRsql(final String rsql, final Pageable pageable) {
|
public Slice<Target> findByRsql(final String rsql, final Pageable pageable) {
|
||||||
return JpaManagementHelper.findAllWithoutCountBySpec(
|
return JpaManagementHelper.findAllWithoutCountBySpec(
|
||||||
targetRepository,
|
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));
|
.orElseThrow(() -> new EntityNotFoundException(TargetFilterQuery.class, targetFilterQueryId));
|
||||||
|
|
||||||
return JpaManagementHelper.findAllWithoutCountBySpec(
|
return JpaManagementHelper.findAllWithoutCountBySpec(
|
||||||
targetRepository, List.of(RsqlUtility.buildRsqlSpecification(
|
targetRepository, List.of(RsqlUtility.getInstance().buildRsqlSpecification(
|
||||||
targetFilterQuery.getQuery(), TargetFields.class, virtualPropertyReplacer, database)), pageable
|
targetFilterQuery.getQuery(), TargetFields.class)), pageable
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -442,7 +432,7 @@ public class JpaTargetManagement implements TargetManagement {
|
|||||||
throwEntityNotFoundExceptionIfTagDoesNotExist(tagId);
|
throwEntityNotFoundExceptionIfTagDoesNotExist(tagId);
|
||||||
|
|
||||||
final List<Specification<JpaTarget>> specList = List.of(
|
final List<Specification<JpaTarget>> specList = List.of(
|
||||||
RsqlUtility.buildRsqlSpecification(rsql, TargetFields.class, virtualPropertyReplacer, database),
|
RsqlUtility.getInstance().buildRsqlSpecification(rsql, TargetFields.class),
|
||||||
TargetSpecifications.hasTag(tagId));
|
TargetSpecifications.hasTag(tagId));
|
||||||
|
|
||||||
return JpaManagementHelper.findAllWithCountBySpec(targetRepository, specList, pageable);
|
return JpaManagementHelper.findAllWithCountBySpec(targetRepository, specList, pageable);
|
||||||
@@ -611,12 +601,12 @@ public class JpaTargetManagement implements TargetManagement {
|
|||||||
@Override
|
@Override
|
||||||
public boolean isTargetMatchingQueryAndDSNotAssignedAndCompatibleAndUpdatable(
|
public boolean isTargetMatchingQueryAndDSNotAssignedAndCompatibleAndUpdatable(
|
||||||
final String controllerId, final long distributionSetId, final String targetFilterQuery) {
|
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)
|
final DistributionSet ds = distributionSetManagement.get(distributionSetId)
|
||||||
.orElseThrow(() -> new EntityNotFoundException(DistributionSet.class, distributionSetId));
|
.orElseThrow(() -> new EntityNotFoundException(DistributionSet.class, distributionSetId));
|
||||||
final Long distSetTypeId = ds.getType().getId();
|
final Long distSetTypeId = ds.getType().getId();
|
||||||
final List<Specification<JpaTarget>> specList = List.of(
|
final List<Specification<JpaTarget>> specList = List.of(
|
||||||
RsqlUtility.buildRsqlSpecification(targetFilterQuery, TargetFields.class, virtualPropertyReplacer, database),
|
RsqlUtility.getInstance().buildRsqlSpecification(targetFilterQuery, TargetFields.class),
|
||||||
TargetSpecifications.hasNotDistributionSetInActions(distributionSetId),
|
TargetSpecifications.hasNotDistributionSetInActions(distributionSetId),
|
||||||
TargetSpecifications.isCompatibleWithDistributionSetType(distSetTypeId),
|
TargetSpecifications.isCompatibleWithDistributionSetType(distSetTypeId),
|
||||||
TargetSpecifications.hasControllerId(controllerId));
|
TargetSpecifications.hasControllerId(controllerId));
|
||||||
|
|||||||
@@ -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.repository.TargetTagRepository;
|
||||||
import org.eclipse.hawkbit.repository.jpa.rsql.RsqlUtility;
|
import org.eclipse.hawkbit.repository.jpa.rsql.RsqlUtility;
|
||||||
import org.eclipse.hawkbit.repository.model.TargetTag;
|
import org.eclipse.hawkbit.repository.model.TargetTag;
|
||||||
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
|
|
||||||
import org.springframework.dao.ConcurrencyFailureException;
|
import org.springframework.dao.ConcurrencyFailureException;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.orm.jpa.vendor.Database;
|
|
||||||
import org.springframework.retry.annotation.Backoff;
|
import org.springframework.retry.annotation.Backoff;
|
||||||
import org.springframework.retry.annotation.Retryable;
|
import org.springframework.retry.annotation.Retryable;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
@@ -48,16 +46,8 @@ public class JpaTargetTagManagement implements TargetTagManagement {
|
|||||||
|
|
||||||
private final TargetTagRepository targetTagRepository;
|
private final TargetTagRepository targetTagRepository;
|
||||||
|
|
||||||
private final VirtualPropertyReplacer virtualPropertyReplacer;
|
public JpaTargetTagManagement(final TargetTagRepository targetTagRepository) {
|
||||||
private final Database database;
|
this.targetTagRepository = targetTagRepository;;
|
||||||
|
|
||||||
public JpaTargetTagManagement(
|
|
||||||
final TargetTagRepository targetTagRepository,
|
|
||||||
final VirtualPropertyReplacer virtualPropertyReplacer,
|
|
||||||
final Database database) {
|
|
||||||
this.targetTagRepository = targetTagRepository;
|
|
||||||
this.virtualPropertyReplacer = virtualPropertyReplacer;
|
|
||||||
this.database = database;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -105,7 +95,7 @@ public class JpaTargetTagManagement implements TargetTagManagement {
|
|||||||
@Override
|
@Override
|
||||||
public Page<TargetTag> findByRsql(final String rsql, final Pageable pageable) {
|
public Page<TargetTag> findByRsql(final String rsql, final Pageable pageable) {
|
||||||
return JpaManagementHelper.findAllWithCountBySpec(targetTagRepository, Collections.singletonList(
|
return JpaManagementHelper.findAllWithCountBySpec(targetTagRepository, Collections.singletonList(
|
||||||
RsqlUtility.buildRsqlSpecification(rsql, TargetTagFields.class, virtualPropertyReplacer, database)), pageable);
|
RsqlUtility.getInstance().buildRsqlSpecification(rsql, TargetTagFields.class)), pageable);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -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.jpa.utils.QuotaHelper;
|
||||||
import org.eclipse.hawkbit.repository.model.DistributionSetType;
|
import org.eclipse.hawkbit.repository.model.DistributionSetType;
|
||||||
import org.eclipse.hawkbit.repository.model.TargetType;
|
import org.eclipse.hawkbit.repository.model.TargetType;
|
||||||
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
|
|
||||||
import org.springframework.dao.ConcurrencyFailureException;
|
import org.springframework.dao.ConcurrencyFailureException;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.data.domain.Slice;
|
import org.springframework.data.domain.Slice;
|
||||||
import org.springframework.orm.jpa.vendor.Database;
|
|
||||||
import org.springframework.retry.annotation.Backoff;
|
import org.springframework.retry.annotation.Backoff;
|
||||||
import org.springframework.retry.annotation.Retryable;
|
import org.springframework.retry.annotation.Retryable;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
@@ -60,9 +58,6 @@ public class JpaTargetTypeManagement implements TargetTypeManagement {
|
|||||||
private final TargetRepository targetRepository;
|
private final TargetRepository targetRepository;
|
||||||
private final DistributionSetTypeRepository distributionSetTypeRepository;
|
private final DistributionSetTypeRepository distributionSetTypeRepository;
|
||||||
|
|
||||||
private final VirtualPropertyReplacer virtualPropertyReplacer;
|
|
||||||
|
|
||||||
private final Database database;
|
|
||||||
private final QuotaManagement quotaManagement;
|
private final QuotaManagement quotaManagement;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -70,18 +65,13 @@ public class JpaTargetTypeManagement implements TargetTypeManagement {
|
|||||||
*
|
*
|
||||||
* @param targetTypeRepository Target type repository
|
* @param targetTypeRepository Target type repository
|
||||||
* @param targetRepository Target repository
|
* @param targetRepository Target repository
|
||||||
* @param virtualPropertyReplacer replacer
|
|
||||||
* @param database database
|
|
||||||
*/
|
*/
|
||||||
public JpaTargetTypeManagement(final TargetTypeRepository targetTypeRepository,
|
public JpaTargetTypeManagement(final TargetTypeRepository targetTypeRepository,
|
||||||
final TargetRepository targetRepository, final DistributionSetTypeRepository distributionSetTypeRepository,
|
final TargetRepository targetRepository, final DistributionSetTypeRepository distributionSetTypeRepository,
|
||||||
final VirtualPropertyReplacer virtualPropertyReplacer, final Database database,
|
|
||||||
final QuotaManagement quotaManagement) {
|
final QuotaManagement quotaManagement) {
|
||||||
this.targetTypeRepository = targetTypeRepository;
|
this.targetTypeRepository = targetTypeRepository;
|
||||||
this.targetRepository = targetRepository;
|
this.targetRepository = targetRepository;
|
||||||
this.distributionSetTypeRepository = distributionSetTypeRepository;
|
this.distributionSetTypeRepository = distributionSetTypeRepository;
|
||||||
this.virtualPropertyReplacer = virtualPropertyReplacer;
|
|
||||||
this.database = database;
|
|
||||||
this.quotaManagement = quotaManagement;
|
this.quotaManagement = quotaManagement;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,10 +135,10 @@ public class JpaTargetTypeManagement implements TargetTypeManagement {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Page<TargetType> findByRsql(final String rsql, final Pageable pageable) {
|
public Page<TargetType> findByRsql(final String rsql, final Pageable pageable) {
|
||||||
return JpaManagementHelper.findAllWithCountBySpec(targetTypeRepository, List.of(
|
return JpaManagementHelper.findAllWithCountBySpec(
|
||||||
RsqlUtility.buildRsqlSpecification(
|
targetTypeRepository,
|
||||||
rsql, TargetTypeFields.class, virtualPropertyReplacer, database)), pageable
|
List.of(RsqlUtility.getInstance().buildRsqlSpecification(rsql, TargetTypeFields.class)),
|
||||||
);
|
pageable);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -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.assertThat;
|
||||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||||
import static org.assertj.core.api.Assertions.fail;
|
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.net.URI;
|
||||||
import java.util.ArrayList;
|
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.TargetType;
|
||||||
import org.eclipse.hawkbit.repository.model.TargetTypeAssignmentResult;
|
import org.eclipse.hawkbit.repository.model.TargetTypeAssignmentResult;
|
||||||
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
|
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.Expect;
|
||||||
import org.eclipse.hawkbit.repository.test.matcher.ExpectEvents;
|
import org.eclipse.hawkbit.repository.test.matcher.ExpectEvents;
|
||||||
import org.eclipse.hawkbit.repository.test.util.SecurityContextSwitch;
|
import org.eclipse.hawkbit.repository.test.util.SecurityContextSwitch;
|
||||||
@@ -1091,7 +1091,7 @@ class TargetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
void findTargetsByRsqlWithTypeAndMetadata() {
|
void findTargetsByRsqlWithTypeAndMetadata() {
|
||||||
if (RsqlConfigHolder.getInstance().getRsqlToSpecBuilder() == LEGACY_G1) {
|
if (RsqlUtility.getInstance().getRsqlToSpecBuilder() == LEGACY_G1) {
|
||||||
// legacy visitor fail with that
|
// legacy visitor fail with that
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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.assertThat;
|
||||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
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.RsqlUtility.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_G1;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import jakarta.persistence.EntityManager;
|
|
||||||
|
|
||||||
import org.eclipse.hawkbit.repository.TargetFields;
|
import org.eclipse.hawkbit.repository.TargetFields;
|
||||||
import org.eclipse.hawkbit.repository.TargetTypeFields;
|
import org.eclipse.hawkbit.repository.TargetTypeFields;
|
||||||
import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException;
|
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.Target;
|
||||||
import org.eclipse.hawkbit.repository.model.TargetTag;
|
import org.eclipse.hawkbit.repository.model.TargetTag;
|
||||||
import org.eclipse.hawkbit.repository.model.TargetType;
|
import org.eclipse.hawkbit.repository.model.TargetType;
|
||||||
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
|
|
||||||
import org.eclipse.hawkbit.repository.test.util.TestdataFactory;
|
import org.eclipse.hawkbit.repository.test.util.TestdataFactory;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.data.domain.Slice;
|
import org.springframework.data.domain.Slice;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -45,11 +41,6 @@ class RsqlTargetFieldTest extends AbstractJpaIntegrationTest {
|
|||||||
private static final String OR = ",";
|
private static final String OR = ",";
|
||||||
private static final String AND = ";";
|
private static final String AND = ";";
|
||||||
|
|
||||||
@Autowired
|
|
||||||
protected VirtualPropertyReplacer virtualPropertyReplacer;
|
|
||||||
@Autowired
|
|
||||||
protected EntityManager entityManager;
|
|
||||||
|
|
||||||
private Target target;
|
private Target target;
|
||||||
private Target target2;
|
private Target target2;
|
||||||
private TargetType targetType1;
|
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.null==null", 1); // "null" check
|
||||||
assertRSQLQuery(TargetFields.ATTRIBUTE.name() + ".test.n/a==null", 0); // "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.dot=is=value.dot", 1);
|
||||||
assertRSQLQuery(TargetFields.ATTRIBUTE.name() + ".test.null=is=null", 5); // null check
|
assertRSQLQuery(TargetFields.ATTRIBUTE.name() + ".test.null=is=null", 5); // null check
|
||||||
assertRSQLQuery(TargetFields.ATTRIBUTE.name() + ".test.n/a=is=null", 1 + 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.null!=null2", 1); // value check
|
||||||
assertRSQLQuery(TargetFields.ATTRIBUTE.name() + ".test.n/a!=null", 0); // "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(
|
assertRSQLQuery(
|
||||||
TargetFields.ATTRIBUTE.name() + ".test.dot=not=value.dot",
|
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=null", 1); // null check
|
||||||
assertRSQLQuery(
|
assertRSQLQuery(
|
||||||
TargetFields.ATTRIBUTE.name() + ".test.null=not=null2",
|
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.n/a=not=null", 0); // null check
|
||||||
assertRSQLQuery(
|
assertRSQLQuery(
|
||||||
TargetFields.ATTRIBUTE.name() + ".test.dot=ne=value.dot",
|
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=null", 1); // null check
|
||||||
assertRSQLQuery(
|
assertRSQLQuery(
|
||||||
TargetFields.ATTRIBUTE.name() + ".test.null=ne=null2",
|
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
|
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() + ".metaKey==noExist*", 0);
|
||||||
assertRSQLQuery(TargetFields.METADATA.name() + ".notExist==metaValue", 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=metaValue", 1);
|
||||||
assertRSQLQuery(TargetFields.METADATA.name() + ".metaKey=is=null", 4); // null check (1 of the initial five has)
|
assertRSQLQuery(TargetFields.METADATA.name() + ".metaKey=is=null", 4); // null check (1 of the initial five has)
|
||||||
assertRSQLQuery(TargetFields.METADATA.name() + ".metaKey=is=*v*", 2);
|
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() + ".notExist!=metaValue", 0);
|
||||||
assertRSQLQuery(TargetFields.METADATA.name() + ".metaKey!=notExist", 2);
|
assertRSQLQuery(TargetFields.METADATA.name() + ".metaKey!=notExist", 2);
|
||||||
|
|
||||||
if (RsqlConfigHolder.getInstance().getRsqlToSpecBuilder() != LEGACY_G1) {
|
if (RsqlUtility.getInstance().getRsqlToSpecBuilder() != LEGACY_G1) {
|
||||||
assertRSQLQuery(
|
assertRSQLQuery(
|
||||||
TargetFields.METADATA.name() + ".metaKey=not=metaValue",
|
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() + ".metaKey=not=null", 2); // null check (2 of the initial five)
|
||||||
assertRSQLQuery(
|
assertRSQLQuery(
|
||||||
TargetFields.METADATA.name() + ".notExist=not=metaValue",
|
TargetFields.METADATA.name() + ".notExist=not=metaValue",
|
||||||
RsqlConfigHolder.getInstance().getRsqlToSpecBuilder() == LEGACY_G2 ? 1 + 5 : 0);
|
RsqlUtility.getInstance().getRsqlToSpecBuilder() == LEGACY_G2 ? 1 + 5 : 0);
|
||||||
assertRSQLQuery(
|
assertRSQLQuery(
|
||||||
TargetFields.METADATA.name() + ".metaKey=not=notExist",
|
TargetFields.METADATA.name() + ".metaKey=not=notExist",
|
||||||
RsqlConfigHolder.getInstance().getRsqlToSpecBuilder() == LEGACY_G2 ? 2 + 4 : 2);
|
RsqlUtility.getInstance().getRsqlToSpecBuilder() == LEGACY_G2 ? 2 + 4 : 2);
|
||||||
assertRSQLQuery(
|
assertRSQLQuery(
|
||||||
TargetFields.METADATA.name() + ".metaKey=ne=metaValue",
|
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() + ".metaKey=ne=null", 2); // null check (2 of the initial five)
|
||||||
assertRSQLQuery(
|
assertRSQLQuery(
|
||||||
TargetFields.METADATA.name() + ".notExist=ne=metaValue",
|
TargetFields.METADATA.name() + ".notExist=ne=metaValue",
|
||||||
RsqlConfigHolder.getInstance().getRsqlToSpecBuilder() == LEGACY_G2 ? 1 + 5 : 0);
|
RsqlUtility.getInstance().getRsqlToSpecBuilder() == LEGACY_G2 ? 1 + 5 : 0);
|
||||||
assertRSQLQuery(
|
assertRSQLQuery(
|
||||||
TargetFields.METADATA.name() + ".metaKey=ne=notExist",
|
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);
|
assertRSQLQuery(TargetFields.METADATA.name() + ".metaKey=in=(metaValue,notexist)", 1);
|
||||||
@@ -386,28 +377,26 @@ class RsqlTargetFieldTest extends AbstractJpaIntegrationTest {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
void rsqlValidTargetFields() {
|
void rsqlValidTargetFields() {
|
||||||
RsqlUtility.validateRsqlFor(
|
RsqlUtility.getInstance().validateRsqlFor(
|
||||||
"ID == '0123' and NAME == abcd and DESCRIPTION == absd and CREATEDAT =lt= 0123 and LASTMODIFIEDAT =gt= 0123" +
|
"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 CONTROLLERID == 0123 and UPDATESTATUS == PENDING and IPADDRESS == 0123 and LASTCONTROLLERREQUESTAT == 0123" +
|
||||||
" and tag == beta",
|
" and tag == beta",
|
||||||
TargetFields.class, JpaTarget.class, virtualPropertyReplacer, entityManager);
|
TargetFields.class, JpaTarget.class);
|
||||||
RsqlUtility.validateRsqlFor(
|
RsqlUtility.getInstance().validateRsqlFor(
|
||||||
"ASSIGNEDDS.name == abcd and ASSIGNEDDS.version == 0123 and INSTALLEDDS.name == abcd and INSTALLEDDS.version == 0123",
|
"ASSIGNEDDS.name == abcd and ASSIGNEDDS.version == 0123 and INSTALLEDDS.name == abcd and INSTALLEDDS.version == 0123",
|
||||||
TargetFields.class, JpaTarget.class, virtualPropertyReplacer, entityManager);
|
TargetFields.class, JpaTarget.class);
|
||||||
RsqlUtility.validateRsqlFor(
|
RsqlUtility.getInstance().validateRsqlFor(
|
||||||
"ATTRIBUTE.subkey1 == test and ATTRIBUTE.subkey2 == test and METADATA.metakey1 == abcd and METADATA.metavalue2 == asdfg",
|
"ATTRIBUTE.subkey1 == test and ATTRIBUTE.subkey2 == test and METADATA.metakey1 == abcd and METADATA.metavalue2 == asdfg",
|
||||||
TargetFields.class, JpaTarget.class, virtualPropertyReplacer, entityManager);
|
TargetFields.class, JpaTarget.class);
|
||||||
RsqlUtility.validateRsqlFor(
|
RsqlUtility.getInstance().validateRsqlFor(
|
||||||
"CREATEDAT =lt= ${NOW_TS} and LASTMODIFIEDAT =ge= ${OVERDUE_TS}",
|
"CREATEDAT =lt= ${NOW_TS} and LASTMODIFIEDAT =ge= ${OVERDUE_TS}",
|
||||||
TargetFields.class, JpaTarget.class, virtualPropertyReplacer, entityManager);
|
TargetFields.class, JpaTarget.class);
|
||||||
RsqlUtility.validateRsqlFor(
|
RsqlUtility.getInstance().validateRsqlFor(
|
||||||
"ATTRIBUTE.test.dot == test and ATTRIBUTE.subkey2 == test and METADATA.test.dot == abcd and METADATA.metavalue2 == asdfg",
|
"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)
|
assertThatExceptionOfType(RSQLParameterUnsupportedFieldException.class)
|
||||||
.isThrownBy(() -> RsqlUtility.validateRsqlFor(
|
.isThrownBy(() -> RsqlUtility.getInstance().validateRsqlFor("wrongfield == abcd", TargetFields.class, JpaTarget.class));
|
||||||
"wrongfield == abcd",
|
|
||||||
TargetFields.class, JpaTarget.class, virtualPropertyReplacer, entityManager));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -452,7 +441,6 @@ class RsqlTargetFieldTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
private void assertRSQLQueryThrowsException(final String rsql) {
|
private void assertRSQLQueryThrowsException(final String rsql) {
|
||||||
assertThatExceptionOfType(RSQLParameterUnsupportedFieldException.class)
|
assertThatExceptionOfType(RSQLParameterUnsupportedFieldException.class)
|
||||||
.isThrownBy(() -> RsqlUtility.validateRsqlFor(
|
.isThrownBy(() -> RsqlUtility.getInstance().validateRsqlFor(rsql, TargetFields.class, JpaTarget.class));
|
||||||
rsql, TargetFields.class, JpaTarget.class, virtualPropertyReplacer, entityManager));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -9,9 +9,9 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.repository.jpa.rsql;
|
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.RsqlUtility.RsqlToSpecBuilder.LEGACY_G2;
|
||||||
import static org.eclipse.hawkbit.repository.jpa.rsql.RsqlConfigHolder.RsqlToSpecBuilder.G3;
|
import static org.eclipse.hawkbit.repository.jpa.rsql.RsqlUtility.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_G1;
|
||||||
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.NONE;
|
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.NONE;
|
||||||
|
|
||||||
import jakarta.persistence.EntityManager;
|
import jakarta.persistence.EntityManager;
|
||||||
|
|||||||
@@ -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<br/>
|
|
||||||
* 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<String> TEST_POLLING_TIME_INTERVAL =
|
|
||||||
TenantConfigurationValue.<String> builder().value("00:05:00").build();
|
|
||||||
private static final TenantConfigurationValue<String> TEST_POLLING_OVERDUE_TIME_INTERVAL =
|
|
||||||
TenantConfigurationValue.<String> 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<Object> baseSoftwareModuleRootMock;
|
|
||||||
@Mock
|
|
||||||
private CriteriaQuery<SoftwareModule> criteriaQueryMock;
|
|
||||||
@Mock
|
|
||||||
private CriteriaBuilder criteriaBuilderMock;
|
|
||||||
@Mock
|
|
||||||
private Subquery<SoftwareModule> subqueryMock;
|
|
||||||
@Mock
|
|
||||||
private Root<SoftwareModule> subqueryRootMock;
|
|
||||||
@Mock
|
|
||||||
private Attribute attribute;
|
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
void beforeEach() {
|
|
||||||
setupRoot(baseSoftwareModuleRootMock);
|
|
||||||
setupRoot(subqueryRootMock);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void wrongFieldThrowUnsupportedFieldException() {
|
|
||||||
when(baseSoftwareModuleRootMock.getJavaType()).thenReturn((Class) SoftwareModule.class);
|
|
||||||
final Specification<Object> rsqlSpecification = RsqlUtility.buildRsqlSpecification("unknownField==abc", SoftwareModuleFields.class, null, testDb);
|
|
||||||
assertThatExceptionOfType(RSQLParameterUnsupportedFieldException.class)
|
|
||||||
.as("RSQLParameterUnsupportedFieldException because of unknown RSQL field")
|
|
||||||
.isThrownBy(() -> rsqlSpecification.toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void wrongRsqlMapSyntaxThrowSyntaxException() {
|
|
||||||
final Specification<Object> rsqlSpecification =
|
|
||||||
RsqlUtility.buildRsqlSpecification(TargetFields.ATTRIBUTE + "==abc", TargetFields.class, null, testDb);
|
|
||||||
assertThatExceptionOfType(RSQLParameterUnsupportedFieldException.class)
|
|
||||||
.as("RSQLParameterSyntaxException for target attributes map, caused by wrong RSQL syntax (key was not present)")
|
|
||||||
.isThrownBy(() -> rsqlSpecification.toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock));
|
|
||||||
|
|
||||||
final Specification<Object> rsqlSpecification2 =
|
|
||||||
RsqlUtility.buildRsqlSpecification(TargetFields.ATTRIBUTE + ".unknown.wrong==abc", TargetFields.class, null, testDb);
|
|
||||||
assertThatExceptionOfType(RSQLParameterUnsupportedFieldException.class)
|
|
||||||
.as("RSQLParameterSyntaxException for target attributes map, caused by wrong RSQL syntax (key includes dots)")
|
|
||||||
.isThrownBy(() -> rsqlSpecification2.toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock));
|
|
||||||
|
|
||||||
final Specification<Object> rsqlSpecification3 =
|
|
||||||
RsqlUtility.buildRsqlSpecification(TargetFields.METADATA + ".unknown.wrong==abc", TargetFields.class, null, testDb);
|
|
||||||
assertThatExceptionOfType(RSQLParameterUnsupportedFieldException.class)
|
|
||||||
.as("RSQLParameterSyntaxException for target metadata map, caused by wrong RSQL syntax (key includes dots)")
|
|
||||||
.isThrownBy(() -> rsqlSpecification3.toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock));
|
|
||||||
|
|
||||||
final Specification<Object> rsqlSpecification4 =
|
|
||||||
RsqlUtility.buildRsqlSpecification(DistributionSetFields.METADATA + "==abc", TargetFields.class, null, testDb);
|
|
||||||
assertThatExceptionOfType(RSQLParameterUnsupportedFieldException.class)
|
|
||||||
.as("RSQLParameterSyntaxException for distribution set metadata map, caused by wrong RSQL syntax (key was not present)\"")
|
|
||||||
.isThrownBy(() -> rsqlSpecification4.toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void wrongRsqlSubEntitySyntaxThrowSyntaxException() {
|
|
||||||
final Specification<Object> rsqlSpecification =
|
|
||||||
RsqlUtility.buildRsqlSpecification(TargetFields.ASSIGNEDDS + "==abc", TargetFields.class, null, testDb);
|
|
||||||
assertThatExceptionOfType(RSQLParameterUnsupportedFieldException.class)
|
|
||||||
.as("RSQLParameterSyntaxException because of wrong RSQL syntax")
|
|
||||||
.isThrownBy(() -> rsqlSpecification.toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock));
|
|
||||||
|
|
||||||
final Specification<Object> rsqlSpecification2 =
|
|
||||||
RsqlUtility.buildRsqlSpecification(TargetFields.ASSIGNEDDS + ".unknownField==abc", TargetFields.class, null, testDb);
|
|
||||||
assertThatExceptionOfType(RSQLParameterUnsupportedFieldException.class)
|
|
||||||
.as("RSQLParameterSyntaxException because of wrong RSQL syntax")
|
|
||||||
.isThrownBy(() -> rsqlSpecification2.toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock));
|
|
||||||
|
|
||||||
final Specification<Object> rsqlSpecification3 =
|
|
||||||
RsqlUtility.buildRsqlSpecification(TargetFields.ASSIGNEDDS + ".unknownField.ToMuch==abc", TargetFields.class, null, testDb);
|
|
||||||
assertThatExceptionOfType(RSQLParameterUnsupportedFieldException.class)
|
|
||||||
.as("RSQLParameterSyntaxException because of wrong RSQL syntax")
|
|
||||||
.isThrownBy(() -> rsqlSpecification3.toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
<T> 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.<String> 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.<String> 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<Object> 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.<String> 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 <Y> Path<Y> pathOfString(final Path<?> path) {
|
|
||||||
return (Path<Y>) 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<String> 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<String> 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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user