From b79939366cef7a99fca6851e7e07619cb370e2b8 Mon Sep 17 00:00:00 2001 From: liamfallon Date: Wed, 19 Dec 2018 19:14:35 +0000 Subject: Add support for parameter inheritance Common parameter support does not allow for inheritance of parameters from a super class. This change allows inheritance of public and protected members from a parameter superclass to a parameter subclass. Issue-ID: POLICY-1222 Change-Id: Ia4f452abab80953b41784c44e4202e8d5405a197 Signed-off-by: liamfallon (cherry picked from commit 7b150f6820d61b8c65b6ddd5f4952ad3d4d17c6c) --- .../common/parameters/GroupValidationResult.java | 78 ++++++++++++++++------ .../http/server/HttpServletServerFactory.java | 78 +++++++++------------- 2 files changed, 92 insertions(+), 64 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 5beef5b1..283f36b9 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 @@ -25,8 +25,10 @@ import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; +import java.util.ArrayList; import java.util.Collection; import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -59,23 +61,24 @@ public class GroupValidationResult implements ValidationResult { return; } - // Add a validation result per field + // Add a validation result for all fields in the declared class for (Field field : parameterGroup.getClass().getDeclaredFields()) { - // Exclude system fields - if (field.getName().startsWith("$") || field.getName().startsWith("_")) { - continue; + // 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)); } + } - // Exclude static fields - if (Modifier.isStatic(field.getModifiers())) { - continue; + // Add a validation result for protected and public fields in super classes + for (Field field : getSuperclassFields(parameterGroup.getClass().getSuperclass())) { + // 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)); } - - // Set the validation result - validationResultMap.put(field.getName(), getValidationResult(field, parameterGroup)); } } - /** * Construct a validation result for a field. * @@ -139,7 +142,7 @@ public class GroupValidationResult implements ValidationResult { getterMethod = targetObject.getClass().getMethod(getterMethodName, (Class[]) null); } catch (NoSuchMethodException | SecurityException e) { throw new ParameterRuntimeException("could not get getter method for parameter \"" + field.getName() + "\"", - e); + e); } // Invoke the getter @@ -147,7 +150,7 @@ public class GroupValidationResult implements ValidationResult { return getterMethod.invoke(targetObject, (Object[]) null); } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { throw new ParameterRuntimeException("error calling getter method for parameter \"" + field.getName() + "\"", - e); + e); } } @@ -168,13 +171,13 @@ public class GroupValidationResult implements ValidationResult { // Check the key is a string if (!String.class.isAssignableFrom(mapEntry.getKey().getClass())) { throw new ParameterRuntimeException("map entry is not a parameter group keyed by a string, key \"" - + mapEntry.getKey() + "\" in map \"" + fieldName + "\" is not a string"); + + mapEntry.getKey() + "\" in map \"" + fieldName + "\" is not a string"); } // Check the value is a parameter group if (!ParameterGroup.class.isAssignableFrom(mapEntry.getValue().getClass())) { throw new ParameterRuntimeException("map entry is not a parameter group keyed by a string, value \"" - + mapEntry.getValue() + "\" in map \"" + fieldName + "\" is not a parameter group"); + + mapEntry.getValue() + "\" in map \"" + fieldName + "\" is not a parameter group"); } } } @@ -195,7 +198,7 @@ public class GroupValidationResult implements ValidationResult { for (Object collectionMember : collection2Check) { if (ParameterGroup.class.isAssignableFrom(collectionMember.getClass())) { throw new ParameterRuntimeException("collection parameter \"" + fieldName + "\" is illegal," - + " parameter groups are not allowed as collection members"); + + " parameter groups are not allowed as collection members"); } } } @@ -307,7 +310,7 @@ public class GroupValidationResult implements ValidationResult { * @param nestedMapValidationResult The validation result from a nested map entry */ public void setResult(final String parameterName, final String key, - final ValidationResult nestedMapValidationResult) { + final ValidationResult nestedMapValidationResult) { GroupMapValidationResult groupMapValidationResult; try { groupMapValidationResult = (GroupMapValidationResult) validationResultMap.get(parameterName); @@ -333,7 +336,7 @@ public class GroupValidationResult implements ValidationResult { * @param message The message for the parameter group */ public void setResult(final String parameterName, final String key, final ValidationStatus status, - final String message) { + final String message) { GroupMapValidationResult groupMapValidationResult; try { groupMapValidationResult = (GroupMapValidationResult) validationResultMap.get(parameterName); @@ -384,7 +387,7 @@ public class GroupValidationResult implements ValidationResult { for (ValidationResult fieldResult : validationResultMap.values()) { String fieldResultMessage = fieldResult.getResult(initialIndentation + subIndentation, subIndentation, - showClean); + showClean); if (fieldResultMessage != null) { validationResultBuilder.append(fieldResultMessage); } @@ -392,4 +395,41 @@ 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 + */ + private boolean isIncludedField(final Field field) { + return !field.getName().startsWith("$") && !field.getName().startsWith("_") + && !Modifier.isStatic(field.getModifiers()); + } + + /** + * Get the public and protected fields of super classes. + * @param firstSuperClass the first superclass to check + * + * @return a set of the superclass fields + */ + private List getSuperclassFields(final Class firstSuperClass) { + List superclassFields = new ArrayList<>(); + + Class currentClass = firstSuperClass; + while (currentClass.getSuperclass() != null) { + for (Field field : currentClass.getDeclaredFields()) { + // Check if this field is public or protected + if (Modifier.isPublic(field.getModifiers()) || Modifier.isProtected(field.getModifiers())) { + superclassFields.add(field); + } + } + + // Check the next super class down + currentClass = currentClass.getSuperclass(); + } + + return superclassFields; + } } \ No newline at end of file diff --git a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/server/HttpServletServerFactory.java b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/server/HttpServletServerFactory.java index 4a33f568..527ada99 100644 --- a/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/server/HttpServletServerFactory.java +++ b/policy-endpoints/src/main/java/org/onap/policy/common/endpoints/http/server/HttpServletServerFactory.java @@ -25,7 +25,6 @@ import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Properties; -import org.onap.aaf.cadi.filter.CadiFilter; import org.onap.policy.common.endpoints.http.server.internal.JettyJerseyServer; import org.onap.policy.common.endpoints.properties.PolicyEndPointProperties; import org.slf4j.Logger; @@ -50,7 +49,7 @@ public interface HttpServletServerFactory { * @throws IllegalArgumentException when invalid parameters are provided */ HttpServletServer build(String name, boolean https, String host, int port, String contextPath, boolean swagger, - boolean managed); + boolean managed); /** * Builds an http server with support for servlets. @@ -64,8 +63,7 @@ public interface HttpServletServerFactory { * @return http server * @throws IllegalArgumentException when invalid parameters are provided */ - HttpServletServer build(String name, String host, int port, String contextPath, boolean swagger, - boolean managed); + HttpServletServer build(String name, String host, int port, String contextPath, boolean swagger, boolean managed); /** * Build a list of http servers per properties. @@ -104,7 +102,6 @@ public interface HttpServletServerFactory { void destroy(); } - /** * Indexed factory implementation. */ @@ -123,9 +120,8 @@ class IndexedHttpServletServerFactory implements HttpServletServerFactory { protected HashMap servers = new HashMap<>(); @Override - public synchronized HttpServletServer build(String name, boolean https, - String host, int port, String contextPath, boolean swagger, - boolean managed) { + public synchronized HttpServletServer build(String name, boolean https, String host, int port, String contextPath, + boolean swagger, boolean managed) { if (servers.containsKey(port)) { return servers.get(port); @@ -140,12 +136,11 @@ class IndexedHttpServletServerFactory implements HttpServletServerFactory { } @Override - public synchronized HttpServletServer build(String name, String host, int port, String contextPath, - boolean swagger, boolean managed) { + public synchronized HttpServletServer build(String name, String host, int port, String contextPath, boolean swagger, + boolean managed) { return build(name, false, host, port, contextPath, swagger, managed); } - @Override public synchronized List build(Properties properties) { @@ -161,7 +156,7 @@ class IndexedHttpServletServerFactory implements HttpServletServerFactory { for (String serviceName : serviceNameList) { String servicePortString = properties.getProperty(PolicyEndPointProperties.PROPERTY_HTTP_SERVER_SERVICES - + "." + serviceName + PolicyEndPointProperties.PROPERTY_HTTP_PORT_SUFFIX); + + "." + serviceName + PolicyEndPointProperties.PROPERTY_HTTP_PORT_SUFFIX); int servicePort; try { @@ -180,48 +175,41 @@ class IndexedHttpServletServerFactory implements HttpServletServerFactory { } final String hostName = properties.getProperty(PolicyEndPointProperties.PROPERTY_HTTP_SERVER_SERVICES + "." - + serviceName + PolicyEndPointProperties.PROPERTY_HTTP_HOST_SUFFIX); + + serviceName + PolicyEndPointProperties.PROPERTY_HTTP_HOST_SUFFIX); - final String contextUriPath = properties.getProperty( - PolicyEndPointProperties.PROPERTY_HTTP_SERVER_SERVICES + "." - + serviceName + PolicyEndPointProperties.PROPERTY_HTTP_CONTEXT_URIPATH_SUFFIX); + final String contextUriPath = properties.getProperty(PolicyEndPointProperties.PROPERTY_HTTP_SERVER_SERVICES + + "." + serviceName + PolicyEndPointProperties.PROPERTY_HTTP_CONTEXT_URIPATH_SUFFIX); final String userName = properties.getProperty(PolicyEndPointProperties.PROPERTY_HTTP_SERVER_SERVICES + "." - + serviceName + PolicyEndPointProperties.PROPERTY_HTTP_AUTH_USERNAME_SUFFIX); + + serviceName + PolicyEndPointProperties.PROPERTY_HTTP_AUTH_USERNAME_SUFFIX); final String password = properties.getProperty(PolicyEndPointProperties.PROPERTY_HTTP_SERVER_SERVICES + "." - + serviceName + PolicyEndPointProperties.PROPERTY_HTTP_AUTH_PASSWORD_SUFFIX); - - final String authUriPath = properties.getProperty( - PolicyEndPointProperties.PROPERTY_HTTP_SERVER_SERVICES + "." - + serviceName + PolicyEndPointProperties.PROPERTY_HTTP_AUTH_URIPATH_SUFFIX); - - final String restClasses = properties.getProperty( - PolicyEndPointProperties.PROPERTY_HTTP_SERVER_SERVICES + "." - + serviceName + PolicyEndPointProperties.PROPERTY_HTTP_REST_CLASSES_SUFFIX); - - final String filterClasses = properties.getProperty( - PolicyEndPointProperties.PROPERTY_HTTP_SERVER_SERVICES + "." - + serviceName + PolicyEndPointProperties.PROPERTY_HTTP_FILTER_CLASSES_SUFFIX); - - final String restPackages = properties.getProperty( - PolicyEndPointProperties.PROPERTY_HTTP_SERVER_SERVICES + "." - + serviceName + PolicyEndPointProperties.PROPERTY_HTTP_REST_PACKAGES_SUFFIX); - - final String restUriPath = properties.getProperty( - PolicyEndPointProperties.PROPERTY_HTTP_SERVER_SERVICES + "." - + serviceName + PolicyEndPointProperties.PROPERTY_HTTP_REST_URIPATH_SUFFIX); - - final String managedString = properties.getProperty( - PolicyEndPointProperties.PROPERTY_HTTP_SERVER_SERVICES + "." - + serviceName + PolicyEndPointProperties.PROPERTY_MANAGED_SUFFIX); + + serviceName + PolicyEndPointProperties.PROPERTY_HTTP_AUTH_PASSWORD_SUFFIX); + + final String authUriPath = properties.getProperty(PolicyEndPointProperties.PROPERTY_HTTP_SERVER_SERVICES + + "." + serviceName + PolicyEndPointProperties.PROPERTY_HTTP_AUTH_URIPATH_SUFFIX); + + final String restClasses = properties.getProperty(PolicyEndPointProperties.PROPERTY_HTTP_SERVER_SERVICES + + "." + serviceName + PolicyEndPointProperties.PROPERTY_HTTP_REST_CLASSES_SUFFIX); + + final String filterClasses = properties.getProperty(PolicyEndPointProperties.PROPERTY_HTTP_SERVER_SERVICES + + "." + serviceName + PolicyEndPointProperties.PROPERTY_HTTP_FILTER_CLASSES_SUFFIX); + + final String restPackages = properties.getProperty(PolicyEndPointProperties.PROPERTY_HTTP_SERVER_SERVICES + + "." + serviceName + PolicyEndPointProperties.PROPERTY_HTTP_REST_PACKAGES_SUFFIX); + + final String restUriPath = properties.getProperty(PolicyEndPointProperties.PROPERTY_HTTP_SERVER_SERVICES + + "." + serviceName + PolicyEndPointProperties.PROPERTY_HTTP_REST_URIPATH_SUFFIX); + + final String managedString = properties.getProperty(PolicyEndPointProperties.PROPERTY_HTTP_SERVER_SERVICES + + "." + serviceName + PolicyEndPointProperties.PROPERTY_MANAGED_SUFFIX); boolean managed = true; if (managedString != null && !managedString.isEmpty()) { managed = Boolean.parseBoolean(managedString); } String swaggerString = properties.getProperty(PolicyEndPointProperties.PROPERTY_HTTP_SERVER_SERVICES + "." - + serviceName + PolicyEndPointProperties.PROPERTY_HTTP_SWAGGER_SUFFIX); + + serviceName + PolicyEndPointProperties.PROPERTY_HTTP_SWAGGER_SUFFIX); boolean swagger = false; if (swaggerString != null && !swaggerString.isEmpty()) { swagger = Boolean.parseBoolean(swaggerString); @@ -241,8 +229,8 @@ class IndexedHttpServletServerFactory implements HttpServletServerFactory { aaf = Boolean.parseBoolean(aafString); } - HttpServletServer service = build(serviceName, https, hostName, servicePort, - contextUriPath, swagger, managed); + HttpServletServer service = build(serviceName, https, hostName, servicePort, contextUriPath, swagger, + managed); /* authentication method either AAF or HTTP Basic Auth */ -- cgit 1.2.3-korg