Changed validation method to throw exception/SpServerError

* changed error handling from return value to throw exceptions, to give the user a feedback what was wrong
* added ValidationException to ResponseExceptionHandler, to map the correct REST status codes

Signed-off-by: Nonnenmacher Fabian <fabian.nonnenmacher@bosch-si.com>
This commit is contained in:
Fabian Nonnenmacher
2016-01-28 15:17:12 +01:00
committed by Nonnenmacher Fabian
parent a5a0dc17f6
commit d83286c94a
11 changed files with 206 additions and 90 deletions

View File

@@ -177,6 +177,12 @@ public enum SpServerError {
SP_REPO_ENTITY_READ_ONLY("hawkbit.server.error.entityreadonly",
"The given entity is read only and the change cannot be completed."),
/**
*
*/
SP_CONFIGURATION_VALUE_INVALID("hawkbit.server.error.configValueInvalid",
"The given configuration value is invalid.");
/**
*
*/

View File

@@ -8,10 +8,11 @@
*/
package org.eclipse.hawkbit.tenancy.configuration;
import org.eclipse.hawkbit.tenancy.configuration.validator.BooleanValidator;
import org.eclipse.hawkbit.tenancy.configuration.validator.PollTimeValidator;
import org.eclipse.hawkbit.tenancy.configuration.validator.StringValidator;
import org.eclipse.hawkbit.tenancy.configuration.validator.TenantConfigurationBooleanValidator;
import org.eclipse.hawkbit.tenancy.configuration.validator.TenantConfigurationPollingDurationValidator;
import org.eclipse.hawkbit.tenancy.configuration.validator.TenantConfigurationStringValidator;
import org.eclipse.hawkbit.tenancy.configuration.validator.TenantConfigurationValidator;
import org.eclipse.hawkbit.tenancy.configuration.validator.exceptions.TenantConfigurationValidatorException;
import org.springframework.context.ApplicationContext;
/**
@@ -29,32 +30,32 @@ public enum TenantConfigurationKey {
*/
AUTHENTICATION_MODE_HEADER_ENABLED("authentication.header.enabled",
"hawkbit.server.controller.security.authentication.header.enabled", Boolean.class, Boolean.FALSE.toString(),
BooleanValidator.class),
TenantConfigurationBooleanValidator.class),
/**
*
*/
AUTHENTICATION_MODE_HEADER_AUTHORITY_NAME("authentication.header.authority",
"hawkbit.server.controller.security.authentication.header.authority", Boolean.class,
Boolean.FALSE.toString(), BooleanValidator.class),
Boolean.FALSE.toString(), TenantConfigurationBooleanValidator.class),
/**
* boolean value {@code true} {@code false}.
*/
AUTHENTICATION_MODE_TARGET_SECURITY_TOKEN_ENABLED("authentication.targettoken.enabled",
"hawkbit.server.controller.security.authentication.targettoken.enabled", Boolean.class,
Boolean.FALSE.toString(), BooleanValidator.class),
Boolean.FALSE.toString(), TenantConfigurationBooleanValidator.class),
/**
* boolean value {@code true} {@code false}.
*/
AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_ENABLED("authentication.gatewaytoken.enabled",
"hawkbit.server.controller.security.authentication.gatewaytoken.enabled", Boolean.class,
Boolean.FALSE.toString(), BooleanValidator.class),
Boolean.FALSE.toString(), TenantConfigurationBooleanValidator.class),
/**
* string value which holds the name of the security token key.
*/
AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_NAME("authentication.gatewaytoken.name",
"hawkbit.server.controller.security.authentication.gatewaytoken.name", String.class, null,
StringValidator.class),
TenantConfigurationStringValidator.class),
/**
* string value which holds the actual security-key of the gateway security
@@ -62,19 +63,19 @@ public enum TenantConfigurationKey {
*/
AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_KEY("authentication.gatewaytoken.key",
"hawkbit.server.controller.security.authentication.gatewaytoken.key", String.class, null,
StringValidator.class),
TenantConfigurationStringValidator.class),
/**
* string value which holds the polling time interval in the format HH:mm:ss
*/
POLLING_TIME_INTERVAL("pollingOverdueTime", "hawkbit.controller.pollingOverdueTime", String.class, null,
PollTimeValidator.class),
TenantConfigurationPollingDurationValidator.class),
/**
* string value which holds the polling time interval in the format HH:mm:ss
*/
POLLING_OVERDUE_TIME_INTERVAL("pollingTime", "hawkbit.controller.pollingTime", String.class, null,
PollTimeValidator.class);
TenantConfigurationPollingDurationValidator.class);
private final String keyName;
private final String defaultKeyName;
@@ -127,11 +128,26 @@ public enum TenantConfigurationKey {
return dataType;
}
public boolean validate(final ApplicationContext context, final Object value) {
/**
* validates if a object matches the allowed data format of the
* corresponding key
*
* @param context
* application context
* @param value
* which will be validated
* @throws TenantConfigurationValidatorException
* is thrown when object is invalid.
*/
public void validate(final ApplicationContext context, final Object value)
throws TenantConfigurationValidatorException {
final TenantConfigurationValidator createBean = context.getAutowireCapableBeanFactory().createBean(validator);
final boolean isValid = createBean.validate(value);
context.getAutowireCapableBeanFactory().destroyBean(createBean);
return isValid;
try {
createBean.validate(value);
} catch (final TenantConfigurationValidatorException ex) {
throw ex;
} finally {
context.getAutowireCapableBeanFactory().destroyBean(createBean);
}
}
}

View File

@@ -1,13 +0,0 @@
package org.eclipse.hawkbit.tenancy.configuration.validator;
public class BooleanValidator implements TenantConfigurationValidator {
@Override
public boolean validate(final Object tenantConfigurationValue) {
if (tenantConfigurationValue instanceof Boolean) {
return true;
}
return false;
}
}

View File

@@ -1,47 +0,0 @@
package org.eclipse.hawkbit.tenancy.configuration.validator;
import java.time.Duration;
import java.time.format.DateTimeParseException;
import org.eclipse.hawkbit.ControllerPollProperties;
import org.eclipse.hawkbit.tenancy.configuration.DurationHelper;
import org.springframework.beans.factory.annotation.Autowired;
public class PollTimeValidator implements TenantConfigurationValidator {
// private final ControllerPollProperties properties;
private final DurationHelper durationHelper = new DurationHelper();
private final Duration minDuration;
private final Duration maxDuration;
@Autowired
public PollTimeValidator(final ControllerPollProperties properties) {
// this.properties = properties;
minDuration = durationHelper.formattedStringToDuration(properties.getMinPollingTime());
maxDuration = durationHelper.formattedStringToDuration(properties.getMaxPollingTime());
}
@Override
public boolean validate(final Object tenantConfigurationObject) {
if (!(tenantConfigurationObject instanceof String)) {
return false;
}
final String tenantConfigurationString = (String) tenantConfigurationObject;
try {
final Duration tenantConfigurationValue = durationHelper
.formattedStringToDuration(tenantConfigurationString);
return durationHelper.durationRangeValidator(minDuration, maxDuration)
.isWithinRange(tenantConfigurationValue);
} catch (final DateTimeParseException ex) {
return false;
}
}
}

View File

@@ -1,13 +0,0 @@
package org.eclipse.hawkbit.tenancy.configuration.validator;
public class StringValidator implements TenantConfigurationValidator {
@Override
public boolean validate(final Object tenantConfigurationValue) {
if (tenantConfigurationValue instanceof String) {
return true;
}
return false;
}
}

View File

@@ -0,0 +1,18 @@
package org.eclipse.hawkbit.tenancy.configuration.validator;
import org.eclipse.hawkbit.tenancy.configuration.validator.exceptions.TenantConfigurationValidatorException;
/**
* specific tenant configuration validator, which validates that the given value is a booleans.
*/
public class TenantConfigurationBooleanValidator implements TenantConfigurationValidator {
@Override
public void validate(final Object tenantConfigurationValue) {
if (tenantConfigurationValue instanceof Boolean) {
return;
}
throw new TenantConfigurationValidatorException("The given configuration value is expected as a boolean.");
}
}

View File

@@ -0,0 +1,62 @@
package org.eclipse.hawkbit.tenancy.configuration.validator;
import java.time.Duration;
import java.time.format.DateTimeParseException;
import org.eclipse.hawkbit.ControllerPollProperties;
import org.eclipse.hawkbit.tenancy.configuration.DurationHelper;
import org.eclipse.hawkbit.tenancy.configuration.validator.exceptions.TenantConfigurationValidatorException;
import org.springframework.beans.factory.annotation.Autowired;
/**
* specific tenant configuration validator, which validates that the given value
* is a String in the correct duration format..
*/
public class TenantConfigurationPollingDurationValidator implements TenantConfigurationValidator {
// private final ControllerPollProperties properties;
private final DurationHelper durationHelper = new DurationHelper();
private final Duration minDuration;
private final Duration maxDuration;
/**
* @param properties
* property accessor for poll configuration
*/
@Autowired
public TenantConfigurationPollingDurationValidator(final ControllerPollProperties properties) {
// this.properties = properties;
minDuration = durationHelper.formattedStringToDuration(properties.getMinPollingTime());
maxDuration = durationHelper.formattedStringToDuration(properties.getMaxPollingTime());
}
@Override
public void validate(final Object tenantConfigurationObject) {
if (!(tenantConfigurationObject instanceof String)) {
throw new TenantConfigurationValidatorException("The given configuration value is expected as a string.");
}
final String tenantConfigurationString = (String) tenantConfigurationObject;
final Duration tenantConfigurationValue;
try {
tenantConfigurationValue = durationHelper.formattedStringToDuration(tenantConfigurationString);
} catch (final DateTimeParseException ex) {
throw new TenantConfigurationValidatorException(
String.format("The given configuration value is expected as a string in the format %s.",
DurationHelper.DURATION_FORMAT));
}
if (!durationHelper.durationRangeValidator(minDuration, maxDuration).isWithinRange(tenantConfigurationValue)) {
throw new TenantConfigurationValidatorException(
String.format("The given configuration value is not in the allowed range from %s to %s.",
durationHelper.durationToFormattedString(minDuration),
durationHelper.durationToFormattedString(maxDuration)));
}
}
}

View File

@@ -0,0 +1,17 @@
package org.eclipse.hawkbit.tenancy.configuration.validator;
import org.eclipse.hawkbit.tenancy.configuration.validator.exceptions.TenantConfigurationValidatorException;
/**
* specific tenant configuration validator, which validates Strings.
*/
public class TenantConfigurationStringValidator implements TenantConfigurationValidator {
@Override
public void validate(final Object tenantConfigurationValue) {
if (tenantConfigurationValue instanceof String) {
return;
}
throw new TenantConfigurationValidatorException("The given configuration value is expected as a String.");
}
}

View File

@@ -1,6 +1,20 @@
package org.eclipse.hawkbit.tenancy.configuration.validator;
import org.eclipse.hawkbit.tenancy.configuration.validator.exceptions.TenantConfigurationValidatorException;
/**
* base interface for clases which can validate tenant configuration values.
*
*/
public interface TenantConfigurationValidator {
boolean validate(Object tenantConfigurationValue);
/**
* validates the tenant configuration value
*
* @param tenantConfigurationValue
* value which will be validated.
* @throws TenantConfigurationValidatorException
* is thrown, when parameter is invalid.
*/
void validate(Object tenantConfigurationValue) throws TenantConfigurationValidatorException;
}

View File

@@ -0,0 +1,55 @@
package org.eclipse.hawkbit.tenancy.configuration.validator.exceptions;
import org.eclipse.hawkbit.exception.SpServerError;
import org.eclipse.hawkbit.exception.SpServerRtException;
/**
* Exception which is thrown, when the validation of the configuration value has
* not been successful.
*
*/
public class TenantConfigurationValidatorException extends SpServerRtException {
private static final long serialVersionUID = 1L;
private static final SpServerError THIS_ERROR = SpServerError.SP_CONFIGURATION_VALUE_INVALID;
/**
* Default constructor.
*/
public TenantConfigurationValidatorException() {
super(THIS_ERROR);
}
/**
* Parameterized constructor.
*
* @param cause
* of the exception
*/
public TenantConfigurationValidatorException(final Throwable cause) {
super(THIS_ERROR, cause);
}
/**
* Parameterized constructor.
*
* @param message
* of the exception
* @param cause
* of the exception
*/
public TenantConfigurationValidatorException(final String message, final Throwable cause) {
super(message, THIS_ERROR, cause);
}
/**
* Parameterized constructor.
*
* @param message
* of the exception
*/
public TenantConfigurationValidatorException(final String message) {
super(message, THIS_ERROR);
}
}

View File

@@ -65,6 +65,7 @@ public class ResponseExceptionHandler {
ERROR_TO_HTTP_STATUS.put(SpServerError.SP_REPO_TENANT_NOT_EXISTS, HttpStatus.BAD_REQUEST);
ERROR_TO_HTTP_STATUS.put(SpServerError.SP_ENTITY_LOCKED, HttpStatus.LOCKED);
ERROR_TO_HTTP_STATUS.put(SpServerError.SP_ROLLOUT_ILLEGAL_STATE, HttpStatus.BAD_REQUEST);
ERROR_TO_HTTP_STATUS.put(SpServerError.SP_CONFIGURATION_VALUE_INVALID, HttpStatus.BAD_REQUEST);
}
private static HttpStatus getStatusOrDefault(final SpServerError error) {