Improve JPA Provider portability - RSQL (#2131)
Signed-off-by: Avgustin Marinov <Avgustin.Marinov@bosch.com>
This commit is contained in:
@@ -27,16 +27,14 @@ public interface SoftwareModuleTypeManagement
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param key to search for
|
* @param key to search for
|
||||||
* @return {@link SoftwareModuleType} in the repository with given
|
* @return {@link SoftwareModuleType} in the repository with given {@link SoftwareModuleType#getKey()}
|
||||||
* {@link SoftwareModuleType#getKey()}
|
|
||||||
*/
|
*/
|
||||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
|
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
|
||||||
Optional<SoftwareModuleType> getByKey(@NotEmpty String key);
|
Optional<SoftwareModuleType> getByKey(@NotEmpty String key);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param name to search for
|
* @param name to search for
|
||||||
* @return all {@link SoftwareModuleType}s in the repository with given
|
* @return all {@link SoftwareModuleType}s in the repository with given {@link SoftwareModuleType#getName()}
|
||||||
* {@link SoftwareModuleType#getName()}
|
|
||||||
*/
|
*/
|
||||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
|
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
|
||||||
Optional<SoftwareModuleType> getByName(@NotEmpty String name);
|
Optional<SoftwareModuleType> getByName(@NotEmpty String name);
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ import org.eclipse.hawkbit.repository.exception.CancelActionNotAllowedException;
|
|||||||
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
|
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
|
||||||
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
|
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
|
||||||
import org.eclipse.hawkbit.repository.exception.InvalidTargetAttributeException;
|
import org.eclipse.hawkbit.repository.exception.InvalidTargetAttributeException;
|
||||||
|
import org.eclipse.hawkbit.repository.jpa.Jpa;
|
||||||
import org.eclipse.hawkbit.repository.jpa.acm.AccessController;
|
import org.eclipse.hawkbit.repository.jpa.acm.AccessController;
|
||||||
import org.eclipse.hawkbit.repository.jpa.builder.JpaActionStatusCreate;
|
import org.eclipse.hawkbit.repository.jpa.builder.JpaActionStatusCreate;
|
||||||
import org.eclipse.hawkbit.repository.jpa.configuration.Constants;
|
import org.eclipse.hawkbit.repository.jpa.configuration.Constants;
|
||||||
@@ -748,24 +749,17 @@ public class JpaControllerManagement extends JpaActionManagement implements Cont
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets {@link Target#getLastTargetQuery()} by native SQL in order to avoid
|
* Sets {@link Target#getLastTargetQuery()} by native SQL in order to avoid raising opt lock revision as this update is not mission-critical
|
||||||
* raising opt lock revision as this update is not mission critical and in
|
* and in fact only written by {@link ControllerManagement}, i.e. the target itself.
|
||||||
* fact only written by {@link ControllerManagement}, i.e. the target
|
|
||||||
* itself.
|
|
||||||
*/
|
*/
|
||||||
private void setLastTargetQuery(final String tenant, final long currentTimeMillis, final List<String> chunk) {
|
private void setLastTargetQuery(final String tenant, final long currentTimeMillis, final List<String> chunk) {
|
||||||
final Map<String, String> paramMapping = new HashMap<>(chunk.size());
|
|
||||||
|
|
||||||
for (int i = 0; i < chunk.size(); i++) {
|
|
||||||
paramMapping.put("cid" + i, chunk.get(i));
|
|
||||||
}
|
|
||||||
|
|
||||||
final Query updateQuery = entityManager.createNativeQuery(
|
final Query updateQuery = entityManager.createNativeQuery(
|
||||||
"UPDATE sp_target SET last_target_query = #last_target_query WHERE controller_id IN ("
|
"UPDATE sp_target SET last_target_query = " + Jpa.NATIVE_QUERY_PARAMETER_PREFIX + "last_target_query " +
|
||||||
+ formatQueryInStatementParams(paramMapping.keySet()) + ") AND tenant = #tenant");
|
"WHERE controller_id IN (" + Jpa.formatNativeQueryInClause("cid", chunk) + ")" +
|
||||||
|
" AND tenant = " + Jpa.NATIVE_QUERY_PARAMETER_PREFIX + "tenant");
|
||||||
|
|
||||||
paramMapping.forEach(updateQuery::setParameter);
|
|
||||||
updateQuery.setParameter("last_target_query", currentTimeMillis);
|
updateQuery.setParameter("last_target_query", currentTimeMillis);
|
||||||
|
Jpa.setNativeQueryInParameter(updateQuery, "cid", chunk);
|
||||||
updateQuery.setParameter("tenant", tenant);
|
updateQuery.setParameter("tenant", tenant);
|
||||||
|
|
||||||
final int updated = updateQuery.executeUpdate();
|
final int updated = updateQuery.executeUpdate();
|
||||||
|
|||||||
@@ -104,6 +104,12 @@ public abstract class AbstractJpaBaseEntity implements BaseEntity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Column(name = "created_at", updatable = false, nullable = false)
|
||||||
|
@Access(AccessType.PROPERTY)
|
||||||
|
public long getCreatedAt() {
|
||||||
|
return createdAt;
|
||||||
|
}
|
||||||
|
|
||||||
@LastModifiedBy
|
@LastModifiedBy
|
||||||
public void setLastModifiedBy(final String lastModifiedBy) {
|
public void setLastModifiedBy(final String lastModifiedBy) {
|
||||||
if (isController()) {
|
if (isController()) {
|
||||||
@@ -113,13 +119,7 @@ public abstract class AbstractJpaBaseEntity implements BaseEntity {
|
|||||||
this.lastModifiedBy = lastModifiedBy;
|
this.lastModifiedBy = lastModifiedBy;
|
||||||
}
|
}
|
||||||
|
|
||||||
// maybe needed to have correct createdAt value in the database
|
@Column(name = "last_modified_by", nullable = false, length = USERNAME_FIELD_LENGTH)
|
||||||
@Access(AccessType.PROPERTY)
|
|
||||||
public long getCreatedAt() {
|
|
||||||
return createdAt;
|
|
||||||
}
|
|
||||||
|
|
||||||
// seems needed to have correct lastModifiedBy value in the database
|
|
||||||
@Access(AccessType.PROPERTY)
|
@Access(AccessType.PROPERTY)
|
||||||
public String getLastModifiedBy() {
|
public String getLastModifiedBy() {
|
||||||
return lastModifiedBy;
|
return lastModifiedBy;
|
||||||
|
|||||||
@@ -25,28 +25,24 @@ import org.springframework.transaction.annotation.Transactional;
|
|||||||
* Repository for {@link SoftwareModuleType}.
|
* Repository for {@link SoftwareModuleType}.
|
||||||
*/
|
*/
|
||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
public interface SoftwareModuleTypeRepository
|
public interface SoftwareModuleTypeRepository extends BaseEntityRepository<JpaSoftwareModuleType> {
|
||||||
extends BaseEntityRepository<JpaSoftwareModuleType> {
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param key to search for
|
* @param key to search for
|
||||||
* @return all {@link SoftwareModuleType}s in the repository with given
|
* @return all {@link SoftwareModuleType}s in the repository with given {@link SoftwareModuleType#getKey()}
|
||||||
* {@link SoftwareModuleType#getKey()}
|
|
||||||
*/
|
*/
|
||||||
Optional<SoftwareModuleType> findByKey(String key);
|
Optional<SoftwareModuleType> findByKey(String key);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param name to search for
|
* @param name to search for
|
||||||
* @return all {@link SoftwareModuleType}s in the repository with given
|
* @return all {@link SoftwareModuleType}s in the repository with given {@link SoftwareModuleType#getName()}
|
||||||
* {@link SoftwareModuleType#getName()}
|
|
||||||
*/
|
*/
|
||||||
Optional<SoftwareModuleType> findByName(String name);
|
Optional<SoftwareModuleType> findByName(String name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes all {@link TenantAwareBaseEntity} of a given tenant. For safety
|
* Deletes all {@link TenantAwareBaseEntity} of a given tenant. For safety reasons (this is a "delete everything" query
|
||||||
* reasons (this is a "delete everything" query after all) we add the tenant
|
* after all) we add the tenant manually to query even if this is done by {@link EntityManager} anyhow. The DB should take
|
||||||
* manually to query even if this will by done by {@link EntityManager}
|
* care of optimizing this away.
|
||||||
* anyhow. The DB should take care of optimizing this away.
|
|
||||||
*
|
*
|
||||||
* @param tenant to delete data from
|
* @param tenant to delete data from
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -17,11 +17,9 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import jakarta.persistence.criteria.CriteriaBuilder;
|
import jakarta.persistence.criteria.CriteriaBuilder;
|
||||||
import jakarta.persistence.criteria.CriteriaQuery;
|
import jakarta.persistence.criteria.CriteriaQuery;
|
||||||
import jakarta.persistence.criteria.Expression;
|
|
||||||
import jakarta.persistence.criteria.JoinType;
|
import jakarta.persistence.criteria.JoinType;
|
||||||
import jakarta.persistence.criteria.MapJoin;
|
import jakarta.persistence.criteria.MapJoin;
|
||||||
import jakarta.persistence.criteria.Path;
|
import jakarta.persistence.criteria.Path;
|
||||||
@@ -185,7 +183,7 @@ public class JpaQueryRsqlVisitorG2<A extends Enum<A> & RsqlQueryField, T>
|
|||||||
final String keyValue = graph[graph.length - 1];
|
final String keyValue = graph[graph.length - 1];
|
||||||
if (fieldPath instanceof MapJoin) {
|
if (fieldPath instanceof MapJoin) {
|
||||||
// Currently we support only string key. So below cast is safe.
|
// Currently we support only string key. So below cast is safe.
|
||||||
return equal((Expression<String>) (((MapJoin<?, ?, ?>) fieldPath).key()), keyValue);
|
return equal((Path<String>) (((MapJoin<?, ?, ?>) fieldPath).key()), keyValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
final String keyFieldName = queryField.getEnumValue().getSubEntityMapTuple().map(Entry::getKey)
|
final String keyFieldName = queryField.getEnumValue().getSubEntityMapTuple().map(Entry::getKey)
|
||||||
@@ -225,7 +223,7 @@ public class JpaQueryRsqlVisitorG2<A extends Enum<A> & RsqlQueryField, T>
|
|||||||
return cb.or(cb.isNull(fieldPath), cb.equal(pathOfString(fieldPath), ""));
|
return cb.or(cb.isNull(fieldPath), cb.equal(pathOfString(fieldPath), ""));
|
||||||
}
|
}
|
||||||
|
|
||||||
final Expression<String> stringExpression = pathOfString(fieldPath);
|
final Path<String> stringExpression = pathOfString(fieldPath);
|
||||||
if (isPattern(transformedValueStr)) { // a pattern, use like
|
if (isPattern(transformedValueStr)) { // a pattern, use like
|
||||||
return like(stringExpression, toSQL(transformedValueStr));
|
return like(stringExpression, toSQL(transformedValueStr));
|
||||||
} else {
|
} else {
|
||||||
@@ -311,14 +309,10 @@ public class JpaQueryRsqlVisitorG2<A extends Enum<A> & RsqlQueryField, T>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Object convertValueIfNecessary(
|
private Object convertValueIfNecessary(final ComparisonNode node, final A fieldName, final Path<?> fieldPath, final String value) {
|
||||||
final ComparisonNode node, final A fieldName, final Path<?> fieldPath, final String value) {
|
// in case the value of an RSQL query e.g. type==application is an enum we need to handle it separately because JPA needs the
|
||||||
// in case the value of an RSQL query e.g. type==application is an
|
// correct java-type to build an expression. So String and numeric values JPA can do it by its own but not for classes like enums.
|
||||||
// enum we need to handle it separately because JPA needs the
|
// So we need to transform the given value string into the enum class.
|
||||||
// correct java-type to build an expression. So String and numeric
|
|
||||||
// values JPA can do it by its own but not for classes like enums.
|
|
||||||
// So we need to transform the given value string into the enum
|
|
||||||
// class.
|
|
||||||
final Class<?> javaType = fieldPath.getJavaType();
|
final Class<?> javaType = fieldPath.getJavaType();
|
||||||
if (javaType != null && javaType.isEnum()) {
|
if (javaType != null && javaType.isEnum()) {
|
||||||
return transformEnumValue(node, javaType, value);
|
return transformEnumValue(node, javaType, value);
|
||||||
@@ -327,7 +321,7 @@ public class JpaQueryRsqlVisitorG2<A extends Enum<A> & RsqlQueryField, T>
|
|||||||
return convertFieldConverterValue(node, fieldName, value);
|
return convertFieldConverterValue(node, fieldName, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Boolean.TYPE.equals(javaType)) {
|
if (Boolean.TYPE.equals(javaType) || Boolean.class.equals(javaType)) {
|
||||||
return convertBooleanValue(node, javaType, value);
|
return convertBooleanValue(node, javaType, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -368,7 +362,7 @@ public class JpaQueryRsqlVisitorG2<A extends Enum<A> & RsqlQueryField, T>
|
|||||||
|
|
||||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||||
private Predicate toNotExistsSubQueryPredicate(final QuertPath queryField, final Path<?> fieldPath,
|
private Predicate toNotExistsSubQueryPredicate(final QuertPath queryField, final Path<?> fieldPath,
|
||||||
final Function<Expression<String>, Predicate> subQueryPredicateProvider) {
|
final Function<Path<String>, Predicate> subQueryPredicateProvider) {
|
||||||
// if a subquery the field's parent joins are not actually used
|
// if a subquery the field's parent joins are not actually used
|
||||||
if (!inOr) {
|
if (!inOr) {
|
||||||
// so, if not in or (hence not reused) we remove them. Parent shall be a Join
|
// so, if not in or (hence not reused) we remove them. Parent shall be a Join
|
||||||
@@ -383,24 +377,27 @@ public class JpaQueryRsqlVisitorG2<A extends Enum<A> & RsqlQueryField, T>
|
|||||||
.where(cb.and(
|
.where(cb.and(
|
||||||
cb.equal(root.get(queryField.getEnumValue().identifierFieldName()),
|
cb.equal(root.get(queryField.getEnumValue().identifierFieldName()),
|
||||||
subqueryRoot.get(queryField.getEnumValue().identifierFieldName())),
|
subqueryRoot.get(queryField.getEnumValue().identifierFieldName())),
|
||||||
subQueryPredicateProvider.apply(getExpressionToCompare(queryField.getEnumValue(),
|
subQueryPredicateProvider.apply(
|
||||||
getFieldPath(subqueryRoot, queryField)))))));
|
getExpressionToCompare(queryField.getEnumValue(),
|
||||||
|
getFieldPath(subqueryRoot, queryField)))))));
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||||
private Expression<String> getExpressionToCompare(final A enumField, final Path fieldPath) {
|
private Path<String> getExpressionToCompare(final A enumField, final Path fieldPath) {
|
||||||
if (!enumField.isMap()) {
|
if (!enumField.isMap()) {
|
||||||
return pathOfString(fieldPath);
|
return pathOfString(fieldPath);
|
||||||
}
|
}
|
||||||
if (fieldPath instanceof MapJoin) {
|
if (fieldPath instanceof MapJoin) {
|
||||||
// Currently we support only string key. So below cast is safe.
|
// Currently we support only string key. So below cast is safe.
|
||||||
return (Expression<String>) (((MapJoin<?, ?, ?>) fieldPath).value());
|
return (Path<String>) (((MapJoin<?, ?, ?>) fieldPath).value());
|
||||||
}
|
}
|
||||||
return enumField.getSubEntityMapTuple()
|
return enumField.getSubEntityMapTuple()
|
||||||
.map(Entry::getValue)
|
.map(Entry::getValue)
|
||||||
.map(valueFieldName -> fieldPath.<String> get(valueFieldName))
|
.map(valueFieldName -> fieldPath.<String> get(valueFieldName))
|
||||||
.orElseThrow(() -> new UnsupportedOperationException(
|
.orElseThrow(() ->
|
||||||
"For the fields, defined as Map, only Map java type or tuple in the form of SimpleImmutableEntry are allowed. Neither of those could be found!"));
|
new UnsupportedOperationException(
|
||||||
|
"For the fields, defined as Map, only Map java type or tuple in the form of SimpleImmutableEntry are allowed." +
|
||||||
|
" Neither of those could be found!"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private String toSQL(final String transformedValue) {
|
private String toSQL(final String transformedValue) {
|
||||||
@@ -437,33 +434,50 @@ public class JpaQueryRsqlVisitorG2<A extends Enum<A> & RsqlQueryField, T>
|
|||||||
return children;
|
return children;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Predicate equal(final Expression<String> expressionToCompare, final String sqlValue) {
|
private Predicate equal(final Path<String> expressionToCompare, final String sqlValue) {
|
||||||
return cb.equal(caseWise(cb, expressionToCompare), caseWise(sqlValue));
|
if (caseWise(expressionToCompare)) {
|
||||||
|
return cb.equal(cb.upper(expressionToCompare), sqlValue.toUpperCase());
|
||||||
|
} else {
|
||||||
|
return cb.equal(expressionToCompare, sqlValue);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Predicate notEqual(final Expression<String> expressionToCompare, String transformedValueStr) {
|
private Predicate notEqual(final Path<String> expressionToCompare, String transformedValueStr) {
|
||||||
return cb.notEqual(caseWise(cb, expressionToCompare), caseWise(transformedValueStr));
|
if (caseWise(expressionToCompare)) {
|
||||||
|
return cb.notEqual(cb.upper(expressionToCompare), transformedValueStr.toUpperCase());
|
||||||
|
} else {
|
||||||
|
return cb.notEqual(expressionToCompare, transformedValueStr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Predicate like(final Expression<String> expressionToCompare, final String sqlValue) {
|
private Predicate like(final Path<String> expressionToCompare, final String sqlValue) {
|
||||||
return cb.like(caseWise(cb, expressionToCompare), caseWise(sqlValue), ESCAPE_CHAR);
|
if (caseWise(expressionToCompare)) {
|
||||||
|
return cb.like(cb.upper(expressionToCompare), sqlValue.toUpperCase(), ESCAPE_CHAR);
|
||||||
|
} else {
|
||||||
|
return cb.like(expressionToCompare, sqlValue, ESCAPE_CHAR);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Predicate notLike(final Expression<String> expressionToCompare, final String sqlValue) {
|
private Predicate notLike(final Path<String> expressionToCompare, final String sqlValue) {
|
||||||
return cb.notLike(caseWise(cb, expressionToCompare), caseWise(sqlValue), ESCAPE_CHAR);
|
if (caseWise(expressionToCompare)) {
|
||||||
|
return cb.notLike(cb.upper(expressionToCompare), sqlValue.toUpperCase(), ESCAPE_CHAR);
|
||||||
|
} else {
|
||||||
|
return cb.notLike(expressionToCompare, sqlValue, ESCAPE_CHAR);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Predicate in(final Expression<String> expressionToCompare, final List<Object> transformedValues) {
|
private Predicate in(final Path<String> expressionToCompare, final List<Object> transformedValues) {
|
||||||
final List<String> inParams = transformedValues.stream().filter(String.class::isInstance)
|
if (ensureIgnoreCase && expressionToCompare.getJavaType() == String.class) {
|
||||||
.map(String.class::cast).map(this::caseWise).collect(Collectors.toList());
|
final List<String> inParams = transformedValues.stream()
|
||||||
return inParams.isEmpty() ? expressionToCompare.in(transformedValues) : caseWise(cb, expressionToCompare).in(inParams);
|
.filter(String.class::isInstance)
|
||||||
|
.map(String.class::cast).map(String::toUpperCase).toList();
|
||||||
|
return inParams.isEmpty() ? expressionToCompare.in(transformedValues) : cb.upper(expressionToCompare).in(inParams);
|
||||||
|
} else {
|
||||||
|
return expressionToCompare.in(transformedValues);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Expression<String> caseWise(final CriteriaBuilder cb, final Expression<String> expression) {
|
private boolean caseWise(final Path<?> fieldPath) {
|
||||||
return ensureIgnoreCase ? cb.upper(expression) : expression;
|
return ensureIgnoreCase && fieldPath.getJavaType() == String.class;
|
||||||
}
|
|
||||||
|
|
||||||
private String caseWise(final String str) {
|
|
||||||
return ensureIgnoreCase ? str.toUpperCase() : str;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -63,8 +63,6 @@ public class RSQLActionFieldsTest extends AbstractJpaIntegrationTest {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
assertRSQLQuery(ActionFields.ID.name() + "==*", 11);
|
|
||||||
assertRSQLQuery(ActionFields.ID.name() + "==noexist*", 0);
|
|
||||||
assertRSQLQuery(ActionFields.ID.name() + "=in=(" + action.getId() + ",10000000)", 1);
|
assertRSQLQuery(ActionFields.ID.name() + "=in=(" + action.getId() + ",10000000)", 1);
|
||||||
assertRSQLQuery(ActionFields.ID.name() + "=out=(" + action.getId() + ",10000000)", 10);
|
assertRSQLQuery(ActionFields.ID.name() + "=out=(" + action.getId() + ",10000000)", 10);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,8 +81,6 @@ public class RSQLDistributionSetFieldTest extends AbstractJpaIntegrationTest {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
assertRSQLQuery(DistributionSetFields.ID.name() + "==*", 5);
|
|
||||||
assertRSQLQuery(DistributionSetFields.ID.name() + "==noexist*", 0);
|
|
||||||
assertRSQLQuery(DistributionSetFields.ID.name() + "=in=(" + ds.getId() + ",10000000)", 1);
|
assertRSQLQuery(DistributionSetFields.ID.name() + "=in=(" + ds.getId() + ",10000000)", 1);
|
||||||
assertRSQLQuery(DistributionSetFields.ID.name() + "=out=(" + ds.getId() + ",10000000)", 4);
|
assertRSQLQuery(DistributionSetFields.ID.name() + "=out=(" + ds.getId() + ",10000000)", 4);
|
||||||
}
|
}
|
||||||
@@ -104,8 +102,8 @@ public class RSQLDistributionSetFieldTest extends AbstractJpaIntegrationTest {
|
|||||||
assertRSQLQuery(DistributionSetFields.MODULE.name() + "." + SoftwareModuleFields.NAME.name() + "==" + sm.getName(), 1);
|
assertRSQLQuery(DistributionSetFields.MODULE.name() + "." + SoftwareModuleFields.NAME.name() + "==" + sm.getName(), 1);
|
||||||
assertRSQLQuery(DistributionSetFields.MODULE.name() + "." + SoftwareModuleFields.ID.name() + "==" + sm.getId(), 1);
|
assertRSQLQuery(DistributionSetFields.MODULE.name() + "." + SoftwareModuleFields.ID.name() + "==" + sm.getId(), 1);
|
||||||
assertRSQLQuery(DistributionSetFields.MODULE.name() + "." + SoftwareModuleFields.NAME.name() + "==noExist", 0);
|
assertRSQLQuery(DistributionSetFields.MODULE.name() + "." + SoftwareModuleFields.NAME.name() + "==noExist", 0);
|
||||||
assertRSQLQuery(DistributionSetFields.MODULE.name() + "." + SoftwareModuleFields.ID.name() + "=in=(" + sm.getId() + ", noExist)", 1);
|
assertRSQLQuery(DistributionSetFields.MODULE.name() + "." + SoftwareModuleFields.ID.name() + "=in=(" + sm.getId() + ", -1)", 1);
|
||||||
assertRSQLQuery(DistributionSetFields.MODULE.name() + "." + SoftwareModuleFields.ID.name() + "=out=(" + sm.getId() + ", noExist)", 4);
|
assertRSQLQuery(DistributionSetFields.MODULE.name() + "." + SoftwareModuleFields.ID.name() + "=out=(" + sm.getId() + ", -1)", 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -128,10 +126,8 @@ public class RSQLDistributionSetFieldTest extends AbstractJpaIntegrationTest {
|
|||||||
public void testFilterByParameterVersion() {
|
public void testFilterByParameterVersion() {
|
||||||
assertRSQLQuery(DistributionSetFields.VERSION.name() + "==" + TestdataFactory.DEFAULT_VERSION, 1);
|
assertRSQLQuery(DistributionSetFields.VERSION.name() + "==" + TestdataFactory.DEFAULT_VERSION, 1);
|
||||||
assertRSQLQuery(DistributionSetFields.VERSION.name() + "!=" + TestdataFactory.DEFAULT_VERSION, 4);
|
assertRSQLQuery(DistributionSetFields.VERSION.name() + "!=" + TestdataFactory.DEFAULT_VERSION, 4);
|
||||||
assertRSQLQuery(
|
assertRSQLQuery(DistributionSetFields.VERSION.name() + "=in=(" + TestdataFactory.DEFAULT_VERSION + ",1.0.0,1.0.1)", 3);
|
||||||
DistributionSetFields.VERSION.name() + "=in=(" + TestdataFactory.DEFAULT_VERSION + ",1.0.0,1.0.1)", 3);
|
assertRSQLQuery(DistributionSetFields.VERSION.name() + "=out=(" + TestdataFactory.DEFAULT_VERSION + ",error)", 4);
|
||||||
assertRSQLQuery(DistributionSetFields.VERSION.name() + "=out=(" + TestdataFactory.DEFAULT_VERSION + ",error)",
|
|
||||||
4);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@@ -58,8 +58,6 @@ public class RSQLRolloutGroupFieldTest extends AbstractJpaIntegrationTest {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
assertRSQLQuery(RolloutGroupFields.ID.name() + "==*", 4);
|
|
||||||
assertRSQLQuery(RolloutGroupFields.ID.name() + "==noexist*", 0);
|
|
||||||
assertRSQLQuery(RolloutGroupFields.ID.name() + "=in=(" + rolloutGroupId + ",10000000)", 1);
|
assertRSQLQuery(RolloutGroupFields.ID.name() + "=in=(" + rolloutGroupId + ",10000000)", 1);
|
||||||
assertRSQLQuery(RolloutGroupFields.ID.name() + "=out=(" + rolloutGroupId + ",10000000)", 3);
|
assertRSQLQuery(RolloutGroupFields.ID.name() + "=out=(" + rolloutGroupId + ",10000000)", 3);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,8 +71,6 @@ public class RSQLSoftwareModuleFieldTest extends AbstractJpaIntegrationTest {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
assertRSQLQuery(SoftwareModuleFields.ID.name() + "==*", 6);
|
|
||||||
assertRSQLQuery(SoftwareModuleFields.ID.name() + "==noexist*", 0);
|
|
||||||
assertRSQLQuery(SoftwareModuleFields.ID.name() + "=in=(" + ah.getId() + ",1000000)", 1);
|
assertRSQLQuery(SoftwareModuleFields.ID.name() + "=in=(" + ah.getId() + ",1000000)", 1);
|
||||||
assertRSQLQuery(SoftwareModuleFields.ID.name() + "=out=(" + ah.getId() + ",1000000)", 5);
|
assertRSQLQuery(SoftwareModuleFields.ID.name() + "=out=(" + ah.getId() + ",1000000)", 5);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,8 +40,6 @@ public class RSQLSoftwareModuleTypeFieldsTest extends AbstractJpaIntegrationTest
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
assertRSQLQuery(SoftwareModuleTypeFields.ID.name() + "==*", 3);
|
|
||||||
assertRSQLQuery(SoftwareModuleTypeFields.ID.name() + "==noexist*", 0);
|
|
||||||
assertRSQLQuery(SoftwareModuleTypeFields.ID.name() + "=in=(" + osType.getId() + ",1000000)", 1);
|
assertRSQLQuery(SoftwareModuleTypeFields.ID.name() + "=in=(" + osType.getId() + ",1000000)", 1);
|
||||||
assertRSQLQuery(SoftwareModuleTypeFields.ID.name() + "=out=(" + osType.getId() + ",1000000)", 2);
|
assertRSQLQuery(SoftwareModuleTypeFields.ID.name() + "=out=(" + osType.getId() + ",1000000)", 2);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -104,8 +104,6 @@ class RSQLTargetFieldTest extends AbstractJpaIntegrationTest {
|
|||||||
@Description("Test filter target by (controller) id")
|
@Description("Test filter target by (controller) id")
|
||||||
void testFilterByParameterId() {
|
void testFilterByParameterId() {
|
||||||
assertRSQLQuery(TargetFields.ID.name() + "==targetId123", 1);
|
assertRSQLQuery(TargetFields.ID.name() + "==targetId123", 1);
|
||||||
assertRSQLQuery(TargetFields.ID.name() + "==target*", 5);
|
|
||||||
assertRSQLQuery(TargetFields.ID.name() + "==noExist*", 0);
|
|
||||||
assertRSQLQuery(TargetFields.ID.name() + "!=targetId123", 4);
|
assertRSQLQuery(TargetFields.ID.name() + "!=targetId123", 4);
|
||||||
assertRSQLQuery(TargetFields.ID.name() + "=in=(targetId123,notexist)", 1);
|
assertRSQLQuery(TargetFields.ID.name() + "=in=(targetId123,notexist)", 1);
|
||||||
assertRSQLQuery(TargetFields.ID.name() + "=out=(targetId123,notexist)", 4);
|
assertRSQLQuery(TargetFields.ID.name() + "=out=(targetId123,notexist)", 4);
|
||||||
|
|||||||
@@ -65,8 +65,6 @@ public class RSQLTargetFilterQueryFieldsTest extends AbstractJpaIntegrationTest
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
assertRSQLQuery(TargetFilterQueryFields.ID.name() + "==*", 3);
|
|
||||||
assertRSQLQuery(TargetFilterQueryFields.ID.name() + "==noexist*", 0);
|
|
||||||
assertRSQLQuery(TargetFilterQueryFields.ID.name() + "=in=(" + filter1.getId() + ",10000000)", 1);
|
assertRSQLQuery(TargetFilterQueryFields.ID.name() + "=in=(" + filter1.getId() + ",10000000)", 1);
|
||||||
assertRSQLQuery(TargetFilterQueryFields.ID.name() + "=out=(" + filter1.getId() + ",10000000)", 2);
|
assertRSQLQuery(TargetFilterQueryFields.ID.name() + "=out=(" + filter1.getId() + ",10000000)", 2);
|
||||||
|
|
||||||
|
|||||||
@@ -270,7 +270,7 @@ public class RSQLUtilityTest {
|
|||||||
reset0(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock);
|
reset0(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock);
|
||||||
final String correctRsql = "name!=abc";
|
final String correctRsql = "name!=abc";
|
||||||
when(baseSoftwareModuleRootMock.get("name")).thenReturn(baseSoftwareModuleRootMock);
|
when(baseSoftwareModuleRootMock.get("name")).thenReturn(baseSoftwareModuleRootMock);
|
||||||
when(baseSoftwareModuleRootMock.getJavaType()).thenReturn((Class) SoftwareModule.class);
|
when(baseSoftwareModuleRootMock.getJavaType()).thenReturn((Class) String.class);
|
||||||
|
|
||||||
when(criteriaBuilderMock.isNull(any(Expression.class))).thenReturn(mock(Predicate.class));
|
when(criteriaBuilderMock.isNull(any(Expression.class))).thenReturn(mock(Predicate.class));
|
||||||
when(criteriaBuilderMock.notEqual(any(Expression.class), anyString()))
|
when(criteriaBuilderMock.notEqual(any(Expression.class), anyString()))
|
||||||
@@ -285,8 +285,7 @@ public class RSQLUtilityTest {
|
|||||||
// verification
|
// verification
|
||||||
verify(criteriaBuilderMock, times(1)).or(any(Predicate.class), any(Predicate.class));
|
verify(criteriaBuilderMock, times(1)).or(any(Predicate.class), any(Predicate.class));
|
||||||
verify(criteriaBuilderMock, times(1)).isNull(eq(pathOfString(baseSoftwareModuleRootMock)));
|
verify(criteriaBuilderMock, times(1)).isNull(eq(pathOfString(baseSoftwareModuleRootMock)));
|
||||||
verify(criteriaBuilderMock, times(1)).notEqual(eq(pathOfString(baseSoftwareModuleRootMock)),
|
verify(criteriaBuilderMock, times(1)).notEqual(eq(pathOfString(baseSoftwareModuleRootMock)), eq("abc".toUpperCase()));
|
||||||
eq("abc".toUpperCase()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -294,7 +293,7 @@ public class RSQLUtilityTest {
|
|||||||
reset0(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock);
|
reset0(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock);
|
||||||
final String correctRsql = "name!=abc*";
|
final String correctRsql = "name!=abc*";
|
||||||
when(baseSoftwareModuleRootMock.get("name")).thenReturn(baseSoftwareModuleRootMock);
|
when(baseSoftwareModuleRootMock.get("name")).thenReturn(baseSoftwareModuleRootMock);
|
||||||
when(baseSoftwareModuleRootMock.getJavaType()).thenReturn((Class) SoftwareModule.class);
|
when(baseSoftwareModuleRootMock.getJavaType()).thenReturn((Class) String.class);
|
||||||
|
|
||||||
when(criteriaBuilderMock.isNull(any(Expression.class))).thenReturn(mock(Predicate.class));
|
when(criteriaBuilderMock.isNull(any(Expression.class))).thenReturn(mock(Predicate.class));
|
||||||
when(criteriaBuilderMock.notLike(any(Expression.class), anyString(), eq('\\')))
|
when(criteriaBuilderMock.notLike(any(Expression.class), anyString(), eq('\\')))
|
||||||
@@ -346,7 +345,7 @@ public class RSQLUtilityTest {
|
|||||||
reset0(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock);
|
reset0(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock);
|
||||||
final String correctRsql = "name==a%";
|
final String correctRsql = "name==a%";
|
||||||
when(baseSoftwareModuleRootMock.get("name")).thenReturn(baseSoftwareModuleRootMock);
|
when(baseSoftwareModuleRootMock.get("name")).thenReturn(baseSoftwareModuleRootMock);
|
||||||
when(baseSoftwareModuleRootMock.getJavaType()).thenReturn((Class) SoftwareModule.class);
|
when(baseSoftwareModuleRootMock.getJavaType()).thenReturn((Class) String.class);
|
||||||
when(criteriaBuilderMock.equal(any(Expression.class), anyString())).thenReturn(mock(Predicate.class));
|
when(criteriaBuilderMock.equal(any(Expression.class), anyString())).thenReturn(mock(Predicate.class));
|
||||||
when(criteriaBuilderMock.<String> greaterThanOrEqualTo(any(Expression.class), any(String.class)))
|
when(criteriaBuilderMock.<String> greaterThanOrEqualTo(any(Expression.class), any(String.class)))
|
||||||
.thenReturn(mock(Predicate.class));
|
.thenReturn(mock(Predicate.class));
|
||||||
@@ -367,7 +366,7 @@ public class RSQLUtilityTest {
|
|||||||
reset0(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock);
|
reset0(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock);
|
||||||
final String correctRsql = "name==a%*";
|
final String correctRsql = "name==a%*";
|
||||||
when(baseSoftwareModuleRootMock.get("name")).thenReturn(baseSoftwareModuleRootMock);
|
when(baseSoftwareModuleRootMock.get("name")).thenReturn(baseSoftwareModuleRootMock);
|
||||||
when(baseSoftwareModuleRootMock.getJavaType()).thenReturn((Class) SoftwareModule.class);
|
when(baseSoftwareModuleRootMock.getJavaType()).thenReturn((Class) String.class);
|
||||||
when(criteriaBuilderMock.like(any(Expression.class), anyString(), eq('\\'))).thenReturn(mock(Predicate.class));
|
when(criteriaBuilderMock.like(any(Expression.class), anyString(), eq('\\'))).thenReturn(mock(Predicate.class));
|
||||||
when(criteriaBuilderMock.<String> greaterThanOrEqualTo(any(Expression.class), any(String.class)))
|
when(criteriaBuilderMock.<String> greaterThanOrEqualTo(any(Expression.class), any(String.class)))
|
||||||
.thenReturn(mock(Predicate.class));
|
.thenReturn(mock(Predicate.class));
|
||||||
@@ -388,7 +387,7 @@ public class RSQLUtilityTest {
|
|||||||
reset0(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock);
|
reset0(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock);
|
||||||
final String correctRsql = "name==a%*";
|
final String correctRsql = "name==a%*";
|
||||||
when(baseSoftwareModuleRootMock.get("name")).thenReturn(baseSoftwareModuleRootMock);
|
when(baseSoftwareModuleRootMock.get("name")).thenReturn(baseSoftwareModuleRootMock);
|
||||||
when(baseSoftwareModuleRootMock.getJavaType()).thenReturn((Class) SoftwareModule.class);
|
when(baseSoftwareModuleRootMock.getJavaType()).thenReturn((Class) String.class);
|
||||||
when(criteriaBuilderMock.upper(eq(pathOfString(baseSoftwareModuleRootMock))))
|
when(criteriaBuilderMock.upper(eq(pathOfString(baseSoftwareModuleRootMock))))
|
||||||
.thenReturn(pathOfString(baseSoftwareModuleRootMock));
|
.thenReturn(pathOfString(baseSoftwareModuleRootMock));
|
||||||
when(criteriaBuilderMock.like(any(Expression.class), anyString(), eq('\\'))).thenReturn(mock(Predicate.class));
|
when(criteriaBuilderMock.like(any(Expression.class), anyString(), eq('\\'))).thenReturn(mock(Predicate.class));
|
||||||
|
|||||||
Reference in New Issue
Block a user