aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--INFO.yaml14
-rw-r--r--feature-distributed-locking/src/assembly/assemble_zip.xml7
-rw-r--r--feature-distributed-locking/src/main/feature/config/feature-distributed-locking.properties4
-rw-r--r--feature-distributed-locking/src/main/feature/db/pooling/sql/1804-distributedlocking.downgrade.sql20
-rw-r--r--feature-distributed-locking/src/main/feature/db/pooling/sql/1804-distributedlocking.upgrade.sql30
-rw-r--r--feature-distributed-locking/src/main/feature/db/pooling/sql/1811-distributedlocking.downgrade.sql19
-rw-r--r--feature-distributed-locking/src/main/feature/db/pooling/sql/1811-distributedlocking.upgrade.sql23
-rw-r--r--feature-distributed-locking/src/main/feature/install/disable26
-rw-r--r--feature-distributed-locking/src/main/feature/install/enable26
-rw-r--r--feature-distributed-locking/src/main/java/org/onap/policy/distributed/locking/DistributedLockManager.java78
-rw-r--r--feature-distributed-locking/src/test/java/org/onap/policy/distributed/locking/DistributedLockManagerTest.java189
-rw-r--r--feature-healthcheck/src/assembly/assemble_zip.xml7
-rw-r--r--feature-healthcheck/src/test/java/org/onap/policy/drools/healthcheck/HealthCheckFeatureTest.java76
-rw-r--r--feature-healthcheck/src/test/java/org/onap/policy/drools/healthcheck/RestMockHealthCheck.java5
-rw-r--r--feature-legacy-config/src/main/feature/config/feature-legacy-config.properties3
-rw-r--r--feature-lifecycle/src/main/feature/config/feature-lifecycle.properties2
-rw-r--r--feature-lifecycle/src/main/java/org/onap/policy/drools/lifecycle/LifecycleFeature.java4
-rw-r--r--feature-lifecycle/src/main/java/org/onap/policy/drools/lifecycle/LifecycleStateRunning.java30
-rw-r--r--feature-lifecycle/src/main/java/org/onap/policy/drools/server/restful/RestLifecycleManager.java4
-rw-r--r--feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/ControllerSupport.java15
-rw-r--r--feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/LifecycleFeatureTest.java164
-rw-r--r--feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/LifecycleFsmTest.java5
-rw-r--r--feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/LifecycleFsmUpdateTest.java26
-rw-r--r--feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/LifecycleStateActiveTest.java8
-rw-r--r--feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/LifecycleStatePassiveTest.java133
-rw-r--r--feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/LifecycleStateSafeTest.java5
-rw-r--r--feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/LifecycleStateTestTest.java5
-rw-r--r--feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/LifecycleStateUnsupportedTest.java11
-rw-r--r--feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/PolicyTypeDroolsControllerTest.java50
-rw-r--r--feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/PolicyTypeNativeArtifactControllerTest.java2
-rw-r--r--feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/PolicyTypeNativeDroolsControllerTest.java102
-rw-r--r--feature-lifecycle/src/test/java/org/onap/policy/drools/server/restful/RestLifecycleManagerTest.java122
-rw-r--r--feature-no-locking/src/assembly/assemble_zip.xml7
-rw-r--r--feature-no-locking/src/main/java/org/onap/policy/no/locking/NoLockManager.java9
-rw-r--r--feature-no-locking/src/test/java/org/onap/policy/no/locking/NoLockManagerTest.java2
-rw-r--r--feature-pooling-messages/src/assembly/assemble_zip.xml7
-rw-r--r--feature-pooling-messages/src/main/feature/config/feature-pooling-messages.properties2
-rw-r--r--feature-test-transaction/src/assembly/assemble_zip.xml6
-rw-r--r--packages/base/src/files/bin/policy8
-rw-r--r--packages/docker/src/main/docker/Dockerfile6
-rw-r--r--packages/docker/src/main/docker/pdpd-entrypoint.sh22
-rw-r--r--packages/docker/src/main/docker/suse.Dockerfile3
-rw-r--r--policy-core/pom.xml4
-rw-r--r--policy-core/src/main/java/org/onap/policy/drools/core/PolicyContainer.java149
-rw-r--r--policy-core/src/main/java/org/onap/policy/drools/core/jmx/PdpJmx.java2
-rw-r--r--policy-core/src/test/java/org/onap/policy/drools/core/DroolsContainerTest.java106
-rw-r--r--policy-core/src/test/java/org/onap/policy/drools/core/PolicyContainerTest.java230
-rw-r--r--policy-core/src/test/java/org/onap/policy/drools/core/PolicySessionFeatureApiMock.java6
-rw-r--r--policy-core/src/test/java/org/onap/policy/drools/core/jmx/PdpJmxListenerTest.java66
-rw-r--r--policy-core/src/test/java/org/onap/policy/drools/core/lock/AlwaysFailLockTest.java6
-rw-r--r--policy-core/src/test/java/org/onap/policy/drools/core/lock/AlwaysSuccessLockTest.java25
-rw-r--r--policy-management/src/main/java/org/onap/policy/drools/controller/IndexedDroolsControllerFactory.java27
-rw-r--r--policy-management/src/main/java/org/onap/policy/drools/controller/internal/MavenDroolsController.java5
-rw-r--r--policy-management/src/main/java/org/onap/policy/drools/features/PolicyControllerFeatureApi.java3
-rw-r--r--policy-management/src/main/java/org/onap/policy/drools/features/PolicyEngineFeatureApi.java4
-rw-r--r--policy-management/src/main/java/org/onap/policy/drools/persistence/FileSystemPersistence.java3
-rw-r--r--policy-management/src/main/java/org/onap/policy/drools/protocol/coders/EventProtocolCoder.java13
-rw-r--r--policy-management/src/main/java/org/onap/policy/drools/protocol/coders/GenericEventProtocolCoder.java322
-rw-r--r--policy-management/src/main/java/org/onap/policy/drools/protocol/coders/GsonProtocolCoderToolset.java37
-rw-r--r--policy-management/src/main/java/org/onap/policy/drools/protocol/coders/MultiplexorEventProtocolCoder.java47
-rw-r--r--policy-management/src/main/java/org/onap/policy/drools/protocol/coders/ProtocolCoderToolset.java10
-rw-r--r--policy-management/src/main/java/org/onap/policy/drools/protocol/coders/TopicCoderFilterConfiguration.java34
-rw-r--r--policy-management/src/main/java/org/onap/policy/drools/server/restful/RestManager.java657
-rw-r--r--policy-management/src/main/java/org/onap/policy/drools/system/PolicyEngineManager.java29
-rw-r--r--policy-management/src/main/java/org/onap/policy/drools/system/internal/LockManager.java3
-rw-r--r--policy-management/src/main/server-gen/bin/db-migrator635
-rw-r--r--policy-management/src/main/server-gen/bin/features315
-rw-r--r--policy-management/src/test/java/org/onap/policy/drools/controller/IndexedDroolsControllerFactoryTest.java154
-rw-r--r--policy-management/src/test/java/org/onap/policy/drools/controller/internal/MavenDroolsControllerUpgradesTest.java56
-rw-r--r--policy-management/src/test/java/org/onap/policy/drools/controller/internal/NullDroolsControllerTest.java89
-rw-r--r--policy-management/src/test/java/org/onap/policy/drools/features/DroolsControllerFeatureApiTest.java83
-rw-r--r--policy-management/src/test/java/org/onap/policy/drools/features/PolicyControllerFeatureApiTest.java171
-rw-r--r--policy-management/src/test/java/org/onap/policy/drools/features/PolicyEngineFeatureApiTest.java174
-rw-r--r--policy-management/src/test/java/org/onap/policy/drools/persistence/FileSystemPersistenceTest.java78
-rw-r--r--policy-management/src/test/java/org/onap/policy/drools/protocol/coders/EventProtocolCoderTest.java27
-rw-r--r--policy-management/src/test/java/org/onap/policy/drools/protocol/coders/GenericProtocolCoderTest.java651
-rw-r--r--policy-management/src/test/java/org/onap/policy/drools/protocol/coders/GsonProtocolCoderToolsetTest.java197
-rw-r--r--policy-management/src/test/java/org/onap/policy/drools/protocol/coders/MultiplexorEventProtocolCoderTest.java308
-rw-r--r--policy-management/src/test/java/org/onap/policy/drools/protocol/coders/ProtocolCoderToolsetTest.java95
-rw-r--r--policy-management/src/test/java/org/onap/policy/drools/protocol/coders/TopicCoderFilterConfigurationTest.java75
-rw-r--r--policy-management/src/test/java/org/onap/policy/drools/server/restful/RestManagerTest.java1221
-rw-r--r--policy-management/src/test/java/org/onap/policy/drools/server/restful/test/RestManagerTest.java252
-rw-r--r--policy-management/src/test/java/org/onap/policy/drools/stats/PolicyStatsManagerTest.java14
-rw-r--r--policy-management/src/test/java/org/onap/policy/drools/stats/PolicyStatsTest.java9
-rw-r--r--policy-management/src/test/java/org/onap/policy/drools/system/PolicyControllerFactoryTest.java7
-rw-r--r--policy-management/src/test/java/org/onap/policy/drools/system/PolicyEngineManagerTest.java207
-rw-r--r--policy-management/src/test/java/org/onap/policy/drools/system/PolicyEngineTest.java18
-rw-r--r--policy-management/src/test/java/org/onap/policy/drools/system/internal/FeatureLockImplTest.java16
-rw-r--r--policy-utils/pom.xml4
-rw-r--r--policy-utils/src/main/java/org/onap/policy/drools/metrics/Metric.java4
-rw-r--r--policy-utils/src/main/java/org/onap/policy/drools/policies/DomainMaker.java27
-rw-r--r--policy-utils/src/test/java/org/onap/policy/drools/metrics/MetricTest.java32
-rw-r--r--policy-utils/src/test/java/org/onap/policy/drools/policies/DomainMakerTest.java72
-rw-r--r--policy-utils/src/test/java/org/onap/policy/drools/utils/LookupTest.java57
-rw-r--r--policy-utils/src/test/java/org/onap/policy/drools/utils/PropertyUtilTest.java125
95 files changed, 5488 insertions, 2760 deletions
diff --git a/INFO.yaml b/INFO.yaml
index 4f4762c0..abf0cf58 100644
--- a/INFO.yaml
+++ b/INFO.yaml
@@ -31,11 +31,6 @@ repositories:
- 'policy/drools-pdp'
committers:
- <<: *onap_releng_ptl
- - name: 'Pamela Dragosh'
- email: 'pd1248@att.com'
- company: 'ATT'
- id: 'pdragosh'
- timezone: 'America/New_York'
- name: 'Jorge Hernandez'
email: 'jorge.hernandez-herrero@att.com'
company: 'ATT'
@@ -46,6 +41,11 @@ committers:
company: 'Bell Canada'
id: 'ramverma'
timezone: 'America/Montreal'
+ - name: 'Liam Fallon'
+ email: 'liam.fallon@est.tech'
+ id: 'liamfallon'
+ company: 'Ericsson'
+ timezone: 'Europe/Ireland'
- name: 'Ramesh Murugan Iyer'
email: 'ramesh.murugan.iyer@est.tech'
company: 'Ericsson'
@@ -89,3 +89,7 @@ tsc:
- type: 'Addition'
name: 'Adheli Tavares'
link: https://lists.onap.org/g/onap-tsc/message/9296
+ #Stepped Down
+ - type: 'Removal'
+ name: 'Pamela Dragosh'
+ link: https://lists.onap.org/g/onap-tsc/message/9550
diff --git a/feature-distributed-locking/src/assembly/assemble_zip.xml b/feature-distributed-locking/src/assembly/assemble_zip.xml
index 2112fbcd..3def9898 100644
--- a/feature-distributed-locking/src/assembly/assemble_zip.xml
+++ b/feature-distributed-locking/src/assembly/assemble_zip.xml
@@ -3,6 +3,7 @@
feature-distributed-locking
================================================================================
Copyright (C) 2018 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.
@@ -59,12 +60,6 @@
<excludes/>
</fileSet>
<fileSet>
- <directory>src/main/feature/db</directory>
- <outputDirectory>db</outputDirectory>
- <fileMode>0744</fileMode>
- <excludes/>
- </fileSet>
- <fileSet>
<directory>src/main/feature/install</directory>
<outputDirectory>install</outputDirectory>
<fileMode>0744</fileMode>
diff --git a/feature-distributed-locking/src/main/feature/config/feature-distributed-locking.properties b/feature-distributed-locking/src/main/feature/config/feature-distributed-locking.properties
index 69629e15..fa311260 100644
--- a/feature-distributed-locking/src/main/feature/config/feature-distributed-locking.properties
+++ b/feature-distributed-locking/src/main/feature/config/feature-distributed-locking.properties
@@ -3,7 +3,7 @@
# ONAP
# ================================================================================
# Copyright (C) 2018-2019, 2021-2022 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.
@@ -20,7 +20,7 @@
###
#Database properties
-jakarta.persistence.jdbc.driver=org.mariadb.jdbc.Driver
+jakarta.persistence.jdbc.driver=${envd:JDBC_DRIVER}
jakarta.persistence.jdbc.url=${envd:JDBC_URL}pooling${envd:JDBC_OPTS}
jakarta.persistence.jdbc.user=${envd:SQL_USER}
jakarta.persistence.jdbc.password=${envd:SQL_PASSWORD}
diff --git a/feature-distributed-locking/src/main/feature/db/pooling/sql/1804-distributedlocking.downgrade.sql b/feature-distributed-locking/src/main/feature/db/pooling/sql/1804-distributedlocking.downgrade.sql
deleted file mode 100644
index cd1b815d..00000000
--- a/feature-distributed-locking/src/main/feature/db/pooling/sql/1804-distributedlocking.downgrade.sql
+++ /dev/null
@@ -1,20 +0,0 @@
-# ============LICENSE_START=======================================================
-# feature-distributed-locking
-# ================================================================================
-# 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=========================================================
-
-use pooling;
-drop table if exists locks; \ No newline at end of file
diff --git a/feature-distributed-locking/src/main/feature/db/pooling/sql/1804-distributedlocking.upgrade.sql b/feature-distributed-locking/src/main/feature/db/pooling/sql/1804-distributedlocking.upgrade.sql
deleted file mode 100644
index 07b30738..00000000
--- a/feature-distributed-locking/src/main/feature/db/pooling/sql/1804-distributedlocking.upgrade.sql
+++ /dev/null
@@ -1,30 +0,0 @@
-# ============LICENSE_START=======================================================
-# feature-distributed-locking
-# ================================================================================
-# Copyright (C) 2018, 2022 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=========================================================
-
-SET foreign_key_checks=0;
-
-CREATE TABLE if NOT EXISTS pooling.locks(
- resourceId VARCHAR(128),
- host VARCHAR(128),
- owner VARCHAR(128),
- expirationTime BIGINT,
- PRIMARY KEY (resourceId),
- INDEX idx_expirationTime(expirationTime),
- INDEX idx_host(host));
-
-SET foreign_key_checks=1; \ No newline at end of file
diff --git a/feature-distributed-locking/src/main/feature/db/pooling/sql/1811-distributedlocking.downgrade.sql b/feature-distributed-locking/src/main/feature/db/pooling/sql/1811-distributedlocking.downgrade.sql
deleted file mode 100644
index 55a883f2..00000000
--- a/feature-distributed-locking/src/main/feature/db/pooling/sql/1811-distributedlocking.downgrade.sql
+++ /dev/null
@@ -1,19 +0,0 @@
-# ============LICENSE_START=======================================================
-# feature-distributed-locking
-# ================================================================================
-# Copyright (C) 2018, 2021 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=========================================================
-
-ALTER TABLE pooling.locks modify if exists expirationTime bigint(20) default 0;
diff --git a/feature-distributed-locking/src/main/feature/db/pooling/sql/1811-distributedlocking.upgrade.sql b/feature-distributed-locking/src/main/feature/db/pooling/sql/1811-distributedlocking.upgrade.sql
deleted file mode 100644
index 0cdad5b9..00000000
--- a/feature-distributed-locking/src/main/feature/db/pooling/sql/1811-distributedlocking.upgrade.sql
+++ /dev/null
@@ -1,23 +0,0 @@
-# ============LICENSE_START=======================================================
-# feature-distributed-locking
-# ================================================================================
-# Copyright (C) 2018, 2021-2022 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=========================================================
-
-SET foreign_key_checks=0;
-
-ALTER TABLE pooling.locks MODIFY expirationTime TIMESTAMP DEFAULT '1971-01-01 00:00:00.000000';
-
-SET foreign_key_checks=1;
diff --git a/feature-distributed-locking/src/main/feature/install/disable b/feature-distributed-locking/src/main/feature/install/disable
deleted file mode 100644
index be455734..00000000
--- a/feature-distributed-locking/src/main/feature/install/disable
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/usr/bin/env sh
-
-# ============LICENSE_START=======================================================
-# ONAP
-# ================================================================================
-# Copyright (C) 2018-2021 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=========================================================
-
-if [ "${DEBUG}" = "y" ]; then
- set -x
-fi
-
-${POLICY_HOME}/bin/db-migrator -s pooling -o downgrade
-
diff --git a/feature-distributed-locking/src/main/feature/install/enable b/feature-distributed-locking/src/main/feature/install/enable
deleted file mode 100644
index af202f56..00000000
--- a/feature-distributed-locking/src/main/feature/install/enable
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/usr/bin/env sh
-
-# ============LICENSE_START=======================================================
-# ONAP
-# ================================================================================
-# Copyright (C) 2018-2021 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=========================================================
-
-if [ "${DEBUG}" = "y" ]; then
- set -x
-fi
-
-${POLICY_HOME}/bin/db-migrator -s pooling -o upgrade
-
diff --git a/feature-distributed-locking/src/main/java/org/onap/policy/distributed/locking/DistributedLockManager.java b/feature-distributed-locking/src/main/java/org/onap/policy/distributed/locking/DistributedLockManager.java
index d7f857eb..e9f1453a 100644
--- a/feature-distributed-locking/src/main/java/org/onap/policy/distributed/locking/DistributedLockManager.java
+++ b/feature-distributed-locking/src/main/java/org/onap/policy/distributed/locking/DistributedLockManager.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.
@@ -24,6 +25,9 @@ import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.SQLTransientException;
+import java.sql.Timestamp;
+import java.time.Instant;
+import java.time.temporal.ChronoUnit;
import java.util.HashSet;
import java.util.Map;
import java.util.Properties;
@@ -57,11 +61,8 @@ import org.slf4j.LoggerFactory;
* Distributed implementation of the Lock Feature. Maintains locks across servers using a
* shared DB.
*
- * <p/>
- * Note: this implementation does <i>not</i> honor the waitForLocks={@code true}
- * parameter.
- *
- * <p/>
+ * <p>Note: this implementation does <i>not</i> honor the waitForLocks={@code true}
+ * parameter.<p/>
* Additional Notes:
* <dl>
* <li>The <i>owner</i> field in the DB is not derived from the lock's owner info, but is
@@ -77,7 +78,7 @@ import org.slf4j.LoggerFactory;
* </dl>
*/
public class DistributedLockManager extends LockManager<DistributedLockManager.DistributedLock>
- implements PolicyEngineFeatureApi {
+ implements PolicyEngineFeatureApi {
private static final Logger logger = LoggerFactory.getLogger(DistributedLockManager.class);
@@ -141,11 +142,11 @@ public class DistributedLockManager extends LockManager<DistributedLockManager.D
}
@Override
- public PolicyResourceLockManager beforeCreateLockManager(PolicyEngine engine, Properties properties) {
+ public PolicyResourceLockManager beforeCreateLockManager() {
try {
this.pdpName = PolicyEngineConstants.getManager().getPdpName();
- this.featProps = new DistributedLockProperties(getProperties(CONFIGURATION_PROPERTIES_NAME));
+ this.featProps = new DistributedLockProperties(getProperties());
this.dataSource = makeDataSource();
return this;
@@ -176,9 +177,9 @@ public class DistributedLockManager extends LockManager<DistributedLockManager.D
* Make data source.
*
* @return a new, pooled data source
- * @throws Exception exception
+ * @throws SQLException exception
*/
- protected BasicDataSource makeDataSource() throws Exception {
+ protected BasicDataSource makeDataSource() throws SQLException {
var props = new Properties();
props.put("driverClassName", featProps.getDbDriver());
props.put("url", featProps.getDbUrl());
@@ -199,7 +200,7 @@ public class DistributedLockManager extends LockManager<DistributedLockManager.D
logger.info("deleting all expired locks from the DB");
try (var conn = dataSource.getConnection();
- var stmt = conn.prepareStatement("DELETE FROM pooling.locks WHERE expirationTime <= now()")) {
+ var stmt = conn.prepareStatement("DELETE FROM pooling.locks WHERE expirationTime <= now()")) {
int ndel = stmt.executeUpdate();
logger.info("deleted {} expired locks from the DB", ndel);
@@ -398,17 +399,17 @@ public class DistributedLockManager extends LockManager<DistributedLockManager.D
/**
* Constructs the object.
*
- * @param state initial state of the lock
+ * @param state initial state of the lock
* @param resourceId identifier of the resource to be locked
- * @param ownerKey information identifying the owner requesting the lock
- * @param holdSec amount of time, in seconds, for which the lock should be held,
- * after which it will automatically be released
- * @param callback callback to be invoked once the lock is granted, or
- * subsequently lost; must not be {@code null}
- * @param feature feature containing this lock
+ * @param ownerKey information identifying the owner requesting the lock
+ * @param holdSec amount of time, in seconds, for which the lock should be held,
+ * after which it will automatically be released
+ * @param callback callback to be invoked once the lock is granted, or
+ * subsequently lost; must not be {@code null}
+ * @param feature feature containing this lock
*/
public DistributedLock(LockState state, String resourceId, String ownerKey, int holdSec, LockCallback callback,
- DistributedLockManager feature) {
+ DistributedLockManager feature) {
super(state, resourceId, ownerKey, holdSec, callback);
this.feature = feature;
@@ -531,7 +532,6 @@ public class DistributedLockManager extends LockManager<DistributedLockManager.D
* there are no more requests in the queue.
*
* @param prevReq the previous request that was just run
- *
* @return the next request, or {@code null} if the queue is empty
*/
private synchronized RunnableWithEx getNextRequest(RunnableWithEx prevReq) {
@@ -699,19 +699,19 @@ public class DistributedLockManager extends LockManager<DistributedLockManager.D
* Inserts the lock into the DB.
*
* @param conn DB connection
- * @return {@code true} if a record was successfully inserted, {@code false}
- * otherwise
+ * @return {@code true} if a record was successfully inserted, {@code false}otherwise
* @throws SQLException if a DB error occurs
*/
protected boolean doDbInsert(Connection conn) throws SQLException {
logger.info("insert lock record {}", this);
- try (var stmt = conn.prepareStatement("INSERT INTO pooling.locks (resourceId, host, owner, expirationTime) "
- + "values (?, ?, ?, timestampadd(second, ?, now()))")) {
+ var time = Instant.now().plus(getHoldSec(), ChronoUnit.SECONDS);
+ String sql = "INSERT INTO pooling.locks (resourceId, host, owner, expirationTime) values (?, ?, ?, ?)";
+ try (var stmt = conn.prepareStatement(sql)) {
stmt.setString(1, getResourceId());
stmt.setString(2, feature.pdpName);
stmt.setString(3, feature.uuidString);
- stmt.setInt(4, getHoldSec());
+ stmt.setTimestamp(4, new Timestamp(time.toEpochMilli()));
stmt.executeUpdate();
@@ -726,20 +726,21 @@ public class DistributedLockManager extends LockManager<DistributedLockManager.D
* Updates the lock in the DB.
*
* @param conn DB connection
- * @return {@code true} if a record was successfully updated, {@code false}
- * otherwise
+ * @return {@code true} if a record was successfully updated, {@code false} otherwise
* @throws SQLException if a DB error occurs
*/
protected boolean doDbUpdate(Connection conn) throws SQLException {
logger.info("update lock record {}", this);
- try (var stmt = conn.prepareStatement("UPDATE pooling.locks SET resourceId=?, host=?, owner=?,"
- + " expirationTime=timestampadd(second, ?, now()) WHERE resourceId=?"
- + " AND ((host=? AND owner=?) OR expirationTime < now())")) {
+ var time = Instant.now().plus(getHoldSec(), ChronoUnit.SECONDS);
+ var query = "UPDATE pooling.locks SET resourceId=?, host=?, owner=?,"
+ + " expirationTime=? WHERE resourceId=?"
+ + " AND ((host=? AND owner=?) OR expirationTime < now())";
+ try (var stmt = conn.prepareStatement(query)) {
stmt.setString(1, getResourceId());
stmt.setString(2, feature.pdpName);
stmt.setString(3, feature.uuidString);
- stmt.setInt(4, getHoldSec());
+ stmt.setTimestamp(4, new Timestamp(time.toEpochMilli()));
stmt.setString(5, getResourceId());
stmt.setString(6, this.hostName);
@@ -764,8 +765,8 @@ public class DistributedLockManager extends LockManager<DistributedLockManager.D
*/
protected void doDbDelete(Connection conn) throws SQLException {
logger.info("delete lock record {}", this);
- try (var stmt = conn
- .prepareStatement("DELETE FROM pooling.locks WHERE resourceId=? AND host=? AND owner=?")) {
+ var query = "DELETE FROM pooling.locks WHERE resourceId=? AND host=? AND owner=?";
+ try (var stmt = conn.prepareStatement(query)) {
stmt.setString(1, getResourceId());
stmt.setString(2, this.hostName);
@@ -793,8 +794,8 @@ public class DistributedLockManager extends LockManager<DistributedLockManager.D
@Override
public String toString() {
return "DistributedLock [state=" + getState() + ", resourceId=" + getResourceId() + ", ownerKey="
- + getOwnerKey() + ", holdSec=" + getHoldSec() + ", hostName=" + hostName + ", uuidString="
- + uuidString + "]";
+ + getOwnerKey() + ", holdSec=" + getHoldSec() + ", hostName=" + hostName + ", uuidString="
+ + uuidString + "]";
}
}
@@ -811,12 +812,13 @@ public class DistributedLockManager extends LockManager<DistributedLockManager.D
// these may be overridden by junit tests
- protected Properties getProperties(String fileName) {
- return SystemPersistenceConstants.getManager().getProperties(fileName);
+ protected Properties getProperties() {
+ return SystemPersistenceConstants.getManager().getProperties(
+ DistributedLockManager.CONFIGURATION_PROPERTIES_NAME);
}
protected DistributedLock makeLock(LockState state, String resourceId, String ownerKey, int holdSec,
- LockCallback callback) {
+ LockCallback callback) {
return new DistributedLock(state, resourceId, ownerKey, holdSec, callback, this);
}
}
diff --git a/feature-distributed-locking/src/test/java/org/onap/policy/distributed/locking/DistributedLockManagerTest.java b/feature-distributed-locking/src/test/java/org/onap/policy/distributed/locking/DistributedLockManagerTest.java
index 2e173cf0..579d53cc 100644
--- a/feature-distributed-locking/src/test/java/org/onap/policy/distributed/locking/DistributedLockManagerTest.java
+++ b/feature-distributed-locking/src/test/java/org/onap/policy/distributed/locking/DistributedLockManagerTest.java
@@ -141,12 +141,12 @@ class DistributedLockManagerTest {
private LockCallback callback;
@Mock
- private BasicDataSource datasrc;
+ private BasicDataSource dataSource;
private DistributedLock lock;
- private AtomicInteger nactive;
- private AtomicInteger nsuccesses;
+ private AtomicInteger numActive;
+ private AtomicInteger numSuccess;
private DistributedLockManager feature;
AutoCloseable closeable;
@@ -204,8 +204,8 @@ class DistributedLockManagerTest {
session.setPolicySession();
- nactive = new AtomicInteger(0);
- nsuccesses = new AtomicInteger(0);
+ numActive = new AtomicInteger(0);
+ numSuccess = new AtomicInteger(0);
cleanDb();
@@ -248,7 +248,7 @@ class DistributedLockManagerTest {
@Test
void testBeforeCreateLockManager() {
- assertSame(feature, feature.beforeCreateLockManager(engine, new Properties()));
+ assertSame(feature, feature.beforeCreateLockManager());
}
/**
@@ -260,13 +260,12 @@ class DistributedLockManagerTest {
feature = new MyLockingFeature(false) {
@Override
- protected Properties getProperties(String fileName) {
+ protected Properties getProperties() {
throw new IllegalArgumentException(EXPECTED_EXCEPTION);
}
};
- Properties props = new Properties();
- assertThatThrownBy(() -> feature.beforeCreateLockManager(engine, props))
+ assertThatThrownBy(() -> feature.beforeCreateLockManager())
.isInstanceOf(DistributedLockManagerException.class);
}
@@ -317,7 +316,6 @@ class DistributedLockManagerTest {
/**
* Tests deleteExpiredDbLocks(), when getConnection() throws an exception.
- *
*/
@Test
void testDeleteExpiredDbLocksEx() {
@@ -347,7 +345,6 @@ class DistributedLockManagerTest {
/**
* Tests afterStop(), when the data source throws an exception when close() is called.
- *
*/
@Test
void testAfterStopEx() {
@@ -416,10 +413,10 @@ class DistributedLockManagerTest {
void testCreateLockNotLatestInstance() {
DistributedLockManager.setLatestInstance(null);
- Lock lock = feature.createLock(RESOURCE, OWNER_KEY, HOLD_SEC, callback, false);
- assertTrue(lock.isUnavailable());
+ Lock newLock = feature.createLock(RESOURCE, OWNER_KEY, HOLD_SEC, callback, false);
+ assertTrue(newLock.isUnavailable());
verify(callback, never()).lockAvailable(any());
- verify(callback).lockUnavailable(lock);
+ verify(callback).lockUnavailable(newLock);
}
@Test
@@ -532,11 +529,11 @@ class DistributedLockManagerTest {
feature = new MyLockingFeature(true) {
@Override
- protected BasicDataSource makeDataSource() throws Exception {
+ protected BasicDataSource makeDataSource() throws SQLException {
// get the real data source
BasicDataSource src2 = super.makeDataSource();
- when(datasrc.getConnection()).thenAnswer(answer -> {
+ when(dataSource.getConnection()).thenAnswer(answer -> {
DistributedLock lck = freeLock.getAndSet(null);
if (lck != null) {
// free it
@@ -549,7 +546,7 @@ class DistributedLockManagerTest {
return src2.getConnection();
});
- return datasrc;
+ return dataSource;
}
};
@@ -596,11 +593,11 @@ class DistributedLockManagerTest {
@Test
void testDistributedLockNoArgs() {
- DistributedLock lock = new DistributedLock();
- assertNull(lock.getResourceId());
- assertNull(lock.getOwnerKey());
- assertNull(lock.getCallback());
- assertEquals(0, lock.getHoldSec());
+ DistributedLock newLock = new DistributedLock();
+ assertNull(newLock.getResourceId());
+ assertNull(newLock.getOwnerKey());
+ assertNull(newLock.getCallback());
+ assertEquals(0, newLock.getHoldSec());
}
@Test
@@ -615,15 +612,15 @@ class DistributedLockManagerTest {
@Test
void testDistributedLockSerializable() throws Exception {
- DistributedLock lock = getLock(RESOURCE, callback);
- lock = roundTrip(lock);
+ DistributedLock newLock = getLock(RESOURCE, callback);
+ newLock = roundTrip(newLock);
- assertTrue(lock.isWaiting());
+ assertTrue(newLock.isWaiting());
- assertEquals(RESOURCE, lock.getResourceId());
- assertEquals(OWNER_KEY, lock.getOwnerKey());
- assertNull(lock.getCallback());
- assertEquals(HOLD_SEC, lock.getHoldSec());
+ assertEquals(RESOURCE, newLock.getResourceId());
+ assertEquals(OWNER_KEY, newLock.getOwnerKey());
+ assertNull(newLock.getCallback());
+ assertEquals(HOLD_SEC, newLock.getHoldSec());
}
@Test
@@ -690,13 +687,13 @@ class DistributedLockManagerTest {
*/
@Test
void testDistributedLockFreeSerialized() throws Exception {
- DistributedLock lock = getLock(RESOURCE, callback);
+ DistributedLock newLock = getLock(RESOURCE, callback);
feature = new MyLockingFeature(true);
- lock = roundTrip(lock);
- assertTrue(lock.free());
- assertTrue(lock.isUnavailable());
+ newLock = roundTrip(newLock);
+ assertTrue(newLock.free());
+ assertTrue(newLock.isUnavailable());
}
/**
@@ -706,13 +703,13 @@ class DistributedLockManagerTest {
*/
@Test
void testDistributedLockFreeNoFeature() throws Exception {
- DistributedLock lock = getLock(RESOURCE, callback);
+ DistributedLock newLock = getLock(RESOURCE, callback);
DistributedLockManager.setLatestInstance(null);
- lock = roundTrip(lock);
- assertFalse(lock.free());
- assertTrue(lock.isUnavailable());
+ newLock = roundTrip(newLock);
+ assertFalse(newLock.free());
+ assertTrue(newLock.isUnavailable());
}
/**
@@ -788,28 +785,28 @@ class DistributedLockManagerTest {
*/
@Test
void testDistributedLockExtendSerialized() throws Exception {
- DistributedLock lock = getLock(RESOURCE, callback);
+ DistributedLock newLock = getLock(RESOURCE, callback);
// run doLock
runLock(0, 0);
- assertTrue(lock.isActive());
+ assertTrue(newLock.isActive());
feature = new MyLockingFeature(true);
- lock = roundTrip(lock);
- assertTrue(lock.isActive());
+ newLock = roundTrip(newLock);
+ assertTrue(newLock.isActive());
- LockCallback scallback = mock(LockCallback.class);
+ LockCallback mockCallback = mock(LockCallback.class);
- lock.extend(HOLD_SEC, scallback);
- assertTrue(lock.isWaiting());
+ newLock.extend(HOLD_SEC, mockCallback);
+ assertTrue(newLock.isWaiting());
// run doExtend (in new feature)
runLock(0, 0);
- assertTrue(lock.isActive());
+ assertTrue(newLock.isActive());
- verify(scallback).lockAvailable(lock);
- verify(scallback, never()).lockUnavailable(lock);
+ verify(mockCallback).lockAvailable(newLock);
+ verify(mockCallback, never()).lockUnavailable(newLock);
}
/**
@@ -819,24 +816,24 @@ class DistributedLockManagerTest {
*/
@Test
void testDistributedLockExtendNoFeature() throws Exception {
- DistributedLock lock = getLock(RESOURCE, callback);
+ DistributedLock newLock = getLock(RESOURCE, callback);
// run doLock
runLock(0, 0);
- assertTrue(lock.isActive());
+ assertTrue(newLock.isActive());
DistributedLockManager.setLatestInstance(null);
- lock = roundTrip(lock);
- assertTrue(lock.isActive());
+ newLock = roundTrip(newLock);
+ assertTrue(newLock.isActive());
LockCallback scallback = mock(LockCallback.class);
- lock.extend(HOLD_SEC, scallback);
- assertTrue(lock.isUnavailable());
+ newLock.extend(HOLD_SEC, scallback);
+ assertTrue(newLock.isUnavailable());
- verify(scallback, never()).lockAvailable(lock);
- verify(scallback).lockUnavailable(lock);
+ verify(scallback, never()).lockAvailable(newLock);
+ verify(scallback).lockUnavailable(newLock);
}
/**
@@ -964,7 +961,7 @@ class DistributedLockManagerTest {
feature = new MyLockingFeature(true) {
@Override
protected DistributedLock makeLock(LockState state, String resourceId, String ownerKey, int holdSec,
- LockCallback callback) {
+ LockCallback callback) {
return new DistributedLock(state, resourceId, ownerKey, holdSec, callback, feature) {
private static final long serialVersionUID = 1L;
@@ -1015,13 +1012,13 @@ class DistributedLockManagerTest {
@Test
void testDistributedLockDoRequestRunExWaiting() throws SQLException {
// throw run-time exception
- when(datasrc.getConnection()).thenThrow(new IllegalStateException(EXPECTED_EXCEPTION));
+ when(dataSource.getConnection()).thenThrow(new IllegalStateException(EXPECTED_EXCEPTION));
// use a data source that throws an exception when getConnection() is called
feature = new MyLockingFeature(true) {
@Override
protected BasicDataSource makeDataSource() {
- return datasrc;
+ return dataSource;
}
};
@@ -1045,7 +1042,7 @@ class DistributedLockManagerTest {
@Test
void testDistributedLockDoRequestRunExUnavailable() throws SQLException {
// throw run-time exception
- when(datasrc.getConnection()).thenAnswer(answer -> {
+ when(dataSource.getConnection()).thenAnswer(answer -> {
lock.free();
throw new IllegalStateException(EXPECTED_EXCEPTION);
});
@@ -1054,7 +1051,7 @@ class DistributedLockManagerTest {
feature = new MyLockingFeature(true) {
@Override
protected BasicDataSource makeDataSource() {
- return datasrc;
+ return dataSource;
}
};
@@ -1232,7 +1229,6 @@ class DistributedLockManagerTest {
/**
* Tests doUnlock() when a DB exception is thrown.
- *
*/
@Test
void testDistributedLockDoUnlockEx() {
@@ -1337,7 +1333,6 @@ class DistributedLockManagerTest {
/**
* Tests doExtend() when both update and insert fail.
- *
*/
@Test
void testDistributedLockDoExtendNeitherSucceeds() {
@@ -1348,7 +1343,7 @@ class DistributedLockManagerTest {
feature = new MyLockingFeature(true) {
@Override
protected DistributedLock makeLock(LockState state, String resourceId, String ownerKey, int holdSec,
- LockCallback callback) {
+ LockCallback callback) {
return new DistributedLock(state, resourceId, ownerKey, holdSec, callback, feature) {
private static final long serialVersionUID = 1L;
private int ntimes = 0;
@@ -1437,7 +1432,7 @@ class DistributedLockManagerTest {
feature = new DistributedLockManager();
// this should create a thread pool
- feature.beforeCreateLockManager(engine, new Properties());
+ feature.beforeCreateLockManager();
feature.afterStart(engine);
assertThatCode(this::shutdownFeature).doesNotThrowAnyException();
@@ -1447,14 +1442,14 @@ class DistributedLockManagerTest {
* Performs a multithreaded test of the locking facility.
*
* @throws InterruptedException if the current thread is interrupted while waiting for
- * the background threads to complete
+ * the background threads to complete
*/
@Test
void testMultiThreaded() throws InterruptedException {
ReflectionTestUtils.setField(PolicyEngineConstants.getManager(), POLICY_ENGINE_EXECUTOR_FIELD, realExec);
feature = new DistributedLockManager();
- feature.beforeCreateLockManager(PolicyEngineConstants.getManager(), new Properties());
+ feature.beforeCreateLockManager();
feature.afterStart(PolicyEngineConstants.getManager());
List<MyThread> threads = new ArrayList<>(MAX_THREADS);
@@ -1475,7 +1470,7 @@ class DistributedLockManagerTest {
}
}
- assertTrue(nsuccesses.get() > 0);
+ assertTrue(numSuccess.get() > 0);
}
private DistributedLock getLock(String resource, LockCallback callback) {
@@ -1511,9 +1506,9 @@ class DistributedLockManagerTest {
/**
* Runs a lock action (e.g., doLock, doUnlock).
*
- * @param nskip number of actions in the work queue to skip
+ * @param nskip number of actions in the work queue to skip
* @param nadditional number of additional actions that appear in the work queue
- * <i>after</i> the desired action
+ * <i>after</i> the desired action
*/
void runLock(int nskip, int nadditional) {
ArgumentCaptor<Runnable> captor = ArgumentCaptor.forClass(Runnable.class);
@@ -1544,7 +1539,7 @@ class DistributedLockManagerTest {
*/
private int getRecordCount() throws SQLException {
try (PreparedStatement stmt = conn.prepareStatement("SELECT count(*) FROM pooling.locks");
- ResultSet result = stmt.executeQuery()) {
+ ResultSet result = stmt.executeQuery()) {
if (result.next()) {
return result.getInt(1);
@@ -1561,16 +1556,16 @@ class DistributedLockManagerTest {
*
* @param resourceId ID of the resource of interest
* @param uuidString UUID string of the owner
- * @param holdSec seconds for which the lock was to be held
- * @param tbegin earliest time, in milliseconds, at which the record could have been
- * inserted into the DB
+ * @param holdSec seconds for which the lock was to be held
+ * @param tbegin earliest time, in milliseconds, at which the record could have been
+ * inserted into the DB
* @return {@code true} if a record is found, {@code false} otherwise
* @throws SQLException if an error occurs accessing the DB
*/
private boolean recordInRange(String resourceId, String uuidString, int holdSec, long tbegin) throws SQLException {
try (PreparedStatement stmt =
- conn.prepareStatement("SELECT timestampdiff(second, now(), expirationTime) FROM pooling.locks"
- + " WHERE resourceId=? AND host=? AND owner=?")) {
+ conn.prepareStatement("SELECT timestampdiff(second, now(), expirationTime) FROM pooling.locks"
+ + " WHERE resourceId=? AND host=? AND owner=?")) {
stmt.setString(1, resourceId);
stmt.setString(2, feature.getPdpName());
@@ -1592,8 +1587,8 @@ class DistributedLockManagerTest {
/**
* Inserts a record into the DB.
*
- * @param resourceId ID of the resource of interest
- * @param uuidString UUID string of the owner
+ * @param resourceId ID of the resource of interest
+ * @param uuidString UUID string of the owner
* @param expireOffset offset, in seconds, from "now", at which the lock should expire
* @throws SQLException if an error occurs accessing the DB
*/
@@ -1604,8 +1599,8 @@ class DistributedLockManagerTest {
private void insertRecord(String resourceId, String hostName, String uuidString, int expireOffset)
throws SQLException {
try (PreparedStatement stmt =
- conn.prepareStatement("INSERT INTO pooling.locks (resourceId, host, owner, expirationTime) "
- + "values (?, ?, ?, timestampadd(second, ?, now()))")) {
+ conn.prepareStatement("INSERT INTO pooling.locks (resourceId, host, owner, expirationTime) "
+ + "values (?, ?, ?, timestampadd(second, ?, now()))")) {
stmt.setString(1, resourceId);
stmt.setString(2, hostName);
@@ -1619,8 +1614,8 @@ class DistributedLockManagerTest {
/**
* Updates a record in the DB.
*
- * @param resourceId ID of the resource of interest
- * @param newUuid UUID string of the <i>new</i> owner
+ * @param resourceId ID of the resource of interest
+ * @param newUuid UUID string of the <i>new</i> owner
* @param expireOffset offset, in seconds, from "now", at which the lock should expire
* @throws SQLException if an error occurs accessing the DB
*/
@@ -1650,7 +1645,7 @@ class DistributedLockManagerTest {
ReflectionTestUtils.setField(PolicyEngineConstants.getManager(), POLICY_ENGINE_EXECUTOR_FIELD, exsvc);
if (init) {
- beforeCreateLockManager(engine, new Properties());
+ beforeCreateLockManager();
start();
afterStart(engine);
}
@@ -1671,14 +1666,14 @@ class DistributedLockManagerTest {
this.isTransient = isTransient;
- this.beforeCreateLockManager(engine, new Properties());
+ this.beforeCreateLockManager();
this.start();
this.afterStart(engine);
}
@Override
- protected BasicDataSource makeDataSource() throws Exception {
- lenient().when(datasrc.getConnection()).thenAnswer(answer -> {
+ protected BasicDataSource makeDataSource() throws SQLException {
+ lenient().when(dataSource.getConnection()).thenAnswer(answer -> {
if (freeLock) {
freeLock = false;
lock.free();
@@ -1687,9 +1682,9 @@ class DistributedLockManagerTest {
throw makeEx();
});
- doThrow(makeEx()).when(datasrc).close();
+ doThrow(makeEx()).when(dataSource).close();
- return datasrc;
+ return dataSource;
}
protected SQLException makeEx() {
@@ -1715,7 +1710,7 @@ class DistributedLockManagerTest {
@Override
protected DistributedLock makeLock(LockState state, String resourceId, String ownerKey, int holdSec,
- LockCallback callback) {
+ LockCallback callback) {
return new DistributedLock(state, resourceId, ownerKey, holdSec, callback, feature) {
private static final long serialVersionUID = 1L;
@@ -1785,27 +1780,27 @@ class DistributedLockManagerTest {
}
};
- Lock lock = feature.createLock(RESOURCE, getName(), HOLD_SEC, cb, false);
+ Lock newLock = feature.createLock(RESOURCE, getName(), HOLD_SEC, cb, false);
// wait for callback, whether available or unavailable
assertTrue(sem.tryAcquire(5, TimeUnit.SECONDS));
- if (!lock.isActive()) {
+ if (!newLock.isActive()) {
return;
}
- nsuccesses.incrementAndGet();
+ numSuccess.incrementAndGet();
- assertEquals(1, nactive.incrementAndGet());
+ assertEquals(1, numActive.incrementAndGet());
- lock.extend(HOLD_SEC2, cb);
+ newLock.extend(HOLD_SEC2, cb);
assertTrue(sem.tryAcquire(5, TimeUnit.SECONDS));
- assertTrue(lock.isActive());
+ assertTrue(newLock.isActive());
// decrement BEFORE free()
- nactive.decrementAndGet();
+ numActive.decrementAndGet();
- assertTrue(lock.free());
- assertTrue(lock.isUnavailable());
+ assertTrue(newLock.free());
+ assertTrue(newLock.isUnavailable());
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
diff --git a/feature-healthcheck/src/assembly/assemble_zip.xml b/feature-healthcheck/src/assembly/assemble_zip.xml
index 0e2eaa8b..3f60900e 100644
--- a/feature-healthcheck/src/assembly/assemble_zip.xml
+++ b/feature-healthcheck/src/assembly/assemble_zip.xml
@@ -3,6 +3,7 @@
feature-healthcheck
================================================================================
Copyright (C) 2017 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.
@@ -59,12 +60,6 @@
<excludes/>
</fileSet>
<fileSet>
- <directory>src/main/feature/db</directory>
- <outputDirectory>db</outputDirectory>
- <fileMode>0744</fileMode>
- <excludes/>
- </fileSet>
- <fileSet>
<directory>src/main/feature/install</directory>
<outputDirectory>install</outputDirectory>
<fileMode>0744</fileMode>
diff --git a/feature-healthcheck/src/test/java/org/onap/policy/drools/healthcheck/HealthCheckFeatureTest.java b/feature-healthcheck/src/test/java/org/onap/policy/drools/healthcheck/HealthCheckFeatureTest.java
index 7cf7ed5f..90413041 100644
--- a/feature-healthcheck/src/test/java/org/onap/policy/drools/healthcheck/HealthCheckFeatureTest.java
+++ b/feature-healthcheck/src/test/java/org/onap/policy/drools/healthcheck/HealthCheckFeatureTest.java
@@ -23,6 +23,7 @@ package org.onap.policy.drools.healthcheck;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doAnswer;
@@ -115,58 +116,31 @@ public class HealthCheckFeatureTest {
var reports = healthcheck(manager);
serverChecks(reports);
checkReports(reports, List.of("STUCK"),
- HttpStatus.OK_200, HttpStatus.getMessage(200));
+ HttpStatus.OK_200, HttpStatus.getMessage(200));
checkReports(reports, List.of("echo"), 1, "[echo:{java.lang.String=1}]");
/* mock controller and clients stuck */
RestMockHealthCheck.stuck = true; // make the server named STUCK unresponsive
doAnswer(AdditionalAnswers
- .answersWithDelay((manager.getTimeoutSeconds() + 2) * 1000L,
- invocationOnMock -> new HashMap<String, Integer>()))
- .when(manager).getFactTypes(any(), any());
+ .answersWithDelay((manager.getTimeoutSeconds() + 2) * 1000L,
+ invocationOnMock -> new HashMap<String, Integer>()))
+ .when(manager).getFactTypes(any(), any());
reports = healthcheck(manager);
RestMockHealthCheck.stuck = false; // unstuck the server named STUCK
serverChecks(reports);
checkReports(reports, List.of("STUCK"),
- HealthCheckManager.TIMEOUT_CODE, HealthCheckManager.TIMEOUT_MESSAGE);
+ HealthCheckManager.TIMEOUT_CODE, HealthCheckManager.TIMEOUT_MESSAGE);
- assertTrue(RestMockHealthCheck.WAIT * 1000 > HealthCheckManagerTest.select(reports, "STUCK",
- HealthCheckManager.TIMEOUT_CODE, HealthCheckManager.TIMEOUT_MESSAGE)
- .get(0).getElapsedTime());
+ assertTrue(RestMockHealthCheck.wait * 1000 > HealthCheckManagerTest.select(reports, "STUCK",
+ HealthCheckManager.TIMEOUT_CODE, HealthCheckManager.TIMEOUT_MESSAGE)
+ .get(0).getElapsedTime());
feature.afterShutdown(PolicyEngineConstants.getManager());
}
- private void checkReports(Reports reports, List<String> reportNames, int code, String message) {
- reportNames
- .forEach(name -> assertEquals(1,
- HealthCheckManagerTest.select(reports, name, code, message).size()));
- }
-
- private Reports healthcheck(HealthCheck manager) {
- var reports = manager.healthCheck();
- logger.info("{}", reports);
- return reports;
- }
-
- private void checkOpen(int port) throws InterruptedException {
- if (!NetworkUtil.isTcpPortOpen("localhost", port, 5, 10000L)) {
- throw new IllegalStateException("cannot connect to port " + port);
- }
- }
-
- private void serverChecks(Reports reports) {
- checkReports(reports, List.of("HEALTHCHECK", "LIVENESS"),
- HttpStatus.OK_200, HttpStatus.getMessage(200));
- checkReports(reports, List.of("UNAUTH"),
- HttpStatus.UNAUTHORIZED_401, HttpStatus.getMessage(401));
- checkReports(reports, List.of(HealthCheckManager.ENGINE_NAME),
- HealthCheckManager.SUCCESS_CODE, HealthCheckManager.ENABLED_MESSAGE);
- }
-
@Test
void testGetSequenceNumber() {
assertEquals(1000, new HealthCheckFeature().getSequenceNumber());
@@ -218,6 +192,38 @@ public class HealthCheckFeatureTest {
assertFalse(feature.afterShutdown(null));
}
+ @Test
+ void testGetManager() {
+ assertNotNull(new HealthCheckFeature().getManager());
+ }
+
+ private void checkReports(Reports reports, List<String> reportNames, int code, String message) {
+ reportNames
+ .forEach(name -> assertEquals(1,
+ HealthCheckManagerTest.select(reports, name, code, message).size()));
+ }
+
+ private Reports healthcheck(HealthCheck manager) {
+ var reports = manager.healthCheck();
+ logger.info("{}", reports);
+ return reports;
+ }
+
+ private void checkOpen(int port) throws InterruptedException {
+ if (!NetworkUtil.isTcpPortOpen("localhost", port, 5, 10000L)) {
+ throw new IllegalStateException("cannot connect to port " + port);
+ }
+ }
+
+ private void serverChecks(Reports reports) {
+ checkReports(reports, List.of("HEALTHCHECK", "LIVENESS"),
+ HttpStatus.OK_200, HttpStatus.getMessage(200));
+ checkReports(reports, List.of("UNAUTH"),
+ HttpStatus.UNAUTHORIZED_401, HttpStatus.getMessage(401));
+ checkReports(reports, List.of(HealthCheckManager.ENGINE_NAME),
+ HealthCheckManager.SUCCESS_CODE, HealthCheckManager.ENABLED_MESSAGE);
+ }
+
/**
* Feature that returns a particular monitor.
*/
diff --git a/feature-healthcheck/src/test/java/org/onap/policy/drools/healthcheck/RestMockHealthCheck.java b/feature-healthcheck/src/test/java/org/onap/policy/drools/healthcheck/RestMockHealthCheck.java
index d2376d9d..ace32dc4 100644
--- a/feature-healthcheck/src/test/java/org/onap/policy/drools/healthcheck/RestMockHealthCheck.java
+++ b/feature-healthcheck/src/test/java/org/onap/policy/drools/healthcheck/RestMockHealthCheck.java
@@ -3,6 +3,7 @@
* ONAP
* ================================================================================
* Copyright (C) 2017-2018,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.
@@ -36,7 +37,7 @@ public class RestMockHealthCheck {
protected static final String OK_MESSAGE = "All Alive";
protected static volatile boolean stuck = false;
- protected static volatile long WAIT = 15;
+ protected static volatile long wait = 15;
@GET
@Path("healthcheck/test")
@@ -49,7 +50,7 @@ public class RestMockHealthCheck {
@Path("healthcheck/stuck")
@Produces({MediaType.APPLICATION_JSON, YamlMessageBodyHandler.APPLICATION_YAML})
public Response stuck() {
- await().atMost(WAIT, TimeUnit.SECONDS).until(() -> !stuck);
+ await().atMost(wait, TimeUnit.SECONDS).until(() -> !stuck);
return Response.status(Status.OK).entity("I may be stuck: " + stuck).build();
}
}
diff --git a/feature-legacy-config/src/main/feature/config/feature-legacy-config.properties b/feature-legacy-config/src/main/feature/config/feature-legacy-config.properties
index 9cb73c58..087f40c9 100644
--- a/feature-legacy-config/src/main/feature/config/feature-legacy-config.properties
+++ b/feature-legacy-config/src/main/feature/config/feature-legacy-config.properties
@@ -26,4 +26,5 @@ kafka.source.topics.pdpd-configuration.apiSecret=${envd:PDPD_CONFIGURATION_API_S
kafka.source.topics.pdpd-configuration.consumerGroup=${envd:PDPD_CONFIGURATION_CONSUMER_GROUP}
kafka.source.topics.pdpd-configuration.consumerInstance=${envd:PDPD_CONFIGURATION_CONSUMER_INSTANCE}
kafka.source.topics.pdpd-configuration.managed=false
-kafka.source.topics.pdpd-configuration.https=${envd:KAFKA_HTTPS:false}
+kafka.source.topics.pdpd-configuration.https=${env:KAFKA_HTTPS:false}
+kafka.source.topics.pdpd-configuration.additionalProps=${env:KAFKA_ADDITIONAL_PROPS}
diff --git a/feature-lifecycle/src/main/feature/config/feature-lifecycle.properties b/feature-lifecycle/src/main/feature/config/feature-lifecycle.properties
index 4a60650c..45dfabdd 100644
--- a/feature-lifecycle/src/main/feature/config/feature-lifecycle.properties
+++ b/feature-lifecycle/src/main/feature/config/feature-lifecycle.properties
@@ -31,9 +31,11 @@ kafka.source.topics.policy-pdp-pap.effectiveTopic=${envd:POLICY_PDP_PAP_TOPIC}
kafka.source.topics.policy-pdp-pap.apiKey=${envd:POLICY_PDP_PAP_API_KEY}
kafka.source.topics.policy-pdp-pap.apiSecret=${envd:POLICY_PDP_PAP_API_SECRET}
kafka.source.topics.policy-pdp-pap.https=${envd:KAFKA_HTTPS:false}
+kafka.source.topics.policy-pdp-pap.additionalProps=${env:KAFKA_ADDITIONAL_PROPS}
kafka.sink.topics.policy-pdp-pap.servers=${envd:KAFKA_SERVERS}
kafka.sink.topics.policy-pdp-pap.effectiveTopic=${envd:POLICY_PDP_PAP_TOPIC}
kafka.sink.topics.policy-pdp-pap.apiKey=${envd:POLICY_PDP_PAP_API_KEY}
kafka.sink.topics.policy-pdp-pap.apiSecret=${envd:POLICY_PDP_PAP_API_SECRET}
kafka.sink.topics.policy-pdp-pap.https=${envd:KAFKA_HTTPS:false}
+kafka.sink.topics.policy-pdp-pap.additionalProps=${env:KAFKA_ADDITIONAL_PROPS}
diff --git a/feature-lifecycle/src/main/java/org/onap/policy/drools/lifecycle/LifecycleFeature.java b/feature-lifecycle/src/main/java/org/onap/policy/drools/lifecycle/LifecycleFeature.java
index a50deb21..1fc45747 100644
--- a/feature-lifecycle/src/main/java/org/onap/policy/drools/lifecycle/LifecycleFeature.java
+++ b/feature-lifecycle/src/main/java/org/onap/policy/drools/lifecycle/LifecycleFeature.java
@@ -3,7 +3,7 @@
* ONAP
* ================================================================================
* Copyright (C) 2019-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.
@@ -38,7 +38,7 @@ public class LifecycleFeature
* Lifecycle FSM.
*/
@Getter
- public static LifecycleFsm fsm = new LifecycleFsm();
+ static LifecycleFsm fsm = new LifecycleFsm();
@Override
public int getSequenceNumber() {
diff --git a/feature-lifecycle/src/main/java/org/onap/policy/drools/lifecycle/LifecycleStateRunning.java b/feature-lifecycle/src/main/java/org/onap/policy/drools/lifecycle/LifecycleStateRunning.java
index 2d5c66b3..14796cea 100644
--- a/feature-lifecycle/src/main/java/org/onap/policy/drools/lifecycle/LifecycleStateRunning.java
+++ b/feature-lifecycle/src/main/java/org/onap/policy/drools/lifecycle/LifecycleStateRunning.java
@@ -4,7 +4,7 @@
* ================================================================================
* Copyright (C) 2019-2021 AT&T Intellectual Property. All rights reserved.
* Modifications Copyright (C) 2019 Bell Canada.
- * Modifications Copyright (C) 2021, 2023 Nordix Foundation.
+ * Modifications Copyright (C) 2021, 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.
@@ -203,13 +203,15 @@ public abstract class LifecycleStateRunning extends LifecycleStateDefault {
List<ToscaPolicy> failedUndeployPolicies = undeployPolicies(policies);
if (!failedUndeployPolicies.isEmpty()) {
- logger.warn("update-policies: undeployment failures: {}", fsm.getPolicyIdsMessage(failedUndeployPolicies));
+ var failures = fsm.getPolicyIdsMessage(failedUndeployPolicies);
+ logger.warn("update-policies: undeployment failures: {}", failures);
failedUndeployPolicies.forEach(fsm::failedUndeployPolicyAction);
}
List<ToscaPolicy> failedDeployPolicies = deployPolicies(policies);
if (!failedDeployPolicies.isEmpty()) {
- logger.warn("update-policies: deployment failures: {}", fsm.getPolicyIdsMessage(failedDeployPolicies));
+ var failures = fsm.getPolicyIdsMessage(failedDeployPolicies);
+ logger.warn("update-policies: deployment failures: {}", failures);
failedDeployPolicies.forEach(fsm::failedDeployPolicyAction);
}
@@ -237,11 +239,15 @@ public abstract class LifecycleStateRunning extends LifecycleStateDefault {
List<ToscaPolicy> preNonNativePolicies = fsm.getNonNativePolicies(preActivePoliciesMap);
preNonNativePolicies.retainAll(fsm.getNonNativePolicies(activePoliciesByType));
+ var nonNativePoliciesIds = fsm.getPolicyIdsMessage(preNonNativePolicies);
+ var activePoliciesIds = fsm.getPolicyIdsMessage(activeNativeArtifactPolicies);
+
logger.info("re-applying non-native policies {} because new native artifact policies have been found: {}",
- fsm.getPolicyIdsMessage(preNonNativePolicies), fsm.getPolicyIdsMessage(activeNativeArtifactPolicies));
+ nonNativePoliciesIds, activePoliciesIds);
List<ToscaPolicy> failedPolicies = syncPolicies(preNonNativePolicies, this::deployPolicy);
- logger.info("re-applying non-native policies failures: {}", fsm.getPolicyIdsMessage(failedPolicies));
+ var failedPoliciesIds = fsm.getPolicyIdsMessage(failedPolicies);
+ logger.info("re-applying non-native policies failures: {}", failedPoliciesIds);
return failedPolicies;
}
@@ -268,9 +274,11 @@ public abstract class LifecycleStateRunning extends LifecycleStateDefault {
List<ToscaPolicy> preNativeArtifactPolicies = fsm.getNativeArtifactPolicies(preActivePoliciesMap);
preNativeArtifactPolicies.retainAll(fsm.getNativeArtifactPolicies(activePoliciesByType));
+ var candidateIds = fsm.getPolicyIdsMessage(preNativeArtifactPolicies);
+ var activeIds = fsm.getPolicyIdsMessage(activeNativeControllerPolicies);
+
logger.info("reapply candidate native artifact policies {} as new native controller policies {} were found",
- fsm.getPolicyIdsMessage(preNativeArtifactPolicies),
- fsm.getPolicyIdsMessage(activeNativeControllerPolicies));
+ candidateIds, activeIds);
// from the intersection, only need to reapply those for which there is a new native
// controller policy
@@ -295,12 +303,14 @@ public abstract class LifecycleStateRunning extends LifecycleStateDefault {
}
}
+ var nativeArtPolIds = fsm.getPolicyIdsMessage(preNativeArtifactPoliciesToApply);
+ var newNativeCtrlPolIds = fsm.getPolicyIdsMessage(activeNativeControllerPolicies);
logger.info("reapply set of native artifact policies {} as new native controller policies {} were found",
- fsm.getPolicyIdsMessage(preNativeArtifactPoliciesToApply),
- fsm.getPolicyIdsMessage(activeNativeControllerPolicies));
+ nativeArtPolIds, newNativeCtrlPolIds);
List<ToscaPolicy> failedPolicies = syncPolicies(preNativeArtifactPoliciesToApply, this::deployPolicy);
- logger.info("re-applying native artifact policies failures: {}", fsm.getPolicyIdsMessage(failedPolicies));
+ var failedIds = fsm.getPolicyIdsMessage(failedPolicies);
+ logger.info("re-applying native artifact policies failures: {}", failedIds);
// since we want non-native policies to be reapplied when a new native artifact policy has been
// reapplied here, remove it from the preActivePolicies, so it is detected as new.
diff --git a/feature-lifecycle/src/main/java/org/onap/policy/drools/server/restful/RestLifecycleManager.java b/feature-lifecycle/src/main/java/org/onap/policy/drools/server/restful/RestLifecycleManager.java
index a4abdf37..c755c444 100644
--- a/feature-lifecycle/src/main/java/org/onap/policy/drools/server/restful/RestLifecycleManager.java
+++ b/feature-lifecycle/src/main/java/org/onap/policy/drools/server/restful/RestLifecycleManager.java
@@ -1,7 +1,7 @@
/*-
* ============LICENSE_START=======================================================
* Copyright (C) 2019-2022 AT&T Intellectual Property. All rights reserved.
- * Modifications Copyright (C) 2021, 2023-2023 Nordix Foundation.
+ * Modifications Copyright (C) 2021, 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.
@@ -417,7 +417,7 @@ public class RestLifecycleManager implements LifecycleApi {
private PdpUpdate getUndeployPolicyUpdate(List<ToscaPolicy> policies) {
PdpUpdate update = getPolicyUpdate();
- update.setPoliciesToBeUndeployed(LifecycleFeature.fsm.getPolicyIds(policies));
+ update.setPoliciesToBeUndeployed(LifecycleFeature.getFsm().getPolicyIds(policies));
return update;
}
diff --git a/feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/ControllerSupport.java b/feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/ControllerSupport.java
index 858e8495..eadafe7c 100644
--- a/feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/ControllerSupport.java
+++ b/feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/ControllerSupport.java
@@ -35,6 +35,8 @@ import org.onap.policy.drools.system.PolicyController;
import org.onap.policy.drools.system.PolicyControllerConstants;
import org.onap.policy.drools.util.KieUtils;
import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* Controller Test Support.
@@ -42,6 +44,8 @@ import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy;
@Getter
public class ControllerSupport {
+ private static final Logger logger = LoggerFactory.getLogger(ControllerSupport.class);
+
protected static final String JUNIT_KMODULE_DRL_PATH = "src/test/resources/lifecycle.drl";
protected static final String JUNIT_KMODULE_POM_PATH = "src/test/resources/lifecycle.pom";
protected static final String JUNIT_KMODULE_PATH = "src/test/resources/lifecycle.kmodule";
@@ -62,20 +66,19 @@ public class ControllerSupport {
/**
* Create controller.
*/
- public PolicyController createController() throws IOException {
+ public void createController() throws IOException {
try {
PolicyController controller = getController();
controller.getDrools().delete(ToscaPolicy.class);
- return controller;
- } catch (IllegalArgumentException ignored) { // NOSONAR
- ; // checkstyle
+ } catch (IllegalArgumentException e) {
+ logger.debug("error when creating controller", e);
}
ReleaseId coordinates = installArtifact();
Properties controllerProps = getControllerProps(coordinates);
- return PolicyControllerConstants.getFactory().build(name, controllerProps);
+ PolicyControllerConstants.getFactory().build(name, controllerProps);
}
private Properties getControllerProps(ReleaseId coordinates) {
@@ -140,7 +143,7 @@ public class ControllerSupport {
* Change final marker in static field.
*/
public static <T> Field unsetFinalStaticAccess(Class<T> clazz, String fieldName)
- throws NoSuchFieldException {
+ throws NoSuchFieldException {
Field field = clazz.getDeclaredField(fieldName);
field.setAccessible(true);
diff --git a/feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/LifecycleFeatureTest.java b/feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/LifecycleFeatureTest.java
new file mode 100644
index 00000000..bb22316c
--- /dev/null
+++ b/feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/LifecycleFeatureTest.java
@@ -0,0 +1,164 @@
+/*
+ * ============LICENSE_START=======================================================
+ * ONAP
+ * ================================================================================
+ * 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.
+ * 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.drools.lifecycle;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.lenient;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.onap.policy.drools.lifecycle.LifecycleFsm.CONFIGURATION_PROPERTIES_NAME;
+
+import java.util.Properties;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.MockedStatic;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.onap.policy.drools.persistence.FileSystemPersistence;
+import org.onap.policy.drools.persistence.SystemPersistenceConstants;
+import org.onap.policy.drools.system.PolicyController;
+import org.onap.policy.drools.system.PolicyEngine;
+
+@ExtendWith(MockitoExtension.class)
+class LifecycleFeatureTest {
+
+ LifecycleFeature feature;
+
+ @Mock
+ LifecycleFsm fsm;
+
+ @Mock
+ PolicyController controller;
+
+ @Mock
+ PolicyEngine engine;
+
+ AutoCloseable closeable;
+
+ @BeforeEach
+ void setUp() {
+ closeable = MockitoAnnotations.openMocks(this);
+
+ var props = new Properties();
+ var fileManager = mock(FileSystemPersistence.class);
+ lenient().when(fileManager.getProperties(CONFIGURATION_PROPERTIES_NAME)).thenReturn(props);
+
+ try (MockedStatic<SystemPersistenceConstants> constants =
+ Mockito.mockStatic(SystemPersistenceConstants.class)) {
+ constants.when(SystemPersistenceConstants::getManager).thenReturn(fileManager);
+ feature = mock(LifecycleFeature.class);
+ }
+ }
+
+ @AfterEach
+ void tearDown() throws Exception {
+ closeable.close();
+ }
+
+ @Test
+ void getSequenceNumber() {
+ when(feature.getSequenceNumber()).thenCallRealMethod();
+
+ assertEquals(1, feature.getSequenceNumber());
+ }
+
+ @Test
+ void afterStart() {
+ when(fsm.start()).thenReturn(true);
+ doNothing().when(fsm).start(controller);
+
+ when(feature.afterStart(engine)).thenCallRealMethod();
+ when(feature.afterStart(controller)).thenCallRealMethod();
+
+ try (MockedStatic<LifecycleFeature> factory = Mockito.mockStatic(LifecycleFeature.class)) {
+ factory.when(LifecycleFeature::getFsm).thenReturn(fsm);
+ assertEquals(fsm, LifecycleFeature.getFsm());
+
+ assertFalse(feature.afterStart(controller));
+ assertFalse(feature.afterStart(engine));
+ }
+ }
+
+ @Test
+ void beforeStop() {
+ when(fsm.stop()).thenReturn(true);
+ doNothing().when(fsm).stop(controller);
+
+ when(feature.beforeStop(engine)).thenCallRealMethod();
+ when(feature.beforeStop(controller)).thenCallRealMethod();
+
+ try (MockedStatic<LifecycleFeature> factory = Mockito.mockStatic(LifecycleFeature.class)) {
+ factory.when(LifecycleFeature::getFsm).thenReturn(fsm);
+ assertEquals(fsm, LifecycleFeature.getFsm());
+
+ assertFalse(feature.beforeStop(controller));
+ assertFalse(feature.beforeStop(engine));
+ }
+ }
+
+ @Test
+ void beforeShutdown() {
+ doNothing().when(fsm).shutdown();
+
+ when(feature.beforeShutdown(engine)).thenCallRealMethod();
+
+ try (MockedStatic<LifecycleFeature> factory = Mockito.mockStatic(LifecycleFeature.class)) {
+ factory.when(LifecycleFeature::getFsm).thenReturn(fsm);
+ assertEquals(fsm, LifecycleFeature.getFsm());
+
+ assertFalse(feature.beforeShutdown(engine));
+ }
+ }
+
+ @Test
+ void beforeLock() {
+ doNothing().when(fsm).stop(controller);
+
+ when(feature.beforeLock(controller)).thenCallRealMethod();
+
+ try (MockedStatic<LifecycleFeature> factory = Mockito.mockStatic(LifecycleFeature.class)) {
+ factory.when(LifecycleFeature::getFsm).thenReturn(fsm);
+ assertEquals(fsm, LifecycleFeature.getFsm());
+
+ assertFalse(feature.beforeLock(controller));
+ }
+ }
+
+ @Test
+ void afterUnlock() {
+ doNothing().when(fsm).start(controller);
+
+ when(feature.afterUnlock(controller)).thenCallRealMethod();
+
+ try (MockedStatic<LifecycleFeature> factory = Mockito.mockStatic(LifecycleFeature.class)) {
+ factory.when(LifecycleFeature::getFsm).thenReturn(fsm);
+ assertEquals(fsm, LifecycleFeature.getFsm());
+
+ assertFalse(feature.afterUnlock(controller));
+ }
+ }
+} \ No newline at end of file
diff --git a/feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/LifecycleFsmTest.java b/feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/LifecycleFsmTest.java
index cae3bb3b..9538cc44 100644
--- a/feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/LifecycleFsmTest.java
+++ b/feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/LifecycleFsmTest.java
@@ -228,6 +228,11 @@ public class LifecycleFsmTest {
fsm.getPolicyIds(List.of(opPolicy, controllerPolicy)).toString());
}
+ @Test
+ void testGetSequenceNumber() {
+ assertEquals(1, new LifecycleFeature().getSequenceNumber());
+ }
+
protected void deployAllPolicies() {
fsm.deployedPolicyAction(controllerPolicy);
fsm.deployedPolicyAction(controller2Policy);
diff --git a/feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/LifecycleFsmUpdateTest.java b/feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/LifecycleFsmUpdateTest.java
index 8f0c19db..c24c61cf 100644
--- a/feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/LifecycleFsmUpdateTest.java
+++ b/feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/LifecycleFsmUpdateTest.java
@@ -143,7 +143,7 @@ public class LifecycleFsmUpdateTest {
noopTopicProperties.put(PolicyEndPointProperties.PROPERTY_NOOP_SINK_TOPICS, TestConstants.APPC_CL_TOPIC);
TopicEndpointManager.getManager().addTopics(noopTopicProperties);
- savedFsm = LifecycleFeature.fsm;
+ savedFsm = LifecycleFeature.getFsm();
}
/**
@@ -174,7 +174,7 @@ public class LifecycleFsmUpdateTest {
public void init() throws CoderException, IOException, NoSuchFieldException, IllegalAccessException {
fsm = new LifecycleFsm() {
@Override
- protected ScheduledExecutorService makeExecutor() { // NOSONAR
+ protected ScheduledExecutorService makeExecutor() {
return new PseudoScheduledExecutorService(new TestTimeMulti());
}
};
@@ -417,14 +417,14 @@ public class LifecycleFsmUpdateTest {
protected void verifyNativeArtifactPolicies(List<ToscaPolicy> policies) throws CoderException {
// check that a brained controller exists for each native artifact policy
for (ToscaPolicy policy : policies) {
- NativeArtifactPolicy artifactPolicy = fsm.getDomainMaker().convertTo(policy, NativeArtifactPolicy.class);
- String controllerName = artifactPolicy.getProperties().getController().getName();
+ NativeArtifactPolicy naPolicy = fsm.getDomainMaker().convertTo(policy, NativeArtifactPolicy.class);
+ String controllerName = naPolicy.getProperties().getController().getName();
assertTrue(PolicyControllerConstants.getFactory().get(controllerName).getDrools().isBrained());
- assertEquals(artifactPolicy.getProperties().getRulesArtifact().getGroupId(),
+ assertEquals(naPolicy.getProperties().getRulesArtifact().getGroupId(),
PolicyControllerConstants.getFactory().get(controllerName).getDrools().getGroupId());
- assertEquals(artifactPolicy.getProperties().getRulesArtifact().getArtifactId(),
+ assertEquals(naPolicy.getProperties().getRulesArtifact().getArtifactId(),
PolicyControllerConstants.getFactory().get(controllerName).getDrools().getArtifactId());
- assertEquals(artifactPolicy.getProperties().getRulesArtifact().getVersion(),
+ assertEquals(naPolicy.getProperties().getRulesArtifact().getVersion(),
PolicyControllerConstants.getFactory().get(controllerName).getDrools().getVersion());
}
}
@@ -446,9 +446,9 @@ public class LifecycleFsmUpdateTest {
// and there is a controller policy for each controllerName
for (ToscaPolicy nativePolicy : nativeArtifactPolicies) {
- NativeArtifactPolicy artifactPolicy =
+ NativeArtifactPolicy naPolicy =
fsm.getDomainMaker().convertTo(nativePolicy, NativeArtifactPolicy.class);
- String artifactControllerName = artifactPolicy.getProperties().getController().getName();
+ String artifactControllerName = naPolicy.getProperties().getController().getName();
// brained controller check
assertTrue(PolicyControllerConstants.getFactory().get(artifactControllerName).getDrools().isBrained(),
@@ -545,13 +545,13 @@ public class LifecycleFsmUpdateTest {
protected List<ControllerPolicy> getNativeControllerPolicies(List<ToscaPolicy> nativePolicies,
String controllerName) {
- return nativePolicies.stream().map(controllerPolicy -> {
+ return nativePolicies.stream().map(nativePolicy -> {
try {
- return fsm.getDomainMaker().convertTo(controllerPolicy, ControllerPolicy.class);
+ return fsm.getDomainMaker().convertTo(nativePolicy, ControllerPolicy.class);
} catch (CoderException ex) {
- throw new RuntimeException(controllerPolicy.getIdentifier().toString(), ex);
+ throw new RuntimeException(nativePolicy.getIdentifier().toString(), ex);
}
- }).filter(controllerPolicy -> controllerName.equals(controllerPolicy.getProperties().getControllerName()))
+ }).filter(nativePolicy -> controllerName.equals(nativePolicy.getProperties().getControllerName()))
.collect(Collectors.toList());
}
diff --git a/feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/LifecycleStateActiveTest.java b/feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/LifecycleStateActiveTest.java
index 86e6ce3c..80fe946f 100644
--- a/feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/LifecycleStateActiveTest.java
+++ b/feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/LifecycleStateActiveTest.java
@@ -186,8 +186,6 @@ class LifecycleStateActiveTest extends LifecycleStateRunningTest {
@Test
void testUpdate() throws IOException, CoderException {
- // TODO: extract repeated similar assertion blocks into their own helper methods
-
PdpUpdate update = new PdpUpdate();
update.setName(PolicyEngineConstants.getManager().getPdpName());
update.setPdpGroup("W");
@@ -311,9 +309,9 @@ class LifecycleStateActiveTest extends LifecycleStateRunningTest {
factPolicies = controllerSupport.getFacts(ToscaPolicy.class);
assertEquals(2, factPolicies.size());
- assertTrue(factPolicies.stream().noneMatch((ff) -> Objects.equals(toscaPolicyRestartV1, ff)));
- assertTrue(factPolicies.stream().anyMatch((ff) -> Objects.equals(toscaPolicyRestartV2, ff)));
- assertTrue(factPolicies.stream().anyMatch((ff) -> Objects.equals(toscaPolicyFirewall, ff)));
+ assertTrue(factPolicies.stream().noneMatch(ff -> Objects.equals(toscaPolicyRestartV1, ff)));
+ assertTrue(factPolicies.stream().anyMatch(ff -> Objects.equals(toscaPolicyRestartV2, ff)));
+ assertTrue(factPolicies.stream().anyMatch(ff -> Objects.equals(toscaPolicyFirewall, ff)));
assertEquals(2, fsm.policiesMap.size());
long originalInterval = fsm.getStatusTimerSeconds();
diff --git a/feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/LifecycleStatePassiveTest.java b/feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/LifecycleStatePassiveTest.java
index 01fb90b5..67e741ac 100644
--- a/feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/LifecycleStatePassiveTest.java
+++ b/feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/LifecycleStatePassiveTest.java
@@ -72,13 +72,13 @@ class LifecycleStatePassiveTest extends LifecycleStateRunningTest {
fsm.start(controllerSupport.getController());
assertSame(controllerSupport.getController(),
((PolicyTypeDroolsController) fsm.getController(
- new ToscaConceptIdentifier(
- ControllerSupport.POLICY_TYPE_COMPLIANT_OP, ControllerSupport.POLICY_TYPE_VERSION)))
+ new ToscaConceptIdentifier(
+ ControllerSupport.POLICY_TYPE_COMPLIANT_OP, ControllerSupport.POLICY_TYPE_VERSION)))
.controllers().get(0));
fsm.stop(controllerSupport.getController());
assertNull(fsm.getController(new ToscaConceptIdentifier(ControllerSupport.POLICY_TYPE_COMPLIANT_OP,
- ControllerSupport.POLICY_TYPE_VERSION)));
+ ControllerSupport.POLICY_TYPE_VERSION)));
fsm.shutdown();
}
@@ -98,16 +98,6 @@ class LifecycleStatePassiveTest extends LifecycleStateRunningTest {
assertBasicTerminated();
}
- private void simpleStart() {
- assertTrue(fsm.start());
- assertBasicPassive();
- }
-
- private void simpleStop() {
- assertTrue(fsm.stop());
- assertBasicTerminated();
- }
-
@Test
void testShutdown() throws Exception {
simpleStop();
@@ -129,14 +119,6 @@ class LifecycleStatePassiveTest extends LifecycleStateRunningTest {
fsm.shutdown();
}
- private void status() {
- waitUntil(5, TimeUnit.SECONDS, isStatus(PdpState.PASSIVE, 1));
- waitUntil(fsm.statusTimerSeconds + 2, TimeUnit.SECONDS, isStatus(PdpState.PASSIVE, 1 + 1));
- waitUntil(fsm.statusTimerSeconds + 2, TimeUnit.SECONDS, isStatus(PdpState.PASSIVE, 1 + 2));
- assertTrue(fsm.status());
- waitUntil(200, TimeUnit.MILLISECONDS, isStatus(PdpState.PASSIVE, 1 + 3));
- }
-
@Test
void testUpdate() throws CoderException {
controllerSupport.getController().getDrools().delete(ToscaPolicy.class);
@@ -154,7 +136,7 @@ class LifecycleStatePassiveTest extends LifecycleStateRunningTest {
int qlength = fsm.client.getSink().getRecentEvents().length;
PdpStatus lastStatus = new StandardCoder().decode(fsm.client.getSink().getRecentEvents()[qlength - 1],
- PdpStatus.class);
+ PdpStatus.class);
assertEquals("foo", lastStatus.getPdpType());
assertEquals(update.getRequestId(), lastStatus.getRequestId());
assertEquals(update.getRequestId(), lastStatus.getResponse().getResponseTo());
@@ -165,21 +147,10 @@ class LifecycleStatePassiveTest extends LifecycleStateRunningTest {
assertEquals("z", fsm.getSubGroup());
assertBasicPassive();
- ToscaPolicy toscaPolicy =
- getExamplesPolicy("policies/vCPE.policy.operational.input.tosca.json", "operational.restart");
+ var policyResourcePath = "policies/vCPE.policy.operational.input.tosca.json";
+ ToscaPolicy toscaPolicy = getExamplesPolicy(policyResourcePath, "operational.restart");
toscaPolicy.getProperties().put("controllerName", "lifecycle");
- update.setPoliciesToBeDeployed(List.of(toscaPolicy));
-
- assertFalse(fsm.update(update));
-
- assertEquals(PdpState.PASSIVE, fsm.state());
- assertEquals(interval, fsm.getStatusTimerSeconds());
- assertEquals(LifecycleFsm.DEFAULT_PDP_GROUP, fsm.getGroup());
- assertEquals("z", fsm.getSubGroup());
- assertBasicPassive();
-
- assertEquals(2, fsm.policyTypesMap.size());
- assertTrue(fsm.policiesMap.isEmpty());
+ verifyVcpePolicyDeployed(update, toscaPolicy, interval);
update.setPdpGroup(null);
update.setPdpSubgroup(null);
@@ -222,32 +193,7 @@ class LifecycleStatePassiveTest extends LifecycleStateRunningTest {
assertBasicPassive();
assertEquals(0, controllerSupport.getController().getDrools().factCount("junits"));
- // The "update" event will undeploy "toscaPolicy" and deploy "toscaPolicy2"
- ToscaPolicy toscaPolicy2 =
- getExamplesPolicy("policies/vFirewall.policy.operational.input.tosca.json", "operational.modifyconfig");
- toscaPolicy.getProperties().remove("controllerName");
- update.setPoliciesToBeUndeployed(List.of(toscaPolicy.getIdentifier()));
- update.setPoliciesToBeDeployed(List.of(toscaPolicy2));
- assertTrue(fsm.update(update));
- assertEquals(3, fsm.policyTypesMap.size());
- assertEquals(1, fsm.policiesMap.size());
- assertEquals(toscaPolicy2, fsm.policiesMap.get(toscaPolicy2.getIdentifier()));
- assertNull(fsm.policiesMap.get(toscaPolicy.getIdentifier()));
- assertEquals(0, controllerSupport.getController().getDrools().factCount("junits"));
-
- update.setPdpGroup(null);
- update.setPdpSubgroup(null);
- update.setPoliciesToBeUndeployed(List.of(toscaPolicy2.getIdentifier()));
- update.setPoliciesToBeDeployed(List.of());
- assertTrue(fsm.update(update));
- assertEquals(3, fsm.policyTypesMap.size());
- assertEquals(0, fsm.policiesMap.size());
- assertEquals(PdpState.PASSIVE, fsm.state());
- assertEquals(interval, fsm.getStatusTimerSeconds());
- assertEquals(LifecycleFsm.DEFAULT_PDP_GROUP, fsm.getGroup());
- assertNull(fsm.getSubGroup());
- assertBasicPassive();
- assertEquals(0, controllerSupport.getController().getDrools().factCount("junits"));
+ verifyUpdateUndeployToscaPolicyDeployToscaPolicy2(toscaPolicy, update, interval);
fsm.shutdown();
}
@@ -309,6 +255,16 @@ class LifecycleStatePassiveTest extends LifecycleStateRunningTest {
fsm.shutdown();
}
+ private void simpleStart() {
+ assertTrue(fsm.start());
+ assertBasicPassive();
+ }
+
+ private void simpleStop() {
+ assertTrue(fsm.stop());
+ assertBasicTerminated();
+ }
+
private void assertBasicTerminated() {
assertEquals(PdpState.TERMINATED, fsm.state.state());
assertFalse(fsm.isAlive());
@@ -348,4 +304,57 @@ class LifecycleStatePassiveTest extends LifecycleStateRunningTest {
assertFalse(fsm.statusTask.isCancelled());
assertFalse(fsm.statusTask.isDone());
}
+
+ private void status() {
+ waitUntil(5, TimeUnit.SECONDS, isStatus(PdpState.PASSIVE, 1));
+ waitUntil(fsm.statusTimerSeconds + 2, TimeUnit.SECONDS, isStatus(PdpState.PASSIVE, 1 + 1));
+ waitUntil(fsm.statusTimerSeconds + 2, TimeUnit.SECONDS, isStatus(PdpState.PASSIVE, 1 + 2));
+ assertTrue(fsm.status());
+ waitUntil(200, TimeUnit.MILLISECONDS, isStatus(PdpState.PASSIVE, 1 + 3));
+ }
+
+ private void verifyVcpePolicyDeployed(PdpUpdate update, ToscaPolicy toscaPolicy, long interval) {
+ update.setPoliciesToBeDeployed(List.of(toscaPolicy));
+
+ assertFalse(fsm.update(update));
+
+ assertEquals(PdpState.PASSIVE, fsm.state());
+ assertEquals(interval, fsm.getStatusTimerSeconds());
+ assertEquals(LifecycleFsm.DEFAULT_PDP_GROUP, fsm.getGroup());
+ assertEquals("z", fsm.getSubGroup());
+ assertBasicPassive();
+
+ assertEquals(2, fsm.policyTypesMap.size());
+ assertTrue(fsm.policiesMap.isEmpty());
+ }
+
+ private void verifyUpdateUndeployToscaPolicyDeployToscaPolicy2(ToscaPolicy toscaPolicy, PdpUpdate update,
+ long interval) throws CoderException {
+ // The "update" event will undeploy "toscaPolicy" and deploy "toscaPolicy2"
+ String policyResourcePath = "policies/vFirewall.policy.operational.input.tosca.json";
+ ToscaPolicy toscaPolicy2 = getExamplesPolicy(policyResourcePath, "operational.modifyconfig");
+ toscaPolicy.getProperties().remove("controllerName");
+ update.setPoliciesToBeUndeployed(List.of(toscaPolicy.getIdentifier()));
+ update.setPoliciesToBeDeployed(List.of(toscaPolicy2));
+ assertTrue(fsm.update(update));
+ assertEquals(3, fsm.policyTypesMap.size());
+ assertEquals(1, fsm.policiesMap.size());
+ assertEquals(toscaPolicy2, fsm.policiesMap.get(toscaPolicy2.getIdentifier()));
+ assertNull(fsm.policiesMap.get(toscaPolicy.getIdentifier()));
+ assertEquals(0, controllerSupport.getController().getDrools().factCount("junits"));
+
+ update.setPdpGroup(null);
+ update.setPdpSubgroup(null);
+ update.setPoliciesToBeUndeployed(List.of(toscaPolicy2.getIdentifier()));
+ update.setPoliciesToBeDeployed(List.of());
+ assertTrue(fsm.update(update));
+ assertEquals(3, fsm.policyTypesMap.size());
+ assertEquals(0, fsm.policiesMap.size());
+ assertEquals(PdpState.PASSIVE, fsm.state());
+ assertEquals(interval, fsm.getStatusTimerSeconds());
+ assertEquals(LifecycleFsm.DEFAULT_PDP_GROUP, fsm.getGroup());
+ assertNull(fsm.getSubGroup());
+ assertBasicPassive();
+ assertEquals(0, controllerSupport.getController().getDrools().factCount("junits"));
+ }
}
diff --git a/feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/LifecycleStateSafeTest.java b/feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/LifecycleStateSafeTest.java
index 4c292b42..3d69ea9a 100644
--- a/feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/LifecycleStateSafeTest.java
+++ b/feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/LifecycleStateSafeTest.java
@@ -36,10 +36,11 @@ class LifecycleStateSafeTest extends LifecycleStateUnsupportedTest {
}
@Override
- public LifecycleState create(LifecycleFsm fsm) {
- return new LifecycleStateSafe(fsm);
+ public void create(LifecycleFsm fsm) {
+ new LifecycleStateSafe(fsm);
}
+ @Override
@Test
public void constructor() {
super.constructor();
diff --git a/feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/LifecycleStateTestTest.java b/feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/LifecycleStateTestTest.java
index 89aae201..e6c7d145 100644
--- a/feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/LifecycleStateTestTest.java
+++ b/feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/LifecycleStateTestTest.java
@@ -36,10 +36,11 @@ class LifecycleStateTestTest extends LifecycleStateUnsupportedTest {
}
@Override
- public LifecycleState create(LifecycleFsm fsm) {
- return new LifecycleStateTest(fsm);
+ public void create(LifecycleFsm fsm) {
+ new LifecycleStateTest(fsm);
}
+ @Override
@Test
public void constructor() {
super.constructor();
diff --git a/feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/LifecycleStateUnsupportedTest.java b/feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/LifecycleStateUnsupportedTest.java
index b5ec6aca..bd412179 100644
--- a/feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/LifecycleStateUnsupportedTest.java
+++ b/feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/LifecycleStateUnsupportedTest.java
@@ -24,12 +24,14 @@ package org.onap.policy.drools.lifecycle;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import java.util.ArrayList;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.onap.policy.drools.persistence.SystemPersistenceConstants;
import org.onap.policy.models.pdp.concepts.PdpStateChange;
import org.onap.policy.models.pdp.concepts.PdpUpdate;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy;
/**
* Lifecycle State Unsupported Test.
@@ -52,7 +54,7 @@ public abstract class LifecycleStateUnsupportedTest {
this.state = state;
}
- public abstract LifecycleState create(LifecycleFsm fsm);
+ public abstract void create(LifecycleFsm fsm);
@Test
public void constructor() {
@@ -109,4 +111,11 @@ public abstract class LifecycleStateUnsupportedTest {
assertThatThrownBy(() -> state.transitionToState(active))
.isInstanceOf(UnsupportedOperationException.class);
}
+
+ @Test
+ public void updatePolicies() {
+ var list = new ArrayList<ToscaPolicy>();
+ assertThatThrownBy(() -> state.updatePolicies(list))
+ .isInstanceOf(UnsupportedOperationException.class);
+ }
}
diff --git a/feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/PolicyTypeDroolsControllerTest.java b/feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/PolicyTypeDroolsControllerTest.java
index 999860a0..1208662a 100644
--- a/feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/PolicyTypeDroolsControllerTest.java
+++ b/feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/PolicyTypeDroolsControllerTest.java
@@ -21,16 +21,24 @@
package org.onap.policy.drools.lifecycle;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.isNull;
+import static org.mockito.Mockito.doCallRealMethod;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
-import org.junit.jupiter.api.BeforeEach;
+import java.util.ArrayList;
+import java.util.List;
import org.junit.jupiter.api.Test;
import org.onap.policy.common.utils.coder.CoderException;
import org.onap.policy.drools.domain.models.operational.OperationalPolicy;
import org.onap.policy.drools.system.PolicyControllerConstants;
+import org.onap.policy.drools.system.internal.AggregatedPolicyController;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy;
/**
@@ -41,7 +49,7 @@ class PolicyTypeDroolsControllerTest extends LifecycleStateRunningTest {
// Operational vCPE Policies
private static final String OP_POLICY_NAME_VCPE = "operational.restart";
private static final String VCPE_OPERATIONAL_DROOLS_POLICY_JSON =
- "policies/vCPE.policy.operational.input.tosca.json";
+ "policies/vCPE.policy.operational.input.tosca.json";
private ToscaPolicy policy;
private PolicyTypeDroolsController controller;
@@ -49,7 +57,6 @@ class PolicyTypeDroolsControllerTest extends LifecycleStateRunningTest {
/**
* Test initialization.
*/
- @BeforeEach
public void init() throws CoderException {
fsm = makeFsmWithPseudoTime();
policy = getExamplesPolicy(VCPE_OPERATIONAL_DROOLS_POLICY_JSON, OP_POLICY_NAME_VCPE);
@@ -72,7 +79,8 @@ class PolicyTypeDroolsControllerTest extends LifecycleStateRunningTest {
}
@Test
- void testDeployUndeploy() {
+ void testDeployUndeploy() throws CoderException {
+ init();
/* non-existing controller */
assertFalse(controller.undeploy(policy));
assertFalse(controller.deploy(policy));
@@ -97,6 +105,40 @@ class PolicyTypeDroolsControllerTest extends LifecycleStateRunningTest {
undeploy(); // one more time
}
+ @Test
+ void testNullExceptions() {
+ var mockController = mock(PolicyTypeDroolsController.class);
+ when(mockController.deploy(isNull())).thenCallRealMethod();
+ doCallRealMethod().when(mockController).remove(isNull());
+ when(mockController.undeploy(isNull())).thenCallRealMethod();
+ doCallRealMethod().when(mockController).add(isNull());
+
+ assertThatThrownBy(() -> mockController.deploy(null))
+ .hasMessageContaining("policy is marked non-null but is null");
+
+ assertThatThrownBy(() -> mockController.remove(null))
+ .hasMessageContaining("controller is marked non-null but is null");
+
+ assertThatThrownBy(() -> mockController.undeploy(null))
+ .hasMessageContaining("policy is marked non-null but is null");
+
+ assertThatThrownBy(() -> mockController.add(null))
+ .hasMessageContaining("controller is marked non-null but is null");
+ }
+
+ @Test
+ void testAddController_DoesNotMatchPolicyType() {
+ var newController = mock(AggregatedPolicyController.class);
+ when(newController.getPolicyTypes()).thenReturn(new ArrayList<>(List.of(mock(ToscaConceptIdentifier.class))));
+ when(newController.getName()).thenReturn("mockControllerName");
+
+ var mockController = mock(PolicyTypeDroolsController.class);
+ doCallRealMethod().when(mockController).add(newController);
+
+ assertThatThrownBy(() -> mockController.add(newController))
+ .hasMessageContaining("controller mockControllerName does not support");
+ }
+
protected void undeploy() {
assertTrue(controller.undeploy(policy));
assertFalse(controllerSupport.getController().getDrools().exists(policy));
diff --git a/feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/PolicyTypeNativeArtifactControllerTest.java b/feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/PolicyTypeNativeArtifactControllerTest.java
index 26e6bbe4..ae11fd27 100644
--- a/feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/PolicyTypeNativeArtifactControllerTest.java
+++ b/feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/PolicyTypeNativeArtifactControllerTest.java
@@ -114,8 +114,6 @@ class PolicyTypeNativeArtifactControllerTest extends LifecycleStateRunningTest {
/* idempotence */
assertTrue(controller.deploy(policy));
assertDeployed();
-
- // TODO: test a point version upgrade
}
private void assertUndeployed() {
diff --git a/feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/PolicyTypeNativeDroolsControllerTest.java b/feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/PolicyTypeNativeDroolsControllerTest.java
index a964d134..29272a01 100644
--- a/feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/PolicyTypeNativeDroolsControllerTest.java
+++ b/feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/PolicyTypeNativeDroolsControllerTest.java
@@ -46,7 +46,7 @@ import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy;
class PolicyTypeNativeDroolsControllerTest extends LifecycleStateRunningTest {
private static final String EXAMPLE_NATIVE_DROOLS_POLICY_NAME = "example.controller";
private static final String EXAMPLE_NATIVE_DROOLS_POLICY_JSON =
- "src/test/resources/tosca-policy-native-controller-example.json";
+ "src/test/resources/tosca-policy-native-controller-example.json";
/**
* Test initialization.
@@ -75,7 +75,7 @@ class PolicyTypeNativeDroolsControllerTest extends LifecycleStateRunningTest {
ToscaPolicy policy = getPolicyFromFile(EXAMPLE_NATIVE_DROOLS_POLICY_JSON, EXAMPLE_NATIVE_DROOLS_POLICY_NAME);
ControllerPolicy controllerPolicy = fsm.getDomainMaker().convertTo(policy, ControllerPolicy.class);
PolicyTypeNativeDroolsController controller =
- new PolicyTypeNativeDroolsController(policy.getTypeIdentifier(), fsm);
+ new PolicyTypeNativeDroolsController(policy.getTypeIdentifier(), fsm);
assertTrue(controller.undeploy(policy));
assertThatIllegalArgumentException().isThrownBy(
() -> PolicyControllerConstants.getFactory().get(controllerPolicy.getName()));
@@ -103,9 +103,9 @@ class PolicyTypeNativeDroolsControllerTest extends LifecycleStateRunningTest {
TopicEndpointManager.getManager().addTopics(noopTopicProperties);
ToscaPolicy nativeControllerPolicy =
- getExamplesPolicy("policies/usecases.native.controller.policy.input.tosca.json", "usecases");
+ getExamplesPolicy("policies/usecases.native.controller.policy.input.tosca.json", "usecases");
PolicyTypeNativeDroolsController controller =
- new PolicyTypeNativeDroolsController(nativeControllerPolicy.getTypeIdentifier(), fsm);
+ new PolicyTypeNativeDroolsController(nativeControllerPolicy.getTypeIdentifier(), fsm);
assertTrue(controller.deploy(nativeControllerPolicy));
Properties properties = PolicyControllerConstants.getFactory().get("usecases").getProperties();
@@ -115,70 +115,90 @@ class PolicyTypeNativeDroolsControllerTest extends LifecycleStateRunningTest {
assertNull(properties.getProperty("rules.artifactId"));
assertNull(properties.getProperty("rules.version"));
+ assertSourceTopics(properties);
+
+ assertSinkTopics(properties);
+
+ assertEquals("test", properties.getProperty("notes"));
+ assertEquals("auto", properties.getProperty("persistence.type"));
+
+ assertTrue(controller.undeploy(nativeControllerPolicy));
+ }
+
+ private static void assertSourceTopics(Properties properties) {
assertEquals("dcae_topic,appc-cl,appc-lcm-write,sdnr-cl-rsp",
- properties.getProperty("noop.source.topics"));
- assertEquals("appc-cl,appc-lcm-read,policy-cl-mgt,dcae_cl_rsp",
- properties.getProperty("noop.sink.topics"));
+ properties.getProperty("noop.source.topics"));
assertEquals("org.onap.policy.controlloop.CanonicalOnset,org.onap.policy.controlloop.CanonicalAbated",
- properties.getProperty("noop.source.topics.dcae_topic.events"));
+ properties.getProperty("noop.source.topics.dcae_topic.events"));
+
assertEquals("[?($.closedLoopEventStatus == 'ONSET')]",
- properties
- .getProperty("noop.source.topics.dcae_topic.events.org.onap.policy.controlloop.CanonicalOnset.filter"));
+ properties.getProperty("noop.source.topics.dcae_topic.events."
+ + "org.onap.policy.controlloop.CanonicalOnset.filter"));
+
assertEquals("[?($.closedLoopEventStatus == 'ABATED')]",
- properties
- .getProperty("noop.source.topics.dcae_topic.events."
- + "org.onap.policy.controlloop.CanonicalAbated.filter"));
+ properties.getProperty("noop.source.topics.dcae_topic.events."
+ + "org.onap.policy.controlloop.CanonicalAbated.filter"));
+
assertEquals("org.onap.policy.controlloop.util.Serialization,gson",
- properties.getProperty("noop.source.topics.dcae_topic.events.custom.gson"));
+ properties.getProperty("noop.source.topics.dcae_topic.events.custom.gson"));
+
+ assertEquals("org.onap.policy.appc.Response",
+ properties.getProperty("noop.source.topics.appc-cl.events"));
- assertEquals("org.onap.policy.appc.Response", properties.getProperty("noop.source.topics.appc-cl.events"));
assertEquals("[?($.CommonHeader && $.Status)]",
- properties
- .getProperty("noop.source.topics.appc-cl.events.org.onap.policy.appc.Response.filter"));
+ properties.getProperty("noop.source.topics.appc-cl.events.org.onap.policy.appc.Response.filter"));
+
assertEquals("org.onap.policy.appc.util.Serialization,gsonPretty",
- properties.getProperty("noop.source.topics.appc-cl.events.custom.gson"));
+ properties.getProperty("noop.source.topics.appc-cl.events.custom.gson"));
assertEquals("org.onap.policy.appclcm.AppcLcmMessageWrapper",
- properties.getProperty("noop.source.topics.appc-lcm-write.events"));
+ properties.getProperty("noop.source.topics.appc-lcm-write.events"));
+
assertEquals("[?($.type == 'response')]",
- properties
- .getProperty("noop.source.topics.appc-lcm-write.events."
- + "org.onap.policy.appclcm.AppcLcmMessageWrapper.filter"));
+ properties.getProperty("noop.source.topics.appc-lcm-write.events."
+ + "org.onap.policy.appclcm.AppcLcmMessageWrapper.filter"));
+
assertEquals("org.onap.policy.appclcm.util.Serialization,gson",
- properties.getProperty("noop.source.topics.appc-lcm-write.events.custom.gson"));
+ properties.getProperty("noop.source.topics.appc-lcm-write.events.custom.gson"));
assertEquals("org.onap.policy.sdnr.PciResponseWrapper",
- properties.getProperty("noop.source.topics.sdnr-cl-rsp.events"));
+ properties.getProperty("noop.source.topics.sdnr-cl-rsp.events"));
+
assertEquals("[?($.type == 'response')]",
- properties
- .getProperty("noop.source.topics.sdnr-cl-rsp.events."
- + "org.onap.policy.sdnr.PciResponseWrapper.filter"));
+ properties.getProperty("noop.source.topics.sdnr-cl-rsp.events."
+ + "org.onap.policy.sdnr.PciResponseWrapper.filter"));
+
assertEquals("org.onap.policy.sdnr.util.Serialization,gson",
- properties.getProperty("noop.source.topics.sdnr-cl-rsp.events.custom.gson"));
+ properties.getProperty("noop.source.topics.sdnr-cl-rsp.events.custom.gson"));
+ }
+
+ private static void assertSinkTopics(Properties properties) {
+ assertEquals("appc-cl,appc-lcm-read,policy-cl-mgt,dcae_cl_rsp",
+ properties.getProperty("noop.sink.topics"));
+
+ assertEquals("org.onap.policy.appc.Request",
+ properties.getProperty("noop.sink.topics.appc-cl.events"));
- assertEquals("org.onap.policy.appc.Request", properties.getProperty("noop.sink.topics.appc-cl.events"));
assertEquals("org.onap.policy.appc.util.Serialization,gsonPretty",
- properties.getProperty("noop.sink.topics.appc-cl.events.custom.gson"));
+ properties.getProperty("noop.sink.topics.appc-cl.events.custom.gson"));
assertEquals("org.onap.policy.appclcm.AppcLcmMessageWrapper",
- properties.getProperty("noop.sink.topics.appc-lcm-read.events"));
+ properties.getProperty("noop.sink.topics.appc-lcm-read.events"));
+
assertEquals("org.onap.policy.appclcm.util.Serialization,gson",
- properties.getProperty("noop.sink.topics.appc-lcm-read.events.custom.gson"));
+ properties.getProperty("noop.sink.topics.appc-lcm-read.events.custom.gson"));
assertEquals("org.onap.policy.controlloop.VirtualControlLoopNotification",
- properties.getProperty("noop.sink.topics.policy-cl-mgt.events"));
- assertEquals("org.onap.policy.controlloop.util.Serialization,gsonPretty",
- properties.getProperty("noop.sink.topics.policy-cl-mgt.events.custom.gson"));
+ properties.getProperty("noop.sink.topics.policy-cl-mgt.events"));
- assertEquals("org.onap.policy.controlloop.ControlLoopResponse",
- properties.getProperty("noop.sink.topics.dcae_cl_rsp.events"));
assertEquals("org.onap.policy.controlloop.util.Serialization,gsonPretty",
- properties.getProperty("noop.sink.topics.dcae_cl_rsp.events.custom.gson"));
+ properties.getProperty("noop.sink.topics.policy-cl-mgt.events.custom.gson"));
- assertEquals("test", properties.getProperty("notes"));
- assertEquals("auto", properties.getProperty("persistence.type"));
+ assertEquals("org.onap.policy.controlloop.ControlLoopResponse",
+ properties.getProperty("noop.sink.topics.dcae_cl_rsp.events"));
- assertTrue(controller.undeploy(nativeControllerPolicy));
+ assertEquals("org.onap.policy.controlloop.util.Serialization,gsonPretty",
+ properties.getProperty("noop.sink.topics.dcae_cl_rsp.events.custom.gson"));
}
}
diff --git a/feature-lifecycle/src/test/java/org/onap/policy/drools/server/restful/RestLifecycleManagerTest.java b/feature-lifecycle/src/test/java/org/onap/policy/drools/server/restful/RestLifecycleManagerTest.java
index fcf946e4..8aa3f43b 100644
--- a/feature-lifecycle/src/test/java/org/onap/policy/drools/server/restful/RestLifecycleManagerTest.java
+++ b/feature-lifecycle/src/test/java/org/onap/policy/drools/server/restful/RestLifecycleManagerTest.java
@@ -187,14 +187,7 @@ public class RestLifecycleManagerTest {
/* start up configuration */
- resourceLists("policyTypes", 2);
- get("policyTypes/onap.policies.native.drools.Artifact/1.0.0", Status.OK.getStatusCode());
- get("policyTypes/onap.policies.native.drools.Controller/1.0.0", Status.OK.getStatusCode());
- get("policyTypes/onap.policies.controlloop.operational.common.Drools/1.0.0", Status.NOT_FOUND.getStatusCode());
-
- resourceLists("policies", 0);
- get("policies/example.controller/1.0.0", Status.NOT_FOUND.getStatusCode());
- get("policies/example.artifact/1.0.0", Status.NOT_FOUND.getStatusCode());
+ assertStartup();
/* start lifecycle */
@@ -208,35 +201,17 @@ public class RestLifecycleManagerTest {
ToscaPolicy nativeControllerPolicy =
getPolicyFromFile(EXAMPLE_NATIVE_CONTROLLER_POLICY_JSON, EXAMPLE_NATIVE_CONTROLLER_POLICY_NAME);
- booleanPost("policies", toString(nativeControllerPolicy), Status.OK.getStatusCode(), Boolean.TRUE);
-
- assertTrue(PolicyControllerConstants.getFactory().get("lifecycle").isAlive());
- assertFalse(PolicyControllerConstants.getFactory().get("lifecycle").getDrools().isBrained());
- assertFalse(PolicyControllerConstants.getFactory().get("lifecycle").getDrools().isAlive());
-
- get("policyTypes/onap.policies.controlloop.operational.common.Drools/1.0.0", Status.NOT_FOUND.getStatusCode());
-
- resourceLists("policies", 1);
- get("policies/example.controller/1.0.0", Status.OK.getStatusCode());
+ assertAddNativeControllerPolicy(nativeControllerPolicy);
/* add native artifact policy */
ToscaPolicy nativeArtifactPolicy =
getPolicyFromFile(EXAMPLE_NATIVE_ARTIFACT_POLICY_JSON, EXAMPLE_NATIVE_ARTIFACT_POLICY_NAME);
- booleanPost("policies", toString(nativeArtifactPolicy), Status.OK.getStatusCode(), Boolean.TRUE);
-
- assertTrue(PolicyControllerConstants.getFactory().get("lifecycle").isAlive());
- assertTrue(PolicyControllerConstants.getFactory().get("lifecycle").getDrools().isBrained());
- assertTrue(PolicyControllerConstants.getFactory().get("lifecycle").getDrools().isAlive());
+ assertAddNativeArtifactPolicy(nativeArtifactPolicy);
/* verify new supported operational policy types */
- resourceLists("policyTypes", 5);
- get("policyTypes/onap.policies.native.drools.Artifact/1.0.0", Status.OK.getStatusCode());
- get("policyTypes/onap.policies.native.drools.Controller/1.0.0", Status.OK.getStatusCode());
- get("policyTypes/onap.policies.controlloop.operational.common.Drools/1.0.0", Status.OK.getStatusCode());
- get("policyTypes/onap.policies.type1.type2/1.0.0", Status.OK.getStatusCode());
- get("policyTypes/onap.policies.typeA/1.0.0", Status.OK.getStatusCode());
+ verifySupportedOperationalPolicyTypes(5, Status.OK);
/* verify controller and artifact policies */
@@ -268,6 +243,48 @@ public class RestLifecycleManagerTest {
/* individual deploy/undeploy operations */
+ assertDeployUndeploy(opPolicy);
+
+ /* delete native artifact policy */
+
+ verifyDeleteNativeArtifactPolicy(opPolicy);
+
+ /* delete native controller policy */
+
+ verifyDeleteNativeControllerPolicy(opPolicy);
+
+ metrics();
+ }
+
+ private void verifyDeleteNativeControllerPolicy(ToscaPolicy opPolicy) throws CoderException {
+ booleanDelete("policies/example.controller/1.0.0", Status.OK.getStatusCode());
+
+ verifySupportedOperationalPolicyTypes(2, Status.NOT_FOUND);
+
+ resourceLists("policies", 0);
+ get("policies/" + opPolicy.getName() + "/" + opPolicy.getVersion(), Status.NOT_FOUND.getStatusCode());
+ get("policies/example.artifact/1.0.0", Status.NOT_FOUND.getStatusCode());
+ get("policies/example.controller/1.0.0", Status.NOT_FOUND.getStatusCode());
+
+ assertThatIllegalArgumentException().isThrownBy(() -> PolicyControllerConstants.getFactory().get("lifecycle"));
+ opPolicy.getMetadata().remove("policy-id");
+ assertThat(listPost(toString(opPolicy), Status.NOT_ACCEPTABLE.getStatusCode())).isEmpty();
+ }
+
+ private void verifyDeleteNativeArtifactPolicy(ToscaPolicy opPolicy) {
+ booleanDelete("policies/example.artifact/1.0.0", Status.OK.getStatusCode());
+ assertTrue(PolicyControllerConstants.getFactory().get("lifecycle").isAlive());
+ assertFalse(PolicyControllerConstants.getFactory().get("lifecycle").getDrools().isBrained());
+
+ verifySupportedOperationalPolicyTypes(2, Status.NOT_FOUND);
+
+ resourceLists("policies", 1);
+ get("policies/" + opPolicy.getName() + "/" + opPolicy.getVersion(), Status.NOT_FOUND.getStatusCode());
+ get("policies/example.artifact/1.0.0", Status.NOT_FOUND.getStatusCode());
+ get("policies/example.controller/1.0.0", Status.OK.getStatusCode());
+ }
+
+ private void assertDeployUndeploy(ToscaPolicy opPolicy) throws CoderException {
resourceLists("policies/operations", 3);
booleanPost("policies/operations/deployment", toString(opPolicy), Status.OK.getStatusCode(), Boolean.TRUE);
@@ -290,46 +307,47 @@ public class RestLifecycleManagerTest {
get("policies/" + opPolicy.getName() + "/" + opPolicy.getVersion(), Status.NOT_FOUND.getStatusCode());
get("policies/example.controller/1.0.0", Status.OK.getStatusCode());
get("policies/example.artifact/1.0.0", Status.OK.getStatusCode());
+ }
- /* delete native artifact policy */
+ private void verifySupportedOperationalPolicyTypes(int size, Status status) {
+ resourceLists("policyTypes", size);
+ get("policyTypes/onap.policies.native.drools.Artifact/1.0.0", Status.OK.getStatusCode());
+ get("policyTypes/onap.policies.native.drools.Controller/1.0.0", Status.OK.getStatusCode());
+ get("policyTypes/onap.policies.controlloop.operational.common.Drools/1.0.0", status.getStatusCode());
+ get("policyTypes/onap.policies.type1.type2/1.0.0", status.getStatusCode());
+ get("policyTypes/onap.policies.typeA/1.0.0", status.getStatusCode());
+ }
+
+ private void assertAddNativeArtifactPolicy(ToscaPolicy nativeArtifactPolicy) throws CoderException {
+ booleanPost("policies", toString(nativeArtifactPolicy), Status.OK.getStatusCode(), Boolean.TRUE);
+
+ assertTrue(PolicyControllerConstants.getFactory().get("lifecycle").isAlive());
+ assertTrue(PolicyControllerConstants.getFactory().get("lifecycle").getDrools().isBrained());
+ assertTrue(PolicyControllerConstants.getFactory().get("lifecycle").getDrools().isAlive());
+ }
+
+ private void assertAddNativeControllerPolicy(ToscaPolicy nativeControllerPolicy) throws CoderException {
+ booleanPost("policies", toString(nativeControllerPolicy), Status.OK.getStatusCode(), Boolean.TRUE);
- booleanDelete("policies/example.artifact/1.0.0", Status.OK.getStatusCode());
assertTrue(PolicyControllerConstants.getFactory().get("lifecycle").isAlive());
assertFalse(PolicyControllerConstants.getFactory().get("lifecycle").getDrools().isBrained());
+ assertFalse(PolicyControllerConstants.getFactory().get("lifecycle").getDrools().isAlive());
- resourceLists("policyTypes", 2);
- get("policyTypes/onap.policies.native.drools.Artifact/1.0.0", Status.OK.getStatusCode());
- get("policyTypes/onap.policies.native.drools.Controller/1.0.0", Status.OK.getStatusCode());
get("policyTypes/onap.policies.controlloop.operational.common.Drools/1.0.0", Status.NOT_FOUND.getStatusCode());
- get("policyTypes/onap.policies.type1.type2/1.0.0", Status.NOT_FOUND.getStatusCode());
- get("policyTypes/onap.policies.typeA/1.0.0", Status.NOT_FOUND.getStatusCode());
resourceLists("policies", 1);
- get("policies/" + opPolicy.getName() + "/" + opPolicy.getVersion(), Status.NOT_FOUND.getStatusCode());
- get("policies/example.artifact/1.0.0", Status.NOT_FOUND.getStatusCode());
get("policies/example.controller/1.0.0", Status.OK.getStatusCode());
+ }
- /* delete native controller policy */
-
- booleanDelete("policies/example.controller/1.0.0", Status.OK.getStatusCode());
-
+ private void assertStartup() {
resourceLists("policyTypes", 2);
get("policyTypes/onap.policies.native.drools.Artifact/1.0.0", Status.OK.getStatusCode());
get("policyTypes/onap.policies.native.drools.Controller/1.0.0", Status.OK.getStatusCode());
get("policyTypes/onap.policies.controlloop.operational.common.Drools/1.0.0", Status.NOT_FOUND.getStatusCode());
- get("policyTypes/onap.policies.type1.type2/1.0.0", Status.NOT_FOUND.getStatusCode());
- get("policyTypes/onap.policies.typeA/1.0.0", Status.NOT_FOUND.getStatusCode());
resourceLists("policies", 0);
- get("policies/" + opPolicy.getName() + "/" + opPolicy.getVersion(), Status.NOT_FOUND.getStatusCode());
- get("policies/example.artifact/1.0.0", Status.NOT_FOUND.getStatusCode());
get("policies/example.controller/1.0.0", Status.NOT_FOUND.getStatusCode());
-
- assertThatIllegalArgumentException().isThrownBy(() -> PolicyControllerConstants.getFactory().get("lifecycle"));
- opPolicy.getMetadata().remove("policy-id");
- assertThat(listPost(toString(opPolicy), Status.NOT_ACCEPTABLE.getStatusCode())).isEmpty();
-
- metrics();
+ get("policies/example.artifact/1.0.0", Status.NOT_FOUND.getStatusCode());
}
private void testNotNativePolicy(ToscaPolicy toscaPolicy) throws CoderException {
diff --git a/feature-no-locking/src/assembly/assemble_zip.xml b/feature-no-locking/src/assembly/assemble_zip.xml
index 2c74fc00..ded6dff7 100644
--- a/feature-no-locking/src/assembly/assemble_zip.xml
+++ b/feature-no-locking/src/assembly/assemble_zip.xml
@@ -3,6 +3,7 @@
ONAP
================================================================================
Copyright (C) 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.
@@ -60,12 +61,6 @@
<excludes/>
</fileSet>
<fileSet>
- <directory>src/main/feature/db</directory>
- <outputDirectory>db</outputDirectory>
- <fileMode>0744</fileMode>
- <excludes/>
- </fileSet>
- <fileSet>
<directory>src/main/feature/install</directory>
<outputDirectory>install</outputDirectory>
<fileMode>0744</fileMode>
diff --git a/feature-no-locking/src/main/java/org/onap/policy/no/locking/NoLockManager.java b/feature-no-locking/src/main/java/org/onap/policy/no/locking/NoLockManager.java
index 49ea0af9..449f7480 100644
--- a/feature-no-locking/src/main/java/org/onap/policy/no/locking/NoLockManager.java
+++ b/feature-no-locking/src/main/java/org/onap/policy/no/locking/NoLockManager.java
@@ -3,6 +3,7 @@
* ONAP
* ================================================================================
* Copyright (C) 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.no.locking;
-import java.util.Properties;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.onap.policy.drools.core.lock.AlwaysSuccessLock;
@@ -28,7 +28,6 @@ import org.onap.policy.drools.core.lock.Lock;
import org.onap.policy.drools.core.lock.LockCallback;
import org.onap.policy.drools.core.lock.PolicyResourceLockManager;
import org.onap.policy.drools.features.PolicyEngineFeatureApi;
-import org.onap.policy.drools.system.PolicyEngine;
/**
* In contrast with other implementations the no-lock manager provides non-synchronized access
@@ -43,8 +42,8 @@ public class NoLockManager implements PolicyResourceLockManager, PolicyEngineFea
@Override
public Lock createLock(String resourceId, String ownerKey, int holdSec,
- LockCallback callback, boolean waitForLock) {
- var successLock = new AlwaysSuccessLock(resourceId, ownerKey, holdSec, callback);
+ LockCallback callback, boolean waitForLock) {
+ var successLock = new AlwaysSuccessLock(resourceId, ownerKey, holdSec, callback);
successLock.notifyAvailable();
return successLock;
}
@@ -90,7 +89,7 @@ public class NoLockManager implements PolicyResourceLockManager, PolicyEngineFea
}
@Override
- public PolicyResourceLockManager beforeCreateLockManager(PolicyEngine engine, Properties properties) {
+ public PolicyResourceLockManager beforeCreateLockManager() {
return this;
}
}
diff --git a/feature-no-locking/src/test/java/org/onap/policy/no/locking/NoLockManagerTest.java b/feature-no-locking/src/test/java/org/onap/policy/no/locking/NoLockManagerTest.java
index 5b5e0964..22f3f5d1 100644
--- a/feature-no-locking/src/test/java/org/onap/policy/no/locking/NoLockManagerTest.java
+++ b/feature-no-locking/src/test/java/org/onap/policy/no/locking/NoLockManagerTest.java
@@ -93,7 +93,7 @@ public class NoLockManagerTest {
@Test
void testBeforeCreateLockManager() {
- assertEquals(nlm, nlm.beforeCreateLockManager(null, null));
+ assertEquals(nlm, nlm.beforeCreateLockManager());
}
@Test
diff --git a/feature-pooling-messages/src/assembly/assemble_zip.xml b/feature-pooling-messages/src/assembly/assemble_zip.xml
index 67424116..a4c7b0fa 100644
--- a/feature-pooling-messages/src/assembly/assemble_zip.xml
+++ b/feature-pooling-messages/src/assembly/assemble_zip.xml
@@ -3,6 +3,7 @@
feature-pooling-messages
================================================================================
Copyright (C) 2018 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.
@@ -61,12 +62,6 @@
<excludes/>
</fileSet>
<fileSet>
- <directory>src/main/feature/db</directory>
- <outputDirectory>db</outputDirectory>
- <fileMode>0744</fileMode>
- <excludes/>
- </fileSet>
- <fileSet>
<directory>src/main/feature/install</directory>
<outputDirectory>install</outputDirectory>
<fileMode>0744</fileMode>
diff --git a/feature-pooling-messages/src/main/feature/config/feature-pooling-messages.properties b/feature-pooling-messages/src/main/feature/config/feature-pooling-messages.properties
index 3870ede1..020df961 100644
--- a/feature-pooling-messages/src/main/feature/config/feature-pooling-messages.properties
+++ b/feature-pooling-messages/src/main/feature/config/feature-pooling-messages.properties
@@ -82,8 +82,10 @@ kafka.source.topics.policy-pdp-pooling.servers=${env:KAFKA_SERVERS}
kafka.source.topics.policy-pdp-pooling.effectiveTopic=${env:POOLING_TOPIC}
kafka.source.topics.policy-pdp-pooling.apiKey=
kafka.source.topics.policy-pdp-pooling.apiSecret=
+kafka.source.topics.policy-pdp-pooling.additionalProps=${env:KAFKA_ADDITIONAL_PROPS}
kafka.sink.topics.policy-pdp-pooling.servers=${env:KAFKA_SERVERS}
kafka.sink.topics.policy-pdp-pooling.effectiveTopic=${env:POOLING_TOPIC}
kafka.sink.topics.policy-pdp-pooling.apiKey=
kafka.sink.topics.policy-pdp-pooling.apiSecret=
+kafka.sink.topics.policy-pdp-pooling.additionalProps=${env:KAFKA_ADDITIONAL_PROPS}
diff --git a/feature-test-transaction/src/assembly/assemble_zip.xml b/feature-test-transaction/src/assembly/assemble_zip.xml
index 9945a1c9..0b5763c4 100644
--- a/feature-test-transaction/src/assembly/assemble_zip.xml
+++ b/feature-test-transaction/src/assembly/assemble_zip.xml
@@ -3,6 +3,7 @@
feature-test-transaction
================================================================================
Copyright (C) 2017 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.
@@ -59,11 +60,6 @@
<fileMode>0744</fileMode>
</fileSet>
<fileSet>
- <directory>src/main/feature/db</directory>
- <outputDirectory>db</outputDirectory>
- <fileMode>0744</fileMode>
- </fileSet>
- <fileSet>
<directory>src/main/feature/install</directory>
<outputDirectory>install</outputDirectory>
<fileMode>0744</fileMode>
diff --git a/packages/base/src/files/bin/policy b/packages/base/src/files/bin/policy
index 690fe1e5..c5ec37fa 100644
--- a/packages/base/src/files/bin/policy
+++ b/packages/base/src/files/bin/policy
@@ -4,6 +4,7 @@
# ONAP
# ================================================================================
# 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.
@@ -72,13 +73,6 @@ function policy_status() {
echo
echo "[features]"
features status
-
- local databases=$(ls -d "${POLICY_HOME}"/etc/db/migration/*/ 2>/dev/null)
- if [ -n "${databases}" ]; then
- echo "[migration]"
- db-migrator -s ALL -o ok
- fi
-
}
function policy_start() {
diff --git a/packages/docker/src/main/docker/Dockerfile b/packages/docker/src/main/docker/Dockerfile
index a3d013d4..d263ba71 100644
--- a/packages/docker/src/main/docker/Dockerfile
+++ b/packages/docker/src/main/docker/Dockerfile
@@ -2,7 +2,7 @@
# Dockerfile
# ============LICENSE_START=======================================================
# Copyright (C) 2020-2021 AT&T Intellectual Property. All rights reserved.
-# Modifications Copyright (C) 2022-2023 Nordix Foundation.
+# Modifications Copyright (C) 2022-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.
@@ -52,9 +52,7 @@ ENV http_proxy $http_proxy
USER root
RUN apk update && \
- apk add --no-cache mariadb-client \
- file \
- maven \
+ apk add --no-cache file maven \
net-tools netcat-openbsd sudo less vim openssl \
&& python3 -m pip install --no-cache-dir --upgrade setuptools http-prompt \
&& python3 -m pip install --no-cache-dir httpie
diff --git a/packages/docker/src/main/docker/pdpd-entrypoint.sh b/packages/docker/src/main/docker/pdpd-entrypoint.sh
index 2caca628..c2e3f020 100644
--- a/packages/docker/src/main/docker/pdpd-entrypoint.sh
+++ b/packages/docker/src/main/docker/pdpd-entrypoint.sh
@@ -138,26 +138,6 @@ function serverConfig {
done
}
-function db {
- if [ "${DEBUG}" = "y" ]; then
- echo "-- db --"
- set -x
- fi
-
- if [ -z "${SQL_HOST}" ]; then
- return 0
- fi
-
- if [ -z "${SQL_PORT}" ]; then
- export SQL_PORT=3306
- fi
-
- echo "Waiting for ${SQL_HOST}:${SQL_PORT} ..."
- timeout 120 sh -c 'until nc -vz -w 20 "${SQL_HOST}" "${SQL_PORT}"; do echo -n "."; sleep 1; done'
-
- "${POLICY_HOME}"/bin/db-migrator -s ALL -o upgrade
-}
-
function inspect {
if [ "${DEBUG}" = "y" ]; then
echo "-- inspect --"
@@ -209,7 +189,6 @@ function configure {
fi
reload
- db
}
function vmBoot {
@@ -219,7 +198,6 @@ function vmBoot {
fi
reload
- db
start
scripts "post.sh"
}
diff --git a/packages/docker/src/main/docker/suse.Dockerfile b/packages/docker/src/main/docker/suse.Dockerfile
index e6bf9dbd..c83a5cc6 100644
--- a/packages/docker/src/main/docker/suse.Dockerfile
+++ b/packages/docker/src/main/docker/suse.Dockerfile
@@ -1,7 +1,7 @@
#-------------------------------------------------------------------------------
# Dockerfile
# ============LICENSE_START=======================================================
-# Copyright (C) 2022 Nordix Foundation.
+# Copyright (C) 2022, 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.
@@ -56,7 +56,6 @@ RUN zypper -n -q install --no-recommends \
gzip \
java-17-openjdk-devel \
maven \
- mariadb-client \
netcat-openbsd \
python3 \
python3-pip \
diff --git a/policy-core/pom.xml b/policy-core/pom.xml
index 57fd613c..9eb0af1a 100644
--- a/policy-core/pom.xml
+++ b/policy-core/pom.xml
@@ -133,6 +133,10 @@
<groupId>org.glassfish.hk2.external</groupId>
<artifactId>jakarta.inject</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-test</artifactId>
+ </dependency>
</dependencies>
</project>
diff --git a/policy-core/src/main/java/org/onap/policy/drools/core/PolicyContainer.java b/policy-core/src/main/java/org/onap/policy/drools/core/PolicyContainer.java
index ec5ceb21..533ac223 100644
--- a/policy-core/src/main/java/org/onap/policy/drools/core/PolicyContainer.java
+++ b/policy-core/src/main/java/org/onap/policy/drools/core/PolicyContainer.java
@@ -28,6 +28,8 @@ import java.util.HashSet;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import lombok.Getter;
+import lombok.NonNull;
+import org.apache.commons.lang3.StringUtils;
import org.kie.api.KieServices;
import org.kie.api.builder.KieScanner;
import org.kie.api.builder.Message;
@@ -49,13 +51,13 @@ public class PolicyContainer implements Startable {
// get an instance of logger
private static final Logger logger = LoggerFactory.getLogger(PolicyContainer.class);
// 'KieServices' singleton
- private static KieServices kieServices = KieServices.Factory.get();
+ private static final KieServices kieServices = KieServices.Factory.get();
// set of all 'PolicyContainer' instances
private static final HashSet<PolicyContainer> containers = new HashSet<>();
// maps feature objects to per-PolicyContainer data
- private ConcurrentHashMap<Object, Object> adjuncts = new ConcurrentHashMap<>();
+ private final ConcurrentHashMap<Object, Object> adjuncts = new ConcurrentHashMap<>();
// 'KieContainer' associated with this 'PolicyContainer'
@Getter
@@ -90,9 +92,9 @@ public class PolicyContainer implements Startable {
*
* <p>An exception occurs if the creation of the 'KieContainer' fails.
*
- * @param groupId the 'groupId' associated with the artifact
+ * @param groupId the 'groupId' associated with the artifact
* @param artifactId the artifact name
- * @param version a comma-separated list of possible versions
+ * @param version a comma-separated list of possible versions
*/
public PolicyContainer(String groupId, String artifactId, String version) {
this(kieServices.newReleaseId(groupId, artifactId, version));
@@ -112,7 +114,7 @@ public class PolicyContainer implements Startable {
if (newReleaseId.getVersion().contains(",")) {
// this is actually a comma-separated list of release ids
newReleaseId =
- loadArtifact(newReleaseId.getGroupId(), newReleaseId.getArtifactId(), newReleaseId.getVersion());
+ loadArtifact(newReleaseId.getGroupId(), newReleaseId.getArtifactId(), newReleaseId.getVersion());
} else {
kieContainer = kieServices.newKieContainer(newReleaseId);
}
@@ -138,9 +140,9 @@ public class PolicyContainer implements Startable {
* Load an artifact into a new KieContainer. This method handles the case where the 'version' is
* actually a comma-separated list of versions.
*
- * @param groupId the 'groupId' associated with the artifact
+ * @param groupId the 'groupId' associated with the artifact
* @param artifactId the artifact name
- * @param version a comma-separated list of possible versions
+ * @param version a comma-separated list of possible versions
*/
private ReleaseId loadArtifact(String groupId, String artifactId, String version) {
String[] versions = version.split(",");
@@ -180,15 +182,11 @@ public class PolicyContainer implements Startable {
}
/**
- * Get name.
+ * Get name in the form of (groupId + ":" + artifactId + ":" + version)
+ * Note that the name changes after a successful call to 'updateToVersion', although
+ * typically only the 'version' part changes.
*
- * @return the name of the container, which is the String equivalent of the 'ReleaseId'. It has
- * the form:
- *
- * (groupId + ":" + artifactId + ":" + version)
- *
- * Note that the name changes after a successful call to 'updateToVersion', although
- * typically only the 'version' part changes.
+ * @return the name of the container, which is the String equivalent of the 'ReleaseId'.
*/
public String getName() {
return kieContainer.getReleaseId().toString();
@@ -204,7 +202,7 @@ public class PolicyContainer implements Startable {
}
/**
- * Get group Id.
+ * Get group id.
*
* @return the Maven GroupId of the top-level artifact wrapped by the container.
*/
@@ -235,7 +233,7 @@ public class PolicyContainer implements Startable {
* Fetch the named 'PolicySession'.
*
* @param name the name of the KieSession (which is also the name of the associated
- * PolicySession)
+ * PolicySession)
* @return a PolicySession if found, 'null' if not
*/
public PolicySession getPolicySession(String name) {
@@ -245,7 +243,7 @@ public class PolicyContainer implements Startable {
/**
* Internal method to create a PolicySession, possibly restoring it from persistent storage.
*
- * @param name of the KieSession and PolicySession
+ * @param name of the KieSession and PolicySession
* @param kieBaseName name of the associated 'KieBase' instance
* @return a new or existing PolicySession, or 'null' if not found
*/
@@ -255,7 +253,7 @@ public class PolicyContainer implements Startable {
PolicySession session = sessions.computeIfAbsent(name, key -> makeSession(name, kieBaseName));
logger.info("activatePolicySession:session - {} is returned.",
- session == null ? "null" : session.getFullName());
+ session == null ? "null" : session.getFullName());
return session;
}
}
@@ -307,30 +305,32 @@ public class PolicyContainer implements Startable {
* provides a way for 'KieSession' instances that are created programmatically to fit into this
* framework.
*
- * @param name the name for the new 'PolicySession'
+ * @param name the name for the new 'PolicySession'
* @param kieSession a 'KieSession' instance, that will be included in this infrastructure
* @return the new 'PolicySession'
* @throws IllegalArgumentException if 'kieSession' does not reside within this container
- * @throws IllegalStateException if a 'PolicySession' already exists with this name
+ * @throws IllegalStateException if a 'PolicySession' already exists with this name
*/
public PolicySession adoptKieSession(String name, KieSession kieSession) {
- if (name == null) {
+ if (StringUtils.isBlank(name)) {
logger.warn("adoptKieSession:input name is null");
throw new IllegalArgumentException("KieSession input name is null " + getName());
- } else if (kieSession == null) {
+ }
+
+ if (kieSession == null) {
logger.warn("adoptKieSession:input kieSession is null");
throw new IllegalArgumentException("KieSession '" + name + "' is null " + getName());
- } else {
- logger.info("adoptKieSession:name: {} kieSession: {}", name, kieSession);
}
+
+ logger.info("adoptKieSession:name: {} kieSession: {}", name, kieSession);
// fetch KieBase, and verify it belongs to this KieContainer
var match = false;
var kieBase = kieSession.getKieBase();
logger.info("adoptKieSession:kieBase: {}", kieBase);
for (String kieBaseName : kieContainer.getKieBaseNames()) {
logger.info("adoptKieSession:kieBaseName: {}", kieBaseName);
- if (kieBase == kieContainer.getKieBase(kieBaseName)) {
+ if (kieBase.equals(kieContainer.getKieBase(kieBaseName))) {
match = true;
break;
}
@@ -338,9 +338,9 @@ public class PolicyContainer implements Startable {
logger.info("adoptKieSession:match {}", match);
// if we don't have a match yet, the last chance is to look at the
// default KieBase, if it exists
- if (!match && kieBase != kieContainer.getKieBase()) {
+ if (!match && !kieBase.equals(kieContainer.getKieBase())) {
throw new IllegalArgumentException(
- "KieSession '" + name + "' does not reside within container " + getName());
+ "KieSession '" + name + "' does not reside within container " + getName());
}
synchronized (sessions) {
@@ -370,15 +370,13 @@ public class PolicyContainer implements Startable {
* This call 'KieContainer.updateToVersion()', and returns the associated response as a String.
* If successful, the name of this 'PolicyContainer' changes to match the new version.
*
- * @param newVersion this is the version to update to (the 'groupId' and 'artifactId' remain the
- * same)
- * @return the list of messages associated with the update (not sure if this can be 'null', or
- * how to determine success/failure)
+ * @param newVersion this is the version to update to ('groupId' and 'artifactId' remain the same)
+ * @return the list of messages associated with the update
*/
public String updateToVersion(String newVersion) {
var releaseId = kieContainer.getReleaseId();
- var results = this.updateToVersion(
- kieServices.newReleaseId(releaseId.getGroupId(), releaseId.getArtifactId(), newVersion));
+ var results = this.updateToVersion(kieServices.newReleaseId(releaseId.getGroupId(),
+ releaseId.getArtifactId(), newVersion));
List<Message> messages = results == null ? null : results.getMessages();
return messages == null ? null : messages.toString();
@@ -455,46 +453,46 @@ public class PolicyContainer implements Startable {
*
* @param releaseId the release id used to create the container
*/
- public synchronized void startScanner(ReleaseId releaseId) {
+ public synchronized void startScanner(@NonNull ReleaseId releaseId) {
String version = releaseId.getVersion();
- if (scannerStarted || scanner != null || version == null) {
+ if (!isValidVersion(version)) {
+ logger.warn("version is invalid - check if empty or if it's not LATEST, RELEASE or SNAPSHOT");
return;
}
- if (!("LATEST".equals(version) || "RELEASE".equals(version) || version.endsWith("-SNAPSHOT"))) {
+ if (isScannerStarted()) {
+ logger.warn("scanner already started");
return;
}
// create the scanner, and poll at 60 second intervals
- try {
- scannerStarted = true;
- // start this in a separate thread -- it can block for a long time
- new Thread("Scanner Starter " + getName()) {
- @Override
- public void run() {
+ scannerStarted = true;
+
+ // start this in a separate thread -- it can block for a long time
+ new Thread("Scanner Starter " + getName()) {
+ @Override
+ public void run() {
+ try {
scanner = kieServices.newKieScanner(kieContainer);
scanner.start(60000L);
+ } catch (Exception e) {
+ // sometimes the scanner initialization fails for some reason
+ logger.error("startScanner error", e);
}
- }.start();
- } catch (Exception e) {
- // sometimes the scanner initialization fails for some reason
- logger.error("startScanner error", e);
- }
+ }
+ }.start();
}
/**
* Insert a fact into a specific named session.
*
- * @param name this is the session name
+ * @param name this is the session name
* @param object this is the fact to be inserted into the session
* @return 'true' if the named session was found, 'false' if not
*/
public boolean insert(String name, Object object) {
- // TODO: Should the definition of 'name' be expanded to include an
- // alternate entry point as well? For example, 'name.entryPoint' (or
- // something other than '.' if that is a problem).
synchronized (sessions) {
PolicySession session = sessions.get(name);
if (session != null) {
@@ -568,7 +566,7 @@ public class PolicyContainer implements Startable {
Collection<PolicySession> localSessions;
synchronized (sessions) {
- // local set containing all of the sessions
+ // local set containing all the sessions
localSessions = new HashSet<>(sessions.values());
// clear the 'name->session' map in 'PolicyContainer'
@@ -631,7 +629,7 @@ public class PolicyContainer implements Startable {
Collection<PolicySession> localSessions;
synchronized (sessions) {
- // local set containing all of the sessions
+ // local set containing all the sessions
localSessions = new HashSet<>(sessions.values());
// clear the 'name->session' map in 'PolicyContainer'
@@ -667,7 +665,7 @@ public class PolicyContainer implements Startable {
* This method is called when the host goes from the 'standby->active' state.
*/
public static void activate() {
- // start all of the 'PolicyContainer' instances
+ // start all the 'PolicyContainer' instances
for (PolicyContainer container : containers) {
try {
container.start();
@@ -681,7 +679,7 @@ public class PolicyContainer implements Startable {
* This method is called when the host goes from the 'active->standby' state.
*/
public static void deactivate() {
- // deactivate all of the 'PolicyContainer' instances
+ // deactivate all the 'PolicyContainer' instances
for (PolicyContainer container : containers) {
try {
container.stop();
@@ -694,7 +692,7 @@ public class PolicyContainer implements Startable {
/**
* This method does the following:
*
- * <p>1) Initializes logging 2) Starts the DroolsPDP Integrity Monitor 3) Initilaizes persistence
+ * <p>1) Initializes logging 2) Starts the DroolsPDP Integrity Monitor 3) Initializes persistence
*
* <p>It no longer reads in properties files, o creates 'PolicyContainer' instances.
*
@@ -718,7 +716,7 @@ public class PolicyContainer implements Startable {
* Fetch the adjunct object associated with a given feature.
*
* @param object this is typically the singleton feature object that is used as a key, but it
- * might also be useful to use nested objects within the feature as keys.
+ * might also be useful to use nested objects within the feature as keys.
* @return a feature-specific object associated with the key, or 'null' if it is not found.
*/
public Object getAdjunct(Object object) {
@@ -729,9 +727,9 @@ public class PolicyContainer implements Startable {
* Store the adjunct object associated with a given feature.
*
* @param object this is typically the singleton feature object that is used as a key, but it
- * might also be useful to use nested objects within the feature as keys.
- * @param value a feature-specific object associated with the key, or 'null' if the
- * feature-specific object should be removed
+ * might also be useful to use nested objects within the feature as keys.
+ * @param value a feature-specific object associated with the key, or 'null' if the
+ * feature-specific object should be removed
*/
public void setAdjunct(Object object, Object value) {
if (value == null) {
@@ -768,4 +766,33 @@ public class PolicyContainer implements Startable {
KieUtils.addKiePackages(kieContainer.getKieBase(name), kiePackages);
}
}
+
+ /**
+ * Checks if boolean scannerStarted is true and if scanner itself is not null.
+ *
+ * @return true if the above is all true, false otherwise.
+ */
+ public boolean isScannerStarted() {
+ return scannerStarted || scanner != null;
+ }
+
+ /**
+ * Validation of a release version for starting a scanner.
+ * Can be valid if LATEST, RELEASE or SNAPSHOT version.
+ *
+ * @param version release version
+ * @return true if valid based on values above, false otherwise.
+ */
+ protected boolean isValidVersion(String version) {
+ if (StringUtils.isBlank(version)) {
+ logger.warn("version is empty");
+ return false;
+ }
+
+ if (version.toUpperCase().contains("LATEST") || version.toUpperCase().contains("RELEASE")) {
+ return true;
+ } else {
+ return version.toUpperCase().endsWith("-SNAPSHOT");
+ }
+ }
}
diff --git a/policy-core/src/main/java/org/onap/policy/drools/core/jmx/PdpJmx.java b/policy-core/src/main/java/org/onap/policy/drools/core/jmx/PdpJmx.java
index 4356d111..4aa8de49 100644
--- a/policy-core/src/main/java/org/onap/policy/drools/core/jmx/PdpJmx.java
+++ b/policy-core/src/main/java/org/onap/policy/drools/core/jmx/PdpJmx.java
@@ -27,7 +27,7 @@ import lombok.Getter;
public class PdpJmx implements PdpJmxMBean {
@Getter
- private static PdpJmx instance = new PdpJmx();
+ static PdpJmx instance = new PdpJmx();
private final AtomicLong updates = new AtomicLong();
private final AtomicLong actions = new AtomicLong();
diff --git a/policy-core/src/test/java/org/onap/policy/drools/core/DroolsContainerTest.java b/policy-core/src/test/java/org/onap/policy/drools/core/DroolsContainerTest.java
index abed9727..d6804b60 100644
--- a/policy-core/src/test/java/org/onap/policy/drools/core/DroolsContainerTest.java
+++ b/policy-core/src/test/java/org/onap/policy/drools/core/DroolsContainerTest.java
@@ -79,44 +79,7 @@ public class DroolsContainerTest {
*/
@Test
void createAndUpdate() throws Exception {
- // make sure feature log starts out clean
- PolicySessionFeatureApiMock.getLog();
-
- // run 'globalInit', and verify expected feature hook fired
- PolicyContainer.globalInit(new String[0]);
- assertEquals(List.of("globalInit"),
- PolicySessionFeatureApiMock.getLog());
-
- // initial conditions -- there should be no containers
- assertEquals(0, PolicyContainer.getPolicyContainers().size());
-
- // create the container, and start it
- PolicyContainer container =
- new PolicyContainer("org.onap.policy.drools-pdp",
- "drools-artifact1", "17.1.0-SNAPSHOT");
- container.start();
- assertTrue(container.isAlive());
-
- // verify expected feature hooks fired
- assertEquals(Arrays.asList("activatePolicySession",
- "newPolicySession",
- "selectThreadModel"),
- PolicySessionFeatureApiMock.getLog());
-
- // this container should be on the list
- {
- Collection<PolicyContainer> containers =
- PolicyContainer.getPolicyContainers();
- assertEquals(1, containers.size());
- assertTrue(containers.contains(container));
- }
-
- // verify initial container attributes
- assertEquals("org.onap.policy.drools-pdp:drools-artifact1:17.1.0-SNAPSHOT",
- container.getName());
- assertEquals("org.onap.policy.drools-pdp", container.getGroupId());
- assertEquals("drools-artifact1", container.getArtifactId());
- assertEquals("17.1.0-SNAPSHOT", container.getVersion());
+ PolicyContainer container = validateCreatedContainer();
try {
// fetch the session, and verify that it exists
@@ -225,20 +188,17 @@ public class DroolsContainerTest {
// run 'globalInit', and verify expected feature hook fired
PolicyContainer.globalInit(new String[0]);
- assertEquals(List.of("globalInit-exception"),
- PolicySessionFeatureApiMock.getLog());
+ assertEquals(List.of("globalInit-exception"), PolicySessionFeatureApiMock.getLog());
// initial conditions -- there should be no containers
assertEquals(0, PolicyContainer.getPolicyContainers().size());
- String versionList =
- "17.3.0-SNAPSHOT,17.1.0-SNAPSHOT,17.2.0-SNAPSHOT";
+ String versionList = "17.3.0-SNAPSHOT,17.1.0-SNAPSHOT,17.2.0-SNAPSHOT";
// versions should be tried in order -- the 17.1.0-SNAPSHOT should "win",
// given the fact that '17.3.0-SNAPSHOT' doesn't exist
PolicyContainer container =
- new PolicyContainer("org.onap.policy.drools-pdp",
- "drools-artifact1", versionList);
+ new PolicyContainer("org.onap.policy.drools-pdp", "drools-artifact1", versionList);
// the following should be equivalent to 'container.start()'
PolicyContainer.activate();
assertTrue(container.isAlive());
@@ -251,15 +211,12 @@ public class DroolsContainerTest {
// this container should be on the list
{
- Collection<PolicyContainer> containers =
- PolicyContainer.getPolicyContainers();
- assertEquals(1, containers.size());
- assertTrue(containers.contains(container));
+ Collection<PolicyContainer> containers = PolicyContainer.getPolicyContainers();
+ assertTrue(containers.contains(container) && (containers.size() == 1));
}
// verify initial container attributes
- assertEquals("org.onap.policy.drools-pdp:drools-artifact1:17.1.0-SNAPSHOT",
- container.getName());
+ assertEquals("org.onap.policy.drools-pdp:drools-artifact1:17.1.0-SNAPSHOT", container.getName());
assertEquals("org.onap.policy.drools-pdp", container.getGroupId());
assertEquals("drools-artifact1", container.getArtifactId());
assertEquals("17.1.0-SNAPSHOT", container.getVersion());
@@ -288,8 +245,7 @@ public class DroolsContainerTest {
// get all sessions, and verify that this one is the only one
{
Collection<PolicySession> sessions = container.getPolicySessions();
- assertEquals(1, sessions.size());
- assertTrue(sessions.contains(session));
+ assertTrue(sessions.contains(session) && (1 == sessions.size()));
}
// verify session attributes
@@ -341,4 +297,50 @@ public class DroolsContainerTest {
// final conditions -- there should be no containers
assertEquals(0, PolicyContainer.getPolicyContainers().size());
}
+
+ /**
+ * Creates a policy container.
+ * @return a container used on create and update test
+ */
+ private static PolicyContainer validateCreatedContainer() {
+ // make sure feature log starts out clean
+ PolicySessionFeatureApiMock.getLog();
+
+ // run 'globalInit', and verify expected feature hook fired
+ PolicyContainer.globalInit(new String[0]);
+ assertEquals(List.of("globalInit"),
+ PolicySessionFeatureApiMock.getLog());
+
+ // initial conditions -- there should be no containers
+ assertEquals(0, PolicyContainer.getPolicyContainers().size());
+
+ // create the container, and start it
+ PolicyContainer container =
+ new PolicyContainer("org.onap.policy.drools-pdp",
+ "drools-artifact1", "17.1.0-SNAPSHOT");
+ container.start();
+ assertTrue(container.isAlive());
+
+ // verify expected feature hooks fired
+ assertEquals(Arrays.asList("activatePolicySession",
+ "newPolicySession",
+ "selectThreadModel"),
+ PolicySessionFeatureApiMock.getLog());
+
+ // this container should be on the list
+ {
+ Collection<PolicyContainer> containers =
+ PolicyContainer.getPolicyContainers();
+ assertEquals(1, containers.size());
+ assertTrue(containers.contains(container));
+ }
+
+ // verify initial container attributes
+ assertEquals("org.onap.policy.drools-pdp:drools-artifact1:17.1.0-SNAPSHOT",
+ container.getName());
+ assertEquals("org.onap.policy.drools-pdp", container.getGroupId());
+ assertEquals("drools-artifact1", container.getArtifactId());
+ assertEquals("17.1.0-SNAPSHOT", container.getVersion());
+ return container;
+ }
}
diff --git a/policy-core/src/test/java/org/onap/policy/drools/core/PolicyContainerTest.java b/policy-core/src/test/java/org/onap/policy/drools/core/PolicyContainerTest.java
new file mode 100644
index 00000000..72c8d2d3
--- /dev/null
+++ b/policy-core/src/test/java/org/onap/policy/drools/core/PolicyContainerTest.java
@@ -0,0 +1,230 @@
+/*-
+ * ============LICENSE_START================================================
+ * policy-core
+ * =========================================================================
+ * 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.
+ * 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.drools.core;
+
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.isNull;
+import static org.mockito.Mockito.doCallRealMethod;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.HashMap;
+import java.util.List;
+import org.junit.jupiter.api.Test;
+import org.kie.api.KieBase;
+import org.kie.api.KieServices;
+import org.kie.api.builder.KieScanner;
+import org.kie.api.builder.ReleaseId;
+import org.kie.api.event.rule.AgendaEventListener;
+import org.kie.api.event.rule.RuleRuntimeEventListener;
+import org.kie.api.runtime.KieContainer;
+import org.kie.api.runtime.KieSession;
+import org.mockito.MockedStatic;
+import org.mockito.Mockito;
+import org.springframework.test.util.ReflectionTestUtils;
+
+class PolicyContainerTest {
+
+ private static final String VERSION = "1.0.0";
+
+ @Test
+ void adoptKieSession_Exceptions() {
+ var mockKieSession = mock(KieSession.class);
+ var policyContainer = mock(PolicyContainer.class);
+
+ when(policyContainer.getName()).thenReturn("kieReleaseName");
+ when(policyContainer.adoptKieSession(any(), eq(mockKieSession))).thenCallRealMethod();
+ when(policyContainer.adoptKieSession("name", null)).thenCallRealMethod();
+
+ assertThatThrownBy(() -> policyContainer.adoptKieSession("", mockKieSession))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("KieSession input name is null kieReleaseName");
+
+ assertThatThrownBy(() -> policyContainer.adoptKieSession(null, mockKieSession))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("KieSession input name is null kieReleaseName");
+
+ assertThatThrownBy(() -> policyContainer.adoptKieSession("name", null))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("KieSession 'name' is null kieReleaseName");
+ }
+
+ @Test
+ void testAdoptKieSession() {
+ var mockKieSession = mock(KieSession.class);
+ doNothing().when(mockKieSession).addEventListener(any(AgendaEventListener.class));
+ doNothing().when(mockKieSession).addEventListener(any(RuleRuntimeEventListener.class));
+
+ var policyContainer = mock(PolicyContainer.class);
+ when(policyContainer.adoptKieSession("name", mockKieSession)).thenCallRealMethod();
+ when(policyContainer.getName()).thenReturn("kieReleaseName");
+
+ var mockKieBase = mock(KieBase.class);
+ when(mockKieSession.getKieBase()).thenReturn(mockKieBase);
+
+ var mockKieContainer = mock(KieContainer.class);
+ when(policyContainer.getKieContainer()).thenReturn(mockKieContainer);
+ when(mockKieContainer.getKieBase("baseName")).thenReturn(mockKieBase);
+ when(mockKieContainer.getKieBaseNames()).thenReturn(List.of("baseName"));
+ when(mockKieContainer.getKieBase()).thenReturn(mockKieBase);
+
+ HashMap<String, PolicySession> sessions = new HashMap<>();
+ ReflectionTestUtils.setField(policyContainer, "sessions", sessions);
+ ReflectionTestUtils.setField(policyContainer, "kieContainer", mockKieContainer);
+
+ assertNotNull(policyContainer.adoptKieSession("name", mockKieSession));
+ assertThatThrownBy(() -> policyContainer.adoptKieSession("name", mockKieSession))
+ .isInstanceOf(IllegalStateException.class)
+ .hasMessageContaining("PolicySession 'name' already exists");
+ }
+
+ @Test
+ void testAdoptKieSession_KieBaseDoesntMatch() {
+ var mockKieSession = mock(KieSession.class);
+
+ var policyContainer = mock(PolicyContainer.class);
+ when(policyContainer.adoptKieSession("name", mockKieSession)).thenCallRealMethod();
+ when(policyContainer.getName()).thenReturn("kieReleaseName");
+
+ var mockKieBase = mock(KieBase.class);
+ when(mockKieSession.getKieBase()).thenReturn(mockKieBase);
+ var mockKieBase2 = mock(KieBase.class);
+
+ var mockKieContainer = mock(KieContainer.class);
+ when(policyContainer.getKieContainer()).thenReturn(mockKieContainer);
+ when(mockKieContainer.getKieBase("baseName")).thenReturn(mockKieBase2);
+ when(mockKieContainer.getKieBaseNames()).thenReturn(List.of("baseName"));
+ when(mockKieContainer.getKieBase()).thenReturn(mockKieBase2);
+
+ ReflectionTestUtils.setField(policyContainer, "kieContainer", mockKieContainer);
+
+ assertThatThrownBy(() -> policyContainer.adoptKieSession("name", mockKieSession))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("KieSession 'name' does not reside within container kieReleaseName");
+ }
+
+ @Test
+ void startScanner_Exceptions() {
+ var policyContainer = mock(PolicyContainer.class);
+ doCallRealMethod().when(policyContainer).startScanner(any(ReleaseId.class));
+ doCallRealMethod().when(policyContainer).startScanner(isNull());
+ when(policyContainer.isScannerStarted()).thenCallRealMethod();
+
+ assertThatThrownBy(() -> policyContainer.startScanner(null))
+ .hasMessageContaining("releaseId is marked non-null but is null");
+ assertFalse(policyContainer.isScannerStarted());
+
+ // shouldn't throw exception, but won't start scanner as version is null
+ var mockVersionNull = mock(ReleaseId.class);
+ when(mockVersionNull.getVersion()).thenReturn(null);
+ when(policyContainer.isValidVersion(isNull())).thenCallRealMethod();
+ assertDoesNotThrow(() -> policyContainer.startScanner(mockVersionNull));
+ assertFalse(policyContainer.isScannerStarted());
+
+ var mockVersionSnapshot = mock(ReleaseId.class);
+ when(mockVersionSnapshot.getVersion()).thenReturn(VERSION);
+ when(policyContainer.isValidVersion(VERSION)).thenCallRealMethod();
+ assertDoesNotThrow(() -> policyContainer.startScanner(mockVersionSnapshot));
+ assertFalse(policyContainer.isScannerStarted());
+ }
+
+ @Test
+ void startScanner_SnapshotVersion() {
+ var policyContainer = mock(PolicyContainer.class);
+ when(policyContainer.isScannerStarted()).thenCallRealMethod();
+ when(policyContainer.isValidVersion(VERSION + "-SNAPSHOT")).thenCallRealMethod();
+
+ var mockVersionSnapshot = mock(ReleaseId.class);
+ when(mockVersionSnapshot.getVersion()).thenReturn(VERSION + "-SNAPSHOT");
+
+ doCallRealMethod().when(policyContainer).startScanner(mockVersionSnapshot);
+
+ assertDoesNotThrow(() -> policyContainer.startScanner(mockVersionSnapshot));
+ assertTrue(policyContainer.isScannerStarted());
+ }
+
+ @Test
+ void startScanner_LatestVersion() {
+ var policyContainer = mock(PolicyContainer.class);
+ when(policyContainer.isScannerStarted()).thenCallRealMethod();
+ when(policyContainer.isValidVersion(anyString())).thenCallRealMethod();
+
+ var mockLatestVersion = mock(ReleaseId.class);
+ when(mockLatestVersion.getVersion()).thenReturn(VERSION + "LATEST");
+
+ doCallRealMethod().when(policyContainer).startScanner(mockLatestVersion);
+
+ assertDoesNotThrow(() -> policyContainer.startScanner(mockLatestVersion));
+ assertTrue(policyContainer.isScannerStarted());
+ }
+
+ @Test
+ void startScanner_ReleaseVersion() {
+ var mockKieServices = mock(KieServices.class);
+ when(mockKieServices.newKieScanner(any(KieContainer.class))).thenReturn(mock(KieScanner.class));
+
+ try (MockedStatic<KieServices.Factory> factory = Mockito.mockStatic(KieServices.Factory.class)) {
+ factory.when(KieServices.Factory::get).thenReturn(mockKieServices);
+ assertEquals(mockKieServices, KieServices.Factory.get());
+
+ var policyContainer = mock(PolicyContainer.class);
+ when(policyContainer.isScannerStarted()).thenCallRealMethod();
+ when(policyContainer.isValidVersion(VERSION + "RELEASE")).thenCallRealMethod();
+
+ var mockLatestVersion = mock(ReleaseId.class);
+ when(mockLatestVersion.getVersion()).thenReturn(VERSION + "RELEASE");
+
+ doCallRealMethod().when(policyContainer).startScanner(mockLatestVersion);
+
+ assertDoesNotThrow(() -> policyContainer.startScanner(mockLatestVersion));
+ assertTrue(policyContainer.isScannerStarted());
+
+ // try again, but should come out at checking if scanner is already started.
+ assertDoesNotThrow(() -> policyContainer.startScanner(mockLatestVersion));
+ }
+ }
+
+ @Test
+ void insert() {
+ var policyContainer = mock(PolicyContainer.class);
+ var object = new Object();
+ when(policyContainer.insert("name", object)).thenCallRealMethod();
+
+ HashMap<String, PolicySession> sessions = new HashMap<>();
+ ReflectionTestUtils.setField(policyContainer, "sessions", sessions);
+
+ assertFalse(policyContainer.insert("name", object));
+ }
+
+ @Test
+ void deactivate() {
+ assertDoesNotThrow(PolicyContainer::deactivate);
+ }
+} \ No newline at end of file
diff --git a/policy-core/src/test/java/org/onap/policy/drools/core/PolicySessionFeatureApiMock.java b/policy-core/src/test/java/org/onap/policy/drools/core/PolicySessionFeatureApiMock.java
index d8257067..f0e5b516 100644
--- a/policy-core/src/test/java/org/onap/policy/drools/core/PolicySessionFeatureApiMock.java
+++ b/policy-core/src/test/java/org/onap/policy/drools/core/PolicySessionFeatureApiMock.java
@@ -86,6 +86,7 @@ public class PolicySessionFeatureApiMock implements PolicySessionFeatureApi {
/**
* {@inheritDoc}.
*/
+ @Override
public void globalInit(String[] args, String configDir) {
addLog("globalInit");
}
@@ -93,6 +94,7 @@ public class PolicySessionFeatureApiMock implements PolicySessionFeatureApi {
/**
* {@inheritDoc}.
*/
+ @Override
public KieSession activatePolicySession(PolicyContainer policyContainer, String name, String kieBaseName) {
addLog("activatePolicySession");
return null;
@@ -101,6 +103,7 @@ public class PolicySessionFeatureApiMock implements PolicySessionFeatureApi {
/**
* {@inheritDoc}.
*/
+ @Override
public void newPolicySession(PolicySession policySession) {
addLog("newPolicySession");
}
@@ -108,6 +111,7 @@ public class PolicySessionFeatureApiMock implements PolicySessionFeatureApi {
/**
* {@inheritDoc}.
*/
+ @Override
public PolicySession.ThreadModel selectThreadModel(PolicySession session) {
addLog("selectThreadModel");
return null;
@@ -116,6 +120,7 @@ public class PolicySessionFeatureApiMock implements PolicySessionFeatureApi {
/**
* {@inheritDoc}.
*/
+ @Override
public void disposeKieSession(PolicySession policySession) {
addLog("disposeKieSession");
}
@@ -123,6 +128,7 @@ public class PolicySessionFeatureApiMock implements PolicySessionFeatureApi {
/**
* {@inheritDoc}.
*/
+ @Override
public void destroyKieSession(PolicySession policySession) {
addLog("destroyKieSession");
}
diff --git a/policy-core/src/test/java/org/onap/policy/drools/core/jmx/PdpJmxListenerTest.java b/policy-core/src/test/java/org/onap/policy/drools/core/jmx/PdpJmxListenerTest.java
new file mode 100644
index 00000000..d81dc3e9
--- /dev/null
+++ b/policy-core/src/test/java/org/onap/policy/drools/core/jmx/PdpJmxListenerTest.java
@@ -0,0 +1,66 @@
+/*-
+ * ============LICENSE_START===============================================
+ * ONAP
+ * ========================================================================
+ * 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.
+ * 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.drools.core.jmx;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.lang.management.ManagementFactory;
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.InstanceNotFoundException;
+import javax.management.MBeanRegistrationException;
+import javax.management.MBeanServer;
+import javax.management.MalformedObjectNameException;
+import javax.management.NotCompliantMBeanException;
+import javax.management.ObjectName;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.mockito.MockedStatic;
+import org.mockito.Mockito;
+
+class PdpJmxListenerTest {
+
+ @Test
+ void test() {
+ Assertions.assertDoesNotThrow(PdpJmxListener::start);
+ Assertions.assertDoesNotThrow(PdpJmxListener::stop);
+ }
+
+ @Test
+ void testExceptions()
+ throws MalformedObjectNameException, NotCompliantMBeanException, InstanceAlreadyExistsException,
+ MBeanRegistrationException, InstanceNotFoundException {
+
+ var mockMBean = Mockito.mock(MBeanServer.class);
+ Mockito.doThrow(MBeanRegistrationException.class).when(mockMBean)
+ .registerMBean(PdpJmx.getInstance(), new ObjectName("PolicyEngine:type=PdpJmx"));
+ Mockito.doThrow(MBeanRegistrationException.class).when(mockMBean)
+ .unregisterMBean(new ObjectName("PolicyEngine:type=PdpJmx"));
+
+ // trying to reach exception catch clause, but can't validate if exception was thrown
+ try (MockedStatic<ManagementFactory> factory = Mockito.mockStatic(ManagementFactory.class)) {
+ factory.when(ManagementFactory::getPlatformMBeanServer).thenReturn(mockMBean);
+ assertEquals(mockMBean, ManagementFactory.getPlatformMBeanServer());
+
+ Assertions.assertDoesNotThrow(PdpJmxListener::start);
+ Assertions.assertDoesNotThrow(PdpJmxListener::stop);
+ }
+ }
+} \ No newline at end of file
diff --git a/policy-core/src/test/java/org/onap/policy/drools/core/lock/AlwaysFailLockTest.java b/policy-core/src/test/java/org/onap/policy/drools/core/lock/AlwaysFailLockTest.java
index 51273d7d..02c3fead 100644
--- a/policy-core/src/test/java/org/onap/policy/drools/core/lock/AlwaysFailLockTest.java
+++ b/policy-core/src/test/java/org/onap/policy/drools/core/lock/AlwaysFailLockTest.java
@@ -22,6 +22,7 @@
package org.onap.policy.drools.core.lock;
import static org.assertj.core.api.Assertions.assertThatCode;
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.mock;
@@ -52,4 +53,9 @@ class AlwaysFailLockTest extends AlwaysLockBaseTest<AlwaysFailLock> {
assertFalse(lock.free());
assertTrue(lock.isUnavailable());
}
+
+ @Test
+ void testExtend() {
+ assertDoesNotThrow(() -> lock.extend(10, callback));
+ }
}
diff --git a/policy-core/src/test/java/org/onap/policy/drools/core/lock/AlwaysSuccessLockTest.java b/policy-core/src/test/java/org/onap/policy/drools/core/lock/AlwaysSuccessLockTest.java
index 80f81f92..0104d0a8 100644
--- a/policy-core/src/test/java/org/onap/policy/drools/core/lock/AlwaysSuccessLockTest.java
+++ b/policy-core/src/test/java/org/onap/policy/drools/core/lock/AlwaysSuccessLockTest.java
@@ -25,6 +25,7 @@ import static org.assertj.core.api.Assertions.assertThatCode;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertSame;
+import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.mock;
@@ -67,4 +68,28 @@ class AlwaysSuccessLockTest extends AlwaysLockBaseTest<AlwaysSuccessLock> {
assertEquals(HOLD_SEC2, lock.getHoldSec());
assertSame(callback2, lock.getCallback());
}
+
+ @Test
+ void testNullArgs() {
+ assertThrows(NullPointerException.class,
+ () -> new AlwaysSuccessLock(null, RESOURCE, OWNER_KEY, HOLD_SEC, callback));
+
+ assertThrows(NullPointerException.class,
+ () -> new AlwaysSuccessLock(LockState.WAITING, null, OWNER_KEY, HOLD_SEC, callback));
+
+ assertThrows(NullPointerException.class,
+ () -> new AlwaysSuccessLock(LockState.WAITING, RESOURCE, null, HOLD_SEC, callback));
+
+ assertThrows(NullPointerException.class,
+ () -> new AlwaysSuccessLock(LockState.WAITING, RESOURCE, OWNER_KEY, HOLD_SEC, null));
+
+ assertThrows(NullPointerException.class,
+ () -> new AlwaysSuccessLock(null, OWNER_KEY, HOLD_SEC, callback));
+
+ assertThrows(NullPointerException.class,
+ () -> new AlwaysSuccessLock(RESOURCE, null, HOLD_SEC, callback));
+
+ assertThrows(NullPointerException.class,
+ () -> new AlwaysSuccessLock(RESOURCE, OWNER_KEY, HOLD_SEC, null));
+ }
}
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/features/PolicyEngineFeatureApi.java b/policy-management/src/main/java/org/onap/policy/drools/features/PolicyEngineFeatureApi.java
index 8edf394e..27b96999 100644
--- a/policy-management/src/main/java/org/onap/policy/drools/features/PolicyEngineFeatureApi.java
+++ b/policy-management/src/main/java/org/onap/policy/drools/features/PolicyEngineFeatureApi.java
@@ -182,7 +182,7 @@ public interface PolicyEngineFeatureApi extends OrderedService {
*
* @return true if this feature intercepts and takes ownership
* of the operation preventing the invocation of
- * lower priority features. False, otherwise..
+ * lower priority features. False, otherwise.
*/
default boolean afterLock(PolicyEngine engine) {
return false;
@@ -281,7 +281,7 @@ public interface PolicyEngineFeatureApi extends OrderedService {
* operation preventing the invocation of lower priority features. Null,
* otherwise
*/
- default PolicyResourceLockManager beforeCreateLockManager(PolicyEngine engine, Properties properties) {
+ default PolicyResourceLockManager beforeCreateLockManager() {
return null;
}
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: &lt;class-containing-custom-coder&gt;,&lt;static-coder-field&gt.
*/
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);
}
diff --git a/policy-management/src/main/java/org/onap/policy/drools/server/restful/RestManager.java b/policy-management/src/main/java/org/onap/policy/drools/server/restful/RestManager.java
index 48cd8140..503ba336 100644
--- a/policy-management/src/main/java/org/onap/policy/drools/server/restful/RestManager.java
+++ b/policy-management/src/main/java/org/onap/policy/drools/server/restful/RestManager.java
@@ -21,6 +21,16 @@
package org.onap.policy.drools.server.restful;
+import static jakarta.ws.rs.core.Response.Status.BAD_REQUEST;
+import static jakarta.ws.rs.core.Response.Status.CREATED;
+import static jakarta.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR;
+import static jakarta.ws.rs.core.Response.Status.NOT_ACCEPTABLE;
+import static jakarta.ws.rs.core.Response.Status.NOT_FOUND;
+import static jakarta.ws.rs.core.Response.Status.NOT_MODIFIED;
+import static jakarta.ws.rs.core.Response.Status.OK;
+import static jakarta.ws.rs.core.Response.Status.PARTIAL_CONTENT;
+import static org.onap.policy.drools.properties.DroolsPropertyConstants.PROPERTY_CONTROLLER_NAME;
+
import ch.qos.logback.classic.LoggerContext;
import com.google.re2j.Pattern;
import jakarta.ws.rs.Consumes;
@@ -56,6 +66,7 @@ import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
+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.TopicEndpointManager;
@@ -64,15 +75,13 @@ import org.onap.policy.common.endpoints.event.comm.TopicSource;
import org.onap.policy.common.endpoints.http.server.YamlMessageBodyHandler;
import org.onap.policy.common.utils.logging.LoggerUtils;
import org.onap.policy.drools.controller.DroolsController;
-import org.onap.policy.drools.properties.DroolsPropertyConstants;
-import org.onap.policy.drools.protocol.coders.EventProtocolCoder.CoderFilters;
import org.onap.policy.drools.protocol.coders.EventProtocolCoderConstants;
import org.onap.policy.drools.protocol.coders.JsonProtocolFilter;
-import org.onap.policy.drools.protocol.coders.ProtocolCoderToolset;
import org.onap.policy.drools.protocol.configuration.ControllerConfiguration;
import org.onap.policy.drools.protocol.configuration.PdpdConfiguration;
import org.onap.policy.drools.system.PolicyController;
import org.onap.policy.drools.system.PolicyControllerConstants;
+import org.onap.policy.drools.system.PolicyDroolsPdpRuntimeException;
import org.onap.policy.drools.system.PolicyEngineConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -86,13 +95,12 @@ import org.slf4j.LoggerFactory;
@Consumes({MediaType.APPLICATION_JSON, YamlMessageBodyHandler.APPLICATION_YAML})
@ToString
public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsApi,
- PropertiesApi, EnvironmentApi, SwitchesApi, ControllersApi,
- TopicsApi, ToolsApi {
+ PropertiesApi, EnvironmentApi, SwitchesApi, ControllersApi,
+ TopicsApi, ToolsApi {
private static final String OFFER_FAILED = "{}: cannot offer to topic {} because of {}";
private static final String CANNOT_PERFORM_OPERATION = "cannot perform operation";
- private static final String NO_FILTERS = " no filters";
- private static final String NOT_FOUND = " not found: ";
+ private static final String NO_FILTERS = " has no filters";
private static final String NOT_FOUND_MSG = " not found";
private static final String DOES_NOT_EXIST_MSG = " does not exist";
private static final String NOT_ACCEPTABLE_MSG = " not acceptable";
@@ -144,19 +152,12 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
@GET
@Path("engine/swagger")
public Response swagger() {
-
- try (InputStream inputStream = getClass().getResourceAsStream(SWAGGER);
- BufferedReader reader = new BufferedReader(
- new InputStreamReader(Objects.requireNonNull(inputStream)))) {
- String contents = reader.lines()
- .collect(Collectors.joining(System.lineSeparator()));
- return Response.status(Response.Status.OK)
- .entity(contents)
- .build();
- } catch (IOException e) {
- logger.error("Cannot read swagger.json {} because of {}", e.getMessage(), e);
- return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
- .build();
+ try {
+ String contents = getSwaggerContents();
+ return Response.status(OK).entity(contents).build();
+ } catch (Exception e) {
+ logger.error("Cannot read swagger.json {} because of {}", e.getMessage(), e.toString());
+ return Response.status(INTERNAL_SERVER_ERROR).build();
}
}
@@ -170,7 +171,7 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
@GET
@Path("engine")
public Response engine() {
- return Response.status(Response.Status.OK).entity(PolicyEngineConstants.getManager()).build();
+ return Response.status(OK).entity(PolicyEngineConstants.getManager()).build();
}
/**
@@ -187,10 +188,10 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
} catch (final IllegalStateException e) {
logger.error("{}: cannot shutdown {} because of {}", this, PolicyEngineConstants.getManager(),
e.getMessage(), e);
- return Response.status(Response.Status.BAD_REQUEST).entity(PolicyEngineConstants.getManager()).build();
+ return Response.status(BAD_REQUEST).entity(PolicyEngineConstants.getManager()).build();
}
- return Response.status(Response.Status.OK).entity(PolicyEngineConstants.getManager()).build();
+ return Response.status(OK).entity(PolicyEngineConstants.getManager()).build();
}
/**
@@ -202,15 +203,14 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
@GET
@Path("engine/features")
public Response engineFeatures() {
- return Response.status(Response.Status.OK).entity(PolicyEngineConstants.getManager().getFeatures()).build();
+ return Response.status(OK).entity(PolicyEngineConstants.getManager().getFeatures()).build();
}
@Override
@GET
@Path("engine/features/inventory")
public Response engineFeaturesInventory() {
- return Response.status(Response.Status.OK).entity(PolicyEngineConstants.getManager().getFeatureProviders())
- .build();
+ return Response.status(OK).entity(PolicyEngineConstants.getManager().getFeatureProviders()).build();
}
/**
@@ -223,11 +223,11 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
@Path("engine/features/{featureName}")
public Response engineFeature(@PathParam("featureName") String featureName) {
try {
- return Response.status(Response.Status.OK)
- .entity(PolicyEngineConstants.getManager().getFeatureProvider(featureName)).build();
+ return Response.status(OK).entity(PolicyEngineConstants.getManager().getFeatureProvider(featureName))
+ .build();
} catch (final IllegalArgumentException iae) {
logger.debug("feature unavailable: {}", featureName, iae);
- return Response.status(Response.Status.NOT_FOUND).entity(new Error(iae.getMessage())).build();
+ return errorResponse(NOT_FOUND, iae.getMessage());
}
}
@@ -240,7 +240,7 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
@GET
@Path("engine/inputs")
public Response engineInputs() {
- return Response.status(Response.Status.OK).entity(INPUTS).build();
+ return Response.status(OK).entity(INPUTS).build();
}
/**
@@ -252,22 +252,16 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
@POST
@Path("engine/inputs/configuration")
public Response engineUpdate(PdpdConfiguration configuration) {
- final PolicyController controller = null;
- boolean success;
try {
- success = PolicyEngineConstants.getManager().configure(configuration);
+ if (PolicyEngineConstants.getManager().configure(configuration)) {
+ return Response.status(OK).entity(true).build();
+ }
} catch (final Exception e) {
- success = false;
logger.info("{}: cannot configure {} because of {}", this, PolicyEngineConstants.getManager(),
e.getMessage(), e);
}
- if (!success) {
- return Response.status(Response.Status.NOT_ACCEPTABLE).entity(new Error(CANNOT_PERFORM_OPERATION))
- .build();
- } else {
- return Response.status(Response.Status.OK).entity(controller).build();
- }
+ return errorResponse(NOT_ACCEPTABLE, CANNOT_PERFORM_OPERATION);
}
/**
@@ -279,7 +273,7 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
@GET
@Path("engine/properties")
public Response engineProperties() {
- return Response.status(Response.Status.OK).entity(PolicyEngineConstants.getManager().getProperties()).build();
+ return Response.status(OK).entity(PolicyEngineConstants.getManager().getProperties()).build();
}
/**
@@ -291,7 +285,7 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
@GET
@Path("engine/environment")
public Response engineEnvironment() {
- return Response.status(Response.Status.OK).entity(PolicyEngineConstants.getManager().getEnvironment()).build();
+ return Response.status(OK).entity(PolicyEngineConstants.getManager().getEnvironment()).build();
}
/**
@@ -304,8 +298,8 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
@Path("engine/environment/{envProperty}")
@Consumes(MediaType.TEXT_PLAIN)
public Response engineEnvironmentProperty(@PathParam("envProperty") String envProperty) {
- return Response.status(Response.Status.OK)
- .entity(PolicyEngineConstants.getManager().getEnvironmentProperty(envProperty)).build();
+ return Response.status(OK).entity(PolicyEngineConstants.getManager().getEnvironmentProperty(envProperty))
+ .build();
}
/**
@@ -320,7 +314,7 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
@Produces(MediaType.TEXT_PLAIN)
public Response engineEnvironmentAdd(@PathParam("envProperty") String envProperty, String envValue) {
final String previousValue = PolicyEngineConstants.getManager().setEnvironmentProperty(envProperty, envValue);
- return Response.status(Response.Status.OK).entity(previousValue).build();
+ return Response.status(OK).entity(previousValue).build();
}
/**
@@ -332,7 +326,7 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
@GET
@Path("engine/switches")
public Response engineSwitches() {
- return Response.status(Response.Status.OK).entity(SWITCHES).build();
+ return Response.status(OK).entity(SWITCHES).build();
}
/**
@@ -344,21 +338,15 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
@PUT
@Path("engine/switches/activation")
public Response engineActivation() {
- var success = true;
try {
PolicyEngineConstants.getManager().activate();
+ return Response.status(OK).entity(PolicyEngineConstants.getManager()).build();
} catch (final Exception e) {
- success = false;
logger.info("{}: cannot activate {} because of {}", this, PolicyEngineConstants.getManager(),
e.getMessage(), e);
}
- if (!success) {
- return Response.status(Response.Status.NOT_ACCEPTABLE).entity(new Error(CANNOT_PERFORM_OPERATION))
- .build();
- } else {
- return Response.status(Response.Status.OK).entity(PolicyEngineConstants.getManager()).build();
- }
+ return errorResponse(NOT_ACCEPTABLE, CANNOT_PERFORM_OPERATION);
}
/**
@@ -370,21 +358,15 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
@DELETE
@Path("engine/switches/activation")
public Response engineDeactivation() {
- var success = true;
try {
PolicyEngineConstants.getManager().deactivate();
+ return Response.status(OK).entity(PolicyEngineConstants.getManager()).build();
} catch (final Exception e) {
- success = false;
logger.info("{}: cannot deactivate {} because of {}", this, PolicyEngineConstants.getManager(),
e.getMessage(), e);
}
- if (!success) {
- return Response.status(Response.Status.NOT_ACCEPTABLE).entity(new Error(CANNOT_PERFORM_OPERATION))
- .build();
- } else {
- return Response.status(Response.Status.OK).entity(PolicyEngineConstants.getManager()).build();
- }
+ return errorResponse(NOT_ACCEPTABLE, CANNOT_PERFORM_OPERATION);
}
/**
@@ -396,11 +378,10 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
@PUT
@Path("engine/switches/lock")
public Response engineLock() {
- final boolean success = PolicyEngineConstants.getManager().lock();
- if (success) {
- return Response.status(Status.OK).entity(PolicyEngineConstants.getManager()).build();
+ if (PolicyEngineConstants.getManager().lock()) {
+ return Response.status(OK).entity(PolicyEngineConstants.getManager()).build();
} else {
- return Response.status(Status.NOT_ACCEPTABLE).entity(new Error(CANNOT_PERFORM_OPERATION)).build();
+ return errorResponse(NOT_ACCEPTABLE, CANNOT_PERFORM_OPERATION);
}
}
@@ -413,11 +394,10 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
@DELETE
@Path("engine/switches/lock")
public Response engineUnlock() {
- final boolean success = PolicyEngineConstants.getManager().unlock();
- if (success) {
- return Response.status(Status.OK).entity(PolicyEngineConstants.getManager()).build();
+ if (PolicyEngineConstants.getManager().unlock()) {
+ return Response.status(OK).entity(PolicyEngineConstants.getManager()).build();
} else {
- return Response.status(Status.NOT_ACCEPTABLE).entity(new Error(CANNOT_PERFORM_OPERATION)).build();
+ return errorResponse(NOT_ACCEPTABLE, CANNOT_PERFORM_OPERATION);
}
}
@@ -430,8 +410,7 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
@GET
@Path("engine/controllers")
public Response controllers() {
- return Response.status(Response.Status.OK).entity(PolicyEngineConstants.getManager().getPolicyControllerIds())
- .build();
+ return Response.status(OK).entity(PolicyEngineConstants.getManager().getPolicyControllerIds()).build();
}
/**
@@ -443,8 +422,7 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
@GET
@Path("engine/controllers/inventory")
public Response controllerInventory() {
- return Response.status(Response.Status.OK).entity(PolicyEngineConstants.getManager().getPolicyControllers())
- .build();
+ return Response.status(OK).entity(PolicyEngineConstants.getManager().getPolicyControllers()).build();
}
/**
@@ -457,54 +435,48 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
@Path("engine/controllers")
public Response controllerAdd(Properties config) {
if (config == null) {
- return Response.status(Response.Status.BAD_REQUEST).entity(new Error("A configuration must be provided"))
- .build();
+ return errorResponse(BAD_REQUEST, "A configuration must be provided");
}
- final String controllerName = config.getProperty(DroolsPropertyConstants.PROPERTY_CONTROLLER_NAME);
+ var controllerName = config.getProperty(PROPERTY_CONTROLLER_NAME);
if (controllerName == null || controllerName.isEmpty()) {
- return Response.status(Response.Status.BAD_REQUEST)
- .entity(new Error(
- "Configuration must have an entry for " + DroolsPropertyConstants.PROPERTY_CONTROLLER_NAME))
- .build();
+ return errorResponse(BAD_REQUEST, "Configuration must have an entry for "
+ + PROPERTY_CONTROLLER_NAME);
}
PolicyController controller;
try {
controller = PolicyControllerConstants.getFactory().get(controllerName);
if (controller != null) {
- return Response.status(Response.Status.NOT_MODIFIED).entity(controller).build();
+ return Response.status(NOT_MODIFIED).entity(controller).build();
}
} catch (final IllegalArgumentException e) {
logger.trace("OK ", e);
// This is OK
} catch (final IllegalStateException e) {
logger.info(FETCH_POLICY_FAILED, this, e.getMessage(), e);
- return Response.status(Response.Status.NOT_ACCEPTABLE).entity(new Error(controllerName + NOT_FOUND_MSG))
- .build();
+ return errorResponse(NOT_ACCEPTABLE, controllerName + NOT_FOUND_MSG);
}
try {
controller = PolicyEngineConstants.getManager().createPolicyController(
- config.getProperty(DroolsPropertyConstants.PROPERTY_CONTROLLER_NAME), config);
+ config.getProperty(PROPERTY_CONTROLLER_NAME), config);
} catch (IllegalArgumentException | IllegalStateException e) {
logger.warn("{}: cannot create policy-controller because of {}", this, e.getMessage(), e);
- return Response.status(Response.Status.BAD_REQUEST).entity(new Error(e.getMessage())).build();
+ return errorResponse(BAD_REQUEST, e.getMessage());
}
try {
- final boolean success = controller.start();
- if (!success) {
+ if (!controller.start()) {
logger.info("{}: cannot start {}", this, controller);
- return Response.status(Response.Status.PARTIAL_CONTENT)
- .entity(new Error(controllerName + " can't be started")).build();
+ return errorResponse(PARTIAL_CONTENT, controllerName + " can't be started");
}
} catch (final IllegalStateException e) {
logger.info("{}: cannot start {} because of {}", this, controller, e.getMessage(), e);
- return Response.status(Response.Status.PARTIAL_CONTENT).entity(controller).build();
+ return Response.status(PARTIAL_CONTENT).entity(controller).build();
}
- return Response.status(Response.Status.CREATED).entity(controller).build();
+ return Response.status(CREATED).entity(controller).build();
}
/**
@@ -516,7 +488,7 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
@GET
@Path("engine/controllers/features")
public Response controllerFeatures() {
- return Response.status(Response.Status.OK).entity(PolicyEngineConstants.getManager().getFeatures()).build();
+ return Response.status(OK).entity(PolicyEngineConstants.getManager().getFeatures()).build();
}
/**
@@ -528,8 +500,7 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
@GET
@Path("engine/controllers/features/inventory")
public Response controllerFeaturesInventory() {
- return Response.status(Response.Status.OK)
- .entity(PolicyControllerConstants.getFactory().getFeatureProviders()).build();
+ return Response.status(OK).entity(PolicyControllerConstants.getFactory().getFeatureProviders()).build();
}
/**
@@ -542,12 +513,11 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
@Path("engine/controllers/features/{featureName}")
public Response controllerFeature(@PathParam("featureName") String featureName) {
try {
- return Response.status(Response.Status.OK)
- .entity(PolicyControllerConstants.getFactory().getFeatureProvider(featureName))
+ return Response.status(OK).entity(PolicyControllerConstants.getFactory().getFeatureProvider(featureName))
.build();
} catch (final IllegalArgumentException iae) {
logger.debug("{}: cannot feature {} because of {}", this, featureName, iae.getMessage(), iae);
- return Response.status(Response.Status.NOT_FOUND).entity(new Error(iae.getMessage())).build();
+ return errorResponse(NOT_FOUND, iae.getMessage());
}
}
@@ -562,8 +532,7 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
public Response controller(@PathParam("controller") String controllerName) {
return catchArgStateGenericEx(
- () -> Response.status(Response.Status.OK)
- .entity(PolicyControllerConstants.getFactory().get(controllerName)).build(),
+ () -> Response.status(OK).entity(PolicyControllerConstants.getFactory().get(controllerName)).build(),
e -> {
logger.debug(FETCH_POLICY_BY_NAME_FAILED, this, controllerName, e.getMessage(), e);
return (controllerName);
@@ -584,28 +553,25 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
try {
controller = PolicyControllerConstants.getFactory().get(controllerName);
if (controller == null) {
- return Response.status(Response.Status.BAD_REQUEST)
- .entity(new Error(controllerName + DOES_NOT_EXIST_MSG)).build();
+ return errorResponse(BAD_REQUEST, controllerName + DOES_NOT_EXIST_MSG);
}
} catch (final IllegalArgumentException e) {
logger.debug(FETCH_POLICY_BY_NAME_FAILED, this, controllerName, e.getMessage(), e);
- return Response.status(Response.Status.BAD_REQUEST)
- .entity(new Error(controllerName + NOT_FOUND + e.getMessage())).build();
+ return errorResponse(BAD_REQUEST, controllerName + NOT_FOUND_MSG + ": " + e.getMessage());
} catch (final IllegalStateException e) {
logger.debug(FETCH_POLICY_BY_NAME_FAILED, this, controllerName, e.getMessage(), e);
- return Response.status(Response.Status.NOT_ACCEPTABLE)
- .entity(new Error(controllerName + NOT_ACCEPTABLE_MSG)).build();
+ return errorResponse(NOT_ACCEPTABLE, controllerName + NOT_ACCEPTABLE_MSG);
}
try {
PolicyEngineConstants.getManager().removePolicyController(controllerName);
} catch (IllegalArgumentException | IllegalStateException e) {
- logger.debug("{}: cannot remove policy-controller {} because of {}", this, controllerName, e.getMessage(),
- e);
- return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(new Error(e.getMessage())).build();
+ logger.debug("{}: cannot remove policy-controller {} because of {}",
+ this, controllerName, e.getMessage(), e);
+ return errorResponse(INTERNAL_SERVER_ERROR, e.getMessage());
}
- return Response.status(Response.Status.OK).entity(controller).build();
+ return Response.status(OK).entity(controller).build();
}
/**
@@ -620,8 +586,8 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
public Response controllerProperties(@PathParam("controller") String controllerName) {
return catchArgStateGenericEx(() -> {
- final PolicyController controller = PolicyControllerConstants.getFactory().get(controllerName);
- return Response.status(Response.Status.OK).entity(controller.getProperties()).build();
+ var controller = PolicyControllerConstants.getFactory().get(controllerName);
+ return Response.status(OK).entity(controller.getProperties()).build();
}, e -> {
logger.debug(FETCH_POLICY_BY_NAME_FAILED, this, controllerName, e.getMessage(), e);
@@ -638,7 +604,7 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
@GET
@Path("engine/controllers/{controller}/inputs")
public Response controllerInputs(@PathParam("controller") String controllerName) {
- return Response.status(Response.Status.OK).entity(INPUTS).build();
+ return Response.status(OK).entity(INPUTS).build();
}
/**
@@ -650,27 +616,25 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
@POST
@Path("engine/controllers/{controller}/inputs/configuration")
public Response controllerUpdate(ControllerConfiguration controllerConfiguration,
- @PathParam("controller") String controllerName) {
+ @PathParam("controller") String controllerName) {
- if (controllerName == null || controllerName.isEmpty() || controllerConfiguration == null
+ if (StringUtils.isBlank(controllerName) || controllerConfiguration == null
|| !controllerName.equals(controllerConfiguration.getName())) {
- return Response.status(Response.Status.BAD_REQUEST)
+ return Response.status(BAD_REQUEST)
.entity("A valid or matching controller names must be provided").build();
}
return catchArgStateGenericEx(() -> {
- var controller =
- PolicyEngineConstants.getManager().updatePolicyController(controllerConfiguration);
+ var controller = PolicyEngineConstants.getManager().updatePolicyController(controllerConfiguration);
if (controller == null) {
- return Response.status(Response.Status.BAD_REQUEST)
- .entity(new Error(controllerName + DOES_NOT_EXIST_MSG)).build();
+ return errorResponse(BAD_REQUEST, controllerName + DOES_NOT_EXIST_MSG);
}
- return Response.status(Response.Status.OK).entity(controller).build();
+ return Response.status(OK).entity(controller).build();
}, e -> {
- logger.info("{}: cannot update policy-controller {} because of {}", this, controllerName,
- e.getMessage(), e);
+ logger.info("{}: cannot update policy-controller {} because of {}",
+ this, controllerName, e.getMessage(), e);
return (controllerName);
});
}
@@ -684,7 +648,7 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
@GET
@Path("engine/controllers/{controller}/switches")
public Response controllerSwitches(@PathParam("controller") String controllerName) {
- return Response.status(Response.Status.OK).entity(SWITCHES).build();
+ return Response.status(OK).entity(SWITCHES).build();
}
/**
@@ -697,12 +661,10 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
@Path("engine/controllers/{controller}/switches/lock")
public Response controllerLock(@PathParam("controller") String controllerName) {
var policyController = PolicyControllerConstants.getFactory().get(controllerName);
- final boolean success = policyController.lock();
- if (success) {
- return Response.status(Status.OK).entity(policyController).build();
+ if (policyController.lock()) {
+ return Response.status(OK).entity(policyController).build();
} else {
- return Response.status(Status.NOT_ACCEPTABLE)
- .entity(new Error("Controller " + controllerName + " cannot be locked")).build();
+ return errorResponse(NOT_ACCEPTABLE, "Controller " + controllerName + " cannot be locked");
}
}
@@ -718,10 +680,9 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
var policyController = PolicyControllerConstants.getFactory().get(controllerName);
final boolean success = policyController.unlock();
if (success) {
- return Response.status(Status.OK).entity(policyController).build();
+ return Response.status(OK).entity(policyController).build();
} else {
- return Response.status(Status.NOT_ACCEPTABLE)
- .entity(new Error("Controller " + controllerName + " cannot be unlocked")).build();
+ return errorResponse(NOT_ACCEPTABLE, "Controller " + controllerName + " cannot be unlocked");
}
}
@@ -737,7 +698,7 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
return catchArgStateGenericEx(() -> {
var drools = this.getDroolsController(controllerName);
- return Response.status(Response.Status.OK).entity(drools).build();
+ return Response.status(OK).entity(drools).build();
}, e -> {
logger.debug(FETCH_DROOLS_FAILED, this, controllerName, e.getMessage(), e);
@@ -778,7 +739,7 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
@GET
@Path("engine/controllers/{controller}/drools/facts/{session}")
public Response droolsFacts1(@PathParam("controller") String controllerName,
- @PathParam("session") String sessionName) {
+ @PathParam("session") String sessionName) {
return catchArgStateGenericEx(() -> {
var drools = this.getDroolsController(controllerName);
@@ -917,8 +878,8 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
}, e -> {
logger.debug(FETCH_DROOLS_BY_PARAMS_FAILED,
- this, controllerName, sessionName, queryName, queriedEntity, e.getMessage(), e);
- return (controllerName + ":" + sessionName + ":" + queryName + queriedEntity);
+ this, controllerName, sessionName, queryName, queriedEntity, e.getMessage(), e.toString());
+ return (controllerName + ":" + sessionName + ":" + queryName + ":" + queriedEntity);
});
}
@@ -931,7 +892,7 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
@POST
@Path("engine/controllers/tools/coders/decoders/filters/rule")
public Response rules(String expression) {
- return Response.status(Status.OK).entity(new JsonProtocolFilter(expression)).build();
+ return Response.status(OK).entity(new JsonProtocolFilter(expression)).build();
}
/**
@@ -949,8 +910,7 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
return EventProtocolCoderConstants.getManager().getDecoders(drools.getGroupId(), drools.getArtifactId());
}, e -> {
- logger.debug(FETCH_DECODERS_BY_POLICY_FAILED, this, controllerName,
- e.getMessage(), e);
+ logger.debug(FETCH_DECODERS_BY_POLICY_FAILED, this, controllerName, e.getMessage(), e);
return (controllerName);
});
}
@@ -1013,11 +973,10 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
return catchArgStateGenericEx(() -> {
var drools = this.getDroolsController(controllerName);
- final ProtocolCoderToolset decoder = EventProtocolCoderConstants.getManager()
+ var decoder = EventProtocolCoderConstants.getManager()
.getDecoders(drools.getGroupId(), drools.getArtifactId(), topic);
if (decoder == null) {
- return Response.status(Response.Status.BAD_REQUEST).entity(new Error(topic + DOES_NOT_EXIST_MSG))
- .build();
+ return errorResponse(BAD_REQUEST, topic + DOES_NOT_EXIST_MSG);
} else {
return decoder.getCoders();
}
@@ -1043,19 +1002,17 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
return catchArgStateGenericEx(() -> {
var drools = this.getDroolsController(controllerName);
- final ProtocolCoderToolset decoder = EventProtocolCoderConstants.getManager()
+ var decoder = EventProtocolCoderConstants.getManager()
.getDecoders(drools.getGroupId(), drools.getArtifactId(), topic);
- final CoderFilters filters = decoder.getCoder(factClass);
+ var filters = decoder.getCoder(factClass);
if (filters == null) {
- return Response.status(Response.Status.BAD_REQUEST)
- .entity(new Error(topic + ":" + factClass + DOES_NOT_EXIST_MSG)).build();
+ return errorResponse(BAD_REQUEST, topic + ":" + factClass + DOES_NOT_EXIST_MSG);
} else {
return filters;
}
}, e -> {
- logger.debug(FETCH_DECODER_BY_TYPE_FAILED, this,
- controllerName, topic, factClass, e.getMessage(), e);
+ logger.debug(FETCH_DECODER_BY_TYPE_FAILED, this, controllerName, topic, factClass, e.getMessage(), e);
return (controllerName + ":" + topic + ":" + factClass);
});
}
@@ -1069,24 +1026,22 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
@PUT
@Path("engine/controllers/{controller}/decoders/{topic}/filters/{factType}")
public Response decoderFilter(
- JsonProtocolFilter configFilters,
- @PathParam("controller") String controllerName,
- @PathParam("topic") String topic,
- @PathParam("factType") String factClass) {
+ JsonProtocolFilter configFilters,
+ @PathParam("controller") String controllerName,
+ @PathParam("topic") String topic,
+ @PathParam("factType") String factClass) {
if (configFilters == null) {
- return Response.status(Response.Status.BAD_REQUEST).entity(new Error("Configuration Filters not provided"))
- .build();
+ return errorResponse(BAD_REQUEST, "Configuration Filters not provided");
}
return catchArgStateGenericEx(() -> {
var drools = this.getDroolsController(controllerName);
- final ProtocolCoderToolset decoder = EventProtocolCoderConstants.getManager()
+ var decoder = EventProtocolCoderConstants.getManager()
.getDecoders(drools.getGroupId(), drools.getArtifactId(), topic);
- final CoderFilters filters = decoder.getCoder(factClass);
+ var filters = decoder.getCoder(factClass);
if (filters == null) {
- return Response.status(Response.Status.BAD_REQUEST)
- .entity(new Error(topic + ":" + factClass + DOES_NOT_EXIST_MSG)).build();
+ return errorResponse(BAD_REQUEST, topic + ":" + factClass + DOES_NOT_EXIST_MSG);
}
filters.setFilter(configFilters);
return filters;
@@ -1112,24 +1067,14 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
@PathParam("factType") String factClass) {
return catchArgStateGenericEx(() -> {
- var drools = this.getDroolsController(controllerName);
- final ProtocolCoderToolset decoder = EventProtocolCoderConstants.getManager()
- .getDecoders(drools.getGroupId(), drools.getArtifactId(), topic);
-
- final CoderFilters filters = decoder.getCoder(factClass);
- if (filters == null) {
- return Response.status(Response.Status.BAD_REQUEST)
- .entity(new Error(controllerName + ":" + topic + ":" + factClass + DOES_NOT_EXIST_MSG)).build();
- }
+ var result = this.checkControllerDecoderAndFilter(controllerName, topic, factClass);
- final JsonProtocolFilter filter = filters.getFilter();
- if (filter == null) {
- return Response.status(Response.Status.BAD_REQUEST)
- .entity(new Error(controllerName + ":" + topic + ":" + factClass + NO_FILTERS)).build();
+ if (result instanceof Response) {
+ return result;
+ } else {
+ var filter = (JsonProtocolFilter) result;
+ return filter.getRule();
}
-
- return filter.getRule();
-
}, e -> {
logger.debug(FETCH_DECODER_BY_TYPE_FAILED, this,
controllerName, topic, factClass, e.getMessage(), e);
@@ -1151,25 +1096,17 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
@PathParam("factType") String factClass) {
return catchArgStateGenericEx(() -> {
- var drools = this.getDroolsController(controllerName);
- final ProtocolCoderToolset decoder = EventProtocolCoderConstants.getManager()
- .getDecoders(drools.getGroupId(), drools.getArtifactId(), topic);
+ var result = this.checkControllerDecoderAndFilter(controllerName, topic, factClass);
- final CoderFilters filters = decoder.getCoder(factClass);
- if (filters == null) {
- return Response.status(Response.Status.BAD_REQUEST)
- .entity(new Error(controllerName + ":" + topic + ":" + factClass + DOES_NOT_EXIST_MSG)).build();
- }
+ if (result instanceof Response) {
+ return result;
+ } else {
+ var filter = (JsonProtocolFilter) result;
- final JsonProtocolFilter filter = filters.getFilter();
- if (filter == null) {
- return Response.status(Response.Status.BAD_REQUEST)
- .entity(new Error(controllerName + ":" + topic + ":" + factClass + NO_FILTERS)).build();
+ filter.setRule(null);
+ return filter.getRule();
}
- filter.setRule(null);
- return filter.getRule();
-
}, e -> {
logger.debug(FETCH_DECODER_BY_TYPE_FAILED,
this, controllerName, topic, factClass, e.getMessage(), e);
@@ -1193,38 +1130,12 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
return catchArgStateGenericEx(() -> decoderFilterRule2(controllerName, topic, factClass, rule), e -> {
logger.debug("{}: cannot access decoder filter rules for policy-controller {} "
- + "topic {} type {} because of {}",
+ + "topic {} type {} because of {}",
this, controllerName, topic, factClass, e.getMessage(), e);
return (controllerName + ":" + topic + ":" + factClass);
});
}
- private Object decoderFilterRule2(String controllerName, String topic, String factClass, String rule) {
- var drools = this.getDroolsController(controllerName);
- final ProtocolCoderToolset decoder = EventProtocolCoderConstants.getManager()
- .getDecoders(drools.getGroupId(), drools.getArtifactId(), topic);
-
- final CoderFilters filters = decoder.getCoder(factClass);
- if (filters == null) {
- return Response.status(Response.Status.BAD_REQUEST)
- .entity(new Error(controllerName + ":" + topic + ":" + factClass + DOES_NOT_EXIST_MSG)).build();
- }
-
- final JsonProtocolFilter filter = filters.getFilter();
- if (filter == null) {
- return Response.status(Response.Status.BAD_REQUEST)
- .entity(new Error(controllerName + ":" + topic + ":" + factClass + NO_FILTERS)).build();
- }
-
- if (rule == null || rule.isEmpty()) {
- return Response.status(Response.Status.BAD_REQUEST).entity(new Error(controllerName + ":" + topic + ":"
- + factClass + " no filter rule provided")).build();
- }
-
- filter.setRule(rule);
- return filter.getRule();
- }
-
/**
* POST.
*
@@ -1239,30 +1150,15 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
@PathParam("topic") String topic,
String json) {
- if (!checkValidNameInput(controllerName)) {
- return Response.status(Response.Status.NOT_ACCEPTABLE)
- .entity(new Error("controllerName contains whitespaces " + NOT_ACCEPTABLE_MSG)).build();
+ if (StringUtils.isBlank(controllerName)) {
+ return errorResponse(NOT_ACCEPTABLE, "controllerName contains whitespaces " + NOT_ACCEPTABLE_MSG);
}
- if (!checkValidNameInput(topic)) {
- return Response.status(Response.Status.NOT_ACCEPTABLE)
- .entity(new Error("topic contains whitespaces " + NOT_ACCEPTABLE_MSG)).build();
+ if (StringUtils.isBlank(topic)) {
+ return errorResponse(NOT_ACCEPTABLE, "topic contains whitespaces " + NOT_ACCEPTABLE_MSG);
}
- PolicyController policyController;
- try {
- policyController = PolicyControllerConstants.getFactory().get(controllerName);
- } catch (final IllegalArgumentException e) {
- logger.debug(FETCH_DECODERS_BY_TOPIC_FAILED, this,
- controllerName, topic, e.getMessage(), e);
- return Response.status(Response.Status.NOT_FOUND)
- .entity(new Error(controllerName + ":" + topic + ":" + NOT_FOUND_MSG)).build();
- } catch (final IllegalStateException e) {
- logger.debug(FETCH_DECODERS_BY_TOPIC_FAILED, this,
- controllerName, topic, e.getMessage(), e);
- return Response.status(Response.Status.NOT_ACCEPTABLE)
- .entity(new Error(controllerName + ":" + topic + ":" + NOT_ACCEPTABLE_MSG)).build();
- }
+ var drools = getDroolsController(controllerName);
var result = new CodingResult();
result.setDecoding(false);
@@ -1271,25 +1167,24 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
Object event;
try {
- event = EventProtocolCoderConstants.getManager().decode(policyController.getDrools().getGroupId(),
- policyController.getDrools().getArtifactId(), topic, json);
+ event = EventProtocolCoderConstants.getManager()
+ .decode(drools.getGroupId(), drools.getArtifactId(), topic, json);
result.setDecoding(true);
} catch (final Exception e) {
- logger.debug(FETCH_POLICY_BY_TOPIC_FAILED, this, controllerName, topic,
- e.getMessage(), e);
- return Response.status(Response.Status.BAD_REQUEST).entity(new Error(e.getMessage())).build();
+ logger.debug(FETCH_POLICY_BY_TOPIC_FAILED, this, controllerName, topic, e.getMessage(), e);
+ return errorResponse(BAD_REQUEST, e.getMessage());
}
try {
result.setJsonEncoding(EventProtocolCoderConstants.getManager().encode(topic, event));
result.setEncoding(true);
} catch (final Exception e) {
- // continue so to propagate decoding results ..
- logger.debug("{}: cannot encode for policy-controller {} topic {} because of {}", this, controllerName,
- topic, e.getMessage(), e);
+ // continue so to propagate decoding results ...
+ logger.debug("{}: cannot encode for policy-controller {} topic {} because of {}",
+ this, controllerName, topic, e.getMessage(), e);
}
- return Response.status(Response.Status.OK).entity(result).build();
+ return Response.status(OK).entity(result).build();
}
/**
@@ -1303,14 +1198,12 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
public Response encoderFilters(@PathParam("controller") String controllerName) {
return catchArgStateGenericEx(() -> {
- final PolicyController controller = PolicyControllerConstants.getFactory().get(controllerName);
- var drools = controller.getDrools();
+ var drools = getDroolsController(controllerName);
return EventProtocolCoderConstants.getManager()
.getEncoderFilters(drools.getGroupId(), drools.getArtifactId());
}, e -> {
- logger.debug(FETCH_ENCODER_BY_FILTER_FAILED, this, controllerName,
- e.getMessage(), e);
+ logger.debug(FETCH_ENCODER_BY_FILTER_FAILED, this, controllerName, e.getMessage(), e);
return (controllerName);
});
}
@@ -1319,14 +1212,14 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
@GET
@Path("engine/topics")
public Response topics() {
- return Response.status(Response.Status.OK).entity(TopicEndpointManager.getManager()).build();
+ return Response.status(OK).entity(TopicEndpointManager.getManager()).build();
}
@Override
@GET
@Path("engine/topics/switches")
public Response topicSwitches() {
- return Response.status(Response.Status.OK).entity(SWITCHES).build();
+ return Response.status(OK).entity(SWITCHES).build();
}
/**
@@ -1338,11 +1231,10 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
@PUT
@Path("engine/topics/switches/lock")
public Response topicsLock() {
- final boolean success = TopicEndpointManager.getManager().lock();
- if (success) {
- return Response.status(Status.OK).entity(TopicEndpointManager.getManager()).build();
+ if (TopicEndpointManager.getManager().lock()) {
+ return Response.status(OK).entity(TopicEndpointManager.getManager()).build();
} else {
- return Response.status(Status.NOT_ACCEPTABLE).entity(new Error(CANNOT_PERFORM_OPERATION)).build();
+ return errorResponse(NOT_ACCEPTABLE, CANNOT_PERFORM_OPERATION);
}
}
@@ -1355,11 +1247,10 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
@DELETE
@Path("engine/topics/switches/lock")
public Response topicsUnlock() {
- final boolean success = TopicEndpointManager.getManager().unlock();
- if (success) {
- return Response.status(Status.OK).entity(TopicEndpointManager.getManager()).build();
+ if (TopicEndpointManager.getManager().unlock()) {
+ return Response.status(OK).entity(TopicEndpointManager.getManager()).build();
} else {
- return Response.status(Status.NOT_ACCEPTABLE).entity(new Error(CANNOT_PERFORM_OPERATION)).build();
+ return errorResponse(NOT_ACCEPTABLE, CANNOT_PERFORM_OPERATION);
}
}
@@ -1372,7 +1263,7 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
@GET
@Path("engine/topics/sources")
public Response sources() {
- return Response.status(Response.Status.OK).entity(TopicEndpointManager.getManager().getTopicSources()).build();
+ return Response.status(OK).entity(TopicEndpointManager.getManager().getTopicSources()).build();
}
/**
@@ -1384,7 +1275,7 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
@GET
@Path("engine/topics/sinks")
public Response sinks() {
- return Response.status(Response.Status.OK).entity(TopicEndpointManager.getManager().getTopicSinks()).build();
+ return Response.status(OK).entity(TopicEndpointManager.getManager().getTopicSinks()).build();
}
/**
@@ -1395,15 +1286,13 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
@Path("engine/topics/sources/{comm: kafka|noop}")
public Response commSources(
@PathParam("comm") String comm) {
- if (!checkValidNameInput(comm)) {
- return Response
- .status(Response.Status.NOT_ACCEPTABLE)
- .entity(new Error("source communication mechanism contains whitespaces " + NOT_ACCEPTABLE_MSG))
- .build();
+ if (StringUtils.isBlank(comm)) {
+ return errorResponse(NOT_ACCEPTABLE,
+ "source communication mechanism contains whitespaces " + NOT_ACCEPTABLE_MSG);
}
List<TopicSource> sources = new ArrayList<>();
- var status = Status.OK;
+ var status = OK;
switch (CommInfrastructure.valueOf(comm.toUpperCase())) {
case NOOP:
sources.addAll(TopicEndpointManager.getManager().getNoopTopicSources());
@@ -1412,8 +1301,8 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
sources.addAll(TopicEndpointManager.getManager().getKafkaTopicSources());
break;
default:
- status = Status.BAD_REQUEST;
- logger.debug("Invalid communication mechanism");
+ status = BAD_REQUEST;
+ logger.debug("{} is invalid communication mechanism", comm);
break;
}
return Response.status(status).entity(sources).build();
@@ -1427,15 +1316,13 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
@Path("engine/topics/sinks/{comm: kafka|noop}")
public Response commSinks(
@PathParam("comm") String comm) {
- if (!checkValidNameInput(comm)) {
- return Response
- .status(Response.Status.NOT_ACCEPTABLE)
- .entity(new Error("sink communication mechanism contains whitespaces " + NOT_ACCEPTABLE_MSG))
- .build();
+ if (StringUtils.isBlank(comm)) {
+ return errorResponse(NOT_ACCEPTABLE,
+ "sink communication mechanism contains whitespaces " + NOT_ACCEPTABLE_MSG);
}
List<TopicSink> sinks = new ArrayList<>();
- var status = Status.OK;
+ var status = OK;
switch (CommInfrastructure.valueOf(comm.toUpperCase())) {
case NOOP:
sinks.addAll(TopicEndpointManager.getManager().getNoopTopicSinks());
@@ -1444,8 +1331,8 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
sinks.addAll(TopicEndpointManager.getManager().getKafkaTopicSinks());
break;
default:
- status = Status.BAD_REQUEST;
- logger.debug("Invalid communication mechanism");
+ status = BAD_REQUEST;
+ logger.debug("{} is invalid communication mechanism", comm);
break;
}
return Response.status(status).entity(sinks).build();
@@ -1460,11 +1347,9 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
public Response sourceTopic(
@PathParam("comm") String comm,
@PathParam("topic") String topic) {
- return Response
- .status(Response.Status.OK)
- .entity(TopicEndpointManager.getManager()
- .getTopicSource(CommInfrastructure.valueOf(comm.toUpperCase()), topic))
- .build();
+ var source = TopicEndpointManager.getManager()
+ .getTopicSource(CommInfrastructure.valueOf(comm.toUpperCase()), topic);
+ return Response.status(OK).entity(source).build();
}
/**
@@ -1476,11 +1361,9 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
public Response sinkTopic(
@PathParam("comm") String comm,
@PathParam("topic") String topic) {
- return Response
- .status(Response.Status.OK)
- .entity(TopicEndpointManager.getManager()
- .getTopicSink(CommInfrastructure.valueOf(comm.toUpperCase()), topic))
- .build();
+ var sink = TopicEndpointManager.getManager()
+ .getTopicSink(CommInfrastructure.valueOf(comm.toUpperCase()), topic);
+ return Response.status(OK).entity(sink).build();
}
/**
@@ -1492,11 +1375,9 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
public Response sourceEvents(
@PathParam("comm") String comm,
@PathParam("topic") String topic) {
- return Response.status(Status.OK)
- .entity(Arrays.asList(TopicEndpointManager.getManager()
- .getTopicSource(CommInfrastructure.valueOf(comm.toUpperCase()), topic)
- .getRecentEvents()))
- .build();
+ var source = TopicEndpointManager.getManager()
+ .getTopicSource(CommInfrastructure.valueOf(comm.toUpperCase()), topic);
+ return Response.status(OK).entity(Arrays.asList(source.getRecentEvents())).build();
}
/**
@@ -1508,11 +1389,9 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
public Response sinkEvents(
@PathParam("comm") String comm,
@PathParam("topic") String topic) {
- return Response.status(Status.OK)
- .entity(Arrays.asList(TopicEndpointManager.getManager()
- .getTopicSink(CommInfrastructure.valueOf(comm.toUpperCase()), topic)
- .getRecentEvents()))
- .build();
+ var sink = TopicEndpointManager.getManager()
+ .getTopicSink(CommInfrastructure.valueOf(comm.toUpperCase()), topic);
+ return Response.status(OK).entity(Arrays.asList(sink.getRecentEvents())).build();
}
/**
@@ -1524,7 +1403,7 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
public Response commSourceTopicSwitches(
@PathParam("comm") String comm,
@PathParam("topic") String topic) {
- return Response.status(Response.Status.OK).entity(SWITCHES).build();
+ return Response.status(OK).entity(SWITCHES).build();
}
/**
@@ -1536,7 +1415,7 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
public Response commSinkTopicSwitches(
@PathParam("comm") String comm,
@PathParam("topic") String topic) {
- return Response.status(Response.Status.OK).entity(SWITCHES).build();
+ return Response.status(OK).entity(SWITCHES).build();
}
/**
@@ -1548,13 +1427,13 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
public Response commSourceTopicLock(
@PathParam("comm") String comm,
@PathParam("topic") String topic) {
- var source =
- TopicEndpointManager.getManager().getTopicSource(CommInfrastructure.valueOf(comm.toUpperCase()), topic);
+ var source = TopicEndpointManager.getManager()
+ .getTopicSource(CommInfrastructure.valueOf(comm.toUpperCase()), topic);
return getResponse(topic, source.lock(), source);
}
/**
- * DELETEs the lock on a topic.
+ * Deletes the lock on a topic.
*/
@Override
@DELETE
@@ -1562,8 +1441,8 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
public Response commSourceTopicUnlock(
@PathParam("comm") String comm,
@PathParam("topic") String topic) {
- var source =
- TopicEndpointManager.getManager().getTopicSource(CommInfrastructure.valueOf(comm.toUpperCase()), topic);
+ var source = TopicEndpointManager.getManager()
+ .getTopicSource(CommInfrastructure.valueOf(comm.toUpperCase()), topic);
return getResponse(topic, source.unlock(), source);
}
@@ -1576,8 +1455,8 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
public Response commSourceTopicActivation(
@PathParam("comm") String comm,
@PathParam("topic") String topic) {
- var source =
- TopicEndpointManager.getManager().getTopicSource(CommInfrastructure.valueOf(comm.toUpperCase()), topic);
+ var source = TopicEndpointManager.getManager()
+ .getTopicSource(CommInfrastructure.valueOf(comm.toUpperCase()), topic);
return getResponse(topic, source.start(), source);
}
@@ -1590,8 +1469,8 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
public Response commSourceTopicDeactivation(
@PathParam("comm") String comm,
@PathParam("topic") String topic) {
- var source =
- TopicEndpointManager.getManager().getTopicSource(CommInfrastructure.valueOf(comm.toUpperCase()), topic);
+ var source = TopicEndpointManager.getManager()
+ .getTopicSource(CommInfrastructure.valueOf(comm.toUpperCase()), topic);
return getResponse(topic, source.stop(), source);
}
@@ -1604,13 +1483,13 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
public Response commSinkTopicLock(
@PathParam("comm") String comm,
@PathParam("topic") String topic) {
- var sink =
- TopicEndpointManager.getManager().getTopicSink(CommInfrastructure.valueOf(comm.toUpperCase()), topic);
+ var sink = TopicEndpointManager.getManager()
+ .getTopicSink(CommInfrastructure.valueOf(comm.toUpperCase()), topic);
return getResponse(topic, sink.lock(), sink);
}
/**
- * DELETEs the lock on a topic.
+ * Deletes the lock on a topic.
*/
@Override
@DELETE
@@ -1618,8 +1497,8 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
public Response commSinkTopicUnlock(
@PathParam("comm") String comm,
@PathParam("topic") String topic) {
- var sink =
- TopicEndpointManager.getManager().getTopicSink(CommInfrastructure.valueOf(comm.toUpperCase()), topic);
+ var sink = TopicEndpointManager.getManager()
+ .getTopicSink(CommInfrastructure.valueOf(comm.toUpperCase()), topic);
return getResponse(topic, sink.unlock(), sink);
}
@@ -1632,8 +1511,8 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
public Response commSinkTopicActivation(
@PathParam("comm") String comm,
@PathParam("topic") String topic) {
- var sink =
- TopicEndpointManager.getManager().getTopicSink(CommInfrastructure.valueOf(comm.toUpperCase()), topic);
+ var sink = TopicEndpointManager.getManager()
+ .getTopicSink(CommInfrastructure.valueOf(comm.toUpperCase()), topic);
return getResponse(topic, sink.start(), sink);
}
@@ -1646,23 +1525,11 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
public Response commSinkTopicDeactivation(
@PathParam("comm") String comm,
@PathParam("topic") String topic) {
- var sink =
- TopicEndpointManager.getManager().getTopicSink(CommInfrastructure.valueOf(comm.toUpperCase()), topic);
+ var sink = TopicEndpointManager.getManager()
+ .getTopicSink(CommInfrastructure.valueOf(comm.toUpperCase()), topic);
return getResponse(topic, sink.stop(), sink);
}
- private Response getResponse(String topicName, boolean success, Topic topic) {
- if (success) {
- return Response.status(Status.OK).entity(topic).build();
- } else {
- return Response.status(Status.NOT_ACCEPTABLE).entity(makeTopicOperError(topicName)).build();
- }
- }
-
- private Error makeTopicOperError(String topic) {
- return new Error("cannot perform operation on " + topic);
- }
-
/**
* Offers an event to a topic in a communication infrastructure.
*
@@ -1683,8 +1550,7 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
if (source.offer(json)) {
return Arrays.asList(source.getRecentEvents());
} else {
- return Response.status(Status.NOT_ACCEPTABLE).entity(new Error("Failure to inject event over " + topic))
- .build();
+ return errorResponse(NOT_ACCEPTABLE, "Failure to inject event over " + topic);
}
}, e -> {
@@ -1703,7 +1569,7 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
@Path("engine/tools/uuid")
@Produces(MediaType.TEXT_PLAIN)
public Response uuid() {
- return Response.status(Status.OK).entity(UUID.randomUUID().toString()).build();
+ return Response.status(OK).entity(UUID.randomUUID().toString()).build();
}
/**
@@ -1716,17 +1582,16 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
@Path("engine/tools/loggers")
public Response loggers() {
final List<String> names = new ArrayList<>();
- if (!(LoggerFactory.getILoggerFactory() instanceof LoggerContext)) {
- logger.warn("The SLF4J logger factory is not configured for logback");
- return Response.status(Status.INTERNAL_SERVER_ERROR).entity(names).build();
+ if (checkLoggerFactoryInstance()) {
+ return Response.status(INTERNAL_SERVER_ERROR).entity(names).build();
}
- final LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
+ var context = (LoggerContext) LoggerFactory.getILoggerFactory();
for (final Logger lgr : context.getLoggerList()) {
names.add(lgr.getName());
}
- return Response.status(Status.OK).entity(names).build();
+ return Response.status(OK).entity(names).build();
}
/**
@@ -1739,19 +1604,18 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
@Path("engine/tools/loggers/{logger}")
@Produces(MediaType.TEXT_PLAIN)
public Response loggerName1(@PathParam("logger") String loggerName) {
- if (!(LoggerFactory.getILoggerFactory() instanceof LoggerContext)) {
- logger.warn("The SLF4J logger factory is not configured for logback");
- return Response.status(Status.INTERNAL_SERVER_ERROR).build();
+ if (checkLoggerFactoryInstance()) {
+ return Response.status(INTERNAL_SERVER_ERROR).build();
}
- final LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
+ var context = (LoggerContext) LoggerFactory.getILoggerFactory();
var lgr = context.getLogger(loggerName);
if (lgr == null) {
- return Response.status(Status.NOT_FOUND).build();
+ return Response.status(NOT_FOUND).build();
}
final String loggerLevel = (lgr.getLevel() != null) ? lgr.getLevel().toString() : "";
- return Response.status(Status.OK).entity(loggerLevel).build();
+ return Response.status(OK).entity(loggerLevel).build();
}
/**
@@ -1768,28 +1632,28 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
String newLevel;
try {
- if (!checkValidNameInput(loggerName)) {
- return Response.status(Response.Status.NOT_ACCEPTABLE)
- .entity(new Error("logger name: " + NOT_ACCEPTABLE_MSG))
- .build();
+ if (StringUtils.isBlank(loggerName)) {
+ return errorResponse(NOT_ACCEPTABLE, "logger name:" + NOT_ACCEPTABLE_MSG);
}
if (!Pattern.matches("^[a-zA-Z]{3,5}$", loggerLevel)) {
- return Response.status(Response.Status.NOT_ACCEPTABLE)
- .entity(new Error("logger level: " + NOT_ACCEPTABLE_MSG))
- .build();
+ return errorResponse(NOT_ACCEPTABLE, "logger level:" + NOT_ACCEPTABLE_MSG);
}
newLevel = LoggerUtils.setLevel(loggerName, loggerLevel);
- } catch (final IllegalArgumentException e) {
- logger.warn("{}: invalid operation for logger {} and level {}", this, loggerName, loggerLevel, e);
- return Response.status(Status.NOT_FOUND).build();
- } catch (final IllegalStateException e) {
+ } catch (Exception e) {
logger.warn("{}: logging framework unavailable for {} / {}", this, loggerName, loggerLevel, e);
- return Response.status(Status.INTERNAL_SERVER_ERROR).build();
+ return Response.status(INTERNAL_SERVER_ERROR).build();
}
- return Response.status(Status.OK).entity(newLevel
+ return Response.status(OK).entity(newLevel).build();
+ }
- ).build();
+ protected String getSwaggerContents() {
+ try (InputStream inputStream = getClass().getResourceAsStream(SWAGGER);
+ BufferedReader reader = new BufferedReader(new InputStreamReader(Objects.requireNonNull(inputStream)))) {
+ return reader.lines().collect(Collectors.joining(System.lineSeparator()));
+ } catch (IOException e) {
+ throw new PolicyDroolsPdpRuntimeException("Cannot read swagger.json", e);
+ }
}
/**
@@ -1800,7 +1664,7 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
* @throws IllegalArgumentException if an invalid controller name has been passed in
*/
protected DroolsController getDroolsController(String controllerName) {
- final PolicyController controller = PolicyControllerConstants.getFactory().get(controllerName);
+ var controller = PolicyControllerConstants.getFactory().get(controllerName);
if (controller == null) {
throw new IllegalArgumentException(controllerName + DOES_NOT_EXIST_MSG);
}
@@ -1818,37 +1682,88 @@ public class RestManager implements SwaggerApi, DefaultApi, FeaturesApi, InputsA
* illegal state, and generic runtime exceptions.
*
* @param responder function that will generate a response. If it returns a "Response"
- * object, then that object is returned as-is. Otherwise, this method will
- * return an "OK" Response, using the function's return value as the "entity"
- * @param errorMsg function that will generate an error message prefix to be included
- * in responses generated as a result of catching an exception
+ * object, then that object is returned as-is. Otherwise, this method will
+ * return an "OK" Response, using the function's return value as the "entity"
+ * @param errorMsg function that will generate an error message prefix to be included
+ * in responses generated as a result of catching an exception
* @return a response
*/
- private Response catchArgStateGenericEx(Supplier<Object> responder, Function<Exception, String> errorMsg) {
+ protected Response catchArgStateGenericEx(Supplier<Object> responder, Function<Exception, String> errorMsg) {
try {
Object result = responder.get();
if (result instanceof Response) {
return (Response) result;
}
- return Response.status(Response.Status.OK).entity(result).build();
+ return Response.status(OK).entity(result).build();
} catch (final IllegalArgumentException e) {
- return Response.status(Response.Status.NOT_FOUND).entity(new Error(errorMsg.apply(e) + NOT_FOUND_MSG))
- .build();
+ return errorResponse(NOT_FOUND, errorMsg.apply(e) + NOT_FOUND_MSG);
} catch (final IllegalStateException e) {
- return Response.status(Response.Status.NOT_ACCEPTABLE)
- .entity(new Error(errorMsg.apply(e) + NOT_ACCEPTABLE_MSG)).build();
+ return errorResponse(NOT_ACCEPTABLE, errorMsg.apply(e) + NOT_ACCEPTABLE_MSG);
} catch (final RuntimeException e) {
errorMsg.apply(e);
- return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(new Error(e.getMessage())).build();
+ return errorResponse(INTERNAL_SERVER_ERROR, e.getMessage());
+ }
+ }
+
+ protected Object decoderFilterRule2(String controllerName, String topic, String factClass, String rule) {
+ if (StringUtils.isBlank(rule)) {
+ var error = controllerName + ":" + topic + ":" + factClass + " no filter rule provided";
+ return errorResponse(BAD_REQUEST, error);
+ }
+
+ var result = this.checkControllerDecoderAndFilter(controllerName, topic, factClass);
+
+ if (result instanceof Response) {
+ return result;
+ } else {
+ var filter = (JsonProtocolFilter) result;
+ filter.setRule(rule);
+ return filter.getRule();
+ }
+ }
+
+ protected Object checkControllerDecoderAndFilter(String controllerName, String topic, String factClass) {
+ var drools = this.getDroolsController(controllerName);
+ var decoder = EventProtocolCoderConstants.getManager()
+ .getDecoders(drools.getGroupId(), drools.getArtifactId(), topic);
+
+ var filters = decoder.getCoder(factClass);
+ if (filters == null) {
+ var error = controllerName + ":" + topic + ":" + factClass + DOES_NOT_EXIST_MSG;
+ return errorResponse(BAD_REQUEST, error);
+ }
+
+ var filter = filters.getFilter();
+ if (filter == null) {
+ var error = controllerName + ":" + topic + ":" + factClass + NO_FILTERS;
+ return errorResponse(BAD_REQUEST, error);
+ }
+ return filter;
+ }
+
+ private Response getResponse(String topicName, boolean success, Topic topic) {
+ if (success) {
+ return Response.status(OK).entity(topic).build();
+ } else {
+ return errorResponse(NOT_ACCEPTABLE, "cannot perform operation on " + topicName);
+ }
+ }
+
+ private static boolean checkLoggerFactoryInstance() {
+ if (!(LoggerFactory.getILoggerFactory() instanceof LoggerContext)) {
+ logger.warn("The SLF4J logger factory is not configured for logback");
+ return true;
}
+ return false;
}
- public static boolean checkValidNameInput(String test) {
- return Pattern.matches("\\S+", test);
+ private Response errorResponse(Status status, String errorMessage) {
+ var error = new Error(errorMessage);
+ return Response.status(status).entity(error).build();
}
/*
diff --git a/policy-management/src/main/java/org/onap/policy/drools/system/PolicyEngineManager.java b/policy-management/src/main/java/org/onap/policy/drools/system/PolicyEngineManager.java
index 0bc2318b..dbcb7917 100644
--- a/policy-management/src/main/java/org/onap/policy/drools/system/PolicyEngineManager.java
+++ b/policy-management/src/main/java/org/onap/policy/drools/system/PolicyEngineManager.java
@@ -98,7 +98,7 @@ import org.slf4j.LoggerFactory;
* Policy Engine Manager Implementation.
*/
@ToString(onlyExplicitlyIncluded = true)
-class PolicyEngineManager implements PolicyEngine {
+public class PolicyEngineManager implements PolicyEngine {
/**
* String literals.
*/
@@ -342,7 +342,7 @@ class PolicyEngineManager implements PolicyEngine {
private void createLockManager(Properties properties) {
for (PolicyEngineFeatureApi feature : getEngineProviders()) {
try {
- this.lockManager = feature.beforeCreateLockManager(this, properties);
+ this.lockManager = feature.beforeCreateLockManager();
if (this.lockManager != null) {
logger.info("overridden lock manager is {}", this.lockManager);
return;
@@ -843,8 +843,7 @@ class PolicyEngineManager implements PolicyEngine {
public synchronized void shutdown() {
/*
- * shutdown activity even when underlying subcomponents (features, controllers, topics, etc
- * ..) are stuck
+ * shutdown activity even when underlying subcomponents (features, controllers, topics, etc) are stuck
*/
var exitThread = makeShutdownThread();
@@ -884,7 +883,7 @@ class PolicyEngineManager implements PolicyEngine {
logger.warn("{}: cannot shutdown lock manager because of {}", this, e.getMessage(), e);
}
- executorService.shutdownNow();
+ getExecutorService().shutdownNow();
// Stop the JMX listener
@@ -941,7 +940,7 @@ class PolicyEngineManager implements PolicyEngine {
@Override
public void run() {
try {
- doSleep(SHUTDOWN_MAX_GRACE_TIME);
+ doSleep();
logger.warn("{}: abnormal termination - shutdown graceful time period expiration",
PolicyEngineManager.this);
} catch (final InterruptedException e) {
@@ -960,18 +959,18 @@ class PolicyEngineManager implements PolicyEngine {
ex.getMessage(), ex));
logger.info("{}: exit", PolicyEngineManager.this);
- doExit(0);
+ doExit();
}
}
// these may be overridden by junit tests
- protected void doSleep(long sleepMs) throws InterruptedException {
- Thread.sleep(sleepMs);
+ protected void doSleep() throws InterruptedException {
+ Thread.sleep(ShutdownThread.SHUTDOWN_MAX_GRACE_TIME);
}
- protected void doExit(int code) {
- System.exit(code);
+ protected void doExit() {
+ System.exit(0);
}
}
@@ -1329,11 +1328,11 @@ class PolicyEngineManager implements PolicyEngine {
policyController.unlock();
policyController.start();
} catch (final Exception e) {
- logger.error("{}: cannot activate of policy-controller {} because of {}", this, policyController,
- e.getMessage(), e);
+ logger.error("{}: cannot activate of policy-controller {} because of {}",
+ this, policyController, e.getMessage(), e);
} catch (final LinkageError e) {
- logger.error("{}: cannot activate (rules compilation) of policy-controller {} because of {}", this,
- policyController, e.getMessage(), e);
+ logger.error("{}: cannot activate (rules compilation) of policy-controller {} because of {}",
+ this, policyController, e.getMessage(), e);
}
}
diff --git a/policy-management/src/main/java/org/onap/policy/drools/system/internal/LockManager.java b/policy-management/src/main/java/org/onap/policy/drools/system/internal/LockManager.java
index 1683b0f5..fa264426 100644
--- a/policy-management/src/main/java/org/onap/policy/drools/system/internal/LockManager.java
+++ b/policy-management/src/main/java/org/onap/policy/drools/system/internal/LockManager.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.
@@ -122,7 +123,7 @@ public abstract class LockManager<T extends FeatureLockImpl> implements PolicyRe
/**
* After performing checks, this invokes
* {@link #makeLock(LockState, String, String, int, LockCallback)} to create a lock
- * object, inserts it into the map, and then invokes {@link #finishLock(MgrLock)}.
+ * object, inserts it into the map, and then invokes {@link #finishLock(FeatureLockImpl)}.
*/
@Override
public Lock createLock(String resourceId, String ownerKey, int holdSec, LockCallback callback,
diff --git a/policy-management/src/main/server-gen/bin/db-migrator b/policy-management/src/main/server-gen/bin/db-migrator
deleted file mode 100644
index 64d0fcf1..00000000
--- a/policy-management/src/main/server-gen/bin/db-migrator
+++ /dev/null
@@ -1,635 +0,0 @@
-#!/usr/bin/env sh
-
-# ============LICENSE_START=======================================================
-# ONAP
-# ================================================================================
-# Copyright (C) 2017-2022 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=========================================================
-
-# #####################################################################
-#
-# Upgrade/Downgrade SQL File Name Format:
-#
-# <VERSION>-<pdp|feature-name>[-description](.upgrade|.downgrade).sql
-#
-# This tool operates on a migration working directory at
-#
-# $POLICY_HOME/etc/db/migration
-#
-# Upgrade/Downgrade files for each schema (aka database) names to be maintained
-# by this tool are located at
-#
-# $POLICY_HOME/etc/db/migration/<schema-name>/sql
-#
-# The nature of the migration directories is dynamic.
-# Other tooling aware of when migrations are needed are in charge to populate
-# the migrations directory accordingly.
-#
-# One of these tools is the 'features' when a feature with DB requirements
-# is 'enabled', the upgrade scripts will be made present in the migration directory.
-# When a features is 'disabled' downgrade scripts will be made available in the
-# migration directory.
-#
-# The 'policy' tool via its operations 'status' or 'start' will signal the
-# need to perform upgrade or downgrade for a given schema.
-#
-# At any given time the following invariant must be preserved in any given
-# $POLICY_HOME/etc/db/migration/<schema-name>/sql directory
-#
-# There is only upgrade scripts, or only downgrade scripts, or none.
-#
-# #####################################################################
-
-source ${POLICY_HOME}/etc/profile.d/env.sh
-
-METADATA_DB=migration
-METADATA_TABLE=${METADATA_DB}.metadata_versions
-MIGRATION_DIR=${POLICY_HOME}/etc/db/migration
-ZERO_VERSION="0"
-UPGRADE_SQL_SUFFIX=".upgrade.sql"
-DOWNGRADE_SQL_SUFFIX=".downgrade.sql"
-
-SQL_QUOTES="SET SESSION SQL_MODE=ANSI_QUOTES;"
-
-#####################################################
-# usage
-#####################################################
-
-function usage() {
- echo
- echo -e "syntax: $(basename "$0") "
- echo -e "\t -s <schema-name> "
- echo -e "\t [-b <migration-dir>] "
- echo -e "\t [-f <from-version>]"
- echo -e "\t [-t <target-version>]"
- echo -e "\t -o <operations> "
- echo
- echo -e "\t where <operations>=upgrade|downgrade|auto|version|erase|report"
- echo
- echo
- echo -e "Configuration Options:"
- echo -e "\t -s|--schema|--database: schema to operate on ('ALL' to apply on all)"
- echo -e "\t -b|--basedir: overrides base DB migration directory"
- echo -e "\t -f|--from: overrides current release version for operations"
- echo -e "\t -t|--target: overrides target release to upgrade/downgrade"
- echo
- echo -e "Operations:"
- echo -e "\t upgrade: upgrade operation"
- echo -e "\t downgrade: performs a downgrade operation"
- echo -e "\t auto: autonomous operation, determines upgrade or downgrade"
- echo -e "\t version: returns current version, and in conjunction if '-f' sets the current version"
- echo -e "\t erase: erase all data related <schema> (use with care)"
- echo -e "\t report: migration detailed report on an schema"
- echo -e "\t ok: is the migration status valid"
- echo
- echo
-}
-
-#####################################################
-# ensure global metadata
-#####################################################
-
-function ensure_metadata
-{
- if [ "${DEBUG}" = "y" ]; then
- echo "-- ensure_metadata --"
- set -x
- fi
-
- local sql rc
-
- sql="CREATE DATABASE IF NOT EXISTS ${METADATA_DB};"
- ${MYSQL} --execute "${sql}"
- rc=$?
- if [ ${rc} -ne 0 ]; then
- return ${rc}
- fi
-
- sql="CREATE TABLE IF NOT EXISTS ${METADATA_TABLE} "
- sql=${sql}"(name VARCHAR(60) NOT NULL, version VARCHAR(20), PRIMARY KEY(name));"
- ${MYSQL} --execute "${sql}"
- return $?
-}
-
-
-#####################################################
-# ensure metadata on a per schema basis
-#####################################################
-
-function ensure_metadata_schema
-{
- if [ "${DEBUG}" = "y" ]; then
- echo "-- ensure_metadata_schema --"
- set -x
- fi
-
- local sql rc
-
- sql="CREATE TABLE IF NOT EXISTS ${METADATA_HISTORY} "
- sql=${sql}"(script VARCHAR(80) NOT NULL, operation VARCHAR(10), success VARCHAR(1), "
- sql=${sql}"atTime TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, "
- sql=${sql}"PRIMARY KEY(script));"
- ${MYSQL} --execute "${sql}"
- rc=$?
- if [ ${rc} -ne 0 ]; then
- return ${rc}
- fi
-
- sql="CREATE DATABASE IF NOT EXISTS ${SCHEMA_DB};"
- ${MYSQL} --execute "${sql}"
- return $?
-}
-
-
-#####################################################
-# target_release
-#####################################################
-
-function target_release
-{
- if [ "${DEBUG}" = "y" ]; then
- echo "-- target_release --"
- set -x
- fi
-
- local sql sqlName upgradeSqls downgradeSqls
-
- TARGET_UPGRADE_RELEASE=${ZERO_VERSION}
- TARGET_DOWNGRADE_RELEASE=${ZERO_VERSION}
-
- upgradeSqls=$(ls -v -r "${UPGRADE_DIR}"/*"${UPGRADE_SQL_SUFFIX}" 2> /dev/null)
- for sql in ${upgradeSqls}; do
- sqlName=$(basename "${sql}")
- TARGET_UPGRADE_RELEASE="${sqlName%-*}"
- break
- done
-
- # default unless overriden
- TARGET_DOWNGRADE_RELEASE="${ZERO_VERSION}"
-}
-
-#####################################################
-# is_upgrade
-#####################################################
-
-function is_upgrade
-{
- if [ "${DEBUG}" = "y" ]; then
- echo "-- is_upgrade --"
- set -x
- fi
-
- local upgradeSqls
-
- upgradeSqls=$(ls "${UPGRADE_DIR}"/*"${UPGRADE_SQL_SUFFIX}" 2> /dev/null)
- if [ -z "${upgradeSqls}" ]; then
- return 1
- else
- return 0
- fi
-}
-
-
-#####################################################
-# is_downgrade
-#####################################################
-
-function is_downgrade
-{
- if [ "${DEBUG}" = "y" ]; then
- echo "-- is_downgrade --"
- set -x
- fi
-
- local downgradeSqls
-
- downgradeSqls=$(ls "${DOWNGRADE_DIR}"/*"${DOWNGRADE_SQL_SUFFIX}" 2> /dev/null)
- if [ -z "${downgradeSqls}" ]; then
- return 1
- else
- return 0
- fi
-}
-
-
-#####################################################
-# set_current_release
-#####################################################
-
-function set_current_release
-{
- if [ "${DEBUG}" = "y" ]; then
- echo "-- set_current_release --"
- set -x
- fi
-
- CURRENT_RELEASE="${1}"
-
- local sql
- sql="INSERT INTO ${METADATA_TABLE} (name, version) "
- sql=${sql}"VALUES('${SCHEMA}', '${CURRENT_RELEASE}') "
- sql=${sql}"ON DUPLICATE KEY UPDATE version='${CURRENT_RELEASE}';"
-
- ${MYSQL} --execute "${sql}"
- return $?
-}
-
-#####################################################
-# current_release
-#####################################################
-
-function current_release
-{
- if [ "${DEBUG}" = "y" ]; then
- echo "-- current_release --"
- set -x
- fi
-
- local rc
- local query="SELECT version FROM ${METADATA_TABLE} WHERE name='${SCHEMA}'"
-
- CURRENT_RELEASE=$(${MYSQL} --skip-column-names --silent --execute "${query}")
- if [ -z "${CURRENT_RELEASE}" ]; then
- set_current_release "${ZERO_VERSION}"
- return $?
- fi
-
- return 0
-}
-
-#####################################################
-# execute sql script history
-#####################################################
-
-function track_script
-{
- if [ "${DEBUG}" = "y" ]; then
- echo "-- track_script $* --"
- set -x
- fi
-
- local script="${1}" operation="${2}" success="${3}"
- local sql="INSERT INTO ${METADATA_HISTORY}(script,operation,success,atTime) "
- sql=${sql}"VALUES ('${script}','${operation}','${success}',now()) "
- sql=${sql}"ON DUPLICATE KEY UPDATE operation=values(operation), success=values(success), atTime=values(atTime);"
-
- ${MYSQL} --execute "${sql}"
- return $?
-}
-
-
-#####################################################
-# execute sql script
-#####################################################
-
-function run_script
-{
- if [ "${DEBUG}" == "y" ]; then
- echo "-- run_script $* --"
- set -x
- fi
-
- local operation="${1}" script="${2}" scriptPath="${3}"
-
- echo
- echo "> ${operation} ${script}"
-
- ${MYSQL} --verbose < "${scriptPath}"
- local rc=$?
- if [ ${rc} -ne 0 ]; then
- success="0"
- else
- success="1"
- fi
-
- track_script "${script}" "${operation}" "${success}"
-
- return ${rc}
-}
-
-#####################################################
-# upgrade
-#####################################################
-
-function upgrade
-{
- if [ "${DEBUG}" = "y" ]; then
- echo "-- upgrade --"
- set -x
- fi
-
- local sqlName sqlFile schemaVersion upgradeSqls rc
-
- ${MYSQL} --execute "USE ${SCHEMA_DB}"
-
- echo "upgrade: ${CURRENT_RELEASE} -> ${TARGET_UPGRADE_RELEASE}"
-
- if [ ${CURRENT_RELEASE} \< ${TARGET_UPGRADE_RELEASE} ]; then
- upgradeSqls=$(ls -v "${UPGRADE_DIR}"/*"${UPGRADE_SQL_SUFFIX}" 2> /dev/null)
- for sqlFile in ${upgradeSqls}; do
- sqlName=$(basename "${sqlFile}")
- schemaVersion="${sqlName%-*}"
- if [ "${schemaVersion}" -gt "${CURRENT_RELEASE}" ] && \
- [ "${schemaVersion}" -le "${TARGET_UPGRADE_RELEASE}" ]; then
- run_script "upgrade" "${sqlName}" "${sqlFile}"
- rc=$?
- if [ ${rc} -ne 0 ]; then
- echo "${SCHEMA}: upgrade aborted at ${schemaVersion} by script ${sqlName}"
- set_current_release "${schemaVersion}"
- return ${rc}
- fi
- fi
- done
-
- set_current_release "${TARGET_UPGRADE_RELEASE}"
- fi
-
- return 0
-}
-
-#####################################################
-# downgrade
-#####################################################
-
-function downgrade
-{
- if [ "${DEBUG}" = "y" ]; then
- echo "-- downgrade --"
- set -x
- fi
-
- local sqlName sqlFile schemaVersion downgradeSqls rc
-
- ${MYSQL} --execute "USE ${SCHEMA_DB}"
-
- echo "downgrade: ${CURRENT_RELEASE} -> ${TARGET_DOWNGRADE_RELEASE}"
-
- if [ ${CURRENT_RELEASE} \> ${TARGET_DOWNGRADE_RELEASE} ]; then
- downgradeSqls=$(ls -v -r "${DOWNGRADE_DIR}"/*"${DOWNGRADE_SQL_SUFFIX}" 2> /dev/null)
- for sqlFile in ${downgradeSqls}; do
- sqlName=$(basename "${sqlFile}")
- schemaVersion="${sqlName%-*}"
- if [ "${schemaVersion}" -le "${CURRENT_RELEASE}" ] && \
- [ "${schemaVersion}" -gt "${TARGET_DOWNGRADE_RELEASE}" ]; then
- run_script "downgrade" "${sqlName}" "${sqlFile}"
- rc=$?
- if [ ${rc} -ne 0 ]; then
- echo "${SCHEMA}: downgrade aborted at ${schemaVersion} by script ${sqlName}"
- set_current_release "${schemaVersion}"
- return ${rc}
- fi
- fi
- done
-
- set_current_release "${TARGET_DOWNGRADE_RELEASE}"
- fi
-
- return 0
-}
-
-#####################################################
-# erase
-#####################################################
-
-function erase
-{
- if [ "${DEBUG}" = "y" ]; then
- echo "-- erase --"
- set -x
- fi
-
- local updateMetadata="UPDATE ${METADATA_TABLE} SET version='${ZERO_VERSION}';"
- ${MYSQL} --execute "${updateMetadata}"
-
- local deleteHistory="DELETE FROM ${METADATA_HISTORY};"
- ${MYSQL} --execute "${deleteHistory}"
-
- local dropDB="DROP DATABASE IF EXISTS ${SCHEMA_DB}";
- ${MYSQL} --execute "${dropDB}"
-}
-
-#####################################################
-# report
-#####################################################
-
-function report
-{
- if [ "${DEBUG}" = "y" ]; then
- echo "-- report --"
- set -x
- fi
-
- local versionSql="SELECT * FROM ${METADATA_TABLE} WHERE name='${SCHEMA}';"
- ${MYSQL} --execute "${versionSql}"
-
- local historySql="SELECT * FROM ${METADATA_HISTORY} ORDER BY atTime ASC;"
- ${MYSQL} --execute "${historySql}"
-
- okay
-}
-
-function okay
-{
- if [ "${DEBUG}" = "y" ]; then
- echo "-- okay --"
- set -x
- fi
-
- local rc=0
- if is_upgrade; then
- if [ "${CURRENT_RELEASE}" = "${TARGET_UPGRADE_RELEASE}" ]; then
- echo "${SCHEMA}: OK @ ${CURRENT_RELEASE}"
- else
- echo "${SCHEMA}: upgrade available: ${CURRENT_RELEASE} -> ${TARGET_UPGRADE_RELEASE}"
- rc=1
- fi
- else
- if [ "${CURRENT_RELEASE}" = "${TARGET_DOWNGRADE_RELEASE}" ]; then
- echo "${SCHEMA}: OK @ ${CURRENT_RELEASE}"
- else
- echo "${SCHEMA}: downgrade available: ${CURRENT_RELEASE} -> ${TARGET_DOWNGRADE_RELEASE}"
- rc=1
- fi
- fi
-
- return ${rc}
-}
-
-#####################################################
-# MAIN
-#####################################################
-
-if [ "${DEBUG}" = "y" ]; then
- echo "-- $0 $* --"
- set -x
-fi
-until [ -z "$1" ]; do
- case $1 in
- -s|--schema|--database) shift
- SCHEMA=$1
- ;;
- -b|--basedir) shift
- MIGRATION_DIR=$1
- ;;
- -t|--target) shift
- INPUT_TARGET_RELEASE=$1
- ;;
- -f|--from) shift
- INPUT_CURRENT_RELEASE=$1
- ;;
- -o|--operation) shift
- OPERATION=$1
- ;;
- *) usage
- exit 1
- ;;
- esac
- shift
-done
-
-case ${OPERATION} in
- upgrade) ;;
- downgrade) ;;
- auto) ;;
- version) ;;
- erase) ;;
- report) ;;
- ok) ;;
- *) echo "error: invalid operation provided"
- usage
- exit 1
- ;;
-esac
-
-if [ -z "${SCHEMA}" ]; then
- echo "error: a database name must be provided"
- usage
- exit 2
-fi
-
-source "${POLICY_HOME}"/etc/profile.d/env.sh
-
-if [ -z "${SQL_HOST}" ] || [ -z "${SQL_USER}" ] || [ -z "${SQL_PASSWORD}" ]; then
- echo "error: no database has been set up"
- exit 4
-fi
-
-if [ -z "${SQL_PORT}" ]; then
- export SQL_PORT=3306
-fi
-
-if [ -z "$MYSQL_CMD" ]; then
- MYSQL_CMD="mysql"
-fi
-
-MYSQL="${MYSQL_CMD} -u${SQL_USER} -p${SQL_PASSWORD} -h ${SQL_HOST} -P ${SQL_PORT}"
-
-if ! ${MYSQL} --execute "show databases;" > /dev/null 2>&1; then
- echo "error: No DB connectivity to ${SQL_HOST} for ${SQL_USER}"
- exit 5
-fi
-
-if [ "${SCHEMA}" = "ALL" ]; then
- SCHEMA="*"
-fi
-
-SCHEMA_S=$(ls -d "${MIGRATION_DIR}"/${SCHEMA}/ 2> /dev/null)
-if [ -z "${SCHEMA_S}" ]; then
- echo "error: no databases available"
- exit 0
-fi
-
-if ! ensure_metadata; then
- echo "error: migration metadata not accessible"
- exit 7
-fi
-
-rc=0
-for dbPath in ${SCHEMA_S}; do
- SCHEMA=$(basename "${dbPath}")
- SCHEMA_DB="\`${SCHEMA}\`"
- UPGRADE_DIR="${MIGRATION_DIR}"/"${SCHEMA}"/sql
- DOWNGRADE_DIR=${UPGRADE_DIR}
- METADATA_HISTORY="${METADATA_DB}.\`${SCHEMA}_history\`"
- TARGET_RELEASE=${INPUT_TARGET_RELEASE}
- CURRENT_RELEASE=${INPUT_CURRENT_RELEASE}
-
- if is_upgrade && is_downgrade; then
- echo "${SCHEMA}: failure: invalid configuration: ${UPGRADE_SQL_SUFFIX} and "\
- "${DOWNGRADE_SQL_SUFFIX} exist under ${DOWNGRADE_DIR}"
- rc=1
- continue
- fi
-
- if [ "${operation}" = "auto" ]; then
- if is_upgrade; then
- operation=upgrade
- else
- operation=downgrade
- fi
- fi
-
- if ! ensure_metadata_schema; then
- echo "${SCHEMA}: failure: metadata not accessible for this schema"
- continue
- fi
-
- if [ -z "${TARGET_RELEASE}" ]; then
- target_release
- else
- # user asked to override
- TARGET_UPGRADE_RELEASE="${TARGET_RELEASE}"
- TARGET_DOWNGRADE_RELEASE="${TARGET_RELEASE}"
- fi
-
- if [ -z "${CURRENT_RELEASE}" ]; then
- if ! current_release; then
- echo "${SCHEMA}: failure: cannot obtain current release"
- continue
- fi
- else
- if ! set_current_release "${CURRENT_RELEASE}"; then
- echo "${SCHEMA}: failure: cannot set current release"
- continue
- fi
- fi
-
- case ${OPERATION} in
- upgrade) if upgrade; then
- echo "${SCHEMA}: OK: upgrade (${CURRENT_RELEASE})"
- else
- rc=1
- echo "${SCHEMA}: failure: upgrade to release ${TARGET_UPGRADE_RELEASE} (${CURRENT_RELEASE})"
- fi
- ;;
- downgrade) if downgrade; then
- echo "${SCHEMA}: OK: downgrade (${CURRENT_RELEASE})"
- else
- rc=1
- echo "${SCHEMA}: failure: downgrade to release ${TARGET_DOWNGRADE_RELEASE} (${CURRENT_RELEASE})"
- fi
- ;;
- version) echo "${SCHEMA}: ${CURRENT_RELEASE}"
- ;;
- erase) erase
- ;;
- report) report
- ;;
- ok) okay
- ;;
- esac
-
-done
-exit $rc
diff --git a/policy-management/src/main/server-gen/bin/features b/policy-management/src/main/server-gen/bin/features
index 3343ffc4..01b77b1c 100644
--- a/policy-management/src/main/server-gen/bin/features
+++ b/policy-management/src/main/server-gen/bin/features
@@ -5,6 +5,7 @@
# ONAP POLICY
# ================================================================================
# 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.
@@ -35,10 +36,6 @@
#     |  | L─ <dependent-jar>+
#     │  L─ feature/
#     │  L─ <feature-jar>
-#     L─ [db]/
-#     │   L─ <db-name>/+
-#     │  L─ sql/
-#     │ L─ <sql-scripts>*
#     L─ [artifacts]/
#      L─ <artifact>+
#     L─ [install]
@@ -60,16 +57,6 @@
# of pdp-d that are necessary for <feature-name> to operate
# correctly.
# lib/feature the single feature jar that implements the feature.
-# [db] database directory, if the feature contains sql.
-# [db]/<db-name> database to which underlying sql scripts should be applied against.
-# ideally, <db-name> = <feature-name> so it is easily to associate
-# the db data with a feature itself. Ideally, since a feature is
-# a somewhat independent isolated unit of functionality,the <db-name>
-# database ideally isolates all its data.
-# [db]/<db-name>/sql directory with all the sql scripts.
-# [db]/<db-name>/sql/<sql-scripts> for this feature sql scripts
-# upgrade scripts should be suffixed with ".upgrade.sql"
-# downgrade scripts should be suffixed with ".downgrade.sql"
# [artifacts] maven artifacts to be deployed in a maven repository.
# [artifacts]/<artifact> maven artifact with identifiable maven coordinates embedded
# in the artifact.
@@ -87,10 +74,10 @@
# Operations:
# install: installs a feature
# uninstall: uninstalls a feature
-# enable : enables 1) dependencies, 2) configuration, 3) binaries 4) database, 5) artifacts,
-# 6) feature, 7) customization.
-# disable: disables 1) dependencies, 2) configuration, 3) binaries, 4) database, 5) feature,
-# 6) customization
+# enable : enables 1) dependencies, 2) configuration, 3) binaries 4) artifacts,
+# 5) feature, 6) customization.
+# disable: disables 1) dependencies, 2) configuration, 3) binaries, 4) feature,
+# 5) customization
# status : status of a feature
#
# 'enable' operation details:
@@ -99,10 +86,8 @@
# 2. sets symbolic links to feature dependencies in pdp-d classpath ($POLICY_HOME/lib)
# 3. sets symbolic links to feature configuration in pdp-d configuration directory ($POLICY_HOME/config)
# 4. sets symbolic links to feature executables in pdp-d bin directory ($POLICY_HOME/bin)
-# 5. sets symbolic links to feature upgrade scripts and removes links to downgrade scripts (if any)
-# in the pdp-d migration directory ($POLICY_HOME/etc/db/migration).
-# 6. deploys any maven artifacts in the maven repositories in use (if any)
-# 7. cd to the feature 'install' directory an executes (if exists) the 'enable' script to allow for specific
+# 5. deploys any maven artifacts in the maven repositories in use (if any)
+# 6. cd to the feature 'install' directory an executes (if exists) the 'enable' script to allow for specific
# customizations for this feature.
#
# 'disable' operation details:
@@ -111,16 +96,9 @@
# 2. removes symbolic links to feature dependencies in pdp-d classpath ($POLICY_HOME/lib)
# 3. removes symbolic links to feature configuration in pdp-d configuration directory ($POLICY_HOME/config)
# 4. removes symbolic links to feature executables in pdp-d bin directory ($POLICY_HOME/bin)
-# 5. removes symbolic links to feature upgrade scripts and sets links to downgrade scripts (if any)
-# in the pdp-d migration directory ($POLICY_HOME/etc/db/migration).
-# 6. cd to the feature 'install' directory an executes (if exists) the 'disable' script to allow for specific
+# 5. cd to the feature 'install' directory an executes (if exists) the 'disable' script to allow for specific
# customizations for this feature.
#
-# Notes for DB enabled features:
-# A. Upgrade/Downgrade SQL File Name Format:
-# <VERSION>-<pdp|feature-name>[-description](.upgrade|.downgrade).sql
-# B. See related tooling: db-migrator, deploy-artifact, and policy
-#
# Example:
#
# POLICY_HOME/
@@ -155,7 +133,6 @@ fi
LIB=${POLICY_HOME}/lib
CONFIG=${POLICY_HOME}/config
BIN=${POLICY_HOME}/bin
-DB=${POLICY_HOME}/etc/db/migration
FEATURES=${POLICY_HOME}/features
if [ ! -d "${LIB}" ]; then
@@ -171,10 +148,6 @@ fi
# ensure that the directory exists
mkdir -p "${FEATURES}" 2> /dev/null
-if [ ! -d "${DB}" ]; then
- mkdir -p "${DB}"
-fi
-
# relative per Feature Directory Paths
FEATURE_DEPS="lib/dependencies"
@@ -183,11 +156,6 @@ FEATURE_CONFIG="config"
FEATURE_BIN="bin"
FEATURE_INSTALL="install"
FEATURE_ARTIFACTS="artifacts"
-FEATURE_DB="db"
-FEATURE_SQL="sql"
-
-UPGRADE_SQL_SUFFIX=".upgrade.sql"
-DOWNGRADE_SQL_SUFFIX=".downgrade.sql"
featureJars=$(find "${FEATURES}" -name "feature-*.jar" -type f -exec basename {} \; 2> /dev/null)
@@ -386,39 +354,6 @@ function enableBinAnalysis ()
}
# ##########################################################
-# enableDbAnalysis (featureName):
-# reports on potential db access problems
-# featureName: name of the feature
-# ##########################################################
-function enableDbAnalysis()
-{
- if [ "${DEBUG}" = "y" ]; then
- echo "-- enableDbAnalysis $* --"
- set -x
- fi
-
- local featureName="$1"
- local featureSqls
-
- if [ -z "${featureName}" ]; then
- echo "warning: no feature name"
- return 1
- fi
-
- featureSqls=$(ls "${FEATURES}"/"${featureName}"/"${FEATURE_DB}"/*/${FEATURE_SQL}/*${UPGRADE_SQL_SUFFIX} 2> /dev/null)
- if [ -z "${featureSqls}" ]; then
- return 0
- fi
-
- source "${POLICY_HOME}"/etc/profile.d/env.sh
- if [ -z "${SQL_HOST}" ] || [ -z "${SQL_USER}" ] || [ -z "${SQL_PASSWORD}" ]; then
- echo "warning: DB server is not configured"
- fi
-
- return 0
-}
-
-# ##########################################################
# enableFeatureDeps(featureName):
# enables feature dependencies
# featureName: name of the feature
@@ -500,95 +435,6 @@ function enableFeatureBin()
}
# ##########################################################
-# enableFeatureDbSchema(featureName):
-# enables feature DB Schema configuration
-# featureName: name of the feature
-# ##########################################################
-function enableFeatureDbSchema()
-{
- if [ "${DEBUG}" = "y" ]; then
- echo "-- enableFeatureDbSchema $* --"
- set -x
- fi
-
- local featureName="$1"
- local featureDbPath="$2"
- local schemaName="$3"
-
- if [ -z "${featureName}" ]; then
- echo "warning: no feature name"
- return 1
- fi
-
- if [ -z "${featureDbPath}" ]; then
- echo "warning: ${featureName} contains no DB path"
- return 2
- fi
-
- if [ -z "${schemaName}" ]; then
- echo "warning: feature ${featureName} contains no schema name"
- return 3
- fi
-
- rc=0
- sqlUpgradeScripts=$(ls "${featureDbPath%/}"/${FEATURE_SQL}/*${UPGRADE_SQL_SUFFIX} 2> /dev/null)
- for sqlUpgradeScript in ${sqlUpgradeScripts}; do
- if [ ! -d "${DB}"/"${schemaName}"/${FEATURE_SQL} ]; then
- mkdir -p "${DB}"/"${schemaName}"/${FEATURE_SQL} 2> /dev/null
- fi
- ln -s -f "${sqlUpgradeScript}" "${DB}"/"${schemaName}"/${FEATURE_SQL}/
- done
-
- sqlDowngradeScripts=$(ls "${featureDbPath%/}"/${FEATURE_SQL}/*${DOWNGRADE_SQL_SUFFIX} 2> /dev/null)
- for sqlDowngradeScript in ${sqlDowngradeScripts}; do
- if [ -d "${DB}"/"${schemaName}"/${FEATURE_SQL} ]; then
- sqlName=$(basename "${sqlDowngradeScript}")
- rm -f "${DB}"/"${schemaName}"/"${FEATURE_SQL}"/"${sqlName}" 2> /dev/null
- else
- echo "warning: feature ${featureName} only contains downgrade scripts"
- rc=4
- break
- fi
- done
-
- if [ -n "${sqlUpgradeScripts}" ] || [ -n "${sqlDowngradeScripts}" ]; then
- DEBUG=${DEBUG} db-migrator -s "${schemaName}" -o ok
- fi
-
- return ${rc}
-}
-
-# ##########################################################
-# enableFeatureDb(featureName):
-# enables DB feature configuration
-# featureName: name of the feature
-# ##########################################################
-function enableFeatureDb()
-{
- if [ "${DEBUG}" = "y" ]; then
- echo "-- enableFeatureDb $* --"
- set -x
- fi
-
- local featureName="$1"
- local featureDbs featureDbPath schemaName sqls
- if [ -z "${featureName}" ]; then
- echo "warning: no feature name"
- return 1
- fi
-
- featureDbs=$(ls -d "${FEATURES}"/"${featureName}"/"${FEATURE_DB}"/*/ 2> /dev/null)
- for featureDbPath in ${featureDbs}; do
- sqls=$(ls "${featureDbPath%/}"/"${FEATURE_SQL}"/*.sql 2> /dev/null)
- if [ -z "${sqls}" ]; then
- continue
- fi
- schemaName=$(basename "${featureDbPath%/}")
- enableFeatureDbSchema "${featureName}" "${featureDbPath%/}" "${schemaName}"
- done
-}
-
-# ##########################################################
# enableFeatureArtifacts(featureName):
# deploys maven artifacts
# featureName: name of the feature
@@ -686,10 +532,6 @@ function enableFeature()
if ! enableBinAnalysis "${featureName}"; then
return "$?"
fi
-
- if ! enableDbAnalysis "${featureName}"; then
- return "$?"
- fi
# enable feature itself
@@ -707,10 +549,6 @@ function enableFeature()
enableFeatureBin "${featureName}"
- # enable db
-
- enableFeatureDb "${featureName}"
-
# enable feature artifacts
enableFeatureArtifacts "${featureName}"
@@ -839,97 +677,6 @@ function disableFeatureBin()
}
# ##########################################################
-# disableFeatureDbSchema(featureName, featureDbPath, schemaName):
-# disables feature db configuration for a schema
-# featureName: name of the feature
-# ##########################################################
-function disableFeatureDbSchema()
-{
- if [ "${DEBUG}" = "y" ]; then
- echo "-- disableFeatureDbSchema $* --"
- set -x
- fi
-
- local featureName="$1" featureDbPath="$2" schemaName="$3"
- local upgradeFeatureSqls downgradeFeatureSqls featureSql sqlDir sqlName schemaDir schemaName
-
- if [ -z "${featureName}" ]; then
- echo "warning: no feature name"
- return 1
- fi
-
- if [ -z "${featureDbPath}" ]; then
- echo "warning: ${featureName} contains no DB path"
- return 2
- fi
-
- if [ -z "${schemaName}" ]; then
- echo "warning: feature ${featureName} contains no schema name"
- return 3
- fi
-
- if [ -z "${featureName}" ]; then
- echo "warning: no feature name"
- return 1
- fi
-
- upgradeFeatureSqls=$(find "${FEATURES}"/"${featureName}"/"${FEATURE_DB}"/"${schemaName}"/"${FEATURE_SQL}"/*"${UPGRADE_SQL_SUFFIX}" -type f -maxdepth 1 2> /dev/null)
- for featureSql in ${upgradeFeatureSqls}; do
- sqlName=$(basename "${featureSql}")
- sqlDir=$(dirname "${featureSql}")
- schemaDir=$(dirname "${sqlDir}")
- schemaName=$(basename "${schemaDir}")
- rm -f "${DB}"/"${schemaName}"/"${FEATURE_SQL}"/"${sqlName}" 2> /dev/null
- done
-
- downgradeFeatureSqls=$(find "${FEATURES}"/"${featureName}"/"${FEATURE_DB}"/"${schemaName}"/"${FEATURE_SQL}"/*"${DOWNGRADE_SQL_SUFFIX}" -type f -maxdepth 1 2> /dev/null)
- for featureSql in ${downgradeFeatureSqls}; do
- sqlName=$(basename "${featureSql}")
- sqlDir=$(dirname "${featureSql}")
- schemaDir=$(dirname "${sqlDir}")
- schemaName=$(basename "${schemaDir}")
- if [ ! -d "${DB}"/"${schemaName}"/${FEATURE_SQL} ]; then
- mkdir -p "${DB}"/"${schemaName}"/${FEATURE_SQL} 2> /dev/null
- fi
- ln -s -f "${featureSql}" "${DB}"/"${schemaName}"/${FEATURE_SQL}/
- done
-
- if [ -n "${sqlUpgradeScripts}" ] || [ -n "${sqlDowngradeScripts}" ]; then
- DEBUG=${DEBUG} db-migrator -s "${schemaName}" -o ok
- fi
-}
-
-# ##########################################################
-# disableFeatureDb(featureName):
-# disables feature db configuration
-# featureName: name of the feature
-# ##########################################################
-function disableFeatureDb()
-{
- if [ "${DEBUG}" = "y" ]; then
- echo "-- disableFeatureDb $* --"
- set -x
- fi
-
- local featureName="$1"
- local featureDbPath featureDbs schemaName
-
- if [ -z "${featureName}" ]; then
- echo "warning: no feature name"
- return 1
- fi
-
- featureDbs=$(ls -d "${FEATURES}"/"${featureName}"/"${FEATURE_DB}"/*/ 2> /dev/null)
- for featureDbPath in ${featureDbs}; do
- if [ -z "$(ls "${featureDbPath%/}"/"${FEATURE_SQL}"/*${UPGRADE_SQL_SUFFIX} 2> /dev/null)" ]; then
- continue
- fi
- schemaName=$(basename "${featureDbPath%/}")
- disableFeatureDbSchema "${featureName}" "${featureDbPath%/}" "${schemaName}"
- done
-}
-
-# ##########################################################
# disableFeature(featureName): disables a feature
# featureName: name of the feature
# ##########################################################
@@ -966,10 +713,6 @@ function disableFeature()
disableFeatureBin "${featureName}"
- # disable DB SQL scripts if any
-
- disableFeatureDb "${featureName}"
-
# run custom disable if any
customOpScript "${featureName}" "disable"
@@ -1080,47 +823,6 @@ function installFeatures
fi
}
-# ##########################################################
-# uninstallFeatureDb(featureName):
-# uninstalls the feature db configuration
-# featureName: name of the feature
-# ##########################################################
-function uninstallFeatureDb()
-{
- if [ "${DEBUG}" = "y" ]; then
- echo "-- uninstallFeatureDb $* --"
- set -x
- fi
-
- local featureName="$1"
- local featureSqls sqlDir sqlName schemaDir schemaName schemaNames leftSqls
-
- if [ -z "${featureName}" ]; then
- echo "warning: no feature name"
- return 1
- fi
-
- featureSqls=$(find "${FEATURES}"/"${featureName}"/"${FEATURE_DB}"/*/${FEATURE_SQL}/*.sql -type f -maxdepth 1 2> /dev/null)
- for featureSql in ${featureSqls}; do
- sqlName=$(basename "${featureSql}")
- sqlDir=$(dirname "${featureSql}")
- schemaDir=$(dirname "${sqlDir}")
- schemaName=$(basename "${schemaDir}")
- schemaNames="${schemaNames} ${schemaName}"
- rm -f "${DB}"/"${schemaName}"/"${FEATURE_SQL}"/"${sqlName}" 2> /dev/null
- done
- for schemaName in ${schemaNames};
- do
- leftSqls=$(ls "${DB}"/"${schemaName}"/"${FEATURE_SQL}"/*.sql 2> /dev/null)
- if [ -n "${leftSqls}" ]; then
- if ! DEBUG=${DEBUG} db-migrator -s "${schemaName}" -o ok; then
- echo -n "warning: ${featureName}: ${schemaName}: database data is leftover. "
- echo -n "Consider cleaning left over data with 'db-migrator'."
- fi
- fi
- done
-}
-
############################################################
# uninstallFeature <feature-name> ...
############################################################
@@ -1138,7 +840,6 @@ function uninstallFeature
return
fi
disableFeature "${featureName}"
- uninstallFeatureDb "${featureName}"
customOpScript "${featureName}" "uninstall"
if [ -n "${FEATURES}" ] && [ -n "${featureName}" ]; then
diff --git a/policy-management/src/test/java/org/onap/policy/drools/controller/IndexedDroolsControllerFactoryTest.java b/policy-management/src/test/java/org/onap/policy/drools/controller/IndexedDroolsControllerFactoryTest.java
new file mode 100644
index 00000000..39a03db3
--- /dev/null
+++ b/policy-management/src/test/java/org/onap/policy/drools/controller/IndexedDroolsControllerFactoryTest.java
@@ -0,0 +1,154 @@
+/*-
+ * ============LICENSE_START===============================================
+ * ONAP
+ * ========================================================================
+ * 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.
+ * 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.drools.controller;
+
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.Mockito.doCallRealMethod;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.onap.policy.drools.protocol.coders.TopicCoderFilterConfiguration;
+import org.springframework.test.util.ReflectionTestUtils;
+
+class IndexedDroolsControllerFactoryTest {
+
+ IndexedDroolsControllerFactory factory;
+ static final String GROUP_ID = "groupId";
+ static final String ARTIFACT_ID = "artifactId";
+ static final String VERSION = "version";
+ static final String OTHER_VERSION = "otherVersion";
+
+ @BeforeEach
+ void setUp() {
+ this.factory = new IndexedDroolsControllerFactory();
+ }
+
+ @Test
+ void build_EmptyArguments() {
+ var props = new Properties();
+ List<TopicCoderFilterConfiguration> decoderConfigs = List.of();
+ List<TopicCoderFilterConfiguration> encoderConfigs = List.of();
+
+ assertThatThrownBy(() -> factory.build(props, "", ARTIFACT_ID, VERSION, decoderConfigs, encoderConfigs))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("Missing maven group-id coordinate");
+
+ assertThatThrownBy(() -> factory.build(props, GROUP_ID, "", VERSION, decoderConfigs, encoderConfigs))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("Missing maven artifact-id coordinate");
+
+ assertThatThrownBy(() -> factory.build(props, GROUP_ID, ARTIFACT_ID, "", decoderConfigs, encoderConfigs))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("Missing maven version coordinate");
+ }
+
+ @Test
+ void testBuild_CheckControllerCopy() {
+ var props = new Properties();
+ List<TopicCoderFilterConfiguration> decoderConfigs = List.of();
+ List<TopicCoderFilterConfiguration> encoderConfigs = List.of();
+
+ var mockFactory = mock(IndexedDroolsControllerFactory.class);
+ when(mockFactory.build(props, GROUP_ID, ARTIFACT_ID, VERSION, decoderConfigs, encoderConfigs))
+ .thenCallRealMethod();
+
+ var controller = mock(DroolsController.class);
+ doNothing().when(controller).updateToVersion(GROUP_ID, ARTIFACT_ID, VERSION, decoderConfigs, encoderConfigs);
+ when(controller.getVersion()).thenReturn(OTHER_VERSION);
+ Map<String, DroolsController> controllers = new HashMap<>();
+ controllers.put(GROUP_ID + ":" + ARTIFACT_ID, controller);
+ ReflectionTestUtils.setField(mockFactory, "droolsControllers", controllers);
+
+ assertNotNull(mockFactory.build(props, GROUP_ID, ARTIFACT_ID, VERSION, decoderConfigs, encoderConfigs));
+ }
+
+ @Test
+ void unmanage() {
+ assertThatThrownBy(() -> factory.unmanage(null))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("No controller provided");
+
+ var mockController = mock(DroolsController.class);
+ when(mockController.isBrained()).thenReturn(false)
+ .thenReturn(true).thenReturn(true);
+ when(mockController.getGroupId()).thenReturn(GROUP_ID);
+ when(mockController.getArtifactId()).thenReturn(ARTIFACT_ID);
+
+ var mockFactory = mock(IndexedDroolsControllerFactory.class);
+ doCallRealMethod().when(mockFactory).unmanage(mockController);
+ when(mockFactory.toString()).thenCallRealMethod();
+
+ Map<String, DroolsController> controllers = new HashMap<>();
+ controllers.put(GROUP_ID + ":" + ARTIFACT_ID, mockController);
+ ReflectionTestUtils.setField(mockFactory, "droolsControllers", controllers);
+
+ // should return after isBrained returns false
+ assertDoesNotThrow(() -> mockFactory.unmanage(mockController));
+ assertFalse(mockFactory.droolsControllers.isEmpty());
+ assertEquals("IndexedDroolsControllerFactory [#droolsControllers=1]", mockFactory.toString());
+
+ // should go ahead and remove controller from hash map
+ assertDoesNotThrow(() -> mockFactory.unmanage(mockController));
+ assertTrue(mockFactory.droolsControllers.isEmpty());
+ assertEquals("IndexedDroolsControllerFactory [#droolsControllers=0]", mockFactory.toString());
+
+ controllers.put("anotherKey", mockController);
+ ReflectionTestUtils.setField(mockFactory, "droolsControllers", controllers);
+
+ // should return after comparing the key in the hash map (does not match)
+ assertDoesNotThrow(() -> mockFactory.unmanage(mockController));
+ assertFalse(mockFactory.droolsControllers.isEmpty());
+ assertEquals("IndexedDroolsControllerFactory [#droolsControllers=1]", mockFactory.toString());
+ }
+
+ @Test
+ void shutdown() {
+ var mockController = mock(DroolsController.class);
+ doNothing().when(mockController).shutdown();
+
+ var mockFactory = mock(IndexedDroolsControllerFactory.class);
+ doNothing().when(mockFactory).unmanage(mockController);
+
+ assertDoesNotThrow(() -> mockFactory.shutdown(mockController));
+ }
+
+ @Test
+ void get_EmptyParameters() {
+ assertThatThrownBy(() -> factory.get("", ARTIFACT_ID, VERSION))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("Missing maven coordinates");
+ assertThatThrownBy(() -> factory.get(GROUP_ID, "", VERSION))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("Missing maven coordinates");
+ }
+} \ No newline at end of file
diff --git a/policy-management/src/test/java/org/onap/policy/drools/controller/internal/MavenDroolsControllerUpgradesTest.java b/policy-management/src/test/java/org/onap/policy/drools/controller/internal/MavenDroolsControllerUpgradesTest.java
index 38b38a8c..753296a8 100644
--- a/policy-management/src/test/java/org/onap/policy/drools/controller/internal/MavenDroolsControllerUpgradesTest.java
+++ b/policy-management/src/test/java/org/onap/policy/drools/controller/internal/MavenDroolsControllerUpgradesTest.java
@@ -88,7 +88,7 @@ public class MavenDroolsControllerUpgradesTest {
KieUtils.installArtifact(
Paths.get(DROOLS_RESOURCES_DIR + RULES_BASE + KMODULE_EXT).toFile(),
Paths.get(DROOLS_RESOURCES_DIR + name + POM_EXT).toFile(),
- DROOLS_KJAR_RESOURCES_DIR + KBNAME_RULES + "/" + KBPACKAGE_RULES + "/",
+ DROOLS_KJAR_RESOURCES_DIR + KBNAME_RULES + "/" + KBPACKAGE_RULES + "/",
drls);
}
@@ -105,8 +105,8 @@ public class MavenDroolsControllerUpgradesTest {
rulesDescriptor2 =
install("rules2",
Stream.of(path.toFile(),
- Paths.get(DROOLS_RESOURCES_DIR + "rules2" + DRL_EXT).toFile())
- .collect(Collectors.toList()));
+ Paths.get(DROOLS_RESOURCES_DIR + "rules2" + DRL_EXT).toFile())
+ .collect(Collectors.toList()));
LoggerUtils.setLevel("ROOT", "WARN");
LoggerUtils.setLevel("org.onap.policy.drools.controller.internal", "INFO");
@@ -169,13 +169,13 @@ public class MavenDroolsControllerUpgradesTest {
private void summary() {
logger.info("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
- logger.info("Controller: " + controller.getGroupId() + ":" + controller.getArtifactId()
- + ":" + controller.getVersion());
+ logger.info("Controller: {}:{}:{}", controller.getGroupId(), controller.getArtifactId(),
+ controller.getVersion());
logger.info(".....................................................................");
- logger.info("KIE-BASES: " + KieUtils.getBases(controller.getContainer().getKieContainer()));
- logger.info("KIE-PACKAGE-NAMES: " + KieUtils.getPackageNames(controller.getContainer().getKieContainer()));
- logger.info("KIE-RULE-NAMES: " + KieUtils.getRuleNames(controller.getContainer().getKieContainer()));
- logger.info("FACTS: " + controller.facts(KBSESSION_RULES, Object.class));
+ logger.info("KIE-BASES: {}", KieUtils.getBases(controller.getContainer().getKieContainer()));
+ logger.info("KIE-PACKAGE-NAMES: {}", KieUtils.getPackageNames(controller.getContainer().getKieContainer()));
+ logger.info("KIE-RULE-NAMES: {}", KieUtils.getRuleNames(controller.getContainer().getKieContainer()));
+ logger.info("FACTS: {}", controller.facts(KBSESSION_RULES, Object.class));
logger.info("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
}
@@ -190,25 +190,25 @@ public class MavenDroolsControllerUpgradesTest {
controller.getContainer()
.getPolicySession(KBSESSION_RULES)
.getKieSession()
- .addEventListener(new RuleRuntimeEventListener() {
- @Override
- public void objectInserted(ObjectInsertedEvent objectInsertedEvent) {
- logger.info("RULE {}: inserting {}",
- objectInsertedEvent.getRule().getName(), objectInsertedEvent.getObject());
- }
-
- @Override
- public void objectUpdated(ObjectUpdatedEvent objectUpdatedEvent) {
- logger.info("RULE {}: updating {}",
- objectUpdatedEvent.getRule().getName(), objectUpdatedEvent.getObject());
- }
-
- @Override
- public void objectDeleted(ObjectDeletedEvent objectDeletedEvent) {
- logger.info("RULE {}: deleting {}",
- objectDeletedEvent.getRule().getName(), objectDeletedEvent.getOldObject());
- }
- });
+ .addEventListener(new RuleRuntimeEventListener() {
+ @Override
+ public void objectInserted(ObjectInsertedEvent objectInsertedEvent) {
+ logger.info("RULE {}: inserting {}",
+ objectInsertedEvent.getRule().getName(), objectInsertedEvent.getObject());
+ }
+
+ @Override
+ public void objectUpdated(ObjectUpdatedEvent objectUpdatedEvent) {
+ logger.info("RULE {}: updating {}",
+ objectUpdatedEvent.getRule().getName(), objectUpdatedEvent.getObject());
+ }
+
+ @Override
+ public void objectDeleted(ObjectDeletedEvent objectDeletedEvent) {
+ logger.info("RULE {}: deleting {}",
+ objectDeletedEvent.getRule().getName(), objectDeletedEvent.getOldObject());
+ }
+ });
controller.getContainer()
.getPolicySession(KBSESSION_RULES)
diff --git a/policy-management/src/test/java/org/onap/policy/drools/controller/internal/NullDroolsControllerTest.java b/policy-management/src/test/java/org/onap/policy/drools/controller/internal/NullDroolsControllerTest.java
index f61412d9..ccefcc6f 100644
--- a/policy-management/src/test/java/org/onap/policy/drools/controller/internal/NullDroolsControllerTest.java
+++ b/policy-management/src/test/java/org/onap/policy/drools/controller/internal/NullDroolsControllerTest.java
@@ -22,6 +22,7 @@
package org.onap.policy.drools.controller.internal;
import static org.assertj.core.api.Assertions.assertThatCode;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
@@ -36,32 +37,35 @@ import org.onap.policy.drools.controller.DroolsControllerConstants;
class NullDroolsControllerTest {
+ private final NullDroolsController controller = new NullDroolsController();
+ private static final String NULL_EXCEPTION = "marked non-null but is null";
+
@Test
void testStart() {
- DroolsController controller = new NullDroolsController();
- controller.start();
- assertFalse(controller.isAlive());
- controller.stop();
- assertFalse(controller.isAlive());
- controller.shutdown();
- assertFalse(controller.isAlive());
- controller.halt();
- assertFalse(controller.isAlive());
+ DroolsController controller1 = new NullDroolsController();
+ controller1.start();
+ assertFalse(controller1.isAlive());
+ controller1.stop();
+ assertFalse(controller1.isAlive());
+ controller1.shutdown();
+ assertFalse(controller1.isAlive());
+ controller1.halt();
+ assertFalse(controller1.isAlive());
}
@Test
void testSerialize() {
assertThatCode(() -> new GsonTestUtils().compareGson(new NullDroolsController(),
- NullDroolsControllerTest.class)).doesNotThrowAnyException();
+ NullDroolsControllerTest.class)).doesNotThrowAnyException();
}
@Test
void testLock() {
- DroolsController controller = new NullDroolsController();
- controller.lock();
- assertFalse(controller.isLocked());
- controller.unlock();
- assertFalse(controller.isLocked());
+ DroolsController controller1 = new NullDroolsController();
+ controller1.lock();
+ assertFalse(controller1.isLocked());
+ controller1.unlock();
+ assertFalse(controller1.isLocked());
}
@Test
@@ -81,78 +85,75 @@ class NullDroolsControllerTest {
@Test
void getSessionNames() {
- assertTrue(new NullDroolsController().getSessionNames().isEmpty());
+ assertTrue(controller.getSessionNames().isEmpty());
}
@Test
void getCanonicalSessionNames() {
- assertTrue(new NullDroolsController().getCanonicalSessionNames().isEmpty());
+ assertTrue(controller.getCanonicalSessionNames().isEmpty());
}
@Test
void offer() {
- assertFalse(new NullDroolsController().offer(null, null));
+ assertFalse(controller.offer(null, null));
+ assertFalse(controller.offer(null));
}
@Test
void deliver() {
- var controller = new NullDroolsController();
assertThrows(IllegalStateException.class, () -> controller.deliver(null, null));
}
@Test
void getRecentSourceEvents() {
- assertEquals(0, new NullDroolsController().getRecentSourceEvents().length);
+ assertEquals(0, controller.getRecentSourceEvents().length);
}
@Test
void getRecentSinkEvents() {
- assertEquals(0, new NullDroolsController().getRecentSinkEvents().length);
+ assertEquals(0, controller.getRecentSinkEvents().length);
}
@Test
void getContainer() {
- assertNull(new NullDroolsController().getContainer());
+ assertNull(controller.getContainer());
}
@Test
void getDomains() {
- assertTrue(new NullDroolsController().getBaseDomainNames().isEmpty());
+ assertTrue(controller.getBaseDomainNames().isEmpty());
}
@Test
void ownsCoder() {
- var controller = new NullDroolsController();
assertThrows(IllegalStateException.class, () -> controller.ownsCoder(null, 0));
}
@Test
void fetchModelClass() {
- var controller = new NullDroolsController();
var className = this.getClass().getName();
assertThrows(IllegalArgumentException.class, () -> controller.fetchModelClass(className));
}
@Test
void isBrained() {
- assertFalse(new NullDroolsController().isBrained());
+ assertFalse(controller.isBrained());
}
@Test
void stringify() {
- assertNotNull(new NullDroolsController().toString());
+ assertNotNull(controller.toString());
}
@Test
void updateToVersion() {
- var controller = new NullDroolsController();
assertThrows(IllegalArgumentException.class, () ->
controller.updateToVersion(null, null, null, null, null));
}
@Test
void factClassNames() {
- assertTrue(new NullDroolsController().factClassNames(null).isEmpty());
+ assertTrue(controller.factClassNames(null).isEmpty());
}
@Test
@@ -162,18 +163,40 @@ class NullDroolsControllerTest {
@Test
void facts() {
- assertTrue(new NullDroolsController().facts(null, null, true).isEmpty());
+ assertTrue(controller.facts(null, null, true).isEmpty());
+ assertTrue(controller.facts("sessionName", Object.class).isEmpty());
+
+ assertThatThrownBy(() -> controller.facts(null, Object.class)).hasMessageContaining(NULL_EXCEPTION);
+ assertThatThrownBy(() -> controller.facts("sessionName", null)).hasMessageContaining(NULL_EXCEPTION);
}
@Test
void factQuery() {
- assertTrue(new NullDroolsController().factQuery(null, null, null, false).isEmpty());
+ assertTrue(controller.factQuery(null, null, null, false).isEmpty());
}
@Test
void exists() {
Object o1 = new Object();
- assertFalse(new NullDroolsController().exists("blah", o1));
- assertFalse(new NullDroolsController().exists(o1));
+ assertFalse(controller.exists("blah", o1));
+ assertFalse(controller.exists(o1));
+
+ assertThatThrownBy(() -> controller.exists("blah", null)).hasMessageContaining(NULL_EXCEPTION);
+ assertThatThrownBy(() -> controller.exists(null, o1)).hasMessageContaining(NULL_EXCEPTION);
+ assertThatThrownBy(() -> controller.exists(null)).hasMessageContaining(NULL_EXCEPTION);
+ }
+
+ @Test
+ void testDelete() {
+ assertThatThrownBy(() -> controller.delete("sessionName", null)).hasMessageContaining(NULL_EXCEPTION);
+ assertThatThrownBy(() -> controller.delete(null, Object.class)).hasMessageContaining(NULL_EXCEPTION);
+ assertThatThrownBy(() -> controller.delete(null)).hasMessageContaining(NULL_EXCEPTION);
+ Object o1 = null;
+ assertThatThrownBy(() -> controller.delete(o1)).hasMessageContaining(NULL_EXCEPTION);
+
+ assertFalse(controller.delete("sessionName", new Object()));
+ assertFalse(controller.delete("sessionName", Object.class));
+ assertFalse(controller.delete(new Object()));
+ assertFalse(controller.delete(Object.class));
}
}
diff --git a/policy-management/src/test/java/org/onap/policy/drools/features/DroolsControllerFeatureApiTest.java b/policy-management/src/test/java/org/onap/policy/drools/features/DroolsControllerFeatureApiTest.java
new file mode 100644
index 00000000..83171dae
--- /dev/null
+++ b/policy-management/src/test/java/org/onap/policy/drools/features/DroolsControllerFeatureApiTest.java
@@ -0,0 +1,83 @@
+/*-
+ * ============LICENSE_START===============================================
+ * ONAP
+ * ========================================================================
+ * 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.
+ * 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.drools.features;
+
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNull;
+
+import java.util.Collections;
+import java.util.Properties;
+import org.junit.jupiter.api.Test;
+import org.onap.policy.common.endpoints.event.comm.TopicSink;
+import org.onap.policy.drools.controller.DroolsController;
+
+/**
+ * DroolsControllerFeatureApi is implemented in other modules, therefore, coverage is not coming up in this module.
+ * This class has no intention of unit testing features, sole goal is raise coverage.
+ */
+class DroolsControllerFeatureApiTest {
+
+ DroolsControllerFeatureApi testClass = new TestDroolsControllerFeatureApi();
+ Properties props = new Properties();
+ DroolsController controller;
+ TopicSink sink;
+ Object fact;
+
+ @Test
+ void beforeInstance() {
+ assertNull(testClass.beforeInstance(props, "group", "artifact", "version",
+ Collections.emptyList(), Collections.emptyList()));
+ }
+
+ @Test
+ void afterInstance() {
+ assertFalse(testClass.afterInstance(controller, props));
+ }
+
+ @Test
+ void beforeInsert() {
+ assertFalse(testClass.beforeInsert(controller, props));
+ }
+
+ @Test
+ void afterInsert() {
+ assertFalse(testClass.afterInsert(controller, fact, false));
+ }
+
+ @Test
+ void beforeDeliver() {
+ assertFalse(testClass.beforeDeliver(controller, sink, fact));
+ }
+
+ @Test
+ void afterDeliver() {
+ assertFalse(testClass.afterDeliver(controller, sink, fact, "json", false));
+ }
+
+ static class TestDroolsControllerFeatureApi implements DroolsControllerFeatureApi {
+
+ @Override
+ public int getSequenceNumber() {
+ return 30;
+ }
+ }
+} \ No newline at end of file
diff --git a/policy-management/src/test/java/org/onap/policy/drools/features/PolicyControllerFeatureApiTest.java b/policy-management/src/test/java/org/onap/policy/drools/features/PolicyControllerFeatureApiTest.java
new file mode 100644
index 00000000..f48bf937
--- /dev/null
+++ b/policy-management/src/test/java/org/onap/policy/drools/features/PolicyControllerFeatureApiTest.java
@@ -0,0 +1,171 @@
+/*-
+ * ============LICENSE_START===============================================
+ * ONAP
+ * ========================================================================
+ * 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.
+ * 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.drools.features;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure.NOOP;
+
+import java.util.Properties;
+import org.junit.jupiter.api.Test;
+import org.onap.policy.drools.protocol.configuration.DroolsConfiguration;
+import org.onap.policy.drools.system.PolicyController;
+
+/**
+ * PolicyControllerFeatureApi is implemented in other modules, therefore, coverage is not coming up in this module.
+ * This class has no intention of unit testing features, sole goal is raise coverage.
+ */
+class PolicyControllerFeatureApiTest {
+
+ PolicyControllerFeatureApi testClass = new TestPolicyControllerFeatureApi();
+ Properties props = new Properties();
+ PolicyController controller;
+ DroolsConfiguration configuration;
+
+
+ @Test
+ void beforeCreate() {
+ assertNull(testClass.beforeCreate("name", props));
+ }
+
+ @Test
+ void afterCreate() {
+ assertFalse(testClass.afterCreate(controller));
+ }
+
+ @Test
+ void beforeInstance() {
+ assertNull(testClass.beforeInstance("name", props));
+ }
+
+ @Test
+ void afterInstance() {
+ assertFalse(testClass.afterInstance(controller, props));
+ }
+
+ @Test
+ void beforeStart() {
+ assertFalse(testClass.beforeStart(controller));
+ }
+
+ @Test
+ void afterStart() {
+ assertFalse(testClass.afterStart(controller));
+ }
+
+ @Test
+ void beforeStop() {
+ assertFalse(testClass.beforeStop(controller));
+ }
+
+ @Test
+ void afterStop() {
+ assertFalse(testClass.afterStop(controller));
+ }
+
+ @Test
+ void beforePatch() {
+ assertFalse(testClass.beforePatch(controller, configuration, configuration));
+ }
+
+ @Test
+ void afterPatch() {
+ assertFalse(testClass.afterPatch(controller, configuration, configuration, true));
+ }
+
+ @Test
+ void beforeLock() {
+ assertFalse(testClass.beforeLock(controller));
+ }
+
+ @Test
+ void afterLock() {
+ assertFalse(testClass.afterLock(controller));
+ }
+
+ @Test
+ void beforeUnlock() {
+ assertFalse(testClass.beforeUnlock(controller));
+ }
+
+ @Test
+ void afterUnlock() {
+ assertFalse(testClass.afterUnlock(controller));
+ }
+
+ @Test
+ void beforeShutdown() {
+ assertFalse(testClass.beforeShutdown(controller));
+ }
+
+ @Test
+ void afterShutdown() {
+ assertFalse(testClass.afterShutdown(controller));
+ }
+
+ @Test
+ void beforeHalt() {
+ assertFalse(testClass.beforeHalt(controller));
+ }
+
+ @Test
+ void afterHalt() {
+ assertFalse(testClass.afterHalt(controller));
+ }
+
+ @Test
+ void beforeOffer() {
+ assertFalse(testClass.beforeOffer(controller, new Object()));
+ }
+
+ @Test
+ void testBeforeOffer() {
+ assertFalse(testClass.beforeOffer(controller, NOOP, "topic", "event"));
+ }
+
+ @Test
+ void afterOffer() {
+ assertFalse(testClass.afterOffer(controller, new Object(), true));
+ }
+
+ @Test
+ void testAfterOffer() {
+ assertFalse(testClass.afterOffer(controller, NOOP, "topic", "event", true));
+ }
+
+ @Test
+ void beforeDeliver() {
+ assertFalse(testClass.beforeDeliver(controller, NOOP, "topic", "event"));
+ }
+
+ @Test
+ void afterDeliver() {
+ assertFalse(testClass.afterDeliver(controller, NOOP, "topic", "event", true));
+ }
+
+ static class TestPolicyControllerFeatureApi implements PolicyControllerFeatureApi {
+
+ @Override
+ public int getSequenceNumber() {
+ return 20;
+ }
+ }
+} \ No newline at end of file
diff --git a/policy-management/src/test/java/org/onap/policy/drools/features/PolicyEngineFeatureApiTest.java b/policy-management/src/test/java/org/onap/policy/drools/features/PolicyEngineFeatureApiTest.java
new file mode 100644
index 00000000..90feeb20
--- /dev/null
+++ b/policy-management/src/test/java/org/onap/policy/drools/features/PolicyEngineFeatureApiTest.java
@@ -0,0 +1,174 @@
+/*-
+ * ============LICENSE_START===============================================
+ * ONAP
+ * ========================================================================
+ * 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.
+ * 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.drools.features;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.mockito.Mockito.mock;
+
+import java.util.Properties;
+import org.junit.jupiter.api.Test;
+import org.onap.policy.common.endpoints.event.comm.Topic;
+import org.onap.policy.drools.core.lock.PolicyResourceLockManager;
+import org.onap.policy.drools.protocol.configuration.PdpdConfiguration;
+import org.onap.policy.drools.system.PolicyEngine;
+
+/**
+ * PolicyEngineFeatureApi is implemented in other modules, therefore, coverage is not coming up in this module.
+ * This class has no intention of unit testing features, sole goal is raise coverage.
+ */
+class PolicyEngineFeatureApiTest {
+
+ PolicyEngineFeatureApi testClass = new TestPolicyEngineFeatureApi();
+
+ PolicyEngine policyEngine = mock(PolicyEngine.class);
+ Properties props = new Properties();
+
+ @Test
+ void beforeBoot() {
+ assertFalse(testClass.beforeBoot(policyEngine, new String[] {"a", "b"}));
+ }
+
+ @Test
+ void afterBoot() {
+ assertFalse(testClass.afterBoot(policyEngine));
+ }
+
+ @Test
+ void beforeConfigure() {
+ assertFalse(testClass.beforeConfigure(policyEngine, props));
+ }
+
+ @Test
+ void afterConfigure() {
+ assertFalse(testClass.afterConfigure(policyEngine));
+ }
+
+ @Test
+ void beforeActivate() {
+ assertFalse(testClass.beforeActivate(policyEngine));
+ }
+
+ @Test
+ void afterActivate() {
+ assertFalse(testClass.afterActivate(policyEngine));
+ }
+
+ @Test
+ void beforeDeactivate() {
+ assertFalse(testClass.beforeDeactivate(policyEngine));
+ }
+
+ @Test
+ void afterDeactivate() {
+ assertFalse(testClass.afterDeactivate(policyEngine));
+ }
+
+ @Test
+ void beforeStart() {
+ assertFalse(testClass.beforeStart(policyEngine));
+ }
+
+ @Test
+ void afterStart() {
+ assertFalse(testClass.afterStart(policyEngine));
+ }
+
+ @Test
+ void beforeStop() {
+ assertFalse(testClass.beforeStop(policyEngine));
+ }
+
+ @Test
+ void afterStop() {
+ assertFalse(testClass.afterStop(policyEngine));
+ }
+
+ @Test
+ void beforeLock() {
+ assertFalse(testClass.beforeLock(policyEngine));
+ }
+
+ @Test
+ void afterLock() {
+ assertFalse(testClass.afterLock(policyEngine));
+ }
+
+ @Test
+ void beforeUnlock() {
+ assertFalse(testClass.beforeUnlock(policyEngine));
+ }
+
+ @Test
+ void afterUnlock() {
+ assertFalse(testClass.afterUnlock(policyEngine));
+ }
+
+ @Test
+ void beforeShutdown() {
+ assertFalse(testClass.beforeShutdown(policyEngine));
+ }
+
+ @Test
+ void afterShutdown() {
+ assertFalse(testClass.afterShutdown(policyEngine));
+ }
+
+ @Test
+ void beforeOnTopicEvent() {
+ assertFalse(testClass.beforeOnTopicEvent(policyEngine, Topic.CommInfrastructure.NOOP, "topic", "event"));
+ }
+
+ @Test
+ void afterOnTopicEvent() {
+ assertFalse(testClass.afterOnTopicEvent(policyEngine, mock(PdpdConfiguration.class),
+ Topic.CommInfrastructure.NOOP, "topic", "event"));
+ }
+
+ @Test
+ void beforeOpen() {
+ assertFalse(testClass.beforeOpen(policyEngine));
+ }
+
+ @Test
+ void afterOpen() {
+ assertFalse(testClass.afterOpen(policyEngine));
+ }
+
+ @Test
+ void beforeCreateLockManager() {
+ assertNull(testClass.beforeCreateLockManager());
+ }
+
+ @Test
+ void afterCreateLockManager() {
+ assertFalse(testClass.afterCreateLockManager(policyEngine, props, mock(PolicyResourceLockManager.class)));
+ }
+
+ static class TestPolicyEngineFeatureApi implements PolicyEngineFeatureApi {
+
+ @Override
+ public int getSequenceNumber() {
+ return 10;
+ }
+
+ }
+} \ No newline at end of file
diff --git a/policy-management/src/test/java/org/onap/policy/drools/persistence/FileSystemPersistenceTest.java b/policy-management/src/test/java/org/onap/policy/drools/persistence/FileSystemPersistenceTest.java
new file mode 100644
index 00000000..80a8dc6b
--- /dev/null
+++ b/policy-management/src/test/java/org/onap/policy/drools/persistence/FileSystemPersistenceTest.java
@@ -0,0 +1,78 @@
+/*-
+ * ============LICENSE_START===============================================
+ * ONAP
+ * ========================================================================
+ * 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.
+ * 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.drools.persistence;
+
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import java.nio.file.Path;
+import org.junit.jupiter.api.Test;
+
+class FileSystemPersistenceTest {
+
+ FileSystemPersistence persistence = new FileSystemPersistence();
+
+ @Test
+ void testSetConfiguration_FileIsNotDirectory() {
+ persistence.configurationPath = Path.of("src/test/resources/echo.drl");
+ assertThrows(IllegalStateException.class, () -> persistence.setConfigurationDir());
+ assertThatThrownBy(() -> persistence.setConfigurationDir())
+ .hasMessageContaining("config directory: src/test/resources/echo.drl is not a directory");
+ }
+
+ @Test
+ void testSetConfiguration_InvalidDir() {
+ persistence.configurationPath = Path.of("/opt/path"); // opt path needs sudo
+ assertThrows(IllegalStateException.class, () -> persistence.setConfigurationDir());
+ assertThatThrownBy(() -> persistence.setConfigurationDir())
+ .hasMessageContaining("cannot create /opt/path");
+ }
+
+ @Test
+ void testGetProperties_Exception() {
+ assertThatThrownBy(() -> persistence.getProperties(""))
+ .hasMessageContaining("properties name must be provided");
+
+ String propName = null;
+ assertThatThrownBy(() -> persistence.getProperties(propName)) // for code coverage
+ .hasMessageContaining("properties name must be provided");
+ }
+
+ @Test
+ void testGetEnvironmentProperties_Exception() {
+ assertThatThrownBy(() -> persistence.getEnvironmentProperties(""))
+ .hasMessageContaining("environment name must be provided");
+
+ String propName = null;
+ assertThatThrownBy(() -> persistence.getEnvironmentProperties(propName)) // for code coverage
+ .hasMessageContaining("environment name must be provided");
+ }
+
+ @Test
+ void testGetProperties_ByPathException() {
+ assertThatThrownBy(() -> persistence.getProperties(Path.of("/path/does/not/exist.properties")))
+ .hasMessageContaining("properties for /path/does/not/exist.properties are not persisted.");
+
+ Path pathProps = null;
+ assertThatThrownBy(() -> persistence.getProperties(pathProps)) // for code coverage
+ .hasMessageContaining("propertiesPath is marked non-null but is null");
+ }
+}
diff --git a/policy-management/src/test/java/org/onap/policy/drools/protocol/coders/EventProtocolCoderTest.java b/policy-management/src/test/java/org/onap/policy/drools/protocol/coders/EventProtocolCoderTest.java
index 6d461eef..c98467ea 100644
--- a/policy-management/src/test/java/org/onap/policy/drools/protocol/coders/EventProtocolCoderTest.java
+++ b/policy-management/src/test/java/org/onap/policy/drools/protocol/coders/EventProtocolCoderTest.java
@@ -22,6 +22,7 @@
package org.onap.policy.drools.protocol.coders;
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.util.Properties;
@@ -88,4 +89,30 @@ class EventProtocolCoderTest {
EventProtocolCoderConstants.getManager().removeEncoders(ENCODER_GROUP, ENCODER_ARTIFACT, NOOP_TOPIC);
}
+
+ @Test
+ void test_extra() {
+ final Properties noopSinkProperties = new Properties();
+ noopSinkProperties.put(PolicyEndPointProperties.PROPERTY_NOOP_SINK_TOPICS, NOOP_TOPIC);
+
+ TopicEndpointManager.getManager().addTopicSinks(noopSinkProperties);
+
+ var encoder = EventProtocolParams.builder().groupId(ENCODER_GROUP).artifactId(ENCODER_ARTIFACT)
+ .topic(NOOP_TOPIC).eventClass(DroolsConfiguration.class.getName())
+ .protocolFilter(new JsonProtocolFilter()).customGsonCoder(null)
+ .modelClassLoaderHash(DroolsConfiguration.class.getName().hashCode()).build();
+
+ EventProtocolCoderConstants.getManager().addEncoder(encoder);
+
+ final String json = EventProtocolCoderConstants.getManager().encode(NOOP_TOPIC,
+ new DroolsConfiguration(ENCODER_ARTIFACT, ENCODER_GROUP, ENCODER_VERSION));
+
+ assertTrue(json.contains(ENCODER_GROUP));
+ assertTrue(json.contains(ENCODER_ARTIFACT));
+
+ // check if adding same encoder doesn't throw any exceptions as expected
+ assertDoesNotThrow(() -> EventProtocolCoderConstants.getManager().addEncoder(encoder));
+ EventProtocolCoderConstants.getManager().removeEncoders(ENCODER_GROUP, ENCODER_ARTIFACT, NOOP_TOPIC);
+ EventProtocolCoderConstants.getManager().removeEncoders("NotExistentGroup", ENCODER_ARTIFACT, NOOP_TOPIC);
+ }
}
diff --git a/policy-management/src/test/java/org/onap/policy/drools/protocol/coders/GenericProtocolCoderTest.java b/policy-management/src/test/java/org/onap/policy/drools/protocol/coders/GenericProtocolCoderTest.java
new file mode 100644
index 00000000..7a8be59e
--- /dev/null
+++ b/policy-management/src/test/java/org/onap/policy/drools/protocol/coders/GenericProtocolCoderTest.java
@@ -0,0 +1,651 @@
+/*-
+ * ============LICENSE_START===============================================
+ * ONAP
+ * ========================================================================
+ * 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.
+ * 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.drools.protocol.coders;
+
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doCallRealMethod;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import org.junit.jupiter.api.Test;
+import org.mockito.MockedStatic;
+import org.mockito.Mockito;
+import org.onap.policy.drools.controller.DroolsController;
+import org.onap.policy.drools.controller.DroolsControllerConstants;
+import org.onap.policy.drools.controller.DroolsControllerFactory;
+import org.onap.policy.drools.controller.internal.NullDroolsController;
+import org.springframework.test.util.ReflectionTestUtils;
+
+class GenericProtocolCoderTest {
+
+ EventProtocolEncoder encoder = new EventProtocolEncoder();
+ EventProtocolDecoder decoder = new EventProtocolDecoder();
+
+ private static final String GROUP_ID = "groupId";
+ private static final String ARTIFACT_ID = "artifactId";
+ private static final String TOPIC = "topic";
+ private static final String VALID_KEY = GROUP_ID + ":" + ARTIFACT_ID + ":" + TOPIC;
+ private static final String INVALID_KEY = "anotherKey";
+
+ @Test
+ void testAdd_ReverseCoder() {
+ var params = new EventProtocolParams(GROUP_ID, ARTIFACT_ID, TOPIC, "java.lang.Object",
+ mock(JsonProtocolFilter.class), mock(TopicCoderFilterConfiguration.CustomGsonCoder.class), 1);
+
+ var myKey = "group:artifact:topic";
+
+ var mockEncoder = mock(EventProtocolEncoder.class);
+ // set the key to be returned when checking the hash maps
+ when(mockEncoder.codersKey(GROUP_ID, ARTIFACT_ID, TOPIC)).thenReturn(myKey);
+ when(mockEncoder.reverseCodersKey(GROUP_ID, "java.lang.Object")).thenReturn(myKey);
+ doCallRealMethod().when(mockEncoder).add(params);
+
+
+ // create the hash maps for coders/reverseCoders
+ var toolset = mock(ProtocolCoderToolset.class);
+ HashMap<String, ProtocolCoderToolset> coders = new HashMap<>();
+ coders.put(myKey, toolset);
+ ReflectionTestUtils.setField(mockEncoder, "coders", coders);
+ HashMap<String, List<ProtocolCoderToolset>> reverseCoders = new HashMap<>();
+ reverseCoders.put("group:javaClass", new ArrayList<>(List.of(toolset)));
+ ReflectionTestUtils.setField(mockEncoder, "reverseCoders", reverseCoders);
+
+ assertDoesNotThrow(() -> mockEncoder.add(params));
+ assertEquals(2, mockEncoder.reverseCoders.size());
+ assertEquals(1, mockEncoder.coders.size());
+ }
+
+ @Test
+ void testAdd_InvalidParams_GroupId() {
+ var mockEventProtocolsParams = mock(EventProtocolParams.class);
+ when(mockEventProtocolsParams.getGroupId()).thenReturn(null);
+
+ assertThatThrownBy(() -> encoder.add(mockEventProtocolsParams))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("Invalid group id");
+
+ when(mockEventProtocolsParams.getGroupId()).thenReturn("");
+
+ assertThatThrownBy(() -> encoder.add(mockEventProtocolsParams))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("Invalid group id");
+ }
+
+ @Test
+ void testAdd_InvalidParams_ArtifactId() {
+ var mockEventProtocolsParams = mock(EventProtocolParams.class);
+ when(mockEventProtocolsParams.getGroupId()).thenReturn(GROUP_ID);
+ when(mockEventProtocolsParams.getArtifactId()).thenReturn(null);
+
+ assertThatThrownBy(() -> encoder.add(mockEventProtocolsParams))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("Invalid artifact id");
+
+ when(mockEventProtocolsParams.getArtifactId()).thenReturn("");
+
+ assertThatThrownBy(() -> encoder.add(mockEventProtocolsParams))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("Invalid artifact id");
+ }
+
+ @Test
+ void testAdd_InvalidParams_Topic() {
+ var mockEventProtocolsParams = mock(EventProtocolParams.class);
+ when(mockEventProtocolsParams.getGroupId()).thenReturn(GROUP_ID);
+ when(mockEventProtocolsParams.getArtifactId()).thenReturn(ARTIFACT_ID);
+ when(mockEventProtocolsParams.getTopic()).thenReturn(null);
+
+ assertThatThrownBy(() -> encoder.add(mockEventProtocolsParams))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("Invalid Topic");
+
+ when(mockEventProtocolsParams.getGroupId()).thenReturn(GROUP_ID);
+ when(mockEventProtocolsParams.getArtifactId()).thenReturn(ARTIFACT_ID);
+ when(mockEventProtocolsParams.getTopic()).thenReturn("");
+
+ assertThatThrownBy(() -> encoder.add(mockEventProtocolsParams))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("Invalid Topic");
+ }
+
+ @Test
+ void testAdd_InvalidParams_EventClass() {
+ var mockEventProtocolsParams = mock(EventProtocolParams.class);
+ when(mockEventProtocolsParams.getGroupId()).thenReturn(GROUP_ID);
+ when(mockEventProtocolsParams.getArtifactId()).thenReturn(ARTIFACT_ID);
+ when(mockEventProtocolsParams.getTopic()).thenReturn(TOPIC);
+ when(mockEventProtocolsParams.getEventClass()).thenReturn(null);
+
+ assertThatThrownBy(() -> encoder.add(mockEventProtocolsParams))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("Invalid Event Class");
+ }
+
+ @Test
+ void testDecode_Exceptions() {
+ var mockDecoder = mock(EventProtocolDecoder.class);
+ when(mockDecoder.isCodingSupported(GROUP_ID, ARTIFACT_ID, TOPIC))
+ .thenReturn(false);
+ when(mockDecoder.decode(GROUP_ID, ARTIFACT_ID, TOPIC, null))
+ .thenCallRealMethod();
+ when(mockDecoder.codersKey(GROUP_ID, ARTIFACT_ID, TOPIC))
+ .thenCallRealMethod();
+
+ assertThatThrownBy(() -> mockDecoder.decode(GROUP_ID, ARTIFACT_ID, TOPIC, null))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("Unsupported: groupId:artifactId:topic for encoding");
+ }
+
+ @Test
+ void testDecode_ExceptionCantDecode() {
+ var mockDecoder = mock(EventProtocolDecoder.class);
+
+ HashMap<String, ProtocolCoderToolset> coders = new HashMap<>();
+ var params = mock(EventProtocolParams.class);
+ coders.put("groupId:artifactId:topic", new GsonProtocolCoderToolset(params, "controllerId"));
+ ReflectionTestUtils.setField(mockDecoder, "coders", coders);
+
+ when(mockDecoder.isCodingSupported(GROUP_ID, ARTIFACT_ID, TOPIC))
+ .thenReturn(true);
+ when(mockDecoder.decode(GROUP_ID, ARTIFACT_ID, TOPIC, null))
+ .thenCallRealMethod();
+ when(mockDecoder.codersKey(GROUP_ID, ARTIFACT_ID, TOPIC))
+ .thenCallRealMethod();
+
+ assertThatThrownBy(() -> mockDecoder.decode(GROUP_ID, ARTIFACT_ID, TOPIC, null))
+ .isInstanceOf(UnsupportedOperationException.class)
+ .hasMessageContaining("Cannot decode with gson");
+ }
+
+ @Test
+ void testDecode_Decode() {
+ var mockDecoder = mock(EventProtocolDecoder.class);
+ var myKey = "groupId:artifactId:topic";
+ var json = "{\"json\":\"true\"}";
+
+ HashMap<String, ProtocolCoderToolset> coders = new HashMap<>();
+ var mockToolset = mock(ProtocolCoderToolset.class);
+ when(mockToolset.decode(json))
+ .thenReturn(new Object()) // success case
+ .thenReturn(null); // failure case
+
+ coders.put(myKey, mockToolset);
+ ReflectionTestUtils.setField(mockDecoder, "coders", coders);
+
+ when(mockDecoder.isCodingSupported(GROUP_ID, ARTIFACT_ID, TOPIC)).thenReturn(true);
+ when(mockDecoder.codersKey(GROUP_ID, ARTIFACT_ID, TOPIC)).thenReturn(myKey);
+ when(mockDecoder.decode(GROUP_ID, ARTIFACT_ID, TOPIC, json))
+ .thenCallRealMethod();
+
+ assertNotNull(mockDecoder.decode(GROUP_ID, ARTIFACT_ID, TOPIC, json));
+
+ assertThatThrownBy(() -> mockDecoder.decode(GROUP_ID, ARTIFACT_ID, TOPIC, json))
+ .isInstanceOf(UnsupportedOperationException.class)
+ .hasMessageContaining("Cannot decode with gson");
+ }
+
+ @Test
+ void testEncode_WithGroupArtifactTopicAndEvent() {
+ var mockEncoder = mock(EventProtocolEncoder.class);
+ var event = new Object();
+ when(mockEncoder.isCodingSupported(GROUP_ID, ARTIFACT_ID, TOPIC))
+ .thenReturn(false);
+ when(mockEncoder.encode(GROUP_ID, ARTIFACT_ID, TOPIC, event))
+ .thenCallRealMethod();
+ when(mockEncoder.codersKey(GROUP_ID, ARTIFACT_ID, TOPIC))
+ .thenCallRealMethod();
+
+ assertThatThrownBy(() -> mockEncoder.encode(GROUP_ID, ARTIFACT_ID, TOPIC, event))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("Unsupported: groupId:artifactId:topic");
+
+ // test with event null
+ when(mockEncoder.isCodingSupported(GROUP_ID, ARTIFACT_ID, TOPIC))
+ .thenReturn(true);
+ when(mockEncoder.codersKey(GROUP_ID, ARTIFACT_ID, TOPIC))
+ .thenCallRealMethod();
+ when(mockEncoder.encode(GROUP_ID, ARTIFACT_ID, TOPIC, null))
+ .thenCallRealMethod();
+
+ assertThatThrownBy(() -> mockEncoder.encode(GROUP_ID, ARTIFACT_ID, TOPIC, null))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("Event cannot be null or empty");
+ }
+
+ @Test
+ void testEncode_WithGroupArtifactTopicAndEvent_ReturnJson() {
+ var mockEncoder = mock(EventProtocolEncoder.class);
+ var event = new Object();
+ var myKey = "group:artifact:topic";
+
+ // test with event null
+ when(mockEncoder.isCodingSupported(GROUP_ID, ARTIFACT_ID, TOPIC)).thenReturn(true);
+ when(mockEncoder.codersKey(GROUP_ID, ARTIFACT_ID, TOPIC)).thenReturn(myKey);
+ when(mockEncoder.encode(GROUP_ID, ARTIFACT_ID, TOPIC, event)).thenCallRealMethod();
+ when(mockEncoder.encodeInternal(myKey, event)).thenCallRealMethod();
+
+ var mockToolset = mock(ProtocolCoderToolset.class);
+ when(mockToolset.encode(event)).thenReturn("{\"json\":\"true\"}");
+
+ HashMap<String, ProtocolCoderToolset> coders = new HashMap<>();
+ coders.put(myKey, mockToolset);
+ ReflectionTestUtils.setField(mockEncoder, "coders", coders);
+
+ var result = mockEncoder.encode(GROUP_ID, ARTIFACT_ID, TOPIC, event);
+ assertNotNull(result);
+ assertEquals("{\"json\":\"true\"}", result);
+ }
+
+ @Test
+ void testEncode_WithTopicAndEvent() {
+ var event = new Object();
+
+ assertThatThrownBy(() -> encoder.encode(null, event))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("Invalid Topic");
+
+ assertThatThrownBy(() -> encoder.encode("", event))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("Invalid Topic");
+
+ assertThatThrownBy(() -> encoder.encode(TOPIC, null))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("Event cannot be null or empty");
+
+ assertThatThrownBy(() -> encoder.encode(TOPIC, event))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("no reverse coder has been found");
+ }
+
+ @Test
+ void testEncode_WithTopicEncodedClassAndDroolsController() {
+ var encodedClass = new Object();
+ var droolsController = new NullDroolsController();
+
+ assertThatThrownBy(() -> encoder.encode(null, encodedClass, droolsController))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("Invalid Topic");
+
+ assertThatThrownBy(() -> encoder.encode("", encodedClass, droolsController))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("Invalid Topic");
+
+ assertThatThrownBy(() -> encoder.encode(TOPIC, null, droolsController))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("Invalid encoded class");
+
+ assertThatThrownBy(() -> encoder.encode(TOPIC, encodedClass, droolsController))
+ .isInstanceOf(UnsupportedOperationException.class)
+ .hasMessageContaining("Cannot encode with gson");
+ }
+
+ @Test
+ void testEncode_WithTopicEncodedClassAndDroolsController_ReturnNullJson() {
+ var encodedClass = new Object();
+ var droolsController = new NullDroolsController();
+ var mockCoderTools = mock(ProtocolCoderToolset.class);
+ when(mockCoderTools.encode(encodedClass)).thenReturn(null);
+
+ var mockEncoder = mock(EventProtocolEncoder.class);
+ when(mockEncoder.codersKey(anyString(), anyString(), anyString())).thenReturn("myKey");
+ when(mockEncoder.encodeInternal("myKey", encodedClass)).thenCallRealMethod();
+ when(mockEncoder.encode(TOPIC, encodedClass, droolsController)).thenCallRealMethod();
+
+ HashMap<String, ProtocolCoderToolset> coders = new HashMap<>();
+ coders.put("myKey", mockCoderTools);
+ ReflectionTestUtils.setField(mockEncoder, "coders", coders);
+
+ assertThatThrownBy(() -> mockEncoder.encode(TOPIC, encodedClass, droolsController))
+ .isInstanceOf(UnsupportedOperationException.class)
+ .hasMessageContaining("Cannot encode with gson");
+ }
+
+ @Test
+ void droolsCreators() {
+ var encodedClass = new Object();
+ assertTrue(encoder.droolsCreators(TOPIC, encodedClass).isEmpty());
+ }
+
+ @Test
+ void droolsCreators_ContainsReverseKey() {
+ var encodedClass = new Object();
+ var mockDecoder = mock(EventProtocolDecoder.class);
+ when(mockDecoder.droolsCreators(TOPIC, encodedClass)).thenCallRealMethod();
+ when(mockDecoder.reverseCodersKey(TOPIC, encodedClass.getClass().getName()))
+ .thenReturn("topic:java.lang.Object");
+
+ HashMap<String, List<ProtocolCoderToolset>> reverseCoders = new HashMap<>();
+ reverseCoders.put("topic:java.lang.Object", List.of());
+ ReflectionTestUtils.setField(mockDecoder, "reverseCoders", reverseCoders);
+
+ assertThatThrownBy(() -> mockDecoder.droolsCreators(TOPIC, encodedClass))
+ .isInstanceOf(IllegalStateException.class)
+ .hasMessageContaining("No Encoders toolsets available for topic:java.lang.Object");
+ }
+
+ @Test
+ void droolsCreators_ContainsReverseKey_ReturnControllers() {
+ var encodedClass = new Object();
+ var mockDecoder = mock(EventProtocolDecoder.class);
+ when(mockDecoder.droolsCreators(TOPIC, encodedClass)).thenCallRealMethod();
+ when(mockDecoder.reverseCodersKey(TOPIC, encodedClass.getClass().getName()))
+ .thenReturn("group:artifact:topic");
+
+ var toolset = mock(ProtocolCoderToolset.class);
+ when(toolset.getGroupId()).thenReturn(GROUP_ID);
+ when(toolset.getArtifactId()).thenReturn(ARTIFACT_ID);
+
+ var mockCoders = mock(EventProtocolCoder.CoderFilters.class);
+ when(mockCoders.getFactClass()).thenReturn("java.lang.Object");
+ when(mockCoders.getModelClassLoaderHash()).thenReturn(1);
+ when(toolset.getCoders()).thenReturn(List.of(mockCoders));
+
+ HashMap<String, List<ProtocolCoderToolset>> reverseCoders = new HashMap<>();
+ var toolsetList = new ArrayList<ProtocolCoderToolset>();
+ toolsetList.add(toolset);
+ reverseCoders.put("group:artifact:topic", toolsetList);
+ ReflectionTestUtils.setField(mockDecoder, "reverseCoders", reverseCoders);
+
+ var mockDroolsController = mock(DroolsController.class);
+ when(mockDroolsController.ownsCoder(encodedClass.getClass(), 1)).thenReturn(true);
+
+ var mockFactory = mock(DroolsControllerFactory.class);
+ when(mockFactory.get(GROUP_ID, ARTIFACT_ID, "")).thenReturn(mockDroolsController);
+
+ try (MockedStatic<DroolsControllerConstants> factory = Mockito.mockStatic(DroolsControllerConstants.class)) {
+ factory.when(DroolsControllerConstants::getFactory).thenReturn(mockFactory);
+ assertEquals(mockFactory, DroolsControllerConstants.getFactory());
+ assertFalse(mockDecoder.droolsCreators(TOPIC, encodedClass).isEmpty());
+ }
+ }
+
+ @Test
+ void testGetFilters_WithGroupArtifactAndTopic() {
+ assertThatThrownBy(() -> encoder.getFilters(GROUP_ID, ARTIFACT_ID, TOPIC))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("Unsupported: groupId:artifactId:topic");
+
+ var mockEncoder = mock(EventProtocolEncoder.class);
+ when(mockEncoder.isCodingSupported(GROUP_ID, ARTIFACT_ID, TOPIC)).thenReturn(true);
+ when((mockEncoder.codersKey(GROUP_ID, ARTIFACT_ID, TOPIC))).thenCallRealMethod();
+ when(mockEncoder.getFilters(GROUP_ID, ARTIFACT_ID, TOPIC)).thenCallRealMethod();
+
+ HashMap<String, ProtocolCoderToolset> coders = new HashMap<>();
+ var mockCoderTools = mock(ProtocolCoderToolset.class);
+ when(mockCoderTools.getCoders()).thenReturn(List.of());
+ coders.put(VALID_KEY, mockCoderTools);
+ ReflectionTestUtils.setField(mockEncoder, "coders", coders);
+
+ assertTrue(mockEncoder.getFilters(GROUP_ID, ARTIFACT_ID, TOPIC).isEmpty());
+ }
+
+ @Test
+ void testGetFilters_WithGroupAndArtifact() {
+ assertTrue(encoder.getFilters(GROUP_ID, ARTIFACT_ID).isEmpty());
+
+ assertThatThrownBy(() -> encoder.getFilters("", ARTIFACT_ID))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("Invalid group");
+
+ assertThatThrownBy(() -> encoder.getFilters(GROUP_ID, ""))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("Invalid artifact");
+ }
+
+ @Test
+ void testGetFilters_WithGroupArtifactTopicAndClassName() {
+ assertThatThrownBy(() -> encoder.getFilters(GROUP_ID, ARTIFACT_ID, TOPIC, "className"))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("Unsupported: groupId:artifactId:topic");
+ }
+
+ @Test
+ void testGetFilters_WithGroupArtifactTopicAndClassNameNull() {
+ var mockEncoder = mock(EventProtocolEncoder.class);
+ when(mockEncoder.isCodingSupported(GROUP_ID, ARTIFACT_ID, TOPIC)).thenReturn(true);
+ when(mockEncoder.getFilters(GROUP_ID, ARTIFACT_ID, TOPIC, ""))
+ .thenCallRealMethod();
+
+ assertThatThrownBy(() -> mockEncoder.getFilters(GROUP_ID, ARTIFACT_ID, TOPIC, ""))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("classname must be provided");
+ }
+
+ @Test
+ void testGetFilters_WithGroupArtifactTopicAndClassName_ReturnValue() {
+ var mockEncoder = mock(EventProtocolEncoder.class);
+ when(mockEncoder.isCodingSupported(GROUP_ID, ARTIFACT_ID, TOPIC)).thenReturn(true);
+ when(mockEncoder.getFilters(GROUP_ID, ARTIFACT_ID, TOPIC, "className"))
+ .thenCallRealMethod();
+ when((mockEncoder.codersKey(GROUP_ID, ARTIFACT_ID, TOPIC))).thenCallRealMethod();
+
+ HashMap<String, ProtocolCoderToolset> coders = new HashMap<>();
+ var mockCoderTools = mock(ProtocolCoderToolset.class);
+ when(mockCoderTools.getCoder("className")).thenReturn(null);
+ coders.put(VALID_KEY, mockCoderTools);
+ ReflectionTestUtils.setField(mockEncoder, "coders", coders);
+
+ assertNull(mockEncoder.getFilters(GROUP_ID, ARTIFACT_ID, TOPIC, "className"));
+ }
+
+ @Test
+ void testGetCoders_ReturnObject() {
+ var mockEncoder = mock(EventProtocolEncoder.class);
+ when(mockEncoder.isCodingSupported(GROUP_ID, ARTIFACT_ID, TOPIC)).thenReturn(true);
+ when(mockEncoder.getCoders(GROUP_ID, ARTIFACT_ID, TOPIC))
+ .thenCallRealMethod();
+ HashMap<String, ProtocolCoderToolset> coders = new HashMap<>();
+ ReflectionTestUtils.setField(mockEncoder, "coders", coders);
+
+ assertNull(mockEncoder.getCoders(GROUP_ID, ARTIFACT_ID, TOPIC));
+ }
+
+ @Test
+ void testGetCoders_ReturnList() {
+ assertThatThrownBy(() -> encoder.getCoders("", ARTIFACT_ID))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("Invalid group");
+
+ assertThatThrownBy(() -> encoder.getCoders(GROUP_ID, ""))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("Invalid artifact");
+
+ assertTrue(encoder.getCoders(GROUP_ID, ARTIFACT_ID).isEmpty());
+
+ // mock a successful return
+ var mockEncoder = mock(EventProtocolEncoder.class);
+ HashMap<String, ProtocolCoderToolset> coders = new HashMap<>();
+ var params = mock(EventProtocolParams.class);
+ coders.put(VALID_KEY, new GsonProtocolCoderToolset(params, "controllerId"));
+ ReflectionTestUtils.setField(mockEncoder, "coders", coders);
+ when(mockEncoder.codersKey(GROUP_ID, ARTIFACT_ID, "")).thenCallRealMethod();
+ when(mockEncoder.getCoders(GROUP_ID, ARTIFACT_ID)).thenCallRealMethod();
+
+ var resultList = mockEncoder.getCoders(GROUP_ID, ARTIFACT_ID);
+ assertFalse(resultList.isEmpty());
+ assertEquals(1, resultList.size());
+
+ var emptyResult = mockEncoder.getCoders("group2", "artifact2");
+ assertTrue(emptyResult.isEmpty());
+ }
+
+ @Test
+ void testGetReverseFilters() {
+ assertThatThrownBy(() -> decoder.getReverseFilters("", "codedClass"))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("Invalid Topic");
+
+ assertThatThrownBy(() -> decoder.getReverseFilters(TOPIC, ""))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("class must be provided");
+
+ assertTrue(decoder.getReverseFilters(TOPIC, "codedClass").isEmpty());
+ }
+
+ @Test
+ void testGetReverseFilters_ReturnToolset() {
+ var mockDecoder = mock(EventProtocolDecoder.class);
+
+ // mock a successful return
+ HashMap<String, List<ProtocolCoderToolset>> reverseCoders = new HashMap<>();
+ var params = mock(EventProtocolParams.class);
+ var toolset = new GsonProtocolCoderToolset(params, "controllerId");
+ reverseCoders.put("topic:codedClass", List.of(toolset));
+ ReflectionTestUtils.setField(mockDecoder, "reverseCoders", reverseCoders);
+
+ when(mockDecoder.reverseCodersKey(TOPIC, "codedClass")).thenReturn("topic:codedClass");
+ when(mockDecoder.getReverseFilters(TOPIC, "codedClass")).thenCallRealMethod();
+
+ var resultList = mockDecoder.getReverseFilters(TOPIC, "codedClass");
+ assertFalse(resultList.isEmpty());
+ assertEquals(1, resultList.size());
+ }
+
+ @Test
+ void testGetDroolsController_Exception() {
+ var fact = new Object();
+ assertThatThrownBy(() -> decoder.getDroolsController("", fact))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("Invalid Topic");
+
+ assertThatThrownBy(() -> decoder.getDroolsController(TOPIC, null))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("class must be provided");
+
+ assertThatThrownBy(() -> decoder.getDroolsController(TOPIC, fact))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("Unsupported topic topic and encodedClass class java.lang.Object");
+ }
+
+ @Test
+ void testGetDroolsController_ReturnObject() {
+ var mockDecoder = mock(EventProtocolDecoder.class);
+ var droolsController = new NullDroolsController();
+ var droolsController2 = new NullDroolsController();
+ var fact = new Object();
+
+ // mock first call to return only one controller, then second call should return 2 controllers
+ when(mockDecoder.getDroolsControllers(TOPIC, fact))
+ .thenReturn(List.of(droolsController))
+ .thenReturn(List.of(droolsController, droolsController2));
+ when(mockDecoder.getDroolsController(TOPIC, fact)).thenCallRealMethod();
+
+ var result = mockDecoder.getDroolsController(TOPIC, fact);
+ assertNotNull(result);
+
+ // second call supposed to return 2 controllers internally, but still return 1 item
+ var result2 = mockDecoder.getDroolsController(TOPIC, fact);
+ assertNotNull(result2);
+ }
+
+ @Test
+ void testGetDroolsControllers_Exception() {
+ var fact = new Object();
+ assertThatThrownBy(() -> decoder.getDroolsControllers("", fact))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("Invalid Topic");
+
+ assertThatThrownBy(() -> decoder.getDroolsControllers(TOPIC, null))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("class must be provided");
+
+ assertTrue(decoder.getDroolsControllers(TOPIC, fact).isEmpty());
+ }
+
+ @Test
+ void testGetDroolsControllers_ReturnValues() {
+ var mockDecoder = mock(EventProtocolDecoder.class);
+ var droolsController = new NullDroolsController();
+ var droolsController2 = new NullDroolsController();
+ var fact = new Object();
+
+ // mock first call to return only one controller, then second call should return 2 controllers
+ when(mockDecoder.droolsCreators(TOPIC, fact))
+ .thenReturn(List.of(droolsController))
+ .thenReturn(List.of(droolsController, droolsController2));
+ when(mockDecoder.getDroolsControllers(TOPIC, fact)).thenCallRealMethod();
+
+ var result = mockDecoder.getDroolsControllers(TOPIC, fact);
+ assertEquals(1, result.size());
+
+ // second call supposed to return 2 controllers
+ var result2 = mockDecoder.getDroolsControllers(TOPIC, fact);
+ assertEquals(2, result2.size());
+ }
+
+ @Test
+ void testRemove() {
+ var mockDecoder = mock(EventProtocolDecoder.class);
+ doCallRealMethod().when(mockDecoder).remove(GROUP_ID, ARTIFACT_ID, TOPIC);
+ when(mockDecoder.codersKey(GROUP_ID, ARTIFACT_ID, TOPIC)).thenCallRealMethod();
+ when(mockDecoder.reverseCodersKey(TOPIC, "className")).thenReturn(INVALID_KEY);
+
+ var toolset = mock(ProtocolCoderToolset.class);
+ var mockCoders = new EventProtocolCoder.CoderFilters("className", mock(JsonProtocolFilter.class), 1);
+ when(toolset.getCoders()).thenReturn(List.of(mockCoders));
+
+ HashMap<String, ProtocolCoderToolset> coders = new HashMap<>();
+ coders.put(VALID_KEY, toolset);
+ ReflectionTestUtils.setField(mockDecoder, "coders", coders);
+ HashMap<String, List<ProtocolCoderToolset>> reverseCoders = new HashMap<>();
+ reverseCoders.put(VALID_KEY, new ArrayList<>(List.of(toolset)));
+ ReflectionTestUtils.setField(mockDecoder, "reverseCoders", reverseCoders);
+
+ assertDoesNotThrow(() -> mockDecoder.remove(GROUP_ID, ARTIFACT_ID, TOPIC));
+ assertEquals(1, mockDecoder.reverseCoders.size());
+ assertTrue(mockDecoder.coders.isEmpty());
+ }
+
+ @Test
+ void testRemove2() {
+ var myKey = "group:artifact:topic";
+ var mockDecoder = mock(EventProtocolDecoder.class);
+ doCallRealMethod().when(mockDecoder).remove(GROUP_ID, ARTIFACT_ID, TOPIC);
+ when(mockDecoder.codersKey(GROUP_ID, ARTIFACT_ID, TOPIC)).thenReturn(myKey);
+ when(mockDecoder.reverseCodersKey(TOPIC, "className")).thenReturn(myKey);
+
+ var toolset = mock(ProtocolCoderToolset.class);
+ var mockCoders = new EventProtocolCoder.CoderFilters("className", mock(JsonProtocolFilter.class), 1);
+ when(toolset.getCoders()).thenReturn(List.of(mockCoders));
+
+ HashMap<String, ProtocolCoderToolset> coders = new HashMap<>();
+ coders.put(myKey, toolset);
+ ReflectionTestUtils.setField(mockDecoder, "coders", coders);
+ HashMap<String, List<ProtocolCoderToolset>> reverseCoders = new HashMap<>();
+ reverseCoders.put(myKey, new ArrayList<>());
+ ReflectionTestUtils.setField(mockDecoder, "reverseCoders", reverseCoders);
+
+ assertDoesNotThrow(() -> mockDecoder.remove(GROUP_ID, ARTIFACT_ID, TOPIC));
+ assertTrue(mockDecoder.reverseCoders.isEmpty());
+ assertTrue(mockDecoder.coders.isEmpty());
+ }
+
+} \ No newline at end of file
diff --git a/policy-management/src/test/java/org/onap/policy/drools/protocol/coders/GsonProtocolCoderToolsetTest.java b/policy-management/src/test/java/org/onap/policy/drools/protocol/coders/GsonProtocolCoderToolsetTest.java
new file mode 100644
index 00000000..4bd2aab2
--- /dev/null
+++ b/policy-management/src/test/java/org/onap/policy/drools/protocol/coders/GsonProtocolCoderToolsetTest.java
@@ -0,0 +1,197 @@
+/*-
+ * ============LICENSE_START===============================================
+ * ONAP
+ * ========================================================================
+ * 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.
+ * 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.drools.protocol.coders;
+
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.jupiter.api.Assertions.assertAll;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.mockito.Mockito.doCallRealMethod;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonDeserializationContext;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonIOException;
+import com.google.gson.JsonSerializationContext;
+import com.google.gson.JsonSyntaxException;
+import java.lang.reflect.Type;
+import java.time.Instant;
+import java.time.ZonedDateTime;
+import org.junit.jupiter.api.Test;
+import org.mockito.MockedStatic;
+import org.mockito.Mockito;
+import org.mockito.stubbing.Answer;
+import org.onap.policy.drools.controller.DroolsControllerConstants;
+import org.onap.policy.drools.controller.DroolsControllerFactory;
+import org.onap.policy.drools.controller.internal.NullDroolsController;
+import org.springframework.test.util.ReflectionTestUtils;
+
+class GsonProtocolCoderToolsetTest {
+
+ @Test
+ void decode() {
+ var mockGsonToolset = mock(GsonProtocolCoderToolset.class);
+ ReflectionTestUtils.setField(mockGsonToolset, "groupId", "group");
+ ReflectionTestUtils.setField(mockGsonToolset, "artifactId", "artifact");
+ doCallRealMethod().when(mockGsonToolset).decode("json");
+
+ var decoderClass = ProtocolCoderToolsetTest.ThreeStrings.class;
+ var mockGson = mock(Gson.class);
+ when(mockGson.fromJson("json", decoderClass)).thenThrow(new JsonSyntaxException("error"));
+ when(mockGsonToolset.getDecoder()).thenReturn(mockGson);
+
+ var mockCustomCoder = mock(TopicCoderFilterConfiguration.CustomCoder.class);
+ when(mockCustomCoder.getClassContainer()).thenReturn("classContainer");
+ ReflectionTestUtils.setField(mockGsonToolset, "customCoder", mockCustomCoder);
+
+ var mockFilter = mock(EventProtocolCoder.CoderFilters.class);
+ when(mockFilter.getFactClass()).thenReturn("someClassName");
+ when(mockGsonToolset.filter("json")).thenReturn(mockFilter);
+
+ var droolsController = mock(NullDroolsController.class);
+ when(droolsController.fetchModelClass("someClassName"))
+ .thenReturn(null)
+ .thenAnswer((Answer<Class<?>>) invocation -> decoderClass)
+ .thenAnswer((Answer<Class<?>>) invocation -> decoderClass);
+ when(droolsController.fetchModelClass("classContainer")).thenReturn(null);
+
+ var mockFactory = mock(DroolsControllerFactory.class);
+ when(mockFactory.get("group", "artifact", ""))
+ .thenReturn(null)
+ .thenReturn(droolsController);
+
+ try (MockedStatic<DroolsControllerConstants> factory = Mockito.mockStatic(DroolsControllerConstants.class)) {
+ factory.when(DroolsControllerConstants::getFactory).thenReturn(mockFactory);
+ assertEquals(mockFactory, DroolsControllerConstants.getFactory());
+
+ // first call to fail when droolsController returns null
+ assertThatThrownBy(() -> mockGsonToolset.decode("json"))
+ .isInstanceOf(IllegalStateException.class)
+ .hasMessageContaining("no drools-controller to process event");
+
+ // second call to fail when droolsController.fetchModelClass returns null
+ assertThatThrownBy(() -> mockGsonToolset.decode("json"))
+ .isInstanceOf(UnsupportedOperationException.class)
+ .hasMessageContaining("cannot fetch application class someClassName");
+
+ // third call to fail when droolsController.fetchModelClass returns null when using customCoder
+ assertThatThrownBy(() -> mockGsonToolset.decode("json"))
+ .isInstanceOf(UnsupportedOperationException.class)
+ .hasMessageContaining("cannot decode with customCoder: classContainer")
+ .hasMessageContaining("using application class someClassName");
+
+ // set customCoder to null to test default decoder
+ ReflectionTestUtils.setField(mockGsonToolset, "customCoder", null);
+
+ // fourth call to fail when decoder can't parse json
+ assertThatThrownBy(() -> mockGsonToolset.decode("json"))
+ .isInstanceOf(UnsupportedOperationException.class)
+ .hasMessageContaining("cannot decode into");
+ }
+ }
+
+ @Test
+ void encode() {
+ var event = new Object();
+
+ var mockGsonToolset = mock(GsonProtocolCoderToolset.class);
+ ReflectionTestUtils.setField(mockGsonToolset, "groupId", "group");
+ ReflectionTestUtils.setField(mockGsonToolset, "artifactId", "artifact");
+ doCallRealMethod().when(mockGsonToolset).encode(event);
+
+ var mockGson = mock(Gson.class);
+ when(mockGson.toJson(event)).thenThrow(new JsonIOException("error"));
+ when(mockGsonToolset.getEncoder()).thenReturn(mockGson);
+
+ var mockCustomCoder = mock(TopicCoderFilterConfiguration.CustomCoder.class);
+ ReflectionTestUtils.setField(mockGsonToolset, "customCoder", mockCustomCoder);
+
+ var mockFactory = mock(DroolsControllerFactory.class);
+ when(mockFactory.get("group", "artifact", "")).thenReturn(null);
+
+ try (MockedStatic<DroolsControllerConstants> factory = Mockito.mockStatic(DroolsControllerConstants.class)) {
+ factory.when(DroolsControllerConstants::getFactory).thenReturn(mockFactory);
+ assertEquals(mockFactory, DroolsControllerConstants.getFactory());
+
+ // first call to encode fails with droolsController returning null, therefore, can't process event
+ assertThatThrownBy(() -> mockGsonToolset.encode(event))
+ .isInstanceOf(UnsupportedOperationException.class)
+ .hasMessageContaining("event cannot be custom encoded");
+
+ // set customCoder to null to test default encoder
+ ReflectionTestUtils.setField(mockGsonToolset, "customCoder", null);
+
+ // second call to encode fails when gson.toJson raises an exception
+ assertThatThrownBy(() -> mockGsonToolset.encode(event))
+ .isInstanceOf(UnsupportedOperationException.class)
+ .hasMessageContaining("event cannot be encoded");
+ }
+ }
+
+ @Test
+ void test_GsonInstantAdapter() {
+ var instantAdapter = new GsonProtocolCoderToolset.GsonInstantAdapter();
+
+ var currentTime = System.currentTimeMillis();
+ var json = mock(JsonElement.class);
+ when(json.getAsLong()).thenReturn(currentTime);
+
+ var result = instantAdapter.deserialize(json, mock(Type.class), mock(JsonDeserializationContext.class));
+ assertInstanceOf(Instant.class, result);
+ assertEquals(currentTime, result.toEpochMilli());
+
+ var jsonResult = instantAdapter.serialize(result, mock(Type.class), mock(JsonSerializationContext.class));
+ assertInstanceOf(JsonElement.class, jsonResult);
+ assertEquals(currentTime, jsonResult.getAsLong());
+ }
+
+ @Test
+ void test_GsonUtcAdapter() {
+ var utcAdapter = new GsonProtocolCoderToolset.GsonUtcAdapter();
+
+ var currentZone = ZonedDateTime.now();
+ var formattedCurrentZone = ZonedDateTime.now().format(GsonProtocolCoderToolset.format);
+ var json = mock(JsonElement.class);
+ when(json.getAsString()).thenReturn(formattedCurrentZone).thenReturn("invalid json");
+
+ var result = utcAdapter.deserialize(json, mock(Type.class), mock(JsonDeserializationContext.class));
+ assertNotNull(result);
+ assertAll(() -> {
+ assertEquals(currentZone.getYear(), result.getYear());
+ assertEquals(currentZone.getMonth(), result.getMonth());
+ assertEquals(currentZone.getDayOfMonth(), result.getDayOfMonth());
+ assertEquals(currentZone.getHour(), result.getHour());
+ assertEquals(currentZone.getMinute(), result.getMinute());
+ assertEquals(currentZone.getSecond(), result.getSecond());
+ });
+
+ // when json.getAsString returns invalid json, should fail and return null
+ assertNull(utcAdapter.deserialize(json, mock(Type.class), mock(JsonDeserializationContext.class)));
+
+ var result2 = utcAdapter.serialize(result, mock(Type.class), mock(JsonSerializationContext.class));
+ assertNotNull(result2);
+ assertEquals(formattedCurrentZone, result2.getAsString());
+ }
+} \ No newline at end of file
diff --git a/policy-management/src/test/java/org/onap/policy/drools/protocol/coders/MultiplexorEventProtocolCoderTest.java b/policy-management/src/test/java/org/onap/policy/drools/protocol/coders/MultiplexorEventProtocolCoderTest.java
new file mode 100644
index 00000000..c64e9bce
--- /dev/null
+++ b/policy-management/src/test/java/org/onap/policy/drools/protocol/coders/MultiplexorEventProtocolCoderTest.java
@@ -0,0 +1,308 @@
+/*-
+ * ============LICENSE_START===============================================
+ * ONAP
+ * ========================================================================
+ * 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.
+ * 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.drools.protocol.coders;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.onap.policy.drools.controller.DroolsController;
+import org.springframework.test.util.ReflectionTestUtils;
+
+class MultiplexorEventProtocolCoderTest {
+
+ @Mock
+ EventProtocolEncoder encoder;
+
+ @Mock
+ EventProtocolDecoder decoder;
+
+ MultiplexorEventProtocolCoder coder = new MultiplexorEventProtocolCoder();
+
+ AutoCloseable closeable;
+
+ private static final String GROUP_ID = "group";
+ private static final String ARTIFACT_ID = "artifact";
+ private static final String TOPIC = "topic";
+
+ @BeforeEach
+ void setUp() {
+ closeable = MockitoAnnotations.openMocks(this);
+ ReflectionTestUtils.setField(coder, "encoders", encoder);
+ ReflectionTestUtils.setField(coder, "decoders", decoder);
+ }
+
+ @AfterEach
+ void tearDown() throws Exception {
+ closeable.close();
+ }
+
+ @Test
+ void addDecoder() {
+ var mockParams = mock(EventProtocolParams.class);
+ doNothing().when(decoder).add(mockParams);
+
+ assertDoesNotThrow(() -> coder.addDecoder(mockParams));
+ }
+
+ @Test
+ void addEncoder() {
+ var mockParams = mock(EventProtocolParams.class);
+ doNothing().when(encoder).add(mockParams);
+
+ assertDoesNotThrow(() -> coder.addEncoder(mockParams));
+ }
+
+ @Test
+ void removeDecoders() {
+ doNothing().when(decoder).remove(GROUP_ID, ARTIFACT_ID, TOPIC);
+ assertDoesNotThrow(() -> coder.removeDecoders(GROUP_ID, ARTIFACT_ID, TOPIC));
+ }
+
+ @Test
+ void removeEncoders() {
+ doNothing().when(encoder).remove(GROUP_ID, ARTIFACT_ID, TOPIC);
+ assertDoesNotThrow(() -> coder.removeEncoders(GROUP_ID, ARTIFACT_ID, TOPIC));
+ }
+
+ @Test
+ void isDecodingSupported() {
+ HashMap<String, ProtocolCoderToolset> coders = new HashMap<>();
+ coders.put("otherGroup:artifact:topic", mock(ProtocolCoderToolset.class));
+ ReflectionTestUtils.setField(decoder, "coders", coders);
+ when(decoder.codersKey(GROUP_ID, ARTIFACT_ID, TOPIC)).thenCallRealMethod();
+ when(decoder.isCodingSupported(GROUP_ID, ARTIFACT_ID, TOPIC))
+ .thenReturn(true)
+ .thenCallRealMethod();
+ assertTrue(coder.isDecodingSupported(GROUP_ID, ARTIFACT_ID, TOPIC));
+ assertFalse(coder.isDecodingSupported(GROUP_ID, ARTIFACT_ID, TOPIC));
+ }
+
+ @Test
+ void isEncodingSupported() {
+ HashMap<String, ProtocolCoderToolset> coders = new HashMap<>();
+ coders.put("otherGroup:artifact:topic", mock(ProtocolCoderToolset.class));
+ ReflectionTestUtils.setField(encoder, "coders", coders);
+ when(encoder.codersKey(GROUP_ID, ARTIFACT_ID, TOPIC)).thenCallRealMethod();
+ when(encoder.isCodingSupported(GROUP_ID, ARTIFACT_ID, TOPIC))
+ .thenReturn(true)
+ .thenCallRealMethod();
+ assertTrue(coder.isEncodingSupported(GROUP_ID, ARTIFACT_ID, TOPIC));
+ assertFalse(coder.isEncodingSupported(GROUP_ID, ARTIFACT_ID, TOPIC));
+ }
+
+ @Test
+ void decode() {
+ when(decoder.decode(GROUP_ID, ARTIFACT_ID, TOPIC, "{}"))
+ .thenReturn(new Object())
+ .thenCallRealMethod();
+ when(decoder.isCodingSupported(GROUP_ID, ARTIFACT_ID, TOPIC)).thenReturn(false);
+
+ // first mock call to return directly new Object()
+ assertNotNull(coder.decode(GROUP_ID, ARTIFACT_ID, TOPIC, "{}"));
+
+ // second mock call to check isCodingSupport return false, then throws exception
+ assertThrows(IllegalArgumentException.class,
+ () -> coder.decode(GROUP_ID, ARTIFACT_ID, TOPIC, "{}"));
+ }
+
+ @Test
+ void encode() {
+ var event = new Object();
+ when(encoder.encode(GROUP_ID, ARTIFACT_ID, TOPIC, event))
+ .thenReturn("{}")
+ .thenCallRealMethod();
+ when(encoder.isCodingSupported(GROUP_ID, ARTIFACT_ID, TOPIC)).thenReturn(false);
+
+ // first mock call to return directly new Object()
+ assertNotNull(coder.encode(GROUP_ID, ARTIFACT_ID, TOPIC, event));
+
+ // second mock call to check isCodingSupport return false, then throws exception
+ assertThrows(IllegalArgumentException.class,
+ () -> coder.encode(GROUP_ID, ARTIFACT_ID, TOPIC, event));
+ }
+
+ @Test
+ void encode_WithTopicAndEvent() {
+ var event = new Object();
+ when(encoder.encode(TOPIC, event)).thenReturn("{}");
+
+ var result = coder.encode(TOPIC, event);
+ assertNotNull(result);
+ assertInstanceOf(String.class, result);
+ }
+
+ @Test
+ void encode_WithTopicEncodedClassAndController() {
+ var event = new Object();
+ var controller = mock(DroolsController.class);
+ when(encoder.encode(TOPIC, event, controller)).thenReturn("{}");
+
+ var result = coder.encode(TOPIC, event, controller);
+ assertNotNull(result);
+ assertInstanceOf(String.class, result);
+ }
+
+ @Test
+ void getDecoderFilters() {
+ when(decoder.getFilters(GROUP_ID, ARTIFACT_ID, TOPIC))
+ .thenReturn(new ArrayList<>())
+ .thenCallRealMethod();
+ when(decoder.isCodingSupported(GROUP_ID, ARTIFACT_ID, TOPIC)).thenReturn(false);
+
+ // first mock call return a list
+ var result = coder.getDecoderFilters(GROUP_ID, ARTIFACT_ID, TOPIC);
+ assertTrue(result.isEmpty());
+
+ // second call goes for real method, with isCodingSupported mocked to false, exception is thrown
+ assertThrows(IllegalArgumentException.class,
+ () -> coder.getDecoderFilters(GROUP_ID, ARTIFACT_ID, TOPIC));
+ }
+
+ @Test
+ void testGetDecoderFilters_WithGroupArtifactTopicAndClassName() {
+ when(decoder.getFilters(GROUP_ID, ARTIFACT_ID, TOPIC, "className"))
+ .thenReturn(mock(EventProtocolCoder.CoderFilters.class))
+ .thenCallRealMethod();
+ when(decoder.isCodingSupported(GROUP_ID, ARTIFACT_ID, TOPIC)).thenReturn(false);
+
+ // first mock call return a mock object
+ assertNotNull(coder.getDecoderFilters(GROUP_ID, ARTIFACT_ID, TOPIC, "className"));
+
+ // second call goes for real method, with isCodingSupported mocked to false, exception is thrown
+ assertThrows(IllegalArgumentException.class,
+ () -> coder.getDecoderFilters(GROUP_ID, ARTIFACT_ID, TOPIC, "className"));
+ }
+
+ @Test
+ void testGetDecoderFilters_WithGroupAndArtifact() {
+ when(decoder.getFilters(GROUP_ID, ARTIFACT_ID)).thenReturn(new ArrayList<>());
+
+ assertThat(coder.getDecoderFilters(GROUP_ID, ARTIFACT_ID, TOPIC)).isEmpty();
+ }
+
+ @Test
+ void getDecoders() {
+ when(decoder.getCoders(GROUP_ID, ARTIFACT_ID, TOPIC))
+ .thenReturn(mock(ProtocolCoderToolset.class))
+ .thenCallRealMethod();
+ when(decoder.isCodingSupported(GROUP_ID, ARTIFACT_ID, TOPIC)).thenReturn(false);
+
+ assertNotNull(coder.getDecoders(GROUP_ID, ARTIFACT_ID, TOPIC));
+ assertThrows(IllegalArgumentException.class,
+ () -> coder.getDecoders(GROUP_ID, ARTIFACT_ID, TOPIC));
+ }
+
+ @Test
+ void testGetDecoders_WithGroupAndArtifact() {
+ when(decoder.getCoders(GROUP_ID, ARTIFACT_ID)).thenReturn(new ArrayList<>());
+
+ assertThat(coder.getDecoders(GROUP_ID, ARTIFACT_ID)).isEmpty();
+ }
+
+ @Test
+ void getEncoderFilters() {
+ when(encoder.getFilters(GROUP_ID, ARTIFACT_ID, TOPIC))
+ .thenReturn(new ArrayList<>())
+ .thenCallRealMethod();
+ when(encoder.isCodingSupported(GROUP_ID, ARTIFACT_ID, TOPIC)).thenReturn(false);
+
+ // first mock call return a list
+ var result = coder.getEncoderFilters(GROUP_ID, ARTIFACT_ID, TOPIC);
+ assertTrue(result.isEmpty());
+
+ // second call goes for real method, with isCodingSupported mocked to false, exception is thrown
+ assertThrows(IllegalArgumentException.class,
+ () -> coder.getEncoderFilters(GROUP_ID, ARTIFACT_ID, TOPIC));
+ }
+
+ @Test
+ void testGetEncoderFilters_WithGroupArtifactTopicAndClassName() {
+ when(encoder.getFilters(GROUP_ID, ARTIFACT_ID, TOPIC, "className"))
+ .thenReturn(mock(EventProtocolCoder.CoderFilters.class))
+ .thenCallRealMethod();
+ when(encoder.isCodingSupported(GROUP_ID, ARTIFACT_ID, TOPIC)).thenReturn(false);
+
+ // first mock call return a mock object
+ assertNotNull(coder.getEncoderFilters(GROUP_ID, ARTIFACT_ID, TOPIC, "className"));
+
+ // second call goes for real method, with isCodingSupported mocked to false, exception is thrown
+ assertThrows(IllegalArgumentException.class,
+ () -> coder.getEncoderFilters(GROUP_ID, ARTIFACT_ID, TOPIC, "className"));
+ }
+
+ @Test
+ void testGetEncoderFilters_WithGroupAndArtifact() {
+ when(encoder.getFilters(GROUP_ID, ARTIFACT_ID)).thenReturn(new ArrayList<>());
+
+ assertThat(coder.getEncoderFilters(GROUP_ID, ARTIFACT_ID, TOPIC)).isEmpty();
+ }
+
+ @Test
+ void getReverseEncoderFilters() {
+ when(encoder.getReverseFilters(TOPIC, "codedClass")).thenReturn(new ArrayList<>());
+ assertThat(coder.getReverseEncoderFilters(TOPIC, "codedClass")).isEmpty();
+ }
+
+ @Test
+ void getDroolsController() {
+ var fact = new Object();
+ // mock success
+ when(encoder.getDroolsController(TOPIC, fact))
+ .thenReturn(mock(DroolsController.class))
+ .thenCallRealMethod();
+ // mock failure
+ when(encoder.getDroolsControllers(TOPIC, fact)).thenReturn(new ArrayList<>());
+
+ // first call gets mock DroolsController - pass
+ assertNotNull(coder.getDroolsController(TOPIC, fact));
+ // second call goes through the method, then call inside method that returns empty list, throws an exception
+ assertThrows(IllegalArgumentException.class, () -> coder.getDroolsController(TOPIC, fact));
+ }
+
+ @Test
+ void getDroolsControllers() {
+ var fact = new Object();
+ when(encoder.getDroolsControllers(TOPIC, fact)).thenReturn(new ArrayList<>());
+
+ assertThat(coder.getDroolsControllers(TOPIC, fact)).isEmpty();
+ }
+
+ @Test
+ void testToString() {
+ assertThat(coder.toString())
+ .contains("MultiplexorEventProtocolCoder");
+ }
+} \ No newline at end of file
diff --git a/policy-management/src/test/java/org/onap/policy/drools/protocol/coders/ProtocolCoderToolsetTest.java b/policy-management/src/test/java/org/onap/policy/drools/protocol/coders/ProtocolCoderToolsetTest.java
index 659965f8..cb4397c8 100644
--- a/policy-management/src/test/java/org/onap/policy/drools/protocol/coders/ProtocolCoderToolsetTest.java
+++ b/policy-management/src/test/java/org/onap/policy/drools/protocol/coders/ProtocolCoderToolsetTest.java
@@ -22,11 +22,19 @@
package org.onap.policy.drools.protocol.coders;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertSame;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doCallRealMethod;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
@@ -53,6 +61,7 @@ import org.onap.policy.drools.protocol.coders.TopicCoderFilterConfiguration.Cust
import org.onap.policy.drools.util.KieUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.springframework.test.util.ReflectionTestUtils;
/**
* ProtocolCoder Toolset Junits.
@@ -62,12 +71,12 @@ public class ProtocolCoderToolsetTest {
private static final String JUNIT_PROTOCOL_CODER_TOPIC = JUNIT_PROTOCOL_CODER_ARTIFACT_ID;
private static final String CONTROLLER_ID = "blah";
- private static final Logger logger = LoggerFactory.getLogger(ProtocolCoderToolset.class);
+ private static final Logger logger = LoggerFactory.getLogger(ProtocolCoderToolsetTest.class);
private static volatile ReleaseId releaseId;
// customCoder has to be public to be accessed in tests below
- public static final Gson customCoder = new GsonBuilder().create();
+ public static final Gson customCoder = new GsonBuilder().create(); // NOSONAR actually being used in the test
private DroolsController controller;
@@ -77,9 +86,9 @@ public class ProtocolCoderToolsetTest {
@BeforeAll
public static void setUpClass() throws IOException {
releaseId = KieUtils.installArtifact(Paths.get(MavenDroolsControllerTest.JUNIT_ECHO_KMODULE_PATH).toFile(),
- Paths.get(MavenDroolsControllerTest.JUNIT_ECHO_KMODULE_POM_PATH).toFile(),
- MavenDroolsControllerTest.JUNIT_ECHO_KJAR_DRL_PATH,
- Paths.get(MavenDroolsControllerTest.JUNIT_ECHO_KMODULE_DRL_PATH).toFile());
+ Paths.get(MavenDroolsControllerTest.JUNIT_ECHO_KMODULE_POM_PATH).toFile(),
+ MavenDroolsControllerTest.JUNIT_ECHO_KJAR_DRL_PATH,
+ Paths.get(MavenDroolsControllerTest.JUNIT_ECHO_KMODULE_DRL_PATH).toFile());
}
/**
@@ -105,6 +114,55 @@ public class ProtocolCoderToolsetTest {
testGsonToolset(createFilterSet());
}
+ @Test
+ void testExceptions() {
+ // should fail without params
+ assertThrows(IllegalArgumentException.class,
+ () -> new GsonProtocolCoderToolset(null, "controller"));
+
+ // should fail without controller ID
+ assertThrows(IllegalArgumentException.class,
+ () -> new GsonProtocolCoderToolset(mock(EventProtocolParams.class), ""));
+
+ // set mock under test - always call real method under test
+ var toolset = mock(GsonProtocolCoderToolset.class);
+ when(toolset.getCoder("")).thenCallRealMethod();
+
+ // should fail calling with empty classname
+ assertThatThrownBy(() -> toolset.getCoder(""))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("no classname provided");
+
+ // should fail when trying to add coder with empty event class
+ doCallRealMethod().when(toolset).addCoder(anyString(), any(JsonProtocolFilter.class), anyInt());
+ assertThatThrownBy(() -> toolset.addCoder("", mock(JsonProtocolFilter.class), 1))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("no event class provided");
+
+ // should fail when trying to remove coder with empty event
+ doCallRealMethod().when(toolset).removeCoders(anyString());
+ assertThatThrownBy(() -> toolset.removeCoders(""))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("no event class provided");
+
+ // set coders to empty list
+ when(toolset.filter(anyString())).thenCallRealMethod();
+ ReflectionTestUtils.setField(toolset, "coders", List.of());
+
+ // should fail when trying to find a filter from an empty list
+ assertThatThrownBy(() -> toolset.filter(""))
+ .isInstanceOf(IllegalStateException.class)
+ .hasMessageContaining("No coders available");
+
+ // there is a coder in the list, but can't check if accepts json when coder doesn't have filter
+ var mockCoderFilter = mock(CoderFilters.class);
+ when(mockCoderFilter.getFilter()).thenReturn(null);
+ ReflectionTestUtils.setField(toolset, "coders", List.of(mockCoderFilter));
+
+ assertNull(toolset.filter("json"));
+
+ }
+
/**
* Test the Gson toolset.
*
@@ -112,10 +170,10 @@ public class ProtocolCoderToolsetTest {
*/
private void testGsonToolset(JsonProtocolFilter protocolFilter) {
GsonProtocolCoderToolset gsonToolset =
- new GsonProtocolCoderToolset(EventProtocolParams.builder().topic(JUNIT_PROTOCOL_CODER_TOPIC)
- .groupId(releaseId.getGroupId()).artifactId(releaseId.getArtifactId())
- .eventClass(ThreeStrings.class.getName()).protocolFilter(protocolFilter)
- .customGsonCoder(null).modelClassLoaderHash(12345678).build(), CONTROLLER_ID);
+ new GsonProtocolCoderToolset(EventProtocolParams.builder().topic(JUNIT_PROTOCOL_CODER_TOPIC)
+ .groupId(releaseId.getGroupId()).artifactId(releaseId.getArtifactId())
+ .eventClass(ThreeStrings.class.getName()).protocolFilter(protocolFilter)
+ .customGsonCoder(null).modelClassLoaderHash(12345678).build(), CONTROLLER_ID);
assertNotNull(gsonToolset.getEncoder());
assertNotNull(gsonToolset.getDecoder());
@@ -154,7 +212,7 @@ public class ProtocolCoderToolsetTest {
}
private void decode(JsonProtocolFilter protocolFilter, ProtocolCoderToolset coderToolset,
- ThreeStrings triple, String tripleEncoded) {
+ ThreeStrings triple, String tripleEncoded) {
try {
coderToolset.decode(tripleEncoded);
@@ -212,7 +270,7 @@ public class ProtocolCoderToolsetTest {
assertNotNull(coderToolset.getCoder(ThreeStrings.class.getName()).getFilter().getRule());
assertEquals("[?($.third =~ /.*/)]",
- coderToolset.getCoder(ThreeStrings.class.getName()).getFilter().getRule());
+ coderToolset.getCoder(ThreeStrings.class.getName()).getFilter().getRule());
}
private void validateInitialization(JsonProtocolFilter protocolFilter, ProtocolCoderToolset coderToolset) {
@@ -241,16 +299,21 @@ public class ProtocolCoderToolsetTest {
sinkConfig.put(PolicyEndPointProperties.PROPERTY_NOOP_SINK_TOPICS, JUNIT_PROTOCOL_CODER_TOPIC);
final List<TopicSink> noopTopics = TopicEndpointManager.getManager().addTopicSinks(sinkConfig);
+ Properties droolsControllerConfig = getDroolsControllerConfig();
+
+ return DroolsControllerConstants.getFactory().build(droolsControllerConfig, null, noopTopics);
+ }
+
+ private static Properties getDroolsControllerConfig() {
Properties droolsControllerConfig = new Properties();
droolsControllerConfig.put(DroolsPropertyConstants.RULES_GROUPID, releaseId.getGroupId());
droolsControllerConfig.put(DroolsPropertyConstants.RULES_ARTIFACTID, releaseId.getArtifactId());
droolsControllerConfig.put(DroolsPropertyConstants.RULES_VERSION, releaseId.getVersion());
droolsControllerConfig.put(
- PolicyEndPointProperties.PROPERTY_NOOP_SINK_TOPICS + "." + JUNIT_PROTOCOL_CODER_TOPIC
- + PolicyEndPointProperties.PROPERTY_TOPIC_EVENTS_SUFFIX,
- ThreeStrings.class.getName());
-
- return DroolsControllerConstants.getFactory().build(droolsControllerConfig, null, noopTopics);
+ PolicyEndPointProperties.PROPERTY_NOOP_SINK_TOPICS + "." + JUNIT_PROTOCOL_CODER_TOPIC
+ + PolicyEndPointProperties.PROPERTY_TOPIC_EVENTS_SUFFIX,
+ ThreeStrings.class.getName());
+ return droolsControllerConfig;
}
private JsonProtocolFilter createFilterSet() {
diff --git a/policy-management/src/test/java/org/onap/policy/drools/protocol/coders/TopicCoderFilterConfigurationTest.java b/policy-management/src/test/java/org/onap/policy/drools/protocol/coders/TopicCoderFilterConfigurationTest.java
new file mode 100644
index 00000000..5429a94e
--- /dev/null
+++ b/policy-management/src/test/java/org/onap/policy/drools/protocol/coders/TopicCoderFilterConfigurationTest.java
@@ -0,0 +1,75 @@
+/*-
+ * ============LICENSE_START===============================================
+ * ONAP
+ * ========================================================================
+ * 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.
+ * 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.drools.protocol.coders;
+
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+import java.util.List;
+import org.junit.jupiter.api.Test;
+
+class TopicCoderFilterConfigurationTest {
+
+ @Test
+ void setCustomGsonCoder() {
+ var topic = "topic";
+ var decodeFilter = new TopicCoderFilterConfiguration
+ .PotentialCoderFilter("codedClass", new JsonProtocolFilter("rule"));
+ var customCoder = new TopicCoderFilterConfiguration
+ .CustomGsonCoder("className", "staticCoderField");
+ var topicConfig = new TopicCoderFilterConfiguration(topic, List.of(decodeFilter), customCoder);
+
+ assertNotNull(topicConfig);
+ assertNotNull(topicConfig.getCoderFilters());
+ assertEquals("topic", topicConfig.getTopic());
+
+ assertEquals("className", topicConfig.getCustomGsonCoder().getClassContainer());
+
+ var customCoder2 = new TopicCoderFilterConfiguration.CustomGsonCoder("className2,staticCoderField2");
+ topicConfig.setCustomGsonCoder(customCoder2);
+
+ assertEquals("className2", topicConfig.getCustomGsonCoder().getClassContainer());
+ }
+
+ @Test
+ void setCustomCoder_Exceptions() {
+ assertThatThrownBy(() -> new TopicCoderFilterConfiguration.CustomGsonCoder("", "staticCoderField"))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("No classname to create CustomCoder cannot be created");
+
+ assertThatThrownBy(() -> new TopicCoderFilterConfiguration.CustomGsonCoder("className", ""))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("No staticCoderField to create CustomCoder cannot be created for class className");
+
+ assertThatThrownBy(() -> new TopicCoderFilterConfiguration.CustomGsonCoder(",staticCoderField"))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("No classname to create CustomCoder cannot be created");
+
+ assertThatThrownBy(() -> new TopicCoderFilterConfiguration.CustomGsonCoder("className,"))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("No staticCoderField to create CustomCoder cannot be created for class className");
+
+ assertThatThrownBy(() -> new TopicCoderFilterConfiguration.CustomGsonCoder(""))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("Constructor argument cannot be empty.");
+ }
+} \ No newline at end of file
diff --git a/policy-management/src/test/java/org/onap/policy/drools/server/restful/RestManagerTest.java b/policy-management/src/test/java/org/onap/policy/drools/server/restful/RestManagerTest.java
new file mode 100644
index 00000000..89cce098
--- /dev/null
+++ b/policy-management/src/test/java/org/onap/policy/drools/server/restful/RestManagerTest.java
@@ -0,0 +1,1221 @@
+/*
+ * ============LICENSE_START=======================================================
+ * ONAP
+ * ================================================================================
+ * 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.
+ * 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.drools.server.restful;
+
+import static jakarta.ws.rs.core.Response.Status.BAD_REQUEST;
+import static jakarta.ws.rs.core.Response.Status.CREATED;
+import static jakarta.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR;
+import static jakarta.ws.rs.core.Response.Status.NOT_ACCEPTABLE;
+import static jakarta.ws.rs.core.Response.Status.NOT_FOUND;
+import static jakarta.ws.rs.core.Response.Status.NOT_MODIFIED;
+import static jakarta.ws.rs.core.Response.Status.OK;
+import static jakarta.ws.rs.core.Response.Status.PARTIAL_CONTENT;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.isNull;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.mockStatic;
+import static org.mockito.Mockito.when;
+import static org.onap.policy.drools.properties.DroolsPropertyConstants.PROPERTY_CONTROLLER_NAME;
+
+import jakarta.ws.rs.core.Response;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+import java.util.concurrent.ScheduledExecutorService;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.Mock;
+import org.mockito.MockedStatic;
+import org.mockito.MockitoAnnotations;
+import org.onap.policy.common.endpoints.event.comm.TopicEndpoint;
+import org.onap.policy.common.endpoints.event.comm.TopicEndpointManager;
+import org.onap.policy.drools.controller.DroolsController;
+import org.onap.policy.drools.controller.internal.NullDroolsController;
+import org.onap.policy.drools.features.PolicyControllerFeatureApi;
+import org.onap.policy.drools.features.PolicyEngineFeatureApi;
+import org.onap.policy.drools.protocol.coders.EventProtocolCoder;
+import org.onap.policy.drools.protocol.coders.EventProtocolCoderConstants;
+import org.onap.policy.drools.protocol.coders.JsonProtocolFilter;
+import org.onap.policy.drools.protocol.coders.ProtocolCoderToolset;
+import org.onap.policy.drools.protocol.configuration.ControllerConfiguration;
+import org.onap.policy.drools.protocol.configuration.PdpdConfiguration;
+import org.onap.policy.drools.system.PolicyController;
+import org.onap.policy.drools.system.PolicyControllerConstants;
+import org.onap.policy.drools.system.PolicyControllerFactory;
+import org.onap.policy.drools.system.PolicyDroolsPdpRuntimeException;
+import org.onap.policy.drools.system.PolicyEngineConstants;
+import org.onap.policy.drools.system.PolicyEngineManager;
+import org.onap.policy.drools.system.internal.AggregatedPolicyController;
+import org.onap.policy.drools.system.internal.LockManager;
+import org.slf4j.ILoggerFactory;
+import org.slf4j.LoggerFactory;
+import org.springframework.test.util.ReflectionTestUtils;
+
+class RestManagerTest {
+
+ private static final String CONTROLLER_NAME = "myControllerName";
+ private static final String FACT_CLASS = "factClass";
+ private static final String TOPIC = "topic";
+ private static final String GROUP_ID = "group";
+ private static final String ARTIFACT_ID = "artifact";
+
+ @Mock
+ RestManager restApi;
+
+ @Mock
+ PolicyControllerFactory controllerFactory;
+
+ @Mock
+ EventProtocolCoder coderManager;
+
+ @Mock
+ TopicEndpoint topicManager;
+
+ @Mock
+ PolicyEngineManager policyEngineManager;
+
+ AutoCloseable closeable;
+
+ @BeforeEach
+ void setUp() {
+ closeable = MockitoAnnotations.openMocks(this);
+
+ try (MockedStatic<TopicEndpointManager> constants = mockStatic(TopicEndpointManager.class)) {
+ setupTopicEndpointManager(constants);
+ restApi = mock(RestManager.class);
+ }
+ }
+
+ @AfterEach
+ void tearDown() throws Exception {
+ closeable.close();
+ }
+
+ @Test
+ void swagger() {
+ when(restApi.swagger()).thenCallRealMethod();
+ var response = restApi.swagger();
+ assertNotNull(response);
+ assertInstanceOf(Response.class, response);
+ assertEquals(OK.getStatusCode(), response.getStatus());
+
+ when(restApi.getSwaggerContents()).thenThrow(new PolicyDroolsPdpRuntimeException("exception"));
+
+ response = restApi.swagger();
+ assertNotNull(response);
+ assertInstanceOf(Response.class, response);
+ assertEquals(INTERNAL_SERVER_ERROR.getStatusCode(), response.getStatus());
+ }
+
+ @Test
+ void engineShutdown() {
+ try (MockedStatic<PolicyEngineConstants> constants = mockStatic(PolicyEngineConstants.class)) {
+ setupLockManagerAndExecutorService();
+
+ doNothing().doThrow(new IllegalStateException("should throw exception"))
+ .when(policyEngineManager).shutdown();
+
+ setupPolicyEngineManager(constants);
+
+ restApi = mock(RestManager.class);
+
+ when(restApi.engineShutdown()).thenCallRealMethod();
+
+ var response = restApi.engineShutdown();
+ assertNotNull(response);
+ assertInstanceOf(Response.class, response);
+ assertEquals(OK.getStatusCode(), response.getStatus());
+
+ response = restApi.engineShutdown();
+ assertEquals(BAD_REQUEST.getStatusCode(), response.getStatus());
+ }
+ }
+
+ @Test
+ void engineFeature() {
+ try (MockedStatic<PolicyEngineConstants> constants = mockStatic(PolicyEngineConstants.class)) {
+ setupLockManagerAndExecutorService();
+ when(policyEngineManager.getFeatureProvider("testFeature"))
+ .thenReturn(mock(PolicyEngineFeatureApi.class))
+ .thenThrow(new IllegalArgumentException("should throw exception"));
+
+ setupPolicyEngineManager(constants);
+
+ restApi = mock(RestManager.class);
+ when(restApi.engineFeature("testFeature")).thenCallRealMethod();
+
+ var response = restApi.engineFeature("testFeature");
+ assertNotNull(response);
+ assertInstanceOf(Response.class, response);
+ assertEquals(OK.getStatusCode(), response.getStatus());
+
+ response = restApi.engineFeature("testFeature");
+ assertEquals(NOT_FOUND.getStatusCode(), response.getStatus());
+ assertEquals("should throw exception", ((RestManager.Error) response.getEntity()).getError());
+ }
+ }
+
+ @Test
+ void engineUpdate() {
+ try (MockedStatic<PolicyEngineConstants> constants = mockStatic(PolicyEngineConstants.class)) {
+ setupLockManagerAndExecutorService();
+ var pdpdConfig = mock(PdpdConfiguration.class);
+ when(policyEngineManager.configure(pdpdConfig))
+ .thenReturn(true)
+ .thenReturn(false)
+ .thenThrow(new IllegalArgumentException("should throw exception"));
+
+ setupPolicyEngineManager(constants);
+
+ restApi = mock(RestManager.class);
+ when(restApi.engineUpdate(pdpdConfig)).thenCallRealMethod();
+
+ var response = restApi.engineUpdate(pdpdConfig);
+ assertNotNull(response);
+ assertInstanceOf(Response.class, response);
+ assertEquals(OK.getStatusCode(), response.getStatus());
+
+ response = restApi.engineUpdate(pdpdConfig);
+ assertEquals(NOT_ACCEPTABLE.getStatusCode(), response.getStatus());
+
+ // call again, should be going on exception
+ response = restApi.engineUpdate(pdpdConfig);
+ assertEquals(NOT_ACCEPTABLE.getStatusCode(), response.getStatus());
+ }
+ }
+
+ @Test
+ void engineActivation() {
+ try (MockedStatic<PolicyEngineConstants> constants = mockStatic(PolicyEngineConstants.class)) {
+ setupLockManagerAndExecutorService();
+ doNothing().doThrow(new IllegalStateException("should throw exception"))
+ .when(policyEngineManager).activate();
+
+ setupPolicyEngineManager(constants);
+
+ restApi = mock(RestManager.class);
+ when(restApi.engineActivation()).thenCallRealMethod();
+
+ var response = restApi.engineActivation();
+ assertNotNull(response);
+ assertInstanceOf(Response.class, response);
+ assertEquals(OK.getStatusCode(), response.getStatus());
+
+ response = restApi.engineActivation();
+ assertEquals(NOT_ACCEPTABLE.getStatusCode(), response.getStatus());
+ }
+ }
+
+ @Test
+ void engineDeactivation() {
+ try (MockedStatic<PolicyEngineConstants> constants = mockStatic(PolicyEngineConstants.class)) {
+ setupLockManagerAndExecutorService();
+ doNothing().doThrow(new IllegalStateException("should throw exception"))
+ .when(policyEngineManager).deactivate();
+
+ setupPolicyEngineManager(constants);
+
+ restApi = mock(RestManager.class);
+ when(restApi.engineDeactivation()).thenCallRealMethod();
+
+ var response = restApi.engineDeactivation();
+ assertNotNull(response);
+ assertInstanceOf(Response.class, response);
+ assertEquals(OK.getStatusCode(), response.getStatus());
+
+ response = restApi.engineDeactivation();
+ assertEquals(NOT_ACCEPTABLE.getStatusCode(), response.getStatus());
+ }
+ }
+
+ @Test
+ void controllerAdd() {
+ try (MockedStatic<PolicyControllerConstants> controllerConst = mockStatic(PolicyControllerConstants.class)) {
+ try (MockedStatic<PolicyEngineConstants> engConst = mockStatic(PolicyEngineConstants.class)) {
+ setupLockManagerAndExecutorService();
+
+ when(controllerFactory.get(CONTROLLER_NAME))
+ .thenReturn(mock(AggregatedPolicyController.class))
+ .thenThrow(new IllegalStateException("exception to test fetch policy failed"))
+ .thenReturn(null);
+
+ setupPolicyControllerFactory(controllerConst);
+
+ var invalidProps = new Properties();
+ invalidProps.setProperty(PROPERTY_CONTROLLER_NAME, "");
+
+ var properties = new Properties();
+ properties.setProperty(PROPERTY_CONTROLLER_NAME, CONTROLLER_NAME);
+
+ var policyController = mock(PolicyController.class);
+ when(policyController.start())
+ .thenReturn(false)
+ .thenThrow(new IllegalStateException("exception when starting controller"))
+ .thenReturn(true);
+
+ when(policyEngineManager.createPolicyController(CONTROLLER_NAME, properties))
+ .thenThrow(new IllegalArgumentException("exception creating controller"))
+ .thenReturn(policyController);
+
+ setupPolicyEngineManager(engConst);
+
+ restApi = mock(RestManager.class);
+
+ when(restApi.controllerAdd(null)).thenCallRealMethod();
+ when(restApi.controllerAdd(invalidProps)).thenCallRealMethod();
+ when(restApi.controllerAdd(properties)).thenCallRealMethod();
+
+ // first test - null properties config
+ var response = restApi.controllerAdd(null);
+ assertNotNull(response);
+ assertInstanceOf(Response.class, response);
+ assertEquals(BAD_REQUEST.getStatusCode(), response.getStatus());
+
+ // second test - controllerName is empty
+ response = restApi.controllerAdd(invalidProps);
+ assertEquals(BAD_REQUEST.getStatusCode(), response.getStatus());
+ assertThat(((RestManager.Error) response.getEntity()).getError())
+ .contains("Configuration must have an entry for controller.name");
+
+ // third test - controller exists
+ response = restApi.controllerAdd(properties);
+ assertEquals(NOT_MODIFIED.getStatusCode(), response.getStatus());
+
+ // fourth test - IllegalStateException
+ response = restApi.controllerAdd(properties);
+ assertEquals(NOT_ACCEPTABLE.getStatusCode(), response.getStatus());
+ assertThat(((RestManager.Error) response.getEntity()).getError())
+ .contains("myControllerName not found");
+
+ // fifth test - cannot create controller
+ response = restApi.controllerAdd(properties);
+ assertEquals(BAD_REQUEST.getStatusCode(), response.getStatus());
+ assertThat(((RestManager.Error) response.getEntity()).getError())
+ .contains("exception creating controller");
+
+ // sixth test - cannot start controller
+ response = restApi.controllerAdd(properties);
+ assertEquals(PARTIAL_CONTENT.getStatusCode(), response.getStatus());
+ assertThat(((RestManager.Error) response.getEntity()).getError())
+ .contains("myControllerName can't be started");
+
+ // seventh test - cannot start controller but Exception
+ response = restApi.controllerAdd(properties);
+ assertEquals(PARTIAL_CONTENT.getStatusCode(), response.getStatus());
+ assertEquals(policyController, response.getEntity());
+
+ // final test - works
+ response = restApi.controllerAdd(properties);
+ assertEquals(CREATED.getStatusCode(), response.getStatus());
+ assertEquals(policyController, response.getEntity());
+ }
+ }
+ }
+
+ @Test
+ void controllerFeature() {
+ try (MockedStatic<PolicyControllerConstants> controllerConst = mockStatic(PolicyControllerConstants.class)) {
+ var myFeature = mock(PolicyControllerFeatureApi.class);
+ when(controllerFactory.getFeatureProvider("myFeature"))
+ .thenReturn(myFeature)
+ .thenThrow(new IllegalArgumentException("exception when getting feature"));
+ setupPolicyControllerFactory(controllerConst);
+
+ restApi = mock(RestManager.class);
+ when(restApi.controllerFeature("myFeature")).thenCallRealMethod();
+
+ var response = restApi.controllerFeature("myFeature");
+ assertNotNull(response);
+ assertInstanceOf(Response.class, response);
+ assertEquals(OK.getStatusCode(), response.getStatus());
+ assertEquals(myFeature, response.getEntity());
+
+ response = restApi.controllerFeature("myFeature");
+ assertEquals(NOT_FOUND.getStatusCode(), response.getStatus());
+ assertThat(((RestManager.Error) response.getEntity()).getError())
+ .contains("exception when getting feature");
+ }
+ }
+
+ @Test
+ void controllerDelete() {
+ try (MockedStatic<PolicyControllerConstants> controllerConst = mockStatic(PolicyControllerConstants.class)) {
+ try (MockedStatic<PolicyEngineConstants> engConst = mockStatic(PolicyEngineConstants.class)) {
+ setupLockManagerAndExecutorService();
+
+ var policyController = mock(PolicyController.class);
+
+ when(controllerFactory.get("nullController"))
+ .thenReturn(null);
+ when(controllerFactory.get("exceptionController"))
+ .thenThrow(new IllegalArgumentException("can't find the controller"))
+ .thenThrow(new IllegalStateException("exception to test fetch policy controller"));
+ when(controllerFactory.get("myValidController")).thenReturn(policyController);
+
+ setupPolicyControllerFactory(controllerConst);
+
+ doThrow(new IllegalStateException("exception when deleting controller"))
+ .doNothing()
+ .when(policyEngineManager).removePolicyController("myValidController");
+
+ setupPolicyEngineManager(engConst);
+
+ restApi = mock(RestManager.class);
+ when(restApi.controllerDelete(anyString())).thenCallRealMethod();
+
+ // first test - controller returns null
+ var response = restApi.controllerDelete("nullController");
+ assertNotNull(response);
+ assertInstanceOf(Response.class, response);
+ assertEquals(BAD_REQUEST.getStatusCode(), response.getStatus());
+ assertThat(((RestManager.Error) response.getEntity()).getError())
+ .contains("nullController does not exist");
+
+ // second test - getController throws IllegalArgExc
+ response = restApi.controllerDelete("exceptionController");
+ assertEquals(BAD_REQUEST.getStatusCode(), response.getStatus());
+ assertThat(((RestManager.Error) response.getEntity()).getError())
+ .contains("can't find the controller");
+
+ // third test - getController throws IllegalStateExc
+ response = restApi.controllerDelete("exceptionController");
+ assertEquals(NOT_ACCEPTABLE.getStatusCode(), response.getStatus());
+ assertThat(((RestManager.Error) response.getEntity()).getError())
+ .contains("exceptionController not acceptable");
+
+ // fourth test - gets controller but exception when removing
+ response = restApi.controllerDelete("myValidController");
+ assertEquals(INTERNAL_SERVER_ERROR.getStatusCode(), response.getStatus());
+ assertThat(((RestManager.Error) response.getEntity()).getError())
+ .contains("exception when deleting controller");
+
+ // fifth test - gets controller and removes it from engine manager
+ response = restApi.controllerDelete("myValidController");
+ assertEquals(OK.getStatusCode(), response.getStatus());
+ assertEquals(policyController, response.getEntity());
+ }
+ }
+ }
+
+ @Test
+ void controllerUpdate() {
+ try (MockedStatic<PolicyEngineConstants> constants = mockStatic(PolicyEngineConstants.class)) {
+ setupLockManagerAndExecutorService();
+
+ var config = mock(ControllerConfiguration.class);
+ when(config.getName()).thenReturn(CONTROLLER_NAME);
+
+ var policyController = mock(PolicyController.class);
+ when(policyEngineManager.updatePolicyController(config))
+ .thenThrow(new IllegalArgumentException("exception to test fetch policy controller"))
+ .thenReturn(null)
+ .thenReturn(policyController);
+
+ setupPolicyEngineManager(constants);
+
+ restApi = mock(RestManager.class);
+ when(restApi.catchArgStateGenericEx(any(), any())).thenCallRealMethod();
+ when(restApi.controllerUpdate(config, "invalidName")).thenCallRealMethod();
+ when(restApi.controllerUpdate(config, CONTROLLER_NAME)).thenCallRealMethod();
+ when(restApi.controllerUpdate(null, CONTROLLER_NAME)).thenCallRealMethod();
+ when(restApi.controllerUpdate(config, "")).thenCallRealMethod();
+
+ // invalid controller name
+ var response = restApi.controllerUpdate(config, "");
+ assertNotNull(response);
+ assertInstanceOf(Response.class, response);
+ assertEquals(BAD_REQUEST.getStatusCode(), response.getStatus());
+
+ // controller configuration is null
+ response = restApi.controllerUpdate(null, CONTROLLER_NAME);
+ assertEquals(BAD_REQUEST.getStatusCode(), response.getStatus());
+
+ // controller name doesn't match name in configuration
+ response = restApi.controllerUpdate(config, "invalidName");
+ assertEquals(BAD_REQUEST.getStatusCode(), response.getStatus());
+
+ // IllegalArgException
+ response = restApi.controllerUpdate(config, CONTROLLER_NAME);
+ assertEquals(NOT_FOUND.getStatusCode(), response.getStatus());
+
+ // return null controller
+ response = restApi.controllerUpdate(config, CONTROLLER_NAME);
+ assertEquals(BAD_REQUEST.getStatusCode(), response.getStatus());
+
+ // return valid controller
+ response = restApi.controllerUpdate(config, CONTROLLER_NAME);
+ assertEquals(OK.getStatusCode(), response.getStatus());
+ assertEquals(policyController, response.getEntity());
+ }
+ }
+
+ @Test
+ void controllerLock() {
+ try (MockedStatic<PolicyControllerConstants> controllerConst = mockStatic(PolicyControllerConstants.class)) {
+ var policyController = mock(PolicyController.class);
+ when(policyController.lock())
+ .thenReturn(true)
+ .thenReturn(false);
+
+ when(controllerFactory.get(CONTROLLER_NAME)).thenReturn(policyController);
+
+ setupPolicyControllerFactory(controllerConst);
+
+ restApi = mock(RestManager.class);
+
+ when(restApi.controllerLock(CONTROLLER_NAME)).thenCallRealMethod();
+
+ // controller lock
+ var response = restApi.controllerLock(CONTROLLER_NAME);
+ assertNotNull(response);
+ assertInstanceOf(Response.class, response);
+ assertEquals(OK.getStatusCode(), response.getStatus());
+ assertEquals(policyController, response.getEntity());
+
+ // controller fails to lock
+ response = restApi.controllerLock(CONTROLLER_NAME);
+ assertEquals(NOT_ACCEPTABLE.getStatusCode(), response.getStatus());
+ assertThat(((RestManager.Error) response.getEntity()).getError())
+ .contains("myControllerName cannot be locked");
+ }
+ }
+
+ @Test
+ void controllerUnlock() {
+ try (MockedStatic<PolicyControllerConstants> controllerConst = mockStatic(PolicyControllerConstants.class)) {
+ var policyController = mock(PolicyController.class);
+ when(policyController.unlock())
+ .thenReturn(true)
+ .thenReturn(false);
+
+ when(controllerFactory.get(CONTROLLER_NAME)).thenReturn(policyController);
+
+ setupPolicyControllerFactory(controllerConst);
+
+ restApi = mock(RestManager.class);
+
+ when(restApi.controllerUnlock(CONTROLLER_NAME)).thenCallRealMethod();
+
+ // controller unlock
+ var response = restApi.controllerUnlock(CONTROLLER_NAME);
+ assertNotNull(response);
+ assertInstanceOf(Response.class, response);
+ assertEquals(OK.getStatusCode(), response.getStatus());
+ assertEquals(policyController, response.getEntity());
+
+ // controller fails to unlock
+ response = restApi.controllerUnlock(CONTROLLER_NAME);
+ assertEquals(NOT_ACCEPTABLE.getStatusCode(), response.getStatus());
+ assertThat(((RestManager.Error) response.getEntity()).getError())
+ .contains("myControllerName cannot be unlocked");
+ }
+ }
+
+ @Test
+ void droolsFactsDelete() {
+ try (MockedStatic<PolicyControllerConstants> controllerConst = mockStatic(PolicyControllerConstants.class)) {
+ var sessionName = "sessionName";
+ var queryName = "queryName";
+ var queriedEntity = "queriedEntity";
+
+ var drools = mock(NullDroolsController.class);
+ when(drools.factQuery(sessionName, queryName, queriedEntity, true))
+ .thenReturn(new ArrayList<>(List.of()));
+ var policyController = mock(PolicyController.class);
+ when(policyController.getDrools()).thenReturn(drools);
+
+ var controllerWithoutDrools = mock(PolicyController.class);
+ when(controllerWithoutDrools.getDrools()).thenReturn(null);
+
+ when(controllerFactory.get("nullController")).thenReturn(null);
+ when(controllerFactory.get("controllerWithoutDrools")).thenReturn(controllerWithoutDrools);
+ when(controllerFactory.get(CONTROLLER_NAME)).thenReturn(policyController);
+
+ setupPolicyControllerFactory(controllerConst);
+
+ restApi = mock(RestManager.class);
+
+ when(restApi.catchArgStateGenericEx(any(), any())).thenCallRealMethod();
+ when(restApi.getDroolsController(anyString())).thenCallRealMethod();
+ when(restApi.droolsFactsDelete("nullController", sessionName, queryName, queriedEntity))
+ .thenCallRealMethod();
+ when(restApi.droolsFactsDelete("controllerWithoutDrools", sessionName, queryName, queriedEntity))
+ .thenCallRealMethod();
+ when(restApi.droolsFactsDelete(CONTROLLER_NAME, sessionName, queryName, queriedEntity))
+ .thenCallRealMethod();
+
+ // controller is null
+ var response = restApi.droolsFactsDelete("nullController", sessionName, queryName, queriedEntity);
+ assertNotNull(response);
+ assertInstanceOf(Response.class, response);
+ assertEquals(NOT_FOUND.getStatusCode(), response.getStatus());
+ assertEquals("nullController:sessionName:queryName:queriedEntity not found",
+ ((RestManager.Error) response.getEntity()).getError());
+
+ // controller has no drools
+ response = restApi.droolsFactsDelete("controllerWithoutDrools", sessionName, queryName, queriedEntity);
+ assertEquals(NOT_FOUND.getStatusCode(), response.getStatus());
+ assertEquals("controllerWithoutDrools:sessionName:queryName:queriedEntity not found",
+ ((RestManager.Error) response.getEntity()).getError());
+
+ // delete works
+ response = restApi.droolsFactsDelete(CONTROLLER_NAME, sessionName, queryName, queriedEntity);
+ assertEquals(OK.getStatusCode(), response.getStatus());
+ assertInstanceOf(List.class, response.getEntity());
+ }
+ }
+
+ @Test
+ void rules() {
+ when(restApi.rules(anyString())).thenCallRealMethod();
+ var response = restApi.rules("expression");
+ assertNotNull(response);
+ assertInstanceOf(Response.class, response);
+ assertEquals(OK.getStatusCode(), response.getStatus());
+ }
+
+ @Test
+ void decoderFilter2() {
+ try (MockedStatic<EventProtocolCoderConstants> constants = mockStatic(EventProtocolCoderConstants.class)) {
+ var decoder = mock(ProtocolCoderToolset.class);
+ when(decoder.getCoders()).thenReturn(new ArrayList<>(List.of()));
+ when(coderManager.getDecoders(GROUP_ID, ARTIFACT_ID, TOPIC))
+ .thenReturn(decoder);
+ when(coderManager.getDecoders(GROUP_ID, ARTIFACT_ID, "invalidTopic"))
+ .thenReturn(null);
+
+ setupEventProtocolManager(constants);
+
+ var drools = getDroolsControllerWithGroupArtifact();
+ restApi = mock(RestManager.class);
+ when(restApi.getDroolsController(CONTROLLER_NAME)).thenReturn(drools);
+ when(restApi.catchArgStateGenericEx(any(), any())).thenCallRealMethod();
+ when(restApi.decoderFilter2(anyString(), anyString())).thenCallRealMethod();
+ when(restApi.getDroolsController("noDecoderCtrl")).thenReturn(drools);
+ when(restApi.getDroolsController("exceptionCtrl"))
+ .thenThrow(new IllegalArgumentException("exceptionCtrl"));
+
+ // should be ok
+ var response = restApi.decoderFilter2(CONTROLLER_NAME, TOPIC);
+ assertNotNull(response);
+ assertInstanceOf(Response.class, response);
+ assertEquals(OK.getStatusCode(), response.getStatus());
+ assertInstanceOf(List.class, response.getEntity());
+
+ // controller has no decoder
+ response = restApi.decoderFilter2("noDecoderCtrl", "invalidTopic");
+ assertNotNull(response);
+ assertInstanceOf(Response.class, response);
+ assertEquals(BAD_REQUEST.getStatusCode(), response.getStatus());
+
+ // can't get a controller
+ response = restApi.decoderFilter2("exceptionCtrl", TOPIC);
+ assertNotNull(response);
+ assertInstanceOf(Response.class, response);
+ assertEquals(NOT_FOUND.getStatusCode(), response.getStatus());
+ }
+ }
+
+ @Test
+ void decoderFilter1() {
+ try (MockedStatic<EventProtocolCoderConstants> constants = mockStatic(EventProtocolCoderConstants.class)) {
+ var decoder = mock(ProtocolCoderToolset.class);
+ when(decoder.getCoder(FACT_CLASS)).thenReturn(mock(EventProtocolCoder.CoderFilters.class));
+ when(decoder.getCoder("invalidClass")).thenReturn(null);
+
+ when(coderManager.getDecoders(GROUP_ID, ARTIFACT_ID, TOPIC))
+ .thenReturn(decoder);
+ when(coderManager.getDecoders(GROUP_ID, ARTIFACT_ID, "invalidTopic"))
+ .thenThrow(new IllegalArgumentException("exception"));
+
+ setupEventProtocolManager(constants);
+
+ var drools = getDroolsControllerWithGroupArtifact();
+ restApi = mock(RestManager.class);
+ when(restApi.getDroolsController(CONTROLLER_NAME)).thenReturn(drools);
+ when(restApi.catchArgStateGenericEx(any(), any())).thenCallRealMethod();
+ when(restApi.decoderFilter1(anyString(), anyString(), anyString())).thenCallRealMethod();
+
+ // should be ok
+ var response = restApi.decoderFilter1(CONTROLLER_NAME, TOPIC, FACT_CLASS);
+ assertNotNull(response);
+ assertInstanceOf(Response.class, response);
+ assertEquals(OK.getStatusCode(), response.getStatus());
+ assertInstanceOf(EventProtocolCoder.CoderFilters.class, response.getEntity());
+
+ // controller has no decoder
+ response = restApi.decoderFilter1(CONTROLLER_NAME, TOPIC, "invalidClass");
+ assertNotNull(response);
+ assertInstanceOf(Response.class, response);
+ assertEquals(BAD_REQUEST.getStatusCode(), response.getStatus());
+
+ // can't get a controller
+ response = restApi.decoderFilter1(CONTROLLER_NAME, "invalidTopic", FACT_CLASS);
+ assertNotNull(response);
+ assertInstanceOf(Response.class, response);
+ assertEquals(NOT_FOUND.getStatusCode(), response.getStatus());
+ }
+ }
+
+ @Test
+ void decoderFilter() {
+ try (MockedStatic<EventProtocolCoderConstants> constants = mockStatic(EventProtocolCoderConstants.class)) {
+ var coderFilter = new EventProtocolCoder.CoderFilters(FACT_CLASS, new JsonProtocolFilter(), 1);
+
+ var decoder = mock(ProtocolCoderToolset.class);
+ when(decoder.getCoder(FACT_CLASS)).thenReturn(coderFilter);
+ when(decoder.getCoder("invalidClass")).thenReturn(null);
+
+ when(coderManager.getDecoders(GROUP_ID, ARTIFACT_ID, TOPIC))
+ .thenReturn(decoder);
+ when(coderManager.getDecoders(GROUP_ID, ARTIFACT_ID, "invalidTopic"))
+ .thenThrow(new IllegalArgumentException("exception"));
+
+ setupEventProtocolManager(constants);
+
+
+ restApi = mock(RestManager.class);
+ var configFilters = new JsonProtocolFilter();
+ when(restApi.decoderFilter(eq(configFilters), eq(CONTROLLER_NAME), anyString(),
+ anyString())).thenCallRealMethod();
+ when(restApi.catchArgStateGenericEx(any(), any())).thenCallRealMethod();
+ when(restApi.decoderFilter(isNull(), eq(CONTROLLER_NAME), anyString(), anyString())).thenCallRealMethod();
+ var drools = getDroolsControllerWithGroupArtifact();
+ when(restApi.getDroolsController(CONTROLLER_NAME)).thenReturn(drools);
+
+ // should be ok
+ var response = restApi.decoderFilter(configFilters, CONTROLLER_NAME, TOPIC, FACT_CLASS);
+ assertNotNull(response);
+ assertInstanceOf(Response.class, response);
+ assertEquals(OK.getStatusCode(), response.getStatus());
+ if (response.getEntity() instanceof EventProtocolCoder.CoderFilters) {
+ var filters = (EventProtocolCoder.CoderFilters) response.getEntity();
+ assertEquals(configFilters, filters.getFilter());
+ }
+
+ // controller has no decoder
+ response = restApi.decoderFilter(configFilters, CONTROLLER_NAME, TOPIC, "invalidClass");
+ assertNotNull(response);
+ assertEquals(BAD_REQUEST.getStatusCode(), response.getStatus());
+
+ // can't get a controller
+ response = restApi.decoderFilter(configFilters, CONTROLLER_NAME, "invalidTopic", FACT_CLASS);
+ assertNotNull(response);
+ assertEquals(NOT_FOUND.getStatusCode(), response.getStatus());
+
+ // can't get a controller
+ response = restApi.decoderFilter(null, CONTROLLER_NAME, "invalidTopic", "invalidClass");
+ assertNotNull(response);
+ assertEquals(BAD_REQUEST.getStatusCode(), response.getStatus());
+ }
+ }
+
+ @Test
+ void decoderFilterRules() {
+ when(restApi.catchArgStateGenericEx(any(), any())).thenCallRealMethod();
+ when(restApi.decoderFilterRules(anyString(), anyString(), anyString())).thenCallRealMethod();
+
+ when(restApi.checkControllerDecoderAndFilter(CONTROLLER_NAME, TOPIC, FACT_CLASS))
+ .thenReturn(new JsonProtocolFilter());
+ when(restApi.checkControllerDecoderAndFilter(CONTROLLER_NAME, TOPIC, "invalidClass"))
+ .thenReturn(Response.status(BAD_REQUEST).build());
+ // trying to trigger RuntimeException for code coverage - normally it wouldn't happen here
+ when(restApi.checkControllerDecoderAndFilter("invalidController", TOPIC, FACT_CLASS))
+ .thenReturn(null);
+
+ // should return a string rule
+ var response = restApi.decoderFilterRules(CONTROLLER_NAME, TOPIC, FACT_CLASS);
+ assertNotNull(response);
+ assertInstanceOf(Response.class, response);
+ assertEquals(OK.getStatusCode(), response.getStatus());
+ assertInstanceOf(String.class, response.getEntity());
+
+ // checkControllerEtc... returned error response, so it just returns it to function
+ response = restApi.decoderFilterRules(CONTROLLER_NAME, TOPIC, "invalidClass");
+ assertEquals(BAD_REQUEST.getStatusCode(), response.getStatus());
+
+ // the runtime exception
+ response = restApi.decoderFilterRules("invalidController", TOPIC, FACT_CLASS);
+ assertEquals(INTERNAL_SERVER_ERROR.getStatusCode(), response.getStatus());
+ }
+
+ @Test
+ void decoderFilterRuleDelete() {
+ when(restApi.catchArgStateGenericEx(any(), any())).thenCallRealMethod();
+ when(restApi.decoderFilterRuleDelete(anyString(), anyString(), anyString())).thenCallRealMethod();
+
+ when(restApi.checkControllerDecoderAndFilter(CONTROLLER_NAME, TOPIC, FACT_CLASS))
+ .thenReturn(new JsonProtocolFilter());
+ when(restApi.checkControllerDecoderAndFilter(CONTROLLER_NAME, TOPIC, "invalidClass"))
+ .thenReturn(Response.status(BAD_REQUEST).build());
+
+ // should return a string rule
+ var response = restApi.decoderFilterRuleDelete(CONTROLLER_NAME, TOPIC, FACT_CLASS);
+ assertNotNull(response);
+ assertInstanceOf(Response.class, response);
+ assertEquals(OK.getStatusCode(), response.getStatus());
+ assertInstanceOf(String.class, response.getEntity());
+
+ // checkControllerEtc... returned error response, so it just returns it to function
+ response = restApi.decoderFilterRuleDelete(CONTROLLER_NAME, TOPIC, "invalidClass");
+ assertEquals(BAD_REQUEST.getStatusCode(), response.getStatus());
+ }
+
+ @Test
+ void decoderFilterRule() {
+ when(restApi.catchArgStateGenericEx(any(), any())).thenCallRealMethod();
+ when(restApi.decoderFilterRule(anyString(), anyString(), anyString(), anyString())).thenCallRealMethod();
+
+ when(restApi.decoderFilterRule2(CONTROLLER_NAME, TOPIC, FACT_CLASS, "rule"))
+ .thenReturn(new JsonProtocolFilter().getRule());
+ when(restApi.decoderFilterRule2(CONTROLLER_NAME, TOPIC, FACT_CLASS, ""))
+ .thenCallRealMethod();
+ when(restApi.decoderFilterRule("invalidController", TOPIC, FACT_CLASS, "rule"))
+ .thenThrow(new IllegalArgumentException("invalid controller"));
+
+ var response = restApi.decoderFilterRule(CONTROLLER_NAME, TOPIC, FACT_CLASS, "rule");
+ assertNotNull(response);
+ assertInstanceOf(Response.class, response);
+ assertEquals(OK.getStatusCode(), response.getStatus());
+ assertInstanceOf(String.class, response.getEntity());
+
+ response = restApi.decoderFilterRule(CONTROLLER_NAME, TOPIC, FACT_CLASS, "");
+ assertEquals(BAD_REQUEST.getStatusCode(), response.getStatus());
+ assertInstanceOf(RestManager.Error.class, response.getEntity());
+
+ response = restApi.decoderFilterRule("invalidController", TOPIC, FACT_CLASS, "rule");
+ assertEquals(NOT_FOUND.getStatusCode(), response.getStatus());
+ assertInstanceOf(RestManager.Error.class, response.getEntity());
+ }
+
+ @Test
+ void decode_EmptyParams() {
+ when(restApi.decode(anyString(), anyString(), anyString())).thenCallRealMethod();
+
+ var response = restApi.decode(CONTROLLER_NAME, "", "json");
+ assertNotNull(response);
+ assertInstanceOf(Response.class, response);
+ assertEquals(NOT_ACCEPTABLE.getStatusCode(), response.getStatus());
+
+ response = restApi.decode("", TOPIC, "json");
+ assertNotNull(response);
+ assertInstanceOf(Response.class, response);
+ assertEquals(NOT_ACCEPTABLE.getStatusCode(), response.getStatus());
+ }
+
+ @Test
+ void decode() {
+ try (MockedStatic<EventProtocolCoderConstants> constants = mockStatic(EventProtocolCoderConstants.class)) {
+ var event = new Object();
+ when(coderManager.decode(GROUP_ID, ARTIFACT_ID, TOPIC, "json")).thenReturn(event);
+ when(coderManager.decode(GROUP_ID, ARTIFACT_ID, "otherTopic", "json")).thenReturn(event);
+ when(coderManager.decode(GROUP_ID, ARTIFACT_ID, TOPIC, "invalidJson"))
+ .thenThrow(new IllegalArgumentException("invalid json"));
+
+ when(coderManager.encode(TOPIC, event)).thenReturn("json");
+ when(coderManager.encode("otherTopic", event))
+ .thenThrow(new IllegalArgumentException("invalid topic"));
+
+ setupEventProtocolManager(constants);
+
+ var drools = getDroolsControllerWithGroupArtifact();
+
+ restApi = mock(RestManager.class);
+ when(restApi.getDroolsController(CONTROLLER_NAME)).thenReturn(drools);
+ when(restApi.decode(anyString(), anyString(), anyString())).thenCallRealMethod();
+
+ // should work
+ var response = restApi.decode(CONTROLLER_NAME, TOPIC, "json");
+ assertNotNull(response);
+ assertInstanceOf(Response.class, response);
+ assertEquals(OK.getStatusCode(), response.getStatus());
+ assertNotNull(response.getEntity());
+ if (response.getEntity() instanceof RestManager.CodingResult) {
+ var codingResult = (RestManager.CodingResult) response.getEntity();
+ assertTrue(codingResult.getDecoding());
+ assertTrue(codingResult.getEncoding());
+ assertEquals("json", codingResult.getJsonEncoding());
+ }
+
+ // can't decode
+ response = restApi.decode(CONTROLLER_NAME, TOPIC, "invalidJson");
+ assertEquals(BAD_REQUEST.getStatusCode(), response.getStatus());
+
+ // can't encode, but return decoded result
+ response = restApi.decode(CONTROLLER_NAME, "otherTopic", "json");
+ assertEquals(OK.getStatusCode(), response.getStatus());
+ assertNotNull(response.getEntity());
+ if (response.getEntity() instanceof RestManager.CodingResult) {
+ var codingResult = (RestManager.CodingResult) response.getEntity();
+ assertTrue(codingResult.getDecoding());
+ assertFalse(codingResult.getEncoding());
+ assertNull(codingResult.getJsonEncoding());
+ }
+ }
+ }
+
+ @Test
+ void encoderFilters() {
+ try (MockedStatic<EventProtocolCoderConstants> constants = mockStatic(EventProtocolCoderConstants.class)) {
+ when(coderManager.getEncoderFilters(GROUP_ID, ARTIFACT_ID))
+ .thenReturn(new ArrayList<>(List.of()));
+
+ setupEventProtocolManager(constants);
+
+ var drools = getDroolsControllerWithGroupArtifact();
+ when(restApi.getDroolsController(CONTROLLER_NAME)).thenReturn(drools);
+ when(restApi.getDroolsController("invalidController"))
+ .thenThrow(new IllegalArgumentException("invalid controller"));
+ when(restApi.catchArgStateGenericEx(any(), any())).thenCallRealMethod();
+ when(restApi.encoderFilters(anyString())).thenCallRealMethod();
+
+ // should work
+ var response = restApi.encoderFilters(CONTROLLER_NAME);
+ assertNotNull(response);
+ assertInstanceOf(Response.class, response);
+ assertEquals(OK.getStatusCode(), response.getStatus());
+ assertNotNull(response.getEntity());
+
+ // exceptions
+ response = restApi.encoderFilters("invalidController");
+ assertEquals(NOT_FOUND.getStatusCode(), response.getStatus());
+ }
+ }
+
+ @Test
+ void topicsLock() {
+ try (MockedStatic<TopicEndpointManager> constants = mockStatic(TopicEndpointManager.class)) {
+ when(topicManager.lock())
+ .thenReturn(true)
+ .thenReturn(false);
+ setupTopicEndpointManager(constants);
+
+ restApi = mock(RestManager.class);
+ when(restApi.topicsLock()).thenCallRealMethod();
+
+ // should work and return ok
+ var response = restApi.topicsLock();
+ assertNotNull(response);
+ assertInstanceOf(Response.class, response);
+ assertEquals(OK.getStatusCode(), response.getStatus());
+
+ // lock fails, return false
+ response = restApi.topicsLock();
+ assertNotNull(response);
+ assertEquals(NOT_ACCEPTABLE.getStatusCode(), response.getStatus());
+ }
+ }
+
+ @Test
+ void topicsUnlock() {
+ try (MockedStatic<TopicEndpointManager> constants = mockStatic(TopicEndpointManager.class)) {
+ when(topicManager.unlock())
+ .thenReturn(true)
+ .thenReturn(false);
+ setupTopicEndpointManager(constants);
+
+ restApi = mock(RestManager.class);
+ when(restApi.topicsUnlock()).thenCallRealMethod();
+
+ // should work and return ok
+ var response = restApi.topicsUnlock();
+ assertNotNull(response);
+ assertInstanceOf(Response.class, response);
+ assertEquals(OK.getStatusCode(), response.getStatus());
+
+ // lock fails, return false
+ response = restApi.topicsUnlock();
+ assertNotNull(response);
+ assertEquals(NOT_ACCEPTABLE.getStatusCode(), response.getStatus());
+ }
+ }
+
+ @Test
+ void commSources() {
+ try (MockedStatic<TopicEndpointManager> constants = mockStatic(TopicEndpointManager.class)) {
+ when(topicManager.getNoopTopicSources()).thenReturn(new ArrayList<>(List.of()));
+ when(topicManager.getKafkaTopicSources()).thenReturn(new ArrayList<>(List.of()));
+ setupTopicEndpointManager(constants);
+
+ restApi = mock(RestManager.class);
+ when(restApi.commSources(anyString())).thenCallRealMethod();
+
+ var response = restApi.commSources("noop");
+ assertNotNull(response);
+ assertInstanceOf(Response.class, response);
+ assertEquals(OK.getStatusCode(), response.getStatus());
+
+ response = restApi.commSources("kafka");
+ assertEquals(OK.getStatusCode(), response.getStatus());
+
+ // topic type rest valid not supported
+ response = restApi.commSources("rest");
+ assertEquals(BAD_REQUEST.getStatusCode(), response.getStatus());
+
+ // empty topic type
+ response = restApi.commSources("");
+ assertEquals(NOT_ACCEPTABLE.getStatusCode(), response.getStatus());
+ }
+ }
+
+ @Test
+ void commSinks() {
+ try (MockedStatic<TopicEndpointManager> constants = mockStatic(TopicEndpointManager.class)) {
+ when(topicManager.getNoopTopicSinks()).thenReturn(new ArrayList<>(List.of()));
+ when(topicManager.getKafkaTopicSinks()).thenReturn(new ArrayList<>(List.of()));
+ setupTopicEndpointManager(constants);
+
+ restApi = mock(RestManager.class);
+ when(restApi.commSinks(anyString())).thenCallRealMethod();
+
+ var response = restApi.commSinks("noop");
+ assertNotNull(response);
+ assertInstanceOf(Response.class, response);
+ assertEquals(OK.getStatusCode(), response.getStatus());
+
+ response = restApi.commSinks("kafka");
+ assertEquals(OK.getStatusCode(), response.getStatus());
+
+ // topic type rest valid but not supported
+ response = restApi.commSinks("rest");
+ assertEquals(BAD_REQUEST.getStatusCode(), response.getStatus());
+
+ // empty topic type
+ response = restApi.commSinks("");
+ assertEquals(NOT_ACCEPTABLE.getStatusCode(), response.getStatus());
+ }
+ }
+
+ @Test
+ void loggers() {
+ try (MockedStatic<LoggerFactory> loggerFactory = mockStatic(LoggerFactory.class)) {
+ var mockFactory = mock(ILoggerFactory.class);
+ loggerFactory.when(LoggerFactory::getILoggerFactory).thenReturn(mockFactory);
+
+ restApi = mock(RestManager.class);
+ when(restApi.loggers()).thenCallRealMethod();
+
+ var response = restApi.loggers();
+ assertNotNull(response);
+ assertInstanceOf(Response.class, response);
+ assertEquals(INTERNAL_SERVER_ERROR.getStatusCode(), response.getStatus());
+ }
+ }
+
+ @Test
+ void loggerName1() {
+ try (MockedStatic<LoggerFactory> loggerFactory = mockStatic(LoggerFactory.class)) {
+ var mockFactory = mock(ILoggerFactory.class);
+ loggerFactory.when(LoggerFactory::getILoggerFactory).thenReturn(mockFactory);
+
+ restApi = mock(RestManager.class);
+ when(restApi.loggerName1(anyString())).thenCallRealMethod();
+
+ var response = restApi.loggerName1("logger1");
+ assertNotNull(response);
+ assertInstanceOf(Response.class, response);
+ assertEquals(INTERNAL_SERVER_ERROR.getStatusCode(), response.getStatus());
+ }
+ }
+
+ @Test
+ void loggerName_EmptyValues() {
+ when(restApi.loggerName(anyString(), anyString())).thenCallRealMethod();
+
+ var response = restApi.loggerName("", "info");
+ assertNotNull(response);
+ assertInstanceOf(Response.class, response);
+ assertEquals(NOT_ACCEPTABLE.getStatusCode(), response.getStatus());
+ assertThat(((RestManager.Error) response.getEntity()).getError())
+ .contains("logger name: not acceptable");
+
+ response = restApi.loggerName("logger1", "");
+ assertNotNull(response);
+ assertInstanceOf(Response.class, response);
+ assertEquals(NOT_ACCEPTABLE.getStatusCode(), response.getStatus());
+ assertThat(((RestManager.Error) response.getEntity()).getError())
+ .contains("logger level: not acceptable");
+ }
+
+ @Test
+ void testLoggerName_Exceptions() {
+ when(restApi.loggerName(anyString(), anyString())).thenCallRealMethod();
+
+ var response = restApi.loggerName("audit", "abc");
+ assertNotNull(response);
+ assertInstanceOf(Response.class, response);
+ assertEquals(INTERNAL_SERVER_ERROR.getStatusCode(), response.getStatus());
+ }
+
+ @Test
+ void testCheckControllerDecoderAndFilter() {
+ try (MockedStatic<EventProtocolCoderConstants> constants = mockStatic(EventProtocolCoderConstants.class)) {
+ var coderFilter = new EventProtocolCoder.CoderFilters(FACT_CLASS, new JsonProtocolFilter(), 1);
+ var decoder = mock(ProtocolCoderToolset.class);
+ when(decoder.getCoder(FACT_CLASS)).thenReturn(coderFilter);
+
+ when(coderManager.getDecoders(GROUP_ID, ARTIFACT_ID, TOPIC))
+ .thenReturn(decoder);
+
+ var decoderWithoutFactClass = mock(ProtocolCoderToolset.class);
+ when(decoderWithoutFactClass.getCoder("noFactClass")).thenReturn(null);
+ when(coderManager.getDecoders(GROUP_ID, ARTIFACT_ID, "topic2"))
+ .thenReturn(decoderWithoutFactClass);
+
+ var coderFactClassWithoutFilter = mock(EventProtocolCoder.CoderFilters.class);
+ when(coderFactClassWithoutFilter.getFilter()).thenReturn(null);
+ var decoderWithoutFilter = mock(ProtocolCoderToolset.class);
+ when(decoderWithoutFilter.getCoder("noFilterClass")).thenReturn(coderFactClassWithoutFilter);
+ when(coderManager.getDecoders(GROUP_ID, ARTIFACT_ID, "topic3"))
+ .thenReturn(decoderWithoutFilter);
+
+ setupEventProtocolManager(constants);
+
+ restApi = mock(RestManager.class);
+
+ var drools = getDroolsControllerWithGroupArtifact();
+ when(restApi.getDroolsController(CONTROLLER_NAME)).thenReturn(drools);
+ when(restApi.getDroolsController("exceptionController"))
+ .thenThrow(new IllegalArgumentException("exception"));
+ when(restApi.catchArgStateGenericEx(any(), any())).thenCallRealMethod();
+ when(restApi.checkControllerDecoderAndFilter(anyString(), anyString(), anyString()))
+ .thenCallRealMethod();
+
+ // should work fine and get back JsonProtocolFilter object
+ var result = restApi.checkControllerDecoderAndFilter(CONTROLLER_NAME, TOPIC, FACT_CLASS);
+ assertNotNull(result);
+ assertInstanceOf(JsonProtocolFilter.class, result);
+
+ // decoder doesn't have coder based on noFactClass parameter
+ var response = restApi.checkControllerDecoderAndFilter(CONTROLLER_NAME, "topic2", "noFactClass");
+ assertNotNull(response);
+ if (response instanceof Response) {
+ var actualResponse = (Response) response;
+ assertEquals(BAD_REQUEST.getStatusCode(), actualResponse.getStatus());
+ assertThat(((RestManager.Error) actualResponse.getEntity()).getError())
+ .contains("noFactClass does not exist");
+ }
+
+ // decoder has factClass, but factClass has no filter
+ response = restApi.checkControllerDecoderAndFilter(CONTROLLER_NAME, "topic3", "noFilterClass");
+ assertNotNull(response);
+ if (response instanceof Response) {
+ var actualResponse = (Response) response;
+ assertEquals(BAD_REQUEST.getStatusCode(), actualResponse.getStatus());
+ assertThat(((RestManager.Error) actualResponse.getEntity()).getError())
+ .contains("noFilterClass has no filters");
+ }
+ }
+ }
+
+ @Test
+ void testDecoderFilterRule2() {
+ var filter = new JsonProtocolFilter();
+ when(restApi.checkControllerDecoderAndFilter(CONTROLLER_NAME, TOPIC, FACT_CLASS))
+ .thenReturn(filter);
+ when(restApi.checkControllerDecoderAndFilter(CONTROLLER_NAME, TOPIC, "invalidFactClass"))
+ .thenReturn(Response.status(BAD_REQUEST).build());
+
+ when(restApi.decoderFilterRule2(anyString(), anyString(), anyString(), anyString()))
+ .thenCallRealMethod();
+ when(restApi.decoderFilterRule2(anyString(), anyString(), anyString(), isNull()))
+ .thenCallRealMethod();
+
+ // should work
+ var result = restApi.decoderFilterRule2(CONTROLLER_NAME, TOPIC, FACT_CLASS, "rule");
+ assertNotNull(result);
+ assertInstanceOf(String.class, result);
+
+ // rule is null
+ var response = restApi.decoderFilterRule2(CONTROLLER_NAME, TOPIC, FACT_CLASS, null);
+ assertNotNull(response);
+ if (response instanceof Response) {
+ var actualResponse = (Response) response;
+ assertEquals(BAD_REQUEST.getStatusCode(), actualResponse.getStatus());
+ assertThat(((RestManager.Error) actualResponse.getEntity()).getError())
+ .contains("no filter rule provided");
+ }
+
+ // rule is empty string
+ response = restApi.decoderFilterRule2(CONTROLLER_NAME, TOPIC, FACT_CLASS, "");
+ assertNotNull(response);
+ if (response instanceof Response) {
+ var actualResponse = (Response) response;
+ assertEquals(BAD_REQUEST.getStatusCode(), actualResponse.getStatus());
+ assertThat(((RestManager.Error) actualResponse.getEntity()).getError())
+ .contains("no filter rule provided");
+ }
+
+ // checkControllerDecoderFilter returns error response
+ response = restApi.decoderFilterRule2(CONTROLLER_NAME, TOPIC, "invalidFactClass", "rule");
+ assertNotNull(response);
+ assertEquals(BAD_REQUEST.getStatusCode(), ((Response) response).getStatus());
+ }
+
+ private void setupPolicyEngineManager(MockedStatic<PolicyEngineConstants> constants) {
+ constants.when(PolicyEngineConstants::getManager).thenReturn(policyEngineManager);
+ assertEquals(policyEngineManager, PolicyEngineConstants.getManager());
+ }
+
+ private void setupLockManagerAndExecutorService() {
+ var executorService = mock(ScheduledExecutorService.class);
+ when(executorService.shutdownNow()).thenReturn(new ArrayList<>());
+ when(policyEngineManager.getExecutorService()).thenReturn(executorService);
+
+ var lockManager = mock(LockManager.class);
+ doNothing().when(lockManager).shutdown();
+ ReflectionTestUtils.setField(policyEngineManager, "lockManager", lockManager);
+ }
+
+ private void setupPolicyControllerFactory(MockedStatic<PolicyControllerConstants> constants) {
+ constants.when(PolicyControllerConstants::getFactory).thenReturn(controllerFactory);
+ assertEquals(controllerFactory, PolicyControllerConstants.getFactory());
+ }
+
+ private void setupEventProtocolManager(MockedStatic<EventProtocolCoderConstants> constants) {
+ constants.when(EventProtocolCoderConstants::getManager).thenReturn(coderManager);
+ assertEquals(coderManager, EventProtocolCoderConstants.getManager());
+ }
+
+ private void setupTopicEndpointManager(MockedStatic<TopicEndpointManager> constants) {
+ constants.when(TopicEndpointManager::getManager).thenReturn(topicManager);
+ assertEquals(topicManager, TopicEndpointManager.getManager());
+ }
+
+ private static DroolsController getDroolsControllerWithGroupArtifact() {
+ var drools = mock(DroolsController.class);
+ when(drools.getGroupId()).thenReturn(GROUP_ID);
+ when(drools.getArtifactId()).thenReturn(ARTIFACT_ID);
+ return drools;
+ }
+} \ No newline at end of file
diff --git a/policy-management/src/test/java/org/onap/policy/drools/server/restful/test/RestManagerTest.java b/policy-management/src/test/java/org/onap/policy/drools/server/restful/test/RestManagerTest.java
index 6a17f269..1ceff3d0 100644
--- a/policy-management/src/test/java/org/onap/policy/drools/server/restful/test/RestManagerTest.java
+++ b/policy-management/src/test/java/org/onap/policy/drools/server/restful/test/RestManagerTest.java
@@ -127,7 +127,6 @@ public class RestManagerTest {
Properties controllerProps = new Properties();
PolicyEngineConstants.getManager().createPolicyController(FOO_CONTROLLER, controllerProps);
- // client = HttpClients.createDefault();
CredentialsProvider provider = new BasicCredentialsProvider();
UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(TELEMETRY_USER, TELEMETRY_PASSWORD);
provider.setCredentials(AuthScope.ANY, credentials);
@@ -249,7 +248,7 @@ public class RestManagerTest {
private void requestTest(HttpRequestBase request, int statusCode) throws IOException {
CloseableHttpResponse resp = client.execute(request);
- logger.info(request.getRequestLine() + "response code: {}", resp.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", request.getRequestLine(), resp.getStatusLine().getStatusCode());
assertEquals(statusCode, resp.getStatusLine().getStatusCode());
request.releaseConnection();
}
@@ -291,13 +290,13 @@ public class RestManagerTest {
CloseableHttpResponse response;
httpGet = new HttpGet(HOST_URL + "/engine/swagger");
response = client.execute(httpGet);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
assertEquals(200, response.getStatusLine().getStatusCode());
httpGet.releaseConnection();
}
@Test
- void testGet() throws IOException {
+ void testGetEngine() throws IOException {
HttpGet httpGet;
CloseableHttpResponse response;
@@ -306,45 +305,46 @@ public class RestManagerTest {
* /engine/inputs /engine/properties /engine/environment /engine/switches
* /engine/controllers
*/
+
httpGet = new HttpGet(HOST_URL + "/engine");
response = client.execute(httpGet);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
assertEquals(200, response.getStatusLine().getStatusCode());
httpGet.releaseConnection();
httpGet = new HttpGet(HOST_URL + "/engine/features");
response = client.execute(httpGet);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
assertEquals(200, response.getStatusLine().getStatusCode());
httpGet.releaseConnection();
httpGet = new HttpGet(HOST_URL + "/engine/features/inventory");
response = client.execute(httpGet);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
assertEquals(200, response.getStatusLine().getStatusCode());
httpGet.releaseConnection();
httpGet = new HttpGet(HOST_URL + "/engine/features/foobar");
response = client.execute(httpGet);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
assertEquals(404, response.getStatusLine().getStatusCode());
httpGet.releaseConnection();
httpGet = new HttpGet(HOST_URL + "/engine/inputs");
response = client.execute(httpGet);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
assertEquals(200, response.getStatusLine().getStatusCode());
httpGet.releaseConnection();
httpGet = new HttpGet(HOST_URL + "/engine/properties");
response = client.execute(httpGet);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
assertEquals(200, response.getStatusLine().getStatusCode());
httpGet.releaseConnection();
httpGet = new HttpGet(HOST_URL + "/engine/environment");
response = client.execute(httpGet);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
assertEquals(200, response.getStatusLine().getStatusCode());
httpGet.releaseConnection();
@@ -352,26 +352,32 @@ public class RestManagerTest {
httpGet = new HttpGet(HOST_URL + "/engine/environment/foo");
response = client.execute(httpGet);
String responseBody = this.getResponseBody(response);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
- logger.info(httpGet.getRequestLine() + " response body: {}", responseBody);
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
+ logger.info("{} response body: {}", httpGet.getRequestLine(), responseBody);
assertEquals(200, response.getStatusLine().getStatusCode());
assertEquals("bar", responseBody);
httpGet.releaseConnection();
httpGet = new HttpGet(HOST_URL + "/engine/switches");
response = client.execute(httpGet);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
assertEquals(200, response.getStatusLine().getStatusCode());
httpGet.releaseConnection();
httpGet = new HttpGet(HOST_URL + "/engine/controllers");
response = client.execute(httpGet);
responseBody = this.getResponseBody(response);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
- logger.info(httpGet.getRequestLine() + " response body: {}", responseBody);
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
+ logger.info("{} response body: {}", httpGet.getRequestLine(), responseBody);
assertEquals(200, response.getStatusLine().getStatusCode());
assertEquals("[\"" + FOO_CONTROLLER + "\"]", responseBody);
httpGet.releaseConnection();
+ }
+
+ @Test
+ void testGet_EngineControllers() throws IOException {
+ HttpGet httpGet;
+ CloseableHttpResponse response;
/*
* GET: /engine/controllers/inventory /engine/controllers/features
@@ -381,39 +387,46 @@ public class RestManagerTest {
*/
httpGet = new HttpGet(HOST_URL + "/engine/controllers/inventory");
response = client.execute(httpGet);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
assertEquals(200, response.getStatusLine().getStatusCode());
httpGet.releaseConnection();
httpGet = new HttpGet(HOST_URL + "/engine/controllers/features");
response = client.execute(httpGet);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
assertEquals(200, response.getStatusLine().getStatusCode());
httpGet.releaseConnection();
httpGet = new HttpGet(HOST_URL + "/engine/controllers/features/inventory");
response = client.execute(httpGet);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
assertEquals(200, response.getStatusLine().getStatusCode());
httpGet.releaseConnection();
httpGet = new HttpGet(HOST_URL + "/engine/controllers/features/dummy");
response = client.execute(httpGet);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
assertEquals(404, response.getStatusLine().getStatusCode());
httpGet.releaseConnection();
httpGet = new HttpGet(HOST_URL + "/engine/controllers/" + FOO_CONTROLLER);
response = client.execute(httpGet);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
assertEquals(200, response.getStatusLine().getStatusCode());
httpGet.releaseConnection();
httpGet = new HttpGet(HOST_URL + "/engine/controllers/nonexistantcontroller");
response = client.execute(httpGet);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
assertEquals(404, response.getStatusLine().getStatusCode());
httpGet.releaseConnection();
+ }
+
+ @Test
+ void testGet() throws IOException {
+ HttpGet httpGet;
+ CloseableHttpResponse response;
+ String responseBody;
/*
* GET: /engine/controllers/controllerName/properties
@@ -423,52 +436,45 @@ public class RestManagerTest {
httpGet = new HttpGet(HOST_URL + "/engine/controllers/" + FOO_CONTROLLER + "/properties");
response = client.execute(httpGet);
responseBody = this.getResponseBody(response);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
- logger.info(httpGet.getRequestLine() + " response code: {}", responseBody);
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", httpGet.getRequestLine(), responseBody);
assertEquals(200, response.getStatusLine().getStatusCode());
assertEquals("{}", responseBody);
httpGet.releaseConnection();
httpGet = new HttpGet(HOST_URL + "/engine/controllers/nonexistantcontroller/properties");
response = client.execute(httpGet);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
assertEquals(404, response.getStatusLine().getStatusCode());
httpGet.releaseConnection();
httpGet = new HttpGet(HOST_URL + "/engine/controllers/" + FOO_CONTROLLER + "/inputs");
response = client.execute(httpGet);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
assertEquals(200, response.getStatusLine().getStatusCode());
httpGet.releaseConnection();
httpGet = new HttpGet(HOST_URL + "/engine/controllers/" + FOO_CONTROLLER + "/switches");
response = client.execute(httpGet);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
assertEquals(200, response.getStatusLine().getStatusCode());
httpGet.releaseConnection();
httpGet = new HttpGet(HOST_URL + "/engine/controllers/" + FOO_CONTROLLER + "/drools");
response = client.execute(httpGet);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
assertEquals(200, response.getStatusLine().getStatusCode());
httpGet.releaseConnection();
httpGet = new HttpGet(HOST_URL + "/engine/controllers/nonexistantcontroller/drools");
response = client.execute(httpGet);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
assertEquals(404, response.getStatusLine().getStatusCode());
httpGet.releaseConnection();
-
- testGetDroolsControllers();
-
- testGetControllersDecoders();
-
- testGetTopics();
-
- testGetEngineTools();
}
- private static void testGetDroolsControllers() throws IOException {
+ @Test
+ void testGetDroolsControllers() throws IOException {
CloseableHttpResponse response;
HttpGet httpGet;
/*
@@ -480,43 +486,44 @@ public class RestManagerTest {
*/
httpGet = new HttpGet(HOST_URL + "/engine/controllers/" + FOO_CONTROLLER + "/drools/facts");
response = client.execute(httpGet);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
assertEquals(200, response.getStatusLine().getStatusCode());
httpGet.releaseConnection();
httpGet = new HttpGet(HOST_URL + "/engine/controllers/nonexistantcontroller/drools/facts");
response = client.execute(httpGet);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
assertEquals(404, response.getStatusLine().getStatusCode());
httpGet.releaseConnection();
httpGet = new HttpGet(HOST_URL + "/engine/controllers/" + FOO_CONTROLLER + "/drools/facts/session");
response = client.execute(httpGet);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
assertEquals(200, response.getStatusLine().getStatusCode());
httpGet.releaseConnection();
httpGet = new HttpGet(HOST_URL + "/engine/controllers/" + FOO_CONTROLLER + "/drools/facts/session/factType");
response = client.execute(httpGet);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
assertEquals(200, response.getStatusLine().getStatusCode());
httpGet.releaseConnection();
httpGet = new HttpGet(
HOST_URL + "/engine/controllers/" + FOO_CONTROLLER + "/drools/facts/session/query/queriedEntity");
response = client.execute(httpGet);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
assertEquals(200, response.getStatusLine().getStatusCode());
httpGet.releaseConnection();
httpGet = new HttpGet(HOST_URL + "/engine/controllers/dummy" + "/drools/facts/session/query/queriedEntity");
response = client.execute(httpGet);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
assertEquals(404, response.getStatusLine().getStatusCode());
httpGet.releaseConnection();
}
- private static void testGetEngineTools() throws IOException {
+ @Test
+ void testGetEngineTools() throws IOException {
CloseableHttpResponse response;
HttpGet httpGet;
/*
@@ -524,24 +531,25 @@ public class RestManagerTest {
*/
httpGet = new HttpGet(HOST_URL + "/engine/tools/uuid");
response = client.execute(httpGet);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
assertEquals(200, response.getStatusLine().getStatusCode());
httpGet.releaseConnection();
httpGet = new HttpGet(HOST_URL + "/engine/tools/loggers");
response = client.execute(httpGet);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
assertEquals(200, response.getStatusLine().getStatusCode());
httpGet.releaseConnection();
httpGet = new HttpGet(HOST_URL + "/engine/tools/loggers/ROOT");
response = client.execute(httpGet);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
assertEquals(200, response.getStatusLine().getStatusCode());
httpGet.releaseConnection();
}
- private static void testGetControllersDecoders() throws IOException {
+ @Test
+ void testGetControllersDecoders() throws IOException {
HttpGet httpGet;
CloseableHttpResponse response;
/*
@@ -556,68 +564,69 @@ public class RestManagerTest {
*/
httpGet = new HttpGet(HOST_URL + "/engine/controllers/" + FOO_CONTROLLER + "/decoders");
response = client.execute(httpGet);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
assertEquals(200, response.getStatusLine().getStatusCode());
httpGet.releaseConnection();
httpGet = new HttpGet(HOST_URL + "/engine/controllers/nonexistantcontroller/decoders");
response = client.execute(httpGet);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
assertEquals(404, response.getStatusLine().getStatusCode());
httpGet.releaseConnection();
httpGet = new HttpGet(HOST_URL + "/engine/controllers/" + FOO_CONTROLLER + "/decoders/filters");
response = client.execute(httpGet);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
assertEquals(200, response.getStatusLine().getStatusCode());
httpGet.releaseConnection();
httpGet = new HttpGet(HOST_URL + "/engine/controllers/nonexistantcontroller/decoders/filters");
response = client.execute(httpGet);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
assertEquals(404, response.getStatusLine().getStatusCode());
httpGet.releaseConnection();
httpGet = new HttpGet(HOST_URL + "/engine/controllers/" + FOO_CONTROLLER + "/decoders/topic");
response = client.execute(httpGet);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
assertEquals(404, response.getStatusLine().getStatusCode());
httpGet.releaseConnection();
httpGet = new HttpGet(HOST_URL + "/engine/controllers/" + FOO_CONTROLLER + "/decoders/topic/filters");
response = client.execute(httpGet);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
assertEquals(404, response.getStatusLine().getStatusCode());
httpGet.releaseConnection();
httpGet = new HttpGet(HOST_URL + "/engine/controllers/" + FOO_CONTROLLER + "/decoders/topic/filters/factType");
response = client.execute(httpGet);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
assertEquals(404, response.getStatusLine().getStatusCode());
httpGet.releaseConnection();
httpGet = new HttpGet(
HOST_URL + "/engine/controllers/" + FOO_CONTROLLER + "/decoders/topic/filters/factType/rules");
response = client.execute(httpGet);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
assertEquals(404, response.getStatusLine().getStatusCode());
httpGet.releaseConnection();
httpGet = new HttpGet(
HOST_URL + "/engine/controllers/" + FOO_CONTROLLER + "/decoders/topic/filters/factType/rules/ruleName");
response = client.execute(httpGet);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
assertEquals(404, response.getStatusLine().getStatusCode());
httpGet.releaseConnection();
httpGet = new HttpGet(HOST_URL + "/engine/controllers/" + FOO_CONTROLLER + "/encoders");
response = client.execute(httpGet);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
assertEquals(200, response.getStatusLine().getStatusCode());
httpGet.releaseConnection();
}
- private static void testGetTopics() throws IOException {
+ @Test
+ void testGetKafkaTopics() throws IOException {
CloseableHttpResponse response;
HttpGet httpGet;
/*
@@ -635,169 +644,186 @@ public class RestManagerTest {
*/
httpGet = new HttpGet(HOST_URL + "/engine/topics");
response = client.execute(httpGet);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
assertEquals(200, response.getStatusLine().getStatusCode());
httpGet.releaseConnection();
httpGet = new HttpGet(HOST_URL + "/engine/topics/switches");
response = client.execute(httpGet);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
assertEquals(200, response.getStatusLine().getStatusCode());
httpGet.releaseConnection();
httpGet = new HttpGet(HOST_URL + "/engine/topics/sources");
response = client.execute(httpGet);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
assertEquals(200, response.getStatusLine().getStatusCode());
httpGet.releaseConnection();
httpGet = new HttpGet(HOST_URL + "/engine/topics/sinks");
response = client.execute(httpGet);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
assertEquals(200, response.getStatusLine().getStatusCode());
httpGet.releaseConnection();
httpGet = new HttpGet(HOST_URL + "/engine/topics/sources/kafka");
response = client.execute(httpGet);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
assertEquals(200, response.getStatusLine().getStatusCode());
httpGet.releaseConnection();
httpGet = new HttpGet(HOST_URL + "/engine/topics/sinks/kafka");
response = client.execute(httpGet);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
assertEquals(200, response.getStatusLine().getStatusCode());
httpGet.releaseConnection();
- httpGet = new HttpGet(HOST_URL + "/engine/topics/sources/noop");
+ httpGet = new HttpGet(HOST_URL + "/engine/topics/sources/kafka/" + KAFKA_TOPIC);
response = client.execute(httpGet);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
assertEquals(200, response.getStatusLine().getStatusCode());
httpGet.releaseConnection();
- httpGet = new HttpGet(HOST_URL + "/engine/topics/sinks/noop");
+ httpGet = new HttpGet(HOST_URL + "/engine/topics/sources/kafka/foobar");
response = client.execute(httpGet);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
- assertEquals(200, response.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
+ assertEquals(500, response.getStatusLine().getStatusCode());
httpGet.releaseConnection();
- httpGet = new HttpGet(HOST_URL + "/engine/topics/sources/kafka/" + KAFKA_TOPIC);
+ httpGet = new HttpGet(HOST_URL + "/engine/topics/sinks/kafka/" + KAFKA_TOPIC);
response = client.execute(httpGet);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
assertEquals(200, response.getStatusLine().getStatusCode());
httpGet.releaseConnection();
- httpGet = new HttpGet(HOST_URL + "/engine/topics/sources/kafka/foobar");
+ httpGet = new HttpGet(HOST_URL + "/engine/topics/sinks/kafka/foobar");
response = client.execute(httpGet);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
assertEquals(500, response.getStatusLine().getStatusCode());
httpGet.releaseConnection();
- httpGet = new HttpGet(HOST_URL + "/engine/topics/sinks/kafka/" + KAFKA_TOPIC);
+ httpGet = new HttpGet(HOST_URL + "/engine/topics/sources/kafka/" + KAFKA_TOPIC + "/events");
response = client.execute(httpGet);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
assertEquals(200, response.getStatusLine().getStatusCode());
httpGet.releaseConnection();
- httpGet = new HttpGet(HOST_URL + "/engine/topics/sinks/kafka/foobar");
+ httpGet = new HttpGet(HOST_URL + "/engine/topics/sources/kafka/foobar/events");
response = client.execute(httpGet);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
assertEquals(500, response.getStatusLine().getStatusCode());
httpGet.releaseConnection();
- httpGet = new HttpGet(HOST_URL + "/engine/topics/sources/noop/" + NOOP_TOPIC);
+ httpGet = new HttpGet(HOST_URL + "/engine/topics/sinks/kafka/" + KAFKA_TOPIC + "/events");
response = client.execute(httpGet);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
assertEquals(200, response.getStatusLine().getStatusCode());
httpGet.releaseConnection();
- httpGet = new HttpGet(HOST_URL + "/engine/topics/sources/noop/foobar");
+ httpGet = new HttpGet(HOST_URL + "/engine/topics/sinks/kafka/foobar/events");
response = client.execute(httpGet);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
assertEquals(500, response.getStatusLine().getStatusCode());
httpGet.releaseConnection();
- httpGet = new HttpGet(HOST_URL + "/engine/topics/sinks/noop/" + NOOP_TOPIC);
+ httpGet = new HttpGet(HOST_URL + "/engine/topics/sources/kafka/" + KAFKA_TOPIC + "/switches");
response = client.execute(httpGet);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
assertEquals(200, response.getStatusLine().getStatusCode());
httpGet.releaseConnection();
- httpGet = new HttpGet(HOST_URL + "/engine/topics/sinks/noop/foobar");
+ httpGet = new HttpGet(HOST_URL + "/engine/topics/sinks/kafka/" + KAFKA_TOPIC + "/switches");
response = client.execute(httpGet);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
- assertEquals(500, response.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
+ assertEquals(200, response.getStatusLine().getStatusCode());
httpGet.releaseConnection();
+ }
- httpGet = new HttpGet(HOST_URL + "/engine/topics/sources/kafka/" + KAFKA_TOPIC + "/events");
+ @Test
+ void testGetNoopTopics() throws IOException {
+ CloseableHttpResponse response;
+ HttpGet httpGet;
+ /*
+ * GET: /engine/topics
+ * /engine/topics/sources/noop
+ * /engine/topics/sinks/noop
+ * /engine/topics/sources/noop/topic
+ * /engine/topics/sinks/noop/topic
+ * /engine/topics/sources/noop/topic/events
+ * /engine/topics/sinks/noop/topic/events
+ * /engine/topics/sources/noop/topic/switches
+ * /engine/topics/sinks/noop/topic/switches
+ */
+
+ httpGet = new HttpGet(HOST_URL + "/engine/topics/sources/noop");
response = client.execute(httpGet);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
assertEquals(200, response.getStatusLine().getStatusCode());
httpGet.releaseConnection();
- httpGet = new HttpGet(HOST_URL + "/engine/topics/sources/kafka/foobar/events");
+ httpGet = new HttpGet(HOST_URL + "/engine/topics/sinks/noop");
response = client.execute(httpGet);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
- assertEquals(500, response.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
+ assertEquals(200, response.getStatusLine().getStatusCode());
httpGet.releaseConnection();
- httpGet = new HttpGet(HOST_URL + "/engine/topics/sinks/kafka/" + KAFKA_TOPIC + "/events");
+ httpGet = new HttpGet(HOST_URL + "/engine/topics/sources/noop/" + NOOP_TOPIC);
response = client.execute(httpGet);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
assertEquals(200, response.getStatusLine().getStatusCode());
httpGet.releaseConnection();
- httpGet = new HttpGet(HOST_URL + "/engine/topics/sinks/kafka/foobar/events");
+ httpGet = new HttpGet(HOST_URL + "/engine/topics/sources/noop/foobar");
response = client.execute(httpGet);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
assertEquals(500, response.getStatusLine().getStatusCode());
httpGet.releaseConnection();
- httpGet = new HttpGet(HOST_URL + "/engine/topics/sources/noop/" + NOOP_TOPIC + "/events");
+ httpGet = new HttpGet(HOST_URL + "/engine/topics/sinks/noop/" + NOOP_TOPIC);
response = client.execute(httpGet);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
assertEquals(200, response.getStatusLine().getStatusCode());
httpGet.releaseConnection();
- httpGet = new HttpGet(HOST_URL + "/engine/topics/sources/noop/foobar/events");
+ httpGet = new HttpGet(HOST_URL + "/engine/topics/sinks/noop/foobar");
response = client.execute(httpGet);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
assertEquals(500, response.getStatusLine().getStatusCode());
httpGet.releaseConnection();
- httpGet = new HttpGet(HOST_URL + "/engine/topics/sinks/noop/" + NOOP_TOPIC + "/events");
+ httpGet = new HttpGet(HOST_URL + "/engine/topics/sources/noop/" + NOOP_TOPIC + "/events");
response = client.execute(httpGet);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
assertEquals(200, response.getStatusLine().getStatusCode());
httpGet.releaseConnection();
- httpGet = new HttpGet(HOST_URL + "/engine/topics/sinks/noop/foobar/events");
+ httpGet = new HttpGet(HOST_URL + "/engine/topics/sources/noop/foobar/events");
response = client.execute(httpGet);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
assertEquals(500, response.getStatusLine().getStatusCode());
httpGet.releaseConnection();
- httpGet = new HttpGet(HOST_URL + "/engine/topics/sources/kafka/" + KAFKA_TOPIC + "/switches");
+ httpGet = new HttpGet(HOST_URL + "/engine/topics/sinks/noop/" + NOOP_TOPIC + "/events");
response = client.execute(httpGet);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
assertEquals(200, response.getStatusLine().getStatusCode());
httpGet.releaseConnection();
- httpGet = new HttpGet(HOST_URL + "/engine/topics/sources/noop/" + NOOP_TOPIC + "/switches");
+ httpGet = new HttpGet(HOST_URL + "/engine/topics/sinks/noop/foobar/events");
response = client.execute(httpGet);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
- assertEquals(200, response.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
+ assertEquals(500, response.getStatusLine().getStatusCode());
httpGet.releaseConnection();
- httpGet = new HttpGet(HOST_URL + "/engine/topics/sinks/kafka/" + KAFKA_TOPIC + "/switches");
+ httpGet = new HttpGet(HOST_URL + "/engine/topics/sources/noop/" + NOOP_TOPIC + "/switches");
response = client.execute(httpGet);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
assertEquals(200, response.getStatusLine().getStatusCode());
httpGet.releaseConnection();
httpGet = new HttpGet(HOST_URL + "/engine/topics/sinks/noop/" + NOOP_TOPIC + "/switches");
response = client.execute(httpGet);
- logger.info(httpGet.getRequestLine() + " response code: {}", response.getStatusLine().getStatusCode());
+ logger.info("{} response code: {}", httpGet.getRequestLine(), response.getStatusLine().getStatusCode());
assertEquals(200, response.getStatusLine().getStatusCode());
httpGet.releaseConnection();
}
diff --git a/policy-management/src/test/java/org/onap/policy/drools/stats/PolicyStatsManagerTest.java b/policy-management/src/test/java/org/onap/policy/drools/stats/PolicyStatsManagerTest.java
index 118c4d7e..c13a4664 100644
--- a/policy-management/src/test/java/org/onap/policy/drools/stats/PolicyStatsManagerTest.java
+++ b/policy-management/src/test/java/org/onap/policy/drools/stats/PolicyStatsManagerTest.java
@@ -21,6 +21,7 @@
package org.onap.policy.drools.stats;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;
@@ -42,4 +43,17 @@ class PolicyStatsManagerTest {
assertEquals(1, stats.getSubgroupStats().get("foo").getPolicyExecutedFailCount());
assertEquals(2, stats.getSubgroupStats().get("blah").getPolicyExecutedFailCount());
}
+
+ @Test
+ void test_Exceptions() {
+ PolicyStatsManager stats = new PolicyStatsManager();
+ assertThatThrownBy(() -> stats.stat("foo", null))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("transaction is marked non-null but is nul");
+
+ Metric trans = new Metric();
+ assertThatThrownBy(() -> stats.stat(null, trans))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("subGroupName is marked non-null but is null");
+ }
} \ No newline at end of file
diff --git a/policy-management/src/test/java/org/onap/policy/drools/stats/PolicyStatsTest.java b/policy-management/src/test/java/org/onap/policy/drools/stats/PolicyStatsTest.java
index 3f26e82e..6b76837d 100644
--- a/policy-management/src/test/java/org/onap/policy/drools/stats/PolicyStatsTest.java
+++ b/policy-management/src/test/java/org/onap/policy/drools/stats/PolicyStatsTest.java
@@ -22,6 +22,7 @@
package org.onap.policy.drools.stats;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;
@@ -74,6 +75,14 @@ class PolicyStatsTest {
assertThat(stats.getBirthTime()).isLessThanOrEqualTo(trans2.getStartTime().toEpochMilli());
}
+ @Test
+ void test_Exception() {
+ PolicyStats stats = new PolicyStats();
+ assertThatThrownBy(() -> stats.stat(null))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("trans is marked non-null but is null");
+ }
+
private Metric createTrans() {
Metric trans = new Metric();
trans.setStartTime(null);
diff --git a/policy-management/src/test/java/org/onap/policy/drools/system/PolicyControllerFactoryTest.java b/policy-management/src/test/java/org/onap/policy/drools/system/PolicyControllerFactoryTest.java
index 615ffe2b..8a388dfc 100644
--- a/policy-management/src/test/java/org/onap/policy/drools/system/PolicyControllerFactoryTest.java
+++ b/policy-management/src/test/java/org/onap/policy/drools/system/PolicyControllerFactoryTest.java
@@ -35,7 +35,6 @@ import static org.mockito.Mockito.when;
import static org.onap.policy.drools.properties.DroolsPropertyConstants.PROPERTY_CONTROLLER_TYPE;
import java.util.Arrays;
-import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Properties;
@@ -504,9 +503,9 @@ class PolicyControllerFactoryTest {
@Override
public DroolsController beforeInstance(Properties properties,
- String groupId, String artifactId, String version,
- List<TopicCoderFilterConfiguration> decoderConfigurations,
- List<TopicCoderFilterConfiguration> encoderConfigurations) {
+ String groupId, String artifactId, String version,
+ List<TopicCoderFilterConfiguration> decoderConfigurations,
+ List<TopicCoderFilterConfiguration> encoderConfigurations) {
if (POLICY_CONTROLLER_BUILDER_TAG.equals(properties.getProperty(PROPERTY_CONTROLLER_TYPE))) {
return new NullDroolsController();
diff --git a/policy-management/src/test/java/org/onap/policy/drools/system/PolicyEngineManagerTest.java b/policy-management/src/test/java/org/onap/policy/drools/system/PolicyEngineManagerTest.java
index 4006c9ed..138ad9f8 100644
--- a/policy-management/src/test/java/org/onap/policy/drools/system/PolicyEngineManagerTest.java
+++ b/policy-management/src/test/java/org/onap/policy/drools/system/PolicyEngineManagerTest.java
@@ -102,7 +102,7 @@ class PolicyEngineManagerTest {
private static final Object MY_EVENT = new Object();
private static final GsonTestUtils gson = new GsonMgmtTestBuilder().addTopicSourceMock().addTopicSinkMock()
- .addHttpServletServerMock().build();
+ .addHttpServletServerMock().build();
private Properties properties;
private PolicyEngineFeatureApi prov1;
@@ -217,7 +217,7 @@ class PolicyEngineManagerTest {
when(lockmgr.lock()).thenReturn(true);
when(lockmgr.unlock()).thenReturn(true);
- when(prov2.beforeCreateLockManager(any(), any())).thenReturn(lockmgr);
+ when(prov2.beforeCreateLockManager()).thenReturn(lockmgr);
when(prov1.getName()).thenReturn(FEATURE1);
when(prov2.getName()).thenReturn(FEATURE2);
@@ -524,7 +524,7 @@ class PolicyEngineManagerTest {
@Test
void testCreateLockManagerHaveProvider() {
// first provider throws an exception
- when(prov1.beforeCreateLockManager(any(), any())).thenThrow(new RuntimeException(EXPECTED));
+ when(prov1.beforeCreateLockManager()).thenThrow(new RuntimeException(EXPECTED));
mgr.configure(properties);
assertSame(lockmgr, mgr.getLockManager());
@@ -535,7 +535,7 @@ class PolicyEngineManagerTest {
*/
@Test
void testCreateLockManagerSimpleEx() {
- when(prov2.beforeCreateLockManager(any(), any())).thenReturn(null);
+ when(prov2.beforeCreateLockManager()).thenReturn(null);
// invalid property for SimpleLockManager
properties.setProperty(SimpleLockProperties.EXPIRE_CHECK_SEC, "abc");
@@ -550,7 +550,7 @@ class PolicyEngineManagerTest {
*/
@Test
void testCreateLockManagerSimple() {
- when(prov2.beforeCreateLockManager(any(), any())).thenReturn(null);
+ when(prov2.beforeCreateLockManager()).thenReturn(null);
mgr.configure(properties);
assertInstanceOf(SimpleLockManager.class, mgr.getLockManager());
@@ -579,30 +579,34 @@ class PolicyEngineManagerTest {
verify(prov1).afterConfigure(mgr);
verify(prov2).afterConfigure(mgr);
+ // other tests
+ checkBeforeAfter(
+ (prov, flag) -> when(prov.beforeConfigure(mgr, properties)).thenReturn(flag),
+ (prov, flag) -> when(prov.afterConfigure(mgr)).thenReturn(flag),
+ () -> mgr.configure(properties),
+ prov -> verify(prov).beforeConfigure(mgr, properties),
+ () -> assertSame(properties, mgr.getProperties()),
+ prov -> verify(prov).afterConfigure(mgr));
+ }
+
+ @Test
+ void testConfigureProperties_InvalidProperties() throws Exception {
// middle stuff throws exception - still calls afterXxx
- setUp();
when(endpoint.addTopicSources(properties)).thenThrow(new IllegalArgumentException(EXPECTED));
when(endpoint.addTopicSinks(properties)).thenThrow(new IllegalArgumentException(EXPECTED));
when(serverFactory.build(properties)).thenThrow(new IllegalArgumentException(EXPECTED));
when(clientFactory.build(properties)).thenThrow(new IllegalArgumentException(EXPECTED));
mgr.configure(properties);
verify(prov2).afterConfigure(mgr);
+ }
+ @Test
+ void testConfigureProperties_NullProperties() {
// null properties - nothing should be invoked
- setUp();
Properties nullProps = null;
assertThatIllegalArgumentException().isThrownBy(() -> mgr.configure(nullProps));
verify(prov1, never()).beforeConfigure(mgr, properties);
verify(prov1, never()).afterConfigure(mgr);
-
- // other tests
- checkBeforeAfter(
- (prov, flag) -> when(prov.beforeConfigure(mgr, properties)).thenReturn(flag),
- (prov, flag) -> when(prov.afterConfigure(mgr)).thenReturn(flag),
- () -> mgr.configure(properties),
- prov -> verify(prov).beforeConfigure(mgr, properties),
- () -> assertSame(properties, mgr.getProperties()),
- prov -> verify(prov).afterConfigure(mgr));
}
@Test
@@ -631,17 +635,8 @@ class PolicyEngineManagerTest {
}
@Test
- void testCreatePolicyController() throws Exception {
- assertEquals(controller, mgr.createPolicyController(MY_NAME, properties));
-
- verify(contProv1).beforeCreate(MY_NAME, properties);
- verify(contProv2).beforeCreate(MY_NAME, properties);
- verify(controller, never()).lock();
- verify(contProv1).afterCreate(controller);
- verify(contProv2).afterCreate(controller);
-
+ void testCreatePolicy_FirstProviderThrowsException() {
// first provider throws exceptions - same result
- setUp();
when(contProv1.beforeCreate(MY_NAME, properties)).thenThrow(new RuntimeException(EXPECTED));
when(contProv1.afterCreate(controller)).thenThrow(new RuntimeException(EXPECTED));
assertEquals(controller, mgr.createPolicyController(MY_NAME, properties));
@@ -651,17 +646,11 @@ class PolicyEngineManagerTest {
verify(controller, never()).lock();
verify(contProv1).afterCreate(controller);
verify(contProv2).afterCreate(controller);
+ }
- // locked - same result, but engine locked
- setUp();
- mgr.lock();
- assertEquals(controller, mgr.createPolicyController(MY_NAME, properties));
- verify(contProv1).beforeCreate(MY_NAME, properties);
- verify(controller, times(2)).lock();
- verify(contProv2).afterCreate(controller);
-
+ @Test
+ void testCreatePolicyController_InvalidProperties() throws Exception {
// empty name in properties - same result
- setUp();
properties.setProperty(DroolsPropertyConstants.PROPERTY_CONTROLLER_NAME, "");
assertEquals(controller, mgr.createPolicyController(MY_NAME, properties));
verify(contProv1).beforeCreate(MY_NAME, properties);
@@ -677,6 +666,25 @@ class PolicyEngineManagerTest {
properties.setProperty(DroolsPropertyConstants.PROPERTY_CONTROLLER_NAME, "mistmatched-name");
assertThatIllegalStateException().isThrownBy(() -> mgr.createPolicyController(MY_NAME, properties));
verify(contProv1, never()).beforeCreate(MY_NAME, properties);
+ }
+
+ @Test
+ void testCreatePolicyController() throws Exception {
+ assertEquals(controller, mgr.createPolicyController(MY_NAME, properties));
+
+ verify(contProv1).beforeCreate(MY_NAME, properties);
+ verify(contProv2).beforeCreate(MY_NAME, properties);
+ verify(controller, never()).lock();
+ verify(contProv1).afterCreate(controller);
+ verify(contProv2).afterCreate(controller);
+
+ // locked - same result, but engine locked
+ setUp();
+ mgr.lock();
+ assertEquals(controller, mgr.createPolicyController(MY_NAME, properties));
+ verify(contProv1).beforeCreate(MY_NAME, properties);
+ verify(controller, times(2)).lock();
+ verify(contProv2).afterCreate(controller);
// first provider generates controller - stops after first provider
setUp();
@@ -731,7 +739,7 @@ class PolicyEngineManagerTest {
}
@Test
- void testUpdatePolicyController() throws Exception {
+ void testUpdatePolicyController_Exceptions() throws Exception {
assertEquals(controller3, mgr.updatePolicyController(config3));
verify(engine).createPolicyController(CONTROLLER3, properties);
@@ -775,7 +783,10 @@ class PolicyEngineManagerTest {
setUp();
when(persist.getControllerProperties(CONTROLLER3)).thenThrow(new LinkageError(EXPECTED));
assertThatIllegalStateException().isThrownBy(() -> mgr.updatePolicyController(config3));
+ }
+ @Test
+ void testUpdatePolicyController() throws Exception {
/*
* For remaining tests, the factory will return the controller instead of creating
* one.
@@ -899,7 +910,7 @@ class PolicyEngineManagerTest {
* Tests the start() method, after setting some option.
*
* @param expectedResult what start() is expected to return
- * @param setOption function that sets an option
+ * @param setOption function that sets an option
* @throws Throwable if an error occurs during setup
*/
private void testStart(boolean expectedResult, RunnableWithEx setOption) throws Throwable {
@@ -954,14 +965,7 @@ class PolicyEngineManagerTest {
assertTrue(mgr.stop());
verify(prov1).beforeStop(mgr);
verify(prov2).beforeStop(mgr);
- verify(controller, never()).stop();
- verify(source1, never()).stop();
- verify(sink1, never()).stop();
- verify(endpoint, never()).stop();
- verify(server1, never()).stop();
- verify(client1, never()).stop();
- verify(prov1, never()).afterStop(mgr);
- verify(prov2, never()).afterStop(mgr);
+ verifyNeverCalled();
// controller fails to stop - still does everything
testStop(false, () -> when(controller.stop()).thenReturn(false));
@@ -1008,7 +1012,7 @@ class PolicyEngineManagerTest {
* Tests the stop() method, after setting some option.
*
* @param expectedResult what stop() is expected to return
- * @param setOption function that sets an option
+ * @param setOption function that sets an option
* @throws Throwable if an error occurs during setup
*/
private void testStop(boolean expectedResult, RunnableWithEx setOption) throws Throwable {
@@ -1215,7 +1219,7 @@ class PolicyEngineManagerTest {
* Tests the lock() method, after setting some option.
*
* @param expectedResult what lock() is expected to return
- * @param setOption function that sets an option
+ * @param setOption function that sets an option
* @throws Throwable if an error occurs during setup
*/
private void testLock(boolean expectedResult, RunnableWithEx setOption) throws Throwable {
@@ -1291,7 +1295,7 @@ class PolicyEngineManagerTest {
* Tests the unlock() method, after setting some option.
*
* @param expectedResult what unlock() is expected to return
- * @param setOption function that sets an option
+ * @param setOption function that sets an option
* @throws Throwable if an error occurs during setup
*/
private void testUnlock(boolean expectedResult, RunnableWithEx setOption) throws Throwable {
@@ -1415,8 +1419,8 @@ class PolicyEngineManagerTest {
assertEquals(1, mgr.getStats().getSubgroupStats().get(CONTROLLOOP).getPolicyExecutedFailCount());
Summary.Child.Value summary =
- PolicyEngineManagerImpl.transLatencySecsSummary
- .labels(CONTROLLER1, CONTROLLOOP, POLICY, PdpResponseStatus.FAIL.name()).get();
+ PolicyEngineManagerImpl.transLatencySecsSummary
+ .labels(CONTROLLER1, CONTROLLOOP, POLICY, PdpResponseStatus.FAIL.name()).get();
assertEquals(0, summary.count, 0.0);
assertEquals(0, summary.sum, 0.0);
@@ -1427,8 +1431,8 @@ class PolicyEngineManagerTest {
mgr.transaction(CONTROLLER1, CONTROLLOOP, metric);
summary =
- PolicyEngineManagerImpl.transLatencySecsSummary
- .labels(CONTROLLER1, CONTROLLOOP, POLICY, PdpResponseStatus.FAIL.name()).get();
+ PolicyEngineManagerImpl.transLatencySecsSummary
+ .labels(CONTROLLER1, CONTROLLOOP, POLICY, PdpResponseStatus.FAIL.name()).get();
assertEquals(1, summary.count, 0.0);
assertEquals(5, summary.sum, 0.0);
@@ -1557,7 +1561,7 @@ class PolicyEngineManagerTest {
mgr.start();
when(sink1.send(any())).thenThrow(new ArithmeticException(EXPECTED));
assertThatThrownBy(() -> mgr.deliver(CommInfrastructure.NOOP, MY_TOPIC, MY_EVENT))
- .isInstanceOf(ArithmeticException.class);
+ .isInstanceOf(ArithmeticException.class);
/*
* For remaining tests, have the controller handle delivery.
@@ -1614,7 +1618,7 @@ class PolicyEngineManagerTest {
// unknown topic
assertThatIllegalStateException()
- .isThrownBy(() -> mgr.deliver(CommInfrastructure.NOOP, "unknown-topic", MESSAGE));
+ .isThrownBy(() -> mgr.deliver(CommInfrastructure.NOOP, "unknown-topic", MESSAGE));
// locked
mgr.lock();
@@ -1741,7 +1745,7 @@ class PolicyEngineManagerTest {
// not configured yet, thus no lock manager
assertThatIllegalStateException()
- .isThrownBy(() -> mgr.createLock(MY_RESOURCE, MY_OWNER, 10, callback, false));
+ .isThrownBy(() -> mgr.createLock(MY_RESOURCE, MY_OWNER, 10, callback, false));
// now configure it and try again
mgr.configure(properties);
@@ -1749,14 +1753,14 @@ class PolicyEngineManagerTest {
// test illegal args
assertThatThrownBy(() -> mgr.createLock(null, MY_OWNER, 10, callback, false))
- .hasMessageContaining("resourceId");
+ .hasMessageContaining("resourceId");
assertThatThrownBy(() -> mgr.createLock(MY_RESOURCE, null, 10, callback, false))
- .hasMessageContaining("ownerKey");
+ .hasMessageContaining("ownerKey");
assertThatIllegalArgumentException()
- .isThrownBy(() -> mgr.createLock(MY_RESOURCE, MY_OWNER, -1, callback, false))
- .withMessageContaining("holdSec");
+ .isThrownBy(() -> mgr.createLock(MY_RESOURCE, MY_OWNER, -1, callback, false))
+ .withMessageContaining("holdSec");
assertThatThrownBy(() -> mgr.createLock(MY_RESOURCE, MY_OWNER, 10, null, false))
- .hasMessageContaining("callback");
+ .hasMessageContaining("callback");
}
@Test
@@ -1854,19 +1858,19 @@ class PolicyEngineManagerTest {
* Performs an operation that has a beforeXxx method and an afterXxx method. Tries
* combinations where beforeXxx and afterXxx return {@code true} and {@code false}.
*
- * @param setBefore function to set the return value of a provider's beforeXxx method
- * @param setAfter function to set the return value of a provider's afterXxx method
- * @param action invokes the operation
+ * @param setBefore function to set the return value of a provider's beforeXxx method
+ * @param setAfter function to set the return value of a provider's afterXxx method
+ * @param action invokes the operation
* @param verifyBefore verifies that a provider's beforeXxx method was invoked
* @param verifyMiddle verifies that the action occurring between the beforeXxx loop
- * and the afterXxx loop was invoked
- * @param verifyAfter verifies that a provider's afterXxx method was invoked
+ * and the afterXxx loop was invoked
+ * @param verifyAfter verifies that a provider's afterXxx method was invoked
* @throws Exception if an error occurs while calling {@link #setUp()}
*/
private void checkBeforeAfter(BiConsumer<PolicyEngineFeatureApi, Boolean> setBefore,
- BiConsumer<PolicyEngineFeatureApi, Boolean> setAfter, Runnable action,
- Consumer<PolicyEngineFeatureApi> verifyBefore, Runnable verifyMiddle,
- Consumer<PolicyEngineFeatureApi> verifyAfter) throws Exception {
+ BiConsumer<PolicyEngineFeatureApi, Boolean> setAfter, Runnable action,
+ Consumer<PolicyEngineFeatureApi> verifyBefore, Runnable verifyMiddle,
+ Consumer<PolicyEngineFeatureApi> verifyAfter) throws Exception {
checkBeforeAfter_FalseFalse(setBefore, setAfter, action, verifyBefore, verifyMiddle, verifyAfter);
checkBeforeAfter_FalseTrue(setBefore, setAfter, action, verifyBefore, verifyMiddle, verifyAfter);
@@ -1879,19 +1883,19 @@ class PolicyEngineManagerTest {
* Performs an operation that has a beforeXxx method and an afterXxx method. Tries the
* case where both the beforeXxx and afterXxx methods return {@code false}.
*
- * @param setBefore function to set the return value of a provider's beforeXxx method
- * @param setAfter function to set the return value of a provider's afterXxx method
- * @param action invokes the operation
+ * @param setBefore function to set the return value of a provider's beforeXxx method
+ * @param setAfter function to set the return value of a provider's afterXxx method
+ * @param action invokes the operation
* @param verifyBefore verifies that a provider's beforeXxx method was invoked
* @param verifyMiddle verifies that the action occurring between the beforeXxx loop
- * and the afterXxx loop was invoked
- * @param verifyAfter verifies that a provider's afterXxx method was invoked
+ * and the afterXxx loop was invoked
+ * @param verifyAfter verifies that a provider's afterXxx method was invoked
* @throws Exception if an error occurs while calling {@link #setUp()}
*/
private void checkBeforeAfter_FalseFalse(BiConsumer<PolicyEngineFeatureApi, Boolean> setBefore,
- BiConsumer<PolicyEngineFeatureApi, Boolean> setAfter, Runnable action,
- Consumer<PolicyEngineFeatureApi> verifyBefore, Runnable verifyMiddle,
- Consumer<PolicyEngineFeatureApi> verifyAfter) throws Exception {
+ BiConsumer<PolicyEngineFeatureApi, Boolean> setAfter, Runnable action,
+ Consumer<PolicyEngineFeatureApi> verifyBefore, Runnable verifyMiddle,
+ Consumer<PolicyEngineFeatureApi> verifyAfter) throws Exception {
setUp();
@@ -1920,19 +1924,19 @@ class PolicyEngineManagerTest {
* case where the first provider's afterXxx returns {@code true}, while the others
* return {@code false}.
*
- * @param setBefore function to set the return value of a provider's beforeXxx method
- * @param setAfter function to set the return value of a provider's afterXxx method
- * @param action invokes the operation
+ * @param setBefore function to set the return value of a provider's beforeXxx method
+ * @param setAfter function to set the return value of a provider's afterXxx method
+ * @param action invokes the operation
* @param verifyBefore verifies that a provider's beforeXxx method was invoked
* @param verifyMiddle verifies that the action occurring between the beforeXxx loop
- * and the afterXxx loop was invoked
- * @param verifyAfter verifies that a provider's afterXxx method was invoked
+ * and the afterXxx loop was invoked
+ * @param verifyAfter verifies that a provider's afterXxx method was invoked
* @throws Exception if an error occurs while calling {@link #setUp()}
*/
private void checkBeforeAfter_FalseTrue(BiConsumer<PolicyEngineFeatureApi, Boolean> setBefore,
- BiConsumer<PolicyEngineFeatureApi, Boolean> setAfter, Runnable action,
- Consumer<PolicyEngineFeatureApi> verifyBefore, Runnable verifyMiddle,
- Consumer<PolicyEngineFeatureApi> verifyAfter) throws Exception {
+ BiConsumer<PolicyEngineFeatureApi, Boolean> setAfter, Runnable action,
+ Consumer<PolicyEngineFeatureApi> verifyBefore, Runnable verifyMiddle,
+ Consumer<PolicyEngineFeatureApi> verifyAfter) throws Exception {
setUp();
@@ -1961,19 +1965,19 @@ class PolicyEngineManagerTest {
* case where the first provider's beforeXxx returns {@code true}, while the others
* return {@code false}.
*
- * @param setBefore function to set the return value of a provider's beforeXxx method
- * @param setAfter function to set the return value of a provider's afterXxx method
- * @param action invokes the operation
+ * @param setBefore function to set the return value of a provider's beforeXxx method
+ * @param setAfter function to set the return value of a provider's afterXxx method
+ * @param action invokes the operation
* @param verifyBefore verifies that a provider's beforeXxx method was invoked
* @param verifyMiddle verifies that the action occurring between the beforeXxx loop
- * and the afterXxx loop was invoked
- * @param verifyAfter verifies that a provider's afterXxx method was invoked
+ * and the afterXxx loop was invoked
+ * @param verifyAfter verifies that a provider's afterXxx method was invoked
* @throws Exception if an error occurs while calling {@link #setUp()}
*/
private void checkBeforeAfter_TrueFalse(BiConsumer<PolicyEngineFeatureApi, Boolean> setBefore,
- BiConsumer<PolicyEngineFeatureApi, Boolean> setAfter, Runnable action,
- Consumer<PolicyEngineFeatureApi> verifyBefore, Runnable verifyMiddle,
- Consumer<PolicyEngineFeatureApi> verifyAfter) throws Exception {
+ BiConsumer<PolicyEngineFeatureApi, Boolean> setAfter, Runnable action,
+ Consumer<PolicyEngineFeatureApi> verifyBefore, Runnable verifyMiddle,
+ Consumer<PolicyEngineFeatureApi> verifyAfter) throws Exception {
setUp();
@@ -1999,6 +2003,17 @@ class PolicyEngineManagerTest {
assertThatThrownBy(() -> verifyAfter.accept(prov2)).isInstanceOf(AssertionError.class);
}
+ private void verifyNeverCalled() {
+ verify(controller, never()).stop();
+ verify(source1, never()).stop();
+ verify(sink1, never()).stop();
+ verify(endpoint, never()).stop();
+ verify(server1, never()).stop();
+ verify(client1, never()).stop();
+ verify(prov1, never()).afterStop(mgr);
+ verify(prov2, never()).afterStop(mgr);
+ }
+
/**
* Manager with overrides.
*/
@@ -2086,8 +2101,8 @@ class PolicyEngineManagerTest {
private class MyShutdown extends ShutdownThread {
@Override
- protected void doSleep(long sleepMs) throws InterruptedException {
- threadSleepMs = sleepMs;
+ protected void doSleep() throws InterruptedException {
+ threadSleepMs = 300L;
if (shouldInterrupt) {
throw new InterruptedException(EXPECTED);
@@ -2095,8 +2110,8 @@ class PolicyEngineManagerTest {
}
@Override
- protected void doExit(int code) {
- threadExitCode = code;
+ protected void doExit() {
+ threadExitCode = 0;
}
@Override
diff --git a/policy-management/src/test/java/org/onap/policy/drools/system/PolicyEngineTest.java b/policy-management/src/test/java/org/onap/policy/drools/system/PolicyEngineTest.java
index b4915ef4..a1b45de2 100644
--- a/policy-management/src/test/java/org/onap/policy/drools/system/PolicyEngineTest.java
+++ b/policy-management/src/test/java/org/onap/policy/drools/system/PolicyEngineTest.java
@@ -176,7 +176,7 @@ class PolicyEngineTest {
@Test
void test200Start() {
- logger.info("enter");
+ logger.info("enter test200Start");
PolicyEngineConstants.getManager().start();
@@ -188,7 +188,7 @@ class PolicyEngineTest {
@Test
void test300Lock() {
- logger.info("enter");
+ logger.info("enter test300Lock");
PolicyEngineConstants.getManager().lock();
@@ -200,7 +200,7 @@ class PolicyEngineTest {
@Test
void test301Unlock() {
- logger.info("enter");
+ logger.info("enter test301Unlock");
PolicyEngineConstants.getManager().unlock();
@@ -235,7 +235,7 @@ class PolicyEngineTest {
@Test
void test400ControllerAdd() {
- logger.info("enter");
+ logger.info("enter test400ControllerAdd");
final Properties controllerProperties = new Properties();
controllerProperties.put(DroolsPropertyConstants.PROPERTY_CONTROLLER_NAME, TEST_CONTROLLER_NAME);
@@ -250,7 +250,7 @@ class PolicyEngineTest {
@Test
void test401ControllerVerify() {
- logger.info("enter");
+ logger.info("enter test401ControllerVerify");
final PolicyController testController = PolicyControllerConstants.getFactory().get(TEST_CONTROLLER_NAME);
@@ -265,7 +265,7 @@ class PolicyEngineTest {
@Test
void test500Deactivate() {
- logger.info("enter");
+ logger.info("enter test500Deactivate");
PolicyEngineConstants.getManager().deactivate();
@@ -278,7 +278,7 @@ class PolicyEngineTest {
@Test
void test501Activate() {
- logger.info("enter");
+ logger.info("enter test501Activate");
PolicyEngineConstants.getManager().activate();
@@ -291,7 +291,7 @@ class PolicyEngineTest {
@Test
void test900ControllerRemove() {
- logger.info("enter");
+ logger.info("enter test900ControllerRemove");
PolicyEngineConstants.getManager().removePolicyController(TEST_CONTROLLER_NAME);
assertTrue(PolicyControllerConstants.getFactory().inventory().isEmpty());
@@ -299,7 +299,7 @@ class PolicyEngineTest {
@Test
void test901Stop() {
- logger.info("enter");
+ logger.info("enter test901Stop");
/* Shutdown managed resources */
PolicyControllerConstants.getFactory().shutdown();
diff --git a/policy-management/src/test/java/org/onap/policy/drools/system/internal/FeatureLockImplTest.java b/policy-management/src/test/java/org/onap/policy/drools/system/internal/FeatureLockImplTest.java
index 8a10c516..6d2380f0 100644
--- a/policy-management/src/test/java/org/onap/policy/drools/system/internal/FeatureLockImplTest.java
+++ b/policy-management/src/test/java/org/onap/policy/drools/system/internal/FeatureLockImplTest.java
@@ -213,22 +213,6 @@ class FeatureLockImplTest {
verify(callback, never()).lockUnavailable(any());
}
- /**
- * Tests doNotify() when there is no session.
- */
- @Test
- void testDoNotifyNoSession() {
- MyLock lock = new MyLock(LockState.WAITING, RESOURCE, OWNER_KEY, HOLD_SEC, callback);
- lock.grant();
-
- assertTrue(lock.isActive());
- assertEquals(1, lock.nupdates);
-
- invokeCallback();
- verify(callback).lockAvailable(any());
- verify(callback, never()).lockUnavailable(any());
- }
-
@Test
void testFreeAllowed() {
MyLock lock = new MyLock(LockState.WAITING, RESOURCE, OWNER_KEY, HOLD_SEC, callback);
diff --git a/policy-utils/pom.xml b/policy-utils/pom.xml
index 319711a1..09c4e142 100644
--- a/policy-utils/pom.xml
+++ b/policy-utils/pom.xml
@@ -70,5 +70,9 @@
<groupId>net.jimblackler.jsonschemafriend</groupId>
<artifactId>core</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-test</artifactId>
+ </dependency>
</dependencies>
</project>
diff --git a/policy-utils/src/main/java/org/onap/policy/drools/metrics/Metric.java b/policy-utils/src/main/java/org/onap/policy/drools/metrics/Metric.java
index 01ff58f5..c2755211 100644
--- a/policy-utils/src/main/java/org/onap/policy/drools/metrics/Metric.java
+++ b/policy-utils/src/main/java/org/onap/policy/drools/metrics/Metric.java
@@ -3,6 +3,7 @@
* ONAP
* ================================================================================
* Copyright (C) 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.
@@ -134,8 +135,7 @@ public class Metric {
}
if (endTime != null && startTime != null) {
- this.elapsedTime =
- Duration.between(startTime, endTime).toMillis();
+ this.elapsedTime = Duration.between(startTime, endTime).toMillis();
return;
}
diff --git a/policy-utils/src/main/java/org/onap/policy/drools/policies/DomainMaker.java b/policy-utils/src/main/java/org/onap/policy/drools/policies/DomainMaker.java
index 84c81cf0..27dfee49 100644
--- a/policy-utils/src/main/java/org/onap/policy/drools/policies/DomainMaker.java
+++ b/policy-utils/src/main/java/org/onap/policy/drools/policies/DomainMaker.java
@@ -31,7 +31,6 @@ import org.onap.policy.common.utils.coder.StandardCoder;
import org.onap.policy.common.utils.resources.ResourceUtils;
import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy;
-import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -70,7 +69,7 @@ public class DomainMaker {
return false;
}
- return validators.get(policyType).isConformant(json);
+ return getValidator(policyType).isConformant(json);
}
/**
@@ -94,7 +93,7 @@ public class DomainMaker {
}
try {
- return validators.get(policyType).encode(domainPolicy) != null;
+ return getValidator(policyType).encode(domainPolicy) != null;
} catch (CoderException e) {
logger.info("policy {}:{} is not conformant", policyType, domainPolicy.getClass().getName(), e);
return false;
@@ -116,7 +115,7 @@ public class DomainMaker {
}
try {
- validators.get(policy.getTypeIdentifier()).conformance(rawPolicy);
+ getValidator(policy.getTypeIdentifier()).conformance(rawPolicy);
} catch (CoderException e) {
logger.error("policy {}:{}:{} is not conformant",
policy.getTypeIdentifier(), policy.getName(), policy.getVersion(), e);
@@ -137,7 +136,7 @@ public class DomainMaker {
}
try {
- validators.get(policyType).encode(domainPolicy);
+ getValidator(policyType).encode(domainPolicy);
} catch (CoderException e) {
logger.error("policy {}:{} is not conformant", policyType, domainPolicy.getClass().getName(), e);
return false;
@@ -190,29 +189,21 @@ public class DomainMaker {
public <T> T convertTo(@NonNull ToscaConceptIdentifier policyType, @NonNull String json, @NonNull Class<T> clazz)
throws CoderException {
if (isRegistered(policyType)) {
- return validators.get(policyType).decode(json, clazz);
+ return getValidator(policyType).decode(json, clazz);
} else {
return nonValCoder.decode(json, clazz);
}
}
- /**
- * Converts a Tosca Policy Type specification to a domain-specific json specification.
- */
- public String convertToSchema(@NonNull ToscaPolicyType policyType) {
- //
- // TODO: // NOSONAR
- // 1. Convert Tosca Policy Type definition schema to suitable json schema.
- // 2. Call registerValidator to register
- throw new UnsupportedOperationException("schema generation from policy type is not supported");
- }
-
public boolean isRegistered(@NonNull ToscaConceptIdentifier policyType) {
return validators.containsKey(policyType) || registerValidator(policyType);
}
+ private StandardValCoder getValidator(ToscaConceptIdentifier policyType) {
+ return validators.get(policyType);
+ }
- private String serialize(@NonNull ToscaPolicy policy) {
+ private String serialize(ToscaPolicy policy) {
String rawPolicy = null;
try {
rawPolicy = nonValCoder.encode(policy);
diff --git a/policy-utils/src/test/java/org/onap/policy/drools/metrics/MetricTest.java b/policy-utils/src/test/java/org/onap/policy/drools/metrics/MetricTest.java
index 924d1c95..f1999cce 100644
--- a/policy-utils/src/test/java/org/onap/policy/drools/metrics/MetricTest.java
+++ b/policy-utils/src/test/java/org/onap/policy/drools/metrics/MetricTest.java
@@ -48,12 +48,12 @@ class MetricTest {
void testPojo() {
PojoClass metric = PojoClassFactory.getPojoClass(Metric.class);
Validator val = ValidatorBuilder
- .create()
- .with(new SetterMustExistRule())
- .with(new GetterMustExistRule())
- .with(new SetterTester())
- .with(new GetterTester())
- .build();
+ .create()
+ .with(new SetterMustExistRule())
+ .with(new GetterMustExistRule())
+ .with(new SetterTester())
+ .with(new GetterTester())
+ .build();
val.validate(metric);
}
@@ -190,4 +190,24 @@ class MetricTest {
Instant now = Instant.now();
assertEquals(new SimpleDateFormat(Metric.DATE_FORMAT).format(Date.from(now)), Metric.toTimestamp(now));
}
+
+ @Test
+ void testElapsedTime_EndTimeStartTimeNullValues() {
+ // test seems unnecessary, but when setElapsedTime receives null,
+ // the method tries to calculate elapsed time between start and end time,
+ // which only having the values was covered.
+ Metric metric = new Metric();
+
+ metric.setElapsedTime(null);
+ assertNull(metric.getElapsedTime());
+
+ metric.setEndTime(Instant.now());
+ metric.setElapsedTime(null);
+ assertNull(metric.getElapsedTime());
+
+ metric = new Metric();
+ metric.setStartTime(Instant.now());
+ metric.setElapsedTime(null);
+ assertNull(metric.getElapsedTime());
+ }
} \ No newline at end of file
diff --git a/policy-utils/src/test/java/org/onap/policy/drools/policies/DomainMakerTest.java b/policy-utils/src/test/java/org/onap/policy/drools/policies/DomainMakerTest.java
index f8ffa503..8fbf237f 100644
--- a/policy-utils/src/test/java/org/onap/policy/drools/policies/DomainMakerTest.java
+++ b/policy-utils/src/test/java/org/onap/policy/drools/policies/DomainMakerTest.java
@@ -26,6 +26,8 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
import java.io.IOException;
import java.nio.file.Files;
@@ -40,7 +42,7 @@ import org.onap.policy.drools.models.domains.a.Nested;
import org.onap.policy.drools.models.domains.a.Properties;
import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy;
-import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyType;
+import org.springframework.test.util.ReflectionTestUtils;
class DomainMakerTest {
@@ -62,6 +64,13 @@ class DomainMakerTest {
policyTypeId.setVersion("2.0.0");
assertFalse(domainMaker.isConformant(policyTypeId, rawJsonPolicyType));
+
+ // for code coverage
+ assertThatThrownBy(() -> domainMaker.isConformant(null, "{\"json\":\"valid\"}"))
+ .hasMessageContaining("policyType is marked non-null but is null");
+
+ assertThatThrownBy(() -> domainMaker.isConformant(policyTypeId, null))
+ .hasMessageContaining("json is marked non-null but is null");
}
@Test
@@ -93,6 +102,12 @@ class DomainMakerTest {
// not registered schema for policy type
policyTypeId.setVersion("2.0.0");
assertFalse(domainMaker.isDomainConformant(policyTypeId, domainAPolicy));
+
+ assertThatThrownBy(() -> domainMaker.isDomainConformant(null, domainAPolicy))
+ .hasMessageContaining("policyType is marked non-null but is null");
+
+ assertThatThrownBy(() -> domainMaker.isDomainConformant(policyTypeId, null))
+ .hasMessageContaining("domainPolicy is marked non-null but is null");
}
@@ -117,6 +132,12 @@ class DomainMakerTest {
policy2.setTypeVersion("4.2.5");
assertFalse(domainMaker.conformance(policy2));
assertFalse(domainMaker.conformance(policy2.getTypeIdentifier(), domainAPolicy));
+
+ assertThatThrownBy(() -> domainMaker.conformance(null, domainAPolicy))
+ .hasMessageContaining("policyType is marked non-null but is null");
+
+ assertThatThrownBy(() -> domainMaker.conformance(null))
+ .hasMessageContaining("policy is marked non-null but is null");
}
@Test
@@ -136,6 +157,15 @@ class DomainMakerTest {
assertFalse(domainMaker.isConformant(policy));
assertFalse(domainMaker.registerValidator(policy.getTypeIdentifier(), "$schema"));
+
+ assertThatThrownBy(() -> domainMaker.registerValidator(null))
+ .hasMessageContaining("policyType is marked non-null but is null");
+
+ assertThatThrownBy(() -> domainMaker.registerValidator(null, "$schema"))
+ .hasMessageContaining("policyType is marked non-null but is null");
+
+ assertThatThrownBy(() -> domainMaker.registerValidator(policy.getTypeIdentifier(), null))
+ .hasMessageContaining("schema is marked non-null but is null");
}
@Test
@@ -146,14 +176,21 @@ class DomainMakerTest {
assertNotNull(domainMaker.convertTo(getToscaPolicy("src/test/resources/policyA-no-policy-type.json"),
DomainAPolicy.class));
- }
- @Test
- void testConvertToSchema() {
- ToscaPolicyType type = new ToscaPolicyType();
- assertThatThrownBy(() -> domainMaker
- .convertToSchema(type))
- .isInstanceOf(UnsupportedOperationException.class);
+ assertThatThrownBy(() -> domainMaker.convertTo(null, DomainAPolicy.class))
+ .hasMessageContaining("toscaPolicy is marked non-null but is null");
+
+ assertThatThrownBy(() -> domainMaker.convertTo(mock(ToscaPolicy.class), null))
+ .hasMessageContaining("clazz is marked non-null but is null");
+
+ assertThatThrownBy(() -> domainMaker.convertTo(null, "json", DomainAPolicy.class))
+ .hasMessageContaining("policyType is marked non-null but is null");
+
+ assertThatThrownBy(() -> domainMaker.convertTo(mock(ToscaConceptIdentifier.class), null, DomainAPolicy.class))
+ .hasMessageContaining("json is marked non-null but is null");
+
+ assertThatThrownBy(() -> domainMaker.convertTo(mock(ToscaConceptIdentifier.class), "json", null))
+ .hasMessageContaining("clazz is marked non-null but is null");
}
@Test
@@ -166,6 +203,25 @@ class DomainMakerTest {
new ToscaConceptIdentifier("policy.type.external", "7.7.9");
assertFalse(domainMaker.isRegistered(policyTypeId2));
+ assertThatThrownBy(() -> domainMaker.isRegistered(null))
+ .hasMessageContaining("policyType is marked non-null but is null");
+ }
+
+ @Test
+ void testIsConformant_SerializeReturnsNull() throws CoderException {
+ var mockDomainMaker = mock(DomainMaker.class);
+ var mockToscaPolicy = mock(ToscaPolicy.class);
+ when(mockDomainMaker.isConformant(mockToscaPolicy)).thenCallRealMethod();
+
+ var mockCoder = mock(StandardCoder.class);
+ when(mockCoder.encode(mockToscaPolicy)).thenThrow(new CoderException("error"));
+ ReflectionTestUtils.setField(mockDomainMaker, "nonValCoder", mockCoder);
+
+ assertFalse(mockDomainMaker.isConformant(mockToscaPolicy));
+
+ when(mockDomainMaker.conformance(mockToscaPolicy)).thenCallRealMethod();
+ when(mockDomainMaker.isRegistered(mockToscaPolicy.getTypeIdentifier())).thenReturn(true);
+ assertFalse(mockDomainMaker.conformance(mockToscaPolicy));
}
private String getJsonFromFile(String filePath) throws IOException {
diff --git a/policy-utils/src/test/java/org/onap/policy/drools/utils/LookupTest.java b/policy-utils/src/test/java/org/onap/policy/drools/utils/LookupTest.java
new file mode 100644
index 00000000..dd043b47
--- /dev/null
+++ b/policy-utils/src/test/java/org/onap/policy/drools/utils/LookupTest.java
@@ -0,0 +1,57 @@
+/*-
+ * ============LICENSE_START================================================
+ * 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.
+ * 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.drools.utils;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import org.junit.jupiter.api.Test;
+import org.onap.policy.common.utils.security.CryptoCoder;
+
+class LookupTest {
+
+ @Test
+ void testCryptoLookup() {
+ var cryptoCoder = new CryptoCoderValueLookup(new CryptoCoder() {
+ @Override
+ public String encrypt(String s) {
+ return String.valueOf(s.hashCode());
+ }
+
+ @Override
+ public String decrypt(String s) {
+ return s;
+ }
+ });
+
+ assertTrue(cryptoCoder.lookup("hello").startsWith("enc"));
+ assertNull(cryptoCoder.lookup(null));
+ assertNull(cryptoCoder.lookup(""));
+ }
+
+ @Test
+ void testEnvDefaultLookup() {
+ var envLookup = new EnvironmentVariableWithDefaultLookup();
+
+ assertNull(envLookup.lookup(null));
+ assertNull(envLookup.lookup(""));
+ assertEquals("", envLookup.lookup(":"));
+ }
+} \ No newline at end of file
diff --git a/policy-utils/src/test/java/org/onap/policy/drools/utils/PropertyUtilTest.java b/policy-utils/src/test/java/org/onap/policy/drools/utils/PropertyUtilTest.java
index f2676e5d..bec22237 100644
--- a/policy-utils/src/test/java/org/onap/policy/drools/utils/PropertyUtilTest.java
+++ b/policy-utils/src/test/java/org/onap/policy/drools/utils/PropertyUtilTest.java
@@ -22,6 +22,8 @@
package org.onap.policy.drools.utils;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.File;
@@ -93,7 +95,8 @@ public class PropertyUtilTest {
// create a directory for temporary files
directory = new File(UUID.randomUUID().toString());
- directory.mkdir();
+ var isDirCreated = directory.mkdir();
+ logger.info("directory created: {}", isDirCreated);
}
/**
@@ -141,8 +144,7 @@ public class PropertyUtilTest {
public void propertiesChanged(Properties properties, Set<String> changedKeys) {
// When a notification is received, store the values in the
// 'returns' array, and signal using the same array.
- logger.info("Listener invoked: properties=" + properties
- + ", changedKeys=" + changedKeys);
+ logger.info("Listener invoked: properties={}, changedKeys={}", properties, changedKeys);
returns[0] = properties;
returns[1] = changedKeys;
synchronized (returns) {
@@ -181,6 +183,73 @@ public class PropertyUtilTest {
}
+ /**
+ * This tests the 'PropertyUtil.Listener' interface.
+ */
+ @Test
+ void testListenerInterface() throws Exception {
+ logger.info("testListenerInterface: test receipt of dynamic updates");
+
+ // create initial property file
+ Properties prop1 = new Properties();
+ prop1.setProperty("p1", "p1 value");
+ prop1.setProperty("p2", "p2 value");
+ prop1.setProperty("p3", "p3 value");
+ logger.info("Create initial properties file: {}", prop1);
+ File file1 = createFile("createAndReadPropertyFile-2", prop1);
+
+ // create a listener for the notification interface
+ Object[] returns = new Object[2];
+ PropertyUtil.Listener listener = createListenerThread(returns);
+
+ // read it in, and do a comparison
+ Properties prop2 = PropertyUtil.getProperties(file1, listener);
+ logger.info("Read in properties: {}", prop2);
+ assertEquals(prop1, prop2);
+ assertEquals("p1 value", prop2.getProperty("p1"));
+ assertEquals("p2 value", prop2.getProperty("p2"));
+ assertEquals("p3 value", prop2.getProperty("p3"));
+
+ // make some changes, and update the file (p3 is left unchanged)
+ prop2.remove("p1"); // remove one property
+ prop2.setProperty("p2", "new p2 value"); // change one property
+ prop2.setProperty("p4", "p4 value"); // add a new property
+ logger.info("Modified properties: {}", prop2);
+
+ // now, update the file, and wait for notification
+ synchronized (returns) {
+ createFile("createAndReadPropertyFile-2", prop2);
+
+ // wait up to 60 seconds, although we should receive notification
+ // in 10 seconds or less (if things are working)
+ returns.wait(60000L);
+ }
+
+ // verify we have the updates
+ assertEquals(prop2, returns[0]);
+
+ // verify that we have the expected set of keys
+ assertEquals(new TreeSet<>(Arrays.asList("p1", "p2", "p4")), returns[1]);
+
+ String filePath = file1.getAbsolutePath();
+ PropertyUtil.stopListening(filePath, listener);
+ }
+
+ @Test
+ void testGetProperties_ListenerNull() throws IOException {
+ String filepath = "src/test/resources/interpolation.properties";
+ File propertiesFile = new File(filepath);
+ assertNotNull(propertiesFile);
+ PropertyUtil.Listener listener = null;
+ var result = PropertyUtil.getProperties(propertiesFile, listener);
+ assertNotNull(result);
+ assertInstanceOf(Properties.class, result);
+
+ var anotherResult = PropertyUtil.getProperties(filepath, listener);
+ assertNotNull(anotherResult);
+ assertInstanceOf(Properties.class, anotherResult);
+ }
+
private void testGetDefaultCryptoSystemProps() throws IOException {
// system properties + default crypto coder
PropertyUtil.setDefaultCryptoCoder(new CryptoUtils(INTERPOLATION_CRYPTO_KEY));
@@ -251,54 +320,4 @@ public class PropertyUtilTest {
assertEquals(System.getProperty("user.home"), props.getProperty(INTERPOLATION_SYS));
assertEquals(INTERPOLATION_ENVD_DEFAULT_VALUE, props.getProperty(INTERPOLATION_ENVD_DEFAULT));
}
-
- /**
- * This tests the 'PropertyUtil.Listener' interface.
- */
- @Test
- void testListenerInterface() throws Exception {
- logger.info("testListenerInterface: test receipt of dynamic updates");
-
- // create initial property file
- Properties prop1 = new Properties();
- prop1.setProperty("p1", "p1 value");
- prop1.setProperty("p2", "p2 value");
- prop1.setProperty("p3", "p3 value");
- logger.info("Create initial properties file: " + prop1);
- File file1 = createFile("createAndReadPropertyFile-2", prop1);
-
- // create a listener for the notification interface
- Object[] returns = new Object[2];
- PropertyUtil.Listener listener = createListenerThread(returns);
-
- // read it in, and do a comparison
- Properties prop2 = PropertyUtil.getProperties(file1, listener);
- logger.info("Read in properties: " + prop2);
- assertEquals(prop1, prop2);
- assertEquals("p1 value", prop2.getProperty("p1"));
- assertEquals("p2 value", prop2.getProperty("p2"));
- assertEquals("p3 value", prop2.getProperty("p3"));
-
- // make some changes, and update the file (p3 is left unchanged)
- prop2.remove("p1"); // remove one property
- prop2.setProperty("p2", "new p2 value"); // change one property
- prop2.setProperty("p4", "p4 value"); // add a new property
- logger.info("Modified properties: " + prop2);
-
- // now, update the file, and wait for notification
- synchronized (returns) {
- createFile("createAndReadPropertyFile-2", prop2);
-
- // wait up to 60 seconds, although we should receive notification
- // in 10 seconds or less (if things are working)
- returns.wait(60000L);
- }
-
- // verify we have the updates
- assertEquals(prop2, returns[0]);
-
- // verify that we have the expected set of keys
- assertEquals(new TreeSet<String>(Arrays.asList(new String[]{"p1", "p2", "p4"})),
- returns[1]);
- }
}