diff options
author | adheli.tavares <adheli.tavares@est.tech> | 2024-09-20 17:33:08 +0100 |
---|---|---|
committer | adheli.tavares <adheli.tavares@est.tech> | 2024-09-23 14:51:04 +0100 |
commit | cedfc60c8266c39ea72efa17aa3a644cbc223d19 (patch) | |
tree | 2146164f826b1d36e95e9aed7491ed949db4c3d7 | |
parent | c274fd4a91bdbd86d8fc719f12834133adc6584d (diff) |
Increase code coverage overall
Issue-ID: POLICY-5068
Change-Id: I1763d3c00392ac655a998cd2fb869748a7323812
Signed-off-by: adheli.tavares <adheli.tavares@est.tech>
23 files changed, 2050 insertions, 630 deletions
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-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/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-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 203d6bf2..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. */ @@ -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 @@ -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/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/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(); |