Feature target metadata filter (#767)
* implemented RSQL query filter for target metadata Signed-off-by: Bogdan Bondar <Bogdan.Bondar@bosch-si.com> * refactored rsql fields providers code for targets, distribution sets and software modules for consistency, fixed predicate grouping for map fields in rsql utility Signed-off-by: Bogdan Bondar <Bogdan.Bondar@bosch-si.com> * extended tests for target management rsql queries with target metadata Signed-off-by: Bogdan Bondar <Bogdan.Bondar@bosch-si.com> * extended target management test for RSQL not equal case of target metadata, added a suggestion of comparator operators when map key ends with = or ! symbol in Target Filter View Signed-off-by: Bogdan Bondar <Bogdan.Bondar@bosch-si.com> * Fixed peer review findings Signed-off-by: Bogdan Bondar <Bogdan.Bondar@bosch-si.com> * small test fixes: seconds are respected while scheduling the maintenance window, redundant ds-target assignment statement removed Signed-off-by: Bogdan Bondar <Bogdan.Bondar@bosch-si.com>
This commit is contained in:
committed by
Dominic Schabel
parent
a460f61e13
commit
b2dfd4a99e
@@ -149,7 +149,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
|
||||
"TargetMetadata");
|
||||
verifyThrownExceptionBy(() -> targetManagement.getMetaDataByControllerId(NOT_EXIST_ID, "xxx"), "Target");
|
||||
verifyThrownExceptionBy(() -> targetManagement.findMetaDataByControllerId(PAGE, NOT_EXIST_ID), "Target");
|
||||
verifyThrownExceptionBy(() -> targetManagement.findMetaDataByControllerIdAndRsql(PAGE, NOT_EXIST_ID, "name==*"),
|
||||
verifyThrownExceptionBy(() -> targetManagement.findMetaDataByControllerIdAndRsql(PAGE, NOT_EXIST_ID, "key==*"),
|
||||
"Target");
|
||||
verifyThrownExceptionBy(
|
||||
() -> targetManagement.updateMetadata(NOT_EXIST_ID, entityFactory.generateTargetMetadata("xxx", "xxx")),
|
||||
@@ -921,7 +921,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
|
||||
final String knownValue = "targetMetaKnownValue";
|
||||
|
||||
final Target target = testdataFactory.createTarget("targetIdWithMetadata");
|
||||
final JpaTargetMetadata createdMetadata = insertTargetMetadata(knownKey, target, knownValue);
|
||||
final JpaTargetMetadata createdMetadata = insertTargetMetadata(knownKey, knownValue, target);
|
||||
|
||||
assertThat(createdMetadata).isNotNull();
|
||||
assertThat(createdMetadata.getId().getKey()).isEqualTo(knownKey);
|
||||
@@ -930,8 +930,8 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
|
||||
assertThat(createdMetadata.getValue()).isEqualTo(knownValue);
|
||||
}
|
||||
|
||||
private JpaTargetMetadata insertTargetMetadata(final String knownKey, final Target target,
|
||||
final String knownValue) {
|
||||
private JpaTargetMetadata insertTargetMetadata(final String knownKey, final String knownValue,
|
||||
final Target target) {
|
||||
final JpaTargetMetadata metadata = new JpaTargetMetadata(knownKey, knownValue, target);
|
||||
return (JpaTargetMetadata) targetManagement
|
||||
.createMetaData(target.getControllerId(), Collections.singletonList(metadata)).get(0);
|
||||
@@ -945,12 +945,12 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
|
||||
final Target target1 = testdataFactory.createTarget("target1");
|
||||
final int maxMetaData = quotaManagement.getMaxMetaDataEntriesPerTarget();
|
||||
for (int i = 0; i < maxMetaData; ++i) {
|
||||
assertThat(insertTargetMetadata("k" + i, target1, "v" + i)).isNotNull();
|
||||
assertThat(insertTargetMetadata("k" + i, "v" + i, target1)).isNotNull();
|
||||
}
|
||||
|
||||
// quota exceeded
|
||||
assertThatExceptionOfType(QuotaExceededException.class)
|
||||
.isThrownBy(() -> insertTargetMetadata("k" + maxMetaData, target1, "v" + maxMetaData));
|
||||
.isThrownBy(() -> insertTargetMetadata("k" + maxMetaData, "v" + maxMetaData, target1));
|
||||
|
||||
// add multiple meta data entries at once
|
||||
final Target target2 = testdataFactory.createTarget("target2");
|
||||
@@ -966,7 +966,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
|
||||
final Target target3 = testdataFactory.createTarget("target3");
|
||||
final int firstHalf = Math.round(maxMetaData / 2);
|
||||
for (int i = 0; i < firstHalf; ++i) {
|
||||
insertTargetMetadata("k" + i, target3, "v" + i);
|
||||
insertTargetMetadata("k" + i, "v" + i, target3);
|
||||
}
|
||||
// add too many data entries
|
||||
final int secondHalf = maxMetaData - firstHalf;
|
||||
@@ -994,7 +994,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
|
||||
assertThat(target.getOptLockRevision()).isEqualTo(1);
|
||||
|
||||
// create target meta data entry
|
||||
insertTargetMetadata(knownKey, target, knownValue);
|
||||
insertTargetMetadata(knownKey, knownValue, target);
|
||||
|
||||
Target changedLockRevisionTarget = targetManagement.get(target.getId()).get();
|
||||
assertThat(changedLockRevisionTarget.getOptLockRevision()).isEqualTo(2);
|
||||
@@ -1024,16 +1024,8 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
|
||||
@Description("Queries and loads the metadata related to a given target.")
|
||||
public void findAllTargetMetadataByControllerId() {
|
||||
// create targets
|
||||
final Target target1 = testdataFactory.createTarget("target1");
|
||||
final Target target2 = testdataFactory.createTarget("target2");
|
||||
|
||||
for (int index = 0; index < 10; index++) {
|
||||
insertTargetMetadata("key" + index, target1, "value" + index);
|
||||
}
|
||||
|
||||
for (int index = 0; index < 8; index++) {
|
||||
insertTargetMetadata("key" + index, target2, "value" + index);
|
||||
}
|
||||
final Target target1 = createTargetWithMetadata("target1", 10);
|
||||
final Target target2 = createTargetWithMetadata("target2", 8);
|
||||
|
||||
final Page<TargetMetadata> metadataOfTarget1 = targetManagement
|
||||
.findMetaDataByControllerId(new PageRequest(0, 100), target1.getControllerId());
|
||||
@@ -1047,4 +1039,47 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
|
||||
assertThat(metadataOfTarget2.getNumberOfElements()).isEqualTo(8);
|
||||
assertThat(metadataOfTarget2.getTotalElements()).isEqualTo(8);
|
||||
}
|
||||
|
||||
private Target createTargetWithMetadata(final String controllerId, final int count) {
|
||||
final Target target = testdataFactory.createTarget(controllerId);
|
||||
|
||||
for (int index = 1; index <= count; index++) {
|
||||
insertTargetMetadata("key" + index, controllerId + "-value" + index, target);
|
||||
}
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Test that RSQL filter finds targets with metadata and/or controllerId.")
|
||||
public void findTargetsByRsqlWithMetadata() {
|
||||
final String controllerId1 = "target1";
|
||||
final String controllerId2 = "target2";
|
||||
createTargetWithMetadata(controllerId1, 2);
|
||||
createTargetWithMetadata(controllerId2, 2);
|
||||
|
||||
final String rsqlAndControllerIdFilter = "id==target1 and metadata.key1==target1-value1";
|
||||
final String rsqlAndControllerIdWithWrongKeyFilter = "id==* and metadata.unknown==value1";
|
||||
final String rsqlAndControllerIdNotEqualFilter = "id==* and metadata.key2!=target1-value2";
|
||||
final String rsqlOrControllerIdFilter = "id==target1 or metadata.key1==*value1";
|
||||
final String rsqlOrControllerIdWithWrongKeyFilter = "id==target2 or metadata.unknown==value1";
|
||||
final String rsqlOrControllerIdNotEqualFilter = "id==target1 or metadata.key1!=target1-value1";
|
||||
|
||||
assertThat(targetManagement.count()).as("Total targets").isEqualTo(2);
|
||||
validateFoundTargetsByRsql(rsqlAndControllerIdFilter, controllerId1);
|
||||
validateFoundTargetsByRsql(rsqlAndControllerIdWithWrongKeyFilter);
|
||||
validateFoundTargetsByRsql(rsqlAndControllerIdNotEqualFilter, controllerId2);
|
||||
validateFoundTargetsByRsql(rsqlOrControllerIdFilter, controllerId1, controllerId2);
|
||||
validateFoundTargetsByRsql(rsqlOrControllerIdWithWrongKeyFilter, controllerId2);
|
||||
validateFoundTargetsByRsql(rsqlOrControllerIdNotEqualFilter, controllerId1, controllerId2);
|
||||
}
|
||||
|
||||
private void validateFoundTargetsByRsql(final String rsqlFilter, final String... controllerIds) {
|
||||
final Page<Target> foundTargetsByMetadataAndControllerId = targetManagement.findByRsql(PAGE, rsqlFilter);
|
||||
|
||||
assertThat(foundTargetsByMetadataAndControllerId.getTotalElements()).as("Targets count in RSQL filter is wrong")
|
||||
.isEqualTo(controllerIds.length);
|
||||
assertThat(foundTargetsByMetadataAndControllerId.getContent().stream().map(Target::getControllerId))
|
||||
.as("Targets found by RSQL filter have wrong controller ids").containsExactlyInAnyOrder(controllerIds);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,7 +112,7 @@ public class RSQLDistributionSetFieldTest extends AbstractJpaIntegrationTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Test filter distribution set by tag")
|
||||
@Description("Test filter distribution set by tag name")
|
||||
public void testFilterByTag() {
|
||||
assertRSQLQuery(DistributionSetFields.TAG.name() + "==Tag1", 2);
|
||||
// does not include untagged sets
|
||||
@@ -124,7 +124,7 @@ public class RSQLDistributionSetFieldTest extends AbstractJpaIntegrationTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Test filter distribution set by type")
|
||||
@Description("Test filter distribution set by type key")
|
||||
public void testFilterByType() {
|
||||
assertRSQLQuery(DistributionSetFields.TYPE.name() + "==" + TestdataFactory.DS_TYPE_DEFAULT, 4);
|
||||
assertRSQLQuery(DistributionSetFields.TYPE.name() + "==noExist*", 0);
|
||||
@@ -133,7 +133,7 @@ public class RSQLDistributionSetFieldTest extends AbstractJpaIntegrationTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("")
|
||||
@Description("Test filter distribution set by metadata")
|
||||
public void testFilterByMetadata() {
|
||||
assertRSQLQuery(DistributionSetFields.METADATA.name() + ".metaKey==metaValue", 1);
|
||||
assertRSQLQuery(DistributionSetFields.METADATA.name() + ".metaKey==*v*", 2);
|
||||
|
||||
@@ -92,7 +92,7 @@ public class RSQLSoftwareModuleFieldTest extends AbstractJpaIntegrationTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Test filter software module by type")
|
||||
@Description("Test filter software module by type key")
|
||||
public void testFilterByType() {
|
||||
assertRSQLQuery(SoftwareModuleFields.TYPE.name() + "==" + TestdataFactory.SM_TYPE_APP, 2);
|
||||
assertRSQLQuery(SoftwareModuleFields.TYPE.name() + "!=" + TestdataFactory.SM_TYPE_APP, 3);
|
||||
|
||||
@@ -49,6 +49,7 @@ public class RSQLTargetFieldTest extends AbstractJpaIntegrationTest {
|
||||
attributes.put("revision", "1.1");
|
||||
target = controllerManagement.updateControllerAttributes(target.getControllerId(), attributes, null);
|
||||
target = controllerManagement.findOrRegisterTargetIfItDoesNotexist(target.getControllerId(), LOCALHOST);
|
||||
createTargetMetadata(target.getControllerId(), entityFactory.generateTargetMetadata("metaKey", "metaValue"));
|
||||
|
||||
target2 = targetManagement
|
||||
.create(entityFactory.target().create().controllerId("targetId1234").description("targetId1234"));
|
||||
@@ -56,6 +57,7 @@ public class RSQLTargetFieldTest extends AbstractJpaIntegrationTest {
|
||||
Thread.sleep(1);
|
||||
target2 = controllerManagement.updateControllerAttributes(target2.getControllerId(), attributes, null);
|
||||
target2 = controllerManagement.findOrRegisterTargetIfItDoesNotexist(target2.getControllerId(), LOCALHOST);
|
||||
createTargetMetadata(target2.getControllerId(), entityFactory.generateTargetMetadata("metaKey", "value"));
|
||||
|
||||
final Target target3 = testdataFactory.createTarget("targetId1235");
|
||||
final Target target4 = testdataFactory.createTarget("targetId1236");
|
||||
@@ -168,7 +170,7 @@ public class RSQLTargetFieldTest extends AbstractJpaIntegrationTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Test filter target by tag")
|
||||
@Description("Test filter target by tag name")
|
||||
public void testFilterByTag() {
|
||||
assertRSQLQuery(TargetFields.TAG.name() + "==Tag1", 2);
|
||||
assertRSQLQuery(TargetFields.TAG.name() + "!=Tag1", 2);
|
||||
@@ -194,6 +196,18 @@ public class RSQLTargetFieldTest extends AbstractJpaIntegrationTest {
|
||||
assertRSQLQuery(TargetFields.LASTCONTROLLERREQUESTAT.name() + "=gt=${OVERDUE_TS}", 2);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Test filter target by metadata")
|
||||
public void testFilterByMetadata() {
|
||||
assertRSQLQuery(TargetFields.METADATA.name() + ".metaKey==metaValue", 1);
|
||||
assertRSQLQuery(TargetFields.METADATA.name() + ".metaKey==*v*", 2);
|
||||
assertRSQLQuery(TargetFields.METADATA.name() + ".metaKey==noExist*", 0);
|
||||
assertRSQLQuery(TargetFields.METADATA.name() + ".metaKey=in=(metaValue,notexist)", 1);
|
||||
assertRSQLQuery(TargetFields.METADATA.name() + ".metaKey=out=(metaValue,notexist)", 1);
|
||||
assertRSQLQuery(TargetFields.METADATA.name() + ".notExist==metaValue", 0);
|
||||
|
||||
}
|
||||
|
||||
private void assertRSQLQuery(final String rsqlParam, final long expcetedTargets) {
|
||||
final Page<Target> findTargetPage = targetManagement.findByRsql(PAGE, rsqlParam);
|
||||
final long countTargetsAll = findTargetPage.getTotalElements();
|
||||
|
||||
@@ -115,15 +115,23 @@ public class RSQLUtilityTest {
|
||||
try {
|
||||
RSQLUtility.parse(wrongRSQL, TargetFields.class, null, testDb).toPredicate(baseSoftwareModuleRootMock,
|
||||
criteriaQueryMock, criteriaBuilderMock);
|
||||
fail("Missing expected RSQLParameterSyntaxException because of wrong RSQL syntax");
|
||||
fail("Missing expected RSQLParameterSyntaxException for target attributes map, caused by wrong RSQL syntax (key was not present)");
|
||||
} catch (final RSQLParameterUnsupportedFieldException e) {
|
||||
}
|
||||
|
||||
wrongRSQL = TargetFields.ATTRIBUTE + ".unkwon.wrong==abc";
|
||||
wrongRSQL = TargetFields.ATTRIBUTE + ".unknown.wrong==abc";
|
||||
try {
|
||||
RSQLUtility.parse(wrongRSQL, TargetFields.class, null, testDb).toPredicate(baseSoftwareModuleRootMock,
|
||||
criteriaQueryMock, criteriaBuilderMock);
|
||||
fail("Missing expected RSQLParameterSyntaxException because of wrong RSQL syntax");
|
||||
fail("Missing expected RSQLParameterSyntaxException for target attributes map, caused by wrong RSQL syntax (key includes dots)");
|
||||
} catch (final RSQLParameterUnsupportedFieldException e) {
|
||||
}
|
||||
|
||||
wrongRSQL = TargetFields.METADATA + ".unknown.wrong==abc";
|
||||
try {
|
||||
RSQLUtility.parse(wrongRSQL, TargetFields.class, null, testDb).toPredicate(baseSoftwareModuleRootMock,
|
||||
criteriaQueryMock, criteriaBuilderMock);
|
||||
fail("Missing expected RSQLParameterSyntaxException for target metadata map, caused by wrong RSQL syntax (key includes dots)");
|
||||
} catch (final RSQLParameterUnsupportedFieldException e) {
|
||||
}
|
||||
|
||||
@@ -131,7 +139,7 @@ public class RSQLUtilityTest {
|
||||
try {
|
||||
RSQLUtility.parse(wrongRSQL, DistributionSetFields.class, null, testDb)
|
||||
.toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock);
|
||||
fail("Missing expected RSQLParameterSyntaxException because of wrong RSQL syntax");
|
||||
fail("Missing expected RSQLParameterSyntaxException for distribution set metadata map, caused by wrong RSQL syntax (key was not present)");
|
||||
} catch (final RSQLParameterUnsupportedFieldException e) {
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user