diff options
15 files changed, 2896 insertions, 0 deletions
diff --git a/utils/src/main/java/org/onap/policy/common/utils/properties/PropertyConfiguration.java b/utils/src/main/java/org/onap/policy/common/utils/properties/PropertyConfiguration.java new file mode 100644 index 00000000..7253c746 --- /dev/null +++ b/utils/src/main/java/org/onap/policy/common/utils/properties/PropertyConfiguration.java @@ -0,0 +1,465 @@ +/* + * ============LICENSE_START======================================================= + * ONAP Policy Engine - Common Modules + * ================================================================================ + * Copyright (C) 2018 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.utils.properties; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.Properties; +import org.onap.policy.common.utils.properties.exception.PropertyAccessException; +import org.onap.policy.common.utils.properties.exception.PropertyException; +import org.onap.policy.common.utils.properties.exception.PropertyInvalidException; +import org.onap.policy.common.utils.properties.exception.PropertyMissingException; + +/** + * Configuration whose fields are initialized by reading from a set of {@link Properties}, + * as directed by the {@link Property} annotations that appear on fields within the + * subclass. + * <p> + * It is possible that an invalid <i>defaultValue</i> is specified via the + * {@link Property} annotation. This could remain undetected until an optional property is + * left out of the {@link Properties}. Consequently, this class will always validate a + * {@link Property}'s default value, if the <i>defaultValue</i> is not empty or if + * <i>accept</i> includes the "empty" option. + */ +public class PropertyConfiguration { + + /** + * The "empty" option that may appear within the {@link Property}'s <i>accept</i> + * attribute. + */ + public static final String ACCEPT_EMPTY = "empty"; + + /** + * Constructs a configuration, without populating any fields; fields should be + * populated later by invoking {@link #setAllFields(Properties)}. + */ + public PropertyConfiguration() { + super(); + } + + /** + * Initializes each "@Property" field with its value, as found in the properties. + * + * @param props properties from which to extract the values + * @throws PropertyException if an error occurs + */ + public PropertyConfiguration(Properties props) throws PropertyException { + setAllFields(props); + } + + /** + * Walks the class hierarchy of "this" object, populating fields defined in each + * class, using values extracted from the given property set. + * + * @param props properties from which to extract the values + * @throws PropertyException if an error occurs + */ + public void setAllFields(Properties props) throws PropertyException { + Class<?> clazz = getClass(); + + while (clazz != PropertyConfiguration.class) { + for (Field field : clazz.getDeclaredFields()) { + setValue(field, props); + } + + clazz = clazz.getSuperclass(); + } + } + + /** + * Sets a field's value, within an object, based on what's in the properties. + * + * @param field field whose value is to be set + * @param props properties from which to get the value + * @return {@code true} if the property's value was set, {@code false} otherwise + * @throws PropertyException if an error occurs + */ + protected boolean setValue(Field field, Properties props) throws PropertyException { + Property prop = field.getAnnotation(Property.class); + if (prop == null) { + return false; + } + + checkModifiable(field, prop); + + if (setValue(field, props, prop)) { + return true; + } + + throw new PropertyAccessException(prop.name(), field.getName(), "unsupported field type"); + } + + /** + * Sets a field's value from a particular property. + * + * @param field field whose value is to be set + * @param props properties from which to get the value + * @param prop property of interest + * @return {@code true} if the property's value was set, {@code false} otherwise + * @throws PropertyException if an error occurs + */ + protected boolean setValue(Field field, Properties props, Property prop) throws PropertyException { + + try { + Object val = getValue(field, props, prop); + if (val == null) { + return false; + + } else { + + /* + * According to java docs & blogs, "field" is our own copy, so we're free + * to change the flags without impacting the real permissions of the field + * within the real class. + */ + field.setAccessible(true); + + field.set(this, val); + return true; + } + + } catch (IllegalArgumentException e) { + throw new PropertyInvalidException(prop.name(), field.getName(), e); + + } catch (IllegalAccessException e) { + throw new PropertyAccessException(prop.name(), field.getName(), e); + } + } + + /** + * Gets a property value, coercing it to the field's type. + * + * @param field field whose value is to be set + * @param props properties from which to get the value + * @param prop property of interest + * @return the value extracted from the property, or {@code null} if the field type is + * not supported + * @throws PropertyException if an error occurs + */ + protected Object getValue(Field field, Properties props, Property prop) throws PropertyException { + + Class<?> clazz = field.getType(); + String fieldName = field.getName(); + + // can still add support for short, float, double, enum + + if (clazz == String.class) { + return getStringValue(fieldName, props, prop); + + } else if (clazz == Boolean.class || clazz == boolean.class) { + return getBooleanValue(fieldName, props, prop); + + } else if (clazz == Integer.class || clazz == int.class) { + return getIntegerValue(fieldName, props, prop); + + } else if (clazz == Long.class || clazz == long.class) { + return getLongValue(fieldName, props, prop); + + } else { + return null; + } + } + + /** + * Verifies that the field can be modified, i.e., it's neither <i>static</i>, nor + * <i>final</i>. + * + * @param field field whose value is to be set + * @param prop property of interest + * @throws PropertyAccessException if the field is not modifiable + */ + protected void checkModifiable(Field field, Property prop) throws PropertyAccessException { + int mod = field.getModifiers(); + + if (Modifier.isStatic(mod)) { + throw new PropertyAccessException(prop.name(), field.getName(), "'static' variable cannot be modified"); + } + + if (Modifier.isFinal(mod)) { + throw new PropertyAccessException(prop.name(), field.getName(), "'final' variable cannot be modified"); + } + } + + /** + * Gets a property value, coercing it to a String. + * + * @param fieldName field whose value is to be set + * @param props properties from which to get the value + * @param prop property of interest + * @return the value extracted from the property + * @throws PropertyException if an error occurs + */ + protected String getStringValue(String fieldName, Properties props, Property prop) throws PropertyException { + + /* + * Note: the default value for a String type is always valid, thus no need to + * check it. + */ + + return getPropValue(fieldName, props, prop); + } + + /** + * Gets a property value, coercing it to a Boolean. + * + * @param fieldName field whose value is to be set + * @param props properties from which to get the value + * @param prop property of interest + * @return the value extracted from the property + * @throws PropertyException if an error occurs + */ + protected Boolean getBooleanValue(String fieldName, Properties props, Property prop) throws PropertyException { + // validate the default value + checkDefaultValue(fieldName, prop, xxx -> makeBoolean(fieldName, prop, prop.defaultValue())); + + return makeBoolean(fieldName, prop, getPropValue(fieldName, props, prop)); + } + + /** + * Gets a property value, coercing it to an Integer. + * + * @param fieldName field whose value is to be set + * @param props properties from which to get the value + * @param prop property of interest + * @return the value extracted from the property + * @throws PropertyException if an error occurs + */ + protected Integer getIntegerValue(String fieldName, Properties props, Property prop) throws PropertyException { + // validate the default value + checkDefaultValue(fieldName, prop, xxx -> makeInteger(fieldName, prop, prop.defaultValue())); + + return makeInteger(fieldName, prop, getPropValue(fieldName, props, prop)); + } + + /** + * Gets a property value, coercing it to a Long. + * + * @param fieldName field whose value is to be set + * @param props properties from which to get the value + * @param prop property of interest + * @return the value extracted from the property + * @throws PropertyException if an error occurs + */ + protected Long getLongValue(String fieldName, Properties props, Property prop) throws PropertyException { + // validate the default value + checkDefaultValue(fieldName, prop, xxx -> makeLong(fieldName, prop, prop.defaultValue())); + + return makeLong(fieldName, prop, getPropValue(fieldName, props, prop)); + } + + /** + * Gets a value from the property set. + * + * @param fieldName field whose value is to be set + * @param props properties from which to get the value + * @param prop property of interest + * @return the value extracted from the property, or the <i>defaultValue</i> if the + * value does not exist + * @throws PropertyMissingException if the property does not exist and the + * <i>defaultValue</i> is empty and <i>emptyOk</i> is {@code false} + */ + protected String getPropValue(String fieldName, Properties props, Property prop) throws PropertyMissingException { + String propnm = prop.name(); + + String val = getRawPropertyValue(props, propnm); + if (val != null && isEmptyOk(prop, val)) { + return val; + } + + val = prop.defaultValue(); + if (val != null && isEmptyOk(prop, val)) { + return val; + } + + throw new PropertyMissingException(prop.name(), fieldName); + } + + /** + * Gets the property value, straight from the property set. + * + * @param props properties from which to get the value + * @param propnm name of the property of interest + * @return + */ + protected String getRawPropertyValue(Properties props, String propnm) { + return props.getProperty(propnm); + } + + /** + * Coerces a String value into a Boolean. + * + * @param fieldName field whose value is to be set + * @param prop property of interest + * @param value value to be coerced + * @return the Boolean value represented by the String value + * @throws PropertyInvalidException if the value does not represent a valid Boolean + */ + private Boolean makeBoolean(String fieldName, Property prop, String value) throws PropertyInvalidException { + if ("true".equals(value.toLowerCase())) { + return Boolean.TRUE; + + } else if ("false".equals(value.toLowerCase())) { + return Boolean.FALSE; + + } else { + throw new PropertyInvalidException(prop.name(), fieldName, "expecting 'true' or 'false'"); + } + } + + /** + * Coerces a String value into an Integer. + * + * @param fieldName field whose value is to be set + * @param prop property of interest + * @param value value to be coerced + * @return the Integer value represented by the String value + * @throws PropertyInvalidException if the value does not represent a valid Integer + */ + private Integer makeInteger(String fieldName, Property prop, String value) throws PropertyInvalidException { + try { + return Integer.valueOf(value); + + } catch (NumberFormatException e) { + throw new PropertyInvalidException(prop.name(), fieldName, e); + } + } + + /** + * Coerces a String value into a Long. + * + * @param fieldName field whose value is to be set + * @param prop property of interest + * @param value value to be coerced + * @return the Long value represented by the String value + * @throws PropertyInvalidException if the value does not represent a valid Long + */ + private Long makeLong(String fieldName, Property prop, String value) throws PropertyInvalidException { + try { + return Long.valueOf(value); + + } catch (NumberFormatException e) { + throw new PropertyInvalidException(prop.name(), fieldName, e); + } + } + + /** + * Applies a function to check a property's default value. If the function throws an + * exception about an invalid property, then it's re-thrown as an exception about an + * invalid <i>defaultValue</i>. + * + * @param fieldName name of the field being checked + * @param prop property of interest + * @param func function to invoke to check the default value + */ + private void checkDefaultValue(String fieldName, Property prop, CheckDefaultValueFunction func) + throws PropertyInvalidException { + + if (isEmptyOk(prop, prop.defaultValue())) { + try { + func.apply(null); + + } catch (PropertyInvalidException ex) { + throw new PropertyInvalidException(ex.getPropertyName(), fieldName, "defaultValue is invalid", + ex.getCause()); + } + } + } + + /** + * Determines if a value is OK, even if it's empty. + * + * @param prop property specifying what's acceptable + * @param value value to be checked + * @return {@code true} if the value is not empty or empty is allowed, {@code false} + * otherwise + */ + protected boolean isEmptyOk(Property prop, String value) { + return !value.isEmpty() || isEmptyOk(prop); + } + + /** + * Determines if a {@link Property}'s <i>accept</i> attribute includes the "empty" + * option. + * + * @param prop property whose <i>accept</i> attribute is to be examined + * @return {@code true} if the <i>accept</i> attribute includes "empty" + */ + protected boolean isEmptyOk(Property prop) { + for (String option : prop.accept().split(",")) { + if (ACCEPT_EMPTY.equals(option)) { + return true; + } + } + + return false; + } + + /** + * Functions to check a default value. + */ + @FunctionalInterface + private static interface CheckDefaultValueFunction { + + /** + * Checks the default value. + * + * @param arg always {@code null} + * @throws PropertyInvalidException if an error occurs + */ + public void apply(Void arg) throws PropertyInvalidException; + } + + /** + * Annotation that declares a variable to be configured via {@link Properties}. + */ + @Target(ElementType.FIELD) + @Retention(RetentionPolicy.RUNTIME) + + protected static @interface Property { + + /** + * Name of the property. + * + * @return the property name + */ + public String name(); + + /** + * Default value, used when the property does not exist. + * + * @return the default value + */ + public String defaultValue() default ""; + + /** + * Comma-separated options identifying what's acceptable. The word, "empty", + * indicates that an empty string, "", is an acceptable value. + * + * @return options identifying what's acceptable + */ + public String accept() default ""; + + } +} diff --git a/utils/src/main/java/org/onap/policy/common/utils/properties/SpecPropertyConfiguration.java b/utils/src/main/java/org/onap/policy/common/utils/properties/SpecPropertyConfiguration.java new file mode 100644 index 00000000..9e3767c1 --- /dev/null +++ b/utils/src/main/java/org/onap/policy/common/utils/properties/SpecPropertyConfiguration.java @@ -0,0 +1,233 @@ +/* + * ============LICENSE_START======================================================= + * ONAP Policy Engine - Common Modules + * ================================================================================ + * Copyright (C) 2018 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.utils.properties; + +import java.util.Properties; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import org.onap.policy.common.utils.properties.exception.PropertyException; + +/** + * PropertyConfiguration whose property names are specialized, using a specialization. A + * property name can take one of the following forms: + * <dl> + * <dt>aaa{$}Ddd</dt> + * <dd>if the specialization is "Xxx", then it looks for the value associated with the + * property named "aaaXxxDdd"</dd> + * <dt>aaa{Bbb?Ccc}Ddd</dt> + * <dd>if the specialization is "Xxx", then it looks for the value associated with the + * property named "aaaBbbXxxCccDdd". If the property does not exist, then it looks for the + * value associated with the property named "aaaDdd" (i.e., without the + * specialization)</dd> + * <dt>aaa</dt> + * <dd>simply looks for the value associated with the property named "aaa", without using + * the specialization</dd> + * </dl> + * <p> + * In the above examples, any of the components (e.g., "aaa") may be empty. + */ +public class SpecPropertyConfiguration extends PropertyConfiguration { + + /** + * Pattern to extract the specializer from a property name. Group 1 matches the form, + * "{$}", while groups 2 and 3 match the prefix and suffix, respectively, of the form, + * "{prefix?suffix}". + */ + private static final Pattern SPEC_PAT = Pattern.compile("" + // start of specialization info + + "\\{(?:" + // specialization type 1 + + "(\\$)" + // alternative + + "|" + // specialization type 2 + + "(?:" + // specialization type 2 prefix, may be empty + + "([^}?]*)" + // place-holder for the specialization, itself + + "\\?" + // specialization type 2 suffix, may be empty + + "([^}]*)" + // end of specialization type 2 + + ")" + // end of specialization info + + ")\\}"); + + /** + * The specialization to be used within property names. + */ + private final String specialization; + + /** + * Constructs a configuration, without populating any fields; fields should be + * populated later by invoking {@link #setAllFields(Properties)}. + * + * @param specialization specialization to be substituted within property names + */ + public SpecPropertyConfiguration(String specialization) { + super(); + + this.specialization = specialization; + } + + /** + * + * Initializes each "@Property" field with its value, as found in the properties. + * + * @param specialization specialization to be substituted within property names + * @param props properties from which to extract the values + * @throws PropertyException if an error occurs + */ + public SpecPropertyConfiguration(String specialization, Properties props) throws PropertyException { + super(); + + this.specialization = specialization; + + setAllFields(props); + } + + /** + * Gets a property's value, examining the property name for each of the types of + * specialization. + */ + @Override + protected String getRawPropertyValue(Properties props, String propnm) { + Matcher mat = SPEC_PAT.matcher(propnm); + + if (!mat.find()) { + // property name isn't specialized - use it as is + return super.getRawPropertyValue(props, propnm); + + } else if (mat.group(1) != null) { + // replace "{$}" with the specialization name + return super.getRawPropertyValue(props, specializeType1(propnm, specialization, mat)); + + } else { + // first try to get the property using the specialization info + String val = super.getRawPropertyValue(props, specializeType2(propnm, specialization, mat)); + if (val != null) { + return val; + } + + // wasn't found - try again, without any specialization info + return super.getRawPropertyValue(props, generalizeType2(propnm, mat)); + } + } + + /** + * Generalizes a property name by stripping any specialization info from it. This is + * typically used to construct property names for junit testing. + * + * @param propnm property name to be stripped of specialization info + * @return the generalized property name + * @throws IllegalArgumentException if the property name requires specialization + * (i.e., contains "{$}") + */ + public static String generalize(String propnm) { + Matcher mat = SPEC_PAT.matcher(propnm); + + if (!mat.find()) { + // property name has no specialization info + return propnm; + + } else if (mat.group(1) != null) { + // the "{$}" form requires specialization + throw new IllegalArgumentException("property requires specialization"); + + } else { + // property name has specialization info - strip it out + return generalizeType2(propnm, mat); + } + } + + /** + * + * Generalizes a property name of specialization type 2 (i.e., "{xxx?yyy}" form). + * + * @param propnm property name to be stripped of specialization info + * @param matcher the matcher that matched the "{xxx?yyy}" + * @return the generalized property name + */ + private static String generalizeType2(String propnm, Matcher mat) { + String prefix = propnm.substring(0, mat.start()); + String suffix = propnm.substring(mat.end()); + + return prefix + suffix; + } + + /** + * Specializes a property name by applying the specialization. This is typically used + * to construct property names for junit testing. + * + * @param propnm property name to be stripped of specialization info + * @param spec specialization to apply + * @return the specialized property name + */ + public static String specialize(String propnm, String spec) { + Matcher mat = SPEC_PAT.matcher(propnm); + + if (!mat.find()) { + // property name has no specialization info - leave it as is + return propnm; + + } else if (mat.group(1) != null) { + // the "{$}" form requires specialization + return specializeType1(propnm, spec, mat); + + } else { + // the "{xxx?yyy}" form requires specialization + return specializeType2(propnm, spec, mat); + } + } + + /** + * Specializes a property name of specialization type 1 (i.e., "{$}" form). + * + * @param propnm property name to be stripped of specialization info + * @param spec specialization to apply + * @param matcher the matcher that matched the "{$}" + * @return the specialized property name + */ + private static String specializeType1(String propnm, String spec, Matcher mat) { + String prefix = propnm.substring(0, mat.start()); + String suffix = propnm.substring(mat.end()); + + return prefix + spec + suffix; + } + + /** + * Specializes a property name of specialization type 2 (i.e., "{xxx?yyy}" form). + * + * @param propnm property name to be stripped of specialization info + * @param spec specialization to apply + * @param matcher the matcher that matched the "{xxx?yyy}" + * @return the specialized property name + */ + private static String specializeType2(String propnm, String spec, Matcher matcher) { + String prefix = propnm.substring(0, matcher.start()); + String suffix = propnm.substring(matcher.end()); + + String specPrefix = matcher.group(2); + String specSuffix = matcher.group(3); + + return (prefix + specPrefix + spec + specSuffix + suffix); + } +} diff --git a/utils/src/main/java/org/onap/policy/common/utils/properties/exception/PropertyAccessException.java b/utils/src/main/java/org/onap/policy/common/utils/properties/exception/PropertyAccessException.java new file mode 100644 index 00000000..568a8a79 --- /dev/null +++ b/utils/src/main/java/org/onap/policy/common/utils/properties/exception/PropertyAccessException.java @@ -0,0 +1,70 @@ +/* + * ============LICENSE_START======================================================= + * ONAP Policy Engine - Common Modules + * ================================================================================ + * Copyright (C) 2018 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.utils.properties.exception; + +/** + * Exception indicating that a property's value cannot be converted to the type required + * by the target field. + */ +public class PropertyAccessException extends PropertyException { + private static final long serialVersionUID = 1L; + + /** + * + * @param propnm name of the property causing the exception, or {@code null} + * @param fieldName name of the field causing the exception, or {@code null} + */ + public PropertyAccessException(String propnm, String fieldName) { + super(propnm, fieldName); + } + + /** + * + * @param propnm name of the property causing the exception, or {@code null} + * @param fieldName name of the field causing the exception, or {@code null} + * @param message error message + */ + public PropertyAccessException(String propnm, String fieldName, String message) { + super(propnm, fieldName, message); + } + + /** + * + * @param propnm name of the property causing the exception, or {@code null} + * @param fieldName name of the field causing the exception, or {@code null} + * @param cause cause of the exception + */ + public PropertyAccessException(String propnm, String fieldName, Throwable cause) { + super(propnm, fieldName, cause); + } + + /** + * + * @param propnm name of the property causing the exception, or {@code null} + * @param fieldName name of the field causing the exception, or {@code null} + * @param message error message + * @param cause cause of the exception + */ + public PropertyAccessException(String propnm, String fieldName, String message, Throwable cause) { + super(propnm, fieldName, message, cause); + } + +} diff --git a/utils/src/main/java/org/onap/policy/common/utils/properties/exception/PropertyAnnotationException.java b/utils/src/main/java/org/onap/policy/common/utils/properties/exception/PropertyAnnotationException.java new file mode 100644 index 00000000..2803ddfe --- /dev/null +++ b/utils/src/main/java/org/onap/policy/common/utils/properties/exception/PropertyAnnotationException.java @@ -0,0 +1,69 @@ +/* + * ============LICENSE_START======================================================= + * ONAP Policy Engine - Common Modules + * ================================================================================ + * Copyright (C) 2018 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.utils.properties.exception; + +/** + * Exception indicating that a property annotation's definition (e.g., null name). + */ +public class PropertyAnnotationException extends PropertyException { + private static final long serialVersionUID = 1L; + + /** + * + * @param propnm name of the property causing the exception, or {@code null} + * @param fieldName name of the field causing the exception, or {@code null} + */ + public PropertyAnnotationException(String propnm, String fieldName) { + super(propnm, fieldName); + } + + /** + * + * @param propnm name of the property causing the exception, or {@code null} + * @param fieldName name of the field causing the exception, or {@code null} + * @param message error message + */ + public PropertyAnnotationException(String propnm, String fieldName, String message) { + super(propnm, fieldName, message); + } + + /** + * + * @param propnm name of the property causing the exception, or {@code null} + * @param fieldName name of the field causing the exception, or {@code null} + * @param cause cause of the exception + */ + public PropertyAnnotationException(String propnm, String fieldName, Throwable cause) { + super(propnm, fieldName, cause); + } + + /** + * + * @param propnm name of the property causing the exception, or {@code null} + * @param fieldName name of the field causing the exception, or {@code null} + * @param message error message + * @param cause cause of the exception + */ + public PropertyAnnotationException(String propnm, String fieldName, String message, Throwable cause) { + super(propnm, fieldName, message, cause); + } + +} diff --git a/utils/src/main/java/org/onap/policy/common/utils/properties/exception/PropertyException.java b/utils/src/main/java/org/onap/policy/common/utils/properties/exception/PropertyException.java new file mode 100644 index 00000000..8df4fb8e --- /dev/null +++ b/utils/src/main/java/org/onap/policy/common/utils/properties/exception/PropertyException.java @@ -0,0 +1,142 @@ +/* + * ============LICENSE_START======================================================= + * ONAP Policy Engine - Common Modules + * ================================================================================ + * Copyright (C) 2018 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.utils.properties.exception; + +/** + * Exception associated with a Property. + */ +public class PropertyException extends Exception { + private static final long serialVersionUID = 1L; + + /** + * Name of the property for which the exception was thrown. + */ + private final String propertyName; + + /** + * Name of the field for which the exception was thrown. + */ + private final String fieldName; + + /** + * + * @param propName name of the property causing the exception, or {@code null} + * @param fieldName name of the field causing the exception, or {@code null} + */ + public PropertyException(String propName, String fieldName) { + super(makeMessage(propName, fieldName)); + + this.propertyName = propName; + this.fieldName = fieldName; + } + + /** + * + * @param propnm name of the property causing the exception, or {@code null} + * @param fieldName name of the field causing the exception, or {@code null} + * @param message error message + */ + public PropertyException(String propnm, String fieldName, String message) { + super(makeMessage(propnm, fieldName, message)); + + this.propertyName = propnm; + this.fieldName = fieldName; + } + + /** + * + * @param propnm name of the property causing the exception, or {@code null} + * @param fieldName name of the field causing the exception, or {@code null} + * @param cause cause of the exception + */ + public PropertyException(String propnm, String fieldName, Throwable cause) { + super(makeMessage(propnm, fieldName), cause); + + this.propertyName = propnm; + this.fieldName = fieldName; + } + + /** + * + * @param propnm name of the property causing the exception, or {@code null} + * @param fieldName name of the field causing the exception, or {@code null} + * @param message error message + * @param cause cause of the exception + */ + public PropertyException(String propnm, String fieldName, String message, Throwable cause) { + super(makeMessage(propnm, fieldName, message), cause); + + this.propertyName = propnm; + this.fieldName = fieldName; + } + + /** + * + * @return name of the property for which the exception was thrown, or {@code null} if + * no name was provided + */ + public String getPropertyName() { + return propertyName; + } + + /** + * + * @return name of the field for which the exception was thrown, or {@code null} if no + * field was provided + */ + public String getFieldName() { + return fieldName; + } + + /** + * @param propnm name of the property causing the exception, or {@code null} + * @param fieldName name of the field causing the exception, or {@code null} + * @param message error message, never {@code null} + * @return an error message composed of the three items + */ + private static String makeMessage(String propnm, String fieldName, String message) { + return makeMessage(propnm, fieldName) + ": " + message; + } + + /** + * + * @param propnm name of the property causing the exception, or {@code null} + * @param fieldName name of the field causing the exception, or {@code null} + * @return an error message composed of the two items + */ + private static String makeMessage(String propnm, String fieldName) { + StringBuilder bldr = new StringBuilder(50); + + if (propnm == null) { + bldr.append("property exception"); + + } else { + bldr.append("exception for property " + propnm); + } + + if (fieldName != null) { + bldr.append(" with field " + fieldName); + } + + return bldr.toString(); + } + +} diff --git a/utils/src/main/java/org/onap/policy/common/utils/properties/exception/PropertyInvalidException.java b/utils/src/main/java/org/onap/policy/common/utils/properties/exception/PropertyInvalidException.java new file mode 100644 index 00000000..da1b6ae8 --- /dev/null +++ b/utils/src/main/java/org/onap/policy/common/utils/properties/exception/PropertyInvalidException.java @@ -0,0 +1,70 @@ +/* + * ============LICENSE_START======================================================= + * ONAP Policy Engine - Common Modules + * ================================================================================ + * Copyright (C) 2018 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.utils.properties.exception; + +/** + * Exception indicating that a property's value cannot be converted to the type required + * by the target field. + */ +public class PropertyInvalidException extends PropertyException { + private static final long serialVersionUID = 1L; + + /** + * + * @param propnm name of the property causing the exception, or {@code null} + * @param fieldName name of the field causing the exception, or {@code null} + */ + public PropertyInvalidException(String propnm, String fieldName) { + super(propnm, fieldName); + } + + /** + * + * @param propnm name of the property causing the exception, or {@code null} + * @param fieldName name of the field causing the exception, or {@code null} + * @param message error message + */ + public PropertyInvalidException(String propnm, String fieldName, String message) { + super(propnm, fieldName, message); + } + + /** + * + * @param propnm name of the property causing the exception, or {@code null} + * @param fieldName name of the field causing the exception, or {@code null} + * @param cause cause of the exception + */ + public PropertyInvalidException(String propnm, String fieldName, Throwable cause) { + super(propnm, fieldName, cause); + } + + /** + * + * @param propnm name of the property causing the exception, or {@code null} + * @param fieldName name of the field causing the exception, or {@code null} + * @param message error message + * @param cause cause of the exception + */ + public PropertyInvalidException(String propnm, String fieldName, String message, Throwable cause) { + super(propnm, fieldName, message, cause); + } + +} diff --git a/utils/src/main/java/org/onap/policy/common/utils/properties/exception/PropertyMissingException.java b/utils/src/main/java/org/onap/policy/common/utils/properties/exception/PropertyMissingException.java new file mode 100644 index 00000000..de542e6a --- /dev/null +++ b/utils/src/main/java/org/onap/policy/common/utils/properties/exception/PropertyMissingException.java @@ -0,0 +1,38 @@ +/* + * ============LICENSE_START======================================================= + * ONAP Policy Engine - Common Modules + * ================================================================================ + * Copyright (C) 2018 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.utils.properties.exception; + +/** + * Exception indicating that a property is missing. + */ +public class PropertyMissingException extends PropertyException { + private static final long serialVersionUID = 1L; + + /** + * + * @param propnm name of the property causing the exception, or {@code null} + * @param fieldName name of the field causing the exception, or {@code null} + */ + public PropertyMissingException(String propnm, String fieldName) { + super(propnm, fieldName); + } + +} diff --git a/utils/src/test/java/org/onap/policy/common/utils/properties/PropertyConfigurationTest.java b/utils/src/test/java/org/onap/policy/common/utils/properties/PropertyConfigurationTest.java new file mode 100644 index 00000000..cf823b5d --- /dev/null +++ b/utils/src/test/java/org/onap/policy/common/utils/properties/PropertyConfigurationTest.java @@ -0,0 +1,1031 @@ +/* + * ============LICENSE_START======================================================= + * ONAP Policy Engine - Common Modules + * ================================================================================ + * Copyright (C) 2018 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.utils.properties; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import java.lang.reflect.Field; +import java.util.Properties; +import org.junit.Before; +import org.junit.Test; +import org.onap.policy.common.utils.properties.exception.PropertyAccessException; +import org.onap.policy.common.utils.properties.exception.PropertyException; +import org.onap.policy.common.utils.properties.exception.PropertyInvalidException; +import org.onap.policy.common.utils.properties.exception.PropertyMissingException; + +/** + * + */ +public class PropertyConfigurationTest { + + /** + * Property used for most of the simple configuration subclasses. + */ + private static final String THE_VALUE = "the.value"; + + /** + * String property value. + */ + private static final String STRING_VALUE = "a string"; + + /** + * Default value for string property. + */ + private static final String STRING_VALUE_DEFAULT = "another string"; + + /** + * Value that cannot be coerced into any other type. + */ + private static final String INVALID_VALUE = "invalid"; + + /** + * Properties used when invoking constructors. + */ + private Properties props; + + @Before + public void setUp() { + props = new Properties(); + } + + @Test + public void testPropertyConfiguration() throws PropertyException { + class Config extends PropertyConfiguration { + + @Property(name = THE_VALUE) + private String value; + }; + + props.setProperty(THE_VALUE, STRING_VALUE); + + Config cfg = new Config(); + assertEquals(null, cfg.value); + + cfg.setAllFields(props); + assertEquals(STRING_VALUE, cfg.value); + } + + @Test + public void testPropertyConfigurationProperties() throws PropertyException { + class Config extends PropertyConfiguration { + + @Property(name = THE_VALUE) + private String value; + + public Config(Properties props) throws PropertyException { + super(props); + } + }; + + props.setProperty(THE_VALUE, STRING_VALUE); + Config cfg = new Config(props); + + assertEquals(STRING_VALUE, cfg.value); + } + + @Test + public void testSetAllFields() throws Exception { + + /* + * Implements an extra interface, just to see that it doesn't cause issues. + */ + class GrandParentConfig extends PropertyConfiguration implements DoesNothing { + + @Property(name = "grandparent.value") + protected boolean grandparentValue; + }; + + /* + * Implements the extra interface, too. + */ + class ParentConfig extends GrandParentConfig implements DoesNothing { + + @Property(name = "parent.value") + protected long parentValue; + }; + + class Config extends ParentConfig { + + @Property(name = THE_VALUE) + private String value; + }; + + + Config cfg = new Config(); + + // try one set of values + props.setProperty(THE_VALUE, STRING_VALUE); + props.setProperty("parent.value", "50000"); + props.setProperty("grandparent.value", "true"); + cfg.setAllFields(props); + + assertEquals(STRING_VALUE, cfg.value); + assertEquals(50000L, cfg.parentValue); + assertEquals(true, cfg.grandparentValue); + + // now a different set of values + props.setProperty(THE_VALUE, STRING_VALUE + "x"); + props.setProperty("parent.value", "50001"); + props.setProperty("grandparent.value", "false"); + cfg.setAllFields(props); + + assertEquals(STRING_VALUE + "x", cfg.value); + assertEquals(50001L, cfg.parentValue); + assertEquals(false, cfg.grandparentValue); + } + + @Test + public void testSetAllFields_NoProperties() throws Exception { + + class Config extends PropertyConfiguration { + + private String value; + }; + + + Config cfg = new Config(); + + props.setProperty(THE_VALUE, STRING_VALUE); + cfg.setAllFields(props); + + assertEquals(null, cfg.value); + } + + @Test + public void testSetValueFieldProperties_FieldSet() throws PropertyException { + class Config extends PropertyConfiguration { + + @Property(name = THE_VALUE) + private String value; + + public Config(Properties props) throws PropertyException { + super(props); + } + }; + + props.setProperty(THE_VALUE, STRING_VALUE); + Config cfg = new Config(props); + + assertEquals(STRING_VALUE, cfg.value); + } + + @Test + public void testSetValueFieldProperties_NoAnnotation() throws PropertyException { + class Config extends PropertyConfiguration { + + private String value; + + public Config(Properties props) throws PropertyException { + super(props); + } + }; + + props.setProperty(THE_VALUE, STRING_VALUE); + Config cfg = new Config(props); + + assertNull(cfg.value); + } + + @Test(expected = PropertyAccessException.class) + public void testSetValueFieldProperties_WrongFieldType() throws PropertyException { + class Config extends PropertyConfiguration { + + // Cannot set a property into an "Exception" field + @Property(name = THE_VALUE) + private Exception value; + + public Config(Properties props) throws PropertyException { + super(props); + } + }; + + props.setProperty(THE_VALUE, STRING_VALUE); + new Config(props); + } + + @Test(expected = PropertyMissingException.class) + public void testSetValueFieldPropertyProperties_NoProperty_NoDefault() throws PropertyException { + class Config extends PropertyConfiguration { + + @Property(name = THE_VALUE) + private String value; + + public Config(Properties props) throws PropertyException { + super(props); + } + }; + + new Config(props); + } + + @Test(expected = PropertyInvalidException.class) + public void testSetValueFieldPropertyProperties_InvalidValue() throws PropertyException { + class Config extends PropertyConfiguration { + + @Property(name = THE_VALUE) + private int value; + + public Config(Properties props) throws PropertyException { + super(props); + } + + /** + * This returns a boolean, but the field is an "int", so it should throw an + * exception when it tries to stuff the value into the field. + */ + @Override + protected Object getValue(Field field, Properties props, Property prop) throws PropertyException { + return Boolean.TRUE; + } + }; + + new Config(props); + } + + @Test + public void testGetValue() throws PropertyException { + // this class contains all of the supported field types + class Config extends PropertyConfiguration { + + @Property(name = "string") + private String stringValue; + + @Property(name = "boolean.true") + private Boolean boolTrueValue; + + @Property(name = "boolean.false") + private Boolean boolFalseValue; + + @Property(name = "primitive.boolean.true") + private boolean primBoolTrueValue; + + @Property(name = "primitive.boolean.false") + private boolean primBoolFalseValue; + + @Property(name = "integer") + private Integer intValue; + + @Property(name = "primitive.integer") + private int primIntValue; + + @Property(name = "long") + private Long longValue; + + @Property(name = "primitive.long") + private long primLongValue; + + public Config(Properties props) throws PropertyException { + super(props); + } + }; + + props.setProperty("string", "a string"); + props.setProperty("boolean.true", "true"); + props.setProperty("boolean.false", "false"); + props.setProperty("primitive.boolean.true", "true"); + props.setProperty("primitive.boolean.false", "false"); + props.setProperty("integer", "100"); + props.setProperty("primitive.integer", "101"); + props.setProperty("long", "10000"); + props.setProperty("primitive.long", "10001"); + + Config cfg = new Config(props); + + assertEquals("a string", cfg.stringValue); + assertEquals(true, cfg.boolTrueValue); + assertEquals(false, cfg.boolFalseValue); + assertEquals(true, cfg.primBoolTrueValue); + assertEquals(false, cfg.primBoolFalseValue); + assertEquals(100, cfg.intValue.intValue()); + assertEquals(101, cfg.primIntValue); + assertEquals(10000, cfg.longValue.longValue()); + assertEquals(10001, cfg.primLongValue); + } + + @Test(expected = PropertyAccessException.class) + public void testGetValue_UnsupportedType() throws PropertyException { + class Config extends PropertyConfiguration { + + // Cannot set a property into an "Exception" field + @Property(name = THE_VALUE) + private Exception value; + + public Config(Properties props) throws PropertyException { + super(props); + } + }; + + props.setProperty(THE_VALUE, STRING_VALUE); + new Config(props); + } + + @Test + public void testCheckModifiable_OtherModifiers() throws PropertyException { + // this class contains all of the supported field types + class Config extends PropertyConfiguration { + + @Property(name = "public") + public String publicString; + + @Property(name = "private") + private String privateString; + + @Property(name = "protected") + protected String protectedString; + + public Config(Properties props) throws PropertyException { + super(props); + } + }; + + props.setProperty("public", "a public string"); + props.setProperty("private", "a private string"); + props.setProperty("protected", "a protected string"); + + Config cfg = new Config(props); + + assertEquals("a public string", cfg.publicString); + assertEquals("a private string", cfg.privateString); + assertEquals("a protected string", cfg.protectedString); + } + + @Test(expected = PropertyAccessException.class) + public void testCheckModifiable_Static() throws PropertyException { + props.setProperty(THE_VALUE, STRING_VALUE); + new StaticConfig(props); + } + + @Test(expected = PropertyAccessException.class) + public void testCheckModifiable_Final() throws PropertyException { + class Config extends PropertyConfiguration { + + // Cannot set a property into an "final" field + @Property(name = THE_VALUE) + private final String value = ""; + + public Config(Properties props) throws PropertyException { + super(props); + } + }; + + props.setProperty(THE_VALUE, STRING_VALUE); + new Config(props); + } + + @Test + public void testGetStringValue() throws PropertyException { + class Config extends PropertyConfiguration { + + @Property(name = THE_VALUE) + private String value; + + public Config(Properties props) throws PropertyException { + super(props); + } + }; + + props.setProperty(THE_VALUE, STRING_VALUE); + Config cfg = new Config(props); + + assertEquals(STRING_VALUE, cfg.value); + } + + @Test + public void testGetBooleanValue_NoDefault() throws PropertyException { + class Config extends PropertyConfiguration { + + @Property(name = THE_VALUE) + private Boolean value; + + public Config(Properties props) throws PropertyException { + super(props); + } + }; + + props.setProperty(THE_VALUE, "true"); + Config cfg = new Config(props); + + assertEquals(true, cfg.value); + } + + @Test(expected = PropertyInvalidException.class) + public void testGetBooleanValue_InvalidDefault() throws PropertyException { + class Config extends PropertyConfiguration { + + @Property(name = THE_VALUE, defaultValue = INVALID_VALUE) + private Boolean value; + + public Config(Properties props) throws PropertyException { + super(props); + } + }; + + props.setProperty(THE_VALUE, "true"); + new Config(props); + } + + @Test + public void testGetBooleanValue_ValidDefault_True() throws PropertyException { + class Config extends PropertyConfiguration { + + @Property(name = THE_VALUE, defaultValue = "true") + private Boolean value; + + public Config(Properties props) throws PropertyException { + super(props); + } + }; + + // property not defined + Config cfg = new Config(props); + assertEquals(true, cfg.value); + + // try again, with the property defined as true + props.setProperty(THE_VALUE, "true"); + cfg = new Config(props); + assertEquals(true, cfg.value); + + // try again, with the property defined as false + props.setProperty(THE_VALUE, "false"); + cfg = new Config(props); + assertEquals(false, cfg.value); + } + + @Test + public void testGetBooleanValue_ValidDefault_False() throws PropertyException { + class Config extends PropertyConfiguration { + + @Property(name = THE_VALUE, defaultValue = "false") + private Boolean value; + + public Config(Properties props) throws PropertyException { + super(props); + } + }; + + // property not defined + Config cfg = new Config(props); + assertEquals(false, cfg.value); + + // try again, with the property defined as true + props.setProperty(THE_VALUE, "true"); + cfg = new Config(props); + assertEquals(true, cfg.value); + + // try again, with the property defined as false + props.setProperty(THE_VALUE, "false"); + cfg = new Config(props); + assertEquals(false, cfg.value); + } + + @Test + public void testGetIntegerValue_NoDefault() throws PropertyException { + class Config extends PropertyConfiguration { + + @Property(name = THE_VALUE) + private Integer value; + + public Config(Properties props) throws PropertyException { + super(props); + } + }; + + props.setProperty(THE_VALUE, "200"); + Config cfg = new Config(props); + + assertEquals(200, cfg.value.intValue()); + } + + @Test(expected = PropertyInvalidException.class) + public void testGetIntegerValue_InvalidDefault() throws PropertyException { + class Config extends PropertyConfiguration { + + @Property(name = THE_VALUE, defaultValue = INVALID_VALUE) + private Integer value; + + public Config(Properties props) throws PropertyException { + super(props); + } + }; + + props.setProperty(THE_VALUE, "200"); + new Config(props); + } + + @Test + public void testGetIntegerValue_ValidDefault() throws PropertyException { + class Config extends PropertyConfiguration { + + @Property(name = THE_VALUE, defaultValue = "201") + private Integer value; + + public Config(Properties props) throws PropertyException { + super(props); + } + }; + + // property not defined + Config cfg = new Config(props); + assertEquals(201, cfg.value.intValue()); + + // try again, with the property defined + props.setProperty(THE_VALUE, "200"); + cfg = new Config(props); + assertEquals(200, cfg.value.intValue()); + } + + @Test + public void testGetLongValue_NoDefault() throws PropertyException { + class Config extends PropertyConfiguration { + + @Property(name = THE_VALUE) + private Long value; + + public Config(Properties props) throws PropertyException { + super(props); + } + }; + + props.setProperty(THE_VALUE, "20000"); + Config cfg = new Config(props); + + assertEquals(20000L, cfg.value.longValue()); + } + + @Test(expected = PropertyInvalidException.class) + public void testGetLongValue_InvalidDefault() throws PropertyException { + class Config extends PropertyConfiguration { + + @Property(name = THE_VALUE, defaultValue = INVALID_VALUE) + private Long value; + + public Config(Properties props) throws PropertyException { + super(props); + } + }; + + props.setProperty(THE_VALUE, "20000"); + new Config(props); + } + + @Test + public void testGetLongValue_ValidDefault() throws PropertyException { + class Config extends PropertyConfiguration { + + @Property(name = THE_VALUE, defaultValue = "20001") + private Long value; + + public Config(Properties props) throws PropertyException { + super(props); + } + }; + + // property not defined + Config cfg = new Config(props); + assertEquals(20001L, cfg.value.longValue()); + + // try again, with the property defined + props.setProperty(THE_VALUE, "20000"); + cfg = new Config(props); + assertEquals(20000L, cfg.value.longValue()); + } + + @Test + public void testGetPropValue_Prop_NoDefault() throws PropertyException { + class Config extends PropertyConfiguration { + + @Property(name = THE_VALUE) + private String value; + + public Config(Properties props) throws PropertyException { + super(props); + } + }; + + props.setProperty(THE_VALUE, STRING_VALUE); + Config cfg = new Config(props); + + assertEquals(STRING_VALUE, cfg.value); + } + + @Test + public void testGetPropValue_Prop_Default() throws PropertyException { + class Config extends PropertyConfiguration { + + @Property(name = THE_VALUE, defaultValue = STRING_VALUE_DEFAULT) + private String value; + + public Config(Properties props) throws PropertyException { + super(props); + } + }; + + props.setProperty(THE_VALUE, STRING_VALUE); + Config cfg = new Config(props); + + assertEquals(STRING_VALUE, cfg.value); + } + + @Test + public void testGetPropValue_EmptyProp_EmptyOk() throws PropertyException { + class Config extends PropertyConfiguration { + + @Property(name = THE_VALUE, accept = "empty") + private String value; + + public Config(Properties props) throws PropertyException { + super(props); + } + }; + + props.setProperty(THE_VALUE, ""); + Config cfg = new Config(props); + + assertEquals("", cfg.value); + } + + @Test + public void testGetPropValue_EmptyDefault_EmptyOk() throws PropertyException { + class Config extends PropertyConfiguration { + + @Property(name = THE_VALUE, defaultValue = "", accept = "empty") + private String value; + + public Config(Properties props) throws PropertyException { + super(props); + } + }; + + Config cfg = new Config(props); + + assertEquals("", cfg.value); + } + + @Test + public void testGetPropValue_Default_EmptyOk() throws PropertyException { + class Config extends PropertyConfiguration { + + @Property(name = THE_VALUE, defaultValue = STRING_VALUE, accept = "empty") + private String value; + + public Config(Properties props) throws PropertyException { + super(props); + } + }; + + Config cfg = new Config(props); + + assertEquals(STRING_VALUE, cfg.value); + } + + @Test(expected = PropertyMissingException.class) + public void testGetPropValue_EmptyDefault_EmptyNotOk() throws PropertyException { + class Config extends PropertyConfiguration { + + @Property(name = THE_VALUE, defaultValue = "") + private String value; + + public Config(Properties props) throws PropertyException { + super(props); + } + }; + + new Config(props); + } + + @Test + public void testGetPropValue_Default_EmptyNotOk() throws PropertyException { + class Config extends PropertyConfiguration { + + @Property(name = THE_VALUE, defaultValue = STRING_VALUE, accept = "") + private String value; + + public Config(Properties props) throws PropertyException { + super(props); + } + }; + + Config cfg = new Config(props); + + assertEquals(STRING_VALUE, cfg.value); + } + + @Test + public void testGetRawPropertyValue() throws PropertyException { + class Config extends PropertyConfiguration { + + @Property(name = THE_VALUE) + private String value; + + public Config(Properties props) throws PropertyException { + super(props); + } + + @Override + protected String getRawPropertyValue(Properties props, String propnm) { + return STRING_VALUE; + } + }; + + Config cfg = new Config(props); + + assertEquals(STRING_VALUE, cfg.value); + + } + + @Test + public void testMakeBoolean_True() throws PropertyException { + class Config extends PropertyConfiguration { + + @Property(name = THE_VALUE) + private Boolean value; + + public Config(Properties props) throws PropertyException { + super(props); + } + }; + + props.setProperty(THE_VALUE, "true"); + Config cfg = new Config(props); + + assertEquals(true, cfg.value); + } + + @Test + public void testMakeBoolean_False() throws PropertyException { + class Config extends PropertyConfiguration { + + @Property(name = THE_VALUE) + private Boolean value; + + public Config(Properties props) throws PropertyException { + super(props); + } + }; + + props.setProperty(THE_VALUE, "false"); + Config cfg = new Config(props); + + assertEquals(false, cfg.value); + } + + @Test(expected = PropertyInvalidException.class) + public void testMakeBoolean_Invalid() throws PropertyException { + class Config extends PropertyConfiguration { + + @Property(name = THE_VALUE) + private Boolean value; + + public Config(Properties props) throws PropertyException { + super(props); + } + }; + + props.setProperty(THE_VALUE, INVALID_VALUE); + new Config(props); + } + + @Test + public void testMakeInteger_Valid() throws PropertyException { + class Config extends PropertyConfiguration { + + @Property(name = THE_VALUE) + private int value; + + public Config(Properties props) throws PropertyException { + super(props); + } + }; + + props.setProperty(THE_VALUE, "300"); + Config cfg = new Config(props); + + assertEquals(300, cfg.value); + } + + @Test(expected = PropertyInvalidException.class) + public void testMakeInteger_Invalid() throws PropertyException { + class Config extends PropertyConfiguration { + + @Property(name = THE_VALUE) + private int value; + + public Config(Properties props) throws PropertyException { + super(props); + } + }; + + props.setProperty(THE_VALUE, INVALID_VALUE); + new Config(props); + } + + @Test(expected = PropertyInvalidException.class) + public void testMakeInteger_TooBig() throws PropertyException { + class Config extends PropertyConfiguration { + + @Property(name = THE_VALUE) + private int value; + + public Config(Properties props) throws PropertyException { + super(props); + } + }; + + props.setProperty(THE_VALUE, String.valueOf(Integer.MAX_VALUE + 10L)); + new Config(props); + } + + @Test + public void testMakeLong_Valid() throws PropertyException { + class Config extends PropertyConfiguration { + + @Property(name = THE_VALUE) + private long value; + + public Config(Properties props) throws PropertyException { + super(props); + } + }; + + props.setProperty(THE_VALUE, "30000"); + Config cfg = new Config(props); + + assertEquals(30000L, cfg.value); + } + + @Test(expected = PropertyInvalidException.class) + public void testMakeLong_Invalid() throws PropertyException { + class Config extends PropertyConfiguration { + + @Property(name = THE_VALUE) + private long value; + + public Config(Properties props) throws PropertyException { + super(props); + } + }; + + props.setProperty(THE_VALUE, INVALID_VALUE); + new Config(props); + } + + @Test + public void testCheckDefaultValue_NotEmpty_Valid() throws PropertyException { + class Config extends PropertyConfiguration { + + @Property(name = THE_VALUE, defaultValue = "700") + private long value; + + public Config(Properties props) throws PropertyException { + super(props); + } + }; + + Config cfg = new Config(props); + + assertEquals(700L, cfg.value); + } + + @Test(expected = PropertyInvalidException.class) + public void testCheckDefaultValue_NotEmpty_Invalid() throws PropertyException { + class Config extends PropertyConfiguration { + + @Property(name = THE_VALUE, defaultValue = INVALID_VALUE) + private long value; + + public Config(Properties props) throws PropertyException { + super(props); + } + }; + + new Config(props); + } + + @Test(expected = PropertyInvalidException.class) + public void testCheckDefaultValue_Empty_EmptyOk_Invalid() throws PropertyException { + class Config extends PropertyConfiguration { + + @Property(name = THE_VALUE, defaultValue = "", accept = "empty") + private long value; + + public Config(Properties props) throws PropertyException { + super(props); + } + }; + + new Config(props); + } + + @Test + public void testIsEmptyOkPropertyString_True() throws PropertyException { + class Config extends PropertyConfiguration { + + @Property(name = THE_VALUE, defaultValue = "", accept = "empty") + private String value; + + public Config(Properties props) throws PropertyException { + super(props); + } + }; + + // missing property - should default to "" + Config cfg = new Config(props); + assertEquals("", cfg.value); + + // add an empty property - should take the property's value + props.setProperty(THE_VALUE, ""); + cfg.setAllFields(props); + assertEquals("", cfg.value); + + // add the property - should take the property's value + props.setProperty(THE_VALUE, STRING_VALUE); + cfg.setAllFields(props); + assertEquals(STRING_VALUE, cfg.value); + } + + @Test(expected = PropertyMissingException.class) + public void testIsEmptyOkPropertyString_False() throws PropertyException { + class Config extends PropertyConfiguration { + + @Property(name = THE_VALUE, defaultValue = "", accept = "") + private long value; + + public Config(Properties props) throws PropertyException { + super(props); + } + }; + + new Config(props); + } + + @Test + public void testIsEmptyOkProperty_True() throws PropertyException { + class Config extends PropertyConfiguration { + + @Property(name = THE_VALUE, defaultValue = "", accept = "empty") + private String value; + + public Config(Properties props) throws PropertyException { + super(props); + } + }; + + Config cfg = new Config(props); + + assertEquals("", cfg.value); + } + + @Test(expected = PropertyMissingException.class) + public void testIsEmptyOkProperty_False() throws PropertyException { + class Config extends PropertyConfiguration { + + @Property(name = THE_VALUE, defaultValue = "", accept = "") + private long value; + + public Config(Properties props) throws PropertyException { + super(props); + } + }; + + new Config(props); + } + + /** + * A config whose annotated property is "static". + */ + public static class StaticConfig extends PropertyConfiguration { + + // "static" field cannot be set + @Property(name = THE_VALUE) + private static String value; + + public StaticConfig(Properties props) throws PropertyException { + super(props); + } + }; + + /** + * This is just used as a mix-in to ensure that the configuration ignores interfaces. + */ + public static interface DoesNothing { + + } +} diff --git a/utils/src/test/java/org/onap/policy/common/utils/properties/SpecPropertyConfigurationTest.java b/utils/src/test/java/org/onap/policy/common/utils/properties/SpecPropertyConfigurationTest.java new file mode 100644 index 00000000..39c8f01a --- /dev/null +++ b/utils/src/test/java/org/onap/policy/common/utils/properties/SpecPropertyConfigurationTest.java @@ -0,0 +1,331 @@ +/* + * ============LICENSE_START======================================================= + * ONAP Policy Engine - Common Modules + * ================================================================================ + * Copyright (C) 2018 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.utils.properties; + +import static org.junit.Assert.*; +import java.util.Properties; +import org.junit.Before; +import org.junit.Test; +import org.onap.policy.common.utils.properties.exception.PropertyException; +import org.onap.policy.common.utils.properties.exception.PropertyMissingException; +import static org.onap.policy.common.utils.properties.SpecPropertyConfiguration.*; + +/** + * + */ +public class SpecPropertyConfigurationTest { + + /** + * The specializer. + */ + private static final String SPEC = "my.name"; + + /** + * Properties used when invoking constructors. + */ + private Properties props; + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception { + props = new Properties(); + } + + /** + * Test method for {@link org.onap.policy.common.utils.properties.SpecPropertyConfiguration#getRawPropertyValue(java.util.Properties, java.lang.String)}. + * @throws PropertyException + */ + @Test + public void testGetRawPropertyValue() throws PropertyException { + class Config extends SpecPropertyConfiguration { + + // no spec + @Property(name = "prefix.suffix") + private String noSpec; + + // no spec, other type + @Property(name = "no.spec.bool") + private boolean noSpecBool; + + // type 1, no prefix + @Property(name = "{$}.suffix") + private String type1NoPrefix; + + // type 1, no suffix + @Property(name = "prefix.{$}") + private String type1NoSuffix; + + // type 1, both prefix and suffix + @Property(name = "prefix.{$}.suffix") + private String type1Both; + + // type 1, other type + @Property(name = "an.{$}.int") + private int type1Int; + + // type 2, no prefix + @Property(name = "{abc.?.def}.suffix") + private String type2NoPrefix; + + // type 2, no suffix + @Property(name = "prefix.{abc.?.def}") + private String type2NoSuffix; + + // type 2, no spec prefix + @Property(name = "prefix.{?.def}.suffix") + private String type2NoSpecPrefix; + + // type 2, no spec suffix + @Property(name = "prefix{.abc.?}.suffix") + private String type2NoSpecSuffix; + + // type 2, all components + @Property(name = "prefix.{abc.?.def.}suffix") + private String type2Both; + + // type 2, other type + @Property(name = "a.{abc.?.def.}long") + private long type2Long; + + public Config(String specialization, Properties props) throws PropertyException { + super(specialization, props); + } + }; + + props.setProperty("prefix.suffix", "no.spec"); + props.setProperty("no.spec.bool", "true"); + props.setProperty("world.suffix", "type1.no.prefix"); + props.setProperty("prefix.world", "type1.no.suffix"); + props.setProperty("prefix.world.suffix", "type1.both"); + props.setProperty("an.world.int", "200"); + props.setProperty("abc.world.def.suffix", "type2.no.prefix"); + props.setProperty("prefix.abc.world.def", "type2.no.suffix"); + props.setProperty("prefix.world.def.suffix", "type2.no.spec.prefix"); + props.setProperty("prefix.abc.world.suffix", "type2.no.spec.suffix"); + props.setProperty("prefix.abc.world.def.suffix", "type2.both"); + props.setProperty("a.abc.world.def.long", "3000"); + + Config cfg = new Config("world", props); + + assertEquals("no.spec", cfg.noSpec); + assertEquals(true, cfg.noSpecBool); + assertEquals("type1.no.prefix", cfg.type1NoPrefix); + assertEquals("type1.no.suffix", cfg.type1NoSuffix); + assertEquals("type1.both", cfg.type1Both); + assertEquals(200, cfg.type1Int); + assertEquals("type2.no.prefix", cfg.type2NoPrefix); + assertEquals("type2.no.suffix", cfg.type2NoSuffix); + assertEquals("type2.no.spec.prefix", cfg.type2NoSpecPrefix); + assertEquals("type2.no.spec.suffix", cfg.type2NoSpecSuffix); + assertEquals("type2.both", cfg.type2Both); + assertEquals(3000L, cfg.type2Long); + } + @Test + public void testGetRawPropertyValue_Type2_Generalized() throws PropertyException { + class Config extends SpecPropertyConfiguration { + + // type 2, all components + @Property(name = "prefix.{abc.?.def.}suffix") + private String value; + + public Config(String specialization, Properties props) throws PropertyException { + super(specialization, props); + } + }; + + props.setProperty("prefix.suffix", "no.spec"); + + Config cfg = new Config("world", props); + + assertEquals("no.spec", cfg.value); + } + + /** + * Test method for {@link org.onap.policy.common.utils.properties.SpecPropertyConfiguration#getRawPropertyValue(java.util.Properties, java.lang.String)}. + * @throws PropertyException + */ + @Test(expected = PropertyMissingException.class) + public void testGetRawPropertyValue_NotFound() throws PropertyException { + class Config extends SpecPropertyConfiguration { + + @Property(name = "not.found") + private String notFound; + + public Config(String specialization, Properties props) throws PropertyException { + super(specialization, props); + } + }; + + new Config("not found", props); + } + + /** + * Test method for {@link org.onap.policy.common.utils.properties.SpecPropertyConfiguration#SpecPropertyConfiguration(java.lang.String)}. + * @throws PropertyException + */ + @Test + public void testSpecPropertyConfigurationString() throws PropertyException { + final String propnm = "string.{$}.prop"; + final String propval = "hello"; + + class Config extends SpecPropertyConfiguration { + + @Property(name = propnm) + private String value; + + public Config(String specialization) { + super(specialization); + } + }; + + props.setProperty(specialize(propnm, SPEC), propval); + + Config cfg = new Config(SPEC); + assertEquals(null, cfg.value); + + cfg.setAllFields(props); + assertEquals(propval, cfg.value); + } + + /** + * Test method for {@link org.onap.policy.common.utils.properties.SpecPropertyConfiguration#SpecPropertyConfiguration(java.lang.String, java.util.Properties)}. + * @throws PropertyException + */ + @Test + public void testSpecPropertyConfigurationStringProperties() throws PropertyException { + final String propnm = "int.{$}.prop"; + final int propval = 10; + + class Config extends SpecPropertyConfiguration { + + @Property(name = propnm) + private int value; + + public Config(String specialization, Properties props) throws PropertyException { + super(specialization, props); + } + }; + + props.setProperty(specialize(propnm, SPEC), String.valueOf(propval)); + + Config cfg = new Config(SPEC, props); + + assertEquals(propval, cfg.value); + } + + /** + * Test method for {@link org.onap.policy.common.utils.properties.SpecPropertyConfiguration#generalize(java.lang.String)}. + */ + @Test + public void testGeneralize_NoSpec() { + final String xyzPdq = "xyz.pdq"; + + // no spec + assertEquals(xyzPdq, generalize(xyzPdq)); + + // spec type 1 throws an exception - we'll test it separately + + // spec type 2 + assertEquals(xyzPdq, generalize("xyz.{xxx.?.yyy.}pdq")); + } + + /** + * Test method for {@link org.onap.policy.common.utils.properties.SpecPropertyConfiguration#generalize(java.lang.String)}. + */ + @Test(expected = IllegalArgumentException.class) + public void testGeneralize_Spec1() { + generalize("abc.{$}.def"); + } + + /** + * Test method for {@link org.onap.policy.common.utils.properties.SpecPropertyConfiguration#generalizeType2(java.lang.String, java.util.regex.Matcher)}. + */ + @Test + public void testGeneralizeType2() { + assertEquals("abc.def", generalize("abc.{xyz?pdq}def")); + + assertEquals("", generalize("{xyz?pdq}")); + } + + /** + * Test method for {@link org.onap.policy.common.utils.properties.SpecPropertyConfiguration#specialize(java.lang.String, java.lang.String)}. + */ + @Test + public void testSpecialize() { + final String spec = "get.spec"; + final String abcDef = "abc.def"; + + // no spec + assertEquals(abcDef, specialize(abcDef, spec)); + + // spec type 1 + assertEquals("abc.get.spec.def", specialize("abc.{$}.def", spec)); + + // spec type 2 + assertEquals("abc.xxx.get.spec.yyy.def", specialize("abc.{xxx.?.yyy.}def", spec)); + } + + /** + * Test method for {@link org.onap.policy.common.utils.properties.SpecPropertyConfiguration#specializeType1(java.lang.String, java.lang.String, java.util.regex.Matcher)}. + */ + @Test + public void testSpecializeType1() { + final String spec = "spec1"; + + // no prefix + assertEquals("spec1.def", specialize("{$}.def", spec)); + + // no suffix + assertEquals("abc.spec1", specialize("abc.{$}", spec)); + + // with both prefix and suffix + assertEquals("abc.spec1.def", specialize("abc.{$}.def", spec)); + } + + /** + * Test method for {@link org.onap.policy.common.utils.properties.SpecPropertyConfiguration#specializeType2(java.lang.String, java.lang.String, java.util.regex.Matcher)}. + */ + @Test + public void testSpecializeType2() { + final String spec = "spec2"; + + // no prefix + assertEquals("xxx.spec2.yyy.def", specialize("{xxx.?.yyy.}def", spec)); + + // no suffix + assertEquals("abc.xxx.spec2.yyy", specialize("abc{.xxx.?.yyy}", spec)); + + // no spec prefix + assertEquals("abc.spec2.yyy.def", specialize("abc.{?.yyy.}def", spec)); + + // no spec suffix + assertEquals("abc.xxx.spec2.def", specialize("abc.{xxx.?}.def", spec)); + + // no components + assertEquals(spec, specialize("{?}", spec)); + + // all components + assertEquals("abc.xxx.spec2.yyy.def", specialize("abc.{xxx.?.yyy.}def", spec)); + } + +} diff --git a/utils/src/test/java/org/onap/policy/common/utils/properties/exception/BasicPropertyExceptionTester.java b/utils/src/test/java/org/onap/policy/common/utils/properties/exception/BasicPropertyExceptionTester.java new file mode 100644 index 00000000..1e5fcfcd --- /dev/null +++ b/utils/src/test/java/org/onap/policy/common/utils/properties/exception/BasicPropertyExceptionTester.java @@ -0,0 +1,130 @@ +/* + * ============LICENSE_START======================================================= + * ONAP Policy Engine - Common Modules + * ================================================================================ + * Copyright (C) 2018 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.utils.properties.exception; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThat; +import org.hamcrest.CoreMatchers; + +/** + * Superclass used to test subclasses of {@link PropertyException}. + */ +public class BasicPropertyExceptionTester { + + /** + * The "message" that's passed each time an exception is constructed. + */ + protected static final String MESSAGE = "some error"; + + /** + * The "throwable" that's passed each time an exception is constructed. + */ + protected static final Throwable THROWABLE = new Throwable(); + + /** + * Name of the "property" to be passed each time an exception is constructed. + */ + protected static final String PROPERTY = "myName"; + + /** + * Name of the "property" field. + */ + protected static final String FIELD = "PROPERTY"; + + /* + * Methods to perform various tests on the except subclass. + */ + + protected void doTestPropertyExceptionStringField_AllPopulated(PropertyException ex) { + standardTests(ex); + } + + protected void doTestPropertyExceptionStringField_NullProperty(PropertyException ex) { + assertEquals(null, ex.getPropertyName()); + assertEquals(FIELD, ex.getFieldName()); + assertNotNull(ex.getMessage()); + assertNotNull(ex.toString()); + } + + protected void doTestPropertyExceptionStringField_NullField(PropertyException ex) { + assertEquals(PROPERTY, ex.getPropertyName()); + assertEquals(null, ex.getFieldName()); + assertNotNull(ex.getMessage()); + assertNotNull(ex.toString()); + } + + protected void doTestPropertyExceptionStringField_BothNull(PropertyException ex) { + assertEquals(null, ex.getPropertyName()); + assertEquals(null, ex.getFieldName()); + assertNotNull(ex.getMessage()); + assertNotNull(ex.toString()); + } + + protected void doTestPropertyExceptionStringFieldString(PropertyException ex) { + standardTests(ex); + standardMessageTests(ex); + } + + protected void doTestPropertyExceptionStringFieldThrowable(PropertyException ex) { + standardTests(ex); + standardThrowableTests(ex); + } + + protected void doTestPropertyExceptionStringFieldStringThrowable(PropertyException ex) { + standardTests(ex); + standardMessageTests(ex); + standardThrowableTests(ex); + } + + /** + * Performs standard tests that should apply to all subclasses. + * + * @param ex exception to test + */ + protected void standardTests(PropertyException ex) { + assertEquals(PROPERTY, ex.getPropertyName()); + assertEquals(FIELD, ex.getFieldName()); + assertNotNull(ex.getMessage()); + assertNotNull(ex.toString()); + } + + /** + * Performs standard tests for exceptions that were provided a message in their + * constructor. + * + * @param ex exception to test + */ + protected void standardMessageTests(PropertyException ex) { + assertThat(ex.getMessage(), CoreMatchers.endsWith(MESSAGE)); + } + + /** + * Performs standard tests for exceptions that were provided a throwable in their + * constructor. + * + * @param ex exception to test + */ + protected void standardThrowableTests(PropertyException ex) { + assertEquals(THROWABLE, ex.getCause()); + } + +} diff --git a/utils/src/test/java/org/onap/policy/common/utils/properties/exception/PropertyAccessExceptionTest.java b/utils/src/test/java/org/onap/policy/common/utils/properties/exception/PropertyAccessExceptionTest.java new file mode 100644 index 00000000..304df9df --- /dev/null +++ b/utils/src/test/java/org/onap/policy/common/utils/properties/exception/PropertyAccessExceptionTest.java @@ -0,0 +1,66 @@ +/* + * ============LICENSE_START======================================================= + * ONAP Policy Engine - Common Modules + * ================================================================================ + * Copyright (C) 2018 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.utils.properties.exception; + +import org.junit.Test; + +/** + * + */ +public class PropertyAccessExceptionTest extends BasicPropertyExceptionTester { + + /** + * Test method for {@link org.onap.policy.common.utils.properties.exception.PropertyAccessException#PropertyAccessException(java.lang.String, java.lang.String)}. + */ + @Test + public void testPropertyAccessExceptionStringField() { + doTestPropertyExceptionStringField_AllPopulated( new PropertyAccessException(PROPERTY, FIELD)); + doTestPropertyExceptionStringField_NullProperty( new PropertyAccessException(null, FIELD)); + doTestPropertyExceptionStringField_NullField( new PropertyAccessException(PROPERTY, null)); + doTestPropertyExceptionStringField_BothNull( new PropertyAccessException(null, null)); + } + + /** + * Test method for {@link org.onap.policy.common.utils.properties.exception.PropertyAccessException#PropertyAccessException(java.lang.String, java.lang.String, java.lang.String)}. + */ + @Test + public void testPropertyAccessExceptionStringFieldString() { + doTestPropertyExceptionStringFieldString(new PropertyAccessException(PROPERTY, FIELD, MESSAGE)); + } + + /** + * Test method for {@link org.onap.policy.common.utils.properties.exception.PropertyAccessException#PropertyAccessException(java.lang.String, java.lang.String, java.lang.Throwable)}. + */ + @Test + public void testPropertyAccessExceptionStringFieldThrowable() { + doTestPropertyExceptionStringFieldThrowable(new PropertyAccessException(PROPERTY, FIELD, THROWABLE)); + } + + /** + * Test method for {@link org.onap.policy.common.utils.properties.exception.PropertyAccessException#PropertyAccessException(java.lang.String, java.lang.String, java.lang.String, java.lang.Throwable)}. + */ + @Test + public void testPropertyAccessExceptionStringFieldStringThrowable() { + doTestPropertyExceptionStringFieldStringThrowable( + new PropertyAccessException(PROPERTY, FIELD, MESSAGE, THROWABLE)); + } + +} diff --git a/utils/src/test/java/org/onap/policy/common/utils/properties/exception/PropertyAnnotationExceptionTest.java b/utils/src/test/java/org/onap/policy/common/utils/properties/exception/PropertyAnnotationExceptionTest.java new file mode 100644 index 00000000..2c033084 --- /dev/null +++ b/utils/src/test/java/org/onap/policy/common/utils/properties/exception/PropertyAnnotationExceptionTest.java @@ -0,0 +1,70 @@ +/* + * ============LICENSE_START======================================================= + * ONAP Policy Engine - Common Modules + * ================================================================================ + * Copyright (C) 2018 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.utils.properties.exception; + +import org.junit.Test; + +/** + * + */ +public class PropertyAnnotationExceptionTest extends BasicPropertyExceptionTester { + + /** + * Test method for + * {@link org.onap.policy.common.utils.properties.exception.PropertyException#PropertyException(java.lang.String, java.lang.String)}. + */ + @Test + public void testPropertyExceptionStringField() { + doTestPropertyExceptionStringField_AllPopulated(new PropertyAnnotationException(PROPERTY, FIELD)); + doTestPropertyExceptionStringField_NullProperty(new PropertyAnnotationException(null, FIELD)); + doTestPropertyExceptionStringField_NullField(new PropertyAnnotationException(PROPERTY, null)); + doTestPropertyExceptionStringField_BothNull(new PropertyAnnotationException(null, null)); + } + + /** + * Test method for + * {@link org.onap.policy.common.utils.properties.exception.PropertyException#PropertyException(java.lang.String, java.lang.String, java.lang.String)}. + */ + @Test + public void testPropertyExceptionStringFieldString() { + doTestPropertyExceptionStringFieldString(new PropertyAnnotationException(PROPERTY, FIELD, MESSAGE)); + } + + /** + * Test method for + * {@link org.onap.policy.common.utils.properties.exception.PropertyException#PropertyException(java.lang.String, java.lang.String, java.lang.Throwable)}. + */ + @Test + public void testPropertyExceptionStringFieldThrowable() { + doTestPropertyExceptionStringFieldThrowable(new PropertyAnnotationException(PROPERTY, FIELD, THROWABLE)); + } + + /** + * Test method for + * {@link org.onap.policy.common.utils.properties.exception.PropertyException#PropertyException(java.lang.String, java.lang.String, java.lang.String, java.lang.Throwable)}. + */ + @Test + public void testPropertyExceptionStringFieldStringThrowable() { + doTestPropertyExceptionStringFieldStringThrowable( + new PropertyAnnotationException(PROPERTY, FIELD, MESSAGE, THROWABLE)); + } + +} diff --git a/utils/src/test/java/org/onap/policy/common/utils/properties/exception/PropertyExceptionTest.java b/utils/src/test/java/org/onap/policy/common/utils/properties/exception/PropertyExceptionTest.java new file mode 100644 index 00000000..18186ba2 --- /dev/null +++ b/utils/src/test/java/org/onap/policy/common/utils/properties/exception/PropertyExceptionTest.java @@ -0,0 +1,69 @@ +/* + * ============LICENSE_START======================================================= + * ONAP Policy Engine - Common Modules + * ================================================================================ + * Copyright (C) 2018 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.utils.properties.exception; + +import org.junit.Test; + +/** + * + */ +public class PropertyExceptionTest extends BasicPropertyExceptionTester { + + /** + * Test method for + * {@link org.onap.policy.common.utils.properties.exception.PropertyException#PropertyException(java.lang.String, java.lang.String)}. + */ + @Test + public void testPropertyExceptionStringField() { + doTestPropertyExceptionStringField_AllPopulated(new PropertyException(PROPERTY, FIELD)); + doTestPropertyExceptionStringField_NullProperty(new PropertyException(null, FIELD)); + doTestPropertyExceptionStringField_NullField(new PropertyException(PROPERTY, null)); + doTestPropertyExceptionStringField_BothNull(new PropertyException(null, null)); + } + + /** + * Test method for + * {@link org.onap.policy.common.utils.properties.exception.PropertyException#PropertyException(java.lang.String, java.lang.String, java.lang.String)}. + */ + @Test + public void testPropertyExceptionStringFieldString() { + doTestPropertyExceptionStringFieldString(new PropertyException(PROPERTY, FIELD, MESSAGE)); + } + + /** + * Test method for + * {@link org.onap.policy.common.utils.properties.exception.PropertyException#PropertyException(java.lang.String, java.lang.String, java.lang.Throwable)}. + */ + @Test + public void testPropertyExceptionStringFieldThrowable() { + doTestPropertyExceptionStringFieldThrowable(new PropertyException(PROPERTY, FIELD, THROWABLE)); + } + + /** + * Test method for + * {@link org.onap.policy.common.utils.properties.exception.PropertyException#PropertyException(java.lang.String, java.lang.String, java.lang.String, java.lang.Throwable)}. + */ + @Test + public void testPropertyExceptionStringFieldStringThrowable() { + doTestPropertyExceptionStringFieldStringThrowable(new PropertyException(PROPERTY, FIELD, MESSAGE, THROWABLE)); + } + +} diff --git a/utils/src/test/java/org/onap/policy/common/utils/properties/exception/PropertyInvalidExceptionTest.java b/utils/src/test/java/org/onap/policy/common/utils/properties/exception/PropertyInvalidExceptionTest.java new file mode 100644 index 00000000..f83b7ed3 --- /dev/null +++ b/utils/src/test/java/org/onap/policy/common/utils/properties/exception/PropertyInvalidExceptionTest.java @@ -0,0 +1,70 @@ +/* + * ============LICENSE_START======================================================= + * ONAP Policy Engine - Common Modules + * ================================================================================ + * Copyright (C) 2018 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.utils.properties.exception; + +import org.junit.Test; + +/** + * + */ +public class PropertyInvalidExceptionTest extends BasicPropertyExceptionTester { + + /** + * Test method for + * {@link org.onap.policy.common.utils.properties.exception.PropertyException#PropertyException(java.lang.String, java.lang.String)}. + */ + @Test + public void testPropertyExceptionStringField() { + doTestPropertyExceptionStringField_AllPopulated(new PropertyInvalidException(PROPERTY, FIELD)); + doTestPropertyExceptionStringField_NullProperty(new PropertyInvalidException(null, FIELD)); + doTestPropertyExceptionStringField_NullField(new PropertyInvalidException(PROPERTY, null)); + doTestPropertyExceptionStringField_BothNull(new PropertyInvalidException(null, null)); + } + + /** + * Test method for + * {@link org.onap.policy.common.utils.properties.exception.PropertyException#PropertyException(java.lang.String, java.lang.String, java.lang.String)}. + */ + @Test + public void testPropertyExceptionStringFieldString() { + doTestPropertyExceptionStringFieldString(new PropertyInvalidException(PROPERTY, FIELD, MESSAGE)); + } + + /** + * Test method for + * {@link org.onap.policy.common.utils.properties.exception.PropertyException#PropertyException(java.lang.String, java.lang.String, java.lang.Throwable)}. + */ + @Test + public void testPropertyExceptionStringFieldThrowable() { + doTestPropertyExceptionStringFieldThrowable(new PropertyInvalidException(PROPERTY, FIELD, THROWABLE)); + } + + /** + * Test method for + * {@link org.onap.policy.common.utils.properties.exception.PropertyException#PropertyException(java.lang.String, java.lang.String, java.lang.String, java.lang.Throwable)}. + */ + @Test + public void testPropertyExceptionStringFieldStringThrowable() { + doTestPropertyExceptionStringFieldStringThrowable( + new PropertyInvalidException(PROPERTY, FIELD, MESSAGE, THROWABLE)); + } + +} diff --git a/utils/src/test/java/org/onap/policy/common/utils/properties/exception/PropertyMissingExceptionTest.java b/utils/src/test/java/org/onap/policy/common/utils/properties/exception/PropertyMissingExceptionTest.java new file mode 100644 index 00000000..f99ddd93 --- /dev/null +++ b/utils/src/test/java/org/onap/policy/common/utils/properties/exception/PropertyMissingExceptionTest.java @@ -0,0 +1,42 @@ +/* + * ============LICENSE_START======================================================= + * ONAP Policy Engine - Common Modules + * ================================================================================ + * Copyright (C) 2018 AT&T Intellectual Property. 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.utils.properties.exception; + +import org.junit.Test; + +/** + * + */ +public class PropertyMissingExceptionTest extends BasicPropertyExceptionTester { + + /** + * Test method for + * {@link org.onap.policy.common.utils.properties.exception.PropertyException#PropertyException(java.lang.String, java.lang.String)}. + */ + @Test + public void testPropertyExceptionStringField() { + doTestPropertyExceptionStringField_AllPopulated(new PropertyMissingException(PROPERTY, FIELD)); + doTestPropertyExceptionStringField_NullProperty(new PropertyMissingException(null, FIELD)); + doTestPropertyExceptionStringField_NullField(new PropertyMissingException(PROPERTY, null)); + doTestPropertyExceptionStringField_BothNull(new PropertyMissingException(null, null)); + } + +} |