diff options
author | liamfallon <liam.fallon@ericsson.com> | 2018-07-30 10:22:27 +0100 |
---|---|---|
committer | liamfallon <liam.fallon@ericsson.com> | 2018-07-31 16:06:47 +0100 |
commit | 73ba8039930ba56f6a64a7acc4126dc50b77070d (patch) | |
tree | bb46330718aa99e9753a69715c0ea54e990aca4d /common-parameters/src/main/java | |
parent | c36939ee0e648f4ac28b9cdc538991ced0c603bd (diff) |
Improve validation, add hierarchical validation
Parameter validaiton updated to generically support nested groups of
parameters, and nested maps of parameters.
Unit test showing JSON parameter input added.
Unit test showing YAML parameter inout added.
Test parameter group classes moved into subdirectory
This allows parameters to be unmarshaled seamlessly from JSON and YAML
files.
Change-Id: I768e11f31ee7f62299c4d5d95ab68a005d1aff16
Issue-ID: POLICY-922
Signed-off-by: liamfallon <liam.fallon@ericsson.com>
Diffstat (limited to 'common-parameters/src/main/java')
10 files changed, 811 insertions, 84 deletions
diff --git a/common-parameters/src/main/java/org/onap/policy/common/parameters/GroupMapValidationResult.java b/common-parameters/src/main/java/org/onap/policy/common/parameters/GroupMapValidationResult.java new file mode 100644 index 00000000..09cdc1de --- /dev/null +++ b/common-parameters/src/main/java/org/onap/policy/common/parameters/GroupMapValidationResult.java @@ -0,0 +1,163 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2018 Ericsson. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.parameters; + +import java.lang.reflect.Field; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Map.Entry; + +/** + * This class holds the result of the validation of a map of parameter groups. + */ +public class GroupMapValidationResult implements ValidationResult { + // The name of the parameter group map + final String mapParameterName; + + // Validation status for the entire parameter class + private ValidationStatus status = ValidationStatus.CLEAN; + private String message = ParameterConstants.PARAMETER_GROUP_MAP_HAS_STATUS_MESSAGE + status.toString(); + + // Validation results for each parameter in the group + private final Map<String, ValidationResult> validationResultMap = new LinkedHashMap<>(); + + /** + * Constructor, create the group map validation result. + * + * @param field the map parameter field + * @param mapObject the value of the map parameter field + */ + protected GroupMapValidationResult(final Field field, final Object mapObject) { + this.mapParameterName = field.getName(); + + // Cast the map object to a map of parameter groups keyed by string, we can't type check maps + // due to restrictions on generics so we have to check each entry key is a string and each entry + // value is a parameter group + @SuppressWarnings("unchecked") + Map<String, ParameterGroup> parameterGroupMap = (Map<String, ParameterGroup>) mapObject; + + // Add a validation result per map entry + for (Entry<String, ParameterGroup> parameterGroupMapEntry : parameterGroupMap.entrySet()) { + // Create a validation status entry for the map + validationResultMap.put(parameterGroupMapEntry.getKey(), + new GroupValidationResult(parameterGroupMapEntry.getValue())); + } + } + + /** + * Gets the name of the parameter being validated. + * + * @return the name + */ + @Override + public String getName() { + return mapParameterName; + } + + /** + * Gets the status of validation. + * + * @return the status + */ + @Override + public ValidationStatus getStatus() { + return status; + } + + /** + * Set the validation result on on a parameter group. + * + * @param status The validation status the field is receiving + * @param message The validation message explaining the validation status + */ + @Override + public void setResult(ValidationStatus status, String message) { + setResult(status); + this.message = message; + } + + /** + * Set the validation result on on a parameter group. + * + * @param status The validation status the field is receiving + */ + public void setResult(final ValidationStatus status) { + // We record the most serious validation status, assuming the status enum ordinals + // increase in order of severity + if (this.status.ordinal() < status.ordinal()) { + this.status = status; + this.message = ParameterConstants.PARAMETER_GROUP_HAS_STATUS_MESSAGE + status.toString(); + } + } + + /** + * Set the validation result on a parameter map entry. + * + * @param entryName The name of the parameter map entry + * @param mapEntryValidationResult The validation result for the entry + */ + public void setResult(String entryName, ValidationResult mapEntryValidationResult) { + ValidationResult validationResult = validationResultMap.get(entryName); + if (validationResult == null) { + throw new ParameterRuntimeException("no entry with name \"" + entryName + "\" exists"); + } + + // Set the status of the parameter group and replace the field result + validationResultMap.put(entryName, mapEntryValidationResult); + this.setResult(status); + } + + /** + * Gets the validation result. + * + * @param initialIndentation the indentation to use on the main result output + * @param subIndentation the indentation to use on sub parts of the result output + * @param showClean output information on clean fields + * @return the result + */ + @Override + public String getResult(final String initialIndentation, final String subIndentation, final boolean showClean) { + if (status == ValidationStatus.CLEAN && !showClean) { + return null; + } + + StringBuilder validationResultBuilder = new StringBuilder(); + + validationResultBuilder.append(initialIndentation); + validationResultBuilder.append("parameter group map \""); + validationResultBuilder.append(mapParameterName); + validationResultBuilder.append("\" "); + validationResultBuilder.append(status); + validationResultBuilder.append(", "); + validationResultBuilder.append(message); + validationResultBuilder.append('\n'); + + for (ValidationResult fieldResult : validationResultMap.values()) { + String fieldResultMessage = fieldResult.getResult(initialIndentation + subIndentation, subIndentation, + showClean); + if (fieldResultMessage != null) { + validationResultBuilder.append(fieldResultMessage); + } + } + + return validationResultBuilder.toString(); + } +}
\ No newline at end of file diff --git a/common-parameters/src/main/java/org/onap/policy/common/parameters/GroupValidationResult.java b/common-parameters/src/main/java/org/onap/policy/common/parameters/GroupValidationResult.java new file mode 100644 index 00000000..91c3d145 --- /dev/null +++ b/common-parameters/src/main/java/org/onap/policy/common/parameters/GroupValidationResult.java @@ -0,0 +1,324 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2018 Ericsson. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.parameters; + +import java.lang.reflect.Field; +import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Map.Entry; + +/** + * This class holds the result of the validation of a parameter group. + */ +public class GroupValidationResult implements ValidationResult { + // The parameter group which the validation result applies + private final ParameterGroup parameterGroup; + + // Validation status for the entire parameter class + private ValidationStatus status = ValidationStatus.CLEAN; + private String message = ParameterConstants.PARAMETER_GROUP_HAS_STATUS_MESSAGE + status.toString(); + + // Validation results for each parameter in the group + private final Map<String, ValidationResult> validationResultMap = new LinkedHashMap<>(); + + /** + * Constructor, create the field validation result with default arguments. + * + * @param parameterGroup the parameter group being validated + */ + public GroupValidationResult(final ParameterGroup parameterGroup) { + this.parameterGroup = parameterGroup; + + // Add a validation result per field + for (Field field : parameterGroup.getClass().getDeclaredFields()) { + // Exclude system fields + if (field.getName().startsWith("$") || field.getName().startsWith("_")) { + continue; + } + + // Make the field accessible + boolean savedAccessibilityValue = field.isAccessible(); + field.setAccessible(true); + + try { + // Set the validation result + validationResultMap.put(field.getName(), getValidationResult(field, parameterGroup)); + } catch (IllegalArgumentException | IllegalAccessException e) { + throw new ParameterRuntimeException("could not get value of parameter \"" + field.getName() + "\"", e); + } finally { + field.setAccessible(savedAccessibilityValue); + } + } + } + + /** + * Construct a validation result for a field + * + * @param field The parameter field + * @param ParameterGroup The parameter group containing the field + * @return the validation result + * @throws IllegalAccessException on accessing private fields + */ + private ValidationResult getValidationResult(final Field field, final ParameterGroup parameterGroup) + throws IllegalAccessException { + final String fieldName = field.getName(); + final Class<?> fieldType = field.getType(); + final Object fieldObject = field.get(parameterGroup); + + // Nested parameter groups are allowed + if (ParameterGroup.class.isAssignableFrom(fieldType)) { + return new GroupValidationResult((ParameterGroup) field.get(parameterGroup)); + } + + // Nested maps of parameter groups are allowed + if (Map.class.isAssignableFrom(field.getType())) { + checkMapIsParameterGroupMap(fieldName, fieldObject); + return new GroupMapValidationResult(field, fieldObject); + } + + // Collections of parameter groups are not allowed + if (Collection.class.isAssignableFrom(field.getType())) { + checkCollection4ParameterGroups(fieldName, fieldObject); + return new ParameterValidationResult(field, fieldObject); + } + + // It's a regular parameter + return new ParameterValidationResult(field, fieldObject); + } + + /** + * Check if this field is a map of parameter groups indexed by string keys. + * + * @param fieldName the name of the collection field. + * @param mapObject the map object to check + */ + private void checkMapIsParameterGroupMap(String fieldName, Object mapObject) { + if (mapObject == null) { + throw new ParameterRuntimeException("map parameter \"" + fieldName + "\" is null"); + } + + Map<?, ?> incomingMap = (Map<?, ?>) mapObject; + + for (Entry<?, ?> mapEntry : incomingMap.entrySet()) { + // Check the key is a string + if (!String.class.isAssignableFrom(mapEntry.getKey().getClass())) { + throw new ParameterRuntimeException("map entry is not a parameter group keyed by a string, key \"" + + mapEntry.getKey() + "\" in map \"" + fieldName + "\" is not a string"); + } + + // Check the value is a parameter group + if (!ParameterGroup.class.isAssignableFrom(mapEntry.getValue().getClass())) { + throw new ParameterRuntimeException("map entry is not a parameter group keyed by a string, value \"" + + mapEntry.getValue() + "\" in map \"" + fieldName + "\" is not a parameter group"); + } + } + } + + /** + * Check if this field contains parameter groups. + * + * @param fieldName the name of the collection field. + * @param collectionObject the collection object to check + */ + private void checkCollection4ParameterGroups(final String fieldName, final Object collectionObject) { + if (collectionObject == null) { + throw new ParameterRuntimeException("collection parameter \"" + fieldName + "\" is null"); + } + + Collection<?> collection2Check = (Collection<?>) collectionObject; + + for (Object collectionMember : collection2Check) { + if (ParameterGroup.class.isAssignableFrom(collectionMember.getClass())) { + throw new ParameterRuntimeException("collection parameter \"" + fieldName + "\" is illegal," + + " parameter groups are not allowed as collection members"); + } + } + } + + /** + * Gets the parameter group for this validation result. + * + * @return the parameter class + */ + public ParameterGroup getParameterGroup() { + return parameterGroup; + } + + /** + * Gets the name of the parameter group being validated. + * + * @return the name + */ + @Override + public String getName() { + return parameterGroup.getName(); + } + + /** + * Gets the status of validation. + * + * @return the status + */ + @Override + public ValidationStatus getStatus() { + return status; + } + + /** + * Set the validation result on on a parameter group. + * + * @param status The validation status the parameter group is receiving + * @param message The validation message explaining the validation status + */ + @Override + public void setResult(ValidationStatus status, String message) { + setResult(status); + this.message = message; + } + + /** + * Set the validation result on on a parameter group. + * + * On a sequence of calls, the most serious validation status is recorded, assuming the status enum ordinal increase + * in order of severity + * + * @param status The validation status the parameter group is receiving + */ + public void setResult(final ValidationStatus status) { + // + if (this.status.ordinal() < status.ordinal()) { + this.status = status; + this.message = ParameterConstants.PARAMETER_GROUP_HAS_STATUS_MESSAGE + status.toString(); + } + } + + /** + * Set the validation result on a parameter group. + * + * @param parameterGroupName The name of the parameter group + * @param status The validation status the field is receiving + * @param message The validation message explaining the validation status + */ + public void setResult(final String parameterGroupName, final ValidationStatus status, final String message) { + ParameterValidationResult parameterValidationResult; + try { + parameterValidationResult = (ParameterValidationResult) validationResultMap.get(parameterGroupName); + } catch (ClassCastException e) { + throw new ParameterRuntimeException("parameter not a regular parameter: " + parameterGroupName, e); + } + + if (parameterValidationResult == null) { + throw new ParameterRuntimeException( + "no regular parameter field exists for parameter: " + parameterGroupName); + } + + // Set the status of the parameter group and the field + parameterValidationResult.setResult(status, message); + this.setResult(status); + } + + /** + * Set the validation result on a nested parameter group. + * + * @param parameterName The name of the parameter field + * @param nestedValidationResult The validation result from a nested field + */ + public void setResult(String parameterName, ValidationResult nestedValidationResult) { + GroupValidationResult groupValidationResult; + try { + groupValidationResult = (GroupValidationResult) validationResultMap.get(parameterName); + } catch (ClassCastException e) { + throw new ParameterRuntimeException("parameter is not a nested group parameter: " + parameterName, e); + } + + if (groupValidationResult == null) { + throw new ParameterRuntimeException("no nested parameter field exists for parameter: " + parameterName); + } + + // Set the status of the parameter group and replace the field result + validationResultMap.put(parameterName, nestedValidationResult); + this.setResult(status); + } + + /** + * Set the validation result on a nested parameter group map entry. + * + * @param parameterName The name of the parameter field + * @param key The key of the map entry + * @param nestedMapValidationResult The validation result from a nested map entry + */ + public void setResult(final String parameterName, final String key, + final ValidationResult nestedMapValidationResult) { + GroupMapValidationResult groupMapValidationResult; + try { + groupMapValidationResult = (GroupMapValidationResult) validationResultMap.get(parameterName); + } catch (ClassCastException e) { + throw new ParameterRuntimeException("parameter is not a nested group map parameter: " + parameterName, e); + } + + if (groupMapValidationResult == null) { + throw new ParameterRuntimeException("no group map parameter field exists for parameter: " + parameterName); + } + + // Set the status of the parameter group and the field + groupMapValidationResult.setResult(key, nestedMapValidationResult); + this.setResult(status); + } + + /** + * Gets the validation result. + * + * @param initialIndentation the indentation to use on the main result output + * @param subIndentation the indentation to use on sub parts of the result output + * @param showClean output information on clean fields + * @return the result + */ + @Override + public String getResult(final String initialIndentation, final String subIndentation, final boolean showClean) { + if (status == ValidationStatus.CLEAN && !showClean) { + return null; + } + + StringBuilder validationResultBuilder = new StringBuilder(); + + validationResultBuilder.append(initialIndentation); + validationResultBuilder.append("parameter group \""); + validationResultBuilder.append(parameterGroup.getName()); + validationResultBuilder.append("\" type \""); + validationResultBuilder.append(parameterGroup.getClass().getCanonicalName()); + validationResultBuilder.append("\" "); + validationResultBuilder.append(status); + validationResultBuilder.append(", "); + validationResultBuilder.append(message); + validationResultBuilder.append('\n'); + + for (ValidationResult fieldResult : validationResultMap.values()) { + String fieldResultMessage = fieldResult.getResult(initialIndentation + subIndentation, subIndentation, + showClean); + if (fieldResultMessage != null) { + validationResultBuilder.append(fieldResultMessage); + } + } + + return validationResultBuilder.toString(); + } +}
\ No newline at end of file diff --git a/common-parameters/src/main/java/org/onap/policy/common/parameters/ParameterConstants.java b/common-parameters/src/main/java/org/onap/policy/common/parameters/ParameterConstants.java new file mode 100644 index 00000000..240b1f40 --- /dev/null +++ b/common-parameters/src/main/java/org/onap/policy/common/parameters/ParameterConstants.java @@ -0,0 +1,45 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2018 Ericsson. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.parameters; + +/** + * This static class holds the values of constants for parameter handling. + */ +public final class ParameterConstants { + // Indentation is 0 on the left and 2 for each level of hierarchy + public static final String DEFAULT_INITIAL_RESULT_INDENTATION = ""; + public static final String DEFAULT_RESULT_INDENTATION = " "; + + // By default we do not show validation results for parameters that are validated as clean + public static final boolean DO_NOT_SHOW_CLEAN_RESULTS = false; + + // Messages for clean validations + public static final String PARAMETER_GROUP_HAS_STATUS_MESSAGE = "parameter group has status "; + public static final String PARAMETER_GROUP_MAP_HAS_STATUS_MESSAGE = "parameter group map has status "; + public static final String PARAMETER_HAS_STATUS_MESSAGE = "parameter has status "; + + /** + * Private constructor to prevent subclassing. + */ + private ParameterConstants() { + // Private constructor to prevent subclassing + } +}
\ No newline at end of file diff --git a/common-parameters/src/main/java/org/onap/policy/common/parameters/ParameterException.java b/common-parameters/src/main/java/org/onap/policy/common/parameters/ParameterException.java index 129d5390..3a6e17e8 100644 --- a/common-parameters/src/main/java/org/onap/policy/common/parameters/ParameterException.java +++ b/common-parameters/src/main/java/org/onap/policy/common/parameters/ParameterException.java @@ -55,21 +55,21 @@ public class ParameterException extends Exception { * Instantiates a new parameter exception. * * @param message the message on the exception - * @param e the exception that caused this parameter exception + * @param exception the exception that caused this parameter exception */ - public ParameterException(final String message, final Exception e) { - this(message, e, null); + public ParameterException(final String message, final Exception exception) { + this(message, exception, null); } /** * Instantiates a new parameter exception. * * @param message the message on the exception - * @param e the exception that caused this parameter exception + * @param exception the exception that caused this parameter exception * @param object the object that the exception was thrown on */ - public ParameterException(final String message, final Exception e, final Object object) { - super(message, e); + public ParameterException(final String message, final Exception exception, final Object object) { + super(message, exception); this.object = object; } @@ -83,7 +83,7 @@ public class ParameterException extends Exception { } /** - * Build a cascaded message from an exception and all its nested exceptions + * Build a cascaded message from an exception and all its nested exceptions. * * @param throwable the top level exception * @return cascaded message string @@ -101,7 +101,6 @@ public class ParameterException extends Exception { } /** - * * Get the object on which the exception was thrown. * * @return The object on which the exception was thrown diff --git a/common-parameters/src/main/java/org/onap/policy/common/parameters/AbstractParameters.java b/common-parameters/src/main/java/org/onap/policy/common/parameters/ParameterGroup.java index 5430dfeb..48e8379f 100644 --- a/common-parameters/src/main/java/org/onap/policy/common/parameters/AbstractParameters.java +++ b/common-parameters/src/main/java/org/onap/policy/common/parameters/ParameterGroup.java @@ -1,5 +1,4 @@ -package org.onap.policy.common.parameters; -/* +/*- * ============LICENSE_START======================================================= * Copyright (C) 2018 Ericsson. All rights reserved. * ================================================================================ @@ -19,29 +18,35 @@ package org.onap.policy.common.parameters; * ============LICENSE_END========================================================= */ +package org.onap.policy.common.parameters; + /** - * This class defines an abstract parameter interface that acts as a base interface for all parameters in the ONAP - * Policy Framework. All parameter POJOs are subclass of the abstract parameter class and can be used with the - * {@link ParameterService}. + * This interface acts as a base interface for all parameter groups in the ONAP Policy Framework. All parameter group + * POJOs are implementations of the parameter group interface and can be used with the {@link ParameterService}. * * @author Liam Fallon (liam.fallon@ericsson.com) */ -public interface AbstractParameters { +public interface ParameterGroup { /** - * Gets the parameter class. - * - * @return the parameter class + * Get the group name. + * + * @return the group name */ - default Class<? extends AbstractParameters> getParameterClass() { - return this.getClass(); - } + public String getName(); + + /** + * Validate parameters. + * + * @return the result of the parameter validation + */ + GroupValidationResult validate(); /** - * Gets the parameter class name. - * - * @return the parameter class name + * Check if the parameters are valid. + * + * @return true if the parameters are valid */ - default String getParameterClassName() { - return this.getClass().getCanonicalName(); + default boolean isValid() { + return validate().getStatus().isValid(); } } diff --git a/common-parameters/src/main/java/org/onap/policy/common/parameters/ParameterRuntimeException.java b/common-parameters/src/main/java/org/onap/policy/common/parameters/ParameterRuntimeException.java index 4b7d5874..071593a9 100644 --- a/common-parameters/src/main/java/org/onap/policy/common/parameters/ParameterRuntimeException.java +++ b/common-parameters/src/main/java/org/onap/policy/common/parameters/ParameterRuntimeException.java @@ -55,21 +55,21 @@ public class ParameterRuntimeException extends RuntimeException { * Instantiates a new parameter runtime exception. * * @param message the message on the exception - * @param e the exception that caused this parameter exception + * @param exception the exception that caused this parameter exception */ - public ParameterRuntimeException(final String message, final Exception e) { - this(message, e, null); + public ParameterRuntimeException(final String message, final Exception exception) { + this(message, exception, null); } /** * Instantiates a new parameter runtime exception. * * @param message the message on the exception - * @param e the exception that caused this parameter exception + * @param exception the exception that caused this parameter exception * @param object the object that the exception was thrown on */ - public ParameterRuntimeException(final String message, final Exception e, final Object object) { - super(message, e); + public ParameterRuntimeException(final String message, final Exception exception, final Object object) { + super(message, exception); this.object = object; } diff --git a/common-parameters/src/main/java/org/onap/policy/common/parameters/ParameterService.java b/common-parameters/src/main/java/org/onap/policy/common/parameters/ParameterService.java index f411937d..db6995c5 100644 --- a/common-parameters/src/main/java/org/onap/policy/common/parameters/ParameterService.java +++ b/common-parameters/src/main/java/org/onap/policy/common/parameters/ParameterService.java @@ -1,5 +1,4 @@ -package org.onap.policy.common.parameters; -/* +/*- * ============LICENSE_START======================================================= * Copyright (C) 2018 Ericsson. All rights reserved. * ================================================================================ @@ -19,25 +18,27 @@ package org.onap.policy.common.parameters; * ============LICENSE_END========================================================= */ +package org.onap.policy.common.parameters; + import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; /** - * The parameter service makes ONAP PF parameters available to all classes in a JVM. - * - * The reason for having a parameter service is to avoid having to pass parameters down long call chains in modules such - * as PDPs and editors. The parameter service makes correct and verified parameters available statically. - * - * The parameter service must be used with care because changing a parameter set anywhere in a JVM will affect all users - * of those parameters anywhere in the JVM. + * The parameter service makes ONAP PF parameter groups available to all classes in a JVM. + * + * <p>The reason for having a parameter service is to avoid having to pass parameters down long call chains in modules + * such as PDPs and editors. The parameter service makes correct and verified parameters available statically. + * + * <p>The parameter service must be used with care because changing a parameter set anywhere in a JVM will affect all + * users of those parameters anywhere in the JVM. * * @author Liam Fallon (liam.fallon@ericsson.com) */ public abstract class ParameterService { // The map holding the parameters - private static Map<Class<? extends AbstractParameters>, AbstractParameters> parameterMap = new ConcurrentHashMap<>(); + private static Map<String, ParameterGroup> parameterGroupMap = new ConcurrentHashMap<>(); /** * This class is an abstract static class that cannot be extended. @@ -46,69 +47,71 @@ public abstract class ParameterService { } /** - * Register parameters with the parameter service. + * Register a parameter group with the parameter service. * - * @param <P> the generic type - * @param parametersClass the class of the parameter, used to index the parameter - * @param parameters the parameters + * @param parameterGroup the parameter group */ - public static <P extends AbstractParameters> void registerParameters(final P parameters) { - parameterMap.put(parameters.getClass(), parameters); + public static void register(final ParameterGroup parameterGroup) { + if (!parameterGroupMap.containsKey(parameterGroup.getName())) { + parameterGroupMap.put(parameterGroup.getName(), parameterGroup); + } else { + throw new ParameterRuntimeException( + "\"" + parameterGroup.getName() + "\" already registered in parameter service"); + } } /** - * Remove parameters from the parameter service. + * Remove a parameter group from the parameter service. * - * @param <P> the generic type - * @param parametersClass the class of the parameter, used to index the parameter + * @param parameterGroupName the name of the parameter group */ - public static <P extends AbstractParameters> void deregisterParameters(final Class<P> parametersClass) { - parameterMap.remove(parametersClass); + public static void deregister(final String parameterGroupName) { + if (parameterGroupMap.containsKey(parameterGroupName)) { + parameterGroupMap.remove(parameterGroupName); + } else { + throw new ParameterRuntimeException("\"" + parameterGroupName + "\" not registered in parameter service"); + } } /** - * Get parameters from the parameter service. + * Get a parameter group from the parameter service. * - * @param <P> the generic type - * @param parametersClass the class of the parameter, used to index the parameter - * @return The parameter + * @param parameterGroupName the name of the parameter group + * @return The parameter group */ - @SuppressWarnings("unchecked") - public static <P extends AbstractParameters> P getParameters(final Class<P> parametersClass) { - final P parameter = (P) parameterMap.get(parametersClass); + public static ParameterGroup get(final String parameterGroupName) { + final ParameterGroup parameterGroup = parameterGroupMap.get(parameterGroupName); - if (parameter == null) { - throw new ParameterRuntimeException( - "Parameters for " + parametersClass.getCanonicalName() + " not found in parameter service"); + if (parameterGroup == null) { + throw new ParameterRuntimeException("\"" + parameterGroupName + "\" not found in parameter service"); } - return parameter; + return parameterGroup; } /** - * Check if parameters is defined on the parameter service. + * Check if a parameter group is defined on the parameter service. * - * @param <P> the generic type - * @param parametersClass the class of the parameter, used to index the parameter + * @param parameterGroupName the name of the parameter group * @return true if the parameter is defined */ - public static <P extends AbstractParameters> boolean existsParameters(final Class<P> parametersClass) { - return parameterMap.get(parametersClass) != null; + public static boolean contains(final String parameterGroupName) { + return parameterGroupMap.containsKey(parameterGroupName) && parameterGroupMap.get(parameterGroupName) != null; } /** - * Get all the entries in the parameters map. + * Get all parameter groups. * * @return The entries */ - public static Set<Entry<Class<? extends AbstractParameters>, AbstractParameters>> getAll() { - return parameterMap.entrySet(); + public static Set<Entry<String, ParameterGroup>> getAll() { + return parameterGroupMap.entrySet(); } /** - * Clear all parameters in the parameter service. + * Clear all parameter groups in the parameter service. */ public static void clear() { - parameterMap.clear(); + parameterGroupMap.clear(); } } diff --git a/common-parameters/src/main/java/org/onap/policy/common/parameters/ParameterValidationResult.java b/common-parameters/src/main/java/org/onap/policy/common/parameters/ParameterValidationResult.java new file mode 100644 index 00000000..9c829f4b --- /dev/null +++ b/common-parameters/src/main/java/org/onap/policy/common/parameters/ParameterValidationResult.java @@ -0,0 +1,110 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2018 Ericsson. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.parameters; + +import java.lang.reflect.Field; + +/** + * This class holds the result of the validation of a parameter. + */ +public class ParameterValidationResult implements ValidationResult { + // The field and value of the parameter to which the validation result applies + private final Field field; + private final Object parameterValue; + + // Validation status and message + private ValidationStatus status = ValidationStatus.CLEAN; + private String message = ParameterConstants.PARAMETER_HAS_STATUS_MESSAGE + status.toString(); + + /** + * Constructor, create validation result for a parameter with default arguments. + * + * @param field the parameter field + * @param parameterValue the value of the parameter field + */ + protected ParameterValidationResult(final Field field, final Object parameterValue) { + this.field = field; + this.parameterValue = parameterValue; + } + + /** + * Gets the name of the parameter being validated. + * + * @return the name + */ + @Override + public String getName() { + return field.getName(); + } + + /** + * Gets the validation status. + * + * @return the validation status + */ + @Override + public ValidationStatus getStatus() { + return status; + } + + /** + * Set the validation result on on a parameter field. + * @param status The validation status the field is receiving + * @param message The validation message explaining the validation status + */ + @Override + public void setResult(final ValidationStatus status, final String message) { + this.status = status; + this.message = message; + } + + /** + * Gets the validation result. + * + * @param initialIndentation the result indentation + * @param subIndentation the indentation to use on sub parts of the result output + * @param showClean output information on clean fields + * @return the result + */ + @Override + public String getResult(final String initialIndentation, final String subIndentation, final boolean showClean) { + if (status == ValidationStatus.CLEAN && !showClean) { + return null; + } + + StringBuilder validationResultBuilder = new StringBuilder(); + + validationResultBuilder.append(initialIndentation); + validationResultBuilder.append("field \""); + validationResultBuilder.append(getName()); + validationResultBuilder.append("\" type \""); + validationResultBuilder.append(field.getType().getCanonicalName()); + validationResultBuilder.append("\" value \""); + validationResultBuilder.append(parameterValue); + validationResultBuilder.append("\" "); + validationResultBuilder.append(getStatus()); + validationResultBuilder.append(", "); + validationResultBuilder.append(message); + validationResultBuilder.append('\n'); + + return validationResultBuilder.toString(); + } +} diff --git a/common-parameters/src/main/java/org/onap/policy/common/parameters/ValidationResult.java b/common-parameters/src/main/java/org/onap/policy/common/parameters/ValidationResult.java new file mode 100644 index 00000000..b97ccda0 --- /dev/null +++ b/common-parameters/src/main/java/org/onap/policy/common/parameters/ValidationResult.java @@ -0,0 +1,78 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2018 Ericsson. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.parameters; + +/** + * This interface defines the result of a parameter validation. + */ +public interface ValidationResult { + /** + * Gets the name of the entity being validated. + * + * @return the name + */ + public String getName(); + + /** + * Gets the status of validation. + * + * @return the status + */ + public ValidationStatus getStatus(); + + /** + * Checks if the result is valid. + * + * @return true, if is valid + */ + default boolean isValid() { + return getStatus().isValid(); + } + + /** + * Gets the validation result. + * + * @return the full validation result + */ + default String getResult() { + return getResult( + ParameterConstants.DEFAULT_INITIAL_RESULT_INDENTATION, + ParameterConstants.DEFAULT_RESULT_INDENTATION, + ParameterConstants.DO_NOT_SHOW_CLEAN_RESULTS); + } + + /** + * Gets the validation result. + * + * @param initialIndentation the indentation to use on the main result output + * @param subIndentation the indentation to use on sub parts of the result output + * @param showClean output information on clean fields + * @return the result + */ + public String getResult(final String initialIndentation, final String subIndentation, final boolean showClean); + + /** + * Set a validation result. + * @param status The validation status the field is receiving + * @param message The validation message explaining the validation status + */ + public void setResult(final ValidationStatus status, final String message); +}
\ No newline at end of file diff --git a/common-parameters/src/main/java/org/onap/policy/common/parameters/ParameterValidator.java b/common-parameters/src/main/java/org/onap/policy/common/parameters/ValidationStatus.java index 0d718267..ff453a1b 100644 --- a/common-parameters/src/main/java/org/onap/policy/common/parameters/ParameterValidator.java +++ b/common-parameters/src/main/java/org/onap/policy/common/parameters/ValidationStatus.java @@ -20,17 +20,17 @@ package org.onap.policy.common.parameters; -/** - * This interface is implemented by ONAP PF parameter classes so that they can be validated. - * - * @author Liam Fallon (liam.fallon@ericsson.com) - */ -public interface ParameterValidator { +public enum ValidationStatus { + CLEAN, + OBSERVATION, + WARNING, + INVALID; + /** - * Validate a parameter java bean, if the parameter bean is valid, an empty string is returned, - * otherwise the string gives details of the invalid parameters. - * - * @return the string with validation errors + * The result of a validation is valid unless the status is INVALID. + * @return true if the validation has passed */ - String validate(); + public boolean isValid() { + return !this.equals(INVALID); + } } |