Initial support for deploy 42/84542/5
authorjhh <jorge.hernandez-herrero@att.com>
Mon, 8 Apr 2019 16:13:14 +0000 (11:13 -0500)
committerjhh <jorge.hernandez-herrero@att.com>
Tue, 9 Apr 2019 00:46:52 +0000 (19:46 -0500)
This is a first pass, some functionality is
missing (undeploy).

Compile error fix from changes in policy/models repo.

Change-Id: If448492ab665c135bace99d4d684d403e2a6be03
Issue-ID: POLICY-1624
Signed-off-by: jhh <jorge.hernandez-herrero@att.com>
22 files changed:
feature-lifecycle/src/main/java/org/onap/policy/drools/lifecycle/LifecycleFeature.java
feature-lifecycle/src/main/java/org/onap/policy/drools/lifecycle/LifecycleFsm.java
feature-lifecycle/src/main/java/org/onap/policy/drools/lifecycle/LifecycleStateActive.java
feature-lifecycle/src/main/java/org/onap/policy/drools/lifecycle/LifecycleStatePassive.java
feature-lifecycle/src/main/java/org/onap/policy/drools/lifecycle/LifecycleStateRunning.java
feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/ControllerSupport.java [new file with mode: 0644]
feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/LifecycleStateActiveTest.java
feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/LifecycleStatePassiveTest.java
feature-lifecycle/src/test/java/org/onap/policy/drools/lifecycle/LifecycleStateRunningTest.java [new file with mode: 0644]
feature-lifecycle/src/test/resources/lifecycle.drl [moved from feature-lifecycle/src/test/resources/echo.drl with 59% similarity]
feature-lifecycle/src/test/resources/lifecycle.kmodule [moved from feature-lifecycle/src/test/resources/echo.kmodule with 93% similarity]
feature-lifecycle/src/test/resources/lifecycle.pom [moved from feature-lifecycle/src/test/resources/echo.pom with 97% similarity]
feature-lifecycle/src/test/resources/tosca-policy.json [new file with mode: 0644]
policy-core/src/main/java/org/onap/policy/drools/properties/DroolsProperties.java
policy-management/src/main/java/org/onap/policy/drools/controller/DroolsController.java
policy-management/src/main/java/org/onap/policy/drools/controller/internal/MavenDroolsController.java
policy-management/src/main/java/org/onap/policy/drools/controller/internal/NullDroolsController.java
policy-management/src/main/java/org/onap/policy/drools/features/PolicyControllerFeatureAPI.java
policy-management/src/main/java/org/onap/policy/drools/system/PolicyController.java
policy-management/src/main/java/org/onap/policy/drools/system/internal/AggregatedPolicyController.java
policy-management/src/test/java/org/onap/policy/drools/system/internal/AggregatedPolicyControllerTest.java
policy-management/src/test/resources/org/onap/policy/drools/system/internal/AggregatedPolicyControllerTest.json

index 5e1ddae..9f29294 100644 (file)
@@ -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;
+    }
 }
index 7437568..b99953e 100644 (file)
@@ -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() {
index 9ec6865..d481b8b 100644 (file)
 
 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;
+    }
 }
index 0720ec9..e9f4b9b 100644 (file)
 
 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;
+    }
 }
index 916d155..405dbeb 100644 (file)
 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 (file)
index 0000000..1beee55
--- /dev/null
@@ -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());
+    }
+}
index c4d47d8..3200642 100644 (file)
@@ -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();
     }
 }
index 376eb3a..100bcef 100644 (file)
@@ -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.
@@ -86,6 +76,21 @@ public class LifecycleStatePassiveTest {
         fsm.shutdown();
     }
 
+    @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);
@@ -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 (file)
index 0000000..d7bb6d7
--- /dev/null
@@ -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);
+    }
+}
 
 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
@@ -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>
@@ -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 (file)
index 0000000..5258ca1
--- /dev/null
@@ -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"
+}
index 468f0e3..0b7a650 100644 (file)
@@ -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";
index 1e7b8c7..344725f 100644 (file)
@@ -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();
 }
index eb401eb..95b053f 100644 (file)
@@ -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
index 4556867..815aaab 100644 (file)
@@ -110,6 +110,11 @@ public class NullDroolsController implements DroolsController {
         return false;
     }
 
+    @Override
+    public <T> boolean offer(T event) {
+        return false;
+    }
+
     @Override
     public boolean deliver(TopicSink sink, Object event) {
         throw new IllegalStateException(makeInvokeMsg());
index 4095842..914b073 100644 (file)
@@ -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;
     }
 }
index 514dc36..9bc75b3 100644 (file)
@@ -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
@@ -78,6 +83,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".
      * 
index 5bfde9a..6fd05fb 100644 (file)
 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;
 
@@ -97,6 +99,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}.
      */
index 4306881..eb226e0 100644 (file)
@@ -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);