diff options
Diffstat (limited to 'feature-lifecycle/src/test')
10 files changed, 781 insertions, 35 deletions
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 9c30b3f9..4c1830b8 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 @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * ONAP * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2019, 2021 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,7 +20,10 @@ package org.onap.policy.drools.lifecycle; +import java.io.File; import java.io.IOException; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; import java.nio.file.Paths; import java.util.List; import java.util.Properties; @@ -64,8 +67,8 @@ public class ControllerSupport { PolicyController controller = getController(); controller.getDrools().delete(ToscaPolicy.class); return controller; - } catch (IllegalArgumentException e) { - ; + } catch (IllegalArgumentException ignored) { // NOSONAR + ; // checkstyle } ReleaseId coordinates = installArtifact(); @@ -81,14 +84,21 @@ public class ControllerSupport { } /** + * Install a maven artifact. + */ + public static ReleaseId installArtifact(File kmodule, File pom, + String drlKjarPath, List<File> drls) throws IOException { + return KieUtils.installArtifact(kmodule, pom, drlKjarPath, drls); + } + + /** * install artifact. */ public ReleaseId installArtifact() throws IOException { - return - KieUtils.installArtifact(Paths.get(JUNIT_KMODULE_PATH).toFile(), + return ControllerSupport.installArtifact(Paths.get(JUNIT_KMODULE_PATH).toFile(), Paths.get(JUNIT_KMODULE_POM_PATH).toFile(), - JUNIT_KJAR_DRL_PATH, - Paths.get(JUNIT_KMODULE_DRL_PATH).toFile()); + JUNIT_KJAR_DRL_PATH, + List.of(Paths.get(JUNIT_KMODULE_DRL_PATH).toFile())); } /** @@ -120,4 +130,27 @@ public class ControllerSupport { .getDrools() .facts(SESSION_NAME, clazz); } + + /** + * Change final marker in static field. + */ + public static <T> Field unsetFinalStaticAccess(Class<T> clazz, String fieldName) + throws NoSuchFieldException, IllegalAccessException { + Field field = clazz.getDeclaredField(fieldName); + field.setAccessible(true); + + Field modifiers = Field.class.getDeclaredField("modifiers"); + modifiers.setAccessible(true); + modifiers.setInt(field, field.getModifiers() & ~Modifier.FINAL); + + return field; + } + + /* + * Reassign static field. + */ + public static <T, E> void setStaticField(Class<T> clazz, String fieldName, E newValue) + throws NoSuchFieldException, IllegalAccessException { + unsetFinalStaticAccess(clazz, fieldName).set(null, newValue); + } } 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 b5c4f1b5..0e3680dc 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 @@ -27,6 +27,7 @@ import java.nio.file.Files; import java.nio.file.Paths; import java.util.Collections; import java.util.List; +import java.util.Map; import java.util.concurrent.ScheduledExecutorService; import org.junit.Before; import org.junit.Test; @@ -139,6 +140,26 @@ public class LifecycleFsmTest { @Test public void testGetUndeployableActions() { + deployAllPolicies(); + List<ToscaPolicy> expectedUndeployOrder = + List.of(opPolicy, op2Policy, unvalPolicy, valPolicy, artifactPolicy, + artifact2Policy, controller2Policy, controllerPolicy); + + assertEquals(expectedUndeployOrder, fsm.getUndeployablePoliciesAction(Collections.EMPTY_LIST)); + assertEquals(expectedUndeployOrder, fsm.getUndeployablePoliciesAction(Collections.EMPTY_LIST)); + assertEquals(expectedUndeployOrder, fsm.getUndeployablePoliciesAction(Collections.EMPTY_LIST)); + } + + @Test + public void testGetNativeArtifactPolicies() { + deployAllPolicies(); + + Map<String, List<ToscaPolicy>> deployedPolicies = fsm.groupPoliciesByPolicyType(fsm.getActivePolicies()); + assertEquals(2, fsm.getNativeArtifactPolicies(deployedPolicies).size()); + assertEquals(List.of(artifactPolicy, artifact2Policy), fsm.getNativeArtifactPolicies(deployedPolicies)); + } + + protected void deployAllPolicies() { fsm.deployedPolicyAction(controllerPolicy); fsm.deployedPolicyAction(controller2Policy); fsm.deployedPolicyAction(artifactPolicy); @@ -147,14 +168,6 @@ public class LifecycleFsmTest { fsm.deployedPolicyAction(valPolicy); fsm.deployedPolicyAction(unvalPolicy); fsm.deployedPolicyAction(op2Policy); - - List<ToscaPolicy> expectedUndeployOrder = - List.of(opPolicy, op2Policy, unvalPolicy, valPolicy, artifactPolicy, - artifact2Policy, controller2Policy, controllerPolicy); - - assertEquals(expectedUndeployOrder, fsm.getUndeployablePoliciesAction(Collections.EMPTY_LIST)); - assertEquals(expectedUndeployOrder, fsm.getUndeployablePoliciesAction(Collections.EMPTY_LIST)); - assertEquals(expectedUndeployOrder, fsm.getUndeployablePoliciesAction(Collections.EMPTY_LIST)); } protected ToscaPolicy getPolicyFromFile(String filePath, String policyName) throws CoderException, IOException { 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 new file mode 100644 index 00000000..01500576 --- /dev/null +++ b/feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/LifecycleFsmUpdateTest.java @@ -0,0 +1,585 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2021 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * =============LICENSE_END======================================================== + */ + +package org.onap.policy.drools.lifecycle; + +import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import com.google.common.base.Strings; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.concurrent.ScheduledExecutorService; +import java.util.stream.Collectors; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.onap.policy.common.endpoints.event.comm.TopicEndpointManager; +import org.onap.policy.common.endpoints.event.comm.bus.NoopTopicFactories; +import org.onap.policy.common.endpoints.properties.PolicyEndPointProperties; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; +import org.onap.policy.common.utils.network.NetworkUtil; +import org.onap.policy.common.utils.resources.ResourceUtils; +import org.onap.policy.common.utils.time.PseudoScheduledExecutorService; +import org.onap.policy.common.utils.time.TestTimeMulti; +import org.onap.policy.drools.domain.models.artifact.NativeArtifactPolicy; +import org.onap.policy.drools.domain.models.controller.ControllerPolicy; +import org.onap.policy.drools.persistence.SystemPersistenceConstants; +import org.onap.policy.drools.system.PolicyControllerConstants; +import org.onap.policy.drools.utils.logging.LoggerUtil; +import org.onap.policy.models.pdp.concepts.PdpStateChange; +import org.onap.policy.models.pdp.concepts.PdpUpdate; +import org.onap.policy.models.pdp.enums.PdpState; +import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy; +import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; + +/** + * Lifecycle FSM Updates Test. + */ +public class LifecycleFsmUpdateTest { + + private static final String EXAMPLE_NATIVE_CONTROLLER_POLICY_NAME = "example.controller"; + private static final String EXAMPLE_NATIVE_CONTROLLER_POLICY_JSON = + "src/test/resources/tosca-policy-native-controller-example.json"; + + private static final String EXAMPLE_NATIVE_ARTIFACT_POLICY_NAME = "example.artifact"; + private static final String EXAMPLE_NATIVE_ARTIFACT_POLICY_JSON = + "src/test/resources/tosca-policy-native-artifact-example.json"; + + private static final String EXAMPLE_OTHER_UNVAL_POLICY_NAME = "other-unvalidated"; + private static final String EXAMPLE_OTHER_UNVAL_POLICY_JSON = + "src/test/resources/tosca-policy-other-unvalidated.json"; + + private static final String EXAMPLE_OTHER_VAL_POLICY_NAME = "other-validated"; + private static final String EXAMPLE_OTHER_VAL_POLICY_JSON = + "src/test/resources/tosca-policy-other-validated.json"; + + private static final String FOO_NATIVE_CONTROLLER_POLICY_NAME = "foo.controller"; + private static final String FOO_NATIVE_CONTROLLER_POLICY_JSON = + "src/test/resources/tosca-policy-native-controller-foo.json"; + + private static final String FOO_NATIVE_ARTIFACT_POLICY_NAME = "foo.artifact"; + private static final String FOO_NATIVE_ARTIFACT_POLICY_JSON = + "src/test/resources/tosca-policy-native-artifact-foo.json"; + + private static final String VCPE_OP_POLICY_NAME = "operational.restart"; + private static final String VCPE_OPERATIONAL_DROOLS_POLICY_JSON = + "policies/vCPE.policy.operational.input.tosca.json"; + + private static final String VFW_OP_POLICY_NAME = "operational.modifyconfig"; + private static final String VFW_OPERATIONAL_DROOLS_POLICY_JSON = + "policies/vFirewall.policy.operational.input.tosca.json"; + + private static final StandardCoder coder = new StandardCoder(); + + protected static LifecycleFsm savedFsm; + protected LifecycleFsm fsm; + + private ToscaPolicy opPolicy; + private ToscaPolicy op2Policy; + private ToscaPolicy valPolicy; + private ToscaPolicy unvalPolicy; + private ToscaPolicy controllerPolicy; + private ToscaPolicy controller2Policy; + private ToscaPolicy artifactPolicy; + private ToscaPolicy artifact2Policy; + + /** + * Set up. + */ + @BeforeClass + public static void setUp() throws IOException { + LoggerUtil.setLevel(LoggerUtil.ROOT_LOGGER, "INFO"); + LoggerUtil.setLevel("org.onap.policy.common.endpoints", "WARN"); + LoggerUtil.setLevel("org.onap.policy.drools", "INFO"); + + SystemPersistenceConstants.getManager().setConfigurationDir("target/test-classes"); + + ControllerSupport.installArtifact( + Paths.get(ControllerSupport.JUNIT_KMODULE_PATH).toFile(), + Paths.get(ControllerSupport.JUNIT_KMODULE_POM_PATH).toFile(), + ControllerSupport.JUNIT_KJAR_DRL_PATH, + List.of(Paths.get(ControllerSupport.JUNIT_KMODULE_DRL_PATH).toFile())); + + ControllerSupport.installArtifact( + Paths.get("src/test/resources/echo.kmodule").toFile(), + Paths.get("src/test/resources/echo.pom").toFile(), + "src/main/resources/kbecho/org/onap/policy/drools/test/", + List.of(Paths.get("src/test/resources/echo.drl").toFile())); + + Properties noopTopicProperties = new Properties(); + noopTopicProperties.put(PolicyEndPointProperties.PROPERTY_NOOP_SOURCE_TOPICS, "DCAE_TOPIC"); + noopTopicProperties.put(PolicyEndPointProperties.PROPERTY_NOOP_SINK_TOPICS, "APPC-CL"); + TopicEndpointManager.getManager().addTopics(noopTopicProperties); + + savedFsm = LifecycleFeature.fsm; + } + + /** + * Tear Down. + */ + @AfterClass + public static void tearDown() throws NoSuchFieldException, IllegalAccessException { + PolicyControllerConstants.getFactory().destroy(); + + NoopTopicFactories.getSourceFactory().destroy(); + NoopTopicFactories.getSinkFactory().destroy(); + try { + Files.deleteIfExists(Paths.get(SystemPersistenceConstants.getManager().getConfigurationPath().toString(), + "lifecycle-controller.properties.bak")); + Files.deleteIfExists(Paths.get(SystemPersistenceConstants.getManager().getConfigurationPath().toString(), + "foo-controller.properties.bak")); + } catch (IOException ignored) { // NOSONAR + ; // checkstyle + } + + ControllerSupport.setStaticField(LifecycleFeature.class, "fsm", savedFsm); + } + + /** + * Test initialization. + */ + @Before + public void init() throws CoderException, IOException, NoSuchFieldException, IllegalAccessException { + fsm = new LifecycleFsm() { + @Override + protected ScheduledExecutorService makeExecutor() { // NOSONAR + return new PseudoScheduledExecutorService(new TestTimeMulti()); + } + }; + ControllerSupport.setStaticField(LifecycleFeature.class, "fsm", fsm); + + fsm.setStatusTimerSeconds(15); + assertTrue(fsm.start()); + + PdpStateChange change = new PdpStateChange(); + change.setPdpGroup("A"); + change.setPdpSubgroup("a"); + change.setState(PdpState.ACTIVE); + change.setName(fsm.getName()); + + fsm.setSubGroupAction("a"); + fsm.source.offer(new StandardCoder().encode(change)); + + assertEquals(0, fsm.getPoliciesMap().size()); + assertEquals("ACTIVE", fsm.state().toString()); + assertEquals(2, fsm.getPolicyTypesMap().size()); + + opPolicy = getExamplesPolicy(VFW_OPERATIONAL_DROOLS_POLICY_JSON, VFW_OP_POLICY_NAME); + op2Policy = getExamplesPolicy(VCPE_OPERATIONAL_DROOLS_POLICY_JSON, VCPE_OP_POLICY_NAME); + controllerPolicy = + getPolicyFromFile(EXAMPLE_NATIVE_CONTROLLER_POLICY_JSON, EXAMPLE_NATIVE_CONTROLLER_POLICY_NAME); + controller2Policy = getPolicyFromFile(FOO_NATIVE_CONTROLLER_POLICY_JSON, FOO_NATIVE_CONTROLLER_POLICY_NAME); + artifactPolicy = + getPolicyFromFile(EXAMPLE_NATIVE_ARTIFACT_POLICY_JSON, EXAMPLE_NATIVE_ARTIFACT_POLICY_NAME); + artifact2Policy = getExamplesPolicy(FOO_NATIVE_ARTIFACT_POLICY_JSON, FOO_NATIVE_ARTIFACT_POLICY_NAME); + valPolicy = + getPolicyFromFile(EXAMPLE_OTHER_VAL_POLICY_JSON, EXAMPLE_OTHER_VAL_POLICY_NAME); + unvalPolicy = + getPolicyFromFile(EXAMPLE_OTHER_UNVAL_POLICY_JSON, EXAMPLE_OTHER_UNVAL_POLICY_NAME); + } + + @Test + public void testUpdate() throws CoderException { + assertEquals(0, fsm.getPoliciesMap().size()); + assertEquals("ACTIVE", fsm.state().toString()); + assertEquals(0, PolicyControllerConstants.getFactory().inventory().size()); + + // native controller policy - deploy + // Delta: +controllerPolicy + assertTrue(fsm.update(getPdpUpdate(List.of(controllerPolicy)))); + verifyActivePolicies(List.of(controllerPolicy)); + + // no policies - undeploy + // Delta: [] + assertTrue(fsm.update(getPdpUpdate(Collections.emptyList()))); + verifyActivePolicies(Collections.emptyList()); + + // native controller + artifact policy (out of order) - deploy + // Delta: +artifactPolicy, +controllerPolicy + assertTrue(fsm.update(getPdpUpdate(List.of(artifactPolicy, controllerPolicy)))); + verifyActivePolicies(List.of(artifactPolicy, controllerPolicy)); + + // attempt to deploy opPolicy but invalid controller + // Delta: +opPolicy + assertFalse(fsm.update(getPdpUpdate(List.of(artifactPolicy, opPolicy, controllerPolicy)))); + assertEquals(1, PolicyControllerConstants.getFactory().inventory().size()); + assertFalse(fsm.getActivePolicies().contains(opPolicy)); + verifyExists(false, "lifecycle", List.of(opPolicy)); + verifyActivePolicies(List.of(artifactPolicy, controllerPolicy)); + + // Delta: +opPolicy + opPolicy.getProperties().remove("controllerName"); + assertTrue(fsm.update(getPdpUpdate(List.of(artifactPolicy, opPolicy, controllerPolicy)))); + verifyExists(true, "lifecycle", List.of(opPolicy)); + verifyActivePolicies(List.of(opPolicy, artifactPolicy, controllerPolicy)); + + // Delta: -opPolicy + assertTrue(fsm.update(getPdpUpdate(List.of(artifactPolicy, controllerPolicy)))); + assertFalse(PolicyControllerConstants.getFactory().get("lifecycle").getDrools().exists(opPolicy)); + verifyActivePolicies(List.of(controllerPolicy, artifactPolicy)); + + // Delta: -artifactPolicy + assertTrue(fsm.update(getPdpUpdate(List.of(controllerPolicy)))); + assertFalse(PolicyControllerConstants.getFactory().get("lifecycle").getDrools().isBrained()); + verifyActivePolicies(List.of(controllerPolicy)); + + // Delta: -controllerPolicy + assertTrue(fsm.update(getPdpUpdate(Collections.emptyList()))); + assertThatIllegalArgumentException().isThrownBy(() -> PolicyControllerConstants.getFactory().get("lifecycle")); + assertEquals(0, PolicyControllerConstants.getFactory().inventory().size()); + verifyActivePolicies(Collections.emptyList()); + + // Delta: +controllerPolicy, +artifactPolicy, and +opPolicy + assertTrue(fsm.update(getPdpUpdate(List.of(opPolicy, artifactPolicy, controllerPolicy)))); + verifyExists(true, "lifecycle", List.of(opPolicy)); + verifyActivePolicies(List.of(opPolicy, artifactPolicy, controllerPolicy)); + + // Delta: -artifactPolicy + assertTrue(fsm.update(getPdpUpdate(List.of(opPolicy, controllerPolicy)))); + assertEquals(1, PolicyControllerConstants.getFactory().inventory().size()); + assertFalse(PolicyControllerConstants.getFactory().get("lifecycle").getDrools().isBrained()); + + // Delta: +artifactPolicy + // from deltas, all delta updates should be successfully applied + assertTrue(fsm.update(getPdpUpdate(List.of(opPolicy, controllerPolicy, artifactPolicy)))); + verifyExists(true, "lifecycle", List.of(opPolicy)); + verifyActivePolicies(List.of(opPolicy, artifactPolicy, controllerPolicy)); + + // Delta: -controllerPolicy + // from deltas, all delta updates should be successfully applied + assertTrue(fsm.update(getPdpUpdate(List.of(opPolicy, artifactPolicy)))); + assertEquals(0, PolicyControllerConstants.getFactory().inventory().size()); + + // Delta: +controllerPolicy + // from deltas, all delta updates should be successfully applied + assertTrue(fsm.update(getPdpUpdate(List.of(opPolicy, controllerPolicy, artifactPolicy)))); + verifyExists(true, "lifecycle", List.of(opPolicy)); + verifyActivePolicies(List.of(opPolicy, artifactPolicy, controllerPolicy)); + + // Delta: +op2Policy, +controller2Policy + // from deltas, all delta updates should be successfully applied + op2Policy.getProperties().put("controllerName", "lifecycle"); + assertTrue(fsm.update(getPdpUpdate( + List.of(opPolicy, controllerPolicy, artifactPolicy, op2Policy, controller2Policy)))); + verifyExists(true, "lifecycle", List.of(opPolicy, op2Policy)); + assertFalse(PolicyControllerConstants.getFactory().get("foo").getDrools().isBrained()); + verifyActivePolicies(List.of(opPolicy, artifactPolicy, controllerPolicy, op2Policy, controller2Policy)); + + // Delta: +artifact2policy, +valPolicy, +unvalPolicy + // from deltas, all delta updates should be successfully applied + assertTrue(fsm.update(getPdpUpdate( + List.of(opPolicy, controllerPolicy, artifactPolicy, + op2Policy, controller2Policy, valPolicy, unvalPolicy, artifact2Policy)))); + verifyExists(true, "lifecycle", List.of(opPolicy, op2Policy, valPolicy, unvalPolicy)); + verifyExists(true, "foo", List.of(valPolicy, unvalPolicy)); + verifyExists(false, "foo", List.of(opPolicy, op2Policy)); + verifyActivePolicies(List.of(opPolicy, artifactPolicy, controllerPolicy, op2Policy, + controller2Policy, valPolicy, unvalPolicy, artifact2Policy)); + + // Delta: -artifact2Policy, +valPolicy + // from deltas, all delta updates should be successfully applied, and unvalPolicy disabled + assertTrue(fsm.update(getPdpUpdate( + List.of(opPolicy, controllerPolicy, artifactPolicy, + op2Policy, controller2Policy, valPolicy)))); + verifyExists(true, "lifecycle", List.of(opPolicy, op2Policy, valPolicy)); + verifyExists(false, "lifecycle", List.of(unvalPolicy)); + assertFalse(PolicyControllerConstants.getFactory().get("foo").getDrools().isBrained()); + verifyActivePolicies(List.of(opPolicy, artifactPolicy, controllerPolicy, op2Policy, + controller2Policy, valPolicy)); + + // Delta: +artifact2Policy + // from deltas, all delta updates should be successfully applied, opPolicy, op2Policy and unvalPolicy + // should be reapplied. + assertTrue(fsm.update(getPdpUpdate( + List.of(opPolicy, controllerPolicy, artifactPolicy, + op2Policy, controller2Policy, valPolicy, artifact2Policy)))); + verifyExists(true, "lifecycle", List.of(opPolicy, op2Policy, valPolicy)); + verifyExists(false, "lifecycle", List.of(unvalPolicy)); + verifyExists(true, "foo", List.of(valPolicy)); + verifyExists(false, "foo", List.of(opPolicy, op2Policy, unvalPolicy)); + verifyActivePolicies(List.of(opPolicy, artifactPolicy, controllerPolicy, op2Policy, + controller2Policy, valPolicy, artifact2Policy)); + + // Delta: -controllerPolicy, +artifactPolicy, +unvalPolicy + // from deltas, all delta updates should be successful + assertTrue(fsm.update(getPdpUpdate( + List.of(opPolicy, op2Policy, controller2Policy, valPolicy, artifact2Policy, unvalPolicy)))); + assertThatIllegalArgumentException().isThrownBy(() -> PolicyControllerConstants.getFactory().get("lifecycle")); + verifyExists(true, "foo", List.of(valPolicy, unvalPolicy)); + verifyExists(false, "foo", List.of(opPolicy, op2Policy)); + // since -controllerPolicy delta => the existing artifact2Policy, opPolicy, op2Policy become disabled as no + // policy type is readily available to host them until there is a host. + verifyActivePoliciesWithDisables( + List.of(opPolicy, op2Policy, controller2Policy, valPolicy, artifact2Policy, unvalPolicy), + List.of(opPolicy.getIdentifier(), op2Policy.getIdentifier())); + + // Delta: -opPolicy, -op2Policy, -controller2Policy, -valPolicy, -artifact2Policy, -unvalPolicy + // from deltas, -opPolicy and -op2Policy undeploys will fail since there is not controller with that + // policy type supported + assertFalse(fsm.update(getPdpUpdate(Collections.emptyList()))); + assertThatIllegalArgumentException().isThrownBy(() -> PolicyControllerConstants.getFactory().get("lifecycle")); + assertThatIllegalArgumentException().isThrownBy(() -> PolicyControllerConstants.getFactory().get("foo")); + assertEquals(0, PolicyControllerConstants.getFactory().inventory().size()); + verifyActivePolicies(Collections.emptyList()); + + fsm.shutdown(); + } + + protected PdpUpdate getPdpUpdate(List<ToscaPolicy> policies) { + PdpUpdate update = new PdpUpdate(); + update.setName(NetworkUtil.getHostname()); + update.setPdpGroup("A"); + update.setPdpSubgroup("a"); + update.setPolicies(policies); + return update; + } + + protected void verifyExists(boolean exists, String controller, List<ToscaPolicy> policies) { + assertTrue(PolicyControllerConstants.getFactory().get(controller).getDrools().isBrained()); + for (ToscaPolicy policy : policies) { + assertEquals("ID: " + controller + ":" + policy.getIdentifier(), + exists, PolicyControllerConstants.getFactory().get(controller).getDrools().exists(policy)); + } + } + + protected void verifyActivePolicies(List<ToscaPolicy> testPolicies) throws CoderException { + verifyActivePoliciesWithDisables(testPolicies, Collections.emptyList()); + } + + protected void verifyActivePoliciesWithDisables(List<ToscaPolicy> testPolicies, + List<ToscaConceptIdentifier> nativeDisables) throws CoderException { + // verify that each policy is tracked in the active lists + + for (ToscaPolicy policy : testPolicies) { + assertTrue(policy.getIdentifier().toString(), fsm.getActivePolicies().contains(policy)); + if (!nativeDisables.contains(policy.getIdentifier())) { + assertTrue(policy.getIdentifier().toString(), + fsm.getPolicyTypesMap().containsKey(policy.getTypeIdentifier())); + } + } + assertEquals(testPolicies.size(), fsm.getActivePolicies().size()); + + Map<String, List<ToscaPolicy>> testPoliciesMap = fsm.groupPoliciesByPolicyType(testPolicies); + Map<String, List<ToscaPolicy>> activePolicyMap = fsm.groupPoliciesByPolicyType(fsm.getActivePolicies()); + assertEquals(new HashSet<>(activePolicyMap.keySet()), new HashSet<>(testPoliciesMap.keySet())); + for (String key: fsm.groupPoliciesByPolicyType(fsm.getActivePolicies()).keySet()) { + assertEquals(new HashSet<>(activePolicyMap.get(key)), new HashSet<>(testPoliciesMap.get(key))); + } + + // verify that a controller exists for each controller policy + assertEquals(fsm.getNativeControllerPolicies(testPoliciesMap).size(), + PolicyControllerConstants.getFactory().inventory().size()); + + // verify that a brained controller with same application coordinates exist for + // each native artifact policy + + verifyNativeArtifactPolicies(fsm.getNativeArtifactPolicies(testPoliciesMap)); + + // verify non-native policies are attached to the right set of brained controllers + + for (ToscaPolicy policy : fsm.getNonNativePolicies(testPoliciesMap)) { + verifyNonNativePolicy(policy, nativeDisables); + } + } + + 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(); + assertTrue(PolicyControllerConstants.getFactory().get(controllerName).getDrools().isBrained()); + assertEquals(artifactPolicy.getProperties().getRulesArtifact().getGroupId(), + PolicyControllerConstants.getFactory().get(controllerName).getDrools().getGroupId()); + assertEquals(artifactPolicy.getProperties().getRulesArtifact().getArtifactId(), + PolicyControllerConstants.getFactory().get(controllerName).getDrools().getArtifactId()); + assertEquals(artifactPolicy.getProperties().getRulesArtifact().getVersion(), + PolicyControllerConstants.getFactory().get(controllerName).getDrools().getVersion()); + } + } + + protected void verifyNonNativePolicy(ToscaPolicy testPolicy, + List<ToscaConceptIdentifier> nativeDisables) throws CoderException { + List<ToscaPolicy> nativeArtifactPolicies = + fsm.getNativeArtifactPolicies(fsm.groupPoliciesByPolicyType(fsm.getActivePolicies())); + + List<ToscaPolicy> nativeControllerPolicies = + fsm.getNativeControllerPolicies(fsm.groupPoliciesByPolicyType(fsm.getActivePolicies())); + + String controllerName = (String) testPolicy.getProperties().get("controllerName"); + + if (Strings.isNullOrEmpty(controllerName)) { + // this non-native policy applies to all controllers that are brained + + // verify the policy is present as a fact in all brained controllers + // and there is a controller policy for each controllerName + + for (ToscaPolicy nativePolicy : nativeArtifactPolicies) { + NativeArtifactPolicy artifactPolicy = + fsm.getDomainMaker().convertTo(nativePolicy, NativeArtifactPolicy.class); + String artifactControllerName = artifactPolicy.getProperties().getController().getName(); + + // brained controller check + assertTrue(artifactControllerName + ":" + testPolicy.getIdentifier(), + PolicyControllerConstants.getFactory().get(artifactControllerName).getDrools().isBrained()); + + // non native tosca policy as a fact in drools + if (PolicyControllerConstants.getFactory() + .get(artifactControllerName).getPolicyTypes().contains(testPolicy.getTypeIdentifier())) { + assertTrue(artifactControllerName + ":" + testPolicy.getIdentifier(), + PolicyControllerConstants.getFactory() + .get(artifactControllerName).getDrools().exists(testPolicy)); + } else { + assertFalse(artifactControllerName + ":" + testPolicy.getIdentifier(), + PolicyControllerConstants.getFactory() + .get(artifactControllerName).getDrools().exists(testPolicy)); + } + + // there should always be a controller policy for each artifact policy + assertEquals(1, + getNativeControllerPolicies(nativeControllerPolicies, artifactControllerName).size()); + } + + return; + } + + // this non-native policy applies only to the specified native controller + // which could be brained or brainless + + // there should always be a controller policy + + if (nativeDisables.contains(testPolicy.getIdentifier())) { + // skip evaluating next section + return; + } + + assertEquals(1, getNativeControllerPolicies(nativeControllerPolicies, controllerName).size()); + + // verify the policy is present as a fact if there is matching artifact policy + + List<NativeArtifactPolicy> candidateNativeArtifactPolicies = + getNativeArtifactPolicies(nativeArtifactPolicies, controllerName); + + if (candidateNativeArtifactPolicies.size() == 1) { + assertTrue(controllerName + ":" + testPolicy.getIdentifier(), + PolicyControllerConstants.getFactory().get(controllerName).getDrools().isBrained()); + assertTrue(controllerName + ":" + testPolicy.getIdentifier(), + PolicyControllerConstants.getFactory().get(controllerName).getDrools().exists(testPolicy)); + + // verify that the other brained controllers don't have this non-native policy + + for (NativeArtifactPolicy nativePolicy : + getNativeArtifactPoliciesBut(nativeArtifactPolicies, controllerName)) { + assertTrue(PolicyControllerConstants.getFactory() + .get(nativePolicy.getProperties().getController().getName()) + .getDrools().isBrained()); + assertFalse(controllerName + ":" + testPolicy.getIdentifier(), + PolicyControllerConstants.getFactory() + .get(nativePolicy.getProperties().getController().getName()) + .getDrools().exists(testPolicy)); + } + + return; + } + + // at this point the only valid possibility is that there is no native artifact policies + + assertTrue("There is more than 1 native artifact policy for " + controllerName, + candidateNativeArtifactPolicies.isEmpty()); + } + + protected List<NativeArtifactPolicy> getNativeArtifactPoliciesBut(List<ToscaPolicy> nativePolicies, + String controllerName) { + return + nativePolicies.stream() + .map(nativePolicy -> { + try { + return fsm.getDomainMaker().convertTo(nativePolicy, NativeArtifactPolicy.class); + } catch (CoderException ex) { + throw new RuntimeException(nativePolicy.getIdentifier().toString(), ex); + } + }) + .filter(nativeArtifactPolicy -> !controllerName.equals(nativeArtifactPolicy + .getProperties() + .getController() + .getName())) + .collect(Collectors.toList()); + } + + protected List<NativeArtifactPolicy> getNativeArtifactPolicies(List<ToscaPolicy> nativePolicies, + String controllerName) { + return + nativePolicies.stream() + .map(nativePolicy -> { + try { + return fsm.getDomainMaker().convertTo(nativePolicy, NativeArtifactPolicy.class); + } catch (CoderException ex) { + throw new RuntimeException(nativePolicy.getIdentifier().toString(), ex); + } + }) + .filter(nativeArtifactPolicy -> controllerName.equals(nativeArtifactPolicy + .getProperties() + .getController() + .getName())) + .collect(Collectors.toList()); + } + + protected List<ControllerPolicy> getNativeControllerPolicies(List<ToscaPolicy> nativePolicies, + String controllerName) { + return + nativePolicies.stream() + .map(controllerPolicy -> { + try { + return fsm.getDomainMaker().convertTo(controllerPolicy, ControllerPolicy.class); + } catch (CoderException ex) { + throw new RuntimeException(controllerPolicy.getIdentifier().toString(), ex); + } + }) + .filter(controllerPolicy -> controllerName.equals(controllerPolicy + .getProperties() + .getControllerName())) + .collect(Collectors.toList()); + } + + protected ToscaPolicy getPolicyFromFile(String filePath, String policyName) throws CoderException, IOException { + String policyJson = Files.readString(Paths.get(filePath)); + ToscaServiceTemplate serviceTemplate = coder.decode(policyJson, ToscaServiceTemplate.class); + return serviceTemplate.getToscaTopologyTemplate().getPolicies().get(0).get(policyName); + } + + protected ToscaPolicy getExamplesPolicy(String resourcePath, String policyName) throws CoderException { + String policyJson = ResourceUtils.getResourceAsString(resourcePath); + ToscaServiceTemplate serviceTemplate = new StandardCoder().decode(policyJson, ToscaServiceTemplate.class); + return serviceTemplate.getToscaTopologyTemplate().getPolicies().get(0).get(policyName); + } + +}
\ No newline at end of file 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 9547aa47..afa89d68 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 @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * ONAP * ================================================================================ - * Copyright (C) 2019-2020 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2019-2021 AT&T Intellectual Property. All rights reserved. * Modifications Copyright (C) 2021 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); @@ -140,7 +140,7 @@ public class LifecycleStatePassiveTest extends LifecycleStateRunningTest { } @Test - public void testUpdate() throws IOException, CoderException { + public void testUpdate() throws CoderException { controllerSupport.getController().getDrools().delete(ToscaPolicy.class); assertEquals(0, controllerSupport.getController().getDrools().factCount("junits")); @@ -224,6 +224,18 @@ public 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.setPolicies(Arrays.asList(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.setPolicies(Collections.emptyList()); @@ -240,7 +252,6 @@ public class LifecycleStatePassiveTest extends LifecycleStateRunningTest { fsm.shutdown(); } - @Test public void testStateChange() throws CoderException, IOException { /* no name */ 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 4f4b124e..18d00fc9 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 @@ -1,6 +1,6 @@ /* * ============LICENSE_START======================================================= - * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2020-2021 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ package org.onap.policy.drools.lifecycle; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; @@ -74,17 +75,36 @@ public class PolicyTypeDroolsControllerTest extends LifecycleStateRunningTest { /* non-existing controller */ assertFalse(controller.undeploy(policy)); assertFalse(controller.deploy(policy)); + assertFalse(controllerSupport.getController().getDrools().exists(policy)); + assertEquals(0, controllerSupport.getController().getDrools().factCount(ControllerSupport.SESSION_NAME)); policy.getProperties().remove("controllerName"); - assertTrue(controller.deploy(policy)); - assertTrue(controller.undeploy(policy)); - assertFalse(controller.undeploy(policy)); + + deploy(); + deploy(); // one more time + + undeploy(); + undeploy(); // one more time /* existing controller */ policy.getProperties().put("controllerName", "lifecycle"); - assertTrue(controller.deploy(policy)); + + deploy(); + deploy(); // one more time + + undeploy(); + undeploy(); // one more time + } + + protected void undeploy() { assertTrue(controller.undeploy(policy)); - assertFalse(controller.undeploy(policy)); + assertFalse(controllerSupport.getController().getDrools().exists(policy)); + assertEquals(0, controllerSupport.getController().getDrools().factCount(ControllerSupport.SESSION_NAME)); } + protected void deploy() { + assertTrue(controller.deploy(policy)); + assertTrue(controllerSupport.getController().getDrools().exists(policy)); + assertEquals(1, controllerSupport.getController().getDrools().factCount(ControllerSupport.SESSION_NAME)); + } }
\ No newline at end of file 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 3a04c313..43d3fe32 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 @@ -25,8 +25,6 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import java.io.IOException; -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Collections; @@ -441,15 +439,8 @@ public class RestLifecycleManagerTest { } private LifecycleFsm newFsmInstance() throws NoSuchFieldException, IllegalAccessException { - Field fsmField = LifecycleFeature.class.getDeclaredField("fsm"); - fsmField.setAccessible(true); - - Field modifiers = Field.class.getDeclaredField("modifiers"); - modifiers.setAccessible(true); - modifiers.setInt(fsmField, fsmField.getModifiers() & ~Modifier.FINAL); - LifecycleFsm fsm = new LifecycleFsm(); - fsmField.set(null, fsm); + ControllerSupport.setStaticField(LifecycleFeature.class, "fsm", fsm); return fsm; } diff --git a/feature-lifecycle/src/test/resources/echo.drl b/feature-lifecycle/src/test/resources/echo.drl new file mode 100644 index 00000000..ac1af3e3 --- /dev/null +++ b/feature-lifecycle/src/test/resources/echo.drl @@ -0,0 +1,35 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2021 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.drools.test; + +rule "INIT" +lock-on-active +when +then + insert(new String("I am up")); +end + +rule "ECHO" +when + $o : Object(); +then + System.out.println("ECHO: " + $o.toString()); +end diff --git a/feature-lifecycle/src/test/resources/echo.kmodule b/feature-lifecycle/src/test/resources/echo.kmodule new file mode 100644 index 00000000..98d80a90 --- /dev/null +++ b/feature-lifecycle/src/test/resources/echo.kmodule @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + ONAP + ================================================================================ + Copyright (C) 2021 AT&T Intellectual Property. All rights reserved. + ================================================================================ + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ============LICENSE_END========================================================= + --> + +<kmodule xmlns="http://jboss.org/kie/6.0.0/kmodule"> + <kbase name="onap.policies.typeA" default="false" equalsBehavior="equality"/> + <kbase name="onap.policies.type1.type2" includes="onap.policies.typeA"> + <ksession name="echo"/> + </kbase> +</kmodule>
\ No newline at end of file diff --git a/feature-lifecycle/src/test/resources/echo.pom b/feature-lifecycle/src/test/resources/echo.pom new file mode 100644 index 00000000..e66e783d --- /dev/null +++ b/feature-lifecycle/src/test/resources/echo.pom @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + ONAP + ================================================================================ + Copyright (C) 2021 AT&T Intellectual Property. All rights reserved. + ================================================================================ + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ============LICENSE_END========================================================= + --> + +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + + <modelVersion>4.0.0</modelVersion> + + <groupId>org.onap.policy.drools.test</groupId> + <artifactId>echo</artifactId> + <!-- the version below is irrelevant --> + <version>1.0.0</version> +</project> diff --git a/feature-lifecycle/src/test/resources/tosca-policy-native-artifact-foo.json b/feature-lifecycle/src/test/resources/tosca-policy-native-artifact-foo.json index afdc0a83..eeb3e5a4 100644 --- a/feature-lifecycle/src/test/resources/tosca-policy-native-artifact-foo.json +++ b/feature-lifecycle/src/test/resources/tosca-policy-native-artifact-foo.json @@ -14,7 +14,7 @@ "properties": { "rulesArtifact": { "groupId": "org.onap.policy.drools.test", - "artifactId": "lifecycle", + "artifactId": "echo", "version": "1.0.0" }, "controller": { |