summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common-parameters/src/main/java/org/onap/policy/common/parameters/GroupValidationResult.java70
-rw-r--r--common-parameters/src/main/java/org/onap/policy/common/parameters/ParameterValidationResult.java62
-rw-r--r--common-parameters/src/main/java/org/onap/policy/common/parameters/annotations/Min.java39
-rw-r--r--common-parameters/src/main/java/org/onap/policy/common/parameters/annotations/NotBlank.java37
-rw-r--r--common-parameters/src/main/java/org/onap/policy/common/parameters/annotations/NotNull.java37
-rw-r--r--common-parameters/src/test/java/org/onap/policy/common/parameters/TestValidation.java270
-rw-r--r--common-parameters/src/test/java/org/onap/policy/common/parameters/testclasses/TestParametersLGeneric.java35
-rw-r--r--common-parameters/src/test/resources/expectedValidationResults/TestParametersL0_2_Invalid.txt6
-rw-r--r--common-parameters/src/test/resources/expectedValidationResults/TestParametersL0_3_Invalid.txt14
-rw-r--r--policy-endpoints/pom.xml9
-rw-r--r--policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/client/TopicSinkClient.java104
-rw-r--r--policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/client/TopicSinkClientException.java51
-rw-r--r--policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/client/TopicSinkClientExceptionTest.java35
-rw-r--r--policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/client/TopicSinkClientTest.java150
-rw-r--r--utils/src/main/java/org/onap/policy/common/utils/properties/PropertyConfiguration.java498
-rw-r--r--utils/src/test/java/org/onap/policy/common/utils/properties/PropertyConfigurationTest.java1268
16 files changed, 835 insertions, 1850 deletions
diff --git a/common-parameters/src/main/java/org/onap/policy/common/parameters/GroupValidationResult.java b/common-parameters/src/main/java/org/onap/policy/common/parameters/GroupValidationResult.java
index 283f36b9..6da36c19 100644
--- a/common-parameters/src/main/java/org/onap/policy/common/parameters/GroupValidationResult.java
+++ b/common-parameters/src/main/java/org/onap/policy/common/parameters/GroupValidationResult.java
@@ -1,20 +1,20 @@
-/*-
+/*
* ============LICENSE_START=======================================================
* Copyright (C) 2018 Ericsson. All rights reserved.
- * Modifications Copyright (C) 2018 AT&T Intellectual Property. All rights reserved.
+ * Modifications Copyright (C) 2018-2019 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.
- *
+ *
* SPDX-License-Identifier: Apache-2.0
* ============LICENSE_END=========================================================
*/
@@ -66,7 +66,7 @@ public class GroupValidationResult implements ValidationResult {
// Check if a validation result should be added for this declared field
if (isIncludedField(field)) {
// Set a validation result for the field
- validationResultMap.put(field.getName(), getValidationResult(field, parameterGroup));
+ validationResultMap.put(field.getName(), getSetValidationResult(field, parameterGroup));
}
}
@@ -75,13 +75,29 @@ public class GroupValidationResult implements ValidationResult {
// Check if a validation result should be added for this declared field
if (isIncludedField(field)) {
// Set a validation result for the field
- validationResultMap.putIfAbsent(field.getName(), getValidationResult(field, parameterGroup));
+ validationResultMap.putIfAbsent(field.getName(), getSetValidationResult(field, parameterGroup));
}
}
}
+
+ /**
+ * Construct a validation result for a field, updating "this" status.
+ *
+ * @param field The parameter field
+ * @param ParameterGroup The parameter group containing the field
+ * @return the validation result
+ * @throws Exception on accessing private fields
+ */
+ private ValidationResult getSetValidationResult(Field field, ParameterGroup parameterGroup) {
+ ValidationResult result = getValidationResult(field, parameterGroup);
+ setResult(result.getStatus());
+
+ return result;
+ }
+
/**
* Construct a validation result for a field.
- *
+ *
* @param field The parameter field
* @param ParameterGroup The parameter group containing the field
* @return the validation result
@@ -92,6 +108,12 @@ public class GroupValidationResult implements ValidationResult {
final Class<?> fieldType = field.getType();
final Object fieldObject = getObjectField(parameterGroup, field);
+ // perform null checks
+ ParameterValidationResult result = new ParameterValidationResult(field, fieldObject);
+ if (!result.isValid()) {
+ return result;
+ }
+
// Nested parameter groups are allowed
if (ParameterGroup.class.isAssignableFrom(fieldType)) {
return new GroupValidationResult((ParameterGroup) fieldObject);
@@ -106,16 +128,16 @@ public class GroupValidationResult implements ValidationResult {
// Collections of parameter groups are not allowed
if (Collection.class.isAssignableFrom(field.getType())) {
checkCollection4ParameterGroups(fieldName, fieldObject);
- return new ParameterValidationResult(field, fieldObject);
+ return result;
}
// It's a regular parameter
- return new ParameterValidationResult(field, fieldObject);
+ return result;
}
/**
* Get the value of a field in an object using a getter found with reflection.
- *
+ *
* @param targetObject The object on which to read the field value
* @param fieldName The name of the field
* @return The field value
@@ -156,7 +178,7 @@ public class GroupValidationResult implements ValidationResult {
/**
* Check if this field is a map of parameter groups indexed by string keys.
- *
+ *
* @param fieldName the name of the collection field.
* @param mapObject the map object to check
*/
@@ -184,7 +206,7 @@ public class GroupValidationResult implements ValidationResult {
/**
* Check if this field contains parameter groups.
- *
+ *
* @param fieldName the name of the collection field.
* @param collectionObject the collection object to check
*/
@@ -234,7 +256,7 @@ public class GroupValidationResult implements ValidationResult {
/**
* Set the validation result on a parameter group.
- *
+ *
* @param status The validation status the parameter group is receiving
* @param message The validation message explaining the validation status
*/
@@ -247,7 +269,7 @@ public class GroupValidationResult implements ValidationResult {
/**
* Set the validation result on a parameter group. On a sequence of calls, the most serious validation status is
* recorded, assuming the status enum ordinal increase in order of severity
- *
+ *
* @param status The validation status the parameter group is receiving
*/
public void setResult(final ValidationStatus status) {
@@ -260,7 +282,7 @@ public class GroupValidationResult implements ValidationResult {
/**
* Set the validation result on a parameter in a parameter group.
- *
+ *
* @param parameterName The name of the parameter
* @param status The validation status the field is receiving
* @param message The validation message explaining the validation status
@@ -281,7 +303,7 @@ public class GroupValidationResult implements ValidationResult {
/**
* Set the validation result on a nested parameter group.
- *
+ *
* @param parameterName The name of the parameter field
* @param nestedValidationResult The validation result from a nested field
*/
@@ -304,7 +326,7 @@ public class GroupValidationResult implements ValidationResult {
/**
* Set the validation result on a nested parameter group map entry.
- *
+ *
* @param parameterName The name of the parameter field
* @param key The key of the map entry
* @param nestedMapValidationResult The validation result from a nested map entry
@@ -329,7 +351,7 @@ public class GroupValidationResult implements ValidationResult {
/**
* Set the validation status on a group map entry.
- *
+ *
* @param parameterName The name of the parameter field
* @param key The key of the map entry
* @param status The validation status of the entry
@@ -395,11 +417,11 @@ public class GroupValidationResult implements ValidationResult {
return validationResultBuilder.toString();
}
-
+
/**
* Check if a field should be included for validation.
- *
+ *
* @param field the field to check for inclusion
* @return true of the field should be included
*/
@@ -425,11 +447,11 @@ public class GroupValidationResult implements ValidationResult {
superclassFields.add(field);
}
}
-
+
// Check the next super class down
currentClass = currentClass.getSuperclass();
}
-
+
return superclassFields;
}
-} \ No newline at end of file
+}
diff --git a/common-parameters/src/main/java/org/onap/policy/common/parameters/ParameterValidationResult.java b/common-parameters/src/main/java/org/onap/policy/common/parameters/ParameterValidationResult.java
index 9c829f4b..e43c2d17 100644
--- a/common-parameters/src/main/java/org/onap/policy/common/parameters/ParameterValidationResult.java
+++ b/common-parameters/src/main/java/org/onap/policy/common/parameters/ParameterValidationResult.java
@@ -1,26 +1,31 @@
-/*-
+/*
* ============LICENSE_START=======================================================
* Copyright (C) 2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019 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.
- *
+ *
* SPDX-License-Identifier: Apache-2.0
* ============LICENSE_END=========================================================
*/
package org.onap.policy.common.parameters;
+import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
+import org.onap.policy.common.parameters.annotations.Min;
+import org.onap.policy.common.parameters.annotations.NotBlank;
+import org.onap.policy.common.parameters.annotations.NotNull;
/**
* This class holds the result of the validation of a parameter.
@@ -43,6 +48,47 @@ public class ParameterValidationResult implements ValidationResult {
protected ParameterValidationResult(final Field field, final Object parameterValue) {
this.field = field;
this.parameterValue = parameterValue;
+
+ if (parameterValue == null && getAnyAnnotation(field, NotNull.class) != null) {
+ setResult(ValidationStatus.INVALID, "is null");
+
+ } else if (parameterValue instanceof String && getAnyAnnotation(field, NotBlank.class) != null
+ && parameterValue.toString().trim().isEmpty()) {
+ setResult(ValidationStatus.INVALID, "must be a non-blank string");
+
+ } else if (parameterValue instanceof Number) {
+ Min minAnnot = field.getAnnotation(Min.class);
+ if (minAnnot != null && ((Number) parameterValue).longValue() < minAnnot.value()) {
+ setResult(ValidationStatus.INVALID, "must be >= " + minAnnot.value());
+ }
+ }
+ }
+
+ /**
+ * Gets an annotation for a field, first checking the field, itself, and then checking
+ * at the class level for the current and superclasses.
+ *
+ * @param field field of interest
+ * @param annotClass class of annotation that is desired
+ * @return the field's annotation, or {@code null} if it does not exist
+ */
+ private static <T extends Annotation> T getAnyAnnotation(final Field field, Class<T> annotClass) {
+ T annot = field.getAnnotation(annotClass);
+ if (annot != null) {
+ return annot;
+ }
+
+ // check class level
+ Class<?> clazz = field.getDeclaringClass();
+ while (clazz != Object.class) {
+ if ((annot = clazz.getAnnotation(annotClass)) != null) {
+ return annot;
+ }
+
+ clazz = clazz.getSuperclass();
+ }
+
+ return null;
}
/**
@@ -66,14 +112,16 @@ public class ParameterValidationResult implements ValidationResult {
}
/**
- * Set the validation result on on a parameter field.
+ * Set the validation result on on a parameter field.
* @param status The validation status the field is receiving
* @param message The validation message explaining the validation status
*/
@Override
public void setResult(final ValidationStatus status, final String message) {
- this.status = status;
- this.message = message;
+ if (this.status == ValidationStatus.CLEAN) {
+ this.status = status;
+ this.message = message;
+ }
}
/**
diff --git a/common-parameters/src/main/java/org/onap/policy/common/parameters/annotations/Min.java b/common-parameters/src/main/java/org/onap/policy/common/parameters/annotations/Min.java
new file mode 100644
index 00000000..9ad6d7e0
--- /dev/null
+++ b/common-parameters/src/main/java/org/onap/policy/common/parameters/annotations/Min.java
@@ -0,0 +1,39 @@
+/*
+ * ============LICENSE_START=======================================================
+ * ONAP
+ * ================================================================================
+ * Copyright (C) 2019 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.parameters.annotations;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+@Retention(RUNTIME)
+@Target(FIELD)
+public @interface Min {
+
+ /**
+ * The minimum value allowed.
+ *
+ * @return the minimum value allowed
+ */
+ long value();
+}
diff --git a/common-parameters/src/main/java/org/onap/policy/common/parameters/annotations/NotBlank.java b/common-parameters/src/main/java/org/onap/policy/common/parameters/annotations/NotBlank.java
new file mode 100644
index 00000000..169fa593
--- /dev/null
+++ b/common-parameters/src/main/java/org/onap/policy/common/parameters/annotations/NotBlank.java
@@ -0,0 +1,37 @@
+/*
+ * ============LICENSE_START=======================================================
+ * ONAP
+ * ================================================================================
+ * Copyright (C) 2019 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.parameters.annotations;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * Indicates that a field (i.e., String) may not be empty.
+ */
+@Retention(RUNTIME)
+@Target({TYPE, FIELD})
+public @interface NotBlank {
+
+}
diff --git a/common-parameters/src/main/java/org/onap/policy/common/parameters/annotations/NotNull.java b/common-parameters/src/main/java/org/onap/policy/common/parameters/annotations/NotNull.java
new file mode 100644
index 00000000..3c7bc8b7
--- /dev/null
+++ b/common-parameters/src/main/java/org/onap/policy/common/parameters/annotations/NotNull.java
@@ -0,0 +1,37 @@
+/*
+ * ============LICENSE_START=======================================================
+ * ONAP
+ * ================================================================================
+ * Copyright (C) 2019 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.parameters.annotations;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * Indicates that a field may not be null.
+ */
+@Retention(RUNTIME)
+@Target({TYPE, FIELD})
+public @interface NotNull {
+
+}
diff --git a/common-parameters/src/test/java/org/onap/policy/common/parameters/TestValidation.java b/common-parameters/src/test/java/org/onap/policy/common/parameters/TestValidation.java
index fb08d325..57d69f8d 100644
--- a/common-parameters/src/test/java/org/onap/policy/common/parameters/TestValidation.java
+++ b/common-parameters/src/test/java/org/onap/policy/common/parameters/TestValidation.java
@@ -1,19 +1,20 @@
-/*-
+/*
* ============LICENSE_START=======================================================
* Copyright (C) 2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019 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.
- *
+ *
* SPDX-License-Identifier: Apache-2.0
* ============LICENSE_END=========================================================
*/
@@ -28,12 +29,43 @@ import static org.junit.Assert.assertTrue;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
-
import org.junit.Test;
+import org.onap.policy.common.parameters.annotations.Min;
+import org.onap.policy.common.parameters.annotations.NotBlank;
+import org.onap.policy.common.parameters.annotations.NotNull;
import org.onap.policy.common.parameters.testclasses.TestParametersL00;
import org.onap.policy.common.parameters.testclasses.TestParametersL10;
public class TestValidation {
+ private static final String NOT_BLANK_STRING_MESSAGE =
+ "field 'notBlankString' type 'java.lang.String' value '' INVALID, must be a non-blank string\n"
+ .replace('\'', '"');
+
+ private static final String NULL_STRING_MESSAGE =
+ "field 'notNullString' type 'java.lang.String' value 'null' INVALID, is null\n".replace('\'', '"');
+
+
+ private static final String NOT_BLANK_OBJECT_NAME = "notBlankObject";
+ private static final String NOT_BLANK_STRING_NAME = "notBlankString";
+ private static final String NOT_NULL_OBJECT_NAME = "notNullObject";
+ private static final String NOT_NULL_STRING_NAME = "notNullString";
+ private static final String MIN_LONG_NAME = "minLong";
+
+ @NotNull
+ private String notNullString;
+
+ @NotNull
+ private Object notNullObject;
+
+ @NotBlank
+ private String notBlankString;
+
+ @NotBlank
+ private Object notBlankObject;
+
+ @Min(value = 10)
+ private long minLong;
+
@Test
public void testValidationOk() throws IOException {
TestParametersL00 l0Parameters = new TestParametersL00("l0Parameters");
@@ -50,11 +82,11 @@ public class TestValidation {
.replaceAll("\\s+", "");
assertEquals(expectedResult, validationResult.getResult("", " ", true).replaceAll("\\s+", ""));
}
-
+
@Test
public void testValidationObservation() throws IOException {
TestParametersL00 l0Parameters = new TestParametersL00("l0Parameters");
-
+
l0Parameters.triggerValidationStatus(ValidationStatus.OBSERVATION, 3);
String expectedResult = new String(Files.readAllBytes(
@@ -65,7 +97,7 @@ public class TestValidation {
assertTrue(validationResult.isValid());
assertFalse(validationResult.isClean());
assertEquals(expectedResult, validationResult.getResult().replaceAll("\\s+", ""));
-
+
l0Parameters.triggerValidationStatus(ValidationStatus.CLEAN, 3);
l0Parameters.triggerValidationStatus(ValidationStatus.OBSERVATION, 2);
@@ -76,7 +108,7 @@ public class TestValidation {
validationResult = l0Parameters.validate();
assertTrue(validationResult.isValid());
assertEquals(expectedResult, validationResult.getResult().replaceAll("\\s+", ""));
-
+
l0Parameters.triggerValidationStatus(ValidationStatus.CLEAN, 3);
l0Parameters.triggerValidationStatus(ValidationStatus.OBSERVATION, 1);
@@ -87,7 +119,7 @@ public class TestValidation {
validationResult = l0Parameters.validate();
assertTrue(validationResult.isValid());
assertEquals(expectedResult, validationResult.getResult().replaceAll("\\s+", ""));
-
+
l0Parameters.triggerValidationStatus(ValidationStatus.CLEAN, 3);
l0Parameters.triggerValidationStatus(ValidationStatus.OBSERVATION, 0);
@@ -95,11 +127,11 @@ public class TestValidation {
assertTrue(validationResult.isValid());
assertEquals(null, validationResult.getResult());
}
-
+
@Test
public void testValidationWarning() throws IOException {
TestParametersL00 l0Parameters = new TestParametersL00("l0Parameters");
-
+
l0Parameters.triggerValidationStatus(ValidationStatus.WARNING, 3);
String expectedResult = new String(Files.readAllBytes(
@@ -109,7 +141,7 @@ public class TestValidation {
GroupValidationResult validationResult = l0Parameters.validate();
assertTrue(validationResult.isValid());
assertEquals(expectedResult, validationResult.getResult().replaceAll("\\s+", ""));
-
+
l0Parameters.triggerValidationStatus(ValidationStatus.CLEAN, 3);
l0Parameters.triggerValidationStatus(ValidationStatus.WARNING, 2);
@@ -120,7 +152,7 @@ public class TestValidation {
validationResult = l0Parameters.validate();
assertTrue(validationResult.isValid());
assertEquals(expectedResult, validationResult.getResult().replaceAll("\\s+", ""));
-
+
l0Parameters.triggerValidationStatus(ValidationStatus.CLEAN, 3);
l0Parameters.triggerValidationStatus(ValidationStatus.WARNING, 1);
@@ -131,7 +163,7 @@ public class TestValidation {
validationResult = l0Parameters.validate();
assertTrue(validationResult.isValid());
assertEquals(expectedResult, validationResult.getResult().replaceAll("\\s+", ""));
-
+
l0Parameters.triggerValidationStatus(ValidationStatus.CLEAN, 3);
l0Parameters.triggerValidationStatus(ValidationStatus.WARNING, 0);
@@ -139,11 +171,11 @@ public class TestValidation {
assertTrue(validationResult.isValid());
assertEquals(null, validationResult.getResult());
}
-
+
@Test
public void testValidationInvalid() throws IOException {
TestParametersL00 l0Parameters = new TestParametersL00("l0Parameters");
-
+
l0Parameters.triggerValidationStatus(ValidationStatus.INVALID, 3);
String expectedResult = new String(Files.readAllBytes(
@@ -153,7 +185,7 @@ public class TestValidation {
GroupValidationResult validationResult = l0Parameters.validate();
assertFalse(validationResult.isValid());
assertEquals(expectedResult, validationResult.getResult().replaceAll("\\s+", ""));
-
+
l0Parameters.triggerValidationStatus(ValidationStatus.CLEAN, 3);
l0Parameters.triggerValidationStatus(ValidationStatus.INVALID, 2);
@@ -164,7 +196,7 @@ public class TestValidation {
validationResult = l0Parameters.validate();
assertFalse(validationResult.isValid());
assertEquals(expectedResult, validationResult.getResult().replaceAll("\\s+", ""));
-
+
l0Parameters.triggerValidationStatus(ValidationStatus.CLEAN, 3);
l0Parameters.triggerValidationStatus(ValidationStatus.INVALID, 1);
@@ -175,7 +207,7 @@ public class TestValidation {
validationResult = l0Parameters.validate();
assertFalse(validationResult.isValid());
assertEquals(expectedResult, validationResult.getResult().replaceAll("\\s+", ""));
-
+
l0Parameters.triggerValidationStatus(ValidationStatus.CLEAN, 3);
l0Parameters.triggerValidationStatus(ValidationStatus.INVALID, 0);
@@ -183,7 +215,7 @@ public class TestValidation {
assertTrue(validationResult.isValid());
assertEquals(null, validationResult.getResult());
}
-
+
@Test
public void testValidationEmptySubGroup() throws IOException {
TestParametersL10 l10Parameters = new TestParametersL10("l10Parameters");
@@ -192,7 +224,201 @@ public class TestValidation {
GroupValidationResult validationResult = l10Parameters.validate();
assertTrue(validationResult.isValid());
-
+
assertTrue(validationResult.getResult("", "", true).contains("UNDEFINED"));
}
+
+ @Test
+ public void testGetValidationResult() throws Exception {
+ Contained item = new Contained();
+ item.setName("item");
+
+ Container cont = new Container();
+ cont.item = item;
+ GroupValidationResult result = cont.validate();
+ assertEquals(ValidationStatus.INVALID, result.getStatus());
+ assertTrue(result.getResult().contains(">= 1"));
+
+ item.minInt = 1000;
+ result = cont.validate();
+ assertEquals(ValidationStatus.CLEAN, result.getStatus());
+
+ cont.item = null;
+ result = cont.validate();
+ assertEquals(ValidationStatus.INVALID, result.getStatus());
+ assertTrue(result.getResult().contains("is null"));
+ }
+
+ @Test
+ public void testParameterValidationResult_NotNull() throws Exception {
+ ParameterValidationResult result = new ParameterValidationResult(
+ TestValidation.class.getDeclaredField(NOT_NULL_STRING_NAME), null);
+ assertEquals(ValidationStatus.INVALID, result.getStatus());
+ assertEquals(NULL_STRING_MESSAGE, result.getResult());
+
+ // don't allow overwrite - values should remain unchanged
+ result.setResult(ValidationStatus.WARNING, "unknown");
+ assertEquals(ValidationStatus.INVALID, result.getStatus());
+ assertEquals(NULL_STRING_MESSAGE, result.getResult());
+
+ // non-null should be OK
+ result = new ParameterValidationResult(TestValidation.class.getDeclaredField(NOT_NULL_STRING_NAME), "");
+ assertEquals(ValidationStatus.CLEAN, result.getStatus());
+
+ // non-null should be OK
+ result = new ParameterValidationResult(TestValidation.class.getDeclaredField(NOT_NULL_STRING_NAME), "abc");
+ assertEquals(ValidationStatus.CLEAN, result.getStatus());
+
+ /*
+ * Check plain object fields, too.
+ */
+ result = new ParameterValidationResult(TestValidation.class.getDeclaredField(NOT_NULL_OBJECT_NAME), null);
+ assertEquals(ValidationStatus.INVALID, result.getStatus());
+ assertEquals("field 'notNullObject' type 'java.lang.Object' value 'null' INVALID, is null\n".replace('\'', '"'),
+ result.getResult());
+
+ // non-null should be OK
+ result = new ParameterValidationResult(TestValidation.class.getDeclaredField(NOT_NULL_OBJECT_NAME),
+ new Object());
+ assertEquals(ValidationStatus.CLEAN, result.getStatus());
+
+ /*
+ * Class-level annotation.
+ */
+
+ result = new ParameterValidationResult(NotNullSub.class.getDeclaredField(NOT_NULL_STRING_NAME), null);
+ assertEquals(ValidationStatus.INVALID, result.getStatus());
+ assertEquals(NULL_STRING_MESSAGE, result.getResult());
+
+ // non-null should be OK
+ result = new ParameterValidationResult(NotNullSub.class.getDeclaredField(NOT_NULL_STRING_NAME), "");
+ assertEquals(ValidationStatus.CLEAN, result.getStatus());
+ }
+
+ @Test
+ public void testParameterValidationResult_NotBlank() throws Exception {
+ ParameterValidationResult result =
+ new ParameterValidationResult(TestValidation.class.getDeclaredField(NOT_BLANK_STRING_NAME), "");
+ assertEquals(ValidationStatus.INVALID, result.getStatus());
+ assertEquals(NOT_BLANK_STRING_MESSAGE, result.getResult());
+
+ // spaces only
+ result = new ParameterValidationResult(TestValidation.class.getDeclaredField(NOT_BLANK_STRING_NAME), " \t");
+ assertEquals(ValidationStatus.INVALID, result.getStatus());
+
+ // null should be OK
+ result = new ParameterValidationResult(TestValidation.class.getDeclaredField(NOT_BLANK_STRING_NAME), null);
+ assertEquals(ValidationStatus.CLEAN, result.getStatus());
+
+ // null should be OK
+ result = new ParameterValidationResult(TestValidation.class.getDeclaredField(NOT_BLANK_STRING_NAME), "abc");
+ assertEquals(ValidationStatus.CLEAN, result.getStatus());
+
+ /*
+ * Check plain object fields, too.
+ */
+ result = new ParameterValidationResult(TestValidation.class.getDeclaredField(NOT_BLANK_OBJECT_NAME), null);
+ assertEquals(ValidationStatus.CLEAN, result.getStatus());
+
+ result = new ParameterValidationResult(TestValidation.class.getDeclaredField(NOT_BLANK_OBJECT_NAME),
+ new Object());
+ assertEquals(ValidationStatus.CLEAN, result.getStatus());
+
+ /*
+ * Class-level annotation.
+ */
+ result = new ParameterValidationResult(NotBlankSub.class.getDeclaredField(NOT_BLANK_STRING_NAME), "");
+ assertEquals(ValidationStatus.INVALID, result.getStatus());
+ assertEquals(NOT_BLANK_STRING_MESSAGE, result.getResult());
+
+ // non-null should be OK
+ result = new ParameterValidationResult(NotBlankSub.class.getDeclaredField(NOT_BLANK_STRING_NAME), "abc");
+ assertEquals(ValidationStatus.CLEAN, result.getStatus());
+ }
+
+ @Test
+ public void testParameterValidationResult_Min() throws Exception {
+ ParameterValidationResult result =
+ new ParameterValidationResult(TestValidation.class.getDeclaredField(MIN_LONG_NAME), 9L);
+ assertEquals(ValidationStatus.INVALID, result.getStatus());
+ assertEquals("field 'minLong' type 'long' value '9' INVALID, must be >= 10\n".replace('\'', '"'),
+ result.getResult());
+
+ result = new ParameterValidationResult(TestValidation.class.getDeclaredField(MIN_LONG_NAME), -2);
+ assertEquals(ValidationStatus.INVALID, result.getStatus());
+ assertEquals("field 'minLong' type 'long' value '-2' INVALID, must be >= 10\n".replace('\'', '"'),
+ result.getResult());
+
+ result = new ParameterValidationResult(TestValidation.class.getDeclaredField(MIN_LONG_NAME), 10L);
+ assertEquals(ValidationStatus.CLEAN, result.getStatus());
+
+ result = new ParameterValidationResult(TestValidation.class.getDeclaredField(MIN_LONG_NAME), 11);
+ assertEquals(ValidationStatus.CLEAN, result.getStatus());
+ }
+
+ // these classes are used to test class-level annotations
+
+ @NotNull
+ private static class NotNullBase {
+
+ }
+
+ private static class NotNullSub extends NotNullBase {
+ @SuppressWarnings("unused")
+ private String notNullString;
+ }
+
+ private static class NotBlankBase {
+
+ }
+
+ @NotBlank
+ private static class NotBlankSub extends NotBlankBase {
+ @SuppressWarnings("unused")
+ private String notBlankString;
+ }
+
+ private abstract static class SimpleGroup implements ParameterGroup {
+ private String name;
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public void setName(String name) {
+ this.name = name;
+ }
+ }
+
+ private static class Contained extends SimpleGroup {
+ @Min(value = 1)
+ private int minInt;
+
+ @Override
+ public GroupValidationResult validate() {
+ return new GroupValidationResult(this);
+ }
+
+ @SuppressWarnings("unused")
+ public int getMinInt() {
+ return minInt;
+ }
+ }
+
+ private static class Container extends SimpleGroup {
+ @NotNull
+ private Contained item;
+
+ @Override
+ public GroupValidationResult validate() {
+ return new GroupValidationResult(this);
+ }
+
+ @SuppressWarnings("unused")
+ public Contained getItem() {
+ return item;
+ }
+ }
}
diff --git a/common-parameters/src/test/java/org/onap/policy/common/parameters/testclasses/TestParametersLGeneric.java b/common-parameters/src/test/java/org/onap/policy/common/parameters/testclasses/TestParametersLGeneric.java
index 2d263fc7..1e5764c6 100644
--- a/common-parameters/src/test/java/org/onap/policy/common/parameters/testclasses/TestParametersLGeneric.java
+++ b/common-parameters/src/test/java/org/onap/policy/common/parameters/testclasses/TestParametersLGeneric.java
@@ -1,19 +1,20 @@
-/*-
+/*
* ============LICENSE_START=======================================================
* Copyright (C) 2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019 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.
- *
+ *
* SPDX-License-Identifier: Apache-2.0
* ============LICENSE_END=========================================================
*/
@@ -21,25 +22,28 @@
package org.onap.policy.common.parameters.testclasses;
import org.onap.policy.common.parameters.GroupValidationResult;
-import org.onap.policy.common.parameters.ParameterConstants;
import org.onap.policy.common.parameters.ParameterGroup;
import org.onap.policy.common.parameters.ValidationStatus;
+import org.onap.policy.common.parameters.annotations.NotBlank;
+import org.onap.policy.common.parameters.annotations.NotNull;
public class TestParametersLGeneric implements ParameterGroup {
private String name;
private int lgenericIntField = 0;
+
+ @NotNull @NotBlank
private String lgenericStringField = "Legal " + this.getClass().getCanonicalName();
-
+
/**
* Default constructor.
*/
public TestParametersLGeneric() {
// Default Constructor
}
-
+
/**
* Create a test parameter group.
- *
+ *
* @param name the parameter group name
*/
public TestParametersLGeneric(final String name) {
@@ -68,7 +72,7 @@ public class TestParametersLGeneric implements ParameterGroup {
/**
* Trigger a validation message.
- *
+ *
* @param level Number of levels to recurse before stopping
*/
public void triggerValidationStatus(final ValidationStatus triggerStatus, int level) {
@@ -111,18 +115,12 @@ public class TestParametersLGeneric implements ParameterGroup {
public GroupValidationResult validate() {
GroupValidationResult validationResult = new GroupValidationResult(this);
- if (lgenericStringField == null || lgenericStringField.trim().length() == 0) {
- validationResult.setResult("lgenericStringField", ValidationStatus.INVALID,
- "lgenericStringField must be a non-blank string");
- } else if (lgenericStringField.equals("lgenericStringField")) {
+ if ("lgenericStringField".equals(lgenericStringField)) {
validationResult.setResult("lgenericStringField", ValidationStatus.WARNING,
"using the field name for the parameter value is dangerous");
- } else if (lgenericStringField.equals("aString")) {
+ } else if ("aString".equals(lgenericStringField)) {
validationResult.setResult("lgenericStringField", ValidationStatus.OBSERVATION,
"this value for name is unhelpful");
- } else {
- validationResult.setResult("lgenericStringField", ValidationStatus.CLEAN,
- ParameterConstants.PARAMETER_HAS_STATUS_MESSAGE + ValidationStatus.CLEAN.toString());
}
if (lgenericIntField < 0) {
@@ -134,9 +132,6 @@ public class TestParametersLGeneric implements ParameterGroup {
} else if (lgenericIntField == 2) {
validationResult.setResult("lgenericIntField", ValidationStatus.OBSERVATION,
"this field has been set to 2");
- } else {
- validationResult.setResult("lgenericIntField", ValidationStatus.CLEAN,
- ParameterConstants.PARAMETER_HAS_STATUS_MESSAGE + ValidationStatus.CLEAN.toString());
}
return validationResult;
diff --git a/common-parameters/src/test/resources/expectedValidationResults/TestParametersL0_2_Invalid.txt b/common-parameters/src/test/resources/expectedValidationResults/TestParametersL0_2_Invalid.txt
index 0dec4a61..d9301997 100644
--- a/common-parameters/src/test/resources/expectedValidationResults/TestParametersL0_2_Invalid.txt
+++ b/common-parameters/src/test/resources/expectedValidationResults/TestParametersL0_2_Invalid.txt
@@ -6,11 +6,11 @@ parameter group "l0Parameters" type "org.onap.policy.common.parameters.testclass
field "l10StringField" type "java.lang.String" value "" INVALID, l10StringField must be a non-blank string
parameter group "l00LGenericNested" type "org.onap.policy.common.parameters.testclasses.TestParametersLGeneric" INVALID, parameter group has status INVALID
field "lgenericIntField" type "int" value "-1" INVALID, lgenericIntField must be a positive integer
- field "lgenericStringField" type "java.lang.String" value "" INVALID, lgenericStringField must be a non-blank string
+ field "lgenericStringField" type "java.lang.String" value "" INVALID, must be a non-blank string
parameter group map "l00LGenericNestedMap" INVALID, parameter group has status INVALID
parameter group "l00LGenericNestedMapVal0" type "org.onap.policy.common.parameters.testclasses.TestParametersLGeneric" INVALID, parameter group has status INVALID
field "lgenericIntField" type "int" value "-1" INVALID, lgenericIntField must be a positive integer
- field "lgenericStringField" type "java.lang.String" value "" INVALID, lgenericStringField must be a non-blank string
+ field "lgenericStringField" type "java.lang.String" value "" INVALID, must be a non-blank string
parameter group "l00LGenericNestedMapVal1" type "org.onap.policy.common.parameters.testclasses.TestParametersLGeneric" INVALID, parameter group has status INVALID
field "lgenericIntField" type "int" value "-1" INVALID, lgenericIntField must be a positive integer
- field "lgenericStringField" type "java.lang.String" value "" INVALID, lgenericStringField must be a non-blank string \ No newline at end of file
+ field "lgenericStringField" type "java.lang.String" value "" INVALID, must be a non-blank string \ No newline at end of file
diff --git a/common-parameters/src/test/resources/expectedValidationResults/TestParametersL0_3_Invalid.txt b/common-parameters/src/test/resources/expectedValidationResults/TestParametersL0_3_Invalid.txt
index 762ef46c..e45a7a6b 100644
--- a/common-parameters/src/test/resources/expectedValidationResults/TestParametersL0_3_Invalid.txt
+++ b/common-parameters/src/test/resources/expectedValidationResults/TestParametersL0_3_Invalid.txt
@@ -6,24 +6,24 @@ parameter group "l0Parameters" type "org.onap.policy.common.parameters.testclass
field "l10StringField" type "java.lang.String" value "" INVALID, l10StringField must be a non-blank string
parameter group "l10LGenericNested0" type "org.onap.policy.common.parameters.testclasses.TestParametersLGeneric" INVALID, parameter group has status INVALID
field "lgenericIntField" type "int" value "-1" INVALID, lgenericIntField must be a positive integer
- field "lgenericStringField" type "java.lang.String" value "" INVALID, lgenericStringField must be a non-blank string
+ field "lgenericStringField" type "java.lang.String" value "" INVALID, must be a non-blank string
parameter group "l10LGenericNested1" type "org.onap.policy.common.parameters.testclasses.TestParametersLGeneric" INVALID, parameter group has status INVALID
field "lgenericIntField" type "int" value "-1" INVALID, lgenericIntField must be a positive integer
- field "lgenericStringField" type "java.lang.String" value "" INVALID, lgenericStringField must be a non-blank string
+ field "lgenericStringField" type "java.lang.String" value "" INVALID, must be a non-blank string
parameter group map "l10LGenericNestedMap" INVALID, parameter group has status INVALID
parameter group "l10LGenericNestedMapVal0" type "org.onap.policy.common.parameters.testclasses.TestParametersLGeneric" INVALID, parameter group has status INVALID
field "lgenericIntField" type "int" value "-1" INVALID, lgenericIntField must be a positive integer
- field "lgenericStringField" type "java.lang.String" value "" INVALID, lgenericStringField must be a non-blank string
+ field "lgenericStringField" type "java.lang.String" value "" INVALID, must be a non-blank string
parameter group "l10LGenericNestedMapVal1" type "org.onap.policy.common.parameters.testclasses.TestParametersLGeneric" INVALID, parameter group has status INVALID
field "lgenericIntField" type "int" value "-1" INVALID, lgenericIntField must be a positive integer
- field "lgenericStringField" type "java.lang.String" value "" INVALID, lgenericStringField must be a non-blank string
+ field "lgenericStringField" type "java.lang.String" value "" INVALID, must be a non-blank string
parameter group "l00LGenericNested" type "org.onap.policy.common.parameters.testclasses.TestParametersLGeneric" INVALID, parameter group has status INVALID
field "lgenericIntField" type "int" value "-1" INVALID, lgenericIntField must be a positive integer
- field "lgenericStringField" type "java.lang.String" value "" INVALID, lgenericStringField must be a non-blank string
+ field "lgenericStringField" type "java.lang.String" value "" INVALID, must be a non-blank string
parameter group map "l00LGenericNestedMap" INVALID, parameter group has status INVALID
parameter group "l00LGenericNestedMapVal0" type "org.onap.policy.common.parameters.testclasses.TestParametersLGeneric" INVALID, parameter group has status INVALID
field "lgenericIntField" type "int" value "-1" INVALID, lgenericIntField must be a positive integer
- field "lgenericStringField" type "java.lang.String" value "" INVALID, lgenericStringField must be a non-blank string
+ field "lgenericStringField" type "java.lang.String" value "" INVALID, must be a non-blank string
parameter group "l00LGenericNestedMapVal1" type "org.onap.policy.common.parameters.testclasses.TestParametersLGeneric" INVALID, parameter group has status INVALID
field "lgenericIntField" type "int" value "-1" INVALID, lgenericIntField must be a positive integer
- field "lgenericStringField" type "java.lang.String" value "" INVALID, lgenericStringField must be a non-blank string \ No newline at end of file
+ field "lgenericStringField" type "java.lang.String" value "" INVALID, must be a non-blank string \ No newline at end of file
diff --git a/policy-endpoints/pom.xml b/policy-endpoints/pom.xml
index 1d8ae53c..53e2186f 100644
--- a/policy-endpoints/pom.xml
+++ b/policy-endpoints/pom.xml
@@ -19,7 +19,8 @@
============LICENSE_END=========================================================
-->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
@@ -205,6 +206,12 @@
<artifactId>openpojo</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.projectlombok</groupId>
+ <artifactId>lombok</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
</dependencies>
<build>
diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/client/TopicSinkClient.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/client/TopicSinkClient.java
new file mode 100644
index 00000000..3188b8d4
--- /dev/null
+++ b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/client/TopicSinkClient.java
@@ -0,0 +1,104 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP PAP
+ * ================================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * Modifications Copyright (C) 2019 Nordix Foundation.
+ * ================================================================================
+ * 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.endpoints.event.comm.client;
+
+
+import java.util.List;
+
+import lombok.Getter;
+
+import org.onap.policy.common.endpoints.event.comm.TopicEndpoint;
+import org.onap.policy.common.endpoints.event.comm.TopicSink;
+import org.onap.policy.common.utils.coder.Coder;
+import org.onap.policy.common.utils.coder.CoderException;
+import org.onap.policy.common.utils.coder.StandardCoder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Client for sending messages to a Topic using TopicSink.
+ */
+public class TopicSinkClient {
+ private static final Logger logger = LoggerFactory.getLogger(TopicSinkClient.class);
+
+ /**
+ * Coder used to encode messages being sent to the topic.
+ */
+ private static final Coder CODER = new StandardCoder();
+
+ /**
+ * Topic to which messages are published.
+ */
+ @Getter
+ private final String topic;
+
+ /**
+ * Where messages are published.
+ */
+ private final TopicSink sink;
+
+ /**
+ * Constructs the object.
+ *
+ * @param topic topic to which messages should be published
+ * @throws TopicSinkClientException if the topic does not exist
+ */
+ public TopicSinkClient(final String topic) throws TopicSinkClientException {
+ this.topic = topic;
+
+ final List<TopicSink> lst = getTopicSinks(topic);
+ if (lst.isEmpty()) {
+ throw new TopicSinkClientException("no sinks for topic: " + topic);
+ }
+
+ this.sink = lst.get(0);
+ }
+
+ /**
+ * Sends a message to the topic, after encoding the message as json.
+ *
+ * @param message message to be encoded and sent
+ * @return {@code true} if the message was successfully sent/enqueued, {@code false} otherwise
+ */
+ public boolean send(final Object message) {
+ try {
+ final String json = CODER.encode(message);
+ return sink.send(json);
+
+ } catch (RuntimeException | CoderException e) {
+ logger.warn("send to {} failed because of {}", topic, e.getMessage(), e);
+ return false;
+ }
+ }
+
+ // the remaining methods are wrappers that can be overridden by junit tests
+
+ /**
+ * Gets the sinks for a given topic.
+ *
+ * @param topic the topic of interest
+ * @return the sinks for the topic
+ */
+ protected List<TopicSink> getTopicSinks(final String topic) {
+ return TopicEndpoint.manager.getTopicSinks(topic);
+ }
+}
diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/client/TopicSinkClientException.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/client/TopicSinkClientException.java
new file mode 100644
index 00000000..608393b3
--- /dev/null
+++ b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/event/comm/client/TopicSinkClientException.java
@@ -0,0 +1,51 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP PAP
+ * ================================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * Modifications Copyright (C) 2019 Nordix Foundation.
+ * ================================================================================
+ * 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.endpoints.event.comm.client;
+
+/**
+ * Exception thrown by TopicSink client classes.
+ */
+public class TopicSinkClientException extends Exception {
+ private static final long serialVersionUID = 1L;
+
+ public TopicSinkClientException() {
+ super();
+ }
+
+ public TopicSinkClientException(final String message) {
+ super(message);
+ }
+
+ public TopicSinkClientException(final Throwable cause) {
+ super(cause);
+ }
+
+ public TopicSinkClientException(final String message, final Throwable cause) {
+ super(message, cause);
+ }
+
+ public TopicSinkClientException(final String message, final Throwable cause, final boolean enableSuppression,
+ final boolean writableStackTrace) {
+ super(message, cause, enableSuppression, writableStackTrace);
+ }
+
+}
diff --git a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/client/TopicSinkClientExceptionTest.java b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/client/TopicSinkClientExceptionTest.java
new file mode 100644
index 00000000..c0814703
--- /dev/null
+++ b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/client/TopicSinkClientExceptionTest.java
@@ -0,0 +1,35 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP PAP
+ * ================================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * Modifications Copyright (C) 2019 Nordix Foundation.
+ * ================================================================================
+ * 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.endpoints.event.comm.client;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+import org.onap.policy.common.utils.test.ExceptionsTester;
+
+public class TopicSinkClientExceptionTest {
+
+ @Test
+ public void test() {
+ assertEquals(5, new ExceptionsTester().test(TopicSinkClientException.class));
+ }
+}
diff --git a/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/client/TopicSinkClientTest.java b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/client/TopicSinkClientTest.java
new file mode 100644
index 00000000..725c0418
--- /dev/null
+++ b/policy-endpoints/src/test/java/org/onap/policy/common/endpoints/event/comm/client/TopicSinkClientTest.java
@@ -0,0 +1,150 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP PAP
+ * ================================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * Modifications Copyright (C) 2019 Nordix Foundation.
+ * ================================================================================
+ * 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.endpoints.event.comm.client;
+
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertSame;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Properties;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.internal.util.reflection.Whitebox;
+import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure;
+import org.onap.policy.common.endpoints.event.comm.TopicEndpoint;
+import org.onap.policy.common.endpoints.event.comm.TopicListener;
+import org.onap.policy.common.endpoints.event.comm.TopicSink;
+
+public class TopicSinkClientTest {
+ private static final String SINK_FIELD_NAME = "sink";
+ private static final String TOPIC = "my-topic";
+
+ private TopicSinkClient client;
+ private TopicSink sink;
+ private List<TopicSink> sinks;
+
+ /**
+ * Creates mocks and an initial client object.
+ *
+ * @throws Exception if an error occurs
+ */
+ @Before
+ public void setUp() throws Exception {
+ sink = mock(TopicSink.class);
+ when(sink.send(anyString())).thenReturn(true);
+
+ sinks = Arrays.asList(sink, null);
+
+ client = new TopicSinkClient2(TOPIC);
+ }
+
+ @AfterClass
+ public static void tearDown() throws Exception {
+ // clear all topics after the tests
+ TopicEndpoint.manager.shutdown();
+ }
+
+ /**
+ * Uses a real NO-OP topic sink.
+ */
+ @Test
+ public void testGetTopicSinks() throws Exception {
+ // clear all topics and then configure one topic
+ TopicEndpoint.manager.shutdown();
+
+ final Properties props = new Properties();
+ props.setProperty("noop.sink.topics", TOPIC);
+ TopicEndpoint.manager.addTopicSinks(props);
+
+ sink = TopicEndpoint.manager.getNoopTopicSink(TOPIC);
+ assertNotNull(sink);
+
+ final AtomicReference<String> evref = new AtomicReference<>(null);
+
+ sink.register(new TopicListener() {
+ @Override
+ public void onTopicEvent(final CommInfrastructure infra, final String topic, final String event) {
+ evref.set(event);
+ }
+ });
+
+ sink.start();
+
+ client = new TopicSinkClient(TOPIC);
+ client.send(100);
+
+ assertEquals("100", evref.get());
+ }
+
+ @Test
+ public void testTopicSinkClient_testGetTopic() {
+ assertEquals(TOPIC, client.getTopic());
+ assertSame(sink, Whitebox.getInternalState(client, SINK_FIELD_NAME));
+
+ // unknown topic -> should throw exception
+ sinks = new LinkedList<>();
+ assertThatThrownBy(() -> new TopicSinkClient2(TOPIC)).isInstanceOf(TopicSinkClientException.class)
+ .hasMessage("no sinks for topic: my-topic");
+ }
+
+ @Test
+ public void testSend() throws Exception {
+ client.send(Arrays.asList("abc", "def"));
+ verify(sink).send("['abc','def']".replace('\'', '"'));
+
+ // sink send fails
+ when(sink.send(anyString())).thenReturn(false);
+ assertFalse(client.send("ghi"));
+
+ // sink send throws an exception
+ final RuntimeException ex = new RuntimeException("expected exception");
+ when(sink.send(anyString())).thenThrow(ex);
+ assertFalse(client.send("jkl"));
+ }
+
+ /**
+ * TopicSinkClient with some overrides.
+ */
+ private class TopicSinkClient2 extends TopicSinkClient {
+
+ public TopicSinkClient2(final String topic) throws TopicSinkClientException {
+ super(topic);
+ }
+
+ @Override
+ protected List<TopicSink> getTopicSinks(final String topic) {
+ return sinks;
+ }
+ }
+}
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
deleted file mode 100644
index b41f3bc0..00000000
--- a/utils/src/main/java/org/onap/policy/common/utils/properties/PropertyConfiguration.java
+++ /dev/null
@@ -1,498 +0,0 @@
-/*
- * ============LICENSE_START=======================================================
- * ONAP Policy Engine - Common Modules
- * ================================================================================
- * Copyright (C) 2018-2019 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.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.Properties;
-import org.apache.commons.lang3.StringUtils;
-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. The values of the fields are set via <i>setXxx()</i> methods. As a result, if
- * a field is annotated and there is no corresponding <i>setXxx()</i> method, then an
- * exception will be thrown.
- *
- * <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);
-
- Method setter = getSetter(field, prop);
- checkSetter(setter, prop);
-
- if (setValue(setter, 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 setter method to be used to set the field's value
- * @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(Method setter, Field field, Properties props, Property prop) throws PropertyException {
-
- try {
- Object val = getValue(field, props, prop);
- if (val == null) {
- return false;
-
- } else {
- setter.invoke(this, val);
- return true;
- }
-
- } catch (IllegalArgumentException e) {
- throw new PropertyInvalidException(prop.name(), field.getName(), e);
-
- } catch (IllegalAccessException | InvocationTargetException e) {
- throw new PropertyAccessException(prop.name(), setter.getName(), e);
- }
- }
-
- /**
- * Get the setter.
- *
- * @param field field whose value is to be set
- * @param prop property of interest
- * @return the method to be used to set the field's value
- * @throws PropertyAccessException if a "set" method cannot be identified
- */
- private Method getSetter(Field field, Property prop) throws PropertyAccessException {
- String nm = "set" + StringUtils.capitalize(field.getName());
-
- try {
- return this.getClass().getMethod(nm, field.getType());
-
- } catch (NoSuchMethodException | SecurityException e) {
- throw new PropertyAccessException(prop.name(), nm, 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");
- }
- }
-
- /**
- * Verifies that the setter method is not <i>static</i>.
- *
- * @param setter method to be checked
- * @param prop property of interest
- * @throws PropertyAccessException if the method is static
- */
- private void checkSetter(Method setter, Property prop) throws PropertyAccessException {
- int mod = setter.getModifiers();
-
- if (Modifier.isStatic(mod)) {
- throw new PropertyAccessException(prop.name(), setter.getName(), "method is 'static'");
- }
- }
-
- /**
- * 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 the raw property value
- */
- 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".equalsIgnoreCase(value)) {
- return Boolean.TRUE;
-
- } else if ("false".equalsIgnoreCase(value)) {
- 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);
- }
- }
- }
-
- /**
- * 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/test/java/org/onap/policy/common/utils/properties/PropertyConfigurationTest.java b/utils/src/test/java/org/onap/policy/common/utils/properties/PropertyConfigurationTest.java
deleted file mode 100644
index dbe04aee..00000000
--- a/utils/src/test/java/org/onap/policy/common/utils/properties/PropertyConfigurationTest.java
+++ /dev/null
@@ -1,1268 +0,0 @@
-/*
- * ============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;
-
-/**
- * Test class for PropertyConfiguration.
- */
-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 {
- props.setProperty(THE_VALUE, STRING_VALUE);
-
- PlainStringConfig cfg = new PlainStringConfig();
- assertEquals(null, cfg.value);
-
- cfg.setAllFields(props);
- assertEquals(STRING_VALUE, cfg.value);
- }
-
- @Test
- public void testPropertyConfigurationProperties() throws PropertyException {
- props.setProperty(THE_VALUE, STRING_VALUE);
- PlainStringConfig cfg = new PlainStringConfig(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;
-
- @SuppressWarnings("unused")
- public void setGrandparentValue(boolean grandparentValue) {
- this.grandparentValue = grandparentValue;
- }
- }
-
- /*
- * Implements the extra interface, too.
- */
- class ParentConfig extends GrandParentConfig implements DoesNothing {
-
- @Property(name = "parent.value")
- protected long parentValue;
-
- @SuppressWarnings("unused")
- public void setParentValue(long parentValue) {
- this.parentValue = parentValue;
- }
- }
-
- class Config extends ParentConfig {
-
- @Property(name = THE_VALUE)
- private String value;
-
- @SuppressWarnings("unused")
- public void setValue(String value) {
- this.value = value;
- }
- }
-
-
- final 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;
-
- @SuppressWarnings("unused")
- public void setValue(String value) {
- this.value = 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 {
- props.setProperty(THE_VALUE, STRING_VALUE);
- PlainStringConfig cfg = new PlainStringConfig(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);
- }
-
- @SuppressWarnings("unused")
- public void setValue(String value) {
- this.value = value;
- }
- }
-
- 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);
- }
-
- @SuppressWarnings("unused")
- public void setValue(Exception value) {
- this.value = value;
- }
- }
-
- props.setProperty(THE_VALUE, STRING_VALUE);
- new Config(props);
- }
-
- @Test(expected = PropertyAccessException.class)
- public void testGetSetter_NoSetter() 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);
- new Config(props);
- }
-
- @Test(expected = PropertyMissingException.class)
- public void testSetValueMethodFieldPropertiesProperty_NoProperty_NoDefault() throws PropertyException {
- new PlainStringConfig(props);
- }
-
- @Test(expected = PropertyInvalidException.class)
- public void testSetValueMethodFieldPropertiesProperty_InvalidValue() throws PropertyException {
- class Config extends PlainPrimIntConfig {
-
- 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(expected = PropertyAccessException.class)
- public void testSetValueMethodFieldPropertiesProperty_MethodEx() throws PropertyException {
- class Config extends PlainStringConfig {
-
- public Config(Properties props) throws PropertyException {
- super(props);
- }
-
- @Override
- public void setValue(String value) {
- throw new IllegalArgumentException("expected exception");
- }
- }
-
- props.setProperty(THE_VALUE, STRING_VALUE);
- 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);
- }
-
- @SuppressWarnings("unused")
- public String getStringValue() {
- return stringValue;
- }
-
- @SuppressWarnings("unused")
- public void setStringValue(String stringValue) {
- this.stringValue = stringValue;
- }
-
- @SuppressWarnings("unused")
- public Boolean getBoolTrueValue() {
- return boolTrueValue;
- }
-
- @SuppressWarnings("unused")
- public void setBoolTrueValue(Boolean boolTrueValue) {
- this.boolTrueValue = boolTrueValue;
- }
-
- @SuppressWarnings("unused")
- public Boolean getBoolFalseValue() {
- return boolFalseValue;
- }
-
- @SuppressWarnings("unused")
- public void setBoolFalseValue(Boolean boolFalseValue) {
- this.boolFalseValue = boolFalseValue;
- }
-
- @SuppressWarnings("unused")
- public boolean isPrimBoolTrueValue() {
- return primBoolTrueValue;
- }
-
- @SuppressWarnings("unused")
- public void setPrimBoolTrueValue(boolean primBoolTrueValue) {
- this.primBoolTrueValue = primBoolTrueValue;
- }
-
- @SuppressWarnings("unused")
- public boolean isPrimBoolFalseValue() {
- return primBoolFalseValue;
- }
-
- @SuppressWarnings("unused")
- public void setPrimBoolFalseValue(boolean primBoolFalseValue) {
- this.primBoolFalseValue = primBoolFalseValue;
- }
-
- @SuppressWarnings("unused")
- public Integer getIntValue() {
- return intValue;
- }
-
- @SuppressWarnings("unused")
- public void setIntValue(Integer intValue) {
- this.intValue = intValue;
- }
-
- @SuppressWarnings("unused")
- public int getPrimIntValue() {
- return primIntValue;
- }
-
- @SuppressWarnings("unused")
- public void setPrimIntValue(int primIntValue) {
- this.primIntValue = primIntValue;
- }
-
- @SuppressWarnings("unused")
- public Long getLongValue() {
- return longValue;
- }
-
- @SuppressWarnings("unused")
- public void setLongValue(Long longValue) {
- this.longValue = longValue;
- }
-
- @SuppressWarnings("unused")
- public long getPrimLongValue() {
- return primLongValue;
- }
-
- @SuppressWarnings("unused")
- public void setPrimLongValue(long primLongValue) {
- this.primLongValue = primLongValue;
- }
- }
-
- 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);
- }
-
- @SuppressWarnings("unused")
- public void setValue(Exception value) {
- this.value = value;
- }
- }
-
- 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);
- }
-
- @SuppressWarnings("unused")
- public void setPublicString(String publicString) {
- this.publicString = publicString;
- }
-
- @SuppressWarnings("unused")
- public void setPrivateString(String privateString) {
- this.privateString = privateString;
- }
-
- @SuppressWarnings("unused")
- public void setProtectedString(String protectedString) {
- this.protectedString = protectedString;
- }
- }
-
- 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 StaticPropConfig(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(expected = PropertyAccessException.class)
- public void testCheckSetter_Static() throws PropertyException {
- props.setProperty(THE_VALUE, STRING_VALUE);
- new StaticMethodConfig(props);
- }
-
- @Test
- public void testGetStringValue() throws PropertyException {
- props.setProperty(THE_VALUE, STRING_VALUE);
- PlainStringConfig cfg = new PlainStringConfig(props);
-
- assertEquals(STRING_VALUE, cfg.value);
- }
-
- @Test
- public void testGetBooleanValue_NoDefault() throws PropertyException {
- props.setProperty(THE_VALUE, "true");
- PlainBooleanConfig cfg = new PlainBooleanConfig(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);
- }
-
- @SuppressWarnings("unused")
- public void setValue(Boolean value) {
- this.value = value;
- }
- }
-
- 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);
- }
-
- @SuppressWarnings("unused")
- public void setValue(Boolean value) {
- this.value = value;
- }
- }
-
- // 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);
- }
-
- @SuppressWarnings("unused")
- public void setValue(Boolean value) {
- this.value = value;
- }
- }
-
- // 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);
- }
-
- @SuppressWarnings("unused")
- public void setValue(Integer value) {
- this.value = value;
- }
- }
-
- 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);
- }
-
- @SuppressWarnings("unused")
- public void setValue(Integer value) {
- this.value = value;
- }
- }
-
- 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);
- }
-
- @SuppressWarnings("unused")
- public void setValue(Integer value) {
- this.value = value;
- }
- }
-
- // 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);
- }
-
- @SuppressWarnings("unused")
- public void setValue(Long value) {
- this.value = value;
- }
- }
-
- 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);
- }
-
- @SuppressWarnings("unused")
- public void setValue(Long value) {
- this.value = value;
- }
- }
-
- 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);
- }
-
- @SuppressWarnings("unused")
- public void setValue(Long value) {
- this.value = value;
- }
- }
-
- // 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 {
- props.setProperty(THE_VALUE, STRING_VALUE);
- PlainStringConfig cfg = new PlainStringConfig(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);
- }
-
- @SuppressWarnings("unused")
- public void setValue(String value) {
- this.value = value;
- }
- }
-
- 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);
- }
-
- @SuppressWarnings("unused")
- public void setValue(String value) {
- this.value = value;
- }
- }
-
- 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);
- }
-
- @SuppressWarnings("unused")
- public void setValue(String value) {
- this.value = value;
- }
- }
-
- 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);
- }
-
- @SuppressWarnings("unused")
- public void setValue(String value) {
- this.value = value;
- }
- }
-
- 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);
- }
-
- @SuppressWarnings("unused")
- public void setValue(String value) {
- this.value = value;
- }
- }
-
- 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);
- }
-
- @SuppressWarnings("unused")
- public void setValue(String value) {
- this.value = value;
- }
- }
-
- Config cfg = new Config(props);
-
- assertEquals(STRING_VALUE, cfg.value);
- }
-
- @Test
- public void testGetRawPropertyValue() throws PropertyException {
- class Config extends PlainStringConfig {
-
- 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.getValue());
-
- }
-
- @Test
- public void testMakeBoolean_True() throws PropertyException {
- props.setProperty(THE_VALUE, "true");
- PlainBooleanConfig cfg = new PlainBooleanConfig(props);
-
- assertEquals(true, cfg.value);
- }
-
- @Test
- public void testMakeBoolean_False() throws PropertyException {
- props.setProperty(THE_VALUE, "false");
- PlainBooleanConfig cfg = new PlainBooleanConfig(props);
-
- assertEquals(false, cfg.value);
- }
-
- @Test(expected = PropertyInvalidException.class)
- public void testMakeBoolean_Invalid() throws PropertyException {
- props.setProperty(THE_VALUE, INVALID_VALUE);
- new PlainBooleanConfig(props);
- }
-
- @Test
- public void testMakeInteger_Valid() throws PropertyException {
- props.setProperty(THE_VALUE, "300");
- PlainPrimIntConfig cfg = new PlainPrimIntConfig(props);
-
- assertEquals(300, cfg.value);
- }
-
- @Test(expected = PropertyInvalidException.class)
- public void testMakeInteger_Invalid() throws PropertyException {
- props.setProperty(THE_VALUE, INVALID_VALUE);
- new PlainPrimIntConfig(props);
- }
-
- @Test(expected = PropertyInvalidException.class)
- public void testMakeInteger_TooBig() throws PropertyException {
- props.setProperty(THE_VALUE, String.valueOf(Integer.MAX_VALUE + 10L));
- new PlainPrimIntConfig(props);
- }
-
- @Test
- public void testMakeLong_Valid() throws PropertyException {
- props.setProperty(THE_VALUE, "30000");
- PlainPrimLongConfig cfg = new PlainPrimLongConfig(props);
-
- assertEquals(30000L, cfg.value);
- }
-
- @Test(expected = PropertyInvalidException.class)
- public void testMakeLong_Invalid() throws PropertyException {
- props.setProperty(THE_VALUE, INVALID_VALUE);
- new PlainPrimLongConfig(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);
- }
-
- @SuppressWarnings("unused")
- public void setValue(long value) {
- this.value = value;
- }
- }
-
- 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);
- }
-
- @SuppressWarnings("unused")
- public void setValue(long value) {
- this.value = value;
- }
- }
-
- 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);
- }
-
- @SuppressWarnings("unused")
- public void setValue(long value) {
- this.value = value;
- }
- }
-
- 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);
- }
-
- @SuppressWarnings("unused")
- public void setValue(String value) {
- this.value = value;
- }
- }
-
- // 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);
- }
-
- @SuppressWarnings("unused")
- public void setValue(long value) {
- this.value = value;
- }
- }
-
- 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);
- }
-
- @SuppressWarnings("unused")
- public void setValue(String value) {
- this.value = value;
- }
- }
-
- 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);
- }
-
- @SuppressWarnings("unused")
- public void setValue(long value) {
- this.value = value;
- }
- }
-
- new Config(props);
- }
-
- /**
- * Config with a String value having no qualifiers.
- */
- public class PlainStringConfig extends PropertyConfiguration {
-
- @Property(name = THE_VALUE)
- private String value;
-
- public PlainStringConfig() {
-
- }
-
- public PlainStringConfig(Properties props) throws PropertyException {
- super(props);
- }
-
- public String getValue() {
- return value;
- }
-
- public void setValue(String value) {
- this.value = value;
- }
- }
-
- /**
- * Config with a Boolean value having no qualifiers.
- */
- public class PlainBooleanConfig extends PropertyConfiguration {
-
- @Property(name = THE_VALUE)
- private Boolean value;
-
- public PlainBooleanConfig(Properties props) throws PropertyException {
- super(props);
- }
-
- public void setValue(Boolean value) {
- this.value = value;
- }
- }
-
- /**
- * Config with an int value having no qualifiers.
- */
- public class PlainPrimIntConfig extends PropertyConfiguration {
-
- @Property(name = THE_VALUE)
- private int value;
-
- public PlainPrimIntConfig(Properties props) throws PropertyException {
- super(props);
- }
-
- public void setValue(int value) {
- this.value = value;
- }
- }
-
- /**
- * Config with a long value having no qualifiers.
- */
- public class PlainPrimLongConfig extends PropertyConfiguration {
-
- @Property(name = THE_VALUE)
- private long value;
-
- public PlainPrimLongConfig(Properties props) throws PropertyException {
- super(props);
- }
-
- public void setValue(long value) {
- this.value = value;
- }
- }
-
- /**
- * A config whose field is "static".
- */
- public static class StaticPropConfig extends PropertyConfiguration {
-
- // "static" field cannot be set
- @Property(name = THE_VALUE)
- private static String value;
-
- public StaticPropConfig(Properties props) throws PropertyException {
- super(props);
- }
-
- public static void setValue(String value) {
- StaticPropConfig.value = value;
- }
- }
-
- /**
- * A config whose method is "static".
- */
- public static class StaticMethodConfig extends PropertyConfiguration {
-
- // "static" field cannot be set
- @Property(name = THE_VALUE)
- private String value;
-
- public StaticMethodConfig(Properties props) throws PropertyException {
- super(props);
- }
-
- public static void setValue(String value) {
-
- }
- }
-
- /**
- * This is just used as a mix-in to ensure that the configuration ignores interfaces.
- */
- public static interface DoesNothing {
-
- }
-}