diff options
22 files changed, 676 insertions, 177 deletions
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 5e1ddaea..9f292946 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 @@ -23,6 +23,7 @@ package org.onap.policy.drools.lifecycle; import org.onap.policy.drools.features.DroolsControllerFeatureAPI; import org.onap.policy.drools.features.PolicyControllerFeatureAPI; import org.onap.policy.drools.features.PolicyEngineFeatureAPI; +import org.onap.policy.drools.system.PolicyController; import org.onap.policy.drools.system.PolicyEngine; /** @@ -40,30 +41,51 @@ public class LifecycleFeature return 10; } - /** - * The 'afterStart' hook on the Policy Engine tell us when the engine is functional. - */ @Override public boolean afterStart(PolicyEngine engine) { fsm.start(); return false; } - /** - * The 'afterStop' hook on the Policy Engine tell us when the engine is stopping. - */ @Override - public boolean afterStop(PolicyEngine engine) { + public boolean afterStart(PolicyController controller) { + fsm.start(controller); + return false; + } + + @Override + public boolean beforeStop(PolicyEngine engine) { fsm.stop(); return false; } - /** - * The 'beforeShutdown' hook on the Policy Engine tell us when the engine is going away. - */ + @Override + public boolean beforeStop(PolicyController controller) { + fsm.stop(controller); + return false; + } + @Override public boolean beforeShutdown(PolicyEngine engine) { fsm.shutdown(); return false; } + + @Override + public boolean beforeHalt(PolicyController controller) { + fsm.stop(controller); + return false; + } + + @Override + public boolean beforeLock(PolicyController controller) { + fsm.stop(controller); + return false; + } + + @Override + public boolean afterUnlock(PolicyController controller) { + fsm.start(controller); + return false; + } } diff --git a/feature-lifecycle/src/main/java/org/onap/policy/drools/lifecycle/LifecycleFsm.java b/feature-lifecycle/src/main/java/org/onap/policy/drools/lifecycle/LifecycleFsm.java index 74375688..b99953ed 100644 --- a/feature-lifecycle/src/main/java/org/onap/policy/drools/lifecycle/LifecycleFsm.java +++ b/feature-lifecycle/src/main/java/org/onap/policy/drools/lifecycle/LifecycleFsm.java @@ -21,7 +21,9 @@ package org.onap.policy.drools.lifecycle; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.Properties; import java.util.concurrent.ScheduledFuture; @@ -44,14 +46,17 @@ import org.onap.policy.common.utils.coder.StandardCoderObject; import org.onap.policy.common.utils.network.NetworkUtil; import org.onap.policy.drools.controller.DroolsController; import org.onap.policy.drools.persistence.SystemPersistence; +import org.onap.policy.drools.system.PolicyController; import org.onap.policy.models.pdp.concepts.PdpResponseDetails; import org.onap.policy.models.pdp.concepts.PdpStateChange; import org.onap.policy.models.pdp.concepts.PdpStatus; import org.onap.policy.models.pdp.concepts.PdpUpdate; -import org.onap.policy.models.pdp.concepts.ToscaPolicyTypeIdentifier; import org.onap.policy.models.pdp.enums.PdpHealthStatus; import org.onap.policy.models.pdp.enums.PdpMessageType; import org.onap.policy.models.pdp.enums.PdpState; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyIdentifier; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyTypeIdentifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -103,6 +108,10 @@ public class LifecycleFsm implements Startable { @Getter protected String subgroup; + protected final Map<ToscaPolicyTypeIdentifier, PolicyController> policyTypesMap = new HashMap<>(); + + protected final Map<ToscaPolicyIdentifier, ToscaPolicy> policiesMap = new HashMap<>(); + /** * Constructor. */ @@ -130,19 +139,39 @@ public class LifecycleFsm implements Startable { @Override public synchronized boolean start() { - logger.info("lifecycle event: start"); + logger.info("lifecycle event: start engine"); return state.start(); } + /** + * Start a controller event. + */ + public synchronized void start(@NonNull PolicyController controller) { + logger.info("lifecycle event: start controller: {}" + controller.getName()); + for (ToscaPolicyTypeIdentifier id : controller.getPolicyTypes()) { + policyTypesMap.put(id, controller); + } + } + @Override public synchronized boolean stop() { - logger.info("lifecycle event: stop"); + logger.info("lifecycle event: stop engine"); return state.stop(); } + /** + * Stop a controller event. + */ + public synchronized void stop(@NonNull PolicyController controller) { + logger.info("lifecycle event: stop controller: {}" + controller.getName()); + for (ToscaPolicyTypeIdentifier id : controller.getPolicyTypes()) { + policyTypesMap.remove(id); + } + } + @Override public synchronized void shutdown() { - logger.info("lifecycle event: shutdown"); + logger.info("lifecycle event: shutdown engine"); state.shutdown(); } @@ -234,6 +263,26 @@ public class LifecycleFsm implements Startable { return stopTimers() && startTimers(); } + protected PolicyController getController(ToscaPolicyTypeIdentifier policyType) { + return policyTypesMap.get(policyType); + } + + protected List<ToscaPolicy> getDeployablePoliciesAction(@NonNull List<ToscaPolicy> policies) { + List<ToscaPolicy> deployPolicies = new ArrayList<>(policies); + deployPolicies.removeAll(policiesMap.values()); + return deployPolicies; + } + + protected List<ToscaPolicy> getUndeployablePoliciesAction(@NonNull List<ToscaPolicy> policies) { + List<ToscaPolicy> undeployPolicies = new ArrayList<>(policiesMap.values()); + undeployPolicies.removeAll(policies); + return undeployPolicies; + } + + protected void deployedPolicyAction(@NonNull ToscaPolicy policy) { + policiesMap.put(policy.getIdentifier(), policy); + } + /* ** Action Helpers ** */ private boolean startIo() { diff --git a/feature-lifecycle/src/main/java/org/onap/policy/drools/lifecycle/LifecycleStateActive.java b/feature-lifecycle/src/main/java/org/onap/policy/drools/lifecycle/LifecycleStateActive.java index 9ec68653..d481b8bd 100644 --- a/feature-lifecycle/src/main/java/org/onap/policy/drools/lifecycle/LifecycleStateActive.java +++ b/feature-lifecycle/src/main/java/org/onap/policy/drools/lifecycle/LifecycleStateActive.java @@ -20,16 +20,22 @@ package org.onap.policy.drools.lifecycle; +import lombok.NonNull; import lombok.ToString; +import org.onap.policy.drools.system.PolicyController; import org.onap.policy.models.pdp.concepts.PdpStateChange; import org.onap.policy.models.pdp.enums.PdpResponseStatus; import org.onap.policy.models.pdp.enums.PdpState; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Lifecycle Active State. */ @ToString public class LifecycleStateActive extends LifecycleStateRunning { + private static final Logger logger = LoggerFactory.getLogger(LifecycleStatePassive.class); protected LifecycleStateActive(LifecycleFsm manager) { super(manager); @@ -51,4 +57,26 @@ public class LifecycleStateActive extends LifecycleStateRunning { return fsm.statusAction(response(change.getRequestId(), PdpResponseStatus.SUCCESS, null)); } + @Override + protected boolean deployPolicy(@NonNull PolicyController controller, @NonNull ToscaPolicy policy) { + logger.info("{}: deploy {} into {}", this, policy.getIdentifier(), controller.getName()); + + // TODO: This is the latest version - retract policy with same id but different version + + if (!controller.offer(policy)) { + return false; + } + + fsm.deployedPolicyAction(policy); + return true; + } + + @Override + protected boolean undeployPolicy(@NonNull PolicyController controller, @NonNull ToscaPolicy policy) { + logger.info("{}: undeploy {} from {}", this, policy.getIdentifier(), controller.getName()); + + // TODO: retract policy. + + return true; + } } diff --git a/feature-lifecycle/src/main/java/org/onap/policy/drools/lifecycle/LifecycleStatePassive.java b/feature-lifecycle/src/main/java/org/onap/policy/drools/lifecycle/LifecycleStatePassive.java index 0720ec98..e9f4b9bf 100644 --- a/feature-lifecycle/src/main/java/org/onap/policy/drools/lifecycle/LifecycleStatePassive.java +++ b/feature-lifecycle/src/main/java/org/onap/policy/drools/lifecycle/LifecycleStatePassive.java @@ -20,16 +20,22 @@ package org.onap.policy.drools.lifecycle; +import lombok.NonNull; import lombok.ToString; +import org.onap.policy.drools.system.PolicyController; import org.onap.policy.models.pdp.concepts.PdpStateChange; import org.onap.policy.models.pdp.enums.PdpResponseStatus; import org.onap.policy.models.pdp.enums.PdpState; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Lifecycle Passive State. */ @ToString public class LifecycleStatePassive extends LifecycleStateRunning { + private static final Logger logger = LoggerFactory.getLogger(LifecycleStatePassive.class); protected LifecycleStatePassive(LifecycleFsm manager) { super(manager); @@ -41,13 +47,25 @@ public class LifecycleStatePassive extends LifecycleStateRunning { } @Override - protected boolean stateChangeToActive(PdpStateChange change) { + protected boolean stateChangeToActive(@NonNull PdpStateChange change) { fsm.transitionToAction(new LifecycleStateActive(fsm)); return fsm.statusAction(response(change.getRequestId(), PdpResponseStatus.SUCCESS,null)); } @Override - protected boolean stateChangeToPassive(PdpStateChange change) { + protected boolean stateChangeToPassive(@NonNull PdpStateChange change) { return fsm.statusAction(response(change.getRequestId(), PdpResponseStatus.SUCCESS,null)); } + + @Override + protected boolean deployPolicy(@NonNull PolicyController controller, @NonNull ToscaPolicy policy) { + logger.info("{}: deploy {} from {}", this, policy.getIdentifier(), controller.getName()); + return true; + } + + @Override + protected boolean undeployPolicy(@NonNull PolicyController controller, @NonNull ToscaPolicy policy) { + logger.info("{}: undeploy {} from {}", this, policy.getIdentifier(), controller.getName()); + return true; + } } 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 916d155e..405dbeba 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 @@ -21,13 +21,16 @@ package org.onap.policy.drools.lifecycle; import java.util.List; +import java.util.function.BiFunction; import lombok.NonNull; +import org.onap.policy.drools.system.PolicyController; import org.onap.policy.models.pdp.concepts.PdpResponseDetails; import org.onap.policy.models.pdp.concepts.PdpStateChange; import org.onap.policy.models.pdp.concepts.PdpUpdate; import org.onap.policy.models.pdp.enums.PdpResponseStatus; import org.onap.policy.models.pdp.enums.PdpState; import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyTypeIdentifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -38,9 +41,13 @@ public abstract class LifecycleStateRunning extends LifecycleStateDefault { private static final Logger logger = LoggerFactory.getLogger(LifecycleState.class); - protected abstract boolean stateChangeToPassive(PdpStateChange change); + protected abstract boolean stateChangeToPassive(@NonNull PdpStateChange change); - protected abstract boolean stateChangeToActive(PdpStateChange change); + protected abstract boolean stateChangeToActive(@NonNull PdpStateChange change); + + protected abstract boolean deployPolicy(@NonNull PolicyController controller, @NonNull ToscaPolicy policy); + + protected abstract boolean undeployPolicy(@NonNull PolicyController controller, @NonNull ToscaPolicy policy); protected LifecycleStateRunning(LifecycleFsm manager) { super(manager); @@ -104,7 +111,8 @@ public abstract class LifecycleStateRunning extends LifecycleStateDefault { @Override public boolean update(@NonNull PdpUpdate update) { synchronized (fsm) { - if (!fsm.setStatusIntervalAction(update.getPdpHeartbeatIntervalMs() / 1000)) { + if (update.getPdpHeartbeatIntervalMs() != null + && !fsm.setStatusIntervalAction(update.getPdpHeartbeatIntervalMs() / 1000)) { fsm.statusAction(response(update.getRequestId(), PdpResponseStatus.FAIL, "invalid interval: " + update.getPdpHeartbeatIntervalMs() + " seconds")); return false; @@ -122,8 +130,38 @@ public abstract class LifecycleStateRunning extends LifecycleStateDefault { } protected boolean updatePolicies(List<ToscaPolicy> policies) { - // TODO - return true; + if (policies == null) { + return true; + } + + boolean success = deployPolicies(policies); + return undeployPolicies(policies) && success; + } + + protected boolean deployPolicies(List<ToscaPolicy> policies) { + return syncPolicies(fsm.getDeployablePoliciesAction(policies), this::deployPolicy); + } + + protected boolean undeployPolicies(List<ToscaPolicy> policies) { + return syncPolicies(fsm.getUndeployablePoliciesAction(policies), this::undeployPolicy); + } + + protected boolean syncPolicies(List<ToscaPolicy> policies, + BiFunction<PolicyController, ToscaPolicy, Boolean> sync) { + boolean success = true; + for (ToscaPolicy policy : policies) { + ToscaPolicyTypeIdentifier policyType = policy.getTypeIdentifier(); + PolicyController controller = fsm.getController(policyType); + if (controller == null) { + logger.warn("no controller found for {}", policyType); + success = false; + continue; + } + + success = sync.apply(controller, policy) && success; + } + + return success; } private void invalidStateChange(PdpStateChange change) { 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 new file mode 100644 index 00000000..1beee552 --- /dev/null +++ b/feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/ControllerSupport.java @@ -0,0 +1,112 @@ +/* + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2019 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.lifecycle; + +import java.io.IOException; +import java.nio.file.Paths; +import java.util.List; +import java.util.Properties; +import java.util.stream.Collectors; +import lombok.Getter; +import lombok.NonNull; +import org.kie.api.builder.ReleaseId; +import org.onap.policy.drools.properties.DroolsProperties; +import org.onap.policy.drools.system.PolicyController; +import org.onap.policy.drools.util.KieUtils; + +/** + * Controller Test Support. + */ +public class ControllerSupport { + + 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"; + protected static final String JUNIT_KJAR_DRL_PATH = + "src/main/resources/kbLifecycle/org/onap/policy/drools/test/lifecycle.drl"; + + protected static final String POLICY_TYPE = "onap.policies.controlloop.Operational"; + protected static final String POLICY_TYPE_VERSION = "1.0.0"; + + protected static final String SESSION_NAME = "junits"; + + @Getter + private final String name; + + public ControllerSupport(@NonNull String name) { + this.name = name; + } + + /** + * Create controller. + */ + public PolicyController createController() throws IOException { + ReleaseId coordinates = + KieUtils.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()); + + + Properties controllerProps = new Properties(); + controllerProps.put(DroolsProperties.PROPERTY_CONTROLLER_NAME, name); + controllerProps.put(DroolsProperties.PROPERTY_CONTROLLER_POLICY_TYPES, getPolicyType()); + controllerProps.put(DroolsProperties.RULES_GROUPID, coordinates.getGroupId()); + controllerProps.put(DroolsProperties.RULES_ARTIFACTID, coordinates.getArtifactId()); + controllerProps.put(DroolsProperties.RULES_VERSION, coordinates.getVersion()); + + return PolicyController.factory.build(name, controllerProps); + } + + /** + * Destroy the echo controller. + */ + public void destroyController() { + PolicyController.factory.destroy(name); + } + + /** + * Get controller. + */ + public PolicyController getController() { + return PolicyController.factory.get(name); + } + + /** + * Get Policy Type. + */ + public static String getPolicyType() { + return POLICY_TYPE + ":" + POLICY_TYPE_VERSION; + } + + /** + * Get facts. + */ + public <T> List<T> getFacts(Class<T> clazz) { + return PolicyController.factory.get(name) + .getDrools() + .facts(SESSION_NAME, clazz.getCanonicalName(), false) + .stream() + .filter(clazz::isInstance) + .map(clazz::cast) + .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 c4d47d83..32006425 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 @@ -27,43 +27,30 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertTrue; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.TimeUnit; -import org.junit.AfterClass; import org.junit.Before; -import org.junit.BeforeClass; import org.junit.Test; 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.drools.persistence.SystemPersistence; -import org.onap.policy.drools.utils.logging.LoggerUtil; import org.onap.policy.models.pdp.concepts.PdpStateChange; import org.onap.policy.models.pdp.concepts.PdpStatus; import org.onap.policy.models.pdp.concepts.PdpUpdate; import org.onap.policy.models.pdp.enums.PdpMessageType; import org.onap.policy.models.pdp.enums.PdpState; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy; /** * Lifecycle State Active Test. */ -public class LifecycleStateActiveTest { - - private LifecycleFsm fsm; - - @BeforeClass - public static void setUp() { - SystemPersistence.manager.setConfigurationDir("src/test/resources"); - LoggerUtil.setLevel("org.onap.policy.common.endpoints", "WARN"); - } - - @AfterClass - public static void tearDown() { - SystemPersistence.manager.setConfigurationDir(null); - } +public class LifecycleStateActiveTest extends LifecycleStateRunningTest { /** * Start tests in the Active state. @@ -199,7 +186,7 @@ public class LifecycleStateActiveTest { } @Test - public void update() { + public void update() throws IOException, CoderException { PdpUpdate update = new PdpUpdate(); update.setName(NetworkUtil.getHostname()); update.setPdpGroup("Z"); @@ -210,6 +197,9 @@ public class LifecycleStateActiveTest { long interval = 2 * originalInterval; update.setPdpHeartbeatIntervalMs(interval * 1000L); + controllerSupport.getController().start(); + fsm.start(controllerSupport.getController()); + assertTrue(fsm.update(update)); assertEquals(PdpState.ACTIVE, fsm.state()); @@ -217,6 +207,20 @@ public class LifecycleStateActiveTest { assertEquals("Z", fsm.getGroup()); assertEquals("z", fsm.getSubgroup()); + String rawPolicy = + new String(Files.readAllBytes(Paths.get("src/test/resources/tosca-policy.json"))); + ToscaPolicy toscaPolicy = new StandardCoder().decode(rawPolicy, ToscaPolicy.class); + update.setPolicies(Arrays.asList(toscaPolicy)); + + assertTrue(fsm.update(update)); + assertEquals(1, fsm.policyTypesMap.size()); + + List<ToscaPolicy> factPolicies = controllerSupport.getFacts(ToscaPolicy.class); + assertEquals(1, factPolicies.size()); + assertEquals(toscaPolicy, factPolicies.get(0)); + assertEquals(1, fsm.policiesMap.size()); + + controllerSupport.getController().stop(); fsm.shutdown(); } } 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 376eb3a7..100bcef5 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 @@ -27,45 +27,35 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.Arrays; import java.util.Collections; import java.util.concurrent.Callable; import java.util.concurrent.TimeUnit; import org.awaitility.core.ConditionTimeoutException; -import org.junit.AfterClass; import org.junit.Before; -import org.junit.BeforeClass; import org.junit.Test; 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.drools.persistence.SystemPersistence; -import org.onap.policy.drools.utils.logging.LoggerUtil; import org.onap.policy.models.pdp.concepts.PdpStateChange; import org.onap.policy.models.pdp.concepts.PdpStatus; import org.onap.policy.models.pdp.concepts.PdpUpdate; import org.onap.policy.models.pdp.enums.PdpHealthStatus; import org.onap.policy.models.pdp.enums.PdpMessageType; import org.onap.policy.models.pdp.enums.PdpState; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyTypeIdentifier; /** * Lifecycle State Passive Tests. */ -public class LifecycleStatePassiveTest { - - private LifecycleFsm fsm; - - @BeforeClass - public static void setUp() { - SystemPersistence.manager.setConfigurationDir("src/test/resources"); - LoggerUtil.setLevel("org.onap.policy.common.endpoints", "WARN"); - } - - @AfterClass - public static void tearDown() { - SystemPersistence.manager.setConfigurationDir(null); - } +public class LifecycleStatePassiveTest extends LifecycleStateRunningTest { /** * Start tests in the Passive state. @@ -87,6 +77,21 @@ public class LifecycleStatePassiveTest { } @Test + public void controller() { + fsm.start(controllerSupport.getController()); + assertSame(controllerSupport.getController(), + fsm.getController(new ToscaPolicyTypeIdentifier(ControllerSupport.POLICY_TYPE, + ControllerSupport.POLICY_TYPE_VERSION))); + + fsm.stop(controllerSupport.getController()); + assertNull(fsm.getController( + new ToscaPolicyTypeIdentifier(ControllerSupport.POLICY_TYPE, + ControllerSupport.POLICY_TYPE_VERSION))); + + fsm.shutdown(); + } + + @Test public void start() { assertEquals(0, fsm.client.getSink().getRecentEvents().length); assertFalse(fsm.start()); @@ -163,7 +168,7 @@ public class LifecycleStatePassiveTest { } @Test - public void update() { + public void update() throws IOException, CoderException { PdpUpdate update = new PdpUpdate(); update.setName(NetworkUtil.getHostname()); update.setPdpGroup("Z"); @@ -181,6 +186,30 @@ public class LifecycleStatePassiveTest { assertEquals("z", fsm.getSubgroup()); assertBasicPassive(); + String rawPolicy = + new String(Files.readAllBytes(Paths.get("src/test/resources/tosca-policy.json"))); + ToscaPolicy toscaPolicy = new StandardCoder().decode(rawPolicy, ToscaPolicy.class); + update.setPolicies(Arrays.asList(toscaPolicy)); + + assertFalse(fsm.update(update)); + + assertEquals(PdpState.PASSIVE, fsm.state()); + assertEquals(interval, fsm.getStatusTimerSeconds()); + assertEquals("Z", fsm.getGroup()); + assertEquals("z", fsm.getSubgroup()); + assertBasicPassive(); + + assertTrue(fsm.policyTypesMap.isEmpty()); + assertTrue(fsm.policiesMap.isEmpty()); + + fsm.start(controllerSupport.getController()); + assertEquals(1, fsm.policyTypesMap.size()); + assertTrue(fsm.policiesMap.isEmpty()); + + assertTrue(fsm.update(update)); + assertEquals(1, fsm.policyTypesMap.size()); + assertTrue(fsm.policiesMap.isEmpty()); + fsm.shutdown(); } diff --git a/feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/LifecycleStateRunningTest.java b/feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/LifecycleStateRunningTest.java new file mode 100644 index 00000000..d7bb6d75 --- /dev/null +++ b/feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/LifecycleStateRunningTest.java @@ -0,0 +1,63 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2019 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 java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.onap.policy.drools.persistence.SystemPersistence; +import org.onap.policy.drools.utils.logging.LoggerUtil; + +public abstract class LifecycleStateRunningTest { + + private static final String CONTROLLER_NAME = "lifecycle"; + protected static ControllerSupport controllerSupport = new ControllerSupport(CONTROLLER_NAME); + protected LifecycleFsm fsm; + + /** + * 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", "WARN"); + SystemPersistence.manager.setConfigurationDir("src/test/resources"); + controllerSupport.createController(); + } + + /** + * Tear Down. + */ + @AfterClass + public static void tearDown() { + controllerSupport.destroyController(); + try { + Files.deleteIfExists(Paths.get(SystemPersistence.manager.getConfigurationPath().toString(), + CONTROLLER_NAME + "-controller.properties.bak")); + } catch (IOException e) { + ; + } + SystemPersistence.manager.setConfigurationDir(null); + } +} diff --git a/feature-lifecycle/src/test/resources/echo.drl b/feature-lifecycle/src/test/resources/lifecycle.drl index c044f2cb..597661cf 100644 --- a/feature-lifecycle/src/test/resources/echo.drl +++ b/feature-lifecycle/src/test/resources/lifecycle.drl @@ -20,17 +20,20 @@ package org.onap.policy.drools.test; -rule "INIT" -lock-on-active -when -then - insert("hello, I am up!"); -end +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy; -rule "ECHO" +rule "INSERT.TOSCA.POLICY" when - $o : Object(); + $policy : ToscaPolicy(); then - System.out.println("ECHO: " + $o); - retract($o); + System.out.println(""); + System.out.println(""); + System.out.println("************************************************************************"); + System.out.println(drools.getRule().getName() + ":"); + System.out.println(""); + System.out.println("Tosca Policy Type: " + $policy.getType() + " " + $policy.getTypeVersion()); + System.out.println("Tosca Policy: " + $policy.getName() + " " + $policy.getVersion()); + System.out.println("************************************************************************"); + System.out.println(""); + System.out.println(""); end diff --git a/feature-lifecycle/src/test/resources/echo.kmodule b/feature-lifecycle/src/test/resources/lifecycle.kmodule index 1019bd3d..8bf1ed5a 100644 --- a/feature-lifecycle/src/test/resources/echo.kmodule +++ b/feature-lifecycle/src/test/resources/lifecycle.kmodule @@ -20,7 +20,7 @@ --> <kmodule xmlns="http://jboss.org/kie/6.0.0/kmodule"> - <kbase name="controller-logs"> - <ksession name="test" /> + <kbase name="onap.policies.type1.type2"> + <ksession name="junits" /> </kbase> </kmodule> diff --git a/feature-lifecycle/src/test/resources/echo.pom b/feature-lifecycle/src/test/resources/lifecycle.pom index 7e654793..87eafc10 100644 --- a/feature-lifecycle/src/test/resources/echo.pom +++ b/feature-lifecycle/src/test/resources/lifecycle.pom @@ -23,7 +23,7 @@ <modelVersion>4.0.0</modelVersion> <groupId>org.onap.policy.drools.test</groupId> - <artifactId>echo</artifactId> + <artifactId>lifecycle</artifactId> <version>1.4.0-SNAPSHOT</version> </project> diff --git a/feature-lifecycle/src/test/resources/tosca-policy.json b/feature-lifecycle/src/test/resources/tosca-policy.json new file mode 100644 index 00000000..5258ca1c --- /dev/null +++ b/feature-lifecycle/src/test/resources/tosca-policy.json @@ -0,0 +1,9 @@ +{ + "type": "onap.policies.controlloop.Operational", + "typeVersion": "1.0.0", + "properties": { + "content": "controlLoop%3A%0A%20%20version%3A%202.0.0%0A%20%20controlLoopName%3A%20ControlLoop-vCPE-48f0c2c3-a172-4192-9ae3-052274181b6e%0A%20%20trigger_policy%3A%20unique-policy-id-1-restart%0A%20%20timeout%3A%203600%0A%20%20abatement%3A%20true%0A%20%0Apolicies%3A%0A%20%20-%20id%3A%20unique-policy-id-1-restart%0A%20%20%20%20name%3A%20Restart%20the%20VM%0A%20%20%20%20description%3A%0A%20%20%20%20actor%3A%20APPC%0A%20%20%20%20recipe%3A%20Restart%0A%20%20%20%20target%3A%0A%20%20%20%20%20%20type%3A%20VM%0A%20%20%20%20retry%3A%203%0A%20%20%20%20timeout%3A%201200%0A%20%20%20%20success%3A%20final_success%0A%20%20%20%20failure%3A%20final_failure%0A%20%20%20%20failure_timeout%3A%20final_failure_timeout%0A%20%20%20%20failure_retries%3A%20final_failure_retries%0A%20%20%20%20failure_exception%3A%20final_failure_exception%0A%20%20%20%20failure_guard%3A%20final_failure_guard" + }, + "name": "operational.restart", + "version": "1.0.0" +} diff --git a/policy-core/src/main/java/org/onap/policy/drools/properties/DroolsProperties.java b/policy-core/src/main/java/org/onap/policy/drools/properties/DroolsProperties.java index 468f0e3a..0b7a6503 100644 --- a/policy-core/src/main/java/org/onap/policy/drools/properties/DroolsProperties.java +++ b/policy-core/src/main/java/org/onap/policy/drools/properties/DroolsProperties.java @@ -26,6 +26,9 @@ public interface DroolsProperties { String PROPERTY_CONTROLLER_NAME = "controller.name"; + String DEFAULT_CONTROLLER_POLICY_TYPE_VERSION = "1.0.0"; + String PROPERTY_CONTROLLER_POLICY_TYPES = "controller.policy.types"; + /* Drools Properties */ String RULES_GROUPID = "rules.groupId"; diff --git a/policy-management/src/main/java/org/onap/policy/drools/controller/DroolsController.java b/policy-management/src/main/java/org/onap/policy/drools/controller/DroolsController.java index 1e7b8c79..344725ff 100644 --- a/policy-management/src/main/java/org/onap/policy/drools/controller/DroolsController.java +++ b/policy-management/src/main/java/org/onap/policy/drools/controller/DroolsController.java @@ -37,74 +37,83 @@ public interface DroolsController extends Startable, Lockable { /** * No Group ID identifier. */ - public static final String NO_GROUP_ID = "NO-GROUP-ID"; + String NO_GROUP_ID = "NO-GROUP-ID"; /** * No Artifact ID identifier. */ - public static final String NO_ARTIFACT_ID = "NO-ARTIFACT-ID"; + String NO_ARTIFACT_ID = "NO-ARTIFACT-ID"; /** * No version identifier. */ - public static final String NO_VERSION = "NO-VERSION"; + String NO_VERSION = "NO-VERSION"; /** * Factory to track and manage drools controllers. */ - public static final DroolsControllerFactory factory = new IndexedDroolsControllerFactory(); + DroolsControllerFactory factory = new IndexedDroolsControllerFactory(); /** * get group id. * * @return group id */ - public String getGroupId(); + String getGroupId(); /** * get artifact id. * * @return artifact id */ - public String getArtifactId(); + String getArtifactId(); /** * get version. * * @return version */ - public String getVersion(); + String getVersion(); /** * return the policy session names. * * @return policy session */ - public List<String> getSessionNames(); + List<String> getSessionNames(); /** * return the policy full session names. * * @return policy session */ - public List<String> getCanonicalSessionNames(); + List<String> getCanonicalSessionNames(); /** * get base domains. * * @return list of base domains. */ - public List<String> getBaseDomainNames(); + List<String> getBaseDomainNames(); /** - * offers an event to this controller for processing. + * offers a raw event to this controller for processing. * * @param topic topic associated with the event * @param event the event * * @return true if the operation was successful */ - public boolean offer(String topic, String event); + boolean offer(String topic, String event); + + /** + * offers a T event to this controller for processing. + * + * @param event the event + * + * @return true if the operation was successful + */ + <T> boolean offer(T event); /** * delivers "event" to "sink". @@ -118,28 +127,28 @@ public interface DroolsController extends Startable, Lockable { * @throws UnsupportedOperationException when the engine cannot deliver due to the functionality * missing (ie. communication infrastructure not supported. */ - public boolean deliver(TopicSink sink, Object event); + boolean deliver(TopicSink sink, Object event); /** * Get recent source events. * * @return the most recent received events. */ - public Object[] getRecentSourceEvents(); + Object[] getRecentSourceEvents(); /** * Get recent sink events. * * @return the most recent delivered events */ - public String[] getRecentSinkEvents(); + String[] getRecentSinkEvents(); /** * Get container. * * @return the underlying policy container */ - public PolicyContainer getContainer(); + PolicyContainer getContainer(); /** * Does it owns the coder. @@ -148,7 +157,7 @@ public interface DroolsController extends Startable, Lockable { * @param modelHash the hash for the model * @return true it owns it */ - public boolean ownsCoder(Class<? extends Object> coderClass, int modelHash); + boolean ownsCoder(Class<? extends Object> coderClass, int modelHash); /** * fetches a class from the model. @@ -156,12 +165,12 @@ public interface DroolsController extends Startable, Lockable { * @param className the class to fetch * @return the actual class object, or null if not found */ - public Class<?> fetchModelClass(String className); + Class<?> fetchModelClass(String className); /** * is this controller Smart. */ - public boolean isBrained(); + boolean isBrained(); /** * update the new version of the maven jar rules file. @@ -175,9 +184,9 @@ public interface DroolsController extends Startable, Lockable { * @throws Exception from within drools libraries * @throws LinkageError from within drools libraries */ - public void updateToVersion(String newGroupId, String newArtifactId, String newVersion, - List<TopicCoderFilterConfiguration> decoderConfigurations, - List<TopicCoderFilterConfiguration> encoderConfigurations) throws LinkageError; + void updateToVersion(String newGroupId, String newArtifactId, String newVersion, + List<TopicCoderFilterConfiguration> decoderConfigurations, + List<TopicCoderFilterConfiguration> encoderConfigurations) throws LinkageError; /** * gets the classnames of facts as well as the current count. @@ -185,7 +194,7 @@ public interface DroolsController extends Startable, Lockable { * @param sessionName the session name * @return map of class to count */ - public Map<String, Integer> factClassNames(String sessionName); + Map<String, Integer> factClassNames(String sessionName); /** * gets the count of facts for a given session. @@ -193,7 +202,7 @@ public interface DroolsController extends Startable, Lockable { * @param sessionName the session name * @return the fact count */ - public long factCount(String sessionName); + long factCount(String sessionName); /** * gets all the facts of a given class for a given session. @@ -203,7 +212,7 @@ public interface DroolsController extends Startable, Lockable { * @param delete retract from drools the results of the query? * @return the list of facts returned by the query */ - public List<Object> facts(String sessionName, String className, boolean delete); + List<Object> facts(String sessionName, String className, boolean delete); /** * gets the facts associated with a query for a give session for a given queried entity. @@ -215,12 +224,12 @@ public interface DroolsController extends Startable, Lockable { * @param queryParams query parameters * @return list of facts returned by the query */ - public List<Object> factQuery(String sessionName, String queryName, String queriedEntity, boolean delete, - Object... queryParams); + List<Object> factQuery(String sessionName, String queryName, String queriedEntity, boolean delete, + Object... queryParams); /** * halts and permanently releases all resources. * */ - public void halt(); + void halt(); } diff --git a/policy-management/src/main/java/org/onap/policy/drools/controller/internal/MavenDroolsController.java b/policy-management/src/main/java/org/onap/policy/drools/controller/internal/MavenDroolsController.java index eb401eba..95b053fb 100644 --- a/policy-management/src/main/java/org/onap/policy/drools/controller/internal/MavenDroolsController.java +++ b/policy-management/src/main/java/org/onap/policy/drools/controller/internal/MavenDroolsController.java @@ -480,19 +480,9 @@ public class MavenDroolsController implements DroolsController { @Override public boolean offer(String topic, String event) { - logger.debug("{}: OFFER: {} <- {}", this, topic, event); + logger.debug("{}: OFFER raw event from {}", this, topic); - if (this.locked) { - return true; - } - if (!this.alive) { - return true; - } - - // 0. Check if the policy container has any sessions - - if (this.policyContainer.getPolicySessions().isEmpty()) { - // no sessions + if (this.locked || !this.alive || this.policyContainer.getPolicySessions().isEmpty()) { return true; } @@ -525,48 +515,55 @@ public class MavenDroolsController implements DroolsController { return true; } + return offer(anEvent); + + } + + @Override + public <T> boolean offer(T event) { + logger.debug("{}: OFFER event", this); + + if (this.locked || !this.alive || this.policyContainer.getPolicySessions().isEmpty()) { + return true; + } + synchronized (this.recentSourceEvents) { - this.recentSourceEvents.add(anEvent); + this.recentSourceEvents.add(event); } - // increment event count for Nagios monitoring PdpJmx.getInstance().updateOccured(); // Broadcast - if (logger.isInfoEnabled()) { - logger.info("{} BROADCAST-INJECT of {} FROM {} INTO {}", - this, event, topic, this.policyContainer.getName()); - } - for (DroolsControllerFeatureAPI feature : DroolsControllerFeatureAPI.providers.getList()) { try { - if (feature.beforeInsert(this, anEvent)) { + if (feature.beforeInsert(this, event)) { return true; } } catch (Exception e) { logger.error("{}: feature {} before-insert failure because of {}", - this, feature.getClass().getName(), e.getMessage(), e); + this, feature.getClass().getName(), e.getMessage(), e); } } - boolean successInject = this.policyContainer.insertAll(anEvent); + boolean successInject = this.policyContainer.insertAll(event); if (!successInject) { logger.warn(this + "Failed to inject into PolicyContainer {}", this.getSessionNames()); } for (DroolsControllerFeatureAPI feature : DroolsControllerFeatureAPI.providers.getList()) { try { - if (feature.afterInsert(this, anEvent, successInject)) { + if (feature.afterInsert(this, event, successInject)) { return true; } } catch (Exception e) { logger.error("{}: feature {} after-insert failure because of {}", - this, feature.getClass().getName(), e.getMessage(), e); + this, feature.getClass().getName(), e.getMessage(), e); } } return true; + } @Override diff --git a/policy-management/src/main/java/org/onap/policy/drools/controller/internal/NullDroolsController.java b/policy-management/src/main/java/org/onap/policy/drools/controller/internal/NullDroolsController.java index 45568678..815aaabb 100644 --- a/policy-management/src/main/java/org/onap/policy/drools/controller/internal/NullDroolsController.java +++ b/policy-management/src/main/java/org/onap/policy/drools/controller/internal/NullDroolsController.java @@ -111,6 +111,11 @@ public class NullDroolsController implements DroolsController { } @Override + public <T> boolean offer(T event) { + return false; + } + + @Override public boolean deliver(TopicSink sink, Object event) { throw new IllegalStateException(makeInvokeMsg()); } diff --git a/policy-management/src/main/java/org/onap/policy/drools/features/PolicyControllerFeatureAPI.java b/policy-management/src/main/java/org/onap/policy/drools/features/PolicyControllerFeatureAPI.java index 40958427..914b073f 100644 --- a/policy-management/src/main/java/org/onap/policy/drools/features/PolicyControllerFeatureAPI.java +++ b/policy-management/src/main/java/org/onap/policy/drools/features/PolicyControllerFeatureAPI.java @@ -21,7 +21,6 @@ package org.onap.policy.drools.features; import java.util.Properties; - import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure; import org.onap.policy.common.utils.services.OrderedService; import org.onap.policy.common.utils.services.OrderedServiceImpl; @@ -32,7 +31,7 @@ public interface PolicyControllerFeatureAPI extends OrderedService { /** * Feature providers implementing this interface. */ - public static final OrderedServiceImpl<PolicyControllerFeatureAPI> providers = + OrderedServiceImpl<PolicyControllerFeatureAPI> providers = new OrderedServiceImpl<>(PolicyControllerFeatureAPI.class); /** @@ -47,7 +46,7 @@ public interface PolicyControllerFeatureAPI extends OrderedService { * 'null' indicates that no take over has taken place, and processing should * continue to the next feature provider. */ - public default PolicyController beforeCreate(String name, Properties properties) { + default PolicyController beforeCreate(String name, Properties properties) { return null; } @@ -60,7 +59,7 @@ public interface PolicyControllerFeatureAPI extends OrderedService { * of the operation preventing the invocation of * lower priority features. False, otherwise. */ - public default boolean afterCreate(PolicyController controller) { + default boolean afterCreate(PolicyController controller) { return false; } @@ -71,7 +70,7 @@ public interface PolicyControllerFeatureAPI extends OrderedService { * of the operation preventing the invocation of * lower priority features. False, otherwise. */ - public default boolean beforeStart(PolicyController controller) { + default boolean beforeStart(PolicyController controller) { return false; } @@ -82,7 +81,7 @@ public interface PolicyControllerFeatureAPI extends OrderedService { * of the operation preventing the invocation of * lower priority features. False, otherwise. */ - public default boolean afterStart(PolicyController controller) { + default boolean afterStart(PolicyController controller) { return false; } @@ -93,7 +92,7 @@ public interface PolicyControllerFeatureAPI extends OrderedService { * of the operation preventing the invocation of * lower priority features. False, otherwise.. */ - public default boolean beforeStop(PolicyController controller) { + default boolean beforeStop(PolicyController controller) { return false; } @@ -104,7 +103,7 @@ public interface PolicyControllerFeatureAPI extends OrderedService { * of the operation preventing the invocation of * lower priority features. False, otherwise.d. */ - public default boolean afterStop(PolicyController controller) { + default boolean afterStop(PolicyController controller) { return false; } @@ -115,7 +114,7 @@ public interface PolicyControllerFeatureAPI extends OrderedService { * of the operation preventing the invocation of * lower priority features. False, otherwise. */ - public default boolean beforeLock(PolicyController controller) { + default boolean beforeLock(PolicyController controller) { return false; } @@ -126,7 +125,7 @@ public interface PolicyControllerFeatureAPI extends OrderedService { * of the operation preventing the invocation of * lower priority features. False, otherwise.. */ - public default boolean afterLock(PolicyController controller) { + default boolean afterLock(PolicyController controller) { return false; } @@ -137,7 +136,7 @@ public interface PolicyControllerFeatureAPI extends OrderedService { * of the operation preventing the invocation of * lower priority features. False, otherwise. */ - public default boolean beforeUnlock(PolicyController controller) { + default boolean beforeUnlock(PolicyController controller) { return false; } @@ -148,7 +147,7 @@ public interface PolicyControllerFeatureAPI extends OrderedService { * of the operation preventing the invocation of * lower priority features. False, otherwise. */ - public default boolean afterUnlock(PolicyController controller) { + default boolean afterUnlock(PolicyController controller) { return false; } @@ -159,7 +158,7 @@ public interface PolicyControllerFeatureAPI extends OrderedService { * of the operation preventing the invocation of * lower priority features. False, otherwise.. */ - public default boolean beforeShutdown(PolicyController controller) { + default boolean beforeShutdown(PolicyController controller) { return false; } @@ -170,7 +169,7 @@ public interface PolicyControllerFeatureAPI extends OrderedService { * of the operation preventing the invocation of * lower priority features. False, otherwise. */ - public default boolean afterShutdown(PolicyController controller) { + default boolean afterShutdown(PolicyController controller) { return false; } @@ -181,7 +180,7 @@ public interface PolicyControllerFeatureAPI extends OrderedService { * of the operation preventing the invocation of * lower priority features. False, otherwise.. */ - public default boolean beforeHalt(PolicyController controller) { + default boolean beforeHalt(PolicyController controller) { return false; } @@ -192,22 +191,33 @@ public interface PolicyControllerFeatureAPI extends OrderedService { * of the operation preventing the invocation of * lower priority features. False, otherwise. */ - public default boolean afterHalt(PolicyController controller) { + default boolean afterHalt(PolicyController controller) { return false; } - /** + /* * intercept before the Policy Controller is offered an event. * * @return true if this feature intercepts and takes ownership. * of the operation preventing the invocation of * lower priority features. False, otherwise. */ - public default boolean beforeOffer(PolicyController controller, - CommInfrastructure protocol, - String topic, - String event) { + default boolean beforeOffer(PolicyController controller, + CommInfrastructure protocol, + String topic, + String event) { + return false; + } + + /** + * intercept before the Policy Controller delivers (posts) an event. + * + * @return true if this feature intercepts and takes ownership + * of the operation preventing the invocation of + * lower priority features. False, otherwise. + */ + default <T> boolean beforeOffer(PolicyController controller, T event) { return false; } @@ -218,11 +228,22 @@ public interface PolicyControllerFeatureAPI extends OrderedService { * of the operation preventing the invocation of * lower priority features. False, otherwise. */ - public default boolean afterOffer(PolicyController controller, - CommInfrastructure protocol, - String topic, - String event, - boolean success) { + default boolean afterOffer(PolicyController controller, + CommInfrastructure protocol, + String topic, + String event, + boolean success) { + return false; + } + + /** + * called after the Policy Controller delivers (posts) an event. + * + * @return true if this feature intercepts and takes ownership + * of the operation preventing the invocation of + * lower priority features. False, otherwise. + */ + default <T> boolean afterOffer(PolicyController controller, T event, boolean success) { return false; } @@ -233,10 +254,10 @@ public interface PolicyControllerFeatureAPI extends OrderedService { * of the operation preventing the invocation of * lower priority features. False, otherwise. */ - public default boolean beforeDeliver(PolicyController controller, - CommInfrastructure protocol, - String topic, - Object event) { + default boolean beforeDeliver(PolicyController controller, + CommInfrastructure protocol, + String topic, + Object event) { return false; } @@ -247,11 +268,11 @@ public interface PolicyControllerFeatureAPI extends OrderedService { * of the operation preventing the invocation of * lower priority features. False, otherwise. */ - public default boolean afterDeliver(PolicyController controller, - CommInfrastructure protocol, - String topic, - Object event, - boolean success) { + default boolean afterDeliver(PolicyController controller, + CommInfrastructure protocol, + String topic, + Object event, + boolean success) { return false; } } diff --git a/policy-management/src/main/java/org/onap/policy/drools/system/PolicyController.java b/policy-management/src/main/java/org/onap/policy/drools/system/PolicyController.java index 514dc364..9bc75b39 100644 --- a/policy-management/src/main/java/org/onap/policy/drools/system/PolicyController.java +++ b/policy-management/src/main/java/org/onap/policy/drools/system/PolicyController.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * policy-management * ================================================================================ - * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2017-2019 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. @@ -22,7 +22,6 @@ package org.onap.policy.drools.system; import java.util.List; import java.util.Properties; - import org.onap.policy.common.capabilities.Lockable; import org.onap.policy.common.capabilities.Startable; import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure; @@ -30,6 +29,7 @@ import org.onap.policy.common.endpoints.event.comm.TopicSink; import org.onap.policy.common.endpoints.event.comm.TopicSource; import org.onap.policy.drools.controller.DroolsController; import org.onap.policy.drools.protocol.configuration.DroolsConfiguration; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyTypeIdentifier; /** * A Policy Controller is the higher level unit of control. It corresponds to the ncomp equivalent @@ -66,7 +66,12 @@ public interface PolicyController extends Startable, Lockable { DroolsController getDrools(); /** - * update maven configuration. + * Get Policy Types supported by this controller. + */ + List<ToscaPolicyTypeIdentifier> getPolicyTypes(); + + /** + * Update maven configuration. * * @param newDroolsConfiguration new drools configuration * @return true if the update was successful, false otherwise @@ -79,6 +84,11 @@ public interface PolicyController extends Startable, Lockable { Properties getProperties(); /** + * Offer an event of type T. + */ + <T> boolean offer(T event); + + /** * Attempts delivering of an String over communication infrastructure "busType". * * @param busType bus type diff --git a/policy-management/src/main/java/org/onap/policy/drools/system/internal/AggregatedPolicyController.java b/policy-management/src/main/java/org/onap/policy/drools/system/internal/AggregatedPolicyController.java index 5bfde9a7..6fd05fb3 100644 --- a/policy-management/src/main/java/org/onap/policy/drools/system/internal/AggregatedPolicyController.java +++ b/policy-management/src/main/java/org/onap/policy/drools/system/internal/AggregatedPolicyController.java @@ -21,11 +21,12 @@ package org.onap.policy.drools.system.internal; import com.fasterxml.jackson.annotation.JsonIgnore; - +import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Properties; - +import java.util.stream.Collectors; import org.onap.policy.common.endpoints.event.comm.Topic; import org.onap.policy.common.endpoints.event.comm.TopicEndpoint; import org.onap.policy.common.endpoints.event.comm.TopicListener; @@ -39,6 +40,7 @@ import org.onap.policy.drools.persistence.SystemPersistence; import org.onap.policy.drools.properties.DroolsProperties; import org.onap.policy.drools.protocol.configuration.DroolsConfiguration; import org.onap.policy.drools.system.PolicyController; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyTypeIdentifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -98,6 +100,11 @@ public class AggregatedPolicyController implements PolicyController, TopicListen private final Properties properties; /** + * Policy Types. + */ + private List<ToscaPolicyTypeIdentifier> policyTypes; + + /** * Constructor version mainly used for bootstrapping at initialization time a policy engine * controller. * @@ -127,6 +134,43 @@ public class AggregatedPolicyController implements PolicyController, TopicListen /* persist new properties */ getPersistenceManager().storeController(name, properties); this.properties = properties; + + this.policyTypes = getPolicyTypesFromProperties(); + } + + @Override + public List<ToscaPolicyTypeIdentifier> getPolicyTypes() { + if (!policyTypes.isEmpty()) { + return policyTypes; + } + + return droolsController + .getBaseDomainNames() + .stream() + .map(d -> new ToscaPolicyTypeIdentifier(d, DroolsProperties.DEFAULT_CONTROLLER_POLICY_TYPE_VERSION)) + .collect(Collectors.toList()); + } + + protected List<ToscaPolicyTypeIdentifier> getPolicyTypesFromProperties() { + List<ToscaPolicyTypeIdentifier> policyTypeIds = new ArrayList<>(); + + String ptiPropValue = properties.getProperty(DroolsProperties.PROPERTY_CONTROLLER_POLICY_TYPES); + if (ptiPropValue == null) { + return policyTypeIds; + } + + List<String> ptiPropList = new ArrayList<>(Arrays.asList(ptiPropValue.split("\\s*,\\s*"))); + for (String pti : ptiPropList) { + String[] ptv = pti.split(":"); + if (ptv.length == 1) { + policyTypeIds.add(new ToscaPolicyTypeIdentifier(ptv[0], + DroolsProperties.DEFAULT_CONTROLLER_POLICY_TYPE_VERSION)); + } else if (ptv.length == 2) { + policyTypeIds.add(new ToscaPolicyTypeIdentifier(ptv[0], ptv[1])); + } + } + + return policyTypeIds; } /** @@ -399,8 +443,11 @@ public class AggregatedPolicyController implements PolicyController, TopicListen */ @Override public void onTopicEvent(Topic.CommInfrastructure commType, String topic, String event) { + logger.debug("{}: raw event offered from {}:{}: {}", this, commType, topic, event); - logger.debug("{}: event offered from {}:{}: {}", this, commType, topic, event); + if (skipOffer()) { + return; + } for (PolicyControllerFeatureAPI feature : getProviders()) { try { @@ -413,14 +460,6 @@ public class AggregatedPolicyController implements PolicyController, TopicListen } } - if (this.locked) { - return; - } - - if (!this.alive) { - return; - } - boolean success = this.droolsController.offer(topic, event); for (PolicyControllerFeatureAPI feature : getProviders()) { @@ -435,6 +474,45 @@ public class AggregatedPolicyController implements PolicyController, TopicListen } } + @Override + public <T> boolean offer(T event) { + logger.debug("{}: event offered: {}", this, event); + + if (skipOffer()) { + return true; + } + + for (PolicyControllerFeatureAPI feature : getProviders()) { + try { + if (feature.beforeOffer(this, event)) { + return true; + } + } catch (Exception e) { + logger.error("{}: feature {} before-offer failure because of {}", this, feature.getClass().getName(), + e.getMessage(), e); + } + } + + boolean success = this.droolsController.offer(event); + + for (PolicyControllerFeatureAPI feature : getProviders()) { + try { + if (feature.afterOffer(this, event, success)) { + return success; + } + } catch (Exception e) { + logger.error("{}: feature {} after-offer failure because of {}", this, feature.getClass().getName(), + e.getMessage(), e); + } + } + + return success; + } + + private boolean skipOffer() { + return isLocked() || !isAlive(); + } + /** * {@inheritDoc}. */ diff --git a/policy-management/src/test/java/org/onap/policy/drools/system/internal/AggregatedPolicyControllerTest.java b/policy-management/src/test/java/org/onap/policy/drools/system/internal/AggregatedPolicyControllerTest.java index 43068810..eb226e00 100644 --- a/policy-management/src/test/java/org/onap/policy/drools/system/internal/AggregatedPolicyControllerTest.java +++ b/policy-management/src/test/java/org/onap/policy/drools/system/internal/AggregatedPolicyControllerTest.java @@ -528,8 +528,8 @@ public class AggregatedPolicyControllerTest { // now offer it apc.onTopicEvent(CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT); - verify(prov1).beforeOffer(apc, CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT); - verify(prov2).beforeOffer(apc, CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT); + verify(prov1, never()).beforeOffer(apc, CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT); + verify(prov2, never()).beforeOffer(apc, CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT); // never gets this far verify(drools, never()).offer(SOURCE_TOPIC1, MY_EVENT); @@ -542,8 +542,8 @@ public class AggregatedPolicyControllerTest { // offer it apc.onTopicEvent(CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT); - verify(prov1).beforeOffer(apc, CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT); - verify(prov2).beforeOffer(apc, CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT); + verify(prov1, never()).beforeOffer(apc, CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT); + verify(prov2, never()).beforeOffer(apc, CommInfrastructure.NOOP, SOURCE_TOPIC1, MY_EVENT); // never gets this far verify(drools, never()).offer(SOURCE_TOPIC1, MY_EVENT); diff --git a/policy-management/src/test/resources/org/onap/policy/drools/system/internal/AggregatedPolicyControllerTest.json b/policy-management/src/test/resources/org/onap/policy/drools/system/internal/AggregatedPolicyControllerTest.json index 3557f21d..f2c218e0 100644 --- a/policy-management/src/test/resources/org/onap/policy/drools/system/internal/AggregatedPolicyControllerTest.json +++ b/policy-management/src/test/resources/org/onap/policy/drools/system/internal/AggregatedPolicyControllerTest.json @@ -7,6 +7,7 @@ }, "locked": false, "name": "agg-name", + "policyTypes":[], "topicSinks": [ { "name": "sink-a" }, { "name": "sink-b" } |