summaryrefslogtreecommitdiffstats
path: root/controlloop
diff options
context:
space:
mode:
authorJorge Hernandez <jh1730@att.com>2017-09-14 01:55:30 -0500
committerJorge Hernandez <jh1730@att.com>2017-09-14 15:00:40 -0500
commit403fe412004ffded378c71df3f17b022a6518442 (patch)
tree44dffde62e6461d3d758a86b6d07748916f37e77 /controlloop
parent0f7e3fb817487b85a4200eb39a5755888c5ad04b (diff)
master lab template maintained under archetype
This is work in progress, the official pom.xml with dependencies, drl template, and support files for controller deployment are maintained here. In the near future the junit template should be consolidated with this one. Added controlloop.properties.environment, this environment file will be populated at installation time with the lab's aai url, etc .. and will be accessible by any drools application such as control loops through the PolicyEngine interface. Note that PDP-D server already supports these environment files, so it is just natural. Therefore, this is the default mechanism to provide to applications, the url, username, and passwords to use at runtime by the control loops for the time being. In the future MSB could set them globally here through existing APIs, or it can be queried by any drools application using MSB library, doesn't matter. There's been some trouble playing nicely with the dependencies used by a control loop application classsloader, and the pdp-d middleware one, causing issues between dependencies version of libraries. Specifically, the snakeyaml library does not play well across classloader when using constructor functionality, note that the snakeyaml libraries are pulled also from jackson parsers used in the pdp-d. I made a change in ControlLoopProcessor to specifically tell the "Yaml" object which classloader to use in order to find the class with the constructor that is intended to be built, otherwise, yaml libraries use a different classloader that does not have visibility into the ControlLoopPolicy that is trying to construct, and fails. This also should respect junits that use the same classloader I pressume and does not give issues. Change-Id: I36271d29cdbf8ff861f9c03ff91cf7116927906a Issue-ID: POLICY-162 Signed-off-by: Jorge Hernandez <jh1730@att.com>
Diffstat (limited to 'controlloop')
-rw-r--r--controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/processor/ControlLoopProcessor.java162
-rw-r--r--controlloop/common/guard/pom.xml7
-rw-r--r--controlloop/packages/basex/src/files/config/controlloop.properties.environment35
-rw-r--r--controlloop/templates/archetype-cl-amsterdam/pom.xml56
-rw-r--r--controlloop/templates/archetype-cl-amsterdam/src/main/resources/META-INF/maven/archetype-metadata.xml78
-rw-r--r--controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/pom.xml139
-rw-r--r--controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/config/__artifactId__-controller.properties55
-rw-r--r--controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/config/__artifactId__-controller.rest.json29
-rw-r--r--controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/config/dcae.onset.json15
-rw-r--r--controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/config/vCPE.yaml23
-rw-r--r--controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/resources/META-INF/kmodule.xml29
-rw-r--r--controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/resources/__closedLoopControlName__.drl1134
-rw-r--r--controlloop/templates/archetype-cl-amsterdam/src/test/resources/projects/basic/archetype.properties43
-rw-r--r--controlloop/templates/pom.xml1
-rw-r--r--controlloop/templates/template.demo.v1.0.0/archetype-cl-legacy/src/main/resources/archetype-resources/pom.xml3
-rw-r--r--controlloop/templates/template.demo.v1.0.0/archetype-cl-legacy/src/main/resources/archetype-resources/src/main/resources/META-INF/kmodule.xml2
-rw-r--r--controlloop/templates/template.demo.v1.0.0/archetype-cl-legacy/src/test/resources/projects/basic/goal.txt0
17 files changed, 1721 insertions, 90 deletions
diff --git a/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/processor/ControlLoopProcessor.java b/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/processor/ControlLoopProcessor.java
index b6fad23d9..f2c565d9a 100644
--- a/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/processor/ControlLoopProcessor.java
+++ b/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/processor/ControlLoopProcessor.java
@@ -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.
@@ -20,91 +20,91 @@
package org.onap.policy.controlloop.processor;
-import org.yaml.snakeyaml.Yaml;
-import org.yaml.snakeyaml.constructor.Constructor;
-
import org.onap.policy.controlloop.ControlLoopException;
import org.onap.policy.controlloop.policy.ControlLoop;
import org.onap.policy.controlloop.policy.ControlLoopPolicy;
import org.onap.policy.controlloop.policy.FinalResult;
import org.onap.policy.controlloop.policy.Policy;
import org.onap.policy.controlloop.policy.PolicyResult;
+import org.yaml.snakeyaml.Yaml;
+import org.yaml.snakeyaml.constructor.CustomClassLoaderConstructor;
public class ControlLoopProcessor {
-
- private final String yaml;
- private final ControlLoopPolicy policy;
- private String currentPolicy = null;
-
- public ControlLoopProcessor(String yaml) throws ControlLoopException {
- this.yaml = yaml;
- try {
- Yaml y = new Yaml(new Constructor(ControlLoopPolicy.class));
- Object obj = y.load(this.yaml);
- if (obj instanceof ControlLoopPolicy) {
- this.policy = (ControlLoopPolicy) obj;
- this.currentPolicy = this.policy.getControlLoop().getTrigger_policy();
- } else {
- this.policy = null;
- throw new ControlLoopException("Unable to parse yaml into ControlLoopPolicy object");
- }
- } catch (Exception e) {
- //
- // Most likely this is a YAML Exception
- //
- throw new ControlLoopException(e);
- }
- }
-
- public ControlLoop getControlLoop() {
- return this.policy.getControlLoop();
- }
-
- public FinalResult checkIsCurrentPolicyFinal() {
- return FinalResult.toResult(this.currentPolicy);
- }
-
- public Policy getCurrentPolicy() {
- for (Policy policy : this.policy.getPolicies()) {
- if (policy.getId().equals(this.currentPolicy)) {
- return policy;
- }
- }
- return null;
- }
-
- public void nextPolicyForResult(PolicyResult result) throws ControlLoopException {
- Policy policy = this.getCurrentPolicy();
- try {
- if (this.policy == null) {
- throw new ControlLoopException("There is no current policy to determine where to go to.");
- }
- switch (result) {
- case SUCCESS:
- this.currentPolicy = policy.getSuccess();
- break;
- case FAILURE:
- this.currentPolicy = policy.getFailure();
- break;
- case FAILURE_TIMEOUT:
- this.currentPolicy = policy.getFailure_timeout();
- break;
- case FAILURE_RETRIES:
- this.currentPolicy = policy.getFailure_retries();
- break;
- case FAILURE_EXCEPTION:
- this.currentPolicy = policy.getFailure_exception();
- break;
- case FAILURE_GUARD:
- this.currentPolicy = policy.getFailure_guard();
- break;
- default:
- throw new ControlLoopException("Bad policy result given: " + result);
- }
- } catch (ControlLoopException e) {
- this.currentPolicy = FinalResult.FINAL_FAILURE_EXCEPTION.toString();
- throw e;
- }
- }
-
+
+ private final String yaml;
+ private final ControlLoopPolicy policy;
+ private String currentPolicy = null;
+
+ public ControlLoopProcessor(String yaml) throws ControlLoopException {
+ this.yaml = yaml;
+ try {
+ final Yaml y = new Yaml(new CustomClassLoaderConstructor(ControlLoopPolicy.class,
+ ControlLoopPolicy.class.getClassLoader()));
+ final Object obj = y.load(this.yaml);
+ if (obj instanceof ControlLoopPolicy) {
+ this.policy = (ControlLoopPolicy) obj;
+ this.currentPolicy = this.policy.getControlLoop().getTrigger_policy();
+ } else {
+ this.policy = null;
+ throw new ControlLoopException("Unable to parse yaml into ControlLoopPolicy object");
+ }
+ } catch (final Exception e) {
+ //
+ // Most likely this is a YAML Exception
+ //
+ throw new ControlLoopException(e);
+ }
+ }
+
+ public ControlLoop getControlLoop() {
+ return this.policy.getControlLoop();
+ }
+
+ public FinalResult checkIsCurrentPolicyFinal() {
+ return FinalResult.toResult(this.currentPolicy);
+ }
+
+ public Policy getCurrentPolicy() {
+ for (final Policy policy : this.policy.getPolicies()) {
+ if (policy.getId().equals(this.currentPolicy)) {
+ return policy;
+ }
+ }
+ return null;
+ }
+
+ public void nextPolicyForResult(PolicyResult result) throws ControlLoopException {
+ final Policy policy = this.getCurrentPolicy();
+ try {
+ if (this.policy == null) {
+ throw new ControlLoopException("There is no current policy to determine where to go to.");
+ }
+ switch (result) {
+ case SUCCESS:
+ this.currentPolicy = policy.getSuccess();
+ break;
+ case FAILURE:
+ this.currentPolicy = policy.getFailure();
+ break;
+ case FAILURE_TIMEOUT:
+ this.currentPolicy = policy.getFailure_timeout();
+ break;
+ case FAILURE_RETRIES:
+ this.currentPolicy = policy.getFailure_retries();
+ break;
+ case FAILURE_EXCEPTION:
+ this.currentPolicy = policy.getFailure_exception();
+ break;
+ case FAILURE_GUARD:
+ this.currentPolicy = policy.getFailure_guard();
+ break;
+ default:
+ throw new ControlLoopException("Bad policy result given: " + result);
+ }
+ } catch (final ControlLoopException e) {
+ this.currentPolicy = FinalResult.FINAL_FAILURE_EXCEPTION.toString();
+ throw e;
+ }
+ }
+
}
diff --git a/controlloop/common/guard/pom.xml b/controlloop/common/guard/pom.xml
index 2b173c36c..e0283589a 100644
--- a/controlloop/common/guard/pom.xml
+++ b/controlloop/common/guard/pom.xml
@@ -13,17 +13,10 @@
<version>1.1.0-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
- <dependency>
- <groupId>com.att.research.xacml</groupId>
- <artifactId>xacml</artifactId>
- <version>1.0.0</version>
- <scope>provided</scope>
- </dependency>
<dependency>
<groupId>com.att.research.xacml</groupId>
<artifactId>xacml-pdp</artifactId>
<version>1.0.0</version>
- <scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
diff --git a/controlloop/packages/basex/src/files/config/controlloop.properties.environment b/controlloop/packages/basex/src/files/config/controlloop.properties.environment
new file mode 100644
index 000000000..c77746f84
--- /dev/null
+++ b/controlloop/packages/basex/src/files/config/controlloop.properties.environment
@@ -0,0 +1,35 @@
+###
+# ============LICENSE_START=======================================================
+# ONAP APPS Base Package
+# ================================================================================
+# Copyright (C) 2017 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=========================================================
+###
+
+# Environment file (.environment) for control loop applications in this
+# directory, it will be automatically loaded by PDP-D, after being expanded
+# by installation scripts.
+
+aai.url=${{AAI_URL}}
+aai.username=${{AAI_USERNAME}}
+aai.password=${{AAI_PASSWORD}}
+
+mso.url=${{MSO_URL}}
+mso.username=${{MSO_USERNAME}}
+mso.password=${{MSO_PASSWORD}}
+
+vfc.url=${{VFC_URL}}
+vfc.username=${{VFC_USERNAME}}
+vfc.password=${{VFC_PASSWORD}} \ No newline at end of file
diff --git a/controlloop/templates/archetype-cl-amsterdam/pom.xml b/controlloop/templates/archetype-cl-amsterdam/pom.xml
new file mode 100644
index 000000000..2f810e299
--- /dev/null
+++ b/controlloop/templates/archetype-cl-amsterdam/pom.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ============LICENSE_START=======================================================
+ ONAP
+ ================================================================================
+ Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ ================================================================================
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ============LICENSE_END=========================================================
+ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.onap.policy.drools-applications</groupId>
+ <artifactId>templates</artifactId>
+ <version>1.1.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>archetype-cl-amsterdam</artifactId>
+ <packaging>maven-archetype</packaging>
+
+ <name>archetype-cl-amsterdam</name>
+ <description>Archetype to generate a yaml based control loop for ONAP Amsterdam release</description>
+
+ <build>
+ <extensions>
+ <extension>
+ <groupId>org.apache.maven.archetype</groupId>
+ <artifactId>archetype-packaging</artifactId>
+ <version>3.0.1</version>
+ </extension>
+ </extensions>
+
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <artifactId>maven-archetype-plugin</artifactId>
+ <version>3.0.1</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+</project>
diff --git a/controlloop/templates/archetype-cl-amsterdam/src/main/resources/META-INF/maven/archetype-metadata.xml b/controlloop/templates/archetype-cl-amsterdam/src/main/resources/META-INF/maven/archetype-metadata.xml
new file mode 100644
index 000000000..dfe7e72cf
--- /dev/null
+++ b/controlloop/templates/archetype-cl-amsterdam/src/main/resources/META-INF/maven/archetype-metadata.xml
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ============LICENSE_START=======================================================
+ archetype-closed-loop-demo-rules
+ ================================================================================
+ Copyright (C) 2017 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=========================================================
+ -->
+
+<archetype-descriptor xsi:schemaLocation="http://maven.apache.org/plugins/maven-archetype-plugin/archetype-descriptor/1.0.0 http://maven.apache.org/xsd/archetype-descriptor-1.0.0.xsd"
+ name="closed-loop-rules"
+ xmlns="http://maven.apache.org/plugins/maven-archetype-plugin/archetype-descriptor/1.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+
+ <requiredProperties>
+ <requiredProperty key="closedLoopControlName">
+ <defaultValue>ControlLoop-vCPE-48f0c2c3-a172-4192-9ae3-052274181b6e</defaultValue>
+ </requiredProperty>
+ <requiredProperty key="controlLoopYaml">
+ <defaultValue>controlLoop%3A%0A++version%3A+2.0.0%0A++controlLoopName%3A+ControlLoop-vCPE-48f0c2c3-a172-4192-9ae3-052274181b6e%0A++trigger_policy%3A+unique-policy-id-1-restart%0A++timeout%3A+3600%0A+%0Apolicies%3A%0A+%0A++-+id%3A+unique-policy-id-1-restart%0A++++name%3A+Restart+the+VM%0A++++description%3A%0A++++actor%3A+APPC%0A++++recipe%3A+Restart%0A++++target%3A%0A++++++type%3A+VM%0A++++retry%3A+3%0A++++timeout%3A+1200%0A++++success%3A+final_success%0A++++failure%3A+final_failure%0A++++failure_timeout%3A+final_failure_timeout%0A++++failure_retries%3A+final_failure_retries%0A++++failure_exception%3A+final_failure_exception%0A++++failure_guard%3A</defaultValue>
+ </requiredProperty>
+ <requiredProperty key="policyName">
+ <defaultValue>DCAE.Config_tca-hi-lo</defaultValue>
+ </requiredProperty>
+ <requiredProperty key="policyScope">
+ <defaultValue>DCAE</defaultValue>
+ </requiredProperty>
+ <requiredProperty key="policyVersion">
+ <defaultValue>1.1.0</defaultValue>
+ </requiredProperty>
+ <requiredProperty key="dmaapServers">
+ <defaultValue>vm1.mr.simpledemo.openecomp.org</defaultValue>
+ </requiredProperty>
+ <requiredProperty key="dcaeTopic">
+ <defaultValue>unauthenticated.TCA_EVENT_OUTPUT</defaultValue>
+ </requiredProperty>
+ <requiredProperty key="dcaeServers">
+ <defaultValue>10.0.4.102</defaultValue>
+ </requiredProperty>
+ <requiredProperty key="dependenciesVersion">
+ <defaultValue>1.1.0</defaultValue>
+ </requiredProperty>
+ </requiredProperties>
+
+ <fileSets>
+ <fileSet filtered="true" encoding="UTF-8">
+ <directory>src/main/resources</directory>
+ <includes>
+ <include>**/*.xml</include>
+ </includes>
+ </fileSet>
+ <fileSet filtered="true" encoding="UTF-8">
+ <directory>src/main/resources</directory>
+ <includes>
+ <include>**/*.drl</include>
+ </includes>
+ </fileSet>
+ <fileSet filtered="true" encoding="UTF-8">
+ <directory>src/main/config</directory>
+ <includes>
+ <include>**/*.properties</include>
+ <include>**/*.json</include>
+ </includes>
+ </fileSet>
+ </fileSets>
+</archetype-descriptor>
diff --git a/controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/pom.xml b/controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/pom.xml
new file mode 100644
index 000000000..74d79f4a4
--- /dev/null
+++ b/controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/pom.xml
@@ -0,0 +1,139 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ============LICENSE_START=======================================================
+ ONAP
+ ================================================================================
+ Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ ================================================================================
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ============LICENSE_END=========================================================
+ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>${groupId}</groupId>
+ <artifactId>${artifactId}</artifactId>
+ <version>${version}</version>
+ <packaging>kjar</packaging>
+
+ <name>${artifactId}</name>
+ <description>Control Loop Amsterdam Release Rules</description>
+
+ <properties>
+ <maven.compiler.source>1.8</maven.compiler.source>
+ <maven.compiler.target>1.8</maven.compiler.target>
+ </properties>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.kie</groupId>
+ <artifactId>kie-maven-plugin</artifactId>
+ <version>6.5.0.Final</version>
+ <extensions>true</extensions>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.onap.policy.drools-applications</groupId>
+ <artifactId>events</artifactId>
+ <version>${dependenciesVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.policy.drools-applications</groupId>
+ <artifactId>appc</artifactId>
+ <version>${dependenciesVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.policy.drools-applications</groupId>
+ <artifactId>appclcm</artifactId>
+ <version>${dependenciesVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.policy.drools-applications</groupId>
+ <artifactId>vfc</artifactId>
+ <version>${dependenciesVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.policy.drools-applications</groupId>
+ <artifactId>mso</artifactId>
+ <version>${dependenciesVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.policy.drools-applications</groupId>
+ <artifactId>aai</artifactId>
+ <version>${dependenciesVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.policy.drools-applications</groupId>
+ <artifactId>sdc</artifactId>
+ <version>${dependenciesVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.policy.drools-applications</groupId>
+ <artifactId>trafficgenerator</artifactId>
+ <version>${dependenciesVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.policy.drools-applications</groupId>
+ <artifactId>eventmanager</artifactId>
+ <version>${dependenciesVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.policy.drools-applications</groupId>
+ <artifactId>guard</artifactId>
+ <version>${dependenciesVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.policy.drools-applications</groupId>
+ <artifactId>actorServiceProvider</artifactId>
+ <version>${dependenciesVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.policy.drools-applications</groupId>
+ <artifactId>actor.appc</artifactId>
+ <version>${dependenciesVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.policy.drools-applications</groupId>
+ <artifactId>actor.appclcm</artifactId>
+ <version>${dependenciesVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.policy.drools-applications</groupId>
+ <artifactId>actor.mso</artifactId>
+ <version>${dependenciesVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.policy.drools-applications</groupId>
+ <artifactId>actor.vfc</artifactId>
+ <version>${dependenciesVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.policy.drools-applications</groupId>
+ <artifactId>policy-yaml</artifactId>
+ <version>${dependenciesVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.policy.drools-pdp</groupId>
+ <artifactId>policy-management</artifactId>
+ <version>${dependenciesVersion}</version>
+ <scope>provided</scope>
+ <optional>true</optional>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/config/__artifactId__-controller.properties b/controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/config/__artifactId__-controller.properties
new file mode 100644
index 000000000..ddc70d784
--- /dev/null
+++ b/controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/config/__artifactId__-controller.properties
@@ -0,0 +1,55 @@
+###
+# ============LICENSE_START=======================================================
+# archetype-closed-loop-demo-rules
+# ================================================================================
+# Copyright (C) 2017 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=========================================================
+###
+
+controller.name=${artifactId}
+
+ueb.source.topics=${dcaeTopic},APPC-CL
+
+ueb.source.topics.${dcaeTopic}.servers=${dcaeServers}
+ueb.source.topics.${dcaeTopic}.apiKey=
+ueb.source.topics.${dcaeTopic}.apiSecret=
+ueb.source.topics.${dcaeTopic}.events=org.onap.policy.controlloop.VirtualControlLoopEvent
+ueb.source.topics.${dcaeTopic}.events.org.onap.policy.controlloop.VirtualControlLoopEvent.filter=closedLoopEventStatus=.*
+ueb.source.topics.${dcaeTopic}.events.custom.gson=org.onap.policy.controlloop.util.Serialization,gson
+
+ueb.source.topics.APPC-CL.servers=${dmaapServers}
+ueb.source.topics.APPC-CL.apiKey=
+ueb.source.topics.APPC-CL.apiSecret=
+ueb.source.topics.APPC-CL.events=org.onap.policy.appclcm.LCMResponseWrapper
+ueb.source.topics.APPC-CL.events.org.onap.policy.appclcm.LCMResponseWrapper.filter=body\=.*
+ueb.source.topics.APPC-CL.events.custom.gson=org.onap.policy.appclcm.util.Serialization,gson
+
+ueb.sink.topics=APPC-CL,POLICY-CL-MGT
+
+ueb.sink.topics.APPC-CL.servers=${dmaapServers}
+ueb.sink.topics.APPC-CL.apiKey=
+ueb.sink.topics.APPC-CL.apiSecret=
+ueb.sink.topics.APPC-CL.events=org.onap.policy.appclcm.LCMRequestWrapper
+ueb.sink.topics.APPC-CL.events.custom.gson=org.onap.policy.appclcm.util.Serialization,gson
+
+ueb.sink.topics.POLICY-CL-MGT.servers=${dmaapServers}
+ueb.sink.topics.POLICY-CL-MGT.apiKey=
+ueb.sink.topics.POLICY-CL-MGT.apiSecret=
+ueb.sink.topics.POLICY-CL-MGT.events=org.onap.policy.controlloop.VirtualControlLoopNotification
+ueb.sink.topics.POLICY-CL-MGT.events.custom.gson=org.onap.policy.controlloop.util.Serialization,gsonPretty
+
+rules.groupId=${groupId}
+rules.artifactId=${artifactId}
+rules.version=${version}
diff --git a/controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/config/__artifactId__-controller.rest.json b/controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/config/__artifactId__-controller.rest.json
new file mode 100644
index 000000000..68d565dcd
--- /dev/null
+++ b/controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/config/__artifactId__-controller.rest.json
@@ -0,0 +1,29 @@
+{
+ "controller.name": "${artifactId}",
+
+ "ueb.source.topics": "${dcaeTopic},APPC-CL",
+
+ "ueb.source.topics.${dcaeTopic}.servers": "${dcaeServers}",
+ "ueb.source.topics.${dcaeTopic}.events": "org.onap.policy.controlloop.VirtualControlLoopEvent",
+ "ueb.source.topics.${dcaeTopic}.events.org.onap.policy.controlloop.VirtualControlLoopEvent.filter": "closedLoopEventStatus=.*",
+ "ueb.source.topics.${dcaeTopic}.events.custom.gson": "org.onap.policy.controlloop.util.Serialization,gson",
+
+ "ueb.source.topics.APPC-CL.servers": "${dmaapServers}",
+ "ueb.source.topics.APPC-CL.events": "org.onap.policy.appclcm.LCMResponseWrapper",
+ "ueb.source.topics.APPC-CL.events.org.onap.policy.appclcm.LCMResponseWrapper.filter": "common-header=.*,status=.*",
+ "ueb.source.topics.APPC-CL.events.custom.gson": "org.onap.policy.appclcm.util.Serialization,gson",
+
+ "ueb.sink.topics": "APPC-CL,POLICY-CL-MGT",
+
+ "ueb.sink.topics.APPC-CL.servers": "${dmaapServers}",
+ "ueb.sink.topics.APPC-CL.events": "org.onap.policy.appclcm.LCMRequestWrapper",
+ "ueb.sink.topics.APPC-CL.events.custom.gson": "org.onap.policy.appclcm.util.Serialization,gson",
+
+ "ueb.sink.topics.POLICY-CL-MGT.servers": "${dmaapServers}",
+ "ueb.sink.topics.POLICY-CL-MGT.events": "org.onap.policy.controlloop.VirtualControlLoopNotification",
+ "ueb.sink.topics.POLICY-CL-MGT.events.custom.gson": "org.onap.policy.controlloop.util.Serialization,gson",
+
+ "rules.groupId": "${groupId}",
+ "rules.artifactId": "${artifactId}",
+ "rules.version": "${version}"
+}
diff --git a/controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/config/dcae.onset.json b/controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/config/dcae.onset.json
new file mode 100644
index 000000000..edb1e27e5
--- /dev/null
+++ b/controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/config/dcae.onset.json
@@ -0,0 +1,15 @@
+{
+ "closedLoopControlName": "${closedLoopControlName}",
+ "closedLoopAlarmStart": 1463679805324,
+ "closedLoopEventClient": "microservice.stringmatcher",
+ "closedLoopEventStatus": "ONSET",
+ "requestID": "664be3d2-6c12-4f4b-a3e7-c349acced200",
+ "target_type": "VNF",
+ "target": "generic-vnf.vnf-id",
+ "AAI": {
+ "vserver.is-closed-loop-disabled": "false",
+ "generic-vnf.vnf-id": "fw0001vm001fw001"
+ },
+ "from": "DCAE",
+ "version": "1.0.2"
+}
diff --git a/controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/config/vCPE.yaml b/controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/config/vCPE.yaml
new file mode 100644
index 000000000..abe02c6a9
--- /dev/null
+++ b/controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/config/vCPE.yaml
@@ -0,0 +1,23 @@
+controlLoop:
+ version: 2.0.0
+ controlLoopName: ${closedLoopControlName}
+ trigger_policy: unique-policy-id-1-restart
+ timeout: 3600
+ abatement: true
+
+policies:
+ - id: unique-policy-id-1-restart
+ name: Restart the VM
+ description:
+ actor: APPC
+ recipe: Restart
+ target:
+ type: VM
+ retry: 3
+ timeout: 1200
+ success: final_success
+ failure: final_failure
+ failure_timeout: final_failure_timeout
+ failure_retries: final_failure_retries
+ failure_exception: final_failure_exception
+ failure_guard: final_failure_guard \ No newline at end of file
diff --git a/controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/resources/META-INF/kmodule.xml b/controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/resources/META-INF/kmodule.xml
new file mode 100644
index 000000000..9ec524b0e
--- /dev/null
+++ b/controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/resources/META-INF/kmodule.xml
@@ -0,0 +1,29 @@
+#set( $symbol_pound = '#' )
+#set( $symbol_dollar = '$' )
+#set( $symbol_escape = '\' )
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ============LICENSE_START=======================================================
+ archetype-closed-loop-demo-rules
+ ================================================================================
+ Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ ================================================================================
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ============LICENSE_END=========================================================
+ -->
+
+<kmodule xmlns="http://jboss.org/kie/6.0.0/kmodule">
+ <kbase name="rules">
+ <ksession name="amsterdam"/>
+ </kbase>
+</kmodule>
diff --git a/controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/resources/__closedLoopControlName__.drl b/controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/resources/__closedLoopControlName__.drl
new file mode 100644
index 000000000..9cf395d72
--- /dev/null
+++ b/controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/resources/__closedLoopControlName__.drl
@@ -0,0 +1,1134 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP
+ * ================================================================================
+ * Copyright (C) 2017 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.controlloop;
+
+import org.onap.policy.controlloop.VirtualControlLoopEvent;
+import org.onap.policy.controlloop.VirtualControlLoopNotification;
+import org.onap.policy.controlloop.ControlLoopEventStatus;
+import org.onap.policy.controlloop.ControlLoopNotificationType;
+import org.onap.policy.controlloop.ControlLoopLogger;
+import org.onap.policy.controlloop.policy.PolicyResult;
+import org.onap.policy.controlloop.policy.ControlLoopPolicy;
+import org.onap.policy.controlloop.policy.Policy;
+import org.onap.policy.controlloop.eventmanager.ControlLoopEventManager;
+import org.onap.policy.controlloop.eventmanager.ControlLoopEventManager.NEW_EVENT_STATUS;
+import org.onap.policy.controlloop.eventmanager.ControlLoopOperationManager;
+import org.onap.policy.controlloop.actor.mso.MSOActorServiceProvider;
+import org.onap.policy.appc.Request;
+import org.onap.policy.appc.Response;
+import org.onap.policy.appc.CommonHeader;
+import org.onap.policy.appclcm.LCMRequestWrapper;
+import org.onap.policy.appclcm.LCMResponseWrapper;
+import org.onap.policy.appclcm.LCMRequest;
+import org.onap.policy.appclcm.LCMResponse;
+import org.onap.policy.appclcm.LCMCommonHeader;
+import org.onap.policy.vfc.VFCRequest;
+import org.onap.policy.vfc.VFCManager;
+import org.onap.policy.mso.SOManager;
+import org.onap.policy.mso.SORequest;
+import org.onap.policy.mso.SORequestStatus;
+import org.onap.policy.mso.SORequestDetails;
+import org.onap.policy.mso.SOModelInfo;
+import org.onap.policy.mso.SOCloudConfiguration;
+import org.onap.policy.mso.SORequestInfo;
+import org.onap.policy.mso.SORequestParameters;
+import org.onap.policy.mso.SORelatedInstanceListElement;
+import org.onap.policy.mso.SORelatedInstance;
+import org.onap.policy.mso.SOResponse;
+import org.onap.policy.guard.PolicyGuard;
+import org.onap.policy.guard.PolicyGuard.LockResult;
+import org.onap.policy.guard.TargetLock;
+import org.onap.policy.guard.GuardResult;
+import org.onap.policy.guard.PolicyGuardRequest;
+import org.onap.policy.guard.PolicyGuardResponse;
+import org.onap.policy.guard.PolicyGuardXacmlRequestAttributes;
+import org.onap.policy.guard.PolicyGuardXacmlHelper;
+
+import org.yaml.snakeyaml.Yaml;
+import org.yaml.snakeyaml.constructor.Constructor;
+
+import org.slf4j.LoggerFactory;
+import org.slf4j.Logger;
+
+import java.time.Instant;
+import java.util.LinkedList;
+import java.util.Iterator;
+
+import org.onap.policy.drools.system.PolicyEngine;
+
+declare Params
+ closedLoopControlName : String
+ controlLoopYaml : String
+end
+
+
+declare OperationTimer
+ closedLoopControlName : String
+ requestID : String
+ delay : String
+end
+
+declare ControlLoopTimer
+ closedLoopControlName : String
+ requestID : String
+ delay : String
+end
+
+/*
+*
+* Called once and only once to insert the parameters into working memory for this Closed Loop policy.
+*
+*/
+rule "${policyName}.SETUP"
+ when
+ then
+
+ Params params = new Params();
+ params.setClosedLoopControlName("${closedLoopControlName}");
+ params.setControlLoopYaml("${controlLoopYaml}");
+ insert(params);
+
+
+ // Note: globals have bad behavior when persistence is used,
+ // hence explicitly getting the logger vs using a global
+
+ Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
+ logger.info("{}: {} : YAML=[{}]", params.getClosedLoopControlName(), drools.getRule().getName(), params.getControlLoopYaml());
+end
+
+/*
+*
+* This rule responds to DCAE Events where there is no manager yet. Either it is
+* the first ONSET, or a subsequent badly formed Event (i.e. Syntax error, or is-closed-loop-disabled)
+*
+*/
+rule "${policyName}.EVENT"
+ when
+ $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" )
+ $event : VirtualControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName() )
+ not ( ControlLoopEventManager( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID ) )
+ then
+
+ Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
+ logger.info("{}: {}", $params.getClosedLoopControlName(), drools.getRule().getName());
+
+ try {
+
+ //
+ // Check the event, because we need it to not be null when
+ // we create the ControlLoopEventManager. The ControlLoopEventManager
+ // will do extra syntax checking as well check if the closed loop is disabled.
+ //
+ if ($event.requestID == null) {
+ VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
+ notification.notification = ControlLoopNotificationType.REJECTED;
+ notification.from = "policy";
+ notification.message = "Missing requestID";
+ notification.policyName = drools.getRule().getName();
+ notification.policyScope = "${policyScope}";
+ notification.policyVersion = "${policyVersion}";
+
+ //
+ // Let interested parties know
+ //
+ PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
+
+ //
+ // Retract it from memory
+ //
+ retract($event);
+ } else {
+ //
+ // Create an EventManager
+ //
+ ControlLoopEventManager manager = new ControlLoopEventManager($params.getClosedLoopControlName(), $event.requestID);
+ //
+ // Determine if EventManager can actively process the event (i.e. syntax, is_closed_loop_disabled checks etc.)
+ //
+ VirtualControlLoopNotification notification = manager.activate($params.getControlLoopYaml(), $event);
+ notification.from = "pdp-0001-controller=controlloop"; // Engine.getInstanceName()
+ notification.policyName = drools.getRule().getName();
+ notification.policyScope = "${policyScope}";
+ notification.policyVersion = "${policyVersion}";
+ //
+ // Are we actively pursuing this event?
+ //
+ if (notification.notification == ControlLoopNotificationType.ACTIVE) {
+ //
+ // Insert Event Manager into memory, this will now kick off processing.
+ //
+ insert(manager);
+ //
+ // Let interested parties know
+ //
+ PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
+ //
+ // Setup the Overall Control Loop timer
+ //
+ ControlLoopTimer clTimer = new ControlLoopTimer();
+ clTimer.setClosedLoopControlName($event.closedLoopControlName);
+ clTimer.setRequestID($event.requestID.toString());
+ clTimer.setDelay(manager.getControlLoopTimeout(1500) + "s");
+ //
+ // Insert it
+ //
+ insert(clTimer);
+ } else {
+ //
+ // Let interested parties know
+ //
+ PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
+ //
+ // Retract it from memory
+ //
+ retract($event);
+ }
+
+ //
+ // Now that the manager is inserted into Drools working memory, we'll wait for
+ // another rule to fire in order to continue processing. This way we can also
+ // then screen for additional ONSET and ABATED events for this RequestID.
+ //
+ }
+ } catch (Exception e) {
+ logger.warn("{}: {}", $params.getClosedLoopControlName(), drools.getRule().getName(), e);
+
+ VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
+ notification.notification = ControlLoopNotificationType.REJECTED;
+ notification.message = "Exception occurred " + e.getMessage();
+ notification.policyName = drools.getRule().getName();
+ notification.policyScope = "${policyScope}";
+ notification.policyVersion = "${policyVersion}";
+ //
+ //
+ //
+ PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
+ //
+ // Retract the event
+ //
+ retract($event);
+ }
+end
+
+/*
+*
+* This rule happens when we got a valid ONSET, closed loop is enabled and an Event Manager
+* is now created. We can start processing the yaml specification via the Event Manager.
+*
+*/
+rule "${policyName}.EVENT.MANAGER"
+ when
+ $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" )
+ $event : VirtualControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName() )
+ $manager : ControlLoopEventManager( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID )
+ $clTimer : ControlLoopTimer ( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID.toString() )
+ then
+
+ Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
+ logger.info("{}: {}: event={} manager={} clTimer={}",
+ $params.getClosedLoopControlName(), drools.getRule().getName(),
+ $event, $manager, $clTimer);
+ //
+ // Check which event this is.
+ //
+ ControlLoopEventManager.NEW_EVENT_STATUS eventStatus = $manager.onNewEvent($event);
+
+ //
+ // Check what kind of event this is
+ //
+ if (eventStatus == NEW_EVENT_STATUS.SUBSEQUENT_ONSET) {
+ //
+ // We don't care about subsequent onsets
+ //
+ logger.info("{}: {}: subsequent onset",
+ $params.getClosedLoopControlName(), drools.getRule().getName());
+ retract($event);
+ return;
+ }
+ if (eventStatus == NEW_EVENT_STATUS.SYNTAX_ERROR) {
+ //
+ // Ignore any bad syntax events
+ //
+ logger.warn("{}: {}: syntax error",
+ $params.getClosedLoopControlName(), drools.getRule().getName());
+ retract($event);
+ return;
+ }
+ //
+ // We only want the initial ONSET event in memory,
+ // all the other events need to be retracted to support
+ // cleanup and avoid the other rules being fired for this event.
+ //
+ if (eventStatus != NEW_EVENT_STATUS.FIRST_ONSET) {
+ logger.warn("{}: {}: no first onset",
+ $params.getClosedLoopControlName(), drools.getRule().getName());
+ retract($event);
+ }
+
+ logger.debug("{}: {}: target={}", $params.getClosedLoopControlName(),
+ drools.getRule().getName(), $event.target);
+ //
+ // Now start seeing if we need to process this event
+ //
+ try {
+ //
+ // Check if this is a Final Event
+ //
+ VirtualControlLoopNotification notification = $manager.isControlLoopFinal();
+
+
+ if (notification != null) {
+ //
+ // Its final, but are we waiting for abatement?
+ //
+ if ($manager.getNumAbatements() > 0) {
+ logger.info("{}: {}: abatement received for {}. Closing the control loop",
+ $params.getClosedLoopControlName(), drools.getRule().getName(),
+ $event.requestID);
+ notification.from = "policy";
+ notification.policyName = drools.getRule().getName();
+ notification.policyScope = "${policyScope}";
+ notification.policyVersion = "${policyVersion}";
+ //
+ // In this case, we are done
+ //
+ PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
+ //
+ // Unlock the target
+ //
+ TargetLock lock = $manager.unlockCurrentOperation();
+ if (lock != null) {
+ logger.debug("{}: {}: retracting lock=", $params.getClosedLoopControlName(),
+ drools.getRule().getName(), lock);
+ retract(lock);
+ }
+ //
+ // Retract everything from memory
+ //
+ logger.info("{}: {}: retracting onset, manager, and timer",
+ $params.getClosedLoopControlName(), drools.getRule().getName());
+
+ retract($manager.getOnsetEvent());
+ retract($manager);
+ retract($clTimer);
+ //
+ // TODO - what if we get subsequent Events for this RequestID?
+ // By default, it will all start over again. May be confusing for Ruby.
+ // Or, we could track this and then subsequently ignore the events
+ //
+ } else {
+ //
+ // Check whether we need to wait for abatement
+ //
+ if ($manager.getProcessor().getControlLoop().getAbatement() == true && notification.notification == ControlLoopNotificationType.FINAL_SUCCESS) {
+ logger.info("{}: {}: waiting for abatement ..",
+ $params.getClosedLoopControlName(), drools.getRule().getName());
+ } else {
+ logger.info("{}: {}: no abatement expect for {}. Closing the control loop",
+ $params.getClosedLoopControlName(), drools.getRule().getName(),
+ $event.requestID);
+
+ notification.from = "policy";
+ notification.policyName = drools.getRule().getName();
+ notification.policyScope = "${policyScope}";
+ notification.policyVersion = "${policyVersion}";
+
+ //
+ // In this case, we are done
+ //
+ PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
+ //
+ // Unlock the target
+ //
+ TargetLock lock = $manager.unlockCurrentOperation();
+ if (lock != null) {
+ logger.debug("{}: {}: retracting lock=", $params.getClosedLoopControlName(),
+ drools.getRule().getName(), lock);
+ retract(lock);
+ }
+ //
+ // Retract everything from memory
+ //
+ logger.info("{}: {}: retracting onset, manager, and timer",
+ $params.getClosedLoopControlName(), drools.getRule().getName());
+
+ retract($manager.getOnsetEvent());
+ retract($manager);
+ retract($clTimer);
+ }
+ }
+ } else {
+ //
+ // NOT final, so let's ask for the next operation
+ //
+ ControlLoopOperationManager operation = $manager.processControlLoop();
+ if (operation != null) {
+ logger.info("{}: {}: starting operation={}",
+ $params.getClosedLoopControlName(), drools.getRule().getName(),
+ operation);
+ //
+ // insert into memory
+ //
+ insert(operation);
+ //
+ // insert operation timeout object
+ //
+ OperationTimer opTimer = new OperationTimer();
+ opTimer.setClosedLoopControlName($event.closedLoopControlName);
+ opTimer.setRequestID($event.requestID.toString());
+ opTimer.setDelay(operation.getOperationTimeout().toString() + "s");
+ insert(opTimer);
+
+ //
+ // Let's ask for a lock right away
+ //
+ LockResult<GuardResult, TargetLock> result = $manager.lockCurrentOperation();
+ if (result.getA().equals(GuardResult.LOCK_ACQUIRED)) {
+ logger.info("{}: {}: guard lock acquired={}",
+ $params.getClosedLoopControlName(), drools.getRule().getName(),
+ result.getB());
+
+ //
+ // Insert into memory
+ //
+ insert(result.getB());
+ }
+ } else {
+ //
+ // Probably waiting for abatement
+ //
+ logger.info("{}: {}: no operation, probably waiting for abatement",
+ $params.getClosedLoopControlName(), drools.getRule().getName());
+ }
+ }
+ } catch (Exception e) {
+ logger.warn("{}: {}: unexpected",
+ $params.getClosedLoopControlName(),
+ drools.getRule().getName(), e);
+
+ //
+ // TODO should we abort if we get an exception?
+ //
+ }
+
+end
+
+
+
+/*
+*
+*
+*
+*/
+rule "${policyName}.EVENT.MANAGER.OPERATION.NOT_LOCKED.TIMEOUT"
+ timer (int: 5s 5s)
+ when
+ $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" )
+ $event : VirtualControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName() )
+ $manager : ControlLoopEventManager( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID )
+ $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.closedLoopControlName, onset.requestID == $event.requestID )
+ not ( TargetLock (requestID == $event.requestID) )
+ then
+
+ Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
+ logger.info("{}: {}: event={} manager={} operation={}",
+ $params.getClosedLoopControlName(), drools.getRule().getName(),
+ $event, $manager, $operation);
+
+ //
+ // Need to ask for a Lock
+ //
+ LockResult<GuardResult, TargetLock> result = $manager.lockCurrentOperation();
+ if (result.getA().equals(GuardResult.LOCK_ACQUIRED)) {
+ logger.info("{}: {}: guard lock acquired={}",
+ $params.getClosedLoopControlName(), drools.getRule().getName(),
+ result.getB());
+
+ //
+ // Insert into memory
+ //
+ insert(result.getB());
+ }
+
+end
+
+/*
+*
+* Guard Permitted, let's send request to the actor.
+*
+*/
+rule "${policyName}.EVENT.MANAGER.OPERATION.LOCKED.GUARD_PERMITTED"
+ when
+ $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" )
+ $event : VirtualControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName() )
+ $manager : ControlLoopEventManager( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID )
+ $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.closedLoopControlName, onset.requestID == $event.requestID, getGuardApprovalStatus() == "Permit" )
+ $lock : TargetLock (requestID == $event.requestID)
+ then
+
+ Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
+ logger.info("{}: {}: event={} manager={} operation={} lock={}",
+ $params.getClosedLoopControlName(), drools.getRule().getName(),
+ $event, $manager, $operation, $lock);
+
+ Object request = $operation.getOperationRequest();
+
+ if (request != null) {
+ logger.debug("{}: {}: starting operation ..",
+ $params.getClosedLoopControlName(), drools.getRule().getName());
+ //
+ // Tell interested parties we are performing this Operation
+ //
+ VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
+ notification.notification = ControlLoopNotificationType.OPERATION;
+ notification.message = $operation.getOperationMessage();
+ notification.history = $operation.getHistory();
+ notification.from = "policy";
+ notification.policyName = drools.getRule().getName();
+ notification.policyScope = "${policyScope}";
+ notification.policyVersion = "${policyVersion}";
+
+ PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
+
+ switch ($operation.policy.getActor()){
+
+ case "APPC":
+
+ if (request instanceof Request || request instanceof LCMRequestWrapper) {
+ PolicyEngine.manager.deliver("APPC-CL", request);
+ }
+ break;
+ case "SO":
+ // at this point the AAI named query request should have already been made, the response recieved and used
+ // in the construction of the SO Request which is stored in operationRequest
+
+ if(request instanceof SORequest) {
+ // Call SO. The response will be inserted into memory once it's received
+ MSOActorServiceProvider.sendRequest(drools.getWorkingMemory(), request);
+ }
+ break;
+ case "VFC":
+ if (request instanceof VFCRequest) {
+ // Start VFC thread
+ VFCManager vfcManager = new VFCManager((VFCRequest) request);
+ vfcManager.setVFCParams(
+ PolicyEngine.manager.getEnvironmentProperty("vfc.url"),
+ PolicyEngine.manager.getEnvironmentProperty("vfc.user"),
+ PolicyEngine.manager.getEnvironmentProperty("vfc.password"));
+
+ Thread t = new Thread(vfcManager);
+ t.start();
+ }
+ break;
+ }
+ } else {
+ //
+ // What happens if its null?
+ //
+ logger.warn("{}: {}: unexpected null operation request",
+ $params.getClosedLoopControlName(),
+ drools.getRule().getName());
+ }
+end
+
+
+/*
+*
+* We were able to acquire a lock so now let's ask Xacml Guard whether
+* we are allowed to proceed with the request to the actor.
+*
+*/
+rule "${policyName}.EVENT.MANAGER.OPERATION.LOCKED.GUARD_NOT_YET_QUERIED"
+ when
+ $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" )
+ $event : VirtualControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName() )
+ $manager : ControlLoopEventManager( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID )
+ $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.closedLoopControlName, onset.requestID == $event.requestID, getGuardApprovalStatus() == "NONE" )
+ $lock : TargetLock (requestID == $event.requestID)
+ then
+
+ Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
+ logger.info("{}: {}: event={} manager={} operation={} lock={}",
+ $params.getClosedLoopControlName(), drools.getRule().getName(),
+ $event, $manager, $operation, $lock);
+
+ //
+ // We are starting the operation but the actor won't be contacted until Guard is queried and permitted.
+ //
+ $operation.startOperation($event);
+
+ //
+ // Sending notification that we are about to query Guard ("DB write - start operation")
+ //
+ VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
+ notification.notification = ControlLoopNotificationType.OPERATION;
+ notification.message = $operation.getOperationMessage();
+ notification.history = $operation.getHistory();
+ notification.from = "policy";
+ notification.policyName = drools.getRule().getName();
+ notification.policyScope = "${policyScope}";
+ notification.policyVersion = "${policyVersion}";
+
+ PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
+
+ //
+ // Now send Guard Request to XACML Guard. In order to bypass the call to Guard,
+ // just change guardEnabled to false.
+ //
+ // In order to use REST XACML, provide a URL instead of "" as a second argument
+ // to the CallGuardTask() and set the first argument to null
+ // (instead of XacmlPdpEngine).
+ //
+ boolean guardEnabled = false;
+
+ if(guardEnabled){
+
+ Thread t = new Thread(new org.onap.policy.guard.CallGuardTask(
+ null,
+ PolicyEngine.manager.getEnvironmentProperty("guard.url"),
+ drools.getWorkingMemory(),
+ $event.closedLoopControlName,
+ $operation.policy.getActor().toString(),
+ $operation.policy.getRecipe(),
+ $manager.getTargetInstance($operation.policy),
+ //$event.target,
+ $event.requestID.toString()
+ ));
+ t.start();
+ }
+ else{
+ insert(new PolicyGuardResponse("Permit", $event.requestID, $operation.policy.getRecipe()));
+ }
+
+end
+
+//
+// This rule will be triggered when a thread talking to the XACML Guard inserts a
+// guardResponse object into the working memory
+//
+rule "${policyName}.GUARD.RESPONSE"
+ when
+ $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" )
+ $event : VirtualControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName(), closedLoopEventStatus == ControlLoopEventStatus.ONSET )
+ $manager : ControlLoopEventManager( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID )
+ $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.closedLoopControlName, onset.requestID == $event.requestID )
+ $lock : TargetLock (requestID == $event.requestID)
+ $opTimer : OperationTimer( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID.toString() )
+ $guardResponse : PolicyGuardResponse(requestID == $event.requestID, $operation.policy.recipe == operation)
+ then
+
+ Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
+ logger.info("{}: {}: event={} manager={} operation={} lock={} opTimer={} guardResponse={}",
+ $params.getClosedLoopControlName(), drools.getRule().getName(),
+ $event, $manager, $operation, $lock, $opTimer, $guardResponse);
+
+
+ //we will permit the operation if there was no Guard for it
+ if($guardResponse.result == "Indeterminate"){
+ $guardResponse.result = "Permit";
+ }
+
+ //
+ // This notification has Guard result in "message". ("DB write - end operation in case of Guard Deny")
+ //
+ VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
+ notification.notification = ControlLoopNotificationType.OPERATION;
+ notification.message = $operation.getOperationMessage($guardResponse.result);
+ notification.history = $operation.getHistory();
+ notification.from = "policy";
+ notification.policyName = drools.getRule().getName();
+ notification.policyScope = "${policyScope}";
+ notification.policyVersion = "${policyVersion}";
+
+ PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
+
+ if($guardResponse.result == "Permit"){
+
+ modify($operation){setGuardApprovalStatus($guardResponse.result)};
+ }
+ else {
+ //This is the Deny case
+ $operation.setOperationHasGuardDeny();
+ retract($opTimer);
+ retract($operation);
+ modify($manager) {finishOperation($operation)};
+ }
+
+ retract($guardResponse);
+
+end
+
+/*
+*
+* This rule responds to APPC Response Events
+*
+* I would have like to be consistent and write the Response like this:
+* $response : Response( CommonHeader.RequestID == $onset.requestID )
+*
+* However, no compile error was given. But a runtime error was given. I think
+* because drools is confused between the classname CommonHeader vs the property CommonHeader.
+*
+*/
+rule "${policyName}.APPC.RESPONSE"
+ when
+ $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" )
+ $event : VirtualControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName(), closedLoopEventStatus == ControlLoopEventStatus.ONSET )
+ $manager : ControlLoopEventManager( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID )
+ $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.closedLoopControlName, onset.requestID == $event.requestID )
+ $opTimer : OperationTimer( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID.toString() )
+ $lock : TargetLock (requestID == $event.requestID)
+ $response : Response( getCommonHeader().RequestID == $event.requestID )
+ then
+
+ Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
+ logger.info("{}: {}", $params.getClosedLoopControlName(), drools.getRule().getName());
+ logger.debug("{}: {}: event={} manager={} operation={} lock={} opTimer={} response={}",
+ $params.getClosedLoopControlName(), drools.getRule().getName(),
+ $event, $manager, $operation, $lock, $opTimer, $response);
+ //
+ // Get the result of the operation
+ //
+ PolicyResult policyResult = $operation.onResponse($response);
+ if (policyResult != null) {
+ logger.debug("{}: {}: operation finished - result={}",
+ $params.getClosedLoopControlName(), drools.getRule().getName(),
+ policyResult);
+ //
+ // This Operation has completed, construct a notification showing our results. (DB write - end operation)
+ //
+ VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
+ notification.from = "policy";
+ notification.policyName = drools.getRule().getName();
+ notification.policyScope = "${policyScope}";
+ notification.policyVersion = "${policyVersion}";
+ notification.message = $operation.getOperationHistory();
+ notification.history = $operation.getHistory();
+ if (policyResult.equals(PolicyResult.SUCCESS)) {
+ notification.notification = ControlLoopNotificationType.OPERATION_SUCCESS;
+ //
+ // Let interested parties know
+ //
+ PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
+ } else {
+ notification.notification = ControlLoopNotificationType.OPERATION_FAILURE;
+ //
+ // Let interested parties know
+ //
+ PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
+ }
+ //
+ // Ensure the operation is complete
+ //
+ if ($operation.isOperationComplete() == true) {
+ //
+ // It is complete, remove it from memory
+ //
+ retract($operation);
+ //
+ // We must also retract the timer object
+ // NOTE: We could write a Rule to do this
+ //
+ retract($opTimer);
+ //
+ // Complete the operation
+ //
+ modify($manager) {finishOperation($operation)};
+ } else {
+ //
+ // Just doing this will kick off the LOCKED rule again
+ //
+ modify($operation) {};
+ }
+ } else {
+ //
+ // Its not finished yet (i.e. expecting more Response objects)
+ //
+ // Or possibly it is a leftover response that we timed the request out previously
+ //
+ }
+ //
+ // We are going to retract these objects from memory
+ //
+ retract($response);
+end
+
+/*
+*
+* The problem with Responses is that they don't have a controlLoopControlName
+* field in them, so the only way to attach them is via RequestID. If we have multiple
+* control loop .drl's loaded in the same container, we need to be sure the cleanup
+* rules don't remove Responses for other control loops.
+*
+*/
+rule "${policyName}.APPC.RESPONSE.CLEANUP"
+ when
+ $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" )
+ $response : Response($id : getCommonHeader().RequestID )
+ not ( VirtualControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName(), requestID == $id, closedLoopEventStatus == ControlLoopEventStatus.ONSET ) )
+ then
+
+ Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
+ logger.info("{}: {}", $params.getClosedLoopControlName(), drools.getRule().getName());
+ logger.debug("{}: {}: orphan appc response={}",
+ $params.getClosedLoopControlName(), drools.getRule().getName(), $id);
+
+ //
+ // Retract it
+ //
+ retract($response);
+end
+
+/*
+*
+* This rule responds to APPC Response Events using the new LCM interface provided by appc
+*
+*/
+rule "${policyName}.APPC.LCM.RESPONSE"
+ when
+ $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" )
+ $event : VirtualControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName(), closedLoopEventStatus == ControlLoopEventStatus.ONSET )
+ $manager : ControlLoopEventManager( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID )
+ $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.closedLoopControlName, onset.requestID == $event.requestID )
+ $opTimer : OperationTimer( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID.toString() )
+ $lock : TargetLock (requestID == $event.requestID)
+ $response : LCMResponseWrapper( getBody().getCommonHeader().getRequestId() == $event.requestID )
+ then
+
+ Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
+ logger.info("{}: {}", $params.getClosedLoopControlName(), drools.getRule().getName());
+ logger.debug("{}: {}: event={} manager={} operation={} lock={} opTimer={} response={}",
+ $params.getClosedLoopControlName(), drools.getRule().getName(),
+ $event, $manager, $operation, $lock, $operation, $opTimer, $response);
+
+ //
+ // Get the result of the operation
+ //
+ PolicyResult policyResult = $operation.onResponse($response);
+ if (policyResult != null) {
+ logger.debug("{}: {}: operation finished - result={}",
+ $params.getClosedLoopControlName(), drools.getRule().getName(),
+ policyResult);
+
+ //
+ // This Operation has completed, construct a notification showing our results. (DB write - end operation)
+ //
+ VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
+ notification.from = "policy";
+ notification.policyName = drools.getRule().getName();
+ notification.policyScope = "${policyScope}";
+ notification.policyVersion = "${policyVersion}";
+ notification.message = $operation.getOperationHistory();
+ notification.history = $operation.getHistory();
+ if (policyResult.equals(PolicyResult.SUCCESS)) {
+ notification.notification = ControlLoopNotificationType.OPERATION_SUCCESS;
+ } else {
+ notification.notification = ControlLoopNotificationType.OPERATION_FAILURE;
+ }
+ PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
+ //
+ // Ensure the operation is complete
+ //
+ if ($operation.isOperationComplete() == true) {
+ //
+ // It is complete, remove it from memory
+ //
+ retract($operation);
+ //
+ // We must also retract the timer object
+ // NOTE: We could write a Rule to do this
+ //
+ retract($opTimer);
+ //
+ // Complete the operation
+ //
+ modify($manager) {finishOperation($operation)};
+ } else {
+ //
+ // Just doing this will kick off the LOCKED rule again
+ //
+ modify($operation) {};
+ }
+ } else {
+ //
+ // Its not finished yet (i.e. expecting more Response objects)
+ //
+ // Or possibly it is a leftover response that we timed the request out previously
+ //
+ }
+ //
+ // We are going to retract these objects from memory
+ //
+ retract($response);
+end
+
+/*
+*
+* Clean Up any lingering LCM reponses
+*
+*/
+rule "${policyName}.APPC.LCM.RESPONSE.CLEANUP"
+ when
+ $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" )
+ $response : LCMResponseWrapper($id : getBody().getCommonHeader().getRequestId )
+ not ( VirtualControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName(), requestID == $id, closedLoopEventStatus == ControlLoopEventStatus.ONSET ) )
+ then
+
+ Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
+ logger.info("{}: {}", $params.getClosedLoopControlName(), drools.getRule().getName());
+ logger.debug("{}: {}: orphan appc response={}",
+ $params.getClosedLoopControlName(), drools.getRule().getName(), $id);
+ //
+ // Retract it
+ //
+ retract($response);
+end
+
+/*
+*
+* This rule responds to SO Response Events
+*
+*/
+rule "${policyName}.SO.RESPONSE"
+ when
+ $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" )
+ $event : VirtualControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName(), closedLoopEventStatus == ControlLoopEventStatus.ONSET )
+ $manager : ControlLoopEventManager( closedLoopControlName == $event.closedLoopControlName )
+ $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.closedLoopControlName, onset.requestID == $event.requestID )
+ $opTimer : OperationTimer( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID.toString() )
+ $lock : TargetLock (requestID == $event.requestID)
+ $request : SORequest( requestId == $event.requestID.toString() )
+ $response : SOResponse( request.requestId == $event.requestID.toString() )
+ then
+
+ Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
+ logger.info("{}: {}", $params.getClosedLoopControlName(), drools.getRule().getName());
+ logger.debug("{}: {}: event={} manager={} operation={} lock={} opTimer={} request={} response={}",
+ $params.getClosedLoopControlName(), drools.getRule().getName(),
+ $event, $manager, $operation, $lock, $operation, $opTimer, $request, $response);
+
+ // Get the result of the operation
+ //
+ PolicyResult policyResult = $operation.onResponse($response);
+ if (policyResult != null) {
+ logger.debug("{}: {}: operation finished - result={}",
+ $params.getClosedLoopControlName(), drools.getRule().getName(),
+ policyResult);
+
+ //
+ // This Operation has completed, construct a notification showing our results
+ //
+ VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
+ notification.from = "policy";
+ notification.policyName = drools.getRule().getName();
+ notification.policyScope = "${policyScope}";
+ notification.policyVersion = "${policyVersion}";
+ notification.message = $operation.getOperationHistory();
+ notification.history = $operation.getHistory();
+ if (policyResult.equals(PolicyResult.SUCCESS)) {
+ notification.notification = ControlLoopNotificationType.OPERATION_SUCCESS;
+ } else {
+ notification.notification = ControlLoopNotificationType.OPERATION_FAILURE;
+
+ }
+ PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
+ //
+ // Ensure the operation is complete
+ //
+ if ($operation.isOperationComplete() == true) {
+ //
+ // It is complete, remove it from memory
+ //
+ retract($operation);
+ //
+ // We must also retract the timer object
+ // NOTE: We could write a Rule to do this
+ //
+ retract($opTimer);
+ //
+ // Complete the operation
+ //
+ modify($manager) {finishOperation($operation)};
+ } else {
+ //
+ // Just doing this will kick off the LOCKED rule again
+ //
+ modify($operation) {};
+ }
+ } else {
+ //
+ // Its not finished yet (i.e. expecting more Response objects)
+ //
+ // Or possibly it is a leftover response that we timed the request out previously
+ //
+ }
+ //
+ // We are going to retract these objects from memory
+ //
+ retract($response);
+
+end
+
+/*
+*
+* This is the timer that manages the timeout for an individual operation.
+*
+*/
+rule "${policyName}.EVENT.MANAGER.OPERATION.TIMEOUT"
+ timer (expr: $to )
+ when
+ $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" )
+ $event : VirtualControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName() )
+ $manager : ControlLoopEventManager( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID )
+ $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.closedLoopControlName, onset.requestID == $event.requestID )
+ $opTimer : OperationTimer( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID.toString(), $to : getDelay() )
+ $lock : TargetLock (requestID == $event.requestID)
+ then
+
+ Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
+ logger.info("{}: {}", $params.getClosedLoopControlName(), drools.getRule().getName());
+ logger.debug("{}: {}: event={} manager={} operation={} lock={} opTimer={}",
+ $params.getClosedLoopControlName(), drools.getRule().getName(),
+ $event, $manager, $operation, $lock, $operation, $opTimer);
+
+ //
+ // Tell it its timed out
+ //
+ $operation.setOperationHasTimedOut();
+ //
+ // Create a notification for it ("DB Write - end operation")
+ //
+ VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
+ notification.from = "policy";
+ notification.policyName = drools.getRule().getName();
+ notification.policyScope = "${policyScope}";
+ notification.policyVersion = "${policyVersion}";
+ notification.notification = ControlLoopNotificationType.OPERATION_FAILURE;
+ notification.message = $operation.getOperationHistory();
+ notification.history = $operation.getHistory();
+ //
+ // Let interested parties know
+ //
+ PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
+ //
+ // Get rid of the timer
+ //
+ retract($opTimer);
+ //
+ // Ensure the operation is complete
+ //
+ if ($operation.isOperationComplete() == true) {
+ //
+ // It is complete, remove it from memory
+ //
+ retract($operation);
+ //
+ // Complete the operation
+ //
+ modify($manager) {finishOperation($operation)};
+ } else {
+ //
+ // Just doing this will kick off the LOCKED rule again
+ //
+ modify($operation) {};
+ }
+end
+
+/*
+*
+* This is the timer that manages the overall control loop timeout.
+*
+*/
+rule "${policyName}.EVENT.MANAGER.TIMEOUT"
+ timer (expr: $to )
+ when
+ $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" )
+ $event : VirtualControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName() )
+ $manager : ControlLoopEventManager( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID )
+ $clTimer : ControlLoopTimer ( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID.toString(), $to : getDelay() )
+ $operations : LinkedList()
+ from collect( ControlLoopOperationManager( onset.closedLoopControlName == $event.closedLoopControlName, onset.requestID == $event.requestID ) )
+ $opTimers : LinkedList()
+ from collect( OperationTimer( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID.toString() ) )
+ $locks : LinkedList()
+ from collect( TargetLock (requestID == $event.requestID) )
+ then
+
+ Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage());
+ logger.info("{}: {}", $params.getClosedLoopControlName(), drools.getRule().getName());
+
+ if ($operations == null) {
+ logger.debug("{}: {}: event={} manager={} clTimer={} operations=0",
+ $params.getClosedLoopControlName(), drools.getRule().getName(),
+ $event, $manager, $clTimer);
+ } else {
+ logger.debug("{}: {}: event={} manager={} clTimer={} operations={}",
+ $params.getClosedLoopControlName(), drools.getRule().getName(),
+ $event, $manager, $clTimer, $operations.size());
+ }
+ //
+ // Tell the Event Manager it has timed out
+ //
+ VirtualControlLoopNotification notification = $manager.setControlLoopTimedOut();
+ if (notification != null) {
+ notification.from = "policy";
+ notification.policyName = drools.getRule().getName();
+ notification.policyScope = "${policyScope}";
+ notification.policyVersion = "${policyVersion}";
+ //
+ // Let interested parties know
+ //
+ PolicyEngine.manager.deliver("POLICY-CL-MGT", notification);
+ }
+ //
+ // Retract EVERYTHING
+ //
+ retract($event);
+ retract($manager);
+ retract($clTimer);
+ if ($operations != null && $operations.size() > 0) {
+ Iterator<ControlLoopOperationManager> iter = $operations.iterator();
+ while (iter.hasNext()) {
+ ControlLoopOperationManager manager = iter.next();
+ retract(manager);
+ }
+ }
+ if ($opTimers != null && $opTimers.size() > 0) {
+ Iterator<OperationTimer> iter = $opTimers.iterator();
+ while (iter.hasNext()) {
+ OperationTimer opTimer = iter.next();
+ retract(opTimer);
+ }
+ }
+ if ($locks != null && $locks.size() > 0) {
+ Iterator<TargetLock> iter = $locks.iterator();
+ while (iter.hasNext()) {
+ TargetLock lock = iter.next();
+ //
+ // Ensure we release the lock
+ //
+ PolicyGuard.unlockTarget(lock);
+ //
+ //
+ //
+ retract(lock);
+ }
+ }
+end
diff --git a/controlloop/templates/archetype-cl-amsterdam/src/test/resources/projects/basic/archetype.properties b/controlloop/templates/archetype-cl-amsterdam/src/test/resources/projects/basic/archetype.properties
new file mode 100644
index 000000000..92bcb4393
--- /dev/null
+++ b/controlloop/templates/archetype-cl-amsterdam/src/test/resources/projects/basic/archetype.properties
@@ -0,0 +1,43 @@
+###
+# ============LICENSE_START=======================================================
+# archetype-closed-loop-demo-rules
+# ================================================================================
+# Copyright (C) 2017 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=========================================================
+###
+
+groupId=org.onap.policy.demo.drools
+artifactId=amsterdam
+version=1.1.0-SNAPSHOT
+package=org.onap.policy.demo.drools
+closedLoopControlName=ControlLoop-vCPE-48f0c2c3-a172-4192-9ae3-052274181b6e
+controlLoopYaml=controlLoop%3A%0A++version%3A+2.0.0%0A++controlLoopName%3A+ControlLoop-vCPE-48f0c2c3-a172-4192-9ae3-052274181b6e%0A++trigger_policy%3A+unique-policy-id-1-restart%0A++timeout%3A+3600%0A++abatement%3A+true%0A+%0Apolicies%3A%0A++-+id%3A+unique-policy-id-1-restart%0A++++name%3A+Restart+the+VM%0A++++description%3A%0A++++actor%3A+APPC%0A++++recipe%3A+Restart%0A++++target%3A%0A++++++type%3A+VM%0A++++retry%3A+3%0A++++timeout%3A+1200%0A++++success%3A+final_success%0A++++failure%3A+final_failure%0A++++failure_timeout%3A+final_failure_timeout%0A++++failure_retries%3A+final_failure_retries%0A++++failure_exception%3A+final_failure_exception%0A++++failure_guard%3A+final_failure_guard%0A
+policyScope=service=test;resource=FRWL;type=configuration
+policyName=FirewallDemo
+policyVersion=v1.0
+dmaapServers=server1,server2,server3
+appcTopic=APPC-CL
+notificationTopic=POLICY-CL-MGT
+dcaeTopic=DCAE-CL-EVENT
+dcaeServers=server1,server2,server3
+dependenciesVersion=1.0.0-SNAPSHOT
+aaiURL=http://localhost:8080/TestREST/Test
+aaiUsername=policy
+aaiPassword=policy
+aaiNamedQueryUUID=d925ed73-8231-4d02-9545-db4e101fffff
+aaiPatternMatch=false
+msoURL=http://localhost:8080/TestREST/Test
+msoUsername=policy
+msoPassword=policy
diff --git a/controlloop/templates/pom.xml b/controlloop/templates/pom.xml
index 046ccee6e..f36e4bb01 100644
--- a/controlloop/templates/pom.xml
+++ b/controlloop/templates/pom.xml
@@ -35,6 +35,7 @@
<modules>
<module>template.demo</module>
<module>template.demo.v1.0.0</module>
+ <module>archetype-cl-amsterdam</module>
</modules>
diff --git a/controlloop/templates/template.demo.v1.0.0/archetype-cl-legacy/src/main/resources/archetype-resources/pom.xml b/controlloop/templates/template.demo.v1.0.0/archetype-cl-legacy/src/main/resources/archetype-resources/pom.xml
index 9c2634579..fdf74293e 100644
--- a/controlloop/templates/template.demo.v1.0.0/archetype-cl-legacy/src/main/resources/archetype-resources/pom.xml
+++ b/controlloop/templates/template.demo.v1.0.0/archetype-cl-legacy/src/main/resources/archetype-resources/pom.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
============LICENSE_START=======================================================
- archetype-closed-loop-demo-rules
+ ONAP
================================================================================
Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
================================================================================
@@ -26,6 +26,7 @@
<groupId>${groupId}</groupId>
<artifactId>${artifactId}</artifactId>
<version>${version}</version>
+ <packaging>kjar</packaging>
<name>${artifactId}</name>
<description>Control Loop Legacy Rules for 1.0.0</description>
diff --git a/controlloop/templates/template.demo.v1.0.0/archetype-cl-legacy/src/main/resources/archetype-resources/src/main/resources/META-INF/kmodule.xml b/controlloop/templates/template.demo.v1.0.0/archetype-cl-legacy/src/main/resources/archetype-resources/src/main/resources/META-INF/kmodule.xml
index 8116d880a..f9d166c74 100644
--- a/controlloop/templates/template.demo.v1.0.0/archetype-cl-legacy/src/main/resources/archetype-resources/src/main/resources/META-INF/kmodule.xml
+++ b/controlloop/templates/template.demo.v1.0.0/archetype-cl-legacy/src/main/resources/archetype-resources/src/main/resources/META-INF/kmodule.xml
@@ -24,6 +24,6 @@
<kmodule xmlns="http://jboss.org/kie/6.0.0/kmodule">
<kbase name="rules">
- <ksession name="closedloop-demo"/>
+ <ksession name="legacy"/>
</kbase>
</kmodule>
diff --git a/controlloop/templates/template.demo.v1.0.0/archetype-cl-legacy/src/test/resources/projects/basic/goal.txt b/controlloop/templates/template.demo.v1.0.0/archetype-cl-legacy/src/test/resources/projects/basic/goal.txt
deleted file mode 100644
index e69de29bb..000000000
--- a/controlloop/templates/template.demo.v1.0.0/archetype-cl-legacy/src/test/resources/projects/basic/goal.txt
+++ /dev/null