Feature Reset Target Attributes (#664)
* Enhance DDI putConfigData REST entry point with update mode Signed-off-by: stefbehl <stefan.behl@bosch-si.com> * ControllerManagement unit tests for new target attribute update modes Signed-off-by: stefbehl <stefan.behl@bosch-si.com> * Added DdiRootControllerRestApi test for new update mode Signed-off-by: stefbehl <stefan.behl@bosch-si.com> * Enhance DMF UPDATE_ATTRIBUTES message with update mode Signed-off-by: stefbehl <stefan.behl@bosch-si.com> * Enhance DMF integration tests Signed-off-by: stefbehl <stefan.behl@bosch-si.com> * Enhance DMF integration tests Signed-off-by: stefbehl <stefan.behl@bosch-si.com> * Fix DMF integration tests * Fix failing tests Signed-off-by: stefbehl <stefan.behl@bosch-si.com> * Fix failing tests Signed-off-by: stefbehl <stefan.behl@bosch-si.com> * Fix Sonar findings Signed-off-by: stefbehl <stefan.behl@bosch-si.com> * Javadoc improvements Signed-off-by: stefbehl <stefan.behl@bosch-si.com> * Fix codacy findings Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com> * Fix PR review findings Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com> * Fix PR review findings Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com> * Fix PR review findings Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com> * Fix PR review findings Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com> * Fix PR review findings Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com> * Fix PR review findings Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com> * Fix PR review findings Signed-off-by: Stefan Behl <stefan.behl@bosch-si.com>
This commit is contained in:
committed by
Kai Zimmermann
parent
e700acc312
commit
607cf92a9e
@@ -38,6 +38,7 @@ import org.eclipse.hawkbit.repository.QuotaManagement;
|
||||
import org.eclipse.hawkbit.repository.RepositoryConstants;
|
||||
import org.eclipse.hawkbit.repository.RepositoryProperties;
|
||||
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
|
||||
import org.eclipse.hawkbit.repository.UpdateMode;
|
||||
import org.eclipse.hawkbit.repository.builder.ActionStatusCreate;
|
||||
import org.eclipse.hawkbit.repository.event.remote.TargetPollEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.CancelTargetAssignmentEvent;
|
||||
@@ -666,18 +667,41 @@ public class JpaControllerManagement implements ControllerManagement {
|
||||
@Transactional
|
||||
@Retryable(include = {
|
||||
ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY))
|
||||
public Target updateControllerAttributes(final String controllerId, final Map<String, String> data) {
|
||||
public Target updateControllerAttributes(final String controllerId, final Map<String, String> data,
|
||||
final UpdateMode mode) {
|
||||
final JpaTarget target = (JpaTarget) targetRepository.findByControllerId(controllerId)
|
||||
.orElseThrow(() -> new EntityNotFoundException(Target.class, controllerId));
|
||||
|
||||
target.getControllerAttributes().putAll(data);
|
||||
// get the modifiable attribute map
|
||||
final Map<String, String> controllerAttributes = target.getControllerAttributes();
|
||||
|
||||
if (target.getControllerAttributes().size() > quotaManagement.getMaxAttributeEntriesPerTarget()) {
|
||||
throw new QuotaExceededException("Controller attribues", target.getControllerAttributes().size(),
|
||||
quotaManagement.getMaxAttributeEntriesPerTarget());
|
||||
final UpdateMode updateMode = mode != null ? mode : UpdateMode.MERGE;
|
||||
switch (updateMode) {
|
||||
case REMOVE:
|
||||
// remove the addressed attributes
|
||||
data.keySet().forEach(controllerAttributes::remove);
|
||||
break;
|
||||
case REPLACE:
|
||||
// clear the attributes before adding the new attributes
|
||||
controllerAttributes.clear();
|
||||
controllerAttributes.putAll(data);
|
||||
target.setRequestControllerAttributes(false);
|
||||
break;
|
||||
case MERGE:
|
||||
// just merge the attributes in
|
||||
controllerAttributes.putAll(data);
|
||||
target.setRequestControllerAttributes(false);
|
||||
break;
|
||||
default:
|
||||
// unknown update mode
|
||||
throw new IllegalStateException("The update mode " + updateMode + " is not supported.");
|
||||
}
|
||||
|
||||
target.setRequestControllerAttributes(false);
|
||||
final int attributeCount = controllerAttributes.size();
|
||||
if (attributeCount > quotaManagement.getMaxAttributeEntriesPerTarget()) {
|
||||
throw new QuotaExceededException("Controller attributes", attributeCount,
|
||||
quotaManagement.getMaxAttributeEntriesPerTarget());
|
||||
}
|
||||
|
||||
return targetRepository.save(target);
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ import static org.junit.Assert.fail;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -24,6 +25,7 @@ import javax.validation.ConstraintViolationException;
|
||||
|
||||
import org.apache.commons.lang3.RandomUtils;
|
||||
import org.eclipse.hawkbit.repository.RepositoryProperties;
|
||||
import org.eclipse.hawkbit.repository.UpdateMode;
|
||||
import org.eclipse.hawkbit.repository.event.remote.TargetAssignDistributionSetEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.TargetPollEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.ActionCreatedEvent;
|
||||
@@ -121,8 +123,8 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
||||
|
||||
verifyThrownExceptionBy(() -> controllerManagement.registerRetrieved(NOT_EXIST_IDL, "test message"), "Action");
|
||||
|
||||
verifyThrownExceptionBy(() -> controllerManagement.updateControllerAttributes(NOT_EXIST_ID, Maps.newHashMap()),
|
||||
"Target");
|
||||
verifyThrownExceptionBy(
|
||||
() -> controllerManagement.updateControllerAttributes(NOT_EXIST_ID, Maps.newHashMap(), null), "Target");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -658,7 +660,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
||||
private void addAttributeAndVerify(final String controllerId) {
|
||||
final Map<String, String> testData = Maps.newHashMapWithExpectedSize(1);
|
||||
testData.put("test1", "testdata1");
|
||||
controllerManagement.updateControllerAttributes(controllerId, testData);
|
||||
controllerManagement.updateControllerAttributes(controllerId, testData, null);
|
||||
|
||||
assertThat(targetManagement.getControllerAttributes(controllerId)).as("Controller Attributes are wrong")
|
||||
.isEqualTo(testData);
|
||||
@@ -668,7 +670,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
||||
private void addSecondAttributeAndVerify(final String controllerId) {
|
||||
final Map<String, String> testData = Maps.newHashMapWithExpectedSize(2);
|
||||
testData.put("test2", "testdata20");
|
||||
controllerManagement.updateControllerAttributes(controllerId, testData);
|
||||
controllerManagement.updateControllerAttributes(controllerId, testData, null);
|
||||
|
||||
testData.put("test1", "testdata1");
|
||||
assertThat(targetManagement.getControllerAttributes(controllerId)).as("Controller Attributes are wrong")
|
||||
@@ -680,13 +682,111 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
||||
final Map<String, String> testData = Maps.newHashMapWithExpectedSize(2);
|
||||
testData.put("test1", "testdata12");
|
||||
|
||||
controllerManagement.updateControllerAttributes(controllerId, testData);
|
||||
controllerManagement.updateControllerAttributes(controllerId, testData, null);
|
||||
|
||||
testData.put("test2", "testdata20");
|
||||
assertThat(targetManagement.getControllerAttributes(controllerId)).as("Controller Attributes are wrong")
|
||||
.isEqualTo(testData);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Ensures that target attributes can be updated using different update modes.")
|
||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||
@Expect(type = TargetUpdatedEvent.class, count = 4) })
|
||||
public void updateTargetAttributesWithDifferentUpdateModes() {
|
||||
|
||||
final String controllerId = "testCtrl";
|
||||
testdataFactory.createTarget(controllerId);
|
||||
|
||||
// no update mode
|
||||
updateTargetAttributesWithoutUpdateMode(controllerId);
|
||||
|
||||
// update mode REPLACE
|
||||
updateTargetAttributesWithUpdateModeReplace(controllerId);
|
||||
|
||||
// update mode MERGE
|
||||
updateTargetAttributesWithUpdateModeMerge(controllerId);
|
||||
|
||||
// update mode REMOVE
|
||||
updateTargetAttributesWithUpdateModeRemove(controllerId);
|
||||
|
||||
}
|
||||
|
||||
@Step
|
||||
private void updateTargetAttributesWithUpdateModeRemove(final String controllerId) {
|
||||
|
||||
final int previousSize = targetManagement.getControllerAttributes(controllerId).size();
|
||||
|
||||
// update the attributes using update mode REMOVE
|
||||
final Map<String, String> removeAttributes = new HashMap<>();
|
||||
removeAttributes.put("k1", "foo");
|
||||
removeAttributes.put("k3", "bar");
|
||||
controllerManagement.updateControllerAttributes(controllerId, removeAttributes, UpdateMode.REMOVE);
|
||||
|
||||
// verify attribute removal
|
||||
final Map<String, String> updatedAttributes = targetManagement.getControllerAttributes(controllerId);
|
||||
assertThat(updatedAttributes.size()).isEqualTo(previousSize - 2);
|
||||
assertThat(updatedAttributes).doesNotContainKeys("k1", "k3");
|
||||
|
||||
}
|
||||
|
||||
@Step
|
||||
private void updateTargetAttributesWithUpdateModeMerge(final String controllerId) {
|
||||
// get the current attributes
|
||||
final HashMap<String, String> attributes = new HashMap<>(
|
||||
targetManagement.getControllerAttributes(controllerId));
|
||||
|
||||
// update the attributes using update mode MERGE
|
||||
final Map<String, String> mergeAttributes = new HashMap<>();
|
||||
mergeAttributes.put("k1", "v1_modified_again");
|
||||
mergeAttributes.put("k4", "v4");
|
||||
controllerManagement.updateControllerAttributes(controllerId, mergeAttributes, UpdateMode.MERGE);
|
||||
|
||||
// verify attribute merge
|
||||
final Map<String, String> updatedAttributes = targetManagement.getControllerAttributes(controllerId);
|
||||
assertThat(updatedAttributes.size()).isEqualTo(4);
|
||||
assertThat(updatedAttributes).containsAllEntriesOf(mergeAttributes);
|
||||
assertThat(updatedAttributes.get("k1")).isEqualTo("v1_modified_again");
|
||||
attributes.keySet().forEach(assertThat(updatedAttributes)::containsKey);
|
||||
}
|
||||
|
||||
@Step
|
||||
private void updateTargetAttributesWithUpdateModeReplace(final String controllerId) {
|
||||
|
||||
// get the current attributes
|
||||
final HashMap<String, String> attributes = new HashMap<>(
|
||||
targetManagement.getControllerAttributes(controllerId));
|
||||
|
||||
// update the attributes using update mode REPLACE
|
||||
final Map<String, String> replacementAttributes = new HashMap<>();
|
||||
replacementAttributes.put("k1", "v1_modified");
|
||||
replacementAttributes.put("k2", "v2");
|
||||
replacementAttributes.put("k3", "v3");
|
||||
controllerManagement.updateControllerAttributes(controllerId, replacementAttributes, UpdateMode.REPLACE);
|
||||
|
||||
// verify attribute replacement
|
||||
final Map<String, String> updatedAttributes = targetManagement.getControllerAttributes(controllerId);
|
||||
assertThat(updatedAttributes.size()).isEqualTo(replacementAttributes.size());
|
||||
assertThat(updatedAttributes).containsAllEntriesOf(replacementAttributes);
|
||||
assertThat(updatedAttributes.get("k1")).isEqualTo("v1_modified");
|
||||
attributes.entrySet().forEach(assertThat(updatedAttributes)::doesNotContain);
|
||||
}
|
||||
|
||||
@Step
|
||||
private void updateTargetAttributesWithoutUpdateMode(final String controllerId) {
|
||||
|
||||
// set the initial attributes
|
||||
final Map<String, String> attributes = new HashMap<>();
|
||||
attributes.put("k0", "v0");
|
||||
attributes.put("k1", "v1");
|
||||
controllerManagement.updateControllerAttributes(controllerId, attributes, null);
|
||||
|
||||
// verify initial attributes
|
||||
final Map<String, String> updatedAttributes = targetManagement.getControllerAttributes(controllerId);
|
||||
assertThat(updatedAttributes.size()).isEqualTo(attributes.size());
|
||||
assertThat(updatedAttributes).containsAllEntriesOf(attributes);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Ensures that target attribute update fails if quota hits.")
|
||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||
@@ -730,7 +830,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
|
||||
for (int i = 0; i < allowedAttributes; i++) {
|
||||
testData.put(keyPrefix + i, valuePrefix);
|
||||
}
|
||||
controllerManagement.updateControllerAttributes(controllerId, testData);
|
||||
controllerManagement.updateControllerAttributes(controllerId, testData, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -418,7 +418,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
|
||||
testData.put("test1", "testdata1");
|
||||
|
||||
targetManagement.create(entityFactory.target().create().controllerId(controllerId));
|
||||
final Target target = controllerManagement.updateControllerAttributes(controllerId, testData);
|
||||
final Target target = controllerManagement.updateControllerAttributes(controllerId, testData, null);
|
||||
|
||||
assertThat(targetManagement.getControllerAttributes(controllerId)).as("Controller Attributes are wrong")
|
||||
.isEqualTo(testData);
|
||||
|
||||
@@ -47,14 +47,14 @@ public class RSQLTargetFieldTest extends AbstractJpaIntegrationTest {
|
||||
target = targetManagement.create(entityFactory.target().create().controllerId("targetId123")
|
||||
.name("targetName123").description("targetDesc123"));
|
||||
attributes.put("revision", "1.1");
|
||||
target = controllerManagement.updateControllerAttributes(target.getControllerId(), attributes);
|
||||
target = controllerManagement.updateControllerAttributes(target.getControllerId(), attributes, null);
|
||||
target = controllerManagement.findOrRegisterTargetIfItDoesNotexist(target.getControllerId(), LOCALHOST);
|
||||
|
||||
target2 = targetManagement
|
||||
.create(entityFactory.target().create().controllerId("targetId1234").description("targetId1234"));
|
||||
attributes.put("revision", "1.2");
|
||||
Thread.sleep(1);
|
||||
target2 = controllerManagement.updateControllerAttributes(target2.getControllerId(), attributes);
|
||||
target2 = controllerManagement.updateControllerAttributes(target2.getControllerId(), attributes, null);
|
||||
target2 = controllerManagement.findOrRegisterTargetIfItDoesNotexist(target2.getControllerId(), LOCALHOST);
|
||||
|
||||
final Target target3 = testdataFactory.createTarget("targetId1235");
|
||||
|
||||
Reference in New Issue
Block a user