From be3dfbf617abc8f333b1543ce9ee3d69017c524d Mon Sep 17 00:00:00 2001 From: Markus Block Date: Mon, 18 Oct 2021 10:51:04 +0200 Subject: [PATCH] Ensure a '.' character is allowed to be used in target filter query for metadata key and attribute name (#1186) * Adapted code to allow '.' inside of metadata key and attribute names Signed-off-by: Markus Block * added handling of corner cases Signed-off-by: Markus Block * Adapted metadata and attribute tests to check that dot is allowed Signed-off-by: Markus Block * fixed documentation Signed-off-by: Markus Block * Allow usage of dot in key names for every map attribute, e.g. also for metadata in distribution set Signed-off-by: Markus Block * fixed typo Signed-off-by: Markus Block * adapted test key to ensure a dot can be used Signed-off-by: Markus Block * fixed typo Signed-off-by: Markus Block --- docs/content/ui.md | 5 +- .../hawkbit/repository/FieldNameProvider.java | 30 ++++++++-- .../hawkbit/repository/TargetFields.java | 2 +- .../rsql/AbstractFieldNameRSQLVisitor.java | 23 ++++---- .../jpa/rsql/JpaQueryRsqlVisitor.java | 10 ++-- .../rsql/RSQLDistributionSetFieldTest.java | 36 +++++++++++- .../jpa/rsql/RSQLTargetFieldTest.java | 55 +++++++++++++++++++ .../MgmtDistributionSetResourceTest.java | 2 +- .../rest/resource/MgmtTargetResourceTest.java | 8 +-- 9 files changed, 138 insertions(+), 33 deletions(-) diff --git a/docs/content/ui.md b/docs/content/ui.md index d655007a2..9f2f4966a 100644 --- a/docs/content/ui.md +++ b/docs/content/ui.md @@ -128,7 +128,8 @@ Custom target filter overview and filter management. The basic syntax to filter is: `fieldvalue fieldvalue <...>` - `field`: is the name of the resource field. -- `value`: is the value of the target field +- `value`: is the expected value of the target field. + - Use `*` for wildcard matches. - ``: Are operators to do simple queries. Supported basic operators are: - `==` : equal - `!=` : not equal @@ -136,8 +137,6 @@ The basic syntax to filter is: `fieldvalue - ``: Are operators to join simple queries: Supported composite operators are: - `and` - `or` - - Use `=IN=` for 'in' parameter.(Example: name=IN=(target1,target2). - - Use `*` for wildcard matches. ### Examples diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/FieldNameProvider.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/FieldNameProvider.java index d54a57011..c15475836 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/FieldNameProvider.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/FieldNameProvider.java @@ -14,6 +14,8 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Optional; +import org.springframework.util.StringUtils; + /** * An interface for declaring the name of the field described in the database * which is used as string representation of the field, e.g. for sorting the @@ -25,7 +27,7 @@ public interface FieldNameProvider { /** * Separator for the sub attributes */ - String SUB_ATTRIBUTE_SEPERATOR = "."; + String SUB_ATTRIBUTE_SEPARATOR = "."; /** * @return the string representation of the underlying persistence field @@ -33,6 +35,26 @@ public interface FieldNameProvider { */ String getFieldName(); + /** + * Returns the sub attributes + * + * @param propertyFieldName + * the given field + * @return array consisting of sub attributes + */ + default String[] getSubAttributes(final String propertyFieldName) { + if (isMap()) { + final String[] subAttributes = propertyFieldName.split("\\" + SUB_ATTRIBUTE_SEPARATOR, 2); + // [0] fieldname |[1] keyname + final String mapKeyName = subAttributes.length == 2 ? subAttributes[1] : null; + if (StringUtils.isEmpty(mapKeyName)) { + return new String[] { getFieldName() }; + } + return new String[] { getFieldName(), mapKeyName }; + } + return propertyFieldName.split("\\" + SUB_ATTRIBUTE_SEPARATOR); + } + /** * Contains the sub entity the given field. * @@ -47,7 +69,7 @@ public interface FieldNameProvider { return true; } for (final String attribute : subEntityAttributes) { - final String[] graph = attribute.split("\\" + SUB_ATTRIBUTE_SEPERATOR); + final String[] graph = attribute.split("\\" + SUB_ATTRIBUTE_SEPARATOR); for (final String subAttribute : graph) { if (subAttribute.equalsIgnoreCase(propertyField)) { @@ -74,7 +96,7 @@ public interface FieldNameProvider { } /** - * Is the entity field a {@link Map}. + * Is the entity field a {@link Map} consisting of key-value pairs. * * @return true is a map false is not a map */ @@ -84,7 +106,7 @@ public interface FieldNameProvider { /** * Returns the name of the field, that identifies the entity. - * + * * @return the name of the identifier, by default 'id' */ default String identifierFieldName() { diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/TargetFields.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/TargetFields.java index 0cb82f3be..2c620fa85 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/TargetFields.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/TargetFields.java @@ -135,4 +135,4 @@ public enum TargetFields implements FieldNameProvider { public String getFieldName() { return fieldName; } -} +} \ No newline at end of file diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/rsql/AbstractFieldNameRSQLVisitor.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/rsql/AbstractFieldNameRSQLVisitor.java index ece88ff41..fbea748e8 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/rsql/AbstractFieldNameRSQLVisitor.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/rsql/AbstractFieldNameRSQLVisitor.java @@ -8,15 +8,16 @@ */ package org.eclipse.hawkbit.repository.jpa.rsql; -import cz.jirutka.rsql.parser.ast.ComparisonNode; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + import org.eclipse.hawkbit.repository.FieldNameProvider; import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.Arrays; -import java.util.List; -import java.util.stream.Collectors; +import cz.jirutka.rsql.parser.ast.ComparisonNode; public abstract class AbstractFieldNameRSQLVisitor & FieldNameProvider> { @@ -30,7 +31,7 @@ public abstract class AbstractFieldNameRSQLVisitor & FieldName protected A getFieldEnumByName(final ComparisonNode node) { String enumName = node.getSelector(); - final String[] graph = getSubAttributesFrom(enumName); + final String[] graph = enumName.split("\\" + FieldNameProvider.SUB_ATTRIBUTE_SEPARATOR); if (graph.length != 0) { enumName = graph[0]; } @@ -42,13 +43,9 @@ public abstract class AbstractFieldNameRSQLVisitor & FieldName } } - protected static String[] getSubAttributesFrom(final String property) { - return property.split("\\" + FieldNameProvider.SUB_ATTRIBUTE_SEPERATOR); - } - protected String getAndValidatePropertyFieldName(final A propertyEnum, final ComparisonNode node) { - final String[] graph = getSubAttributesFrom(node.getSelector()); + final String[] graph = propertyEnum.getSubAttributes(node.getSelector()); validateMapParameter(propertyEnum, node, graph); @@ -62,7 +59,7 @@ public abstract class AbstractFieldNameRSQLVisitor & FieldName for (int i = 1; i < graph.length; i++) { final String propertyField = graph[i]; - fieldNameBuilder.append(FieldNameProvider.SUB_ATTRIBUTE_SEPERATOR).append(propertyField); + fieldNameBuilder.append(FieldNameProvider.SUB_ATTRIBUTE_SEPARATOR).append(propertyField); // the key of map is not in the graph if (propertyEnum.isMap() && graph.length == (i + 1)) { @@ -126,7 +123,7 @@ public abstract class AbstractFieldNameRSQLVisitor & FieldName final String enumFieldName = enumField.name().toLowerCase(); if (enumField.isMap()) { - return enumFieldName + FieldNameProvider.SUB_ATTRIBUTE_SEPERATOR + "keyName"; + return enumFieldName + FieldNameProvider.SUB_ATTRIBUTE_SEPARATOR + "keyName"; } return enumFieldName; @@ -136,7 +133,7 @@ public abstract class AbstractFieldNameRSQLVisitor & FieldName .filter(enumField -> !enumField.getSubEntityAttributes().isEmpty()).flatMap(enumField -> { final List subEntity = enumField .getSubEntityAttributes().stream().map(fieldName -> enumField.name().toLowerCase() - + FieldNameProvider.SUB_ATTRIBUTE_SEPERATOR + fieldName) + + FieldNameProvider.SUB_ATTRIBUTE_SEPARATOR + fieldName) .collect(Collectors.toList()); return subEntity.stream(); diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/rsql/JpaQueryRsqlVisitor.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/rsql/JpaQueryRsqlVisitor.java index eb9871134..91632d483 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/rsql/JpaQueryRsqlVisitor.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/rsql/JpaQueryRsqlVisitor.java @@ -15,9 +15,9 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.Optional; import java.util.Set; -import java.util.Map.Entry; import java.util.function.BiFunction; import java.util.function.Function; import java.util.stream.Collectors; @@ -179,7 +179,7 @@ public class JpaQueryRsqlVisitor & FieldNameProvider, T> exten */ @SuppressWarnings("unchecked") private Path getFieldPath(final A enumField, final String finalProperty) { - return (Path) getFieldPath(root, getSubAttributesFrom(finalProperty), enumField.isMap(), + return (Path) getFieldPath(root, enumField.getSubAttributes(finalProperty), enumField.isMap(), this::getJoinFieldPath).orElseThrow( () -> createRSQLParameterUnsupportedException("RSQL field path cannot be empty", null)); } @@ -377,7 +377,7 @@ public class JpaQueryRsqlVisitor & FieldNameProvider, T> exten private Predicate getOutPredicate(final List transformedValues, final String finalProperty, final A enumField, final Path fieldPath) { - final String[] fieldNames = getSubAttributesFrom(finalProperty); + final String[] fieldNames = enumField.getSubAttributes(finalProperty); final List outParams = transformedValues.stream().filter(String.class::isInstance) .map(String.class::cast).map(String::toUpperCase).collect(Collectors.toList()); @@ -423,7 +423,7 @@ public class JpaQueryRsqlVisitor & FieldNameProvider, T> exten return null; } - final String[] graph = getSubAttributesFrom(node.getSelector()); + final String[] graph = enumField.getSubAttributes(node.getSelector()); final String keyValue = graph[graph.length - 1]; if (fieldPath instanceof MapJoin) { @@ -469,7 +469,7 @@ public class JpaQueryRsqlVisitor & FieldNameProvider, T> exten } final String sqlValue = toSQL((String) transformedValue); - final String[] fieldNames = getSubAttributesFrom(finalProperty); + final String[] fieldNames = enumField.getSubAttributes(finalProperty); if (isSimpleField(fieldNames, enumField.isMap())) { return toNullOrNotLikePredicate(fieldPath, sqlValue); diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RSQLDistributionSetFieldTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RSQLDistributionSetFieldTest.java index ccf03597b..2dc9712ab 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RSQLDistributionSetFieldTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RSQLDistributionSetFieldTest.java @@ -9,12 +9,14 @@ package org.eclipse.hawkbit.repository.jpa.rsql; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.junit.jupiter.api.Assertions.fail; import java.util.Arrays; import org.eclipse.hawkbit.repository.DistributionSetFields; import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException; +import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException; import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest; import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.DistributionSetTag; @@ -47,13 +49,13 @@ public class RSQLDistributionSetFieldTest extends AbstractJpaIntegrationTest { ds2 = distributionSetManagement.update(entityFactory.distributionSet().update(ds2.getId()).description("DS%")); createDistributionSetMetadata(ds2.getId(), entityFactory.generateDsMetadata("metaKey", "value")); - final DistributionSetTag targetTag = distributionSetTagManagement + final DistributionSetTag distSetTag = distributionSetTagManagement .create(entityFactory.tag().create().name("Tag1")); distributionSetTagManagement.create(entityFactory.tag().create().name("Tag2")); distributionSetTagManagement.create(entityFactory.tag().create().name("Tag3")); distributionSetTagManagement.create(entityFactory.tag().create().name("Tag4")); - distributionSetManagement.assignTag(Arrays.asList(ds.getId(), ds2.getId()), targetTag.getId()); + distributionSetManagement.assignTag(Arrays.asList(ds.getId(), ds2.getId()), distSetTag.getId()); distributionSetManagement .create(entityFactory.distributionSet().create().name("test123").version("noDescription")); @@ -151,12 +153,27 @@ public class RSQLDistributionSetFieldTest extends AbstractJpaIntegrationTest { @Test @Description("Test filter distribution set by metadata") public void testFilterByMetadata() { + createDistributionSetWithMetadata("key.dot", "value.dot"); + assertRSQLQuery(DistributionSetFields.METADATA.name() + ".metaKey==metaValue", 1); assertRSQLQuery(DistributionSetFields.METADATA.name() + ".metaKey==*v*", 2); assertRSQLQuery(DistributionSetFields.METADATA.name() + ".metaKey==noExist*", 0); assertRSQLQuery(DistributionSetFields.METADATA.name() + ".metaKey=in=(metaValue,notexist)", 1); assertRSQLQuery(DistributionSetFields.METADATA.name() + ".metaKey=out=(metaValue,notexist)", 1); assertRSQLQuery(DistributionSetFields.METADATA.name() + ".notExist==metaValue", 0); + assertRSQLQuery(DistributionSetFields.METADATA.name() + ".key.dot==value.dot", 1); + assertRSQLQuery(DistributionSetFields.METADATA.name() + ".key.dot*==value.dot", 0); + assertRSQLQuery(DistributionSetFields.METADATA.name() + ".key.*==value.dot", 0); + assertRSQLQuery(DistributionSetFields.METADATA.name() + ".key.==value.dot", 0); + assertRSQLQuery(DistributionSetFields.METADATA.name() + ".key*==value.dot", 0); + assertRSQLQuery(DistributionSetFields.METADATA.name() + ".*==value.dot", 0); + assertRSQLQuery(DistributionSetFields.METADATA.name() + "..==value.dot", 0); + assertRSQLQueryThrowsException(DistributionSetFields.METADATA.name() + ".==value.dot", + RSQLParameterUnsupportedFieldException.class); + assertRSQLQueryThrowsException(DistributionSetFields.METADATA.name() + "*==value.dot", + RSQLParameterUnsupportedFieldException.class); + assertRSQLQueryThrowsException(DistributionSetFields.METADATA.name() + "==value.dot", + RSQLParameterUnsupportedFieldException.class); } @@ -166,4 +183,19 @@ public class RSQLDistributionSetFieldTest extends AbstractJpaIntegrationTest { assertThat(find).as("Founded entity is should not be null").isNotNull(); assertThat(countAll).as("Founded entity size is wrong").isEqualTo(excpectedEntity); } + + private void assertRSQLQueryThrowsException(final String rsqlParam, + final Class expectedException) { + assertThatExceptionOfType(expectedException) + .isThrownBy(() -> RSQLUtility.validateRsqlFor(rsqlParam, DistributionSetFields.class)); + } + + private DistributionSet createDistributionSetWithMetadata(final String metadataKeyName, + final String metadataValue) { + final DistributionSet distributionSet = testdataFactory.createDistributionSet(); + createDistributionSetMetadata(distributionSet.getId(), + entityFactory.generateDsMetadata(metadataKeyName, metadataValue)); + return distributionSet; + } + } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RSQLTargetFieldTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RSQLTargetFieldTest.java index f9ebbd9f7..4b060f30a 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RSQLTargetFieldTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RSQLTargetFieldTest.java @@ -16,6 +16,7 @@ import java.util.Arrays; import java.util.HashMap; import java.util.Map; +import org.assertj.core.util.Maps; import org.eclipse.hawkbit.repository.TargetFields; import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException; import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest; @@ -148,12 +149,27 @@ public class RSQLTargetFieldTest extends AbstractJpaIntegrationTest { @Test @Description("Test filter target by attribute") public void testFilterByAttribute() { + createTargetWithAttributes("test.dot", "value.dot"); + assertRSQLQuery(TargetFields.ATTRIBUTE.name() + ".revision==1.1", 1); assertRSQLQuery(TargetFields.ATTRIBUTE.name() + ".revision!=1.1", 1); assertRSQLQuery(TargetFields.ATTRIBUTE.name() + ".revision==1*", 2); assertRSQLQuery(TargetFields.ATTRIBUTE.name() + ".revision==noExist*", 0); assertRSQLQuery(TargetFields.ATTRIBUTE.name() + ".revision=in=(1.1,notexist)", 1); assertRSQLQuery(TargetFields.ATTRIBUTE.name() + ".revision=out=(1.1)", 1); + assertRSQLQuery(TargetFields.ATTRIBUTE.name() + ".test.dot==value.dot", 1); + assertRSQLQuery(TargetFields.ATTRIBUTE.name() + ".key.dot*==value.dot", 0); + assertRSQLQuery(TargetFields.ATTRIBUTE.name() + ".key.*==value.dot", 0); + assertRSQLQuery(TargetFields.ATTRIBUTE.name() + ".key.==value.dot", 0); + assertRSQLQuery(TargetFields.ATTRIBUTE.name() + ".key*==value.dot", 0); + assertRSQLQuery(TargetFields.ATTRIBUTE.name() + ".*==value.dot", 0); + assertRSQLQuery(TargetFields.ATTRIBUTE.name() + "..==value.dot", 0); + assertRSQLQueryThrowsException(TargetFields.ATTRIBUTE.name() + ".==value.dot", + RSQLParameterUnsupportedFieldException.class); + assertRSQLQueryThrowsException(TargetFields.ATTRIBUTE.name() + "*==value.dot", + RSQLParameterUnsupportedFieldException.class); + assertRSQLQueryThrowsException(TargetFields.ATTRIBUTE.name() + "==value.dot", + RSQLParameterUnsupportedFieldException.class); } @Test @@ -214,6 +230,8 @@ public class RSQLTargetFieldTest extends AbstractJpaIntegrationTest { @Test @Description("Test filter target by metadata") public void testFilterByMetadata() { + createTargetWithMetadata("key.dot", "value.dot"); + assertRSQLQuery(TargetFields.METADATA.name() + ".metaKey==metaValue", 1); assertRSQLQuery(TargetFields.METADATA.name() + ".metaKey==*v*", 2); assertRSQLQuery(TargetFields.METADATA.name() + ".metaKey==noExist*", 0); @@ -223,6 +241,19 @@ public class RSQLTargetFieldTest extends AbstractJpaIntegrationTest { assertRSQLQuery(TargetFields.METADATA.name() + ".metaKey!=metaValue", 1); assertRSQLQuery(TargetFields.METADATA.name() + ".notExist!=metaValue", 0); assertRSQLQuery(TargetFields.METADATA.name() + ".metaKey!=notExist", 2); + assertRSQLQuery(TargetFields.METADATA.name() + ".key.dot==value.dot", 1); + assertRSQLQuery(TargetFields.METADATA.name() + ".key.dot*==value.dot", 0); + assertRSQLQuery(TargetFields.METADATA.name() + ".key.*==value.dot", 0); + assertRSQLQuery(TargetFields.METADATA.name() + ".key.==value.dot", 0); + assertRSQLQuery(TargetFields.METADATA.name() + ".key*==value.dot", 0); + assertRSQLQuery(TargetFields.METADATA.name() + ".*==value.dot", 0); + assertRSQLQuery(TargetFields.METADATA.name() + "..==value.dot", 0); + assertRSQLQueryThrowsException(TargetFields.METADATA.name() + ".==value.dot", + RSQLParameterUnsupportedFieldException.class); + assertRSQLQueryThrowsException(TargetFields.METADATA.name() + "*==value.dot", + RSQLParameterUnsupportedFieldException.class); + assertRSQLQueryThrowsException(TargetFields.METADATA.name() + "==value.dot", + RSQLParameterUnsupportedFieldException.class); } @Test @@ -259,6 +290,10 @@ public class RSQLTargetFieldTest extends AbstractJpaIntegrationTest { final String rsql5 = "wrongfield == abcd"; assertThatExceptionOfType(RSQLParameterUnsupportedFieldException.class) .isThrownBy(() -> RSQLUtility.validateRsqlFor(rsql5, TargetFields.class)); + + final String rsql6 = "ATTRIBUTE.test.dot == test and ATTRIBUTE.subkey2 == test" + + " and METADATA.test.dot == abcd and METADATA.metavalue2 == asdfg"; + RSQLUtility.validateRsqlFor(rsql6, TargetFields.class); } private void assertRSQLQuery(final String rsqlParam, final long expcetedTargets) { @@ -267,4 +302,24 @@ public class RSQLTargetFieldTest extends AbstractJpaIntegrationTest { assertThat(findTargetPage).isNotNull(); assertThat(countTargetsAll).isEqualTo(expcetedTargets); } + + private void assertRSQLQueryThrowsException(final String rsqlParam, + final Class expectedException) { + assertThatExceptionOfType(expectedException) + .isThrownBy(() -> RSQLUtility.validateRsqlFor(rsqlParam, TargetFields.class)); + } + + private Target createTargetWithMetadata(final String metadataKeyName, final String metadataValue) { + final Target target = testdataFactory.createTarget(); + createTargetMetadata(target.getControllerId(), + entityFactory.generateTargetMetadata(metadataKeyName, metadataValue)); + return target; + } + + private Target createTargetWithAttributes(final String attributeName, final String attributeValue) { + final Target target = testdataFactory.createTarget(); + controllerManagement.updateControllerAttributes(target.getControllerId(), + Maps.newHashMap(attributeName, attributeValue), null); + return target; + } } diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetResourceTest.java b/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetResourceTest.java index fbf87caa9..ace193371 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetResourceTest.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetResourceTest.java @@ -1025,7 +1025,7 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr public void createMetadata() throws Exception { final DistributionSet testDS = testdataFactory.createDistributionSet("one"); - final String knownKey1 = "knownKey1"; + final String knownKey1 = "known.key.1.1"; final String knownKey2 = "knownKey2"; final String knownValue1 = "knownValue1"; diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetResourceTest.java b/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetResourceTest.java index 0bb647053..c2f3d827e 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetResourceTest.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetResourceTest.java @@ -9,8 +9,8 @@ package org.eclipse.hawkbit.mgmt.rest.resource; import static org.assertj.core.api.Assertions.assertThat; -import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.not; import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.hasItem; @@ -1611,8 +1611,8 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest // create target with attributes final String knownTargetId = "targetIdNeedsUpdate"; final Map knownControllerAttrs = new HashMap<>(); - knownControllerAttrs.put("a", "1"); - knownControllerAttrs.put("b", "2"); + knownControllerAttrs.put("a.1", "1"); + knownControllerAttrs.put("b.2", "2"); testdataFactory.createTarget(knownTargetId); controllerManagement.updateControllerAttributes(knownTargetId, knownControllerAttrs, null); assertThat(targetManagement.isControllerAttributesRequested(knownTargetId)).isFalse(); @@ -1721,7 +1721,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest final String knownControllerId = "targetIdWithMetadata"; testdataFactory.createTarget(knownControllerId); - final String knownKey1 = "knownKey1"; + final String knownKey1 = "known.key.1"; final String knownKey2 = "knownKey2"; final String knownValue1 = "knownValue1";