diff options
author | adheli.tavares <adheli.tavares@est.tech> | 2024-09-10 09:17:27 +0100 |
---|---|---|
committer | adheli.tavares <adheli.tavares@est.tech> | 2024-09-12 11:42:16 +0100 |
commit | 8ea8fb5c9cfcf82f5f1fcdabbf8751add12a9fa8 (patch) | |
tree | 0f07961aa094378f80313ab8f2ddb3a40ec091fb /policy-management/src/main | |
parent | 3b11f334df61e239c2a3e14b28afd0dc0e55153b (diff) |
Increase code coverage in policy-management
Issue-ID: POLICY-5068
Change-Id: Ie7ac44a948fe559306b1aa3a403d888c352be7f2
Signed-off-by: adheli.tavares <adheli.tavares@est.tech>
Diffstat (limited to 'policy-management/src/main')
10 files changed, 186 insertions, 315 deletions
diff --git a/policy-management/src/main/java/org/onap/policy/drools/controller/IndexedDroolsControllerFactory.java b/policy-management/src/main/java/org/onap/policy/drools/controller/IndexedDroolsControllerFactory.java index 7f28f9bb..a6459d67 100644 --- a/policy-management/src/main/java/org/onap/policy/drools/controller/IndexedDroolsControllerFactory.java +++ b/policy-management/src/main/java/org/onap/policy/drools/controller/IndexedDroolsControllerFactory.java @@ -28,6 +28,7 @@ import java.util.List; import java.util.Map; import java.util.Properties; import lombok.NonNull; +import org.apache.commons.lang3.StringUtils; import org.onap.policy.common.endpoints.event.comm.Topic; import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure; import org.onap.policy.common.endpoints.event.comm.TopicSink; @@ -62,7 +63,7 @@ class IndexedDroolsControllerFactory implements DroolsControllerFactory { /** * Null Drools Controller. */ - protected NullDroolsController nullDroolsController = new NullDroolsController(); + protected NullDroolsController nullDroolsController; /** * Constructs the object. @@ -71,11 +72,11 @@ class IndexedDroolsControllerFactory implements DroolsControllerFactory { /* Add a NULL controller which will always be present in the hash */ - DroolsController controller = new NullDroolsController(); - String controllerId = controller.getGroupId() + ":" + controller.getArtifactId(); + nullDroolsController = new NullDroolsController(); + String controllerId = nullDroolsController.getGroupId() + ":" + nullDroolsController.getArtifactId(); synchronized (this) { - droolsControllers.put(controllerId, controller); + droolsControllers.put(controllerId, nullDroolsController); } } @@ -84,17 +85,17 @@ class IndexedDroolsControllerFactory implements DroolsControllerFactory { List<? extends TopicSink> eventSinks) throws LinkageError { String groupId = properties.getProperty(DroolsPropertyConstants.RULES_GROUPID); - if (groupId == null || groupId.isEmpty()) { + if (StringUtils.isBlank(groupId)) { groupId = DroolsControllerConstants.NO_GROUP_ID; } String artifactId = properties.getProperty(DroolsPropertyConstants.RULES_ARTIFACTID); - if (artifactId == null || artifactId.isEmpty()) { + if (StringUtils.isBlank(artifactId)) { artifactId = DroolsControllerConstants.NO_ARTIFACT_ID; } String version = properties.getProperty(DroolsPropertyConstants.RULES_VERSION); - if (version == null || version.isEmpty()) { + if (StringUtils.isBlank(version)) { version = DroolsControllerConstants.NO_VERSION; } @@ -110,15 +111,15 @@ class IndexedDroolsControllerFactory implements DroolsControllerFactory { List<TopicCoderFilterConfiguration> decoderConfigurations, List<TopicCoderFilterConfiguration> encoderConfigurations) throws LinkageError { - if (newGroupId == null || newGroupId.isEmpty()) { + if (StringUtils.isBlank(newGroupId)) { throw new IllegalArgumentException("Missing maven group-id coordinate"); } - if (newArtifactId == null || newArtifactId.isEmpty()) { + if (StringUtils.isBlank(newArtifactId)) { throw new IllegalArgumentException("Missing maven artifact-id coordinate"); } - if (newVersion == null || newVersion.isEmpty()) { + if (StringUtils.isBlank(newVersion)) { throw new IllegalArgumentException("Missing maven version coordinate"); } @@ -240,7 +241,7 @@ class IndexedDroolsControllerFactory implements DroolsControllerFactory { String eventClasses = properties .getProperty(propertyTopicEntityPrefix + PolicyEndPointProperties.PROPERTY_TOPIC_EVENTS_SUFFIX); - if (eventClasses == null || eventClasses.isEmpty()) { + if (StringUtils.isBlank(eventClasses)) { logger.warn("There are no event classes for topic {}", firstTopic); continue; } @@ -280,7 +281,7 @@ class IndexedDroolsControllerFactory implements DroolsControllerFactory { + PolicyEndPointProperties.PROPERTY_TOPIC_EVENTS_CUSTOM_MODEL_CODER_GSON_SUFFIX); CustomGsonCoder customGsonCoder = null; - if (customGson != null && !customGson.isEmpty()) { + if (StringUtils.isNotBlank(customGson)) { try { customGsonCoder = new CustomGsonCoder(customGson); } catch (IllegalArgumentException e) { @@ -375,7 +376,7 @@ class IndexedDroolsControllerFactory implements DroolsControllerFactory { @Override public DroolsController get(String groupId, String artifactId, String version) { - if (groupId == null || artifactId == null || groupId.isEmpty() || artifactId.isEmpty()) { + if (StringUtils.isBlank(groupId) || StringUtils.isBlank(artifactId)) { throw new IllegalArgumentException("Missing maven coordinates: " + groupId + ":" + artifactId); } diff --git a/policy-management/src/main/java/org/onap/policy/drools/controller/internal/MavenDroolsController.java b/policy-management/src/main/java/org/onap/policy/drools/controller/internal/MavenDroolsController.java index 68a69159..aa701dfd 100644 --- a/policy-management/src/main/java/org/onap/policy/drools/controller/internal/MavenDroolsController.java +++ b/policy-management/src/main/java/org/onap/policy/drools/controller/internal/MavenDroolsController.java @@ -3,7 +3,7 @@ * ONAP * ================================================================================ * Copyright (C) 2017-2021 AT&T Intellectual Property. All rights reserved. - * Modifications Copyright (C) 2023 Nordix Foundation. + * Modifications Copyright (C) 2023-2024 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,6 +31,7 @@ import java.util.stream.Collectors; import lombok.Getter; import lombok.NonNull; import org.apache.commons.collections4.queue.CircularFifoQueue; +import org.apache.commons.lang3.StringUtils; import org.drools.core.ClassObjectFilter; import org.kie.api.definition.KiePackage; import org.kie.api.definition.rule.Query; @@ -219,7 +220,7 @@ public class MavenDroolsController implements DroolsController { } private void validateText(String text, String errorMessage) { - if (text == null || text.isEmpty()) { + if (StringUtils.isBlank(text)) { throw new IllegalArgumentException(errorMessage); } } diff --git a/policy-management/src/main/java/org/onap/policy/drools/features/PolicyControllerFeatureApi.java b/policy-management/src/main/java/org/onap/policy/drools/features/PolicyControllerFeatureApi.java index f022bf1d..15b48a5c 100644 --- a/policy-management/src/main/java/org/onap/policy/drools/features/PolicyControllerFeatureApi.java +++ b/policy-management/src/main/java/org/onap/policy/drools/features/PolicyControllerFeatureApi.java @@ -3,6 +3,7 @@ * ONAP * ================================================================================ * Copyright (C) 2017-2020 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2024 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,7 +33,7 @@ public interface PolicyControllerFeatureApi extends OrderedService { * called before creating a controller with name 'name' and * properties 'properties'. * - * @param name name of the the controller + * @param name name of the controller * @param properties configuration properties * * @return a policy controller. A take over of the creation operation diff --git a/policy-management/src/main/java/org/onap/policy/drools/persistence/FileSystemPersistence.java b/policy-management/src/main/java/org/onap/policy/drools/persistence/FileSystemPersistence.java index 9fb76d87..717a6f58 100644 --- a/policy-management/src/main/java/org/onap/policy/drools/persistence/FileSystemPersistence.java +++ b/policy-management/src/main/java/org/onap/policy/drools/persistence/FileSystemPersistence.java @@ -35,6 +35,7 @@ import java.util.List; import java.util.Properties; import java.util.function.BiPredicate; import lombok.Getter; +import lombok.NonNull; import lombok.ToString; import org.onap.policy.drools.properties.DroolsPropertyConstants; import org.onap.policy.drools.utils.PropertyUtil; @@ -151,7 +152,7 @@ public class FileSystemPersistence implements SystemPersistence { } } - protected Properties getProperties(Path propertiesPath) { + protected Properties getProperties(@NonNull Path propertiesPath) { if (!Files.exists(propertiesPath)) { throw new IllegalArgumentException("properties for " + propertiesPath + " are not persisted."); } diff --git a/policy-management/src/main/java/org/onap/policy/drools/protocol/coders/EventProtocolCoder.java b/policy-management/src/main/java/org/onap/policy/drools/protocol/coders/EventProtocolCoder.java index 88b25255..7cfa5a3a 100644 --- a/policy-management/src/main/java/org/onap/policy/drools/protocol/coders/EventProtocolCoder.java +++ b/policy-management/src/main/java/org/onap/policy/drools/protocol/coders/EventProtocolCoder.java @@ -4,6 +4,7 @@ * ================================================================================ * Copyright (C) 2017-2019,2022 AT&T Intellectual Property. All rights reserved. * Modifications Copyright(C) 2018 Samsung Electronics Co., Ltd. + * Modifications Copyright (C) 2024 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -35,7 +36,7 @@ public interface EventProtocolCoder { @Getter @Setter @AllArgsConstructor - public static class CoderFilters { + class CoderFilters { /** * coder class. @@ -54,13 +55,9 @@ public interface EventProtocolCoder { @Override public String toString() { - return "CoderFilters [factClass=" - + factClass - + ", filter=" - + filter - + ", modelClassLoaderHash=" - + modelClassLoaderHash - + "]"; + return "CoderFilters [factClass=" + factClass + + ", filter=" + filter + + ", modelClassLoaderHash=" + modelClassLoaderHash + "]"; } } diff --git a/policy-management/src/main/java/org/onap/policy/drools/protocol/coders/GenericEventProtocolCoder.java b/policy-management/src/main/java/org/onap/policy/drools/protocol/coders/GenericEventProtocolCoder.java index 0729c706..6fe1648a 100644 --- a/policy-management/src/main/java/org/onap/policy/drools/protocol/coders/GenericEventProtocolCoder.java +++ b/policy-management/src/main/java/org/onap/policy/drools/protocol/coders/GenericEventProtocolCoder.java @@ -3,6 +3,7 @@ * ONAP * ================================================================================ * Copyright (C) 2019-2020, 2021 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2024 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,15 +22,19 @@ package org.onap.policy.drools.protocol.coders; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Objects; import lombok.AccessLevel; import lombok.NoArgsConstructor; +import org.apache.commons.lang3.StringUtils; import org.onap.policy.drools.controller.DroolsController; import org.onap.policy.drools.controller.DroolsControllerConstants; import org.onap.policy.drools.protocol.coders.EventProtocolCoder.CoderFilters; +import org.onap.policy.drools.system.PolicyDroolsPdpRuntimeException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -43,7 +48,7 @@ abstract class GenericEventProtocolCoder { private static final String INVALID_GROUP_ID_MSG = "Invalid group id"; private static final String INVALID_TOPIC_MSG = "Invalid Topic"; private static final String UNSUPPORTED_MSG = "Unsupported"; - private static final String UNSUPPORTED_EX_MSG = "Unsupported:"; + private static final String UNSUPPORTED_EX_MSG = "Unsupported: "; private static final String MISSING_CLASS = "class must be provided"; private static final Logger logger = LoggerFactory.getLogger(GenericEventProtocolCoder.class); @@ -52,37 +57,26 @@ abstract class GenericEventProtocolCoder { * Mapping topic:controller-id -> /<protocol-decoder-toolset/> where protocol-coder-toolset contains * a gson-protocol-coder-toolset. */ - protected final HashMap<String, ProtocolCoderToolset> coders = - new HashMap<>(); + protected final HashMap<String, ProtocolCoderToolset> coders = new HashMap<>(); /** * Mapping topic + classname -> Protocol Set. */ - protected final HashMap<String, List<ProtocolCoderToolset>> - reverseCoders = new HashMap<>(); + protected final HashMap<String, List<ProtocolCoderToolset>> reverseCoders = new HashMap<>(); /** * Index a new coder. */ public void add(EventProtocolParams eventProtocolParams) { - if (eventProtocolParams.getGroupId() == null || eventProtocolParams.getGroupId().isEmpty()) { - throw new IllegalArgumentException(INVALID_GROUP_ID_MSG); - } - if (eventProtocolParams.getArtifactId() == null || eventProtocolParams.getArtifactId().isEmpty()) { - throw new IllegalArgumentException(INVALID_ARTIFACT_ID_MSG); - } + validateKeyParameters(eventProtocolParams.getGroupId(), + eventProtocolParams.getArtifactId(), + eventProtocolParams.getTopic()); - if (eventProtocolParams.getTopic() == null || eventProtocolParams.getTopic().isEmpty()) { - throw new IllegalArgumentException(INVALID_TOPIC_MSG); - } - - if (eventProtocolParams.getEventClass() == null) { - throw new IllegalArgumentException("Invalid Event Class"); - } + validateStringParameter(eventProtocolParams.getEventClass(), "Invalid Event Class"); String key = this.codersKey(eventProtocolParams.getGroupId(), eventProtocolParams.getArtifactId(), - eventProtocolParams.getTopic()); + eventProtocolParams.getTopic()); String reverseKey = this.reverseCodersKey(eventProtocolParams.getTopic(), eventProtocolParams.getEventClass()); synchronized (this) { @@ -91,22 +85,16 @@ abstract class GenericEventProtocolCoder { logger.info("{}: adding coders for existing {}: {}", this, key, toolset); - toolset - .addCoder( - eventProtocolParams.getEventClass(), - eventProtocolParams.getProtocolFilter(), - eventProtocolParams.getModelClassLoaderHash()); + toolset.addCoder( + eventProtocolParams.getEventClass(), + eventProtocolParams.getProtocolFilter(), + eventProtocolParams.getModelClassLoaderHash()); if (!reverseCoders.containsKey(reverseKey)) { - logger.info( - "{}: adding new reverse coders (multiple classes case) for {}:{}: {}", - this, - reverseKey, - key, - toolset); - - List<ProtocolCoderToolset> reverseMappings = - new ArrayList<>(); + logger.info("{}: adding new reverse coders (multiple classes case) for {}:{}: {}", + this, reverseKey, key, toolset); + + List<ProtocolCoderToolset> reverseMappings = new ArrayList<>(); reverseMappings.add(toolset); reverseCoders.put(reverseKey, reverseMappings); } @@ -128,20 +116,15 @@ abstract class GenericEventProtocolCoder { // There is another controller (different group id/artifact id/topic) // that shares the class and the topic. - List<ProtocolCoderToolset> toolsets = - reverseCoders.get(reverseKey); + List<ProtocolCoderToolset> toolsets = reverseCoders.get(reverseKey); var present = false; for (ProtocolCoderToolset parserSet : toolsets) { - // just doublecheck + // just double check present = parserSet.getControllerId().equals(key); if (present) { /* anomaly */ - logger.error( - "{}: unexpected toolset reverse mapping found for {}:{}: {}", - this, - reverseKey, - key, - parserSet); + logger.error("{}: unexpected toolset reverse mapping found for {}:{}: {}", + this, reverseKey, key, parserSet); } } @@ -191,17 +174,7 @@ abstract class GenericEventProtocolCoder { */ public void remove(String groupId, String artifactId, String topic) { - if (groupId == null || groupId.isEmpty()) { - throw new IllegalArgumentException(INVALID_GROUP_ID_MSG); - } - - if (artifactId == null || artifactId.isEmpty()) { - throw new IllegalArgumentException(INVALID_ARTIFACT_ID_MSG); - } - - if (topic == null || topic.isEmpty()) { - throw new IllegalArgumentException(INVALID_TOPIC_MSG); - } + validateKeyParameters(groupId, artifactId, topic); String key = this.codersKey(groupId, artifactId, topic); @@ -225,23 +198,23 @@ abstract class GenericEventProtocolCoder { return; } - List<ProtocolCoderToolset> toolsets = - this.reverseCoders.get(reverseKey); - Iterator<ProtocolCoderToolset> toolsetsIter = - toolsets.iterator(); + List<ProtocolCoderToolset> toolsets = this.reverseCoders.getOrDefault(reverseKey, Collections.emptyList()); + + if (toolsets.isEmpty()) { + logger.info("{}: removing reverse mapping for {}: ", this, reverseKey); + this.reverseCoders.remove(reverseKey); + return; + } + + Iterator<ProtocolCoderToolset> toolsetsIter = toolsets.iterator(); + while (toolsetsIter.hasNext()) { ProtocolCoderToolset toolset = toolsetsIter.next(); if (toolset.getControllerId().equals(key)) { - logger.info( - "{}: removed coder from toolset for {} from reverse mapping", this, reverseKey); + logger.info("{}: removed coder from toolset for {} from reverse mapping", this, reverseKey); toolsetsIter.remove(); } } - - if (this.reverseCoders.get(reverseKey).isEmpty()) { - logger.info("{}: removing reverse mapping for {}: ", this, reverseKey); - this.reverseCoders.remove(reverseKey); - } } /** @@ -250,23 +223,14 @@ abstract class GenericEventProtocolCoder { * @param groupId group id * @param artifactId artifact id * @param topic topic - * @return true if its is codable + * @return true if it's supported to be coded */ public boolean isCodingSupported(String groupId, String artifactId, String topic) { - if (groupId == null || groupId.isEmpty()) { - throw new IllegalArgumentException(INVALID_GROUP_ID_MSG); - } - - if (artifactId == null || artifactId.isEmpty()) { - throw new IllegalArgumentException(INVALID_ARTIFACT_ID_MSG); - } - - if (topic == null || topic.isEmpty()) { - throw new IllegalArgumentException(INVALID_TOPIC_MSG); - } + validateKeyParameters(groupId, artifactId, topic); String key = this.codersKey(groupId, artifactId, topic); + synchronized (this) { return coders.containsKey(key); } @@ -280,14 +244,14 @@ abstract class GenericEventProtocolCoder { * @param topic topic * @param json json string to convert to object * @return the decoded object - * @throws IllegalArgumentException if invalid argument is provided - * @throws UnsupportedOperationException if the operation cannot be performed + * @throws IllegalArgumentException if invalid argument is provided + * @throws PolicyDroolsPdpRuntimeException if the operation cannot be performed */ public Object decode(String groupId, String artifactId, String topic, String json) { if (!isCodingSupported(groupId, artifactId, topic)) { throw new IllegalArgumentException( - UNSUPPORTED_EX_MSG + codersKey(groupId, artifactId, topic) + " for encoding"); + UNSUPPORTED_EX_MSG + codersKey(groupId, artifactId, topic) + " for encoding"); } String key = this.codersKey(groupId, artifactId, topic); @@ -321,9 +285,7 @@ abstract class GenericEventProtocolCoder { throw new IllegalArgumentException(UNSUPPORTED_EX_MSG + codersKey(groupId, artifactId, topic)); } - if (event == null) { - throw new IllegalArgumentException("Unsupported topic:" + topic); - } + validateObjectParameter(event, "Event cannot be null or empty"); // reuse the decoder set, since there must be affinity in the model String key = this.codersKey(groupId, artifactId, topic); @@ -341,25 +303,18 @@ abstract class GenericEventProtocolCoder { */ public String encode(String topic, Object event) { - if (event == null) { - throw new IllegalArgumentException("Invalid encoded class"); - } + validateObjectParameter(event, "Event cannot be null or empty"); - if (topic == null || topic.isEmpty()) { - throw new IllegalArgumentException("Invalid topic"); - } + validateStringParameter(topic, INVALID_TOPIC_MSG); String reverseKey = this.reverseCodersKey(topic, event.getClass().getName()); if (!this.reverseCoders.containsKey(reverseKey)) { throw new IllegalArgumentException("no reverse coder has been found"); } - List<ProtocolCoderToolset> toolsets = - this.reverseCoders.get(reverseKey); + List<ProtocolCoderToolset> toolsets = this.reverseCoders.get(reverseKey); - String key = - codersKey( - toolsets.get(0).getGroupId(), toolsets.get(0).getArtifactId(), topic); + String key = codersKey(toolsets.get(0).getGroupId(), toolsets.get(0).getArtifactId(), topic); return this.encodeInternal(key, event); } @@ -374,13 +329,9 @@ abstract class GenericEventProtocolCoder { */ public String encode(String topic, Object encodedClass, DroolsController droolsController) { - if (encodedClass == null) { - throw new IllegalArgumentException("Invalid encoded class"); - } + validateObjectParameter(encodedClass, "Invalid encoded class"); - if (topic == null || topic.isEmpty()) { - throw new IllegalArgumentException("Invalid topic"); - } + validateStringParameter(topic, INVALID_TOPIC_MSG); String key = codersKey(droolsController.getGroupId(), droolsController.getArtifactId(), topic); return this.encodeInternal(key, encodedClass); @@ -397,31 +348,19 @@ abstract class GenericEventProtocolCoder { */ protected String encodeInternal(String key, Object event) { - logger.debug("{}: encode for {}: {}", this, key, event); // NOSONAR - - /* - * It seems that sonar declares the previous logging line as a security vulnerability - * when logging the topic variable. The static code analysis indicates that - * the path starts in org.onap.policy.drools.server.restful.RestManager::decode(), - * but the request is rejected if the topic contains invalid characters (the sonar description - * mentions "/r/n/t" characters) all of which are validated against in the checkValidNameInput(topic). - * Furthermore production instances are assumed not to have debug enabled, nor the REST telemetry API - * should be published externally. An additional note is that Path URLs containing spaces and newlines - * will be rejected earlier in the HTTP protocol libraries (jetty) so an URL of the form - * "https://../to\npic" won't even make it here. - */ + logger.debug("{}: encode for {}: {}", this, key, event); ProtocolCoderToolset coderTools = coders.get(key); try { String json = coderTools.encode(event); - if (json != null && !json.isEmpty()) { + if (!StringUtils.isBlank(json)) { return json; } } catch (Exception e) { logger.warn("{}: cannot encode (first) for {}: {}", this, key, event, e); } - throw new UnsupportedOperationException("Cannot decode with gson"); + throw new UnsupportedOperationException("Cannot encode with gson"); } /** @@ -443,50 +382,37 @@ abstract class GenericEventProtocolCoder { return droolsControllers; } - List<ProtocolCoderToolset> toolsets = - this.reverseCoders.get(reverseKey); + List<ProtocolCoderToolset> toolsets = this.reverseCoders.getOrDefault(reverseKey, Collections.emptyList()); // There must be multiple toolsets associated with <topic,classname> reverseKey // case 2 different controllers use the same models and register the same encoder for // the same topic. This is assumed not to occur often but for the purpose of encoding - // but there should be no side-effects. Ownership is crosscheck against classname and + // but there should be no side effects. Ownership is crosscheck against classname and // classloader reference. - if (toolsets == null || toolsets.isEmpty()) { - throw new IllegalStateException( - "No Encoders toolsets available for topic " - + topic - + " encoder " - + encodedClass.getClass().getName()); - } - for (ProtocolCoderToolset encoderSet : toolsets) { addToolsetControllers(droolsControllers, encodedClass, encoderSet); } if (droolsControllers.isEmpty()) { - throw new IllegalStateException( - "No Encoders toolsets available for " - + topic - + ":" - + encodedClass.getClass().getName()); + throw new IllegalStateException("No Encoders toolsets available for " + topic + ":" + + encodedClass.getClass().getName()); } return droolsControllers; } private void addToolsetControllers(List<DroolsController> droolsControllers, Object encodedClass, - ProtocolCoderToolset encoderSet) { + ProtocolCoderToolset encoderSet) { // figure out the right toolset String groupId = encoderSet.getGroupId(); String artifactId = encoderSet.getArtifactId(); List<CoderFilters> coderFilters = encoderSet.getCoders(); for (CoderFilters coder : coderFilters) { if (coder.getFactClass().equals(encodedClass.getClass().getName())) { - var droolsController = - DroolsControllerConstants.getFactory().get(groupId, artifactId, ""); + var droolsController = DroolsControllerConstants.getFactory().get(groupId, artifactId, ""); if (droolsController.ownsCoder( - encodedClass.getClass(), coder.getModelClassLoaderHash())) { + encodedClass.getClass(), coder.getModelClassLoaderHash())) { droolsControllers.add(droolsController); } } @@ -523,19 +449,13 @@ abstract class GenericEventProtocolCoder { */ public List<CoderFilters> getFilters(String groupId, String artifactId) { - if (groupId == null || groupId.isEmpty()) { - throw new IllegalArgumentException(INVALID_GROUP_ID_MSG); - } - - if (artifactId == null || artifactId.isEmpty()) { - throw new IllegalArgumentException(INVALID_ARTIFACT_ID_MSG); - } + validateStringParameter(groupId, INVALID_GROUP_ID_MSG); + validateStringParameter(artifactId, INVALID_ARTIFACT_ID_MSG); String key = this.codersKey(groupId, artifactId, ""); List<CoderFilters> codersFilters = new ArrayList<>(); - for (Map.Entry<String, ProtocolCoderToolset> entry : - coders.entrySet()) { + for (Map.Entry<String, ProtocolCoderToolset> entry : coders.entrySet()) { if (entry.getKey().startsWith(key)) { codersFilters.addAll(entry.getValue().getCoders()); } @@ -555,15 +475,13 @@ abstract class GenericEventProtocolCoder { * @throws IllegalArgumentException if invalid input */ public CoderFilters getFilters( - String groupId, String artifactId, String topic, String classname) { + String groupId, String artifactId, String topic, String classname) { if (!isCodingSupported(groupId, artifactId, topic)) { throw new IllegalArgumentException(UNSUPPORTED_EX_MSG + codersKey(groupId, artifactId, topic)); } - if (classname == null || classname.isEmpty()) { - throw new IllegalArgumentException("classname must be provided"); - } + validateStringParameter(classname, "classname must be provided"); String key = this.codersKey(groupId, artifactId, topic); ProtocolCoderToolset coderTools = coders.get(key); @@ -580,7 +498,7 @@ abstract class GenericEventProtocolCoder { * @throws IllegalArgumentException if invalid input */ public ProtocolCoderToolset getCoders( - String groupId, String artifactId, String topic) { + String groupId, String artifactId, String topic) { if (!isCodingSupported(groupId, artifactId, topic)) { throw new IllegalArgumentException(UNSUPPORTED_EX_MSG + codersKey(groupId, artifactId, topic)); @@ -598,22 +516,16 @@ abstract class GenericEventProtocolCoder { * @return list of coders * @throws IllegalArgumentException if invalid input */ - public List<ProtocolCoderToolset> getCoders( - String groupId, String artifactId) { + public List<ProtocolCoderToolset> getCoders(String groupId, String artifactId) { - if (groupId == null || groupId.isEmpty()) { - throw new IllegalArgumentException(INVALID_GROUP_ID_MSG); - } + validateStringParameter(groupId, INVALID_GROUP_ID_MSG); - if (artifactId == null || artifactId.isEmpty()) { - throw new IllegalArgumentException(INVALID_ARTIFACT_ID_MSG); - } + validateStringParameter(artifactId, INVALID_ARTIFACT_ID_MSG); String key = this.codersKey(groupId, artifactId, ""); List<ProtocolCoderToolset> coderToolset = new ArrayList<>(); - for (Map.Entry<String, ProtocolCoderToolset> entry : - coders.entrySet()) { + for (Map.Entry<String, ProtocolCoderToolset> entry : coders.entrySet()) { if (entry.getKey().startsWith(key)) { coderToolset.add(entry.getValue()); } @@ -631,19 +543,12 @@ abstract class GenericEventProtocolCoder { */ public List<CoderFilters> getReverseFilters(String topic, String codedClass) { - if (topic == null || topic.isEmpty()) { - throw new IllegalArgumentException(UNSUPPORTED_MSG); - } + validateStringParameter(topic, INVALID_TOPIC_MSG); - if (codedClass == null) { - throw new IllegalArgumentException(MISSING_CLASS); - } + validateStringParameter(codedClass, MISSING_CLASS); String key = this.reverseCodersKey(topic, codedClass); - List<ProtocolCoderToolset> toolsets = this.reverseCoders.get(key); - if (toolsets == null) { - throw new IllegalArgumentException("No Coder found for " + key); - } + List<ProtocolCoderToolset> toolsets = this.reverseCoders.getOrDefault(key, Collections.emptyList()); List<CoderFilters> coderFilters = new ArrayList<>(); for (ProtocolCoderToolset toolset : toolsets) { @@ -656,79 +561,70 @@ abstract class GenericEventProtocolCoder { /** * returns group and artifact id of the creator of the encoder. * - * @param topic topic - * @param fact fact + * @param topic topic + * @param encodedClass class encoder * @return the drools controller */ - DroolsController getDroolsController(String topic, Object fact) { - - if (topic == null || topic.isEmpty()) { - throw new IllegalArgumentException(UNSUPPORTED_MSG); - } - - if (fact == null) { - throw new IllegalArgumentException(MISSING_CLASS); - } - - List<DroolsController> droolsControllers = droolsCreators(topic, fact); + DroolsController getDroolsController(String topic, Object encodedClass) { + List<DroolsController> droolsControllers = getDroolsControllers(topic, encodedClass); if (droolsControllers.isEmpty()) { - throw new IllegalArgumentException("Invalid Topic: " + topic); + throw new IllegalArgumentException(UNSUPPORTED_MSG + " topic " + topic + + " and encodedClass " + encodedClass.getClass()); } - if (droolsControllers.size() > 1) { - logger.warn( - "{}: multiple drools-controller {} for {}:{} ", - this, - droolsControllers, - topic, - fact.getClass().getName()); - // continue - } return droolsControllers.get(0); } /** * returns group and artifact id of the creator of the encoder. * - * @param topic topic - * @param fact fact + * @param topic topic + * @param encodedClass class encoder * @return list of drools controllers */ - List<DroolsController> getDroolsControllers(String topic, Object fact) { + List<DroolsController> getDroolsControllers(String topic, Object encodedClass) { - if (topic == null || topic.isEmpty()) { - throw new IllegalArgumentException(UNSUPPORTED_MSG); - } + validateStringParameter(topic, INVALID_TOPIC_MSG); - if (fact == null) { - throw new IllegalArgumentException(MISSING_CLASS); - } + validateObjectParameter(encodedClass, MISSING_CLASS); - List<DroolsController> droolsControllers = droolsCreators(topic, fact); + List<DroolsController> droolsControllers = droolsCreators(topic, encodedClass); if (droolsControllers.size() > 1) { // unexpected - logger.warn( - "{}: multiple drools-controller {} for {}:{} ", - this, - droolsControllers, - topic, - fact.getClass().getName()); + logger.warn("{}: multiple drools-controller {} for {}:{} ", + this, droolsControllers, topic, encodedClass.getClass().getName()); // continue } return droolsControllers; } + private void validateKeyParameters(String groupId, String artifactId, String topic) { + validateStringParameter(groupId, INVALID_GROUP_ID_MSG); + validateStringParameter(artifactId, INVALID_ARTIFACT_ID_MSG); + validateStringParameter(topic, INVALID_TOPIC_MSG); + } + + private static void validateStringParameter(String value, String errorMessage) { + if (StringUtils.isBlank(value)) { + throw new IllegalArgumentException(errorMessage); + } + } + + private static void validateObjectParameter(Object object, String errorMessage) { + if (Objects.isNull(object)) { + throw new IllegalArgumentException(errorMessage); + } + } + /* - * Note: this only logs the KEYSETS, thus lombok ToString annotation is not used. + * Note: this only logs the KEY SETS, thus lombok ToString annotation is not used. * Otherwise, it results in too much verbosity. */ @Override public String toString() { - return "GenericEventProtocolCoder [coders=" - + coders.keySet() - + ", reverseCoders=" - + reverseCoders.keySet() - + "]"; + return "GenericEventProtocolCoder " + + "[coders=" + coders.keySet() + ", " + + "reverseCoders=" + reverseCoders.keySet() + "]"; } } diff --git a/policy-management/src/main/java/org/onap/policy/drools/protocol/coders/GsonProtocolCoderToolset.java b/policy-management/src/main/java/org/onap/policy/drools/protocol/coders/GsonProtocolCoderToolset.java index 80844612..18fcb1a3 100644 --- a/policy-management/src/main/java/org/onap/policy/drools/protocol/coders/GsonProtocolCoderToolset.java +++ b/policy-management/src/main/java/org/onap/policy/drools/protocol/coders/GsonProtocolCoderToolset.java @@ -3,6 +3,7 @@ * ONAP * ================================================================================ * Copyright (C) 2019-2022 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2024 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -62,7 +63,7 @@ class GsonProtocolCoderToolset extends ProtocolCoderToolset { public static class GsonUtcAdapter implements JsonSerializer<ZonedDateTime>, JsonDeserializer<ZonedDateTime> { @Override public ZonedDateTime deserialize(JsonElement element, Type type, - JsonDeserializationContext context) { + JsonDeserializationContext context) { try { return ZonedDateTime.parse(element.getAsString(), format); } catch (final Exception e) { @@ -73,7 +74,7 @@ class GsonProtocolCoderToolset extends ProtocolCoderToolset { @Override public JsonElement serialize(ZonedDateTime datetime, Type type, - JsonSerializationContext context) { + JsonSerializationContext context) { return new JsonPrimitive(datetime.format(format)); } } @@ -112,7 +113,7 @@ class GsonProtocolCoderToolset extends ProtocolCoderToolset { * Toolset to encode/decode tools associated with a topic. * * @param eventProtocolParams parameter object for event encoder - * @param controllerId controller id + * @param controllerId controller id */ public GsonProtocolCoderToolset(EventProtocolParams eventProtocolParams, String controllerId) { super(eventProtocolParams, controllerId); @@ -145,7 +146,7 @@ class GsonProtocolCoderToolset extends ProtocolCoderToolset { public Object decode(String json) { final var droolsController = - DroolsControllerConstants.getFactory().get(this.groupId, this.artifactId, ""); + DroolsControllerConstants.getFactory().get(this.groupId, this.artifactId, ""); if (droolsController == null) { logger.warn("{}: no drools-controller to process {}", this, json); throw new IllegalStateException("no drools-controller to process event"); @@ -163,35 +164,36 @@ class GsonProtocolCoderToolset extends ProtocolCoderToolset { if (decoderClass == null) { logger.warn(CANNOT_FETCH_CLASS, this, decoderFilter.getFactClass()); throw new IllegalStateException( - FETCH_CLASS_EX_MSG + decoderFilter.getFactClass()); + FETCH_CLASS_EX_MSG + decoderFilter.getFactClass()); } } catch (final Exception e) { logger.warn(CANNOT_FETCH_CLASS, this, decoderFilter.getFactClass()); throw new UnsupportedOperationException( - FETCH_CLASS_EX_MSG + decoderFilter.getFactClass(), e); + FETCH_CLASS_EX_MSG + decoderFilter.getFactClass(), e); } if (this.customCoder != null) { try { final var gsonClassContainer = - droolsController.fetchModelClass(this.customCoder.getClassContainer()); + droolsController.fetchModelClass(this.customCoder.getClassContainer()); final var gsonField = gsonClassContainer.getField(this.customCoder.staticCoderField); final var gsonObject = gsonField.get(null); final var fromJsonMethod = gsonObject.getClass().getDeclaredMethod("fromJson", - String.class, Class.class); + String.class, Class.class); return fromJsonMethod.invoke(gsonObject, json, decoderClass); } catch (final Exception e) { logger.warn(CANNOT_FETCH_CLASS, this, decoderFilter.getFactClass()); - throw new UnsupportedOperationException( - FETCH_CLASS_EX_MSG + decoderFilter.getFactClass(), e); + throw new UnsupportedOperationException("cannot decode with customCoder: " + + customCoder.getClassContainer() + + " using application class " + decoderFilter.getFactClass(), e); } } else { try { - return this.decoder.fromJson(json, decoderClass); + return this.getDecoder().fromJson(json, decoderClass); } catch (final Exception e) { logger.warn("{} cannot decode {} into {}", this, json, decoderClass.getName()); throw new UnsupportedOperationException( - "cannot decode into " + decoderFilter.getFactClass(), e); + "cannot decode into " + decoderFilter.getFactClass(), e); } } } @@ -205,21 +207,20 @@ class GsonProtocolCoderToolset extends ProtocolCoderToolset { if (this.customCoder != null) { try { final var droolsController = - DroolsControllerConstants.getFactory().get(this.groupId, this.artifactId, null); + DroolsControllerConstants.getFactory().get(this.groupId, this.artifactId, null); final Class<?> gsonClassContainer = - droolsController.fetchModelClass(this.customCoder.getClassContainer()); + droolsController.fetchModelClass(this.customCoder.getClassContainer()); final var gsonField = gsonClassContainer.getField(this.customCoder.staticCoderField); final var gsonObject = gsonField.get(null); - final var toJsonMethod = - gsonObject.getClass().getDeclaredMethod("toJson", Object.class); + final var toJsonMethod = gsonObject.getClass().getDeclaredMethod("toJson", Object.class); return (String) toJsonMethod.invoke(gsonObject, event); } catch (final Exception e) { logger.warn("{} cannot custom-encode {}", this, event); - throw new UnsupportedOperationException("event cannot be encoded", e); + throw new UnsupportedOperationException("event cannot be custom encoded", e); } } else { try { - return this.encoder.toJson(event); + return this.getEncoder().toJson(event); } catch (final Exception e) { logger.warn("{} cannot encode {}", this, event); throw new UnsupportedOperationException("event cannot be encoded", e); diff --git a/policy-management/src/main/java/org/onap/policy/drools/protocol/coders/MultiplexorEventProtocolCoder.java b/policy-management/src/main/java/org/onap/policy/drools/protocol/coders/MultiplexorEventProtocolCoder.java index 3fea6821..cfbf2e4f 100644 --- a/policy-management/src/main/java/org/onap/policy/drools/protocol/coders/MultiplexorEventProtocolCoder.java +++ b/policy-management/src/main/java/org/onap/policy/drools/protocol/coders/MultiplexorEventProtocolCoder.java @@ -3,6 +3,7 @@ * ONAP * ================================================================================ * Copyright (C) 2019, 2021 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2024 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,7 +21,6 @@ package org.onap.policy.drools.protocol.coders; -import java.util.ArrayList; import java.util.List; import lombok.ToString; import org.onap.policy.drools.controller.DroolsController; @@ -126,19 +126,7 @@ class MultiplexorEventProtocolCoder implements EventProtocolCoder { */ @Override public Object decode(String groupId, String artifactId, String topic, String json) { - logger.debug("{}: decode {}:{}:{}:{}", this, groupId, artifactId, topic, json); // NOSONAR - - /* - * It seems that sonar declares the previous logging line as a security vulnerability - * when logging the topic variable. The static code analysis indicates that - * the path starts in org.onap.policy.drools.server.restful.RestManager::decode(), - * but the request is rejected if the topic contains invalid characters (the sonar description - * mentions "/r/n/t" characters) which are validated against in the checkValidNameInput(topic). - * Furthermore production instances are assumed not to have debug enabled, nor the REST telemetry API - * should be published externally. An additional note is that Path URLs containing spaces and newlines - * will be failed earlier at the HTTP protocol libraries (jetty, etc ..) so an URL of the form - * "https://../to\npic" won't even make it here. - */ + logger.debug("{}: decode {}:{}:{}:{}", this, groupId, artifactId, topic, json); return this.decoders.decode(groupId, artifactId, topic, json); } @@ -156,13 +144,7 @@ class MultiplexorEventProtocolCoder implements EventProtocolCoder { */ @Override public String encode(String topic, Object event) { - logger.debug("{}: encode {}:{}", this, topic, event); // NOSONAR - - /* - * See explanation for decode(String groupId, String artifactId, String topic, String json). - * The same applies here as it is called from - * org.onap.policy.drools.server.restful.RestManager::encode(), - */ + logger.debug("{}: encode {}:{}", this, topic, event); return this.encoders.encode(topic, event); } @@ -187,8 +169,7 @@ class MultiplexorEventProtocolCoder implements EventProtocolCoder { * {@inheritDoc}. */ @Override - public CoderFilters getDecoderFilters( - String groupId, String artifactId, String topic, String classname) { + public CoderFilters getDecoderFilters(String groupId, String artifactId, String topic, String classname) { return this.decoders.getFilters(groupId, artifactId, topic, classname); } @@ -205,18 +186,11 @@ class MultiplexorEventProtocolCoder implements EventProtocolCoder { */ @Override public ProtocolCoderToolset getDecoders(String groupId, String artifactId, String topic) { - ProtocolCoderToolset decoderToolsets = - this.decoders.getCoders(groupId, artifactId, topic); - if (decoderToolsets == null) { - throw new IllegalArgumentException( - "Decoders not found for " + groupId + ":" + artifactId + ":" + topic); - } - - return decoderToolsets; + return this.decoders.getCoders(groupId, artifactId, topic); } /** - * get all deocders by maven coordinates and topic. + * get all decoders by maven coordinates and topic. * * @param groupId group id * @param artifactId artifact id @@ -225,14 +199,7 @@ class MultiplexorEventProtocolCoder implements EventProtocolCoder { */ @Override public List<ProtocolCoderToolset> getDecoders(String groupId, String artifactId) { - - List<ProtocolCoderToolset> decoderToolsets = - this.decoders.getCoders(groupId, artifactId); - if (decoderToolsets == null) { - throw new IllegalArgumentException("Decoders not found for " + groupId + ":" + artifactId); - } - - return new ArrayList<>(decoderToolsets); + return this.decoders.getCoders(groupId, artifactId); } /** diff --git a/policy-management/src/main/java/org/onap/policy/drools/protocol/coders/ProtocolCoderToolset.java b/policy-management/src/main/java/org/onap/policy/drools/protocol/coders/ProtocolCoderToolset.java index 277c4ed3..5cd68709 100644 --- a/policy-management/src/main/java/org/onap/policy/drools/protocol/coders/ProtocolCoderToolset.java +++ b/policy-management/src/main/java/org/onap/policy/drools/protocol/coders/ProtocolCoderToolset.java @@ -4,6 +4,7 @@ * ================================================================================ * Copyright (C) 2017-2022 AT&T Intellectual Property. All rights reserved. * Modifications Copyright (C) 2018 Samsung Electronics Co., Ltd. + * Modifications Copyright (C) 2024 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,6 +27,7 @@ import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import lombok.Getter; import lombok.Setter; +import org.apache.commons.lang3.StringUtils; import org.onap.policy.drools.protocol.coders.EventProtocolCoder.CoderFilters; import org.onap.policy.drools.protocol.coders.TopicCoderFilterConfiguration.CustomCoder; import org.slf4j.Logger; @@ -82,7 +84,7 @@ public abstract class ProtocolCoderToolset { */ protected ProtocolCoderToolset(EventProtocolParams eventProtocolParams, String controllerId) { - if (eventProtocolParams == null || controllerId == null) { + if (eventProtocolParams == null || StringUtils.isBlank(controllerId)) { throw new IllegalArgumentException("Invalid input"); } @@ -104,7 +106,7 @@ public abstract class ProtocolCoderToolset { * @return the decoder filters or null if not found */ public CoderFilters getCoder(String classname) { - if (classname == null || classname.isEmpty()) { + if (StringUtils.isBlank(classname)) { throw new IllegalArgumentException("no classname provided"); } @@ -132,7 +134,7 @@ public abstract class ProtocolCoderToolset { * @param filter filter */ public void addCoder(String eventClass, JsonProtocolFilter filter, int modelClassLoaderHash) { - if (eventClass == null || eventClass.isEmpty()) { + if (StringUtils.isBlank(eventClass)) { throw new IllegalArgumentException("no event class provided"); } @@ -152,7 +154,7 @@ public abstract class ProtocolCoderToolset { * @param eventClass event class */ public void removeCoders(String eventClass) { - if (eventClass == null || eventClass.isEmpty()) { + if (StringUtils.isBlank(eventClass)) { throw new IllegalArgumentException("no event class provided"); } diff --git a/policy-management/src/main/java/org/onap/policy/drools/protocol/coders/TopicCoderFilterConfiguration.java b/policy-management/src/main/java/org/onap/policy/drools/protocol/coders/TopicCoderFilterConfiguration.java index 4dd132b9..69bc0527 100644 --- a/policy-management/src/main/java/org/onap/policy/drools/protocol/coders/TopicCoderFilterConfiguration.java +++ b/policy-management/src/main/java/org/onap/policy/drools/protocol/coders/TopicCoderFilterConfiguration.java @@ -3,6 +3,7 @@ * policy-management * ================================================================================ * Copyright (C) 2017-2021 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2024 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,6 +26,7 @@ import lombok.AllArgsConstructor; import lombok.Getter; import lombok.Setter; import lombok.ToString; +import org.apache.commons.lang3.StringUtils; @Getter @ToString @@ -51,19 +53,21 @@ public class TopicCoderFilterConfiguration { * @param rawCustomCoder with format: <class-containing-custom-coder>,<static-coder-field>. */ protected CustomCoder(String rawCustomCoder) { - if (rawCustomCoder != null && !rawCustomCoder.isEmpty()) { - - this.classContainer = rawCustomCoder.substring(0, rawCustomCoder.indexOf(',')); - if (this.classContainer == null || this.classContainer.isEmpty()) { - throw new IllegalArgumentException( - "No classname to create CustomCoder cannot be created"); - } - - this.staticCoderField = rawCustomCoder.substring(rawCustomCoder.indexOf(',') + 1); - if (this.staticCoderField == null || this.staticCoderField.isEmpty()) { - throw new IllegalArgumentException( - "No staticCoderField to create CustomCoder cannot be created for class " + classContainer); - } + if (StringUtils.isBlank(rawCustomCoder)) { + throw new IllegalArgumentException("Constructor argument cannot be empty. " + + "Use format \"customCoderClass,staticCoderField\""); + } + + this.classContainer = rawCustomCoder.substring(0, rawCustomCoder.indexOf(',')); + if (StringUtils.isBlank(this.classContainer)) { + throw new IllegalArgumentException( + "No classname to create CustomCoder cannot be created"); + } + + this.staticCoderField = rawCustomCoder.substring(rawCustomCoder.indexOf(',') + 1); + if (StringUtils.isBlank(this.staticCoderField)) { + throw new IllegalArgumentException( + "No staticCoderField to create CustomCoder cannot be created for class " + classContainer); } } @@ -74,11 +78,11 @@ public class TopicCoderFilterConfiguration { * @param staticCoderField static coder field */ protected CustomCoder(String className, String staticCoderField) { - if (className == null || className.isEmpty()) { + if (StringUtils.isBlank(className)) { throw new IllegalArgumentException("No classname to create CustomCoder cannot be created"); } - if (staticCoderField == null || staticCoderField.isEmpty()) { + if (StringUtils.isBlank(staticCoderField)) { throw new IllegalArgumentException( "No staticCoderField to create CustomCoder cannot be created for class " + className); } |