Consider Target Fields when validating RSQL filters (#1121)
* Removed unnecessary DB queries when editing/validating RSQL query in Target Filter Management (#1023) Added valid TargetFields to RSQL validation when editing Target Filter. Signed-off-by: Sergey Gerasimov <sergey.gerasimov@devolo.de> * Corrected visit OrNode implementation. Changed isValid to receive FieldNameProvider as parameter Reduced code duplication by moving commonly used utility methods to AbstractFieldNameRSQLVisitor from ValidationRSQLVisitor abd JpqQueryRSQLVisitor Refactored and extended Unit Tests. Minor corrections and typos. Signed-off-by: Sergey Gerasimov <sergey.gerasimov@devolo.de> * Added Maven entry for devolo 2020 copyright header. Signed-off-by: Sergey Gerasimov <sergey.gerasimov@devolo.de> * Fix failing unit tests * # WARNING: head commit changed in the meantime Signed-off-by: Stefan Behl <stefan.behl@bosch.io> * Fix Sonar findings. Signed-off-by: Stefan Behl <stefan.behl@bosch.io> * Cleanup Signed-off-by: Stefan Behl <stefan.behl@bosch.io> * Fix PR review findings * Fix invalid queries in unit tests Signed-off-by: Stefan Behl <stefan.behl@bosch.io> * Added test case to create filter with invalid query via Mgmt REST API Signed-off-by: Stefan Behl <stefan.behl@bosch.io> Co-authored-by: Sergey Gerasimov <sergey.gerasimov@devolo.de>
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* Copyright (c) 2020 devolo AG and others.
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*/
|
||||
package org.eclipse.hawkbit.repository.jpa.rsql;
|
||||
|
||||
import org.eclipse.hawkbit.repository.TargetFields;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
|
||||
@Feature("Component Tests - Repository")
|
||||
@Story("RSQL target field validation")
|
||||
public class RSQLTargetFieldValidationTest {
|
||||
@Test
|
||||
@Description("Testing allowed RSQL keys based on TargetFields.class")
|
||||
public void rsqlValidTargetFields() {
|
||||
final String rsql1 = "ID == '0123' and NAME == abcd and DESCRIPTION == absd"
|
||||
+ " and CREATEDAT =lt= 0123 and LASTMODIFIEDAT =gt= 0123"
|
||||
+ " and CONTROLLERID == 0123 and UPDATESTATUS == PENDING"
|
||||
+ " and IPADDRESS == 0123 and LASTCONTROLLERREQUESTAT == 0123" + " and tag == beta";
|
||||
|
||||
RSQLUtility.validateRsqlFor(rsql1, TargetFields.class);
|
||||
|
||||
final String rsql2 = "ASSIGNEDDS.name == abcd and ASSIGNEDDS.version == 0123"
|
||||
+ " and INSTALLEDDS.name == abcd and INSTALLEDDS.version == 0123";
|
||||
RSQLUtility.validateRsqlFor(rsql2, TargetFields.class);
|
||||
|
||||
final String rsql3 = "ATTRIBUTE.subkey1 == test and ATTRIBUTE.subkey2 == test"
|
||||
+ " and METADATA.metakey1 == abcd and METADATA.metavalue2 == asdfg";
|
||||
RSQLUtility.validateRsqlFor(rsql3, TargetFields.class);
|
||||
|
||||
final String rsql4 = "CREATEDAT =lt= ${NOW_TS} and LASTMODIFIEDAT =ge= ${OVERDUE_TS}";
|
||||
RSQLUtility.validateRsqlFor(rsql4, TargetFields.class);
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@
|
||||
*/
|
||||
package org.eclipse.hawkbit.repository.jpa.rsql;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
@@ -19,6 +20,9 @@ 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 javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.Expression;
|
||||
@@ -99,6 +103,46 @@ public class RSQLUtilityTest {
|
||||
private static final TenantConfigurationValue<String> TEST_POLLING_OVERDUE_TIME_INTERVAL = TenantConfigurationValue
|
||||
.<String> builder().value("00:07:37").build();
|
||||
|
||||
@Test
|
||||
@Description("Testing throwing exception in case of not allowed RSQL key")
|
||||
public void rsqlUnsupportedFieldExceptionTest() {
|
||||
final String rsql1 = "wrongfield == abcd";
|
||||
assertThatExceptionOfType(RSQLParameterUnsupportedFieldException.class)
|
||||
.isThrownBy(() -> RSQLUtility.validateRsqlFor(rsql1, TestFieldEnum.class));
|
||||
|
||||
final String rsql2 = "wrongfield == abcd or TESTFIELD_WITH_SUB_ENTITIES.subentity11 == 0123";
|
||||
assertThatExceptionOfType(RSQLParameterUnsupportedFieldException.class)
|
||||
.isThrownBy(() -> RSQLUtility.validateRsqlFor(rsql2, TestFieldEnum.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Testing exception in case of not allowed subkey")
|
||||
public void rsqlUnsupportedSubkeyThrowException() {
|
||||
final String rsql1 = "TESTFIELD_WITH_SUB_ENTITIES.unsupported == abcd and TESTFIELD_WITH_SUB_ENTITIES.subentity22 == 0123";
|
||||
assertThatExceptionOfType(RSQLParameterUnsupportedFieldException.class)
|
||||
.isThrownBy(() -> RSQLUtility.validateRsqlFor(rsql1, TestFieldEnum.class));
|
||||
|
||||
final String rsql2 = "TESTFIELD_WITH_SUB_ENTITIES.unsupported == abcd or TESTFIELD_WITH_SUB_ENTITIES.subentity22 == 0123";
|
||||
assertThatExceptionOfType(RSQLParameterUnsupportedFieldException.class)
|
||||
.isThrownBy(() -> RSQLUtility.validateRsqlFor(rsql2, TestFieldEnum.class));
|
||||
|
||||
final String rsql3 = "TESTFIELD == abcd or TESTFIELD_WITH_SUB_ENTITIES.unsupported == 0123";
|
||||
assertThatExceptionOfType(RSQLParameterUnsupportedFieldException.class)
|
||||
.isThrownBy(() -> RSQLUtility.validateRsqlFor(rsql3, TestFieldEnum.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Testing valid RSQL keys based on TestFieldEnum.class")
|
||||
public void rsqlFieldValidation() {
|
||||
final String rsql1 = "TESTFIELD_WITH_SUB_ENTITIES.subentity11 == abcd and TESTFIELD_WITH_SUB_ENTITIES.subentity22 == 0123";
|
||||
final String rsql2 = "TESTFIELD_WITH_SUB_ENTITIES.subentity11 == abcd or TESTFIELD_WITH_SUB_ENTITIES.subentity22 == 0123";
|
||||
final String rsql3 = "TESTFIELD_WITH_SUB_ENTITIES.subentity11 == abcd and TESTFIELD_WITH_SUB_ENTITIES.subentity22 == 0123 and TESTFIELD == any";
|
||||
|
||||
RSQLUtility.validateRsqlFor(rsql1, TestFieldEnum.class);
|
||||
RSQLUtility.validateRsqlFor(rsql2, TestFieldEnum.class);
|
||||
RSQLUtility.validateRsqlFor(rsql3, TestFieldEnum.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void wrongRsqlSyntaxThrowSyntaxException() {
|
||||
final String wrongRSQL = "name==abc;d";
|
||||
@@ -421,23 +465,32 @@ public class RSQLUtilityTest {
|
||||
}
|
||||
|
||||
private enum TestFieldEnum implements FieldNameProvider {
|
||||
TESTFIELD;
|
||||
TESTFIELD("testfield"), TESTFIELD_WITH_SUB_ENTITIES("testfieldWithSubEntities", "subentity11", "subentity22");
|
||||
|
||||
private final String fieldName;
|
||||
private 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));
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.eclipse.hawkbit.server.rest.resource.model.FieldNameProvider#
|
||||
* getFieldName()
|
||||
*/
|
||||
@Override
|
||||
public String getFieldName() {
|
||||
return "testfield";
|
||||
return this.fieldName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getSubEntityAttributes() {
|
||||
return subEntityAttributes;
|
||||
}
|
||||
}
|
||||
|
||||
private enum TestValueEnum {
|
||||
BUMLUX;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user