Add Controller Logging Feature 32/79032/6
authorDaniel Cruz <dc443y@att.com>
Fri, 22 Feb 2019 17:31:17 +0000 (11:31 -0600)
committerDaniel Cruz <dc443y@att.com>
Sat, 2 Mar 2019 00:44:07 +0000 (18:44 -0600)
This features provides a mechanism to extend the logback.xml
properties to add controller specific loggers. The controller's
logger will log messages from topics that the controller listens
to in a controller specific network log. The original network
log is preserved and still logs every message from every controller.
Note that the way a logger is associated with a controller is by
having the logger name match the controller's name. Any configuration
file that has "logback-include-" prepended and a ".xml" extension
will be added to the logback.xml and logback-eelf.xml files as
extensions to the base configuration.

Issue-ID: POLICY-1427
Change-Id: Iaeb823421eadb7ee413b6b03ae3dfe862f230612
Signed-off-by: Daniel Cruz <dc443y@att.com>
21 files changed:
feature-controller-logging/pom.xml [new file with mode: 0755]
feature-controller-logging/src/assembly/assemble_zip.xml [new file with mode: 0755]
feature-controller-logging/src/main/feature/install/disable [new file with mode: 0644]
feature-controller-logging/src/main/feature/install/enable [new file with mode: 0644]
feature-controller-logging/src/main/java/org/onap/policy/drools/controller/logging/ControllerLoggingFeature.java [new file with mode: 0755]
feature-controller-logging/src/main/resources/META-INF/services/org.onap.policy.drools.features.DroolsControllerFeatureAPI [new file with mode: 0755]
feature-controller-logging/src/main/resources/META-INF/services/org.onap.policy.drools.features.PolicyControllerFeatureAPI [new file with mode: 0755]
feature-controller-logging/src/main/resources/META-INF/services/org.onap.policy.drools.features.PolicyEngineFeatureAPI [new file with mode: 0755]
feature-controller-logging/src/test/java/org/onap/policy/drools/controller/logging/ControllerLoggingTest.java [new file with mode: 0755]
feature-controller-logging/src/test/resources/kmodule.xml [new file with mode: 0755]
feature-controller-logging/src/test/resources/logback-test.xml [new file with mode: 0755]
feature-controller-logging/src/test/resources/test.drl [new file with mode: 0755]
feature-controller-logging/src/test/resources/test.pom [new file with mode: 0755]
feature-eelf/src/main/feature/config/logback-eelf.xml
packages/install/pom.xml
policy-management/src/main/java/org/onap/policy/drools/controller/internal/MavenDroolsController.java
policy-management/src/main/java/org/onap/policy/drools/features/DroolsControllerFeatureAPI.java
policy-management/src/main/java/org/onap/policy/drools/features/PolicyEngineFeatureAPI.java
policy-management/src/main/java/org/onap/policy/drools/system/PolicyEngine.java
policy-management/src/main/server/config/logback.xml
pom.xml

diff --git a/feature-controller-logging/pom.xml b/feature-controller-logging/pom.xml
new file mode 100755 (executable)
index 0000000..0798c64
--- /dev/null
@@ -0,0 +1,103 @@
+<!--\r
+  ============LICENSE_START=======================================================\r
+  feature-controller-logging\r
+  ================================================================================\r
+  Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.\r
+  ================================================================================\r
+  Licensed under the Apache License, Version 2.0 (the "License");\r
+  you may not use this file except in compliance with the License.\r
+  You may obtain a copy of the License at\r
+  \r
+       http://www.apache.org/licenses/LICENSE-2.0\r
+  \r
+  Unless required by applicable law or agreed to in writing, software\r
+  distributed under the License is distributed on an "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+  See the License for the specific language governing permissions and\r
+  limitations under the License.\r
+  ============LICENSE_END=========================================================\r
+  -->\r
+\r
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">\r
+    <modelVersion>4.0.0</modelVersion>\r
+\r
+    <parent>\r
+        <groupId>org.onap.policy.drools-pdp</groupId>\r
+        <artifactId>drools-pdp</artifactId>\r
+        <version>1.4.0-SNAPSHOT</version>\r
+    </parent>\r
+\r
+    <artifactId>feature-controller-logging</artifactId>\r
+\r
+    <name>feature-controller-logging</name>\r
+    <description>Loadable module that enables individual network logs per controller</description>\r
+\r
+    <properties>\r
+        <maven.compiler.source>1.8</maven.compiler.source>\r
+        <maven.compiler.target>1.8</maven.compiler.target>\r
+    </properties>\r
+\r
+    <build>\r
+        <plugins>\r
+            <plugin>\r
+                <artifactId>maven-assembly-plugin</artifactId>\r
+                <executions>\r
+                    <execution>\r
+                        <id>zipfile</id>\r
+                        <goals>\r
+                            <goal>single</goal>\r
+                        </goals>\r
+                        <phase>package</phase>\r
+                        <configuration>\r
+                            <attach>true</attach>\r
+                            <finalName>${project.artifactId}-${project.version}</finalName>\r
+                            <descriptors>\r
+                                <descriptor>src/assembly/assemble_zip.xml</descriptor>\r
+                            </descriptors>\r
+                            <appendAssemblyId>false</appendAssemblyId>\r
+                        </configuration>\r
+                    </execution>\r
+                </executions>\r
+            </plugin>\r
+            <plugin>\r
+                <groupId>org.apache.maven.plugins</groupId>\r
+                <artifactId>maven-dependency-plugin</artifactId>\r
+                <executions>\r
+                    <execution>\r
+                        <id>copy-dependencies</id>\r
+                        <goals>\r
+                            <goal>copy-dependencies</goal>\r
+                        </goals>\r
+                        <phase>prepare-package</phase>\r
+                        <configuration>\r
+                            <outputDirectory>${project.build.directory}/assembly/lib</outputDirectory>\r
+                            <overWriteReleases>false</overWriteReleases>\r
+                            <overWriteSnapshots>true</overWriteSnapshots>\r
+                            <overWriteIfNewer>true</overWriteIfNewer>\r
+                            <useRepositoryLayout>false</useRepositoryLayout>\r
+                            <addParentPoms>false</addParentPoms>\r
+                            <copyPom>false</copyPom>\r
+                            <includeScope>runtime</includeScope>\r
+                            <excludeTransitive>true</excludeTransitive>\r
+                        </configuration>\r
+                    </execution>\r
+                </executions>\r
+            </plugin>\r
+        </plugins>\r
+    </build>\r
+\r
+    <dependencies>\r
+        <dependency>\r
+            <groupId>org.onap.policy.drools-pdp</groupId>\r
+            <artifactId>policy-management</artifactId>\r
+            <version>${project.version}</version>\r
+            <scope>provided</scope>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>junit</groupId>\r
+            <artifactId>junit</artifactId>\r
+            <scope>test</scope>\r
+        </dependency>\r
+    </dependencies>\r
+</project>\r
diff --git a/feature-controller-logging/src/assembly/assemble_zip.xml b/feature-controller-logging/src/assembly/assemble_zip.xml
new file mode 100755 (executable)
index 0000000..6832604
--- /dev/null
@@ -0,0 +1,68 @@
+<!--\r
+  ============LICENSE_START=======================================================\r
+  feature-controller-logging\r
+  ================================================================================\r
+  Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.\r
+  ================================================================================\r
+  Licensed under the Apache License, Version 2.0 (the "License");\r
+  you may not use this file except in compliance with the License.\r
+  You may obtain a copy of the License at\r
+\r
+       http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+  Unless required by applicable law or agreed to in writing, software\r
+  distributed under the License is distributed on an "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+  See the License for the specific language governing permissions and\r
+  limitations under the License.\r
+  ============LICENSE_END=========================================================\r
+  -->\r
+\r
+<!-- Defines how we build the .zip file which is our distribution. -->\r
+\r
+<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"\r
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+    xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">\r
+    <id>feature-controller-logging</id>\r
+    <formats>\r
+        <format>zip</format>\r
+    </formats>\r
+\r
+    <includeBaseDirectory>false</includeBaseDirectory>\r
+\r
+    <fileSets>\r
+        <fileSet>\r
+            <directory>target</directory>\r
+            <outputDirectory>lib/feature</outputDirectory>\r
+            <includes>\r
+                <include>feature-controller-logging-${project.version}.jar</include>\r
+            </includes>\r
+        </fileSet>\r
+        <fileSet>\r
+            <directory>target/assembly/lib</directory>\r
+            <outputDirectory>lib/dependencies</outputDirectory>\r
+            <includes>\r
+                <include>*.jar</include>\r
+            </includes>\r
+        </fileSet>\r
+        <fileSet>\r
+            <directory>src/main/feature/config</directory>\r
+            <outputDirectory>config</outputDirectory>\r
+            <fileMode>0644</fileMode>\r
+            <excludes />\r
+        </fileSet>\r
+        <fileSet>\r
+            <directory>src/main/feature/bin</directory>\r
+            <outputDirectory>bin</outputDirectory>\r
+            <fileMode>0744</fileMode>\r
+            <excludes />\r
+        </fileSet>\r
+        <fileSet>\r
+            <directory>src/main/feature/install</directory>\r
+            <outputDirectory>install</outputDirectory>\r
+            <fileMode>0744</fileMode>\r
+            <excludes />\r
+        </fileSet>\r
+    </fileSets>\r
+\r
+</assembly>\r
diff --git a/feature-controller-logging/src/main/feature/install/disable b/feature-controller-logging/src/main/feature/install/disable
new file mode 100644 (file)
index 0000000..698b6b3
--- /dev/null
@@ -0,0 +1,26 @@
+#!/bin/bash
+
+# ============LICENSE_START=======================================================
+# feature-controller-logging
+# ================================================================================
+# 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=========================================================
+
+configDir=${POLICY_HOME}/config
+for mainConfig in ${configDir}/logback.xml ${configDir}/logback-eelf.xml; do
+    if [ -e "${mainConfig}" ]; then
+        sed -i --follow-symlinks "/\<include.*logback\-include\-.*\.xml\>/d" "${mainConfig}"
+    fi
+done
\ No newline at end of file
diff --git a/feature-controller-logging/src/main/feature/install/enable b/feature-controller-logging/src/main/feature/install/enable
new file mode 100644 (file)
index 0000000..170598b
--- /dev/null
@@ -0,0 +1,29 @@
+#!/bin/bash
+
+# ============LICENSE_START=======================================================
+# feature-controller-logging
+# ================================================================================
+# 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=========================================================
+
+configDir=${POLICY_HOME}/config
+for includedConfig in $(ls "${configDir}" | grep "logback-include-.*.xml"); do
+    include="\t\<include optional\=\"true\" resource\=\"${includedConfig}\"/\>"
+    for mainConfig in ${configDir}/logback.xml ${configDir}/logback-eelf.xml; do
+        if [ -e "${mainConfig}" ]; then
+            sed -i --follow-symlinks "/\<configuration.*\> /a\ ${include}" "${mainConfig}"
+        fi
+    done
+done
\ No newline at end of file
diff --git a/feature-controller-logging/src/main/java/org/onap/policy/drools/controller/logging/ControllerLoggingFeature.java b/feature-controller-logging/src/main/java/org/onap/policy/drools/controller/logging/ControllerLoggingFeature.java
new file mode 100755 (executable)
index 0000000..ec59ace
--- /dev/null
@@ -0,0 +1,97 @@
+/*\r
+ * ============LICENSE_START=======================================================\r
+ * feature-controller-logging\r
+ * ================================================================================\r
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.\r
+ * ================================================================================\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ * ============LICENSE_END=========================================================\r
+ */\r
+\r
+package org.onap.policy.drools.controller.logging;\r
+\r
+import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure;\r
+import org.onap.policy.common.endpoints.event.comm.TopicSink;\r
+import org.onap.policy.drools.controller.DroolsController;\r
+import org.onap.policy.drools.features.DroolsControllerFeatureAPI;\r
+import org.onap.policy.drools.features.PolicyControllerFeatureAPI;\r
+import org.onap.policy.drools.features.PolicyEngineFeatureAPI;\r
+import org.onap.policy.drools.protocol.configuration.ControllerConfiguration;\r
+import org.onap.policy.drools.protocol.configuration.PdpdConfiguration;\r
+import org.onap.policy.drools.system.PolicyController;\r
+import org.onap.policy.drools.system.PolicyEngine;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+/**\r
+ * This class hooks the network logging implementation into DroolsPDP. It will disable the\r
+ * default network logger where all topic traffic is logged and segregates the topic\r
+ * traffic by controller for each supported control loop use case.\r
+ */\r
+\r
+/*\r
+ * PolicyControllerFeatureAPI - the 'beforeStart' hook is used to shut off the default\r
+ * network logger and the 'beforeOffer' hook is used to log incoming topic messages\r
+ *\r
+ * DroolsControllerFeatureAPI - the 'afterDeliver' hook is where the outgoing topic\r
+ * messages are logged\r
+ *\r
+ */\r
+public class ControllerLoggingFeature\r
+                implements PolicyEngineFeatureAPI, DroolsControllerFeatureAPI, PolicyControllerFeatureAPI {\r
+\r
+    @Override\r
+    public int getSequenceNumber() {\r
+        return 1000;\r
+    }\r
+\r
+    /**\r
+     * The 'beforeOffer' hook will intercept an incoming topic message and append it to\r
+     * the log file that is configured for the controller logger.\r
+     */\r
+    @Override\r
+    public boolean beforeOffer(PolicyController controller, CommInfrastructure protocol, String topic, String event) {\r
+        Logger controllerLogger = LoggerFactory.getLogger(controller.getName());\r
+        controllerLogger.info("[IN|{}|{}]{}{}", protocol, topic, System.lineSeparator(), event);\r
+        return false;\r
+    }\r
+\r
+    /**\r
+     * The 'afterDeliver' hook will intercept an outgoing topic message and append it to\r
+     * the log file that is configured for the controller logger.\r
+     */\r
+    @Override\r
+    public boolean afterDeliver(DroolsController controller, TopicSink sink, Object fact, String json,\r
+                    boolean success) {\r
+        if (success) {\r
+            Logger controllerLogger = LoggerFactory.getLogger(PolicyController.factory.get(controller).getName());\r
+            controllerLogger.info("[OUT|{}|{}]{}{}", sink.getTopicCommInfrastructure(), sink.getTopic(),\r
+                            System.lineSeparator(), json);\r
+        }\r
+        return false;\r
+    }\r
+\r
+    /**\r
+     * The 'afterOnTopicEvent' hook will determine which controllers were updated and log\r
+     * the event to the appropriate controller logs.\r
+     */\r
+    @Override\r
+    public boolean afterOnTopicEvent(PolicyEngine engine, PdpdConfiguration configuration, CommInfrastructure commType,\r
+                    String topic, String event) {\r
+        for (ControllerConfiguration controller : configuration.getControllers()) {\r
+            Logger controllerLogger = LoggerFactory.getLogger(controller.getName());\r
+            controllerLogger.info("[IN|{}|{}]{}{}", commType, topic, System.lineSeparator(), event);\r
+        }\r
+        return false;\r
+    }\r
+}\r
diff --git a/feature-controller-logging/src/main/resources/META-INF/services/org.onap.policy.drools.features.DroolsControllerFeatureAPI b/feature-controller-logging/src/main/resources/META-INF/services/org.onap.policy.drools.features.DroolsControllerFeatureAPI
new file mode 100755 (executable)
index 0000000..dbde0a8
--- /dev/null
@@ -0,0 +1 @@
+org.onap.policy.drools.controller.logging.ControllerLoggingFeature\r
diff --git a/feature-controller-logging/src/main/resources/META-INF/services/org.onap.policy.drools.features.PolicyControllerFeatureAPI b/feature-controller-logging/src/main/resources/META-INF/services/org.onap.policy.drools.features.PolicyControllerFeatureAPI
new file mode 100755 (executable)
index 0000000..dbde0a8
--- /dev/null
@@ -0,0 +1 @@
+org.onap.policy.drools.controller.logging.ControllerLoggingFeature\r
diff --git a/feature-controller-logging/src/main/resources/META-INF/services/org.onap.policy.drools.features.PolicyEngineFeatureAPI b/feature-controller-logging/src/main/resources/META-INF/services/org.onap.policy.drools.features.PolicyEngineFeatureAPI
new file mode 100755 (executable)
index 0000000..dbde0a8
--- /dev/null
@@ -0,0 +1 @@
+org.onap.policy.drools.controller.logging.ControllerLoggingFeature\r
diff --git a/feature-controller-logging/src/test/java/org/onap/policy/drools/controller/logging/ControllerLoggingTest.java b/feature-controller-logging/src/test/java/org/onap/policy/drools/controller/logging/ControllerLoggingTest.java
new file mode 100755 (executable)
index 0000000..02e879f
--- /dev/null
@@ -0,0 +1,228 @@
+/*\r
+ * ============LICENSE_START=======================================================\r
+ * feature-controller-logging\r
+ * ================================================================================\r
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.\r
+ * ================================================================================\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ * ============LICENSE_END=========================================================\r
+ */\r
+\r
+package org.onap.policy.drools.controller.logging;\r
+\r
+import static org.junit.Assert.assertEquals;\r
+\r
+import ch.qos.logback.classic.spi.LoggingEvent;\r
+import ch.qos.logback.core.AppenderBase;\r
+import com.google.gson.Gson;\r
+import com.google.gson.GsonBuilder;\r
+import java.io.IOException;\r
+import java.nio.file.Paths;\r
+import java.util.ArrayList;\r
+import java.util.Arrays;\r
+import java.util.List;\r
+import java.util.Properties;\r
+import org.junit.After;\r
+import org.junit.BeforeClass;\r
+import org.junit.Test;\r
+import org.onap.policy.common.endpoints.event.comm.Topic;\r
+import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure;\r
+import org.onap.policy.common.endpoints.event.comm.bus.NoopTopicSink;\r
+import org.onap.policy.drools.controller.DroolsController;\r
+import org.onap.policy.drools.controller.logging.ControllerLoggingFeature;\r
+import org.onap.policy.drools.properties.DroolsProperties;\r
+import org.onap.policy.drools.protocol.configuration.ControllerConfiguration;\r
+import org.onap.policy.drools.protocol.configuration.PdpdConfiguration;\r
+import org.onap.policy.drools.system.PolicyController;\r
+import org.onap.policy.drools.system.PolicyEngine;\r
+import org.onap.policy.drools.util.KieUtils;\r
+\r
+/**\r
+ * Controller Logger Tests.\r
+ */\r
+public class ControllerLoggingTest {\r
+\r
+    /**\r
+     * These properties are for installing a test artifact that the drools controller can\r
+     * fetch while testing.\r
+     */\r
+    private static final String JUNIT_KMODULE_DRL_PATH = "src/test/resources/test.drl";\r
+    private static final String JUNIT_KMODULE_POM_PATH = "src/test/resources/test.pom";\r
+    private static final String JUNIT_KMODULE_PATH = "src/test/resources/kmodule.xml";\r
+    private static final String JUNIT_KJAR_DRL_PATH = "src/main/resources/org/onap/policy/drools/test/test.drl";\r
+\r
+    /**\r
+     * These properties are used for the Policy Controller to point to the test artifact.\r
+     */\r
+    private static final String TEST_CONTROLLER_NAME = "test-controller";\r
+    private static final String TEST_GROUP_ID = "org.onap.policy.drools.test";\r
+    private static final String TEST_ARTIFACT_ID = "test";\r
+    private static final String TEST_VERSION = "1.4.0-SNAPSHOT";\r
+\r
+    /**\r
+     * A test topic used for delivery and network logging.\r
+     */\r
+    private static final String TEST_TOPIC = "test-topic";\r
+    private static final String TEST_SERVER = "http://test.com";\r
+\r
+    /**\r
+     * These are used for sending PDPD configuration notifications to a policy controller.\r
+     */\r
+    private static Properties controllerProps = null;\r
+    private static String message = null;\r
+    private static PdpdConfiguration pdpdNotification = null;\r
+    private static PolicyController policyController = null;\r
+\r
+    /**\r
+     * This is a list of events that are appended to the controller-test logger.\r
+     */\r
+    private static List<LoggingEvent> events = new ArrayList<>();\r
+\r
+    /**\r
+     * A custom appender used to intercept events and add them to a list of events that\r
+     * the junits can use to determine logging was successful.\r
+     */\r
+    public static class NetworkAppender extends AppenderBase<LoggingEvent> {\r
+\r
+        @Override\r
+        protected void append(LoggingEvent event) {\r
+            events.add(event);\r
+        }\r
+\r
+    }\r
+\r
+    /**\r
+     * Runs before all the test cases to install the drools artifact, create a policy\r
+     * controller, and create a PDPD configuration notification.\r
+     */\r
+    @BeforeClass\r
+    public static void setUp() throws IOException {\r
+        KieUtils.installArtifact(Paths.get(JUNIT_KMODULE_PATH).toFile(), Paths.get(JUNIT_KMODULE_POM_PATH).toFile(),\r
+                        JUNIT_KJAR_DRL_PATH, Paths.get(JUNIT_KMODULE_DRL_PATH).toFile());\r
+\r
+        controllerProps = new Properties();\r
+        controllerProps.put(DroolsProperties.PROPERTY_CONTROLLER_NAME, TEST_CONTROLLER_NAME);\r
+        controllerProps.put(DroolsProperties.RULES_GROUPID, TEST_GROUP_ID);\r
+        controllerProps.put(DroolsProperties.RULES_ARTIFACTID, TEST_ARTIFACT_ID);\r
+        controllerProps.put(DroolsProperties.RULES_VERSION, TEST_VERSION);\r
+\r
+        policyController = PolicyEngine.manager.createPolicyController(TEST_CONTROLLER_NAME, controllerProps);\r
+\r
+        message = "{\"requestID\":\"38adde30-cc22-11e8-a8d5-f2801f1b9fd1\",\"entity\":\"controller\",\"controllers\":"\r
+                        + "[{\"name\":\"test-controller\",\"drools\":{\"groupId\":\"org.onap.policy.drools.test\","\r
+                        + "\"artifactId\":\"test\",\"version\":\"0.0.1\"},\"operation\":\"update\"}]}";\r
+\r
+        Gson decoder = new GsonBuilder().disableHtmlEscaping().create();\r
+        pdpdNotification = decoder.fromJson(message, PdpdConfiguration.class);\r
+    }\r
+\r
+    /**\r
+     * Runs after every test case to clean up the events added to the event list during\r
+     * unit test.\r
+     */\r
+    @After\r
+    public void cleanUpLogs() {\r
+        events.clear();\r
+    }\r
+\r
+    /**\r
+     * Obtains the sequence number of the controller logging feature. This should return\r
+     * 1000.\r
+     */\r
+    @Test\r
+    public void getSequenceNumberTest() {\r
+        ControllerLoggingFeature nlf = new ControllerLoggingFeature();\r
+        assertEquals(1000, nlf.getSequenceNumber());\r
+    }\r
+\r
+    /**\r
+     * Asserts that the controller-test logger appends the incoming message to the event\r
+     * list.\r
+     */\r
+    @Test\r
+    public void beforeOffer() {\r
+        ControllerLoggingFeature nlf = new ControllerLoggingFeature();\r
+\r
+        nlf.beforeOffer(policyController, Topic.CommInfrastructure.UEB, TEST_TOPIC, "{\"test\":\"test\"}");\r
+\r
+        assertEquals(1, events.size());\r
+    }\r
+\r
+    /**\r
+     * Asserts that the controller-test logger appends the outgoing message to the event\r
+     * list.\r
+     */\r
+    @Test\r
+    public void afterDeliverSuccess() {\r
+\r
+        final ControllerLoggingFeature nlf = new ControllerLoggingFeature();\r
+\r
+        DroolsController droolsController = DroolsController.factory.get(TEST_GROUP_ID, TEST_ARTIFACT_ID, TEST_VERSION);\r
+\r
+        NoopTopicSink sinkTopic = new NoopTopicSink(Arrays.asList(TEST_SERVER), TEST_TOPIC);\r
+\r
+        nlf.afterDeliver(droolsController, sinkTopic, null, "{\"test\":\"test\"}", true);\r
+\r
+        assertEquals(1, events.size());\r
+\r
+    }\r
+\r
+    /**\r
+     * Asserts that the controller-test logger does not append the outgoing message to the\r
+     * event list if there was a failure.\r
+     */\r
+    @Test\r
+    public void afterDeliverFailure() {\r
+\r
+        final ControllerLoggingFeature nlf = new ControllerLoggingFeature();\r
+\r
+        DroolsController droolsController = DroolsController.factory.get(TEST_GROUP_ID, TEST_ARTIFACT_ID, TEST_VERSION);\r
+\r
+        NoopTopicSink sinkTopic = new NoopTopicSink(Arrays.asList(TEST_SERVER), TEST_TOPIC);\r
+\r
+        nlf.afterDeliver(droolsController, sinkTopic, null, "{\"test\":\"test\"}", false);\r
+\r
+        assertEquals(0, events.size());\r
+    }\r
+\r
+    /**\r
+     * Asserts that the controller logging feature can log the messages to the proper\r
+     * controller based on the message containing the controller name.\r
+     */\r
+    @Test\r
+    public void afterOnTopicEventSuccess() {\r
+        final ControllerLoggingFeature nlf = new ControllerLoggingFeature();\r
+\r
+        nlf.afterOnTopicEvent(PolicyEngine.manager, pdpdNotification, CommInfrastructure.UEB, TEST_TOPIC, message);\r
+\r
+        assertEquals(1, events.size());\r
+    }\r
+\r
+    /**\r
+     * Asserts that the controller logging feature can skip logging messages that don't\r
+     * contain the controller names in it.\r
+     */\r
+    @Test\r
+    public void afterOnTopicEventFailure() {\r
+        final ControllerLoggingFeature nlf = new ControllerLoggingFeature();\r
+\r
+        PdpdConfiguration notification = new PdpdConfiguration();\r
+        ControllerConfiguration config = new ControllerConfiguration();\r
+        config.setName("test-controller-2");\r
+        notification.setControllers(Arrays.asList(config));\r
+\r
+        nlf.afterOnTopicEvent(PolicyEngine.manager, notification, CommInfrastructure.UEB, TEST_TOPIC, message);\r
+\r
+        assertEquals(0, events.size());\r
+    }\r
+}\r
diff --git a/feature-controller-logging/src/test/resources/kmodule.xml b/feature-controller-logging/src/test/resources/kmodule.xml
new file mode 100755 (executable)
index 0000000..2410a0f
--- /dev/null
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!--\r
+  ============LICENSE_START=======================================================\r
+  feature-controller-logging\r
+  ================================================================================\r
+  Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.\r
+  ================================================================================\r
+  Licensed under the Apache License, Version 2.0 (the "License");\r
+  you may not use this file except in compliance with the License.\r
+  You may obtain a copy of the License at\r
+\r
+       http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+  Unless required by applicable law or agreed to in writing, software\r
+  distributed under the License is distributed on an "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+  See the License for the specific language governing permissions and\r
+  limitations under the License.\r
+  ============LICENSE_END=========================================================\r
+  -->\r
+\r
+<kmodule xmlns="http://jboss.org/kie/6.0.0/kmodule">\r
+    <kbase name="controller-logs">\r
+        <ksession name="test" />\r
+    </kbase>\r
+</kmodule>\r
diff --git a/feature-controller-logging/src/test/resources/logback-test.xml b/feature-controller-logging/src/test/resources/logback-test.xml
new file mode 100755 (executable)
index 0000000..dfe9a45
--- /dev/null
@@ -0,0 +1,41 @@
+<!--\r
+  ============LICENSE_START=======================================================\r
+  feature-controller-logging\r
+  ================================================================================\r
+  Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.\r
+  ================================================================================\r
+  Licensed under the Apache License, Version 2.0 (the "License");\r
+  you may not use this file except in compliance with the License.\r
+  You may obtain a copy of the License at\r
+\r
+       http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+  Unless required by applicable law or agreed to in writing, software\r
+  distributed under the License is distributed on an "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+  See the License for the specific language governing permissions and\r
+  limitations under the License.\r
+  ============LICENSE_END=========================================================\r
+  -->\r
+<configuration>\r
+\r
+    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">\r
+        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">\r
+            <Pattern>\r
+                %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36}.%M\(%line\) - %msg%n\r
+            </Pattern>\r
+        </encoder>\r
+    </appender>\r
+    <logger name="org.onap.policy.drools.system.test" level="INFO" />\r
+\r
+    <appender name="network"\r
+        class="org.onap.policy.drools.controller.logging.ControllerLoggingTest$NetworkAppender" />\r
+    <logger name="test-controller" level="INFO">\r
+        <appender-ref ref="network" />\r
+    </logger>\r
+\r
+    <root level="INFO">\r
+        <appender-ref ref="STDOUT" />\r
+    </root>\r
+\r
+</configuration>
\ No newline at end of file
diff --git a/feature-controller-logging/src/test/resources/test.drl b/feature-controller-logging/src/test/resources/test.drl
new file mode 100755 (executable)
index 0000000..dcae7fa
--- /dev/null
@@ -0,0 +1,35 @@
+/*-\r
+ * ============LICENSE_START=======================================================\r
+ * feature-controller-logging\r
+ * ================================================================================\r
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.\r
+ * ================================================================================\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ * ============LICENSE_END=========================================================\r
+ */\r
+\r
+package org.onap.policy.drools.test;\r
+\r
+rule "INIT"\r
+when\r
+then\r
+    insert("This is a test");\r
+end\r
+\r
+rule "PRINT_MSG"\r
+when\r
+    $o : Object();\r
+then\r
+    System.out.println("MSG: " + $o);\r
+    retract($o);\r
+end\r
diff --git a/feature-controller-logging/src/test/resources/test.pom b/feature-controller-logging/src/test/resources/test.pom
new file mode 100755 (executable)
index 0000000..2226b9f
--- /dev/null
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!--\r
+  ============LICENSE_START=======================================================\r
+  feature-controller-logging\r
+  ================================================================================\r
+  Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.\r
+  ================================================================================\r
+  Licensed under the Apache License, Version 2.0 (the "License");\r
+  you may not use this file except in compliance with the License.\r
+  You may obtain a copy of the License at\r
+\r
+       http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+  Unless required by applicable law or agreed to in writing, software\r
+  distributed under the License is distributed on an "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+  See the License for the specific language governing permissions and\r
+  limitations under the License.\r
+  ============LICENSE_END=========================================================\r
+  -->\r
+\r
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">\r
+\r
+    <modelVersion>4.0.0</modelVersion>\r
+\r
+    <groupId>org.onap.policy.drools.test</groupId>\r
+    <artifactId>test</artifactId>\r
+    <version>1.4.0-SNAPSHOT</version>\r
+\r
+</project>\r
index 4dafd45..90b7f45 100644 (file)
@@ -2,7 +2,7 @@
   ============LICENSE_START=======================================================
   feature-eelf
   ================================================================================
-  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.
index 809c9e7..e603fb6 100644 (file)
             <version>${project.version}</version>
             <type>zip</type>
         </dependency>
+        <dependency>
+            <groupId>org.onap.policy.drools-pdp</groupId>
+            <artifactId>feature-controller-logging</artifactId>
+            <version>${project.version}</version>
+            <type>zip</type>
+        </dependency>
        </dependencies>
 
 </project>
index 6a4b8f2..eb401eb 100644 (file)
@@ -7,9 +7,9 @@
  * 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.
@@ -54,7 +54,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
- * Maven-based Drools Controller that interacts with the 
+ * Maven-based Drools Controller that interacts with the
  * policy-core PolicyContainer and PolicySession to manage
  * Drools containers instantiated using Maven.
  */
@@ -73,7 +73,7 @@ public class MavenDroolsController implements DroolsController {
     protected final PolicyContainer policyContainer;
 
     /**
-     * alive status of this drools controller, 
+     * alive status of this drools controller,
      * reflects invocation of start()/stop() only.
      */
     protected volatile boolean alive = false;
@@ -82,7 +82,7 @@ public class MavenDroolsController implements DroolsController {
      * locked status of this drools controller,
      * reflects if i/o drools related operations are permitted,
      * more specifically: offer() and deliver().
-     * It does not affect the ability to start and stop 
+     * It does not affect the ability to start and stop
      * underlying drools infrastructure
      */
     protected volatile boolean locked = false;
@@ -116,17 +116,17 @@ public class MavenDroolsController implements DroolsController {
 
     /**
      * Expanded version of the constructor.
-     * 
+     *
      * @param groupId maven group id
      * @param artifactId maven artifact id
      * @param version maven version
      * @param decoderConfigurations list of topic -> decoders -> filters mapping
      * @param encoderConfigurations list of topic -> encoders -> filters mapping
-     * 
+     *
      * @throws IllegalArgumentException invalid arguments passed in
      */
-    public MavenDroolsController(String groupId, 
-            String artifactId, 
+    public MavenDroolsController(String groupId,
+            String artifactId,
             String version,
             List<TopicCoderFilterConfiguration> decoderConfigurations,
             List<TopicCoderFilterConfiguration> encoderConfigurations) {
@@ -153,7 +153,7 @@ public class MavenDroolsController implements DroolsController {
 
     /**
      * init encoding/decoding configuration.
-     * 
+     *
      * @param decoderConfigurations list of topic -> decoders -> filters mapping
      * @param encoderConfigurations list of topic -> encoders -> filters mapping
      */
@@ -172,7 +172,7 @@ public class MavenDroolsController implements DroolsController {
     @Override
     public void updateToVersion(String newGroupId, String newArtifactId, String newVersion,
             List<TopicCoderFilterConfiguration> decoderConfigurations,
-            List<TopicCoderFilterConfiguration> encoderConfigurations) 
+            List<TopicCoderFilterConfiguration> encoderConfigurations)
                     throws LinkageError {
 
         logger.info("updating version -> [{}:{}:{}]", newGroupId, newArtifactId, newVersion);
@@ -189,27 +189,27 @@ public class MavenDroolsController implements DroolsController {
             throw new IllegalArgumentException("Missing maven version coordinate");
         }
 
-        if (newGroupId.equalsIgnoreCase(DroolsController.NO_GROUP_ID) 
-                || newArtifactId.equalsIgnoreCase(DroolsController.NO_ARTIFACT_ID) 
+        if (newGroupId.equalsIgnoreCase(DroolsController.NO_GROUP_ID)
+                || newArtifactId.equalsIgnoreCase(DroolsController.NO_ARTIFACT_ID)
                 || newVersion.equalsIgnoreCase(DroolsController.NO_VERSION)) {
-            throw new IllegalArgumentException("BRAINLESS maven coordinates provided: " 
-                    + newGroupId + ":" + newArtifactId + ":" 
+            throw new IllegalArgumentException("BRAINLESS maven coordinates provided: "
+                    + newGroupId + ":" + newArtifactId + ":"
                     + newVersion);
         }
 
         if (newGroupId.equalsIgnoreCase(this.getGroupId())
                 && newArtifactId.equalsIgnoreCase(this.getArtifactId())
                 && newVersion.equalsIgnoreCase(this.getVersion())) {
-            logger.warn("Al in the right version: " + newGroupId + ":" 
+            logger.warn("Al in the right version: " + newGroupId + ":"
                     + newArtifactId + ":" +  newVersion + " vs. " + this);
             return;
         }
 
-        if (!newGroupId.equalsIgnoreCase(this.getGroupId()) 
+        if (!newGroupId.equalsIgnoreCase(this.getGroupId())
                 || !newArtifactId.equalsIgnoreCase(this.getArtifactId())) {
             throw new IllegalArgumentException(
-                    "Group ID and Artifact ID maven coordinates must be identical for the upgrade: " 
-                    + newGroupId + ":" + newArtifactId + ":" 
+                    "Group ID and Artifact ID maven coordinates must be identical for the upgrade: "
+                    + newGroupId + ":" + newArtifactId + ":"
                     + newVersion + " vs. " + this);
         }
 
@@ -238,10 +238,10 @@ public class MavenDroolsController implements DroolsController {
      * initialize decoders for all the topics supported by this controller
      * Note this is critical to be done after the Policy Container is
      * instantiated to be able to fetch the corresponding classes.
-     * 
+     *
      * @param coderConfigurations list of topic -> decoders -> filters mapping
      */
-    protected void initCoders(List<TopicCoderFilterConfiguration> coderConfigurations, 
+    protected void initCoders(List<TopicCoderFilterConfiguration> coderConfigurations,
             boolean decoder) {
 
         if (logger.isInfoEnabled()) {
@@ -257,7 +257,7 @@ public class MavenDroolsController implements DroolsController {
             String topic = coderConfig.getTopic();
 
             CustomGsonCoder customGsonCoder = coderConfig.getCustomGsonCoder();
-            if (coderConfig.getCustomGsonCoder() != null 
+            if (coderConfig.getCustomGsonCoder() != null
                     && coderConfig.getCustomGsonCoder().getClassContainer() != null
                     && !coderConfig.getCustomGsonCoder().getClassContainer().isEmpty()) {
 
@@ -281,7 +281,7 @@ public class MavenDroolsController implements DroolsController {
                 String potentialCodedClass = coderFilter.getCodedClass();
                 JsonProtocolFilter protocolFilter = coderFilter.getFilter();
 
-                if (!ReflectionUtil.isClass(this.policyContainer.getClassLoader(), 
+                if (!ReflectionUtil.isClass(this.policyContainer.getClassLoader(),
                         potentialCodedClass)) {
                     throw makeRetrieveEx(potentialCodedClass);
                 } else {
@@ -378,7 +378,7 @@ public class MavenDroolsController implements DroolsController {
 
         if (modelHash == this.modelClassLoaderHash) {
             if (logger.isInfoEnabled()) {
-                logger.info(coderClass.getCanonicalName() 
+                logger.info(coderClass.getCanonicalName()
                         + this + " class loader matches original drools controller rules classloader "
                         + coderClass.getClassLoader());
             }
@@ -386,7 +386,7 @@ public class MavenDroolsController implements DroolsController {
         } else {
             if (logger.isWarnEnabled()) {
                 logger.warn(this + coderClass.getCanonicalName() + " class loaders don't match  "
-                        + coderClass.getClassLoader() + " vs " 
+                        + coderClass.getClassLoader() + " vs "
                         + this.policyContainer.getClassLoader());
             }
             return false;
@@ -498,11 +498,11 @@ public class MavenDroolsController implements DroolsController {
 
         // 1. Now, check if this topic has a decoder:
 
-        if (!EventProtocolCoder.manager.isDecodingSupported(this.getGroupId(), 
-                this.getArtifactId(), 
+        if (!EventProtocolCoder.manager.isDecodingSupported(this.getGroupId(),
+                this.getArtifactId(),
                 topic)) {
 
-            logger.warn("{}: DECODING-UNSUPPORTED {}:{}:{}", this, 
+            logger.warn("{}: DECODING-UNSUPPORTED {}:{}:{}", this,
                     topic, this.getGroupId(), this.getArtifactId());
             return true;
         }
@@ -511,16 +511,16 @@ public class MavenDroolsController implements DroolsController {
 
         Object anEvent;
         try {
-            anEvent = EventProtocolCoder.manager.decode(this.getGroupId(), 
-                    this.getArtifactId(), 
-                    topic, 
+            anEvent = EventProtocolCoder.manager.decode(this.getGroupId(),
+                    this.getArtifactId(),
+                    topic,
                     event);
         } catch (UnsupportedOperationException uoe) {
-            logger.debug("{}: DECODE FAILED: {} <- {} because of {}", this, topic, 
+            logger.debug("{}: DECODE FAILED: {} <- {} because of {}", this, topic,
                     event, uoe.getMessage(), uoe);
             return true;
         } catch (Exception e) {
-            logger.warn("{}: DECODE FAILED: {} <- {} because of {}", this, topic, 
+            logger.warn("{}: DECODE FAILED: {} <- {} because of {}", this, topic,
                     event, e.getMessage(), e);
             return true;
         }
@@ -530,12 +530,12 @@ public class MavenDroolsController implements DroolsController {
         }
 
         // increment event count for Nagios monitoring
-        PdpJmx.getInstance().updateOccured();  
+        PdpJmx.getInstance().updateOccured();
 
         // Broadcast
 
         if (logger.isInfoEnabled()) {
-            logger.info("{} BROADCAST-INJECT of {} FROM {} INTO {}", 
+            logger.info("{} BROADCAST-INJECT of {} FROM {} INTO {}",
                     this, event, topic, this.policyContainer.getName());
         }
 
@@ -575,7 +575,19 @@ public class MavenDroolsController implements DroolsController {
         if (logger.isInfoEnabled()) {
             logger.info("{}DELIVER: {} FROM {} TO {}", this, event, this, sink);
         }
-        
+
+        for (DroolsControllerFeatureAPI feature : DroolsControllerFeatureAPI.providers.getList()) {
+            try {
+                if (feature.beforeDeliver(this, sink, event)) {
+                    return true;
+                }
+            }
+            catch (Exception e) {
+                logger.error("{}: feature {} before-deliver failure because of {}", this, feature.getClass().getName(),
+                        e.getMessage(), e);
+            }
+        }
+
         if (sink == null) {
             throw new IllegalArgumentException(this +  " invalid sink");
         }
@@ -583,7 +595,7 @@ public class MavenDroolsController implements DroolsController {
         if (event == null) {
             throw new IllegalArgumentException(this +  " invalid event");
         }
-        
+
         if (this.locked) {
             throw new IllegalStateException(this +  " is locked");
         }
@@ -599,7 +611,21 @@ public class MavenDroolsController implements DroolsController {
             this.recentSinkEvents.add(json);
         }
 
-        return sink.send(json);
+        boolean success = sink.send(json);
+
+        for (DroolsControllerFeatureAPI feature : DroolsControllerFeatureAPI.providers.getList()) {
+            try {
+                if (feature.afterDeliver(this, sink, event, json, success)) {
+                    return true;
+                }
+            }
+            catch (Exception e) {
+                logger.error("{}: feature {} after-deliver failure because of {}", this, feature.getClass().getName(),
+                        e.getMessage(), e);
+            }
+        }
+
+        return success;
 
     }
 
@@ -620,7 +646,7 @@ public class MavenDroolsController implements DroolsController {
 
     /**
      * Get model class loader hash.
-     * 
+     *
      * @return the modelClassLoaderHash
      */
     public int getModelClassLoaderHash() {
@@ -664,7 +690,7 @@ public class MavenDroolsController implements DroolsController {
 
     /**
      * get session names.
-     * 
+     *
      * @param abbreviated true for the short form, otherwise the long form
      * @return session names
      */
@@ -699,7 +725,7 @@ public class MavenDroolsController implements DroolsController {
 
     /**
      * provides the underlying core layer container sessions.
-     * 
+     *
      * @return the attached Policy Container
      */
     protected List<PolicySession> getSessions() {
@@ -710,7 +736,7 @@ public class MavenDroolsController implements DroolsController {
 
     /**
      * provides the underlying core layer container session with name sessionName.
-     * 
+     *
      * @param sessionName session name
      * @return the attached Policy Container
      * @throws IllegalArgumentException when an invalid session name is provided
@@ -783,7 +809,7 @@ public class MavenDroolsController implements DroolsController {
             throw new IllegalArgumentException("Invalid Class Name: " + className);
         }
 
-        Class<?> factClass = 
+        Class<?> factClass =
                 ReflectionUtil.fetchClass(this.policyContainer.getClassLoader(), className);
         if (factClass == null) {
             throw new IllegalArgumentException("Class cannot be fetched in model's classloader: " + className);
@@ -810,7 +836,7 @@ public class MavenDroolsController implements DroolsController {
     }
 
     @Override
-    public List<Object> factQuery(String sessionName, String queryName, String queriedEntity, 
+    public List<Object> factQuery(String sessionName, String queryName, String queriedEntity,
             boolean delete, Object... queryParams) {
         if (sessionName == null || sessionName.isEmpty()) {
             throw invalidSessNameEx(sessionName);
@@ -864,7 +890,7 @@ public class MavenDroolsController implements DroolsController {
 
     /**
      * Get recent source events.
-     * 
+     *
      * @return the recentSourceEvents
      */
     @Override
@@ -877,7 +903,7 @@ public class MavenDroolsController implements DroolsController {
 
     /**
      * Get recent sink events.
-     * 
+     *
      * @return the recentSinkEvents
      */
     @Override
index 135e1c5..d8663f1 100644 (file)
@@ -2,14 +2,14 @@
  * ============LICENSE_START=======================================================
  * ONAP
  * ================================================================================
- * Copyright (C) 2018 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2018-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.
@@ -20,6 +20,7 @@
 
 package org.onap.policy.drools.features;
 
+import org.onap.policy.common.endpoints.event.comm.TopicSink;
 import org.onap.policy.drools.controller.DroolsController;
 import org.onap.policy.drools.utils.OrderedService;
 import org.onap.policy.drools.utils.OrderedServiceImpl;
@@ -52,6 +53,28 @@ public interface DroolsControllerFeatureAPI extends OrderedService {
         return false;
     }
 
+    /**
+     * Intercept before the Drools 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 boolean beforeDeliver(DroolsController controller, TopicSink sink, Object fact) {
+        return false;
+    }
+
+    /**
+     * Called after the Drools 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 boolean afterDeliver(DroolsController controller, TopicSink sink, Object fact, String json,
+                    boolean success) {
+        return false;
+    }
+
     /**
      * Feature providers implementing this interface.
      */
index c86f6e0..a877211 100644 (file)
@@ -2,14 +2,14 @@
  * ============LICENSE_START=======================================================
  * policy-engine
  * ================================================================================
- * 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.
  * 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.
@@ -21,7 +21,8 @@
 package org.onap.policy.drools.features;
 
 import java.util.Properties;
-
+import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure;
+import org.onap.policy.drools.protocol.configuration.PdpdConfiguration;
 import org.onap.policy.drools.system.PolicyEngine;
 import org.onap.policy.drools.utils.OrderedService;
 import org.onap.policy.drools.utils.OrderedServiceImpl;
@@ -34,14 +35,14 @@ public interface PolicyEngineFeatureAPI extends OrderedService {
     /**
      * Feature providers implementing this interface.
      */
-    public static final OrderedServiceImpl<PolicyEngineFeatureAPI> providers = 
+    public static final OrderedServiceImpl<PolicyEngineFeatureAPI> providers =
             new OrderedServiceImpl<>(PolicyEngineFeatureAPI.class);
 
     /**
      * intercept before the Policy Engine is commanded to boot.
-     * 
+     *
      * @return true if this feature intercepts and takes ownership
-     *     of the operation preventing the invocation of 
+     *     of the operation preventing the invocation of
      *     lower priority features.   False, otherwise.
      */
     public default boolean beforeBoot(PolicyEngine engine, String[] cliArgs) {
@@ -50,9 +51,9 @@ public interface PolicyEngineFeatureAPI extends OrderedService {
 
     /**
      * intercept after the Policy Engine is booted.
-     * 
+     *
      * @return true if this feature intercepts and takes ownership
-     *     of the operation preventing the invocation of 
+     *     of the operation preventing the invocation of
      *     lower priority features.   False, otherwise.
      */
     public default boolean afterBoot(PolicyEngine engine) {
@@ -61,9 +62,9 @@ public interface PolicyEngineFeatureAPI extends OrderedService {
 
     /**
      * intercept before the Policy Engine is configured.
-     * 
+     *
      * @return true if this feature intercepts and takes ownership
-     *     of the operation preventing the invocation of 
+     *     of the operation preventing the invocation of
      *     lower priority features.   False, otherwise.
      */
     public default boolean beforeConfigure(PolicyEngine engine, Properties properties) {
@@ -72,9 +73,9 @@ public interface PolicyEngineFeatureAPI extends OrderedService {
 
     /**
      * intercept after the Policy Engine is configured.
-     * 
+     *
      * @return true if this feature intercepts and takes ownership
-     *     of the operation preventing the invocation of 
+     *     of the operation preventing the invocation of
      *     lower priority features.   False, otherwise.
      */
     public default boolean afterConfigure(PolicyEngine engine) {
@@ -83,9 +84,9 @@ public interface PolicyEngineFeatureAPI extends OrderedService {
 
     /**
      * intercept before the Policy Engine goes active.
-     * 
+     *
      * @return true if this feature intercepts and takes ownership
-     *     of the operation preventing the invocation of 
+     *     of the operation preventing the invocation of
      *     lower priority features.   False, otherwise.
      */
     public default boolean beforeActivate(PolicyEngine engine) {
@@ -94,9 +95,9 @@ public interface PolicyEngineFeatureAPI extends OrderedService {
 
     /**
      * intercept after the Policy Engine goes active.
-     * 
+     *
      * @return true if this feature intercepts and takes ownership
-     *     of the operation preventing the invocation of 
+     *     of the operation preventing the invocation of
      *     lower priority features.   False, otherwise.
      */
     public default boolean afterActivate(PolicyEngine engine) {
@@ -105,9 +106,9 @@ public interface PolicyEngineFeatureAPI extends OrderedService {
 
     /**
      * intercept before the Policy Engine goes standby.
-     * 
+     *
      * @return true if this feature intercepts and takes ownership
-     *     of the operation preventing the invocation of 
+     *     of the operation preventing the invocation of
      *     lower priority features.   False, otherwise.
      */
     public default boolean beforeDeactivate(PolicyEngine engine) {
@@ -116,9 +117,9 @@ public interface PolicyEngineFeatureAPI extends OrderedService {
 
     /**
      * intercept after the Policy Engine goes standby.
-     * 
+     *
      * @return true if this feature intercepts and takes ownership
-     *     of the operation preventing the invocation of 
+     *     of the operation preventing the invocation of
      *     lower priority features.   False, otherwise.
      */
     public default boolean afterDeactivate(PolicyEngine engine) {
@@ -127,9 +128,9 @@ public interface PolicyEngineFeatureAPI extends OrderedService {
 
     /**
      * intercept before the Policy Engine is started.
-     * 
+     *
      * @return true if this feature intercepts and takes ownership
-     *     of the operation preventing the invocation of 
+     *     of the operation preventing the invocation of
      *     lower priority features.   False, otherwise.
      */
     public default boolean beforeStart(PolicyEngine engine) {
@@ -138,9 +139,9 @@ public interface PolicyEngineFeatureAPI extends OrderedService {
 
     /**
      * intercept after the Policy Engine is started.
-     * 
+     *
      * @return true if this feature intercepts and takes ownership
-     *     of the operation preventing the invocation of 
+     *     of the operation preventing the invocation of
      *     lower priority features.   False, otherwise.
      */
     public default boolean afterStart(PolicyEngine engine) {
@@ -149,9 +150,9 @@ public interface PolicyEngineFeatureAPI extends OrderedService {
 
     /**
      * intercept before the Policy Engine is stopped.
-     * 
+     *
      * @return true if this feature intercepts and takes ownership
-     *     of the operation preventing the invocation of 
+     *     of the operation preventing the invocation of
      *     lower priority features.   False, otherwise..
      */
     public default boolean beforeStop(PolicyEngine engine) {
@@ -160,9 +161,9 @@ public interface PolicyEngineFeatureAPI extends OrderedService {
 
     /**
      * intercept after the Policy Engine is stopped.
-     * 
+     *
      * @return true if this feature intercepts and takes ownership
-     *     of the operation preventing the invocation of 
+     *     of the operation preventing the invocation of
      *     lower priority features.   False, otherwise.d.
      */
     public default boolean afterStop(PolicyEngine engine) {
@@ -171,9 +172,9 @@ public interface PolicyEngineFeatureAPI extends OrderedService {
 
     /**
      * intercept before the Policy Engine is locked.
-     * 
+     *
      * @return true if this feature intercepts and takes ownership
-     *     of the operation preventing the invocation of 
+     *     of the operation preventing the invocation of
      *     lower priority features.   False, otherwise.
      */
     public default boolean beforeLock(PolicyEngine engine) {
@@ -182,9 +183,9 @@ public interface PolicyEngineFeatureAPI extends OrderedService {
 
     /**
      * intercept after the Policy Engine is locked.
-     * 
+     *
      * @return true if this feature intercepts and takes ownership
-     *     of the operation preventing the invocation of 
+     *     of the operation preventing the invocation of
      *     lower priority features.   False, otherwise..
      */
     public default boolean afterLock(PolicyEngine engine) {
@@ -193,9 +194,9 @@ public interface PolicyEngineFeatureAPI extends OrderedService {
 
     /**
      * intercept before the Policy Engine is locked.
-     * 
+     *
      * @return true if this feature intercepts and takes ownership
-     *     of the operation preventing the invocation of 
+     *     of the operation preventing the invocation of
      *     lower priority features.   False, otherwise.
      */
     public default boolean beforeUnlock(PolicyEngine engine) {
@@ -204,9 +205,9 @@ public interface PolicyEngineFeatureAPI extends OrderedService {
 
     /**
      * intercept after the Policy Engine is locked.
-     * 
+     *
      * @return true if this feature intercepts and takes ownership
-     *     of the operation preventing the invocation of 
+     *     of the operation preventing the invocation of
      *     lower priority features.   False, otherwise.
      */
     public default boolean afterUnlock(PolicyEngine engine) {
@@ -215,9 +216,9 @@ public interface PolicyEngineFeatureAPI extends OrderedService {
 
     /**
      * intercept the Policy Engine is shut down.
-     * 
+     *
      * @return true if this feature intercepts and takes ownership
-     *     of the operation preventing the invocation of 
+     *     of the operation preventing the invocation of
      *     lower priority features.   False, otherwise..
      */
     public default boolean beforeShutdown(PolicyEngine engine) {
@@ -226,12 +227,34 @@ public interface PolicyEngineFeatureAPI extends OrderedService {
 
     /**
      * called after the Policy Engine is shut down.
-     * 
+     *
      * @return true if this feature intercepts and takes ownership
-     *     of the operation preventing the invocation of 
+     *     of the operation preventing the invocation of
      *     lower priority features.   False, otherwise.
      */
     public default boolean afterShutdown(PolicyEngine engine) {
         return false;
     }
+
+    /**
+     * Intercept an event from UEB/DMaaP before the PolicyEngine processes it.
+     *
+     * @return True if this feature intercepts and takes ownership of the operation
+     *         preventing the invocation of lower priority features. False, otherwise.
+     */
+    public default boolean beforeOnTopicEvent(PolicyEngine engine, CommInfrastructure commType, String topic,
+                    String event) {
+        return false;
+    }
+
+    /**
+     * Called after the PolicyEngine processes the events.
+     *
+     * @return True if this feature intercepts and takes ownership of the operation
+     *         preventing the invocation of lower priority features. False, otherwise
+     */
+    public default boolean afterOnTopicEvent(PolicyEngine engine, PdpdConfiguration configuration,
+                    CommInfrastructure commType, String topic, String event) {
+        return false;
+    }
 }
index 959114a..740a119 100644 (file)
@@ -695,7 +695,7 @@ class PolicyEngineManager implements PolicyEngine {
                     throw new IllegalArgumentException(controllerName + " is invalid");
                 }
 
-                logger.warn("controller being recovered. {} Reset controller's bad maven coordinates to brainless", 
+                logger.warn("controller being recovered. {} Reset controller's bad maven coordinates to brainless",
                         controllerName);
 
                 /*
@@ -918,7 +918,7 @@ class PolicyEngineManager implements PolicyEngine {
                 logger.error("{}: cannot start http-server {} because of {}", this, httpServer, e.getMessage(), e);
             }
         }
-        
+
         // stop JMX?
 
         /* policy-engine dispatch pre stop hook */
@@ -1003,7 +1003,7 @@ class PolicyEngineManager implements PolicyEngine {
         exitThread.interrupt();
         logger.info("{}: normal termination", this);
     }
-    
+
     /**
      * Thread that shuts down http servers.
      */
@@ -1038,13 +1038,13 @@ class PolicyEngineManager implements PolicyEngine {
                 doExit(0);
             }
         }
-        
+
         // these may be overridden by junit tests
 
         protected void doSleep(long sleepMs) throws InterruptedException {
             Thread.sleep(sleepMs);
         }
-        
+
         protected void doExit(int code) {
             System.exit(code);
         }
@@ -1245,13 +1245,38 @@ class PolicyEngineManager implements PolicyEngine {
 
     @Override
     public void onTopicEvent(CommInfrastructure commType, String topic, String event) {
+        /* policy-engine pre topic event hook */
+        for (final PolicyEngineFeatureAPI feature : getFeatureProviders()) {
+            try {
+                if (feature.beforeOnTopicEvent(this, commType, topic, event)) {
+                    return;
+                }
+            } catch (final Exception e) {
+                logger.error("{}: feature {} beforeOnTopicEvent failure on event {} because of {}", this,
+                        feature.getClass().getName(), event, e.getMessage(), e);
+            }
+        }
+
         /* configuration request */
+        PdpdConfiguration configuration = null;
         try {
-            final PdpdConfiguration configuration = this.decoder.fromJson(event, PdpdConfiguration.class);
+            configuration = this.decoder.fromJson(event, PdpdConfiguration.class);
             this.configure(configuration);
         } catch (final Exception e) {
             logger.error("{}: configuration-error due to {} because of {}", this, event, e.getMessage(), e);
         }
+
+        /* policy-engine after topic event hook */
+        for (final PolicyEngineFeatureAPI feature : getFeatureProviders()) {
+            try {
+                if (feature.afterOnTopicEvent(this, configuration, commType, topic, event)) {
+                    return;
+                }
+            } catch (final Exception e) {
+                logger.error("{}: feature {} afterOnTopicEvent failure on event {} because of {}", this,
+                        feature.getClass().getName(), event, e.getMessage(), e);
+            }
+        }
     }
 
     @Override
index 538fcf8..4fb8276 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.
@@ -19,7 +19,7 @@
   -->
 
 <configuration scan="true" scanPeriod="30 seconds" debug="false">
-
+    
        <property name="logDir" value="${POLICY_LOGS}" />
 
        <property name="errorLog" value="error" />
diff --git a/pom.xml b/pom.xml
index ff9cdb7..c2733c8 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -80,6 +80,7 @@
         <module>feature-active-standby-management</module>
         <module>feature-simulators</module>
         <module>feature-distributed-locking</module>
+        <module>feature-controller-logging</module>
         <module>packages</module>
     </modules>