Fix handle invalid controller attributes (#740)
* Move controller attribute validation from DMF to Repository Rational: Constraint validation on key & value of a map is currently not supported by EclipseLink Maven Plugin. Therefore, this check has to be done by hawkBit. The check is required for both APIs (DMF + DDI). * add tests for attribute validation * update tests Signed-off-by: Jeroen Laverman <jeroen.laverman@bosch-si.com> * Review findings Signed-off-by: Jeroen Laverman <jeroen.laverman@bosch-si.com> * * Add custom exception for invalid target attributes * Add integration tests for DDI and DMF Signed-off-by: Jeroen Laverman <jeroen.laverman@bosch-si.com> * * rename exception Signed-off-by: Jeroen Laverman <jeroen.laverman@bosch-si.com> * * rename test steps Signed-off-by: Jeroen Laverman <jeroen.laverman@bosch-si.com> * Fix value size Signed-off-by: Jeroen Laverman <jeroen.laverman@bosch-si.com> * Ensure constraints are validated correctly Signed-off-by: Jeroen Laverman <jeroen.laverman@bosch-si.com> * Introduce review findings Signed-off-by: Jeroen Laverman <jeroen.laverman@bosch-si.com> * fix sonar finding Signed-off-by: Jeroen Laverman <jeroen.laverman@bosch-si.com>
This commit is contained in:
committed by
Dominic Schabel
parent
cab2a6f774
commit
5fe86954b0
@@ -44,6 +44,7 @@ import org.eclipse.hawkbit.repository.event.remote.TargetPollEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.CancelTargetAssignmentEvent;
|
||||
import org.eclipse.hawkbit.repository.exception.CancelActionNotAllowedException;
|
||||
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
|
||||
import org.eclipse.hawkbit.repository.exception.InvalidTargetAttributeException;
|
||||
import org.eclipse.hawkbit.repository.jpa.builder.JpaActionStatusCreate;
|
||||
import org.eclipse.hawkbit.repository.jpa.configuration.Constants;
|
||||
import org.eclipse.hawkbit.repository.jpa.executor.AfterTransactionCommitExecutor;
|
||||
@@ -96,6 +97,9 @@ import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
import static org.eclipse.hawkbit.repository.model.Target.CONTROLLER_ATTRIBUTE_KEY_SIZE;
|
||||
import static org.eclipse.hawkbit.repository.model.Target.CONTROLLER_ATTRIBUTE_VALUE_SIZE;
|
||||
|
||||
/**
|
||||
* JPA based {@link ControllerManagement} implementation.
|
||||
*
|
||||
@@ -657,6 +661,15 @@ public class JpaControllerManagement implements ControllerManagement {
|
||||
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,
|
||||
final UpdateMode mode) {
|
||||
|
||||
/*
|
||||
Constraints on attribute keys & values are not validated by EclipseLink. Hence, they are validated here.
|
||||
*/
|
||||
if (data.entrySet().stream()
|
||||
.anyMatch(e -> !isAttributeEntryValid(e))) {
|
||||
throw new InvalidTargetAttributeException();
|
||||
}
|
||||
|
||||
final JpaTarget target = (JpaTarget) targetRepository.findByControllerId(controllerId)
|
||||
.orElseThrow(() -> new EntityNotFoundException(Target.class, controllerId));
|
||||
|
||||
@@ -689,15 +702,27 @@ public class JpaControllerManagement implements ControllerManagement {
|
||||
return targetRepository.save(target);
|
||||
}
|
||||
|
||||
private static boolean isAttributeEntryValid(final Map.Entry<String, String> e) {
|
||||
return isAttributeKeyValid(e.getKey()) && isAttributeValueValid(e.getValue());
|
||||
}
|
||||
|
||||
private static boolean isAttributeKeyValid(final String key) {
|
||||
return key != null && key.length() <= CONTROLLER_ATTRIBUTE_KEY_SIZE;
|
||||
}
|
||||
|
||||
private static boolean isAttributeValueValid(final String value) {
|
||||
return value == null || value.length() <= CONTROLLER_ATTRIBUTE_VALUE_SIZE;
|
||||
}
|
||||
|
||||
private static void copy(final Map<String, String> src, final Map<String, String> trg) {
|
||||
if (src == null || src.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
src.entrySet().forEach(e -> {
|
||||
if (e.getValue() != null) {
|
||||
trg.put(e.getKey(), e.getValue());
|
||||
src.forEach((key, value) -> {
|
||||
if (value != null) {
|
||||
trg.put(key, value);
|
||||
} else {
|
||||
trg.remove(e.getKey());
|
||||
trg.remove(key);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user