diff options
author | jhh <jorge.hernandez-herrero@att.com> | 2021-01-15 16:51:47 -0600 |
---|---|---|
committer | jhh <jorge.hernandez-herrero@att.com> | 2021-01-27 00:39:32 -0600 |
commit | 77d088a607c33c236bc41c58d9567e10299357a5 (patch) | |
tree | c35c7d92a58f49cc6d069910a4eab20a6bd08993 /feature-lifecycle/src/test | |
parent | 6d94c4ec33520776971c781c6ea6e80e6d0070b5 (diff) |
sync policies when native artifact policies added
interoperability between native and non-native policies
present several difficulties. The code submitted
operates in deltas where deploy and undeploy operations
are performed on the deltas of the updates.
In order to support interoperability, policies not
part of a delta update may need to be reapplied.
For example, in the case when the delta is just
a new native controller artifact, we should go
through the set of already deployed policies and
reapply non-native policies as long as the policy types that
the native artifact policy supports.
Issue-ID: POLICY-2762
Signed-off-by: jhh <jorge.hernandez-herrero@att.com>
Change-Id: Ieb8e5e17862e9d607433a1d4e86a026725d73498
Signed-off-by: jhh <jorge.hernandez-herrero@att.com>
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": { |