aboutsummaryrefslogtreecommitdiffstats
path: root/controlloop/templates
diff options
context:
space:
mode:
authorGao, Chenfei (cg287m) <cgao@research.att.com>2017-06-22 14:48:41 -0400
committerPamela Dragosh <pdragosh@research.att.com>2017-06-29 12:50:23 -0400
commit68377161605e39c8c74ea77d0b504177480788f3 (patch)
treefb0fb8a27178da607866e1850f73ac056e046ee8 /controlloop/templates
parentf0c29b57e132e6335f0fa7bbad885d403e4c85df (diff)
[POLICY-22] Reorganizing drools-apps
Change-Id: I5f9bb3908f8d55c466dd847ae5e01a424e9ba364 Signed-off-by: Gao, Chenfei (cg287m) <chenfei.gao11@gmail.com> Signed-off-by: Pamela Dragosh <pdragosh@research.att.com>
Diffstat (limited to 'controlloop/templates')
-rw-r--r--controlloop/templates/pom.xml41
-rw-r--r--controlloop/templates/template.demo.v1.0.0/README.md2
-rw-r--r--controlloop/templates/template.demo.v1.0.0/archetype-closedloop-demo-rules/pom.xml57
-rw-r--r--controlloop/templates/template.demo.v1.0.0/archetype-closedloop-demo-rules/src/main/resources/META-INF/maven/archetype-metadata.xml77
-rw-r--r--controlloop/templates/template.demo.v1.0.0/archetype-closedloop-demo-rules/src/main/resources/archetype-resources/pom.xml75
-rw-r--r--controlloop/templates/template.demo.v1.0.0/archetype-closedloop-demo-rules/src/main/resources/archetype-resources/src/main/config/__artifactId__-controller.properties55
-rw-r--r--controlloop/templates/template.demo.v1.0.0/archetype-closedloop-demo-rules/src/main/resources/archetype-resources/src/main/config/__artifactId__-controller.rest.json37
-rw-r--r--controlloop/templates/template.demo.v1.0.0/archetype-closedloop-demo-rules/src/main/resources/archetype-resources/src/main/config/appc.accepted.json1
-rw-r--r--controlloop/templates/template.demo.v1.0.0/archetype-closedloop-demo-rules/src/main/resources/archetype-resources/src/main/config/appc.success.json1
-rw-r--r--controlloop/templates/template.demo.v1.0.0/archetype-closedloop-demo-rules/src/main/resources/archetype-resources/src/main/config/dcae.onset.json14
-rw-r--r--controlloop/templates/template.demo.v1.0.0/archetype-closedloop-demo-rules/src/main/resources/archetype-resources/src/main/config/vFWsim-controller.properties49
-rw-r--r--controlloop/templates/template.demo.v1.0.0/archetype-closedloop-demo-rules/src/main/resources/archetype-resources/src/main/config/vFWsim-controller.rest.json31
-rw-r--r--controlloop/templates/template.demo.v1.0.0/archetype-closedloop-demo-rules/src/main/resources/archetype-resources/src/main/config/vfwsim-onset.json5
-rw-r--r--controlloop/templates/template.demo.v1.0.0/archetype-closedloop-demo-rules/src/main/resources/archetype-resources/src/main/resources/ControlLoopDemo__closedLoopControlName__.drl1140
-rw-r--r--controlloop/templates/template.demo.v1.0.0/archetype-closedloop-demo-rules/src/main/resources/archetype-resources/src/main/resources/META-INF/kmodule.xml29
-rw-r--r--controlloop/templates/template.demo.v1.0.0/archetype-closedloop-demo-rules/src/test/resources/projects/basic/archetype.properties50
-rw-r--r--controlloop/templates/template.demo.v1.0.0/archetype-closedloop-demo-rules/src/test/resources/projects/basic/goal.txt0
-rw-r--r--controlloop/templates/template.demo.v1.0.0/pom.xml41
-rw-r--r--controlloop/templates/template.demo.v1.0.0/template.demo/pom.xml112
-rw-r--r--controlloop/templates/template.demo.v1.0.0/template.demo/src/main/resources/archetype-resources/src/main/resources/ControlLoopDemo__closedLoopControlName__.drl1316
-rw-r--r--controlloop/templates/template.demo.v1.0.0/template.demo/src/test/java/org/onap/policy/template/demo/TestAPPCPayload.java58
-rw-r--r--controlloop/templates/template.demo.v1.0.0/template.demo/src/test/java/org/onap/policy/template/demo/TestFirewallDemo.java593
-rw-r--r--controlloop/templates/template.demo.v1.0.0/template.demo/src/test/java/org/onap/policy/template/demo/TestMSO.java159
-rw-r--r--controlloop/templates/template.demo.v1.0.0/template.demo/src/test/resources/aairesponse.json227
-rw-r--r--controlloop/templates/template.demo/README.md3
-rw-r--r--controlloop/templates/template.demo/pom.xml112
-rw-r--r--controlloop/templates/template.demo/src/main/resources/ControlLoop_Template_1707_xacml_guard.drl917
-rw-r--r--controlloop/templates/template.demo/src/main/resources/blacklist_template.xml48
-rw-r--r--controlloop/templates/template.demo/src/main/resources/frequency_limiter_template.xml44
-rw-r--r--controlloop/templates/template.demo/src/main/resources/frequency_limiter_template_old.xml44
-rw-r--r--controlloop/templates/template.demo/src/main/resources/old/ControlLoop_Template_1610_v1.1_xacml_guard.drl867
-rw-r--r--controlloop/templates/template.demo/src/main/resources/old/ControlLoop_Template_1707_xacml_guard_enodeb.drl952
-rw-r--r--controlloop/templates/template.demo/src/test/java/org/onap/policy/controlloop/processor/ControlLoopXacmlGuardTest.java674
-rw-r--r--controlloop/templates/template.demo/src/test/java/org/onap/policy/controlloop/processor/Util.java90
-rw-r--r--controlloop/templates/template.demo/src/test/resources/xacml/old/frequency_limiter_1.xml37
-rw-r--r--controlloop/templates/template.demo/src/test/resources/xacml/old/frequency_limiter_2.xml52
-rw-r--r--controlloop/templates/template.demo/src/test/resources/xacml/old/frequency_limiter_3.xml37
-rw-r--r--controlloop/templates/template.demo/src/test/resources/xacml/old/frequency_limiter_4.xml51
-rw-r--r--controlloop/templates/template.demo/src/test/resources/xacml/old/xacml.properties119
-rw-r--r--controlloop/templates/template.demo/src/test/resources/xacml/old/xacml2.properties120
-rw-r--r--controlloop/templates/template.demo/src/test/resources/xacml/old/xacml3.properties123
-rw-r--r--controlloop/templates/template.demo/src/test/resources/xacml/xacml_guard.properties52
-rw-r--r--controlloop/templates/template.demo/src/test/resources/xacml/xacml_guard_old.properties277
-rw-r--r--controlloop/templates/template.demo/src/test/resources/yaml/policy_ControlLoop_vUSP_1707.yaml68
-rw-r--r--controlloop/templates/template.demo/src/test/resources/yaml/policy_guard_vUSP_1707_appc_migrate.yaml24
-rw-r--r--controlloop/templates/template.demo/src/test/resources/yaml/policy_guard_vUSP_1707_appc_rebuild.yaml24
-rw-r--r--controlloop/templates/template.demo/src/test/resources/yaml/policy_guard_vUSP_1707_appc_rebuild_1.yaml24
-rw-r--r--controlloop/templates/template.demo/src/test/resources/yaml/policy_guard_vUSP_1707_appc_restart.yaml24
-rw-r--r--controlloop/templates/template.demo/src/test/resources/yaml/policy_guard_vUSP_1707_appc_restart_blacklist.yaml26
49 files changed, 8979 insertions, 0 deletions
diff --git a/controlloop/templates/pom.xml b/controlloop/templates/pom.xml
new file mode 100644
index 000000000..046ccee6e
--- /dev/null
+++ b/controlloop/templates/pom.xml
@@ -0,0 +1,41 @@
+<!--
+ ============LICENSE_START=======================================================
+ drools-pdp-apps Control Loop Drools Templates
+ ================================================================================
+ 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>
+
+ <artifactId>templates</artifactId>
+ <packaging>pom</packaging>
+
+ <parent>
+ <groupId>org.onap.policy.drools-applications</groupId>
+ <artifactId>controlloop</artifactId>
+ <version>1.1.0-SNAPSHOT</version>
+ </parent>
+
+ <modules>
+ <module>template.demo</module>
+ <module>template.demo.v1.0.0</module>
+ </modules>
+
+
+</project>
diff --git a/controlloop/templates/template.demo.v1.0.0/README.md b/controlloop/templates/template.demo.v1.0.0/README.md
new file mode 100644
index 000000000..3d5a32dcd
--- /dev/null
+++ b/controlloop/templates/template.demo.v1.0.0/README.md
@@ -0,0 +1,2 @@
+
+This is the legacy template to support vFW/vDNS W/O integration with AAI.
diff --git a/controlloop/templates/template.demo.v1.0.0/archetype-closedloop-demo-rules/pom.xml b/controlloop/templates/template.demo.v1.0.0/archetype-closedloop-demo-rules/pom.xml
new file mode 100644
index 000000000..2e43a6019
--- /dev/null
+++ b/controlloop/templates/template.demo.v1.0.0/archetype-closedloop-demo-rules/pom.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ============LICENSE_START=======================================================
+ drools-pdp-apps Control Loop Drools Templates
+ ================================================================================
+ 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>template.demo.v1.0.0</artifactId>
+ <version>1.1.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>archetype-closedloop-demo-rules</artifactId>
+ <packaging>maven-archetype</packaging>
+
+ <name>archetype-closed-loop-demo-rules</name>
+ <description>archetype to generate a closed loop demo rules jar</description>
+
+ <build>
+ <extensions>
+ <extension>
+ <groupId>org.apache.maven.archetype</groupId>
+ <artifactId>archetype-packaging</artifactId>
+ <version>2.4</version>
+ </extension>
+ </extensions>
+
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <artifactId>maven-archetype-plugin</artifactId>
+ <version>2.4</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+
+</project>
diff --git a/controlloop/templates/template.demo.v1.0.0/archetype-closedloop-demo-rules/src/main/resources/META-INF/maven/archetype-metadata.xml b/controlloop/templates/template.demo.v1.0.0/archetype-closedloop-demo-rules/src/main/resources/META-INF/maven/archetype-metadata.xml
new file mode 100644
index 000000000..a0b5506fc
--- /dev/null
+++ b/controlloop/templates/template.demo.v1.0.0/archetype-closedloop-demo-rules/src/main/resources/META-INF/maven/archetype-metadata.xml
@@ -0,0 +1,77 @@
+<?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"></requiredProperty>
+ <requiredProperty key="policyScope"></requiredProperty>
+ <requiredProperty key="policyName"></requiredProperty>
+ <requiredProperty key="policyVersion"></requiredProperty>
+ <requiredProperty key="actor"></requiredProperty>
+ <requiredProperty key="aaiURL"></requiredProperty>
+ <requiredProperty key="aaiUsername"></requiredProperty>
+ <requiredProperty key="aaiPassword"></requiredProperty>
+ <requiredProperty key="aaiNamedQueryUUID"></requiredProperty>
+ <requiredProperty key="aaiPatternMatch"></requiredProperty>
+ <requiredProperty key="msoURL"></requiredProperty>
+ <requiredProperty key="msoUsername"></requiredProperty>
+ <requiredProperty key="msoPassword"></requiredProperty>
+ <requiredProperty key="appcTopic"></requiredProperty>
+ <requiredProperty key="appcServers"></requiredProperty>
+ <requiredProperty key="appcApiKey"></requiredProperty>
+ <requiredProperty key="appcApiSecret"></requiredProperty>
+ <requiredProperty key="notificationTopic"></requiredProperty>
+ <requiredProperty key="notificationServers"></requiredProperty>
+ <requiredProperty key="notificationApiKey"></requiredProperty>
+ <requiredProperty key="notificationApiSecret"></requiredProperty>
+ <requiredProperty key="dcaeTopic"></requiredProperty>
+ <requiredProperty key="dcaeServers"></requiredProperty>
+ <requiredProperty key="dcaeApiKey"></requiredProperty>
+ <requiredProperty key="dcaeApiSecret"></requiredProperty>
+ <requiredProperty key="dependenciesVersion"></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/template.demo.v1.0.0/archetype-closedloop-demo-rules/src/main/resources/archetype-resources/pom.xml b/controlloop/templates/template.demo.v1.0.0/archetype-closedloop-demo-rules/src/main/resources/archetype-resources/pom.xml
new file mode 100644
index 000000000..c3973a7d9
--- /dev/null
+++ b/controlloop/templates/template.demo.v1.0.0/archetype-closedloop-demo-rules/src/main/resources/archetype-resources/pom.xml
@@ -0,0 +1,75 @@
+<?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=========================================================
+ -->
+
+<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>
+
+ <name>${artifactId}</name>
+ <description>Closed Loop Demo Rules</description>
+
+ <properties>
+ <maven.compiler.source>1.8</maven.compiler.source>
+ <maven.compiler.target>1.8</maven.compiler.target>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.openecomp.policy.drools-applications</groupId>
+ <artifactId>demo</artifactId>
+ <version>${dependenciesVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.openecomp.policy.drools-applications</groupId>
+ <artifactId>controlloop</artifactId>
+ <version>${dependenciesVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.openecomp.policy.drools-applications</groupId>
+ <artifactId>rest</artifactId>
+ <version>${dependenciesVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.openecomp.policy.drools-applications</groupId>
+ <artifactId>appc</artifactId>
+ <version>${dependenciesVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.openecomp.policy.drools-applications</groupId>
+ <artifactId>aai</artifactId>
+ <version>${dependenciesVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.openecomp.policy.drools-applications</groupId>
+ <artifactId>mso</artifactId>
+ <version>${dependenciesVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.openecomp.policy.drools-applications</groupId>
+ <artifactId>trafficgenerator</artifactId>
+ <version>${dependenciesVersion}</version>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/controlloop/templates/template.demo.v1.0.0/archetype-closedloop-demo-rules/src/main/resources/archetype-resources/src/main/config/__artifactId__-controller.properties b/controlloop/templates/template.demo.v1.0.0/archetype-closedloop-demo-rules/src/main/resources/archetype-resources/src/main/config/__artifactId__-controller.properties
new file mode 100644
index 000000000..9c3885947
--- /dev/null
+++ b/controlloop/templates/template.demo.v1.0.0/archetype-closedloop-demo-rules/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},${appcTopic}
+
+ueb.source.topics.${dcaeTopic}.servers=${dcaeServers}
+ueb.source.topics.${dcaeTopic}.apiKey=${dcaeApiKey}
+ueb.source.topics.${dcaeTopic}.apiSecret=${dcaeApiSecret}
+ueb.source.topics.${dcaeTopic}.events=org.openecomp.policy.controlloop.VirtualControlLoopEvent
+ueb.source.topics.${dcaeTopic}.events.org.openecomp.policy.controlloop.VirtualControlLoopEvent.filter=closedLoopEventStatus=.*
+ueb.source.topics.${dcaeTopic}.events.custom.gson=org.openecomp.policy.controlloop.util.Serialization,gsonPretty
+
+ueb.source.topics.${appcTopic}.servers=${appcServers}
+ueb.source.topics.${appcTopic}.apiKey=${appcApiKey}
+ueb.source.topics.${appcTopic}.apiSecret=${appcApiSecret}
+ueb.source.topics.${appcTopic}.events=org.openecomp.policy.appc.Response
+ueb.source.topics.${appcTopic}.events.org.openecomp.policy.appc.Response.filter=CommonHeader=.*,Status=.*
+ueb.source.topics.${appcTopic}.events.custom.gson=org.openecomp.policy.appc.util.Serialization,gsonPretty
+
+ueb.sink.topics=${appcTopic},${notificationTopic}
+
+ueb.sink.topics.${appcTopic}.servers=${appcServers}
+ueb.sink.topics.${appcTopic}.apiKey=${appcApiKey}
+ueb.sink.topics.${appcTopic}.apiSecret=${appcApiSecret}
+ueb.sink.topics.${appcTopic}.events=org.openecomp.policy.appc.Request
+ueb.sink.topics.${appcTopic}.events.custom.gson=org.openecomp.policy.appc.util.Serialization,gsonPretty
+
+ueb.sink.topics.${notificationTopic}.servers=${notificationServers}
+ueb.sink.topics.${notificationTopic}.apiKey=${notificationApiKey}
+ueb.sink.topics.${notificationTopic}.apiSecret=${notificationApiSecret}
+ueb.sink.topics.${notificationTopic}.events=org.openecomp.policy.controlloop.VirtualControlLoopNotification
+ueb.sink.topics.${notificationTopic}.events.custom.gson=org.openecomp.policy.controlloop.util.Serialization,gsonPretty
+
+rules.groupId=${groupId}
+rules.artifactId=${artifactId}
+rules.version=${version}
diff --git a/controlloop/templates/template.demo.v1.0.0/archetype-closedloop-demo-rules/src/main/resources/archetype-resources/src/main/config/__artifactId__-controller.rest.json b/controlloop/templates/template.demo.v1.0.0/archetype-closedloop-demo-rules/src/main/resources/archetype-resources/src/main/config/__artifactId__-controller.rest.json
new file mode 100644
index 000000000..de5db52df
--- /dev/null
+++ b/controlloop/templates/template.demo.v1.0.0/archetype-closedloop-demo-rules/src/main/resources/archetype-resources/src/main/config/__artifactId__-controller.rest.json
@@ -0,0 +1,37 @@
+{
+ "controller.name": "${artifactId}",
+
+ "ueb.source.topics": "${dcaeTopic},${appcTopic}",
+
+ "ueb.source.topics.${dcaeTopic}.servers": "${dcaeServers}",
+ "ueb.source.topics.${dcaeTopic}.apiKey": "${dcaeApiKey}",
+ "ueb.source.topics.${dcaeTopic}.apiSecret": "${dcaeApiSecret}",
+ "ueb.source.topics.${dcaeTopic}.events": "org.openecomp.policy.controlloop.VirtualControlLoopEvent",
+ "ueb.source.topics.${dcaeTopic}.events.org.openecomp.policy.controlloop.VirtualControlLoopEvent.filter": "closedLoopEventStatus=.*",
+ "ueb.source.topics.${dcaeTopic}.events.custom.gson": "org.openecomp.policy.controlloop.util.Serialization,gsonPretty",
+
+ "ueb.source.topics.${appcTopic}.servers": "${appcServers}",
+ "ueb.source.topics.${appcTopic}.apiKey": "${appcApiKey}",
+ "ueb.source.topics.${appcTopic}.apiSecret": "${appcApiSecret}",
+ "ueb.source.topics.${appcTopic}.events": "org.openecomp.policy.appc.Response",
+ "ueb.source.topics.${appcTopic}.events.org.openecomp.policy.appc.Response.filter": "CommonHeader=.*,Status=.*",
+ "ueb.source.topics.${appcTopic}.events.custom.gson": "org.openecomp.policy.appc.util.Serialization,gsonPretty",
+
+ "ueb.sink.topics": "${appcTopic},${notificationTopic}",
+
+ "ueb.sink.topics.${appcTopic}.servers": "${appcServers}",
+ "ueb.sink.topics.${appcTopic}.apiKey": "${appcApiKey}",
+ "ueb.sink.topics.${appcTopic}.apiSecret": "${appcApiSecret}",
+ "ueb.sink.topics.${appcTopic}.events": "org.openecomp.policy.appc.Request",
+ "ueb.sink.topics.${appcTopic}.events.custom.gson": "org.openecomp.policy.appc.util.Serialization,gsonPretty",
+
+ "ueb.sink.topics.${notificationTopic}.servers": "${notificationServers}",
+ "ueb.sink.topics.${notificationTopic}.apiKey": "${notificationApiKey}",
+ "ueb.sink.topics.${notificationTopic}.apiSecret": "${notificationApiSecret}",
+ "ueb.sink.topics.${notificationTopic}.events": "org.openecomp.policy.controlloop.VirtualControlLoopNotification",
+ "ueb.sink.topics.${notificationTopic}.events.custom.gson": "org.openecomp.policy.controlloop.util.Serialization,gsonPretty",
+
+ "rules.groupId": "${groupId}",
+ "rules.artifactId": "${artifactId}",
+ "rules.version": "${version}"
+}
diff --git a/controlloop/templates/template.demo.v1.0.0/archetype-closedloop-demo-rules/src/main/resources/archetype-resources/src/main/config/appc.accepted.json b/controlloop/templates/template.demo.v1.0.0/archetype-closedloop-demo-rules/src/main/resources/archetype-resources/src/main/config/appc.accepted.json
new file mode 100644
index 000000000..01be66011
--- /dev/null
+++ b/controlloop/templates/template.demo.v1.0.0/archetype-closedloop-demo-rules/src/main/resources/archetype-resources/src/main/config/appc.accepted.json
@@ -0,0 +1 @@
+{"Status":{"Value":"ACCEPTED","Code":"100"},"Payload":{"pg-streams":"{\\\"pg-streams\\\": {\\\"pg-stream\\\":[{\\\"id\\\":\\\"fw_udp1\\\", \\\"is-enabled\\\":\\\"true\\\"},{\\\"id\\\":\\\"fw_udp2\\\", \\\"is-enabled\\\":\\\"true\\\"},{\\\"id\\\":\\\"fw_udp3\\\", \\\"is-enabled\\\":\\\"true\\\"},{\\\"id\\\":\\\"fw_udp4\\\", \\\"is-enabled\\\":\\\"true\\\"},{\\\"id\\\":\\\"fw_udp5\\\", \\\"is-enabled\\\":\\\"true\\\"}]}}","generic-vnf.vnf-id":"fw0001vm001fw001"},"CommonHeader":{"TimeStamp":"1493841850199","APIver":"1.01","RequestID":"664be3d2-6c12-4f4b-a3e7-c349acced200","SubrequestID":null,"OriginatorID":null}}
diff --git a/controlloop/templates/template.demo.v1.0.0/archetype-closedloop-demo-rules/src/main/resources/archetype-resources/src/main/config/appc.success.json b/controlloop/templates/template.demo.v1.0.0/archetype-closedloop-demo-rules/src/main/resources/archetype-resources/src/main/config/appc.success.json
new file mode 100644
index 000000000..b9ef41f50
--- /dev/null
+++ b/controlloop/templates/template.demo.v1.0.0/archetype-closedloop-demo-rules/src/main/resources/archetype-resources/src/main/config/appc.success.json
@@ -0,0 +1 @@
+{"Status":{"Value":"SUCCESS","Code":"400"},"Payload":{"pg-streams":"{\\\"pg-streams\\\": {\\\"pg-stream\\\":[{\\\"id\\\":\\\"fw_udp1\\\", \\\"is-enabled\\\":\\\"true\\\"},{\\\"id\\\":\\\"fw_udp2\\\", \\\"is-enabled\\\":\\\"true\\\"},{\\\"id\\\":\\\"fw_udp3\\\", \\\"is-enabled\\\":\\\"true\\\"},{\\\"id\\\":\\\"fw_udp4\\\", \\\"is-enabled\\\":\\\"true\\\"},{\\\"id\\\":\\\"fw_udp5\\\", \\\"is-enabled\\\":\\\"true\\\"}]}}","generic-vnf.vnf-id":"fw0001vm001fw001"},"CommonHeader":{"TimeStamp":"1493841850199","APIver":"1.01","RequestID":"664be3d2-6c12-4f4b-a3e7-c349acced200","SubrequestID":null,"OriginatorID":null}}
diff --git a/controlloop/templates/template.demo.v1.0.0/archetype-closedloop-demo-rules/src/main/resources/archetype-resources/src/main/config/dcae.onset.json b/controlloop/templates/template.demo.v1.0.0/archetype-closedloop-demo-rules/src/main/resources/archetype-resources/src/main/config/dcae.onset.json
new file mode 100644
index 000000000..4553faa13
--- /dev/null
+++ b/controlloop/templates/template.demo.v1.0.0/archetype-closedloop-demo-rules/src/main/resources/archetype-resources/src/main/config/dcae.onset.json
@@ -0,0 +1,14 @@
+{
+ "closedLoopControlName": "${closedLoopControlName}",
+ "closedLoopAlarmStart": 1463679805324,
+ "closedLoopEventClient": "microservice.stringmatcher",
+ "closedLoopEventStatus": "ONSET",
+ "requestID": "664be3d2-6c12-4f4b-a3e7-c349acced200",
+ "target_type": "VF",
+ "target": "generic-vnf.vnf-id",
+ "AAI": {
+ "generic-vnf.vnf-id": "fw0001vm001fw001"
+ },
+ "from": "DCAE",
+ "version": "1.0.2"
+}
diff --git a/controlloop/templates/template.demo.v1.0.0/archetype-closedloop-demo-rules/src/main/resources/archetype-resources/src/main/config/vFWsim-controller.properties b/controlloop/templates/template.demo.v1.0.0/archetype-closedloop-demo-rules/src/main/resources/archetype-resources/src/main/config/vFWsim-controller.properties
new file mode 100644
index 000000000..5cbe5f682
--- /dev/null
+++ b/controlloop/templates/template.demo.v1.0.0/archetype-closedloop-demo-rules/src/main/resources/archetype-resources/src/main/config/vFWsim-controller.properties
@@ -0,0 +1,49 @@
+###
+# ============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=vFWsim
+
+ueb.source.topics=${appcTopic}
+
+ueb.source.topics.${appcTopic}.servers=${appcServers}
+ueb.source.topics.${appcTopic}.apiKey=${appcApiKey}
+ueb.source.topics.${appcTopic}.apiSecret=${appcApiSecret}
+ueb.source.topics.${appcTopic}.events=org.openecomp.policy.appc.Request,org.openecomp.policy.sim.vfw.OnsetEvent
+ueb.source.topics.${appcTopic}.events.org.openecomp.policy.appc.Request.filter=CommonHeader=.*,Action=.*
+ueb.source.topics.${appcTopic}.events.org.openecomp.policy.sim.vfw.OnsetEvent.filter=appcResponseCode=.*
+ueb.source.topics.${appcTopic}.events.custom.gson=org.openecomp.policy.appc.util.Serialization,gsonPretty
+
+ueb.sink.topics=${dcaeTopic},${appcTopic}
+
+ueb.sink.topics.${dcaeTopic}.servers=${dcaeServers}
+ueb.sink.topics.${dcaeTopic}.apiKey=${dcaeApiKey}
+ueb.sink.topics.${dcaeTopic}.apiSecret=${dcaeApiSecret}
+ueb.sink.topics.${dcaeTopic}.events=org.openecomp.policy.controlloop.VirtualControlLoopEvent
+ueb.sink.topics.${dcaeTopic}.events.custom.gson=org.openecomp.policy.controlloop.util.Serialization,gsonPretty
+
+ueb.sink.topics.${appcTopic}.servers=${appcServers}
+ueb.sink.topics.${appcTopic}.apiKey=${appcApiKey}
+ueb.sink.topics.${appcTopic}.apiSecret=${appcApiSecret}
+ueb.sink.topics.${appcTopic}.events=org.openecomp.policy.appc.Response
+ueb.sink.topics.${appcTopic}.events.custom.gson=org.openecomp.policy.appc.util.Serialization,gsonPretty
+
+rules.groupId=org.openecomp.policy.drools-applications
+rules.artifactId=vfwsim
+rules.version=${dependenciesVersion}
diff --git a/controlloop/templates/template.demo.v1.0.0/archetype-closedloop-demo-rules/src/main/resources/archetype-resources/src/main/config/vFWsim-controller.rest.json b/controlloop/templates/template.demo.v1.0.0/archetype-closedloop-demo-rules/src/main/resources/archetype-resources/src/main/config/vFWsim-controller.rest.json
new file mode 100644
index 000000000..23840c48b
--- /dev/null
+++ b/controlloop/templates/template.demo.v1.0.0/archetype-closedloop-demo-rules/src/main/resources/archetype-resources/src/main/config/vFWsim-controller.rest.json
@@ -0,0 +1,31 @@
+{
+ "controller.name": "vFWsim",
+
+ "ueb.source.topics": "${appcTopic}",
+
+ "ueb.source.topics.${appcTopic}.servers": "${appcServers}",
+ "ueb.source.topics.${appcTopic}.apiKey": "${appcApiKey}",
+ "ueb.source.topics.${appcTopic}.apiSecret": "${appcApiSecret}",
+ "ueb.source.topics.${appcTopic}.events": "org.openecomp.policy.appc.Request,org.openecomp.policy.sim.vfw.OnsetEvent",
+ "ueb.source.topics.${appcTopic}.events.org.openecomp.policy.appc.Request.filter": "CommonHeader=.*,Action=.*",
+ "ueb.source.topics.${appcTopic}.events.org.openecomp.policy.sim.vfw.OnsetEvent.filter": "appcResponseCode=.*",
+ "ueb.source.topics.${appcTopic}.events.custom.gson": "org.openecomp.policy.appc.util.Serialization,gsonPretty",
+
+ "ueb.sink.topics": "${dcaeTopic},${appcTopic}",
+
+ "ueb.sink.topics.${dcaeTopic}.servers": "${dcaeServers}",
+ "ueb.sink.topics.${dcaeTopic}.apiKey": "${dcaeApiKey}",
+ "ueb.sink.topics.${dcaeTopic}.apiSecret": "${dcaeApiSecret}",
+ "ueb.sink.topics.${dcaeTopic}.events": "org.openecomp.policy.controlloop.VirtualControlLoopEvent",
+ "ueb.sink.topics.${dcaeTopic}.events.custom.gson": "org.openecomp.policy.controlloop.util.Serialization,gsonPretty",
+
+ "ueb.sink.topics.${appcTopic}.servers": "${appcServers}",
+ "ueb.sink.topics.${appcTopic}.apiKey": "${appcApiKey}",
+ "ueb.sink.topics.${appcTopic}.apiSecret": "${appcApiSecret}",
+ "ueb.sink.topics.${appcTopic}.events": "org.openecomp.policy.appc.Response",
+ "ueb.sink.topics.${appcTopic}.events.custom.gson": "org.openecomp.policy.appc.util.Serialization,gsonPretty",
+
+ "rules.groupId": "org.openecomp.policy.drools-applications",
+ "rules.artifactId": "vfwsim",
+ "rules.version": "${dependenciesVersion}"
+} \ No newline at end of file
diff --git a/controlloop/templates/template.demo.v1.0.0/archetype-closedloop-demo-rules/src/main/resources/archetype-resources/src/main/config/vfwsim-onset.json b/controlloop/templates/template.demo.v1.0.0/archetype-closedloop-demo-rules/src/main/resources/archetype-resources/src/main/config/vfwsim-onset.json
new file mode 100644
index 000000000..dd559c039
--- /dev/null
+++ b/controlloop/templates/template.demo.v1.0.0/archetype-closedloop-demo-rules/src/main/resources/archetype-resources/src/main/config/vfwsim-onset.json
@@ -0,0 +1,5 @@
+{
+ "dcaeTopic": "${dcaeTopic}",
+ "appcTopic": "${appcTopic}",
+ "appcResponseCode": 400
+}
diff --git a/controlloop/templates/template.demo.v1.0.0/archetype-closedloop-demo-rules/src/main/resources/archetype-resources/src/main/resources/ControlLoopDemo__closedLoopControlName__.drl b/controlloop/templates/template.demo.v1.0.0/archetype-closedloop-demo-rules/src/main/resources/archetype-resources/src/main/resources/ControlLoopDemo__closedLoopControlName__.drl
new file mode 100644
index 000000000..98b7b060c
--- /dev/null
+++ b/controlloop/templates/template.demo.v1.0.0/archetype-closedloop-demo-rules/src/main/resources/archetype-resources/src/main/resources/ControlLoopDemo__closedLoopControlName__.drl
@@ -0,0 +1,1140 @@
+/*-
+ * ============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=========================================================
+ */
+
+package org.onap.policy.controlloop;
+
+import java.util.List;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.UUID;
+
+import org.onap.policy.controlloop.VirtualControlLoopEvent;
+import org.onap.policy.controlloop.ControlLoopEventStatus;
+import org.onap.policy.controlloop.VirtualControlLoopNotification;
+import org.onap.policy.controlloop.ControlLoopNotificationType;
+import org.onap.policy.controlloop.ControlLoopOperation;
+import org.onap.policy.controlloop.ControlLoopOperationWrapper;
+import org.onap.policy.controlloop.ControlLoopException;
+
+import org.onap.policy.aai.AAINQF199.AAINQF199CloudRegion;
+import org.onap.policy.aai.AAINQF199.AAINQF199ExtraProperties;
+import org.onap.policy.aai.AAINQF199.AAINQF199ExtraProperty;
+import org.onap.policy.aai.AAINQF199.AAINQF199GenericVNF;
+import org.onap.policy.aai.AAINQF199.AAINQF199InstanceFilters;
+import org.onap.policy.aai.AAINQF199.AAINQF199InventoryResponseItem;
+import org.onap.policy.aai.AAINQF199.AAINQF199InventoryResponseItems;
+import org.onap.policy.aai.AAINQF199.AAINQF199Manager;
+import org.onap.policy.aai.AAINQF199.AAINQF199NamedQuery;
+import org.onap.policy.aai.AAINQF199.AAINQF199QueryParameters;
+import org.onap.policy.aai.AAINQF199.AAINQF199Request;
+import org.onap.policy.aai.AAINQF199.AAINQF199RequestWrapper;
+import org.onap.policy.aai.AAINQF199.AAINQF199Response;
+import org.onap.policy.aai.AAINQF199.AAINQF199ResponseWrapper;
+import org.onap.policy.aai.AAINQF199.AAINQF199ServiceInstance;
+import org.onap.policy.aai.AAINQF199.AAINQF199Tenant;
+import org.onap.policy.aai.AAINQF199.AAINQF199VfModule;
+import org.onap.policy.aai.AAINQF199.AAINQF199VServer;
+import org.onap.policy.aai.util.Serialization;
+
+import org.onap.policy.appc.CommonHeader;
+import org.onap.policy.appc.Request;
+import org.onap.policy.appc.Response;
+import org.onap.policy.appc.ResponseCode;
+import org.onap.policy.appc.ResponseStatus;
+import org.onap.policy.appc.ResponseValue;
+
+import org.onap.policy.controlloop.eventmanager.ControlLoopEventManager;
+import org.onap.policy.vnf.trafficgenerator.PGRequest;
+import org.onap.policy.vnf.trafficgenerator.PGStream;
+import org.onap.policy.vnf.trafficgenerator.PGStreams;
+
+import org.onap.policy.mso.MSOManager;
+import org.onap.policy.mso.MSORequest;
+import org.onap.policy.mso.MSORequestStatus;
+import org.onap.policy.mso.MSORequestDetails;
+import org.onap.policy.mso.MSOModelInfo;
+import org.onap.policy.mso.MSOCloudConfiguration;
+import org.onap.policy.mso.MSORequestInfo;
+import org.onap.policy.mso.MSORequestParameters;
+import org.onap.policy.mso.MSORelatedInstanceListElement;
+import org.onap.policy.mso.MSORelatedInstance;
+import org.onap.policy.mso.MSOResponse;
+
+import org.openecomp.policy.drools.system.PolicyEngine;
+
+//
+// These parameters are required to build the runtime policy
+//
+declare Params
+ closedLoopControlName : String
+ actor : String
+ aaiURL : String
+ aaiUsername : String
+ aaiPassword : String
+ msoURL : String
+ msoUsername : String
+ msoPassword : String
+ aaiNamedQueryUUID : String
+ aaiPatternMatch : int
+ notificationTopic : String
+ appcTopic : String
+end
+
+/*
+*
+* Called once and only once to insert the parameters into working memory for this Closed Loop policy.
+* NOTE: If this file is to be used as a template to be used with the policy BRMS GW, please comment out this line
+* as the BRMS_GW already generates a SETUP rule
+*
+*/
+rule "${policyName}.SETUP"
+ when
+ then
+ System.out.println("rule SETUP is triggered.");
+ Params params = new Params();
+ params.setClosedLoopControlName("${closedLoopControlName}");
+ params.setActor("${actor}");
+ params.setAaiURL("${aaiURL}");
+ params.setAaiUsername("${aaiUsername}");
+ params.setAaiPassword("${aaiPassword}");
+ params.setMsoURL("${msoURL}");
+ params.setMsoUsername("${msoUsername}");
+ params.setMsoPassword("${msoPassword}");
+ params.setAaiNamedQueryUUID("${aaiNamedQueryUUID}");
+ params.setAaiPatternMatch(${aaiPatternMatch});
+ params.setNotificationTopic("${notificationTopic}");
+ params.setAppcTopic("${appcTopic}");
+ //
+ // This stays in memory as long as the rule is alive and running
+ //
+ insert(params);
+end
+
+
+/*
+*
+* This rule responds to DCAE Events
+*
+*/
+rule "${policyName}.EVENT"
+ when
+ $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" )
+ $event : VirtualControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName(), closedLoopEventStatus == ControlLoopEventStatus.ONSET )
+ not ( ControlLoopEventManager( closedLoopControlName == $event.closedLoopControlName ))
+ then
+ System.out.println("rule EVENT is triggered.");
+ try {
+ //
+ // Check the requestID in the event to make sure it is not null before we create the EventManager.
+ // The EventManager 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 from DCAE event";
+ notification.policyName = drools.getRule().getName();
+ notification.policyScope = "${policyScope}";
+ notification.policyVersion = "${policyVersion}";
+ //
+ // Let interested parties know
+ //
+ try {
+ System.out.println(Serialization.gsonPretty.toJson(notification));
+ PolicyEngine.manager.deliver($params.getNotificationTopic(), notification);
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.out.println("Can't deliver notification: " + notification);
+ }
+ //
+ // Retract it from memory
+ //
+ retract($event);
+ System.out.println("Event with requestID=null has been retracted.");
+ } else {
+ //
+ // Create an EventManager
+ //
+ ControlLoopEventManager manager = new ControlLoopEventManager($params.getClosedLoopControlName(), $event.requestID);
+ //
+ // Determine if EventManager can actively process the event (i.e. syntax)
+ //
+ VirtualControlLoopNotification notification = manager.activate($event);
+ notification.from = "policy";
+ 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
+ //
+ try {
+ System.out.println(Serialization.gsonPretty.toJson(notification));
+ PolicyEngine.manager.deliver($params.getNotificationTopic(), notification);
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.out.println("Can't deliver notification: " + notification);
+ }
+ } else {
+ //
+ // Let interested parties know
+ //
+ try {
+ System.out.println(Serialization.gsonPretty.toJson(notification));
+ PolicyEngine.manager.deliver($params.getNotificationTopic(), notification);
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.out.println("Can't deliver notification: " + 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 same RequestIDs
+ // and for different RequestIDs but with the same closedLoopControlName and target.
+ //
+ }
+ //
+ } catch (Exception e) {
+ e.printStackTrace();
+ 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}";
+ //
+ //
+ //
+ try {
+ System.out.println(Serialization.gsonPretty.toJson(notification));
+ PolicyEngine.manager.deliver($params.getNotificationTopic(), notification);
+ } catch (Exception e1) {
+ System.out.println("Can't deliver notification: " + notification);
+ e1.printStackTrace();
+ }
+ //
+ // Retract the event
+ //
+ retract($event);
+ }
+end
+
+/*
+*
+* This rule happens when we got a valid ONSET, closed loop is enabled and an Event Manager
+* is created. We can start the operations for this closed loop.
+*
+*/
+rule "${policyName}.EVENT.MANAGER"
+ when
+ $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" )
+ $event : VirtualControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName(), closedLoopEventStatus == ControlLoopEventStatus.ONSET )
+ $manager : ControlLoopEventManager( closedLoopControlName == $event.closedLoopControlName, controlLoopResult == null)
+ then
+ System.out.println("rule EVENT.MANAGER is triggered.");
+ //
+ // Check which event this is.
+ //
+ ControlLoopEventManager.NEW_EVENT_STATUS eventStatus = $manager.onNewEvent($event);
+ //
+ // 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 != ControlLoopEventManager.NEW_EVENT_STATUS.FIRST_ONSET) {
+ System.out.println("Retracting "+eventStatus+" Event.");
+ retract($event);
+ return;
+ }
+ //
+ // Now the event in memory is first onset event
+ //
+ try {
+ //
+ // Pull the known AAI field from the Event
+ //
+ // generic-vnf is needed for vFirewall case
+ // vserver-name is needed for vLoadBalancer case
+ //
+ String genericVNF = $event.AAI.get("generic-vnf.vnf-id");
+ String vserver = $event.AAI.get("vserver.vserver-name");
+ //
+ // Check if we are implementing a simple pattern match.
+ //
+ if ($params.getAaiPatternMatch() == 1) {
+ //
+ // Yes
+ //
+ //Basic naming characteristics:
+ //VF Name (9 char)+VM name (13 char total)+VFC (19 char total)
+ //Example:
+ //VF Name (9 characters): cscf0001v
+ //VM Name(13 characters): cscf0001vm001
+ //VFC name(19 characters): cscf0001vm001cfg001
+ //
+ // zdfw1fwl01fwl02 or zdfw1fwl01fwl01
+ // replaced with
+ // zdfw1fwl01pgn02 or zdfw1fwl01pgn01
+ //
+ int index = genericVNF.lastIndexOf("fwl");
+ if (index == -1) {
+ System.err.println("The generic-vnf.vnf-id from DCAE Event is not valid.");
+ } else {
+ genericVNF = genericVNF.substring(0, index) + "pgn" + genericVNF.substring(index+"fwl".length());
+ }
+ //
+ // Construct an APPC request
+ //
+ ControlLoopOperation operation = new ControlLoopOperation();
+ operation.actor = $params.getActor();
+ operation.operation = "ModifyConfig";
+ operation.target = $event.target;
+ //
+ // Create operationWrapper
+ //
+ ControlLoopOperationWrapper operationWrapper = new ControlLoopOperationWrapper($event.requestID, operation);
+ //
+ // insert operationWrapper into memory
+ //
+ insert(operationWrapper);
+ //
+ Request request = new Request();
+ request.CommonHeader = new CommonHeader();
+ request.CommonHeader.RequestID = $event.requestID;
+ request.Action = operation.operation;
+ request.Payload = new HashMap<String, Object>();
+ //
+ // Fill in the payload
+ //
+ request.Payload.put("generic-vnf.vnf-id", genericVNF);
+ //
+ PGRequest pgRequest = new PGRequest();
+ pgRequest.pgStreams = new PGStreams();
+
+ PGStream pgStream;
+ for(int i = 0; i < 5; i++){
+ pgStream = new PGStream();
+ pgStream.streamId = "fw_udp"+(i+1);
+ pgStream.isEnabled = "true";
+ pgRequest.pgStreams.pgStream.add(pgStream);
+ }
+ request.Payload.put("pg-streams", pgRequest.pgStreams);
+
+ if (request != null) {
+ //
+ // Insert request into memory
+ //
+ insert(request);
+ //
+ // Tell interested parties we are performing this Operation
+ //
+ VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
+ notification.notification = ControlLoopNotificationType.OPERATION;
+ // message and history ??
+ notification.from = "policy";
+ notification.policyName = drools.getRule().getName();
+ notification.policyScope = "${policyScope}";
+ notification.policyVersion = "${policyVersion}";
+ try {
+ System.out.println(Serialization.gsonPretty.toJson(notification));
+ PolicyEngine.manager.deliver($params.getNotificationTopic(), notification);
+ } catch (Exception e) {
+ System.out.println("Can't deliver notification: " + notification);
+ e.printStackTrace();
+ }
+ //
+ // Now send the operation request
+ //
+ if (request instanceof Request) {
+ try {
+ System.out.println("APPC request sent:");
+ System.out.println(Serialization.gsonPretty.toJson(request));
+ PolicyEngine.manager.deliver($params.getAppcTopic(), request);
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.out.println("Can't deliver request: " + request);
+ }
+ }
+ } else {
+ //
+ // what happens if it is null
+ //
+ }
+ //
+ } else {
+ //
+ // create AAI named-query request with UUID started with "F199"
+ //
+ AAINQF199Request aainqf199request = new AAINQF199Request();
+ AAINQF199QueryParameters aainqf199queryparam = new AAINQF199QueryParameters();
+ AAINQF199NamedQuery aainqf199namedquery = new AAINQF199NamedQuery();
+ AAINQF199InstanceFilters aainqf199instancefilter = new AAINQF199InstanceFilters();
+ //
+ // queryParameters
+ //
+ aainqf199namedquery.namedQueryUUID = UUID.fromString($params.getAaiNamedQueryUUID());
+ aainqf199queryparam.namedQuery = aainqf199namedquery;
+ aainqf199request.queryParameters = aainqf199queryparam;
+ //
+ // instanceFilters
+ //
+ Map aainqf199instancefiltermap = new HashMap();
+ Map aainqf199instancefiltermapitem = new HashMap();
+ aainqf199instancefiltermapitem.put("vserver-name", vserver);
+ aainqf199instancefiltermap.put("vserver", aainqf199instancefiltermapitem);
+ aainqf199instancefilter.instanceFilter.add(aainqf199instancefiltermap);
+ aainqf199request.instanceFilters = aainqf199instancefilter;
+ //
+ // print aainqf199request for debug
+ //
+ System.out.println("AAI Request sent:");
+ System.out.println(Serialization.gsonPretty.toJson(aainqf199request));
+ //
+ // Create AAINQF199RequestWrapper
+ //
+ AAINQF199RequestWrapper aainqf199RequestWrapper = new AAINQF199RequestWrapper($event.requestID, aainqf199request);
+ //
+ // insert aainqf199request into memory
+ //
+ insert(aainqf199RequestWrapper);
+ }
+ //
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+end
+
+/*
+*
+* This rule happens when we got a valid ONSET, closed loop is enabled, an Event Manager
+* is created, AAI Manager and AAI Request are ready in memory. We can start sending query to AAI and then wait for response.
+*
+*/
+rule "${policyName}.EVENT.MANAGER.AAINQF199REQUEST"
+ when
+ $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" )
+ $event : VirtualControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName(), closedLoopEventStatus == ControlLoopEventStatus.ONSET )
+ $manager : ControlLoopEventManager( closedLoopControlName == $event.closedLoopControlName )
+ $aainqf199RequestWrapper : AAINQF199RequestWrapper(requestID == $event.requestID)
+ then
+ System.out.println("rule EVENT.MANAGER.AAINQF199REQUEST is triggered.");
+ //
+ // send the request
+ //
+ AAINQF199Response aainqf199response = AAINQF199Manager.postQuery($params.getAaiURL(), $params.getAaiUsername(), $params.getAaiPassword(),
+ $aainqf199RequestWrapper.aainqf199request, $event.requestID);
+
+ //
+ // Check AAI response
+ //
+ if (aainqf199response == null) {
+ System.err.println("Failed to get AAI response");
+ //
+ // Fail and retract everything
+ //
+ retract($event);
+ retract($manager);
+ retract($aainqf199RequestWrapper);
+ } else {
+ //
+ // Create AAINQF199ResponseWrapper
+ //
+ AAINQF199ResponseWrapper aainqf199ResponseWrapper = new AAINQF199ResponseWrapper($event.requestID, aainqf199response);
+ //
+ // insert aainqf199ResponseWrapper to memeory
+ //
+ insert(aainqf199ResponseWrapper);
+ }
+end
+
+/*
+*
+* This rule happens when we got a valid AAI response. We can start sending request to APPC or MSO now.
+*
+*/
+rule "${policyName}.EVENT.MANAGER.AAINQF199RESPONSE"
+ when
+ $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" )
+ $event : VirtualControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName(), closedLoopEventStatus == ControlLoopEventStatus.ONSET )
+ $manager : ControlLoopEventManager( closedLoopControlName == $event.closedLoopControlName )
+ $aainqf199RequestWrapper : AAINQF199RequestWrapper(requestID == $event.requestID)
+ $aainqf199ResponseWrapper : AAINQF199ResponseWrapper(requestID == $event.requestID)
+ then
+ System.out.println("rule EVENT.MANAGER.AAINQF199RESPONSE is triggered.");
+ //
+ // Extract related fields out of AAINQF199RESPONSE
+ //
+ String vnfItemVnfId, vnfItemVnfType, vnfItemPersonaModelId, vnfItemPersonaModelVersion, vnfItemModelName,
+ vnfItemModelVersion, vnfItemModelNameVersionId, serviceItemServiceInstanceId, serviceItemPersonaModelId,
+ serviceItemModelName, serviceItemModelType, serviceItemModelVersion, serviceItemModelNameVersionId,
+ vfModuleItemVfModuleName, vfModuleItemPersonaModelId, vfModuleItemPersonaModelVersion, vfModuleItemModelName,
+ vfModuleItemModelNameVersionId, tenantItemTenantId, cloudRegionItemCloudRegionId;
+ try {
+ //
+ // vnfItem
+ //
+ vnfItemVnfId = $aainqf199ResponseWrapper.aainqf199response.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).genericVNF.vnfID;
+ vnfItemVnfType = $aainqf199ResponseWrapper.aainqf199response.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).genericVNF.vnfType;
+ vnfItemVnfType = vnfItemVnfType.substring(vnfItemVnfType.lastIndexOf("/")+1);
+ vnfItemPersonaModelId = $aainqf199ResponseWrapper.aainqf199response.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).genericVNF.personaModelId;
+ vnfItemPersonaModelVersion = $aainqf199ResponseWrapper.aainqf199response.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).genericVNF.personaModelVersion;
+ vnfItemModelName = $aainqf199ResponseWrapper.aainqf199response.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).extraProperties.extraProperty.get(0).propertyValue;
+ vnfItemModelVersion = $aainqf199ResponseWrapper.aainqf199response.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).extraProperties.extraProperty.get(2).propertyValue;
+ vnfItemModelNameVersionId = $aainqf199ResponseWrapper.aainqf199response.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).extraProperties.extraProperty.get(4).propertyValue;
+ //
+ // serviceItem
+ //
+ serviceItemServiceInstanceId = $aainqf199ResponseWrapper.aainqf199response.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).serviceInstance.serviceInstanceID;
+ serviceItemPersonaModelId = $aainqf199ResponseWrapper.aainqf199response.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).serviceInstance.personaModelId;
+ serviceItemModelName = $aainqf199ResponseWrapper.aainqf199response.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).extraProperties.extraProperty.get(0).propertyValue;
+ serviceItemModelType = $aainqf199ResponseWrapper.aainqf199response.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).extraProperties.extraProperty.get(1).propertyValue;
+ serviceItemModelVersion = $aainqf199ResponseWrapper.aainqf199response.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).serviceInstance.personaModelVersion;
+ serviceItemModelNameVersionId = $aainqf199ResponseWrapper.aainqf199response.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).extraProperties.extraProperty.get(4).propertyValue;
+ //
+ // Find the index for base vf module and non-base vf module
+ //
+ int baseIndex = -1;
+ int nonBaseIndex = -1;
+ List<AAINQF199InventoryResponseItem> inventoryItems = $aainqf199ResponseWrapper.aainqf199response.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).items.inventoryResponseItems;
+ for (AAINQF199InventoryResponseItem m : inventoryItems) {
+ if (m.vfModule != null && m.vfModule.isBaseVfModule == true) {
+ baseIndex = inventoryItems.indexOf(m);
+ } else if (m.vfModule != null && m.vfModule.isBaseVfModule == false && m.vfModule.orchestrationStatus == null) {
+ nonBaseIndex = inventoryItems.indexOf(m);
+ }
+ //
+ if (baseIndex != -1 && nonBaseIndex != -1) {
+ break;
+ }
+ }
+ //
+ // Report the error if either base vf module or non-base vf module is not found
+ //
+ if (baseIndex == -1 || nonBaseIndex == -1) {
+ System.err.println("Either base or non-base vf module is not found from AAI response.");
+ retract($aainqf199RequestWrapper);
+ retract($aainqf199ResponseWrapper);
+ retract($manager);
+ retract($event);
+ return;
+ }
+ //
+ // This comes from the base module
+ //
+ vfModuleItemVfModuleName = $aainqf199ResponseWrapper.aainqf199response.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).items.inventoryResponseItems.get(baseIndex).vfModule.vfModuleName;
+ vfModuleItemVfModuleName = vfModuleItemVfModuleName.replace("Vfmodule", "vDNS");
+ //
+ // vfModuleItem - NOT the base module
+ //
+ vfModuleItemPersonaModelId = $aainqf199ResponseWrapper.aainqf199response.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).items.inventoryResponseItems.get(nonBaseIndex).vfModule.personaModelId;
+ vfModuleItemPersonaModelVersion = $aainqf199ResponseWrapper.aainqf199response.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).items.inventoryResponseItems.get(nonBaseIndex).vfModule.personaModelVersion;
+ vfModuleItemModelName = $aainqf199ResponseWrapper.aainqf199response.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).items.inventoryResponseItems.get(nonBaseIndex).extraProperties.extraProperty.get(0).propertyValue;
+ vfModuleItemModelNameVersionId = $aainqf199ResponseWrapper.aainqf199response.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).items.inventoryResponseItems.get(nonBaseIndex).extraProperties.extraProperty.get(4).propertyValue;
+ //
+ // tenantItem
+ //
+ tenantItemTenantId = $aainqf199ResponseWrapper.aainqf199response.inventoryResponseItems.get(0).items.inventoryResponseItems.get(1).tenant.tenantId;
+ //
+ // cloudRegionItem
+ //
+ cloudRegionItemCloudRegionId = $aainqf199ResponseWrapper.aainqf199response.inventoryResponseItems.get(0).items.inventoryResponseItems.get(1).items.inventoryResponseItems.get(0).cloudRegion.cloudRegionId;
+ //
+ } catch (Exception e) {
+ e.printStackTrace();
+ 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}";
+ //
+ try {
+ System.out.println(Serialization.gsonPretty.toJson(notification));
+ PolicyEngine.manager.deliver($params.getNotificationTopic(), notification);
+ } catch (Exception e1) {
+ System.out.println("Can't deliver notification: " + notification);
+ e1.printStackTrace();
+ }
+ //
+ notification.notification = ControlLoopNotificationType.FINAL_FAILURE;
+ notification.message = "Invalid named-query response from AAI";
+ //
+ try {
+ System.out.println(Serialization.gsonPretty.toJson(notification));
+ PolicyEngine.manager.deliver($params.getNotificationTopic(), notification);
+ } catch (Exception e1) {
+ System.out.println("Can't deliver notification: " + notification);
+ e1.printStackTrace();
+ }
+ //
+ // Retract everything
+ //
+ retract($aainqf199RequestWrapper);
+ retract($aainqf199ResponseWrapper);
+ retract($manager);
+ retract($event);
+ return;
+ }
+ //
+ // Extracted fields should not be null
+ //
+ if ((vnfItemVnfId == null) || (vnfItemVnfType == null) ||
+ (vnfItemPersonaModelId == null) || (vnfItemModelName == null) ||
+ (vnfItemModelVersion == null) || (vnfItemModelNameVersionId == null) ||
+ (serviceItemServiceInstanceId == null) || (serviceItemModelName == null) ||
+ (serviceItemModelType == null) || (serviceItemModelVersion == null) ||
+ (serviceItemModelNameVersionId == null) || (vfModuleItemVfModuleName == null) ||
+ (vfModuleItemPersonaModelId == null) || (vfModuleItemPersonaModelVersion == null) ||
+ (vfModuleItemModelName == null) || (vfModuleItemModelNameVersionId == null) ||
+ (tenantItemTenantId == null) || (cloudRegionItemCloudRegionId == null)) {
+ //
+ System.err.println("some fields are missing from AAI response.");
+ //
+ // Fail and retract everything
+ //
+ retract($aainqf199RequestWrapper);
+ retract($aainqf199ResponseWrapper);
+ retract($manager);
+ retract($event);
+ return;
+ }
+ //
+ // We don't need them any more
+ //
+ retract($aainqf199ResponseWrapper);
+ retract($aainqf199RequestWrapper);
+ //
+ // check the actor of this closed loop
+ //
+ switch ($params.getActor()) {
+ case "APPC":
+ {
+ //
+ // Construct an APPC request
+ //
+ ControlLoopOperation operation = new ControlLoopOperation();
+ operation.actor = $params.getActor();
+ operation.operation = "ModifyConfig";
+ operation.target = $event.target;
+ //
+ // Create operationWrapper
+ //
+ ControlLoopOperationWrapper operationWrapper = new ControlLoopOperationWrapper($event.requestID, operation);
+ //
+ // insert operationWrapper into memory
+ //
+ insert(operationWrapper);
+ //
+ Request request = new Request();
+ request.CommonHeader = new CommonHeader();
+ request.CommonHeader.RequestID = $event.requestID;
+ request.Action = operation.operation;
+ request.Payload = new HashMap<String, Object>();
+ //
+ // Fill in the payload
+ // Hardcode genericVNF for now since AAI has not been ready for vFirewall demo case
+ //
+ String genericVNF = "zdfw1fwl01pgn02";
+ request.Payload.put("generic-vnf.vnf-id", genericVNF);
+ //
+ PGRequest pgRequest = new PGRequest();
+ pgRequest.pgStreams = new PGStreams();
+
+ PGStream pgStream;
+ for(int i = 0; i < 5; i++){
+ pgStream = new PGStream();
+ pgStream.streamId = "fw_udp"+(i+1);
+ pgStream.isEnabled = "true";
+ pgRequest.pgStreams.pgStream.add(pgStream);
+ }
+ request.Payload.put("pg-streams", pgRequest.pgStreams);
+
+ if (request != null) {
+ //
+ // Insert request into memory
+ //
+ insert(request);
+ //
+ // Tell interested parties we are performing this Operation
+ //
+ VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
+ notification.notification = ControlLoopNotificationType.OPERATION;
+ // message and history ??
+ notification.from = "policy";
+ notification.policyName = drools.getRule().getName();
+ notification.policyScope = "${policyScope}";
+ notification.policyVersion = "${policyVersion}";
+ try {
+ System.out.println(Serialization.gsonPretty.toJson(notification));
+ PolicyEngine.manager.deliver($params.getNotificationTopic(), notification);
+ } catch (Exception e) {
+ System.out.println("Can't deliver notification: " + notification);
+ e.printStackTrace();
+ }
+ //
+ // Now send the operation request
+ //
+ if (request instanceof Request) {
+ try {
+ System.out.println("APPC request sent:");
+ System.out.println(Serialization.gsonPretty.toJson(request));
+ PolicyEngine.manager.deliver($params.getAppcTopic(), request);
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.out.println("Can't deliver request: " + request);
+ }
+ }
+ } else {
+ //
+ // what happens if it is null
+ //
+ }
+ }
+ break;
+ case "MSO":
+ {
+ //
+ // Construct an operation
+ //
+ ControlLoopOperation operation = new ControlLoopOperation();
+ operation.actor = $params.getActor();
+ operation.operation = "createModuleInstance";
+ operation.target = $event.target;
+ //
+ // Create operationWrapper
+ //
+ ControlLoopOperationWrapper operationWrapper = new ControlLoopOperationWrapper($event.requestID, operation);
+ //
+ // Construct an MSO request
+ //
+ MSORequest request = new MSORequest();
+ request.requestDetails = new MSORequestDetails();
+ request.requestDetails.modelInfo = new MSOModelInfo();
+ request.requestDetails.cloudConfiguration = new MSOCloudConfiguration();
+ request.requestDetails.requestInfo = new MSORequestInfo();
+ request.requestDetails.requestParameters = new MSORequestParameters();
+ request.requestDetails.requestParameters.userParams = null;
+ //
+ // cloudConfiguration
+ //
+ request.requestDetails.cloudConfiguration.lcpCloudRegionId = cloudRegionItemCloudRegionId;
+ request.requestDetails.cloudConfiguration.tenantId = tenantItemTenantId;
+ //
+ // modelInfo
+ //
+ request.requestDetails.modelInfo.modelType = "vfModule";
+ request.requestDetails.modelInfo.modelInvariantId = vfModuleItemPersonaModelId;
+ request.requestDetails.modelInfo.modelNameVersionId = vfModuleItemModelNameVersionId;
+ request.requestDetails.modelInfo.modelName = vfModuleItemModelName;
+ request.requestDetails.modelInfo.modelVersion = vfModuleItemPersonaModelVersion;
+ //
+ // requestInfo
+ //
+ request.requestDetails.requestInfo.instanceName = vfModuleItemVfModuleName;
+ request.requestDetails.requestInfo.source = "POLICY";
+ request.requestDetails.requestInfo.suppressRollback = false;
+ //
+ // relatedInstanceList
+ //
+ MSORelatedInstanceListElement relatedInstanceListElement1 = new MSORelatedInstanceListElement();
+ MSORelatedInstanceListElement relatedInstanceListElement2 = new MSORelatedInstanceListElement();
+ relatedInstanceListElement1.relatedInstance = new MSORelatedInstance();
+ relatedInstanceListElement2.relatedInstance = new MSORelatedInstance();
+ //
+ relatedInstanceListElement1.relatedInstance.instanceId = serviceItemServiceInstanceId;
+ relatedInstanceListElement1.relatedInstance.modelInfo = new MSOModelInfo();
+ relatedInstanceListElement1.relatedInstance.modelInfo.modelType = "service";
+ relatedInstanceListElement1.relatedInstance.modelInfo.modelInvariantId = serviceItemPersonaModelId;
+ relatedInstanceListElement1.relatedInstance.modelInfo.modelNameVersionId = serviceItemModelNameVersionId;
+ relatedInstanceListElement1.relatedInstance.modelInfo.modelName = serviceItemModelName;
+ relatedInstanceListElement1.relatedInstance.modelInfo.modelVersion = serviceItemModelVersion;
+ //
+ relatedInstanceListElement2.relatedInstance.instanceId = vnfItemVnfId;
+ relatedInstanceListElement2.relatedInstance.modelInfo = new MSOModelInfo();
+ relatedInstanceListElement2.relatedInstance.modelInfo.modelType = "vnf";
+ relatedInstanceListElement2.relatedInstance.modelInfo.modelInvariantId = vnfItemPersonaModelId;
+ relatedInstanceListElement2.relatedInstance.modelInfo.modelNameVersionId = vnfItemModelNameVersionId;
+ relatedInstanceListElement2.relatedInstance.modelInfo.modelName = vnfItemModelName;
+ relatedInstanceListElement2.relatedInstance.modelInfo.modelVersion = vnfItemModelVersion;
+ relatedInstanceListElement2.relatedInstance.modelInfo.modelCustomizationName = vnfItemVnfType;
+ //
+ request.requestDetails.relatedInstanceList.add(relatedInstanceListElement1);
+ request.requestDetails.relatedInstanceList.add(relatedInstanceListElement2);
+ //
+ // print MSO request for debug
+ //
+ System.out.println("MSO request sent:");
+ System.out.println(Serialization.gsonPretty.toJson(request));
+ //
+ //
+ //
+ if (request != null) {
+ //
+ // Tell interested parties we are performing this Operation
+ //
+ VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
+ notification.notification = ControlLoopNotificationType.OPERATION;
+ notification.from = "policy";
+ notification.policyName = drools.getRule().getName();
+ notification.policyScope = "${policyScope}";
+ notification.policyVersion = "${policyVersion}";
+ try {
+ System.out.println(Serialization.gsonPretty.toJson(notification));
+ PolicyEngine.manager.deliver($params.getNotificationTopic(), notification);
+ } catch (Exception e) {
+ System.out.println("Can't deliver notification: " + notification);
+ e.printStackTrace();
+ }
+ //
+ // Concatenate serviceItemServiceInstanceId and vnfItemVnfId to msoURL
+ //
+ String MSOUrl = $params.getMsoURL() + "/serviceInstances/v2/" + serviceItemServiceInstanceId + "/vnfs/" + vnfItemVnfId + "/vfModules";
+ //
+ // Call MSO
+ //
+ MSOResponse response = MSOManager.createModuleInstance(MSOUrl, $params.getMsoURL(), $params.getMsoUsername(), $params.getMsoPassword(), request);
+
+
+ if (response != null) {
+ //
+ // Assign requestId
+ //
+ request.requestId = $event.requestID.toString();
+ response.request.requestId = $event.requestID.toString();
+ //
+ // Insert facts
+ //
+ insert(operationWrapper);
+ insert(request);
+ insert(response);
+ } else {
+ //
+ // MSO request not even accepted
+ //
+ notification.message = operationWrapper.operation.toMessage();
+ operationWrapper.operation.message = operationWrapper.operation.toMessage();
+ operationWrapper.operation.outcome = "FAILURE_EXCEPTION";
+ $manager.setControlLoopResult("FAILURE_EXCEPTION");
+ notification.history.add(operationWrapper.operation);
+ notification.notification = ControlLoopNotificationType.OPERATION_FAILURE;
+ //
+ // Let interested parties know
+ //
+ try {
+ System.out.println(Serialization.gsonPretty.toJson(notification));
+ PolicyEngine.manager.deliver($params.getNotificationTopic(), notification);
+ } catch (Exception e) {
+ System.out.println("Can't deliver notification: " + notification);
+ e.printStackTrace();
+ }
+ notification.notification = ControlLoopNotificationType.FINAL_FAILURE;
+ try {
+ System.out.println(Serialization.gsonPretty.toJson(notification));
+ PolicyEngine.manager.deliver($params.getNotificationTopic(), notification);
+ } catch (Exception e) {
+ System.out.println("Can't deliver notification: " + notification);
+ e.printStackTrace();
+ }
+ //
+ // Retract everything
+ //
+ retract($event);
+ retract($manager);
+ }
+ } else {
+ System.err.println("constructed MSO request is invalid.");
+ }
+ }
+ break;
+ }
+end
+
+/*
+*
+* This rule responds to APPC Response Events
+*
+*/
+rule "${policyName}.APPC.RESPONSE"
+ when
+ $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" )
+ $event : VirtualControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName(), closedLoopEventStatus == ControlLoopEventStatus.ONSET )
+ $manager : ControlLoopEventManager( closedLoopControlName == $event.closedLoopControlName )
+ $operationWrapper : ControlLoopOperationWrapper( requestID == $event.requestID )
+ $request : Request( getCommonHeader().RequestID == $event.requestID )
+ $response : Response( getCommonHeader().RequestID == $event.requestID )
+ then
+ System.out.println("rule APPC.RESPONSE is triggered.");
+ if ($response.Status == null) {
+ $operationWrapper.operation.outcome = "FAILURE_EXCEPTION";
+ $manager.setControlLoopResult("FAILURE_EXCEPTION");
+ }
+ //
+ // Get the Response Code
+ //
+ ResponseCode code = ResponseCode.toResponseCode($response.Status.Code);
+ if (code == null) {
+ $operationWrapper.operation.outcome = "FAILURE_EXCEPTION";
+ $manager.setControlLoopResult("FAILURE_EXCEPTION");
+ }
+ //
+ // Construct notification
+ //
+ VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
+ notification.from = "policy";
+ notification.policyName = drools.getRule().getName();
+ notification.policyScope = "${policyScope}";
+ notification.policyVersion = "${policyVersion}";
+ notification.message = $operationWrapper.operation.toMessage();
+ $operationWrapper.operation.message = $operationWrapper.operation.toMessage();
+ //
+ // Ok, let's figure out what APP-C's response is
+ //
+ switch (code) {
+ case ACCEPT:
+ $operationWrapper.operation.outcome = "PROCESSING";
+ break;
+ case ERROR:
+ case REJECT:
+ $operationWrapper.operation.outcome = "FAILURE_EXCEPTION";
+ $manager.setControlLoopResult("FAILURE_EXCEPTION");
+ break;
+ case SUCCESS:
+ $operationWrapper.operation.outcome = "SUCCESS";
+ $manager.setControlLoopResult("SUCCESS");
+ break;
+ case FAILURE:
+ $operationWrapper.operation.outcome = "FAILURE";
+ $manager.setControlLoopResult("FAILURE");
+ break;
+ }
+ if ($operationWrapper.operation.outcome.equals("SUCCESS")) {
+ notification.history.add($operationWrapper.operation);
+ notification.notification = ControlLoopNotificationType.OPERATION_SUCCESS;
+ //
+ // Let interested parties know
+ //
+ try {
+ System.out.println(Serialization.gsonPretty.toJson(notification));
+ PolicyEngine.manager.deliver($params.getNotificationTopic(), notification);
+ } catch (Exception e) {
+ System.out.println("Can't deliver notification: " + notification);
+ e.printStackTrace();
+ }
+ notification.notification = ControlLoopNotificationType.FINAL_SUCCESS;
+ try {
+ System.out.println(Serialization.gsonPretty.toJson(notification));
+ PolicyEngine.manager.deliver($params.getNotificationTopic(), notification);
+ } catch (Exception e) {
+ System.out.println("Can't deliver notification: " + notification);
+ e.printStackTrace();
+ }
+
+ //
+ // We are going to retract these objects from memory
+ //
+ System.out.println("Retracting everything");
+ retract($operationWrapper);
+ retract($request);
+ retract($response);
+ retract($event);
+ retract($manager);
+ } else if ($operationWrapper.operation.outcome.equals("PROCESSING")) {
+ retract($response);
+ } else {
+ notification.history.add($operationWrapper.operation);
+ notification.notification = ControlLoopNotificationType.OPERATION_FAILURE;
+ //
+ // Let interested parties know
+ //
+ try {
+ System.out.println(Serialization.gsonPretty.toJson(notification));
+ PolicyEngine.manager.deliver($params.getNotificationTopic(), notification);
+ } catch (Exception e) {
+ System.out.println("Can't deliver notification: " + notification);
+ e.printStackTrace();
+ }
+ notification.notification = ControlLoopNotificationType.FINAL_FAILURE;
+ //
+ // Let interested parties know
+ //
+ try {
+ System.out.println(Serialization.gsonPretty.toJson(notification));
+ PolicyEngine.manager.deliver($params.getNotificationTopic(), notification);
+ } catch (Exception e) {
+ System.out.println("Can't deliver notification: " + notification);
+ e.printStackTrace();
+ }
+ //
+ // We are going to retract these objects from memory
+ //
+ System.out.println("Retracting everything");
+ retract($operationWrapper);
+ retract($request);
+ retract($response);
+ retract($event);
+ retract($manager);
+ }
+
+end
+
+/*
+*
+* This rule is used to clean up APPC response
+*
+*/
+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
+ System.out.println("rule APPC.RESPONSE.CLEANUP is triggered.");
+ retract($response);
+end
+
+/*
+*
+* This rule responds to MSO Response Events
+*
+*/
+rule "${policyName}.MSO.RESPONSE"
+ when
+ $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" )
+ $event : VirtualControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName(), closedLoopEventStatus == ControlLoopEventStatus.ONSET )
+ $manager : ControlLoopEventManager( closedLoopControlName == $event.closedLoopControlName )
+ $operationWrapper : ControlLoopOperationWrapper( requestID == $event.requestID )
+ $request : MSORequest( requestId == $event.requestID.toString() )
+ $response : MSOResponse( request.requestId == $event.requestID.toString() )
+ then
+ System.out.println("rule MSO.RESPONSE is triggered.");
+ //
+ // Construct notification
+ //
+ VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
+ notification.from = "policy";
+ notification.policyName = drools.getRule().getName();
+ notification.policyScope = "${policyScope}";
+ notification.policyVersion = "${policyVersion}";
+ notification.message = $operationWrapper.operation.toMessage();
+ $operationWrapper.operation.message = $operationWrapper.operation.toMessage();
+ //
+ // The operation can either be succeeded or failed
+ //
+ if($response.request.requestStatus.requestState.equals("COMPLETE")) {
+ $operationWrapper.operation.outcome = "SUCCESS";
+ $manager.setControlLoopResult("SUCCESS");
+ notification.history.add($operationWrapper.operation);
+ notification.notification = ControlLoopNotificationType.OPERATION_SUCCESS;
+ //
+ // Let interested parties know
+ //
+ try {
+ System.out.println(Serialization.gsonPretty.toJson(notification));
+ PolicyEngine.manager.deliver($params.getNotificationTopic(), notification);
+ } catch (Exception e) {
+ System.out.println("Can't deliver notification: " + notification);
+ e.printStackTrace();
+ }
+ notification.notification = ControlLoopNotificationType.FINAL_SUCCESS;
+ //
+ // Let interested parties know
+ //
+ try {
+ System.out.println(Serialization.gsonPretty.toJson(notification));
+ PolicyEngine.manager.deliver($params.getNotificationTopic(), notification);
+ } catch (Exception e) {
+ System.out.println("Can't deliver notification: " + notification);
+ e.printStackTrace();
+ }
+ //
+ // We are going to retract these objects from memory
+ //
+ System.out.println("Retracting everything");
+ retract($operationWrapper);
+ retract($request);
+ retract($response);
+ retract($event);
+ retract($manager);
+ } else {
+ $operationWrapper.operation.outcome = "FAILURE";
+ $manager.setControlLoopResult("FAILURE");
+ notification.history.add($operationWrapper.operation);
+ notification.notification = ControlLoopNotificationType.OPERATION_FAILURE;
+ //
+ // Let interested parties know
+ //
+ try {
+ System.out.println(Serialization.gsonPretty.toJson(notification));
+ PolicyEngine.manager.deliver($params.getNotificationTopic(), notification);
+ } catch (Exception e) {
+ System.out.println("Can't deliver notification: " + notification);
+ e.printStackTrace();
+ }
+ notification.notification = ControlLoopNotificationType.FINAL_FAILURE;
+ //
+ // Let interested parties know
+ //
+ try {
+ System.out.println(Serialization.gsonPretty.toJson(notification));
+ PolicyEngine.manager.deliver($params.getNotificationTopic(), notification);
+ } catch (Exception e) {
+ System.out.println("Can't deliver notification: " + notification);
+ e.printStackTrace();
+ }
+ //
+ // We are going to retract these objects from memory
+ //
+ System.out.println("Retracting everything");
+ retract($operationWrapper);
+ retract($request);
+ retract($response);
+ retract($event);
+ retract($manager);
+ }
+end
+
+/*
+ * Sample Queries for illustration with and without arguments
+ * The results of the query can be introspected (and retracted if desired)
+ * through REST API.
+ */
+query "${policyName}.QUERY.EVENT.ONSET"
+ event : VirtualControlLoopEvent( closedLoopEventStatus == ControlLoopEventStatus.ONSET )
+end
+
+query "${policyName}.QUERY.MANAGER.RNA" (String aRequestId, Integer numOnsetsLowerBound, Boolean aActivated)
+ manager : ControlLoopEventManager( closedLoopControlName == "${closedLoopControlName}",
+ requestID.toString() == aRequestId,
+ numOnsets > numOnsetsLowerBound,
+ activated == aActivated )
+end
diff --git a/controlloop/templates/template.demo.v1.0.0/archetype-closedloop-demo-rules/src/main/resources/archetype-resources/src/main/resources/META-INF/kmodule.xml b/controlloop/templates/template.demo.v1.0.0/archetype-closedloop-demo-rules/src/main/resources/archetype-resources/src/main/resources/META-INF/kmodule.xml
new file mode 100644
index 000000000..8116d880a
--- /dev/null
+++ b/controlloop/templates/template.demo.v1.0.0/archetype-closedloop-demo-rules/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="closedloop-demo"/>
+ </kbase>
+</kmodule>
diff --git a/controlloop/templates/template.demo.v1.0.0/archetype-closedloop-demo-rules/src/test/resources/projects/basic/archetype.properties b/controlloop/templates/template.demo.v1.0.0/archetype-closedloop-demo-rules/src/test/resources/projects/basic/archetype.properties
new file mode 100644
index 000000000..6dce9747d
--- /dev/null
+++ b/controlloop/templates/template.demo.v1.0.0/archetype-closedloop-demo-rules/src/test/resources/projects/basic/archetype.properties
@@ -0,0 +1,50 @@
+###
+# ============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.openecomp.policy.demo.drools
+artifactId=closedloop-demo-rules
+version=1.0.0-SNAPSHOT
+package=org.openecomp.policy.demo.drools
+closedLoopControlName=CL-FRWL-LOW-TRAFFIC-SIG-d925ed73-8231-4d02-9545-db4e101f88f8
+policyScope=service=test;resource=FRWL;type=configuration
+policyName=FirewallDemo
+policyVersion=v1.0
+actor=APPC
+appcTopic=APPC-CL
+appcApiKey=NO-API-KEY
+appcApiSecret=NO-API-SECRET
+appcServers=server1,server2,server3
+notificationTopic=POLICY-CL-MGT
+notificationApiKey=NO-API-KEY
+notificationApiSecret=NO-API-SECRET
+notificationServers=server1,server2,server3
+dcaeTopic=DCAE-CL-EVENT
+dcaeServers=server1,server2,server3
+dcaeApiKey=NO-API-KEY
+dcaeApiSecret=NO-API-SECRET
+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/template.demo.v1.0.0/archetype-closedloop-demo-rules/src/test/resources/projects/basic/goal.txt b/controlloop/templates/template.demo.v1.0.0/archetype-closedloop-demo-rules/src/test/resources/projects/basic/goal.txt
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/controlloop/templates/template.demo.v1.0.0/archetype-closedloop-demo-rules/src/test/resources/projects/basic/goal.txt
diff --git a/controlloop/templates/template.demo.v1.0.0/pom.xml b/controlloop/templates/template.demo.v1.0.0/pom.xml
new file mode 100644
index 000000000..4a746135a
--- /dev/null
+++ b/controlloop/templates/template.demo.v1.0.0/pom.xml
@@ -0,0 +1,41 @@
+<!--
+ ============LICENSE_START=======================================================
+ drools-pdp-apps Control Loop Drools Templates
+ ================================================================================
+ 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>
+
+ <artifactId>template.demo.v1.0.0</artifactId>
+ <packaging>pom</packaging>
+
+ <parent>
+ <groupId>org.onap.policy.drools-applications</groupId>
+ <artifactId>templates</artifactId>
+ <version>1.1.0-SNAPSHOT</version>
+ </parent>
+
+ <modules>
+ <module>archetype-closedloop-demo-rules</module>
+ <module>template.demo</module>
+ </modules>
+
+
+</project>
diff --git a/controlloop/templates/template.demo.v1.0.0/template.demo/pom.xml b/controlloop/templates/template.demo.v1.0.0/template.demo/pom.xml
new file mode 100644
index 000000000..e48b78709
--- /dev/null
+++ b/controlloop/templates/template.demo.v1.0.0/template.demo/pom.xml
@@ -0,0 +1,112 @@
+<!--
+ ============LICENSE_START=======================================================
+ drools-pdp-apps Control Loop Drools Templates
+ ================================================================================
+ 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>
+
+ <artifactId>demo</artifactId>
+
+ <parent>
+ <groupId>org.onap.policy.drools-applications</groupId>
+ <artifactId>template.demo.v1.0.0</artifactId>
+ <version>1.1.0-SNAPSHOT</version>
+ </parent>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.httpcomponents</groupId>
+ <artifactId>httpclient</artifactId>
+ <version>4.5.2</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.12</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.google.code.gson</groupId>
+ <artifactId>gson</artifactId>
+ <version>2.5</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.drools</groupId>
+ <artifactId>drools-core</artifactId>
+ <version>6.3.0.Final</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.drools</groupId>
+ <artifactId>drools-compiler</artifactId>
+ <version>6.3.0.Final</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.policy.drools-applications</groupId>
+ <artifactId>events</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.policy.drools-applications</groupId>
+ <artifactId>appc</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.policy.drools-applications</groupId>
+ <artifactId>aai</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.policy.drools-applications</groupId>
+ <artifactId>mso</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.policy.drools-applications</groupId>
+ <artifactId>trafficgenerator</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.policy.drools-applications</groupId>
+ <artifactId>eventmanager</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.policy.drools-applications</groupId>
+ <artifactId>guard</artifactId>
+ <version>1.1.0-SNAPSHOT</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.policy.drools-applications</groupId>
+ <artifactId>policy-yaml</artifactId>
+ <version>1.1.0-SNAPSHOT</version>
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/controlloop/templates/template.demo.v1.0.0/template.demo/src/main/resources/archetype-resources/src/main/resources/ControlLoopDemo__closedLoopControlName__.drl b/controlloop/templates/template.demo.v1.0.0/template.demo/src/main/resources/archetype-resources/src/main/resources/ControlLoopDemo__closedLoopControlName__.drl
new file mode 100644
index 000000000..4ac822661
--- /dev/null
+++ b/controlloop/templates/template.demo.v1.0.0/template.demo/src/main/resources/archetype-resources/src/main/resources/ControlLoopDemo__closedLoopControlName__.drl
@@ -0,0 +1,1316 @@
+/*-
+ * ============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=========================================================
+ */
+
+package org.onap.policy.controlloop;
+
+import java.util.List;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.UUID;
+
+import org.onap.policy.controlloop.VirtualControlLoopEvent;
+import org.onap.policy.controlloop.ControlLoopEventStatus;
+import org.onap.policy.controlloop.VirtualControlLoopNotification;
+import org.onap.policy.controlloop.ControlLoopNotificationType;
+import org.onap.policy.controlloop.ControlLoopOperation;
+import org.onap.policy.controlloop.ControlLoopOperationWrapper;
+import org.onap.policy.controlloop.ControlLoopException;
+
+import org.onap.policy.aai.AAINQF199.AAINQF199CloudRegion;
+import org.onap.policy.aai.AAINQF199.AAINQF199ExtraProperties;
+import org.onap.policy.aai.AAINQF199.AAINQF199ExtraProperty;
+import org.onap.policy.aai.AAINQF199.AAINQF199GenericVNF;
+import org.onap.policy.aai.AAINQF199.AAINQF199InstanceFilters;
+import org.onap.policy.aai.AAINQF199.AAINQF199InventoryResponseItem;
+import org.onap.policy.aai.AAINQF199.AAINQF199InventoryResponseItems;
+import org.onap.policy.aai.AAINQF199.AAINQF199Manager;
+import org.onap.policy.aai.AAINQF199.AAINQF199NamedQuery;
+import org.onap.policy.aai.AAINQF199.AAINQF199QueryParameters;
+import org.onap.policy.aai.AAINQF199.AAINQF199Request;
+import org.onap.policy.aai.AAINQF199.AAINQF199RequestWrapper;
+import org.onap.policy.aai.AAINQF199.AAINQF199Response;
+import org.onap.policy.aai.AAINQF199.AAINQF199ResponseWrapper;
+import org.onap.policy.aai.AAINQF199.AAINQF199ServiceInstance;
+import org.onap.policy.aai.AAINQF199.AAINQF199Tenant;
+import org.onap.policy.aai.AAINQF199.AAINQF199VfModule;
+import org.onap.policy.aai.AAINQF199.AAINQF199VServer;
+import org.onap.policy.aai.util.Serialization;
+
+import org.onap.policy.appc.CommonHeader;
+import org.onap.policy.appc.Request;
+import org.onap.policy.appc.Response;
+import org.onap.policy.appc.ResponseCode;
+import org.onap.policy.appc.ResponseStatus;
+import org.onap.policy.appc.ResponseValue;
+
+import org.onap.policy.controlloop.eventmanager.ControlLoopEventManager;
+import org.onap.policy.vnf.trafficgenerator.PGRequest;
+import org.onap.policy.vnf.trafficgenerator.PGStream;
+import org.onap.policy.vnf.trafficgenerator.PGStreams;
+
+import org.onap.policy.mso.MSOManager;
+import org.onap.policy.mso.MSORequest;
+import org.onap.policy.mso.MSORequestStatus;
+import org.onap.policy.mso.MSORequestDetails;
+import org.onap.policy.mso.MSOModelInfo;
+import org.onap.policy.mso.MSOCloudConfiguration;
+import org.onap.policy.mso.MSORequestInfo;
+import org.onap.policy.mso.MSORequestParameters;
+import org.onap.policy.mso.MSORelatedInstanceListElement;
+import org.onap.policy.mso.MSORelatedInstance;
+import org.onap.policy.mso.MSOResponse;
+
+//import org.openecomp.policy.drools.system.PolicyEngine;
+
+//
+// These parameters are required to build the runtime policy
+//
+declare Params
+ closedLoopControlName : String
+ actor : String
+ aaiURL : String
+ aaiUsername : String
+ aaiPassword : String
+ msoURL : String
+ msoUsername : String
+ msoPassword : String
+ aaiNamedQueryUUID : String
+ aaiPatternMatch : int
+ notificationTopic : String
+ appcTopic : String
+end
+
+/*
+*
+* Called once and only once to insert the parameters into working memory for this Closed Loop policy.
+* NOTE: If this file is to be used as a template to be used with the policy BRMS GW, please comment out this line
+* as the BRMS_GW already generates a SETUP rule
+*
+*/
+rule "${policyName}.SETUP"
+ when
+ then
+ System.out.println("rule SETUP is triggered.");
+ Params params = new Params();
+ params.setClosedLoopControlName("${closedLoopControlName}");
+ params.setActor("${actor}");
+ params.setAaiURL("${aaiURL}");
+ params.setAaiUsername("${aaiUsername}");
+ params.setAaiPassword("${aaiPassword}");
+ params.setMsoURL("${msoURL}");
+ params.setMsoUsername("${msoUsername}");
+ params.setMsoPassword("${msoPassword}");
+ params.setAaiNamedQueryUUID("${aaiNamedQueryUUID}");
+ params.setAaiPatternMatch(${aaiPatternMatch});
+ params.setNotificationTopic("${notificationTopic}");
+ params.setAppcTopic("${appcTopic}");
+ //
+ // This stays in memory as long as the rule is alive and running
+ //
+ insert(params);
+end
+
+
+/*
+*
+* This rule responds to DCAE Events
+*
+*/
+rule "${policyName}.EVENT"
+ when
+ $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" )
+ $event : VirtualControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName(), closedLoopEventStatus == ControlLoopEventStatus.ONSET )
+ not ( ControlLoopEventManager( closedLoopControlName == $event.closedLoopControlName ))
+ then
+ System.out.println("rule EVENT is triggered.");
+ try {
+ //
+ // Check the requestID in the event to make sure it is not null before we create the EventManager.
+ // The EventManager 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 from DCAE event";
+ notification.policyName = drools.getRule().getName();
+ notification.policyScope = "${policyScope}";
+ notification.policyVersion = "${policyVersion}";
+ //
+ // Let interested parties know
+ //
+ try {
+ System.out.println(Serialization.gsonPretty.toJson(notification));
+ //PolicyEngine.manager.deliver($params.getNotificationTopic(), notification);
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.out.println("Can't deliver notification: " + notification);
+ }
+ //
+ // Retract it from memory
+ //
+ retract($event);
+ System.out.println("Event with requestID=null has been retracted.");
+ } else {
+ //
+ // Create an EventManager
+ //
+ ControlLoopEventManager manager = new ControlLoopEventManager($params.getClosedLoopControlName(), $event.requestID);
+ //
+ // Determine if EventManager can actively process the event (i.e. syntax)
+ //
+ VirtualControlLoopNotification notification = manager.activate($event);
+ notification.from = "policy";
+ 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
+ //
+ try {
+ System.out.println(Serialization.gsonPretty.toJson(notification));
+ //PolicyEngine.manager.deliver($params.getNotificationTopic(), notification);
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.out.println("Can't deliver notification: " + notification);
+ }
+ } else {
+ //
+ // Let interested parties know
+ //
+ try {
+ System.out.println(Serialization.gsonPretty.toJson(notification));
+ //PolicyEngine.manager.deliver($params.getNotificationTopic(), notification);
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.out.println("Can't deliver notification: " + 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 same RequestIDs
+ // and for different RequestIDs but with the same closedLoopControlName and target.
+ //
+ }
+ //
+ } catch (Exception e) {
+ e.printStackTrace();
+ 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}";
+ //
+ //
+ //
+ try {
+ System.out.println(Serialization.gsonPretty.toJson(notification));
+ //PolicyEngine.manager.deliver($params.getNotificationTopic(), notification);
+ } catch (Exception e1) {
+ System.out.println("Can't deliver notification: " + notification);
+ e1.printStackTrace();
+ }
+ //
+ // Retract the event
+ //
+ retract($event);
+ }
+end
+
+/*
+*
+* This rule happens when we got a valid ONSET, closed loop is enabled and an Event Manager
+* is created. We can start the operations for this closed loop.
+*
+*/
+rule "${policyName}.EVENT.MANAGER"
+ when
+ $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" )
+ $event : VirtualControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName(), closedLoopEventStatus == ControlLoopEventStatus.ONSET )
+ $manager : ControlLoopEventManager( closedLoopControlName == $event.closedLoopControlName, controlLoopResult == null)
+ then
+ System.out.println("rule EVENT.MANAGER is triggered.");
+ //
+ // Check which event this is.
+ //
+ ControlLoopEventManager.NEW_EVENT_STATUS eventStatus = $manager.onNewEvent($event);
+ //
+ // 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 != ControlLoopEventManager.NEW_EVENT_STATUS.FIRST_ONSET) {
+ System.out.println("Retracting "+eventStatus+" Event.");
+ retract($event);
+ return;
+ }
+ //
+ // Now the event in memory is first onset event
+ //
+ try {
+ //
+ // Pull the known AAI field from the Event
+ //
+ // generic-vnf is needed for vFirewall case
+ // vserver-name is needed for vLoadBalancer case
+ //
+ String genericVNF = $event.AAI.get("generic-vnf.vnf-id");
+ String vserver = $event.AAI.get("vserver.vserver-name");
+ //
+ // Check if we are implementing a simple pattern match.
+ //
+ if ($params.getAaiPatternMatch() == 1) {
+ //
+ // Yes
+ //
+ //Basic naming characteristics:
+ //VF Name (9 char)+VM name (13 char total)+VFC (19 char total)
+ //Example:
+ //VF Name (9 characters): cscf0001v
+ //VM Name(13 characters): cscf0001vm001
+ //VFC name(19 characters): cscf0001vm001cfg001
+ //
+ // zdfw1fwl01fwl02 or zdfw1fwl01fwl01
+ // replaced with
+ // zdfw1fwl01pgn02 or zdfw1fwl01pgn01
+ //
+ int index = genericVNF.lastIndexOf("fwl");
+ if (index == -1) {
+ System.err.println("The generic-vnf.vnf-id from DCAE Event is not valid.");
+ } else {
+ genericVNF = genericVNF.substring(0, index) + "pgn" + genericVNF.substring(index+"fwl".length());
+ }
+ //
+ // Construct an APPC request
+ //
+ ControlLoopOperation operation = new ControlLoopOperation();
+ operation.actor = $params.getActor();
+ operation.operation = "ModifyConfig";
+ operation.target = $event.target;
+ //
+ // Create operationWrapper
+ //
+ ControlLoopOperationWrapper operationWrapper = new ControlLoopOperationWrapper($event.requestID, operation);
+ //
+ // insert operationWrapper into memory
+ //
+ insert(operationWrapper);
+ //
+ Request request = new Request();
+ request.CommonHeader = new CommonHeader();
+ request.CommonHeader.RequestID = $event.requestID;
+ request.Action = operation.operation;
+ request.Payload = new HashMap<String, Object>();
+ //
+ // Fill in the payload
+ //
+ request.Payload.put("generic-vnf.vnf-id", genericVNF);
+ //
+ PGRequest pgRequest = new PGRequest();
+ pgRequest.pgStreams = new PGStreams();
+
+ PGStream pgStream;
+ for(int i = 0; i < 5; i++){
+ pgStream = new PGStream();
+ pgStream.streamId = "fw_udp"+(i+1);
+ pgStream.isEnabled = "true";
+ pgRequest.pgStreams.pgStream.add(pgStream);
+ }
+ request.Payload.put("pg-streams", pgRequest.pgStreams);
+
+ if (request != null) {
+ //
+ // Insert request into memory
+ //
+ insert(request);
+ //
+ // Tell interested parties we are performing this Operation
+ //
+ VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
+ notification.notification = ControlLoopNotificationType.OPERATION;
+ // message and history ??
+ notification.from = "policy";
+ notification.policyName = drools.getRule().getName();
+ notification.policyScope = "${policyScope}";
+ notification.policyVersion = "${policyVersion}";
+ try {
+ System.out.println(Serialization.gsonPretty.toJson(notification));
+ //PolicyEngine.manager.deliver($params.getNotificationTopic(), notification);
+ } catch (Exception e) {
+ System.out.println("Can't deliver notification: " + notification);
+ e.printStackTrace();
+ }
+ //
+ // Now send the operation request
+ //
+ if (request instanceof Request) {
+ try {
+ System.out.println("APPC request sent:");
+ System.out.println(Serialization.gsonPretty.toJson(request));
+ //PolicyEngine.manager.deliver($params.getAppcTopic(), request);
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.out.println("Can't deliver request: " + request);
+ }
+ }
+ } else {
+ //
+ // what happens if it is null
+ //
+ }
+ //
+ } else {
+ //
+ // create AAI named-query request with UUID started with "F199"
+ //
+ AAINQF199Request aainqf199request = new AAINQF199Request();
+ AAINQF199QueryParameters aainqf199queryparam = new AAINQF199QueryParameters();
+ AAINQF199NamedQuery aainqf199namedquery = new AAINQF199NamedQuery();
+ AAINQF199InstanceFilters aainqf199instancefilter = new AAINQF199InstanceFilters();
+ //
+ // queryParameters
+ //
+ aainqf199namedquery.namedQueryUUID = UUID.fromString($params.getAaiNamedQueryUUID());
+ aainqf199queryparam.namedQuery = aainqf199namedquery;
+ aainqf199request.queryParameters = aainqf199queryparam;
+ //
+ // instanceFilters
+ //
+ Map aainqf199instancefiltermap = new HashMap();
+ Map aainqf199instancefiltermapitem = new HashMap();
+ aainqf199instancefiltermapitem.put("vserver-name", vserver);
+ aainqf199instancefiltermap.put("vserver", aainqf199instancefiltermapitem);
+ aainqf199instancefilter.instanceFilter.add(aainqf199instancefiltermap);
+ aainqf199request.instanceFilters = aainqf199instancefilter;
+ //
+ // print aainqf199request for debug
+ //
+ System.out.println("AAI Request sent:");
+ System.out.println(Serialization.gsonPretty.toJson(aainqf199request));
+ //
+ // Create AAINQF199RequestWrapper
+ //
+ AAINQF199RequestWrapper aainqf199RequestWrapper = new AAINQF199RequestWrapper($event.requestID, aainqf199request);
+ //
+ // insert aainqf199request into memory
+ //
+ insert(aainqf199RequestWrapper);
+ }
+ //
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+end
+
+/*
+*
+* This rule happens when we got a valid ONSET, closed loop is enabled, an Event Manager
+* is created, AAI Manager and AAI Request are ready in memory. We can start sending query to AAI and then wait for response.
+*
+*/
+rule "${policyName}.EVENT.MANAGER.AAINQF199REQUEST"
+ when
+ $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" )
+ $event : VirtualControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName(), closedLoopEventStatus == ControlLoopEventStatus.ONSET )
+ $manager : ControlLoopEventManager( closedLoopControlName == $event.closedLoopControlName )
+ $aainqf199RequestWrapper : AAINQF199RequestWrapper(requestID == $event.requestID)
+ then
+ System.out.println("rule EVENT.MANAGER.AAINQF199REQUEST is triggered.");
+ //
+ // send the request
+ //
+ AAINQF199Response aainqf199response = AAINQF199Manager.postQuery($params.getAaiURL(), $params.getAaiUsername(), $params.getAaiPassword(),
+ $aainqf199RequestWrapper.aainqf199request, $event.requestID);
+
+
+
+ //////////////////////////////////////////////////////////
+ // Simulate a valid aainqf199response for junit test
+ // Remove this for real deployment
+ //
+
+ AAINQF199InventoryResponseItem serviceItem = new AAINQF199InventoryResponseItem();
+ serviceItem.modelName = "service-instance";
+ serviceItem.serviceInstance = new AAINQF199ServiceInstance();
+ serviceItem.serviceInstance.serviceInstanceID = "cf8426a6-0b53-4e3d-bfa6-4b2f4d5913a5";
+ serviceItem.serviceInstance.serviceInstanceName = "Service_Ete_Named90e1ab3-dcd5-4877-9edb-eadfc84e32c8";
+ serviceItem.serviceInstance.personaModelId = "4fcbc1c0-7793-46d8-8aa1-fa1c2ed9ec7b";
+ serviceItem.serviceInstance.personaModelVersion = "1.0";
+ serviceItem.serviceInstance.resourceVersion = "1485542400";
+ serviceItem.extraProperties = new AAINQF199ExtraProperties();
+ serviceItem.extraProperties.extraProperty.add(new AAINQF199ExtraProperty("model.model-name", "8330e932-2a23-4943-8606"));
+ serviceItem.extraProperties.extraProperty.add(new AAINQF199ExtraProperty("model.model-type", "service"));
+ serviceItem.extraProperties.extraProperty.add(new AAINQF199ExtraProperty("model.model-version", "1"));
+ serviceItem.extraProperties.extraProperty.add(new AAINQF199ExtraProperty("model.model-id", "4fcbc1c0-7793-46d8-8aa1-fa1c2ed9ec7b"));
+ serviceItem.extraProperties.extraProperty.add(new AAINQF199ExtraProperty("model.model-name-version-id", "5c996219-b2e2-4c76-9b43-7e8672a33c1d"));
+
+ AAINQF199InventoryResponseItem vfModuleItem = new AAINQF199InventoryResponseItem();
+ vfModuleItem.modelName = "C15ce9e1E9144c8fB8bb..base_vlb..module-0";
+ vfModuleItem.vfModule = new AAINQF199VfModule();
+ vfModuleItem.vfModule.vfModuleId = "b0eff878-e2e1-4947-9597-39afdd0f51dd";
+ vfModuleItem.vfModule.vfModuleName = "Vfmodule_Ete_Named90e1ab3-dcd5-4877-9edb-eadfc84e32c8";
+ vfModuleItem.vfModule.heatStackId = "Vfmodule_Ete_Named90e1ab3-dcd5-4877-9edb-eadfc84e32c8/5845f37b-6cda-4e91-8ca3-f5572d226488";
+ vfModuleItem.vfModule.orchestrationStatus = "active";
+ vfModuleItem.vfModule.isBaseVfModule = true;
+ vfModuleItem.vfModule.resourceVersion = "1485542667";
+ vfModuleItem.vfModule.personaModelId = "79ee24cd-fc9a-4f14-afae-5e1dd2ab2941";
+ vfModuleItem.vfModule.personaModelVersion = "1";
+
+ vfModuleItem.extraProperties = new AAINQF199ExtraProperties();
+ vfModuleItem.extraProperties.extraProperty.add(new AAINQF199ExtraProperty("model.model-name", "C15ce9e1E9144c8fB8bb..base_vlb..module-0"));
+ vfModuleItem.extraProperties.extraProperty.add(new AAINQF199ExtraProperty("model.model-type", "resource"));
+ vfModuleItem.extraProperties.extraProperty.add(new AAINQF199ExtraProperty("model.model-version", "1"));
+ vfModuleItem.extraProperties.extraProperty.add(new AAINQF199ExtraProperty("model.model-id", "79ee24cd-fc9a-4f14-afae-5e1dd2ab2941"));
+ vfModuleItem.extraProperties.extraProperty.add(new AAINQF199ExtraProperty("model.model-name-version-id", "5484cabb-1a0d-4f29-a616-094a3f643d73"));
+
+
+ AAINQF199InventoryResponseItem vfModuleItem1 = new AAINQF199InventoryResponseItem();
+ //vfModuleItem1.modelName = "vf-module";
+ vfModuleItem1.vfModule = new AAINQF199VfModule();
+ vfModuleItem1.vfModule.vfModuleId = "dummy";
+ vfModuleItem1.vfModule.vfModuleName = "dummy";
+ vfModuleItem1.vfModule.isBaseVfModule = false;
+ vfModuleItem1.vfModule.resourceVersion = "1485561752";
+ vfModuleItem1.vfModule.personaModelId = "f32568ec-2f1c-458a-864b-0593d53d141a";
+ vfModuleItem1.vfModule.personaModelVersion = "1.0";
+
+ vfModuleItem1.extraProperties = new AAINQF199ExtraProperties();
+ vfModuleItem1.extraProperties.extraProperty.add(new AAINQF199ExtraProperty("model.model-name", "C15ce9e1E9144c8fB8bb..dnsscaling..module-1"));
+ vfModuleItem1.extraProperties.extraProperty.add(new AAINQF199ExtraProperty("model.model-type", "resource"));
+ vfModuleItem1.extraProperties.extraProperty.add(new AAINQF199ExtraProperty("model.model-version", "1"));
+ vfModuleItem1.extraProperties.extraProperty.add(new AAINQF199ExtraProperty("model.model-id", "f32568ec-2f1c-458a-864b-0593d53d141a"));
+ vfModuleItem1.extraProperties.extraProperty.add(new AAINQF199ExtraProperty("model.model-name-version-id", "69615025-879d-4f0d-afe3-b7d1a7eeed1f"));
+
+
+
+ AAINQF199InventoryResponseItem vfModuleItem2 = new AAINQF199InventoryResponseItem();
+ //vfModuleItem2.modelName = "vf-module";
+ vfModuleItem2.vfModule = new AAINQF199VfModule();
+ vfModuleItem2.vfModule.vfModuleId = "8cd79e44-1fae-48c1-a160-609f90b46749";
+ vfModuleItem2.vfModule.vfModuleName = "vDNS_Ete_Named90e1ab3-dcd5-4877-9edb-eadfc84e32c8";
+ vfModuleItem2.vfModule.heatStackId = "vDNS_Ete_Named90e1ab3-dcd5-4877-9edb-eadfc84e32c8/f447ce51-14dd-4dcd-9957-68a047c79673";
+ vfModuleItem2.vfModule.orchestrationStatus = "active";
+ vfModuleItem2.vfModule.isBaseVfModule = false;
+ vfModuleItem2.vfModule.resourceVersion = "1485562712";
+ vfModuleItem2.vfModule.personaModelId = "f32568ec-2f1c-458a-864b-0593d53d141a";
+ vfModuleItem2.vfModule.personaModelVersion = "1.0";
+
+ vfModuleItem2.extraProperties = new AAINQF199ExtraProperties();
+ vfModuleItem2.extraProperties.extraProperty.add(new AAINQF199ExtraProperty("model.model-name", "C15ce9e1E9144c8fB8bb..dnsscaling..module-1"));
+ vfModuleItem2.extraProperties.extraProperty.add(new AAINQF199ExtraProperty("model.model-type", "resource"));
+ vfModuleItem2.extraProperties.extraProperty.add(new AAINQF199ExtraProperty("model.model-version", "1"));
+ vfModuleItem2.extraProperties.extraProperty.add(new AAINQF199ExtraProperty("model.model-id", "f32568ec-2f1c-458a-864b-0593d53d141a"));
+ vfModuleItem2.extraProperties.extraProperty.add(new AAINQF199ExtraProperty("model.model-name-version-id", "69615025-879d-4f0d-afe3-b7d1a7eeed1f"));
+
+
+
+
+
+ AAINQF199InventoryResponseItem genericVNFItem = new AAINQF199InventoryResponseItem();
+ genericVNFItem.modelName = "generic-vnf";
+ genericVNFItem.genericVNF = new AAINQF199GenericVNF();
+ genericVNFItem.genericVNF.vnfID = "594e2fe0-48b8-41ff-82e2-3d4bab69b192";
+ genericVNFItem.genericVNF.vnfName = "Vnf_Ete_Named90e1ab3-dcd5-4877-9edb-eadfc84e32c8";
+ genericVNFItem.genericVNF.vnfType = "8330e932-2a23-4943-8606/c15ce9e1-e914-4c8f-b8bb 1";
+ genericVNFItem.genericVNF.serviceId = "b3f70641-bdb9-4030-825e-6abb73a1f929";
+// genericVNFItem.genericVNF.provStatus = "PREPROV";
+// genericVNFItem.genericVNF.operationalState = "dhv-test-operational-state";
+// genericVNFItem.genericVNF.ipv4OamAddress = "dhv-test-gvnf-ipv4-oam-address";
+// genericVNFItem.genericVNF.ipv4Loopback0Address = "dhv-test-gvnfipv4-loopback0-address";
+ genericVNFItem.genericVNF.inMaint = false;
+ genericVNFItem.genericVNF.isClosedLoopDisabled = false;
+ genericVNFItem.genericVNF.resourceVersion = "1485542422";
+// genericVNFItem.genericVNF.encrypedAccessFlag = true;
+ genericVNFItem.genericVNF.personaModelId = "033a32ed-aa65-4764-a736-36f2942f1aa0";
+ genericVNFItem.genericVNF.personaModelVersion = "1.0";
+ genericVNFItem.extraProperties = new AAINQF199ExtraProperties();
+ genericVNFItem.extraProperties.extraProperty = new LinkedList<AAINQF199ExtraProperty>();
+ genericVNFItem.extraProperties.extraProperty.add(new AAINQF199ExtraProperty("model.model-name", "c15ce9e1-e914-4c8f-b8bb"));
+ genericVNFItem.extraProperties.extraProperty.add(new AAINQF199ExtraProperty("model.model-type", "resource"));
+ genericVNFItem.extraProperties.extraProperty.add(new AAINQF199ExtraProperty("model.model-version", "1"));
+ genericVNFItem.extraProperties.extraProperty.add(new AAINQF199ExtraProperty("model.model-id", "033a32ed-aa65-4764-a736-36f2942f1aa0"));
+ genericVNFItem.extraProperties.extraProperty.add(new AAINQF199ExtraProperty("model.model-name-version-id", "d4d072dc-4e21-4a03-9524-628985819a8e"));
+ genericVNFItem.items = new AAINQF199InventoryResponseItems();
+ genericVNFItem.items.inventoryResponseItems = new LinkedList<AAINQF199InventoryResponseItem>();
+ genericVNFItem.items.inventoryResponseItems.add(serviceItem);
+ genericVNFItem.items.inventoryResponseItems.add(vfModuleItem);
+ genericVNFItem.items.inventoryResponseItems.add(vfModuleItem1);
+ genericVNFItem.items.inventoryResponseItems.add(vfModuleItem2);
+
+ AAINQF199InventoryResponseItem cloudItem = new AAINQF199InventoryResponseItem();
+ cloudItem.cloudRegion = new AAINQF199CloudRegion();
+ cloudItem.cloudRegion.cloudOwner = "OWNER";
+ cloudItem.cloudRegion.cloudRegionId = "REGIONID";
+ cloudItem.cloudRegion.cloudRegionVersion = "2.5";
+ cloudItem.cloudRegion.complexName = "COMPLEXNAME";
+ cloudItem.cloudRegion.resourceVersion = "1485465545";
+
+ AAINQF199InventoryResponseItem tenantItem = new AAINQF199InventoryResponseItem();
+ tenantItem.tenant = new AAINQF199Tenant();
+ tenantItem.tenant.tenantId = "1015548";
+ tenantItem.tenant.tenantName = "1015548";
+ tenantItem.tenant.resourceVersion = "1485465545";
+ tenantItem.items = new AAINQF199InventoryResponseItems();
+ tenantItem.items.inventoryResponseItems = new LinkedList<AAINQF199InventoryResponseItem>();
+ tenantItem.items.inventoryResponseItems.add(cloudItem);
+
+ AAINQF199InventoryResponseItem vserverItem = new AAINQF199InventoryResponseItem();
+ vserverItem.vserver = new AAINQF199VServer();
+ vserverItem.vserver.vserverId = "70f081eb-2a87-4c81-9296-4b93d7d145c6";
+ vserverItem.vserver.vserverName = "vlb-lb-32c8";
+ vserverItem.vserver.vserverName2 = "vlb-lb-32c8";
+ vserverItem.vserver.provStatus = "ACTIVE";
+ vserverItem.vserver.vserverSelflink = "https://dfw.servers.api.rackspacecloud.com/v2/1015548/servers/70f081eb-2a87-4c81-9296-4b93d7d145c6";
+ vserverItem.vserver.inMaint = false;
+ vserverItem.vserver.isClosedLoopDisabled = false;
+ vserverItem.vserver.resourceVersion = "1485546436";
+ vserverItem.items = new AAINQF199InventoryResponseItems();
+ vserverItem.items.inventoryResponseItems = new LinkedList<AAINQF199InventoryResponseItem>();
+ vserverItem.items.inventoryResponseItems.add(genericVNFItem);
+ vserverItem.items.inventoryResponseItems.add(tenantItem);
+
+ aainqf199response = new AAINQF199Response();
+ aainqf199response.inventoryResponseItems.add(vserverItem);
+
+ System.out.println("PAM");
+ System.out.println(Serialization.gsonPretty.toJson(aainqf199response));
+
+ //////////////////////////////////////////////////////////
+
+
+
+
+
+
+ //
+ // Check AAI response
+ //
+ if (aainqf199response == null) {
+ System.err.println("Failed to get AAI response");
+ //
+ // Fail and retract everything
+ //
+ retract($event);
+ retract($manager);
+ retract($aainqf199RequestWrapper);
+ } else {
+ //
+ // Create AAINQF199ResponseWrapper
+ //
+ AAINQF199ResponseWrapper aainqf199ResponseWrapper = new AAINQF199ResponseWrapper($event.requestID, aainqf199response);
+ //
+ // insert aainqf199ResponseWrapper to memeory
+ //
+ insert(aainqf199ResponseWrapper);
+ }
+end
+
+/*
+*
+* This rule happens when we got a valid AAI response. We can start sending request to APPC or MSO now.
+*
+*/
+rule "${policyName}.EVENT.MANAGER.AAINQF199RESPONSE"
+ when
+ $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" )
+ $event : VirtualControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName(), closedLoopEventStatus == ControlLoopEventStatus.ONSET )
+ $manager : ControlLoopEventManager( closedLoopControlName == $event.closedLoopControlName )
+ $aainqf199RequestWrapper : AAINQF199RequestWrapper(requestID == $event.requestID)
+ $aainqf199ResponseWrapper : AAINQF199ResponseWrapper(requestID == $event.requestID)
+ then
+ System.out.println("rule EVENT.MANAGER.AAINQF199RESPONSE is triggered.");
+ //
+ // Extract related fields out of AAINQF199RESPONSE
+ //
+ String vnfItemVnfId, vnfItemVnfType, vnfItemPersonaModelId, vnfItemPersonaModelVersion, vnfItemModelName,
+ vnfItemModelVersion, vnfItemModelNameVersionId, serviceItemServiceInstanceId, serviceItemPersonaModelId,
+ serviceItemModelName, serviceItemModelType, serviceItemModelVersion, serviceItemModelNameVersionId,
+ vfModuleItemVfModuleName, vfModuleItemPersonaModelId, vfModuleItemPersonaModelVersion, vfModuleItemModelName,
+ vfModuleItemModelNameVersionId, tenantItemTenantId, cloudRegionItemCloudRegionId;
+ try {
+ //
+ // vnfItem
+ //
+ vnfItemVnfId = $aainqf199ResponseWrapper.aainqf199response.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).genericVNF.vnfID;
+ vnfItemVnfType = $aainqf199ResponseWrapper.aainqf199response.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).genericVNF.vnfType;
+ vnfItemVnfType = vnfItemVnfType.substring(vnfItemVnfType.lastIndexOf("/")+1);
+ vnfItemPersonaModelId = $aainqf199ResponseWrapper.aainqf199response.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).genericVNF.personaModelId;
+ vnfItemPersonaModelVersion = $aainqf199ResponseWrapper.aainqf199response.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).genericVNF.personaModelVersion;
+ vnfItemModelName = $aainqf199ResponseWrapper.aainqf199response.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).extraProperties.extraProperty.get(0).propertyValue;
+ vnfItemModelVersion = $aainqf199ResponseWrapper.aainqf199response.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).extraProperties.extraProperty.get(2).propertyValue;
+ vnfItemModelNameVersionId = $aainqf199ResponseWrapper.aainqf199response.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).extraProperties.extraProperty.get(4).propertyValue;
+ //
+ // serviceItem
+ //
+ serviceItemServiceInstanceId = $aainqf199ResponseWrapper.aainqf199response.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).serviceInstance.serviceInstanceID;
+ serviceItemPersonaModelId = $aainqf199ResponseWrapper.aainqf199response.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).serviceInstance.personaModelId;
+ serviceItemModelName = $aainqf199ResponseWrapper.aainqf199response.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).extraProperties.extraProperty.get(0).propertyValue;
+ serviceItemModelType = $aainqf199ResponseWrapper.aainqf199response.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).extraProperties.extraProperty.get(1).propertyValue;
+ serviceItemModelVersion = $aainqf199ResponseWrapper.aainqf199response.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).serviceInstance.personaModelVersion;
+ serviceItemModelNameVersionId = $aainqf199ResponseWrapper.aainqf199response.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).extraProperties.extraProperty.get(4).propertyValue;
+ //
+ // Find the index for base vf module and non-base vf module
+ //
+ int baseIndex = -1;
+ int nonBaseIndex = -1;
+ List<AAINQF199InventoryResponseItem> inventoryItems = $aainqf199ResponseWrapper.aainqf199response.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).items.inventoryResponseItems;
+ for (AAINQF199InventoryResponseItem m : inventoryItems) {
+ if (m.vfModule != null && m.vfModule.isBaseVfModule == true) {
+ baseIndex = inventoryItems.indexOf(m);
+ } else if (m.vfModule != null && m.vfModule.isBaseVfModule == false && m.vfModule.orchestrationStatus == null) {
+ nonBaseIndex = inventoryItems.indexOf(m);
+ }
+ //
+ if (baseIndex != -1 && nonBaseIndex != -1) {
+ break;
+ }
+ }
+ //
+ // Report the error if either base vf module or non-base vf module is not found
+ //
+ if (baseIndex == -1 || nonBaseIndex == -1) {
+ System.err.println("Either base or non-base vf module is not found from AAI response.");
+ retract($aainqf199RequestWrapper);
+ retract($aainqf199ResponseWrapper);
+ retract($manager);
+ retract($event);
+ return;
+ }
+ //
+ // This comes from the base module
+ //
+ vfModuleItemVfModuleName = $aainqf199ResponseWrapper.aainqf199response.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).items.inventoryResponseItems.get(baseIndex).vfModule.vfModuleName;
+ vfModuleItemVfModuleName = vfModuleItemVfModuleName.replace("Vfmodule", "vDNS");
+ //
+ // vfModuleItem - NOT the base module
+ //
+ vfModuleItemPersonaModelId = $aainqf199ResponseWrapper.aainqf199response.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).items.inventoryResponseItems.get(nonBaseIndex).vfModule.personaModelId;
+ vfModuleItemPersonaModelVersion = $aainqf199ResponseWrapper.aainqf199response.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).items.inventoryResponseItems.get(nonBaseIndex).vfModule.personaModelVersion;
+ vfModuleItemModelName = $aainqf199ResponseWrapper.aainqf199response.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).items.inventoryResponseItems.get(nonBaseIndex).extraProperties.extraProperty.get(0).propertyValue;
+ vfModuleItemModelNameVersionId = $aainqf199ResponseWrapper.aainqf199response.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).items.inventoryResponseItems.get(nonBaseIndex).extraProperties.extraProperty.get(4).propertyValue;
+ //
+ // tenantItem
+ //
+ tenantItemTenantId = $aainqf199ResponseWrapper.aainqf199response.inventoryResponseItems.get(0).items.inventoryResponseItems.get(1).tenant.tenantId;
+ //
+ // cloudRegionItem
+ //
+ cloudRegionItemCloudRegionId = $aainqf199ResponseWrapper.aainqf199response.inventoryResponseItems.get(0).items.inventoryResponseItems.get(1).items.inventoryResponseItems.get(0).cloudRegion.cloudRegionId;
+ //
+ } catch (Exception e) {
+ e.printStackTrace();
+ 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}";
+ //
+ try {
+ System.out.println(Serialization.gsonPretty.toJson(notification));
+ //PolicyEngine.manager.deliver($params.getNotificationTopic(), notification);
+ } catch (Exception e1) {
+ System.out.println("Can't deliver notification: " + notification);
+ e1.printStackTrace();
+ }
+ //
+ notification.notification = ControlLoopNotificationType.FINAL_FAILURE;
+ notification.message = "Invalid named-query response from AAI";
+ //
+ try {
+ System.out.println(Serialization.gsonPretty.toJson(notification));
+ //PolicyEngine.manager.deliver($params.getNotificationTopic(), notification);
+ } catch (Exception e1) {
+ System.out.println("Can't deliver notification: " + notification);
+ e1.printStackTrace();
+ }
+ //
+ // Retract everything
+ //
+ retract($aainqf199RequestWrapper);
+ retract($aainqf199ResponseWrapper);
+ retract($manager);
+ retract($event);
+ return;
+ }
+ //
+ // Extracted fields should not be null
+ //
+ if ((vnfItemVnfId == null) || (vnfItemVnfType == null) ||
+ (vnfItemPersonaModelId == null) || (vnfItemModelName == null) ||
+ (vnfItemModelVersion == null) || (vnfItemModelNameVersionId == null) ||
+ (serviceItemServiceInstanceId == null) || (serviceItemModelName == null) ||
+ (serviceItemModelType == null) || (serviceItemModelVersion == null) ||
+ (serviceItemModelNameVersionId == null) || (vfModuleItemVfModuleName == null) ||
+ (vfModuleItemPersonaModelId == null) || (vfModuleItemPersonaModelVersion == null) ||
+ (vfModuleItemModelName == null) || (vfModuleItemModelNameVersionId == null) ||
+ (tenantItemTenantId == null) || (cloudRegionItemCloudRegionId == null)) {
+ //
+ System.err.println("some fields are missing from AAI response.");
+ //
+ // Fail and retract everything
+ //
+ retract($aainqf199RequestWrapper);
+ retract($aainqf199ResponseWrapper);
+ retract($manager);
+ retract($event);
+ return;
+ }
+ //
+ // We don't need them any more
+ //
+ retract($aainqf199ResponseWrapper);
+ retract($aainqf199RequestWrapper);
+ //
+ // check the actor of this closed loop
+ //
+ switch ($params.getActor()) {
+ case "APPC":
+ {
+ //
+ // Construct an APPC request
+ //
+ ControlLoopOperation operation = new ControlLoopOperation();
+ operation.actor = $params.getActor();
+ operation.operation = "ModifyConfig";
+ operation.target = $event.target;
+ //
+ // Create operationWrapper
+ //
+ ControlLoopOperationWrapper operationWrapper = new ControlLoopOperationWrapper($event.requestID, operation);
+ //
+ // insert operationWrapper into memory
+ //
+ insert(operationWrapper);
+ //
+ Request request = new Request();
+ request.CommonHeader = new CommonHeader();
+ request.CommonHeader.RequestID = $event.requestID;
+ request.Action = operation.operation;
+ request.Payload = new HashMap<String, Object>();
+ //
+ // Fill in the payload
+ // Hardcode genericVNF for now since AAI has not been ready for vFirewall demo case
+ //
+ String genericVNF = "zdfw1fwl01pgn02";
+ request.Payload.put("generic-vnf.vnf-id", genericVNF);
+ //
+ PGRequest pgRequest = new PGRequest();
+ pgRequest.pgStreams = new PGStreams();
+
+ PGStream pgStream;
+ for(int i = 0; i < 5; i++){
+ pgStream = new PGStream();
+ pgStream.streamId = "fw_udp"+(i+1);
+ pgStream.isEnabled = "true";
+ pgRequest.pgStreams.pgStream.add(pgStream);
+ }
+ request.Payload.put("pg-streams", pgRequest.pgStreams);
+
+ if (request != null) {
+ //
+ // Insert request into memory
+ //
+ insert(request);
+ //
+ // Tell interested parties we are performing this Operation
+ //
+ VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
+ notification.notification = ControlLoopNotificationType.OPERATION;
+ // message and history ??
+ notification.from = "policy";
+ notification.policyName = drools.getRule().getName();
+ notification.policyScope = "${policyScope}";
+ notification.policyVersion = "${policyVersion}";
+ try {
+ System.out.println(Serialization.gsonPretty.toJson(notification));
+ //PolicyEngine.manager.deliver($params.getNotificationTopic(), notification);
+ } catch (Exception e) {
+ System.out.println("Can't deliver notification: " + notification);
+ e.printStackTrace();
+ }
+ //
+ // Now send the operation request
+ //
+ if (request instanceof Request) {
+ try {
+ System.out.println("APPC request sent:");
+ System.out.println(Serialization.gsonPretty.toJson(request));
+ //PolicyEngine.manager.deliver($params.getAppcTopic(), request);
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.out.println("Can't deliver request: " + request);
+ }
+ }
+ } else {
+ //
+ // what happens if it is null
+ //
+ }
+ }
+ break;
+ case "MSO":
+ {
+ //
+ // Construct an operation
+ //
+ ControlLoopOperation operation = new ControlLoopOperation();
+ operation.actor = $params.getActor();
+ operation.operation = "createModuleInstance";
+ operation.target = $event.target;
+ //
+ // Create operationWrapper
+ //
+ ControlLoopOperationWrapper operationWrapper = new ControlLoopOperationWrapper($event.requestID, operation);
+ //
+ // Construct an MSO request
+ //
+ MSORequest request = new MSORequest();
+ request.requestDetails = new MSORequestDetails();
+ request.requestDetails.modelInfo = new MSOModelInfo();
+ request.requestDetails.cloudConfiguration = new MSOCloudConfiguration();
+ request.requestDetails.requestInfo = new MSORequestInfo();
+ request.requestDetails.requestParameters = new MSORequestParameters();
+ request.requestDetails.requestParameters.userParams = null;
+ //
+ // cloudConfiguration
+ //
+ request.requestDetails.cloudConfiguration.lcpCloudRegionId = cloudRegionItemCloudRegionId;
+ request.requestDetails.cloudConfiguration.tenantId = tenantItemTenantId;
+ //
+ // modelInfo
+ //
+ request.requestDetails.modelInfo.modelType = "vfModule";
+ request.requestDetails.modelInfo.modelInvariantId = vfModuleItemPersonaModelId;
+ request.requestDetails.modelInfo.modelNameVersionId = vfModuleItemModelNameVersionId;
+ request.requestDetails.modelInfo.modelName = vfModuleItemModelName;
+ request.requestDetails.modelInfo.modelVersion = vfModuleItemPersonaModelVersion;
+ //
+ // requestInfo
+ //
+ request.requestDetails.requestInfo.instanceName = vfModuleItemVfModuleName;
+ request.requestDetails.requestInfo.source = "POLICY";
+ request.requestDetails.requestInfo.suppressRollback = false;
+ //
+ // relatedInstanceList
+ //
+ MSORelatedInstanceListElement relatedInstanceListElement1 = new MSORelatedInstanceListElement();
+ MSORelatedInstanceListElement relatedInstanceListElement2 = new MSORelatedInstanceListElement();
+ relatedInstanceListElement1.relatedInstance = new MSORelatedInstance();
+ relatedInstanceListElement2.relatedInstance = new MSORelatedInstance();
+ //
+ relatedInstanceListElement1.relatedInstance.instanceId = serviceItemServiceInstanceId;
+ relatedInstanceListElement1.relatedInstance.modelInfo = new MSOModelInfo();
+ relatedInstanceListElement1.relatedInstance.modelInfo.modelType = "service";
+ relatedInstanceListElement1.relatedInstance.modelInfo.modelInvariantId = serviceItemPersonaModelId;
+ relatedInstanceListElement1.relatedInstance.modelInfo.modelNameVersionId = serviceItemModelNameVersionId;
+ relatedInstanceListElement1.relatedInstance.modelInfo.modelName = serviceItemModelName;
+ relatedInstanceListElement1.relatedInstance.modelInfo.modelVersion = serviceItemModelVersion;
+ //
+ relatedInstanceListElement2.relatedInstance.instanceId = vnfItemVnfId;
+ relatedInstanceListElement2.relatedInstance.modelInfo = new MSOModelInfo();
+ relatedInstanceListElement2.relatedInstance.modelInfo.modelType = "vnf";
+ relatedInstanceListElement2.relatedInstance.modelInfo.modelInvariantId = vnfItemPersonaModelId;
+ relatedInstanceListElement2.relatedInstance.modelInfo.modelNameVersionId = vnfItemModelNameVersionId;
+ relatedInstanceListElement2.relatedInstance.modelInfo.modelName = vnfItemModelName;
+ relatedInstanceListElement2.relatedInstance.modelInfo.modelVersion = vnfItemModelVersion;
+ relatedInstanceListElement2.relatedInstance.modelInfo.modelCustomizationName = vnfItemVnfType;
+ //
+ request.requestDetails.relatedInstanceList.add(relatedInstanceListElement1);
+ request.requestDetails.relatedInstanceList.add(relatedInstanceListElement2);
+ //
+ // print MSO request for debug
+ //
+ System.out.println("MSO request sent:");
+ System.out.println(Serialization.gsonPretty.toJson(request));
+ //
+ //
+ //
+ if (request != null) {
+ //
+ // Tell interested parties we are performing this Operation
+ //
+ VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
+ notification.notification = ControlLoopNotificationType.OPERATION;
+ notification.from = "policy";
+ notification.policyName = drools.getRule().getName();
+ notification.policyScope = "${policyScope}";
+ notification.policyVersion = "${policyVersion}";
+ try {
+ System.out.println(Serialization.gsonPretty.toJson(notification));
+ //PolicyEngine.manager.deliver($params.getNotificationTopic(), notification);
+ } catch (Exception e) {
+ System.out.println("Can't deliver notification: " + notification);
+ e.printStackTrace();
+ }
+ //
+ // Concatenate serviceItemServiceInstanceId and vnfItemVnfId to msoURL
+ //
+ String MSOUrl = $params.getMsoURL() + "/serviceInstances/v2/" + serviceItemServiceInstanceId + "/vnfs/" + vnfItemVnfId + "/vfModules";
+ //
+ // Call MSO
+ //
+ MSOResponse response = MSOManager.createModuleInstance(MSOUrl, $params.getMsoURL(), $params.getMsoUsername(), $params.getMsoPassword(), request);
+
+
+
+
+ //////////////////////////////////////////////////////////
+ // Simulate a valid MSOResponse for junit test
+ // Remove this for real deployment
+ //
+ response = new MSOResponse();
+ response.request = new MSORequest();
+ response.request.requestStatus = new MSORequestStatus();
+ response.request.requestStatus.requestState = "COMPLETE";
+ //////////////////////////////////////////////////////////
+
+
+
+
+
+ if (response != null) {
+ //
+ // Assign requestId
+ //
+ request.requestId = $event.requestID.toString();
+ response.request.requestId = $event.requestID.toString();
+ //
+ // Insert facts
+ //
+ insert(operationWrapper);
+ insert(request);
+ insert(response);
+ } else {
+ //
+ // MSO request not even accepted
+ //
+ notification.message = operationWrapper.operation.toMessage();
+ operationWrapper.operation.message = operationWrapper.operation.toMessage();
+ operationWrapper.operation.outcome = "FAILURE_EXCEPTION";
+ $manager.setControlLoopResult("FAILURE_EXCEPTION");
+ notification.history.add(operationWrapper.operation);
+ notification.notification = ControlLoopNotificationType.OPERATION_FAILURE;
+ //
+ // Let interested parties know
+ //
+ try {
+ System.out.println(Serialization.gsonPretty.toJson(notification));
+ //PolicyEngine.manager.deliver($params.getNotificationTopic(), notification);
+ } catch (Exception e) {
+ System.out.println("Can't deliver notification: " + notification);
+ e.printStackTrace();
+ }
+ notification.notification = ControlLoopNotificationType.FINAL_FAILURE;
+ try {
+ System.out.println(Serialization.gsonPretty.toJson(notification));
+ //PolicyEngine.manager.deliver($params.getNotificationTopic(), notification);
+ } catch (Exception e) {
+ System.out.println("Can't deliver notification: " + notification);
+ e.printStackTrace();
+ }
+ //
+ // Retract everything
+ //
+ retract($event);
+ retract($manager);
+ }
+ } else {
+ System.err.println("constructed MSO request is invalid.");
+ }
+ }
+ break;
+ }
+end
+
+/*
+*
+* This rule responds to APPC Response Events
+*
+*/
+rule "${policyName}.APPC.RESPONSE"
+ when
+ $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" )
+ $event : VirtualControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName(), closedLoopEventStatus == ControlLoopEventStatus.ONSET )
+ $manager : ControlLoopEventManager( closedLoopControlName == $event.closedLoopControlName )
+ $operationWrapper : ControlLoopOperationWrapper( requestID == $event.requestID )
+ $request : Request( getCommonHeader().RequestID == $event.requestID )
+ $response : Response( getCommonHeader().RequestID == $event.requestID )
+ then
+ System.out.println("rule APPC.RESPONSE is triggered.");
+ if ($response.Status == null) {
+ $operationWrapper.operation.outcome = "FAILURE_EXCEPTION";
+ $manager.setControlLoopResult("FAILURE_EXCEPTION");
+ }
+ //
+ // Get the Response Code
+ //
+ ResponseCode code = ResponseCode.toResponseCode($response.Status.Code);
+ if (code == null) {
+ $operationWrapper.operation.outcome = "FAILURE_EXCEPTION";
+ $manager.setControlLoopResult("FAILURE_EXCEPTION");
+ }
+ //
+ // Construct notification
+ //
+ VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
+ notification.from = "policy";
+ notification.policyName = drools.getRule().getName();
+ notification.policyScope = "${policyScope}";
+ notification.policyVersion = "${policyVersion}";
+ notification.message = $operationWrapper.operation.toMessage();
+ $operationWrapper.operation.message = $operationWrapper.operation.toMessage();
+ //
+ // Ok, let's figure out what APP-C's response is
+ //
+ switch (code) {
+ case ACCEPT:
+ $operationWrapper.operation.outcome = "PROCESSING";
+ break;
+ case ERROR:
+ case REJECT:
+ $operationWrapper.operation.outcome = "FAILURE_EXCEPTION";
+ $manager.setControlLoopResult("FAILURE_EXCEPTION");
+ break;
+ case SUCCESS:
+ $operationWrapper.operation.outcome = "SUCCESS";
+ $manager.setControlLoopResult("SUCCESS");
+ break;
+ case FAILURE:
+ $operationWrapper.operation.outcome = "FAILURE";
+ $manager.setControlLoopResult("FAILURE");
+ break;
+ }
+ if ($operationWrapper.operation.outcome.equals("SUCCESS")) {
+ notification.history.add($operationWrapper.operation);
+ notification.notification = ControlLoopNotificationType.OPERATION_SUCCESS;
+ //
+ // Let interested parties know
+ //
+ try {
+ System.out.println(Serialization.gsonPretty.toJson(notification));
+ //PolicyEngine.manager.deliver($params.getNotificationTopic(), notification);
+ } catch (Exception e) {
+ System.out.println("Can't deliver notification: " + notification);
+ e.printStackTrace();
+ }
+ notification.notification = ControlLoopNotificationType.FINAL_SUCCESS;
+ try {
+ System.out.println(Serialization.gsonPretty.toJson(notification));
+ //PolicyEngine.manager.deliver($params.getNotificationTopic(), notification);
+ } catch (Exception e) {
+ System.out.println("Can't deliver notification: " + notification);
+ e.printStackTrace();
+ }
+
+ //
+ // We are going to retract these objects from memory
+ //
+ System.out.println("Retracting everything");
+ retract($operationWrapper);
+ retract($request);
+ retract($response);
+ retract($event);
+ retract($manager);
+ } else if ($operationWrapper.operation.outcome.equals("PROCESSING")) {
+ retract($response);
+ } else {
+ notification.history.add($operationWrapper.operation);
+ notification.notification = ControlLoopNotificationType.OPERATION_FAILURE;
+ //
+ // Let interested parties know
+ //
+ try {
+ System.out.println(Serialization.gsonPretty.toJson(notification));
+ //PolicyEngine.manager.deliver($params.getNotificationTopic(), notification);
+ } catch (Exception e) {
+ System.out.println("Can't deliver notification: " + notification);
+ e.printStackTrace();
+ }
+ notification.notification = ControlLoopNotificationType.FINAL_FAILURE;
+ //
+ // Let interested parties know
+ //
+ try {
+ System.out.println(Serialization.gsonPretty.toJson(notification));
+ //PolicyEngine.manager.deliver($params.getNotificationTopic(), notification);
+ } catch (Exception e) {
+ System.out.println("Can't deliver notification: " + notification);
+ e.printStackTrace();
+ }
+ //
+ // We are going to retract these objects from memory
+ //
+ System.out.println("Retracting everything");
+ retract($operationWrapper);
+ retract($request);
+ retract($response);
+ retract($event);
+ retract($manager);
+ }
+
+end
+
+/*
+*
+* This rule is used to clean up APPC response
+*
+*/
+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
+ System.out.println("rule APPC.RESPONSE.CLEANUP is triggered.");
+ retract($response);
+end
+
+/*
+*
+* This rule responds to MSO Response Events
+*
+*/
+rule "${policyName}.MSO.RESPONSE"
+ when
+ $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" )
+ $event : VirtualControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName(), closedLoopEventStatus == ControlLoopEventStatus.ONSET )
+ $manager : ControlLoopEventManager( closedLoopControlName == $event.closedLoopControlName )
+ $operationWrapper : ControlLoopOperationWrapper( requestID == $event.requestID )
+ $request : MSORequest( requestId == $event.requestID.toString() )
+ $response : MSOResponse( request.requestId == $event.requestID.toString() )
+ then
+ System.out.println("rule MSO.RESPONSE is triggered.");
+ //
+ // Construct notification
+ //
+ VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
+ notification.from = "policy";
+ notification.policyName = drools.getRule().getName();
+ notification.policyScope = "${policyScope}";
+ notification.policyVersion = "${policyVersion}";
+ notification.message = $operationWrapper.operation.toMessage();
+ $operationWrapper.operation.message = $operationWrapper.operation.toMessage();
+ //
+ // The operation can either be succeeded or failed
+ //
+ if($response.request.requestStatus.requestState.equals("COMPLETE")) {
+ $operationWrapper.operation.outcome = "SUCCESS";
+ $manager.setControlLoopResult("SUCCESS");
+ notification.history.add($operationWrapper.operation);
+ notification.notification = ControlLoopNotificationType.OPERATION_SUCCESS;
+ //
+ // Let interested parties know
+ //
+ try {
+ System.out.println(Serialization.gsonPretty.toJson(notification));
+ //PolicyEngine.manager.deliver($params.getNotificationTopic(), notification);
+ } catch (Exception e) {
+ System.out.println("Can't deliver notification: " + notification);
+ e.printStackTrace();
+ }
+ notification.notification = ControlLoopNotificationType.FINAL_SUCCESS;
+ //
+ // Let interested parties know
+ //
+ try {
+ System.out.println(Serialization.gsonPretty.toJson(notification));
+ //PolicyEngine.manager.deliver($params.getNotificationTopic(), notification);
+ } catch (Exception e) {
+ System.out.println("Can't deliver notification: " + notification);
+ e.printStackTrace();
+ }
+ //
+ // We are going to retract these objects from memory
+ //
+ System.out.println("Retracting everything");
+ retract($operationWrapper);
+ retract($request);
+ retract($response);
+ retract($event);
+ retract($manager);
+ } else {
+ $operationWrapper.operation.outcome = "FAILURE";
+ $manager.setControlLoopResult("FAILURE");
+ notification.history.add($operationWrapper.operation);
+ notification.notification = ControlLoopNotificationType.OPERATION_FAILURE;
+ //
+ // Let interested parties know
+ //
+ try {
+ System.out.println(Serialization.gsonPretty.toJson(notification));
+ //PolicyEngine.manager.deliver($params.getNotificationTopic(), notification);
+ } catch (Exception e) {
+ System.out.println("Can't deliver notification: " + notification);
+ e.printStackTrace();
+ }
+ notification.notification = ControlLoopNotificationType.FINAL_FAILURE;
+ //
+ // Let interested parties know
+ //
+ try {
+ System.out.println(Serialization.gsonPretty.toJson(notification));
+ //PolicyEngine.manager.deliver($params.getNotificationTopic(), notification);
+ } catch (Exception e) {
+ System.out.println("Can't deliver notification: " + notification);
+ e.printStackTrace();
+ }
+ //
+ // We are going to retract these objects from memory
+ //
+ System.out.println("Retracting everything");
+ retract($operationWrapper);
+ retract($request);
+ retract($response);
+ retract($event);
+ retract($manager);
+ }
+end
+
+/*
+ * Sample Queries for illustration with and without arguments
+ * The results of the query can be introspected (and retracted if desired)
+ * through REST API.
+ */
+query "${policyName}.QUERY.EVENT.ONSET"
+ event : VirtualControlLoopEvent( closedLoopEventStatus == ControlLoopEventStatus.ONSET )
+end
+
+query "${policyName}.QUERY.MANAGER.RNA" (String aRequestId, Integer numOnsetsLowerBound, Boolean aActivated)
+ manager : ControlLoopEventManager( closedLoopControlName == "${closedLoopControlName}",
+ requestID.toString() == aRequestId,
+ numOnsets > numOnsetsLowerBound,
+ activated == aActivated )
+end
diff --git a/controlloop/templates/template.demo.v1.0.0/template.demo/src/test/java/org/onap/policy/template/demo/TestAPPCPayload.java b/controlloop/templates/template.demo.v1.0.0/template.demo/src/test/java/org/onap/policy/template/demo/TestAPPCPayload.java
new file mode 100644
index 000000000..73501bce5
--- /dev/null
+++ b/controlloop/templates/template.demo.v1.0.0/template.demo/src/test/java/org/onap/policy/template/demo/TestAPPCPayload.java
@@ -0,0 +1,58 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * demo
+ * ================================================================================
+ * 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.template.demo;
+
+import java.util.HashMap;
+import java.util.UUID;
+
+import org.junit.Test;
+import org.onap.policy.appc.CommonHeader;
+import org.onap.policy.appc.Request;
+import org.onap.policy.appc.util.Serialization;
+import org.onap.policy.vnf.trafficgenerator.PGRequest;
+import org.onap.policy.vnf.trafficgenerator.PGStream;
+import org.onap.policy.vnf.trafficgenerator.PGStreams;
+
+public class TestAPPCPayload {
+
+ @Test
+ public void test() {
+ PGRequest request = new PGRequest();
+ request.pgStreams = new PGStreams();
+
+ PGStream pgStream;
+ for(int i = 0; i < 5; i++){
+ pgStream = new PGStream();
+ pgStream.streamId = "fw_udp"+(i+1);
+ pgStream.isEnabled = "true";
+ request.pgStreams.pgStream.add(pgStream);
+ }
+
+ Request appc = new Request();
+ appc.CommonHeader = new CommonHeader();
+ appc.CommonHeader.RequestID = UUID.randomUUID();
+ appc.Action = "ModifyConfig";
+ appc.Payload = new HashMap<String, Object>();
+ appc.Payload.put("pg-streams", request);
+ System.out.println(Serialization.gsonPretty.toJson(appc));
+ }
+
+}
diff --git a/controlloop/templates/template.demo.v1.0.0/template.demo/src/test/java/org/onap/policy/template/demo/TestFirewallDemo.java b/controlloop/templates/template.demo.v1.0.0/template.demo/src/test/java/org/onap/policy/template/demo/TestFirewallDemo.java
new file mode 100644
index 000000000..e48aafdad
--- /dev/null
+++ b/controlloop/templates/template.demo.v1.0.0/template.demo/src/test/java/org/onap/policy/template/demo/TestFirewallDemo.java
@@ -0,0 +1,593 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * demo
+ * ================================================================================
+ * 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.template.demo;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.time.Instant;
+import java.util.HashMap;
+import java.util.UUID;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.junit.Test;
+import org.kie.api.KieServices;
+import org.kie.api.builder.KieBuilder;
+import org.kie.api.builder.KieFileSystem;
+import org.kie.api.builder.Message;
+import org.kie.api.builder.ReleaseId;
+import org.kie.api.builder.Results;
+import org.kie.api.builder.model.KieModuleModel;
+import org.kie.api.runtime.KieContainer;
+import org.kie.api.runtime.KieSession;
+import org.kie.api.runtime.rule.FactHandle;
+import org.onap.policy.appc.CommonHeader;
+import org.onap.policy.appc.Response;
+import org.onap.policy.appc.ResponseStatus;
+import org.onap.policy.controlloop.ControlLoopEventStatus;
+import org.onap.policy.controlloop.ControlLoopTargetType;
+import org.onap.policy.controlloop.VirtualControlLoopEvent;
+import org.onap.policy.appc.util.Serialization;
+
+
+
+public class TestFirewallDemo {
+
+
+ @Test
+ public void testvDNS() throws IOException {
+ //
+ // Build a container
+ //
+ final String closedLoopControlName = "CL-DNS-LOW-TRAFFIC-SIG-d925ed73-8231-4d02-9545-db4e101f88f8";
+ final KieSession kieSession = buildContainer("src/main/resources/archetype-resources/src/main/resources/ControlLoopDemo__closedLoopControlName__.drl",
+ closedLoopControlName,
+ "type=operational",
+ "myFirewallDemoPolicy",
+ "v1.0",
+ "MSO",
+ "http://localhost:8080/TestREST/Test",
+ "POLICY",
+ "POLICY",
+ "http://localhost:8080/TestREST/Test",
+ "POLICY",
+ "POLICY",
+ "4ff56a54-9e3f-46b7-a337-07a1d3c6b469",
+ 0,
+ "POLICY-CL-MGT",
+ "APPC-CL"
+ );
+ //
+ // Initial fire of rules
+ //
+ kieSession.fireAllRules();
+ //
+ // Kick a thread that starts testing
+ //
+ new Thread(new Runnable() {
+
+ @Override
+ public void run() {
+ //
+ // Generate an invalid DCAE Event with requestID=null
+ //
+ VirtualControlLoopEvent invalidEvent = new VirtualControlLoopEvent();
+ invalidEvent.closedLoopControlName = closedLoopControlName;
+ invalidEvent.requestID = null;
+ invalidEvent.closedLoopEventClient = "tca.instance00001";
+ invalidEvent.target_type = ControlLoopTargetType.VF;
+ invalidEvent.target = "generic-vnf.vnf-id";
+ invalidEvent.from = "DCAE";
+ invalidEvent.closedLoopAlarmStart = Instant.now();
+ invalidEvent.AAI = new HashMap<String, String>();
+ invalidEvent.AAI.put("vserver.vserver-name", "vserver-name-16102016-aai3255-data-11-1");
+ invalidEvent.closedLoopEventStatus = ControlLoopEventStatus.ONSET;
+
+ System.out.println("----- Invalid ONSET -----");
+ System.out.println(Serialization.gsonPretty.toJson(invalidEvent));
+
+ //
+ // Insert invalid DCAE Event into memory
+ //
+ kieSession.insert(invalidEvent);
+ try {
+ Thread.sleep(500);
+ } catch (InterruptedException e) {
+ }
+ //
+ // Generate first DCAE ONSET Event
+ //
+ VirtualControlLoopEvent onsetEvent = new VirtualControlLoopEvent();
+ onsetEvent.closedLoopControlName = closedLoopControlName;
+ onsetEvent.requestID = UUID.randomUUID();
+ onsetEvent.closedLoopEventClient = "tca.instance00001";
+ onsetEvent.target_type = ControlLoopTargetType.VF;
+ onsetEvent.target = "generic-vnf.vnf-id";
+ onsetEvent.from = "DCAE";
+ onsetEvent.closedLoopAlarmStart = Instant.now();
+ onsetEvent.AAI = new HashMap<String, String>();
+ onsetEvent.AAI.put("vserver.vserver-name", "vserver-name-16102016-aai3255-data-11-1");
+ onsetEvent.closedLoopEventStatus = ControlLoopEventStatus.ONSET;
+
+ System.out.println("----- ONSET -----");
+ System.out.println(Serialization.gsonPretty.toJson(onsetEvent));
+
+ //
+ // Insert first DCAE ONSET Event into memory
+ //
+ kieSession.insert(onsetEvent);
+ //
+ // We have test for subsequent ONSET Events in testvFirewall()
+ // So no need to test it again here
+ //
+ try {
+ Thread.sleep(3000);
+ } catch (InterruptedException e) {
+ }
+ //
+ // Test is finished, so stop the kieSession
+ //
+ kieSession.halt();
+ }
+ //
+ }).start();
+ //
+ // Start firing rules
+ //
+ kieSession.fireUntilHalt();
+ //
+ // Dump working memory
+ //
+ dumpFacts(kieSession);
+ //
+ // See if there is anything left in memory, there SHOULD only be
+ // a params fact.
+ //
+ assertEquals("There should only be 1 Fact left in memory.", 1, kieSession.getFactCount());
+ for (FactHandle handle : kieSession.getFactHandles()) {
+ Object fact = kieSession.getObject(handle);
+ assertEquals("Non-Param Fact left in working memory", "org.onap.policy.controlloop.Params", fact.getClass().getName());
+ }
+ }
+
+ @Test
+ public void testvFirewall() throws IOException {
+ //
+ // Build a container
+ //
+ final String closedLoopControlName = "CL-FRWL-LOW-TRAFFIC-SIG-d925ed73-8231-4d02-9545-db4e101f88f8";
+ final KieSession kieSession = buildContainer("src/main/resources/archetype-resources/src/main/resources/ControlLoopDemo__closedLoopControlName__.drl",
+ closedLoopControlName,
+ "type=operational",
+ "myFirewallDemoPolicy",
+ "v1.0",
+ "APPC",
+ "http://localhost:8080/TestREST/Test",
+ "POLICY",
+ "POLICY",
+ null,
+ null,
+ null,
+ null,
+ 1,
+ "POLICY-CL-MGT",
+ "APPC-CL"
+ );
+ //
+ // Initial fire of rules
+ //
+ kieSession.fireAllRules();
+ //
+ // Kick a thread that starts testing
+ //
+ new Thread(new Runnable() {
+
+ @Override
+ public void run() {
+ //
+ // Generate an invalid DCAE Event with requestID=null
+ //
+ VirtualControlLoopEvent invalidEvent = new VirtualControlLoopEvent();
+ invalidEvent.closedLoopControlName = closedLoopControlName;
+ invalidEvent.requestID = null;
+ invalidEvent.closedLoopEventClient = "tca.instance00001";
+ invalidEvent.target_type = ControlLoopTargetType.VF;
+ invalidEvent.target = "generic-vnf.vnf-id";
+ invalidEvent.from = "DCAE";
+ invalidEvent.closedLoopAlarmStart = Instant.now();
+ invalidEvent.AAI = new HashMap<String, String>();
+ invalidEvent.AAI.put("generic-vnf.vnf-id", "foo");
+ invalidEvent.closedLoopEventStatus = ControlLoopEventStatus.ONSET;
+
+ System.out.println("----- Invalid ONSET -----");
+ System.out.println(Serialization.gsonPretty.toJson(invalidEvent));
+
+ //
+ // Insert invalid DCAE Event into memory
+ //
+ kieSession.insert(invalidEvent);
+ try {
+ Thread.sleep(500);
+ } catch (InterruptedException e) {
+ }
+ //
+ // Generate first DCAE ONSET Event
+ //
+ VirtualControlLoopEvent onsetEvent = new VirtualControlLoopEvent();
+ onsetEvent.closedLoopControlName = closedLoopControlName;
+ onsetEvent.requestID = UUID.randomUUID();
+ onsetEvent.closedLoopEventClient = "tca.instance00001";
+ onsetEvent.target_type = ControlLoopTargetType.VF;
+ onsetEvent.target = "generic-vnf.vnf-id";
+ onsetEvent.from = "DCAE";
+ onsetEvent.closedLoopAlarmStart = Instant.now();
+ onsetEvent.AAI = new HashMap<String, String>();
+ onsetEvent.AAI.put("generic-vnf.vnf-id", "fw0001vm001fw001");
+ //onsetEvent.AAI.put("vserver.vserver-name", "vserver-name-16102016-aai3255-data-11-1");
+ onsetEvent.closedLoopEventStatus = ControlLoopEventStatus.ONSET;
+
+ System.out.println("----- ONSET -----");
+ System.out.println(Serialization.gsonPretty.toJson(onsetEvent));
+
+ //
+ // Insert first DCAE ONSET Event into memory
+ //
+ kieSession.insert(onsetEvent);
+ try {
+ Thread.sleep(500);
+ } catch (InterruptedException e) {
+ }
+
+
+ Thread thread = new Thread(new Runnable() {
+
+ @Override
+ public void run() {
+ while (true) {
+ //
+ // Generate subsequent DCAE ONSET Event
+ //
+ VirtualControlLoopEvent subOnsetEvent = new VirtualControlLoopEvent();
+ subOnsetEvent.closedLoopControlName = closedLoopControlName;
+ subOnsetEvent.requestID = UUID.randomUUID();
+ subOnsetEvent.closedLoopEventClient = "tca.instance00001";
+ subOnsetEvent.target_type = ControlLoopTargetType.VF;
+ subOnsetEvent.target = "generic-vnf.vnf-id";
+ subOnsetEvent.from = "DCAE";
+ subOnsetEvent.closedLoopAlarmStart = Instant.now();
+ subOnsetEvent.AAI = new HashMap<String, String>();
+ subOnsetEvent.AAI.put("generic-vnf.vnf-id", "fw0001vm001fw001");
+ //subOnsetEvent.AAI.put("vserver.vserver-name", "vserver-name-16102016-aai3255-data-11-1");
+ subOnsetEvent.closedLoopEventStatus = ControlLoopEventStatus.ONSET;
+
+ System.out.println("----- Subsequent ONSET -----");
+ System.out.println(Serialization.gsonPretty.toJson(subOnsetEvent));
+
+ //
+ // Insert subsequent DCAE ONSET Event into memory
+ //
+ kieSession.insert(subOnsetEvent);
+ try {
+ Thread.sleep(500);
+ } catch (InterruptedException e) {
+ break;
+ }
+ }
+ }
+
+ });
+ thread.start();
+ try {
+ Thread.sleep(3000);
+ } catch (InterruptedException e) {
+ }
+ //
+ // Stop the thread
+ //
+ thread.interrupt();
+ //
+ // Generate APPC ACCEPT Response
+ //
+ Response response1 = new Response();
+ // CommonHeader
+ CommonHeader commonHeader1 = new CommonHeader();
+ commonHeader1.RequestID = onsetEvent.requestID;
+ response1.CommonHeader = commonHeader1;
+ // ResponseStatus
+ ResponseStatus responseStatus1 = new ResponseStatus();
+ responseStatus1.Code = 100;
+ response1.Status = responseStatus1;
+ //
+ System.out.println("----- APP-C RESPONSE 100 -----");
+ System.out.println(Serialization.gsonPretty.toJson(response1));
+ //
+ // Insert APPC Response into memory
+ //
+ kieSession.insert(response1);
+ //
+ // Simulating APPC takes some time for processing the recipe
+ // and then gives response
+ //
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ }
+ //
+ // Generate APPC SUCCESS Response
+ //
+ Response response2 = new Response();
+ // CommonHeader
+ CommonHeader commonHeader2 = new CommonHeader();
+ commonHeader2.RequestID = onsetEvent.requestID;
+ response2.CommonHeader = commonHeader2;
+ // ResponseStatus
+ ResponseStatus responseStatus2 = new ResponseStatus();
+ responseStatus2.Code = 400;
+ response2.Status = responseStatus2;
+ //
+ System.out.println("----- APP-C RESPONSE 400 -----");
+ System.out.println(Serialization.gsonPretty.toJson(response2));
+ //
+ // Insert APPC Response into memory
+ //
+ kieSession.insert(response2);
+ //
+ try {
+ Thread.sleep(3000);
+ } catch (InterruptedException e) {
+ }
+ //
+ // Test is finished, so stop the kieSession
+ //
+ kieSession.halt();
+ }
+ //
+ }).start();
+ //
+ // Start firing rules
+ //
+ kieSession.fireUntilHalt();
+ //
+ // Dump working memory
+ //
+ dumpFacts(kieSession);
+ //
+ // See if there is anything left in memory, there SHOULD only be
+ // a params fact.
+ //
+ assertEquals("There should only be 1 Fact left in memory.", 1, kieSession.getFactCount());
+ for (FactHandle handle : kieSession.getFactHandles()) {
+ Object fact = kieSession.getObject(handle);
+ assertEquals("Non-Param Fact left in working memory", "org.onap.policy.controlloop.Params", fact.getClass().getName());
+ }
+ }
+
+ public static void dumpFacts(KieSession kieSession) {
+ System.out.println("Fact Count: " + kieSession.getFactCount());
+ for (FactHandle handle : kieSession.getFactHandles()) {
+ System.out.println("FACT: " + handle);
+ }
+ }
+
+ public static KieSession buildContainer(String droolsTemplate,
+ String closedLoopControlName,
+ String policyScope,
+ String policyName,
+ String policyVersion,
+ String actor,
+ String aaiURL,
+ String aaiUsername,
+ String aaiPassword,
+ String msoURL,
+ String msoUsername,
+ String msoPassword,
+ String aaiNamedQuery,
+ int aaiPatternMatch,
+ String notificationTopic,
+ String appcTopic ) throws IOException {
+ //
+ // Get our Drools Kie factory
+ //
+ KieServices ks = KieServices.Factory.get();
+
+ KieModuleModel kModule = ks.newKieModuleModel();
+
+ System.out.println("KMODULE:" + System.lineSeparator() + kModule.toXML());
+
+ //
+ // Generate our drools rule from our template
+ //
+ KieFileSystem kfs = ks.newKieFileSystem();
+
+ kfs.writeKModuleXML(kModule.toXML());
+ {
+ Path rule = Paths.get(droolsTemplate);
+ String ruleTemplate = new String(Files.readAllBytes(rule));
+ String drlContents = generatePolicy(ruleTemplate,
+ closedLoopControlName,
+ policyScope,
+ policyName,
+ policyVersion,
+ actor,
+ aaiURL,
+ aaiUsername,
+ aaiPassword,
+ msoURL,
+ msoUsername,
+ msoPassword,
+ aaiNamedQuery,
+ aaiPatternMatch,
+ notificationTopic,
+ appcTopic
+ );
+
+ kfs.write("src/main/resources/" + policyName + ".drl", ks.getResources().newByteArrayResource(drlContents.getBytes()));
+ }
+ //
+ // Compile the rule
+ //
+ KieBuilder builder = ks.newKieBuilder(kfs).buildAll();
+ Results results = builder.getResults();
+ if (results.hasMessages(Message.Level.ERROR)) {
+ for (Message msg : results.getMessages()) {
+ System.err.println(msg.toString());
+ }
+ throw new RuntimeException("Drools Rule has Errors");
+ }
+ for (Message msg : results.getMessages()) {
+ System.out.println(msg.toString());
+ }
+ //
+ // Create our kie Session and container
+ //
+ ReleaseId releaseId = ks.getRepository().getDefaultReleaseId();
+ System.out.println(releaseId);
+ KieContainer kContainer = ks.newKieContainer(releaseId);
+
+ return kContainer.newKieSession();
+ }
+ public static String generatePolicy(String ruleContents,
+ String closedLoopControlName,
+ String policyScope,
+ String policyName,
+ String policyVersion,
+ String actor,
+ String aaiURL,
+ String aaiUsername,
+ String aaiPassword,
+ String msoURL,
+ String msoUsername,
+ String msoPassword,
+ String aaiNamedQueryUUID,
+ int aaiPatternMatch,
+ String notificationTopic,
+ String appcTopic) {
+
+ Pattern p = Pattern.compile("\\$\\{closedLoopControlName\\}");
+ Matcher m = p.matcher(ruleContents);
+ ruleContents = m.replaceAll(closedLoopControlName);
+
+ p = Pattern.compile("\\$\\{policyScope\\}");
+ m = p.matcher(ruleContents);
+ ruleContents = m.replaceAll(policyScope);
+
+ p = Pattern.compile("\\$\\{policyName\\}");
+ m = p.matcher(ruleContents);
+ ruleContents = m.replaceAll(policyName);
+
+ p = Pattern.compile("\\$\\{policyVersion\\}");
+ m = p.matcher(ruleContents);
+ ruleContents = m.replaceAll(policyVersion);
+
+ p = Pattern.compile("\\$\\{actor\\}");
+ m = p.matcher(ruleContents);
+ ruleContents = m.replaceAll(actor);
+
+ p = Pattern.compile("\\$\\{aaiURL\\}");
+ m = p.matcher(ruleContents);
+ if (aaiURL == null) {
+ ruleContents = m.replaceAll("null");
+ } else {
+ ruleContents = m.replaceAll(aaiURL);
+ }
+
+ p = Pattern.compile("\\$\\{aaiUsername\\}");
+ m = p.matcher(ruleContents);
+ if (aaiUsername == null) {
+ ruleContents = m.replaceAll("null");
+ } else {
+ ruleContents = m.replaceAll(aaiUsername);
+ }
+
+ p = Pattern.compile("\\$\\{aaiPassword\\}");
+ m = p.matcher(ruleContents);
+ if (aaiPassword == null) {
+ ruleContents = m.replaceAll("null");
+ } else {
+ ruleContents = m.replaceAll(aaiPassword);
+ }
+
+ p = Pattern.compile("\\$\\{msoURL\\}");
+ m = p.matcher(ruleContents);
+ if (msoURL == null) {
+ ruleContents = m.replaceAll("null");
+ } else {
+ ruleContents = m.replaceAll(msoURL);
+ }
+
+ p = Pattern.compile("\\$\\{msoUsername\\}");
+ m = p.matcher(ruleContents);
+ if (msoUsername == null) {
+ ruleContents = m.replaceAll("null");
+ } else {
+ ruleContents = m.replaceAll(msoUsername);
+ }
+
+ p = Pattern.compile("\\$\\{msoPassword\\}");
+ m = p.matcher(ruleContents);
+ if (msoPassword == null) {
+ ruleContents = m.replaceAll("null");
+ } else {
+ ruleContents = m.replaceAll(msoPassword);
+ }
+
+ p = Pattern.compile("\\$\\{aaiNamedQueryUUID\\}");
+ m = p.matcher(ruleContents);
+ if (aaiNamedQueryUUID == null) {
+ ruleContents = m.replaceAll("null");
+ } else {
+ ruleContents = m.replaceAll(aaiNamedQueryUUID);
+ }
+
+ p = Pattern.compile("\\$\\{aaiPatternMatch\\}");
+ m = p.matcher(ruleContents);
+ if (aaiPatternMatch == 1) {
+ ruleContents = m.replaceAll("1");
+ } else {
+ ruleContents = m.replaceAll("0");
+ }
+
+ p = Pattern.compile("\\$\\{notificationTopic\\}");
+ m = p.matcher(ruleContents);
+ if (notificationTopic == null) {
+ ruleContents = m.replaceAll("null");
+ } else {
+ ruleContents = m.replaceAll(notificationTopic);
+ }
+
+ p = Pattern.compile("\\$\\{appcTopic\\}");
+ m = p.matcher(ruleContents);
+ if (appcTopic == null) {
+ ruleContents = m.replaceAll("null");
+ } else {
+ ruleContents = m.replaceAll(appcTopic);
+ }
+
+ System.out.println(ruleContents);
+
+ return ruleContents;
+ }
+
+}
diff --git a/controlloop/templates/template.demo.v1.0.0/template.demo/src/test/java/org/onap/policy/template/demo/TestMSO.java b/controlloop/templates/template.demo.v1.0.0/template.demo/src/test/java/org/onap/policy/template/demo/TestMSO.java
new file mode 100644
index 000000000..a960661ee
--- /dev/null
+++ b/controlloop/templates/template.demo.v1.0.0/template.demo/src/test/java/org/onap/policy/template/demo/TestMSO.java
@@ -0,0 +1,159 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * demo
+ * ================================================================================
+ * 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.template.demo;
+
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.util.UUID;
+
+import org.junit.Test;
+import org.onap.policy.mso.MSOCloudConfiguration;
+import org.onap.policy.mso.MSOModelInfo;
+import org.onap.policy.mso.MSORelatedInstance;
+import org.onap.policy.mso.MSORelatedInstanceListElement;
+import org.onap.policy.mso.MSORequest;
+import org.onap.policy.mso.MSORequestDetails;
+import org.onap.policy.mso.MSORequestInfo;
+import org.onap.policy.mso.MSORequestParameters;
+import org.onap.policy.aai.AAINQF199.AAINQF199Response;
+import org.onap.policy.aai.AAINQF199.AAINQF199ResponseWrapper;
+import org.onap.policy.mso.util.Serialization;
+
+import com.google.gson.Gson;
+import com.google.gson.stream.JsonReader;
+
+public class TestMSO {
+
+ @Test
+ public void test() throws FileNotFoundException {
+ Gson gson = new Gson();
+ JsonReader reader = new JsonReader(new FileReader("src/test/resources/aairesponse.json"));
+ AAINQF199Response response = gson.fromJson(reader, AAINQF199Response.class);
+
+ System.out.println(Serialization.gsonPretty.toJson(response));
+
+ AAINQF199ResponseWrapper aainqf199ResponseWrapper = new AAINQF199ResponseWrapper(UUID.randomUUID(), response);
+
+ //
+ //
+ // vnfItem
+ //
+ String vnfItemVnfId = aainqf199ResponseWrapper.aainqf199response.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).genericVNF.vnfID;
+ String vnfItemVnfType = aainqf199ResponseWrapper.aainqf199response.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).genericVNF.vnfType;
+ vnfItemVnfType = vnfItemVnfType.substring(vnfItemVnfType.lastIndexOf("/")+1);
+ String vnfItemPersonaModelId = aainqf199ResponseWrapper.aainqf199response.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).genericVNF.personaModelId;
+ String vnfItemPersonaModelVersion = aainqf199ResponseWrapper.aainqf199response.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).genericVNF.personaModelVersion;
+ String vnfItemModelName = aainqf199ResponseWrapper.aainqf199response.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).extraProperties.extraProperty.get(0).propertyValue;
+ String vnfItemModelNameVersionId = aainqf199ResponseWrapper.aainqf199response.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).extraProperties.extraProperty.get(4).propertyValue;
+ //
+ // serviceItem
+ //
+ String serviceItemServiceInstanceId = aainqf199ResponseWrapper.aainqf199response.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).serviceInstance.serviceInstanceID;
+ String serviceItemPersonaModelId = aainqf199ResponseWrapper.aainqf199response.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).serviceInstance.personaModelId;
+ String serviceItemModelName = aainqf199ResponseWrapper.aainqf199response.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).extraProperties.extraProperty.get(0).propertyValue;
+ String serviceItemModelVersion = aainqf199ResponseWrapper.aainqf199response.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).serviceInstance.personaModelVersion;
+ String serviceItemModelNameVersionId = aainqf199ResponseWrapper.aainqf199response.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).extraProperties.extraProperty.get(4).propertyValue;
+ //
+ // This comes from the base module
+ //
+ String vfModuleItemVfModuleName = aainqf199ResponseWrapper.aainqf199response.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).items.inventoryResponseItems.get(1).vfModule.vfModuleName;
+ vfModuleItemVfModuleName = vfModuleItemVfModuleName.replace("Vfmodule", "vDNS");
+ //
+ // vfModuleItem - NOT the base module
+ //
+ String vfModuleItemPersonaModelId = aainqf199ResponseWrapper.aainqf199response.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).items.inventoryResponseItems.get(2).vfModule.personaModelId;
+ String vfModuleItemPersonaModelVersion = aainqf199ResponseWrapper.aainqf199response.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).items.inventoryResponseItems.get(2).vfModule.personaModelVersion;
+ String vfModuleItemModelName = aainqf199ResponseWrapper.aainqf199response.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).items.inventoryResponseItems.get(2).extraProperties.extraProperty.get(0).propertyValue;
+ String vfModuleItemModelNameVersionId = aainqf199ResponseWrapper.aainqf199response.inventoryResponseItems.get(0).items.inventoryResponseItems.get(0).items.inventoryResponseItems.get(2).extraProperties.extraProperty.get(4).propertyValue;
+
+ //
+ // tenantItem
+ //
+ String tenantItemTenantId = aainqf199ResponseWrapper.aainqf199response.inventoryResponseItems.get(0).items.inventoryResponseItems.get(1).tenant.tenantId;
+ //
+ // cloudRegionItem
+ //
+ String cloudRegionItemCloudRegionId = aainqf199ResponseWrapper.aainqf199response.inventoryResponseItems.get(0).items.inventoryResponseItems.get(1).items.inventoryResponseItems.get(0).cloudRegion.cloudRegionId;
+
+ //
+ // Construct an MSO request
+ //
+ MSORequest request = new MSORequest();
+ request.requestDetails = new MSORequestDetails();
+ request.requestDetails.modelInfo = new MSOModelInfo();
+ request.requestDetails.cloudConfiguration = new MSOCloudConfiguration();
+ request.requestDetails.requestInfo = new MSORequestInfo();
+ request.requestDetails.requestParameters = new MSORequestParameters();
+ request.requestDetails.requestParameters.userParams = null;
+ //
+ // cloudConfiguration
+ //
+ request.requestDetails.cloudConfiguration.lcpCloudRegionId = cloudRegionItemCloudRegionId;
+ request.requestDetails.cloudConfiguration.tenantId = tenantItemTenantId;
+ //
+ // modelInfo
+ //
+ request.requestDetails.modelInfo.modelType = "vfModule";
+ request.requestDetails.modelInfo.modelInvariantId = vfModuleItemPersonaModelId;
+ request.requestDetails.modelInfo.modelNameVersionId = vfModuleItemModelNameVersionId;
+ request.requestDetails.modelInfo.modelName = vfModuleItemModelName;
+ request.requestDetails.modelInfo.modelVersion = vfModuleItemPersonaModelVersion;
+ //
+ // requestInfo
+ //
+ request.requestDetails.requestInfo.instanceName = vfModuleItemVfModuleName;
+ request.requestDetails.requestInfo.source = "POLICY";
+ request.requestDetails.requestInfo.suppressRollback = false;
+ //
+ // relatedInstanceList
+ //
+ MSORelatedInstanceListElement relatedInstanceListElement1 = new MSORelatedInstanceListElement();
+ MSORelatedInstanceListElement relatedInstanceListElement2 = new MSORelatedInstanceListElement();
+ relatedInstanceListElement1.relatedInstance = new MSORelatedInstance();
+ relatedInstanceListElement2.relatedInstance = new MSORelatedInstance();
+ //
+ relatedInstanceListElement1.relatedInstance.instanceId = serviceItemServiceInstanceId;
+ relatedInstanceListElement1.relatedInstance.modelInfo = new MSOModelInfo();
+ relatedInstanceListElement1.relatedInstance.modelInfo.modelType = "service";
+ relatedInstanceListElement1.relatedInstance.modelInfo.modelInvariantId = serviceItemPersonaModelId;
+ relatedInstanceListElement1.relatedInstance.modelInfo.modelNameVersionId = serviceItemModelNameVersionId;
+ relatedInstanceListElement1.relatedInstance.modelInfo.modelName = serviceItemModelName;
+ relatedInstanceListElement1.relatedInstance.modelInfo.modelVersion = serviceItemModelVersion;
+ //
+ relatedInstanceListElement2.relatedInstance.instanceId = vnfItemVnfId;
+ relatedInstanceListElement2.relatedInstance.modelInfo = new MSOModelInfo();
+ relatedInstanceListElement2.relatedInstance.modelInfo.modelType = "vnf";
+ relatedInstanceListElement2.relatedInstance.modelInfo.modelInvariantId = vnfItemPersonaModelId;
+ relatedInstanceListElement2.relatedInstance.modelInfo.modelNameVersionId = vnfItemModelNameVersionId;
+ relatedInstanceListElement2.relatedInstance.modelInfo.modelName = vnfItemModelName;
+ relatedInstanceListElement2.relatedInstance.modelInfo.modelVersion = vnfItemPersonaModelVersion;
+ relatedInstanceListElement2.relatedInstance.modelInfo.modelCustomizationName = vnfItemVnfType;
+ //
+ request.requestDetails.relatedInstanceList.add(relatedInstanceListElement1);
+ request.requestDetails.relatedInstanceList.add(relatedInstanceListElement2);
+ //
+ // print MSO request for debug
+ //
+ System.out.println("MSO request sent:");
+ System.out.println(Serialization.gsonPretty.toJson(request));
+ }
+
+}
diff --git a/controlloop/templates/template.demo.v1.0.0/template.demo/src/test/resources/aairesponse.json b/controlloop/templates/template.demo.v1.0.0/template.demo/src/test/resources/aairesponse.json
new file mode 100644
index 000000000..66da8e715
--- /dev/null
+++ b/controlloop/templates/template.demo.v1.0.0/template.demo/src/test/resources/aairesponse.json
@@ -0,0 +1,227 @@
+{
+ "inventory-response-item": [
+ {
+ "extra-properties": {},
+ "inventory-response-items": {
+ "inventory-response-item": [
+ {
+ "extra-properties": {
+ "extra-property": [
+ {
+ "property-name": "model.model-name",
+ "property-value": "c15ce9e1-e914-4c8f-b8bb"
+ },
+ {
+ "property-name": "model.model-type",
+ "property-value": "resource"
+ },
+ {
+ "property-name": "model.model-version",
+ "property-value": "1"
+ },
+ {
+ "property-name": "model.model-id",
+ "property-value": "033a32ed-aa65-4764-a736-36f2942f1aa0"
+ },
+ {
+ "property-name": "model.model-name-version-id",
+ "property-value": "d4d072dc-4e21-4a03-9524-628985819a8e"
+ }
+ ]
+ },
+ "generic-vnf": {
+ "in-maint": false,
+ "is-closed-loop-disabled": false,
+ "orchestration-status": "Created",
+ "persona-model-id": "033a32ed-aa65-4764-a736-36f2942f1aa0",
+ "persona-model-version": "1.0",
+ "resource-version": "1485542422",
+ "service-id": "b3f70641-bdb9-4030-825e-6abb73a1f929",
+ "vnf-id": "594e2fe0-48b8-41ff-82e2-3d4bab69b192",
+ "vnf-name": "Vnf_Ete_Named90e1ab3-dcd5-4877-9edb-eadfc84e32c8",
+ "vnf-type": "8330e932-2a23-4943-8606/c15ce9e1-e914-4c8f-b8bb 1"
+ },
+ "inventory-response-items": {
+ "inventory-response-item": [
+ {
+ "extra-properties": {
+ "extra-property": [
+ {
+ "property-name": "model.model-name",
+ "property-value": "8330e932-2a23-4943-8606"
+ },
+ {
+ "property-name": "model.model-type",
+ "property-value": "service"
+ },
+ {
+ "property-name": "model.model-version",
+ "property-value": "1"
+ },
+ {
+ "property-name": "model.model-id",
+ "property-value": "4fcbc1c0-7793-46d8-8aa1-fa1c2ed9ec7b"
+ },
+ {
+ "property-name": "model.model-name-version-id",
+ "property-value": "5c996219-b2e2-4c76-9b43-7e8672a33c1d"
+ }
+ ]
+ },
+ "service-instance": {
+ "persona-model-id": "4fcbc1c0-7793-46d8-8aa1-fa1c2ed9ec7b",
+ "persona-model-version": "1.0",
+ "resource-version": "1485542400",
+ "service-instance-id": "cf8426a6-0b53-4e3d-bfa6-4b2f4d5913a5",
+ "service-instance-name": "Service_Ete_Named90e1ab3-dcd5-4877-9edb-eadfc84e32c8"
+ }
+ },
+ {
+ "extra-properties": {
+ "extra-property": [
+ {
+ "property-name": "model.model-name",
+ "property-value": "C15ce9e1E9144c8fB8bb..base_vlb..module-0"
+ },
+ {
+ "property-name": "model.model-type",
+ "property-value": "resource"
+ },
+ {
+ "property-name": "model.model-version",
+ "property-value": "1"
+ },
+ {
+ "property-name": "model.model-id",
+ "property-value": "79ee24cd-fc9a-4f14-afae-5e1dd2ab2941"
+ },
+ {
+ "property-name": "model.model-name-version-id",
+ "property-value": "5484cabb-1a0d-4f29-a616-094a3f643d73"
+ }
+ ]
+ },
+ "model-name": "C15ce9e1E9144c8fB8bb..base_vlb..module-0",
+ "vf-module": {
+ "heat-stack-id": "Vfmodule_Ete_Named90e1ab3-dcd5-4877-9edb-eadfc84e32c8/5845f37b-6cda-4e91-8ca3-f5572d226488",
+ "is-base-vf-module": true,
+ "orchestration-status": "active",
+ "persona-model-id": "79ee24cd-fc9a-4f14-afae-5e1dd2ab2941",
+ "persona-model-version": "1",
+ "resource-version": "1485542667",
+ "vf-module-id": "b0eff878-e2e1-4947-9597-39afdd0f51dd",
+ "vf-module-name": "Vfmodule_Ete_Named90e1ab3-dcd5-4877-9edb-eadfc84e32c8"
+ }
+ },
+ {
+ "extra-properties": {
+ "extra-property": [
+ {
+ "property-name": "model.model-name",
+ "property-value": "C15ce9e1E9144c8fB8bb..dnsscaling..module-1"
+ },
+ {
+ "property-name": "model.model-type",
+ "property-value": "resource"
+ },
+ {
+ "property-name": "model.model-version",
+ "property-value": "1"
+ },
+ {
+ "property-name": "model.model-id",
+ "property-value": "f32568ec-2f1c-458a-864b-0593d53d141a"
+ },
+ {
+ "property-name": "model.model-name-version-id",
+ "property-value": "69615025-879d-4f0d-afe3-b7d1a7eeed1f"
+ }
+ ]
+ },
+ "vf-module": {
+ "is-base-vf-module": false,
+ "persona-model-id": "f32568ec-2f1c-458a-864b-0593d53d141a",
+ "persona-model-version": "1.0",
+ "resource-version": "1485561752",
+ "vf-module-id": "dummy",
+ "vf-module-name": "dummy"
+ }
+ },
+ {
+ "extra-properties": {
+ "extra-property": [
+ {
+ "property-name": "model.model-name",
+ "property-value": "C15ce9e1E9144c8fB8bb..dnsscaling..module-1"
+ },
+ {
+ "property-name": "model.model-type",
+ "property-value": "resource"
+ },
+ {
+ "property-name": "model.model-version",
+ "property-value": "1"
+ },
+ {
+ "property-name": "model.model-id",
+ "property-value": "f32568ec-2f1c-458a-864b-0593d53d141a"
+ },
+ {
+ "property-name": "model.model-name-version-id",
+ "property-value": "69615025-879d-4f0d-afe3-b7d1a7eeed1f"
+ }
+ ]
+ },
+ "vf-module": {
+ "heat-stack-id": "vDNS_Ete_Named90e1ab3-dcd5-4877-9edb-eadfc84e32c8/f447ce51-14dd-4dcd-9957-68a047c79673",
+ "is-base-vf-module": false,
+ "orchestration-status": "active",
+ "persona-model-id": "f32568ec-2f1c-458a-864b-0593d53d141a",
+ "persona-model-version": "1.0",
+ "resource-version": "1485562712",
+ "vf-module-id": "8cd79e44-1fae-48c1-a160-609f90b46749",
+ "vf-module-name": "vDNS_Ete_Named90e1ab3-dcd5-4877-9edb-eadfc84e32c8"
+ }
+ }
+ ]
+ }
+ },
+ {
+ "extra-properties": {},
+ "inventory-response-items": {
+ "inventory-response-item": [
+ {
+ "cloud-region": {
+ "cloud-owner": "Rackspace",
+ "cloud-region-id": "DFW",
+ "cloud-region-version": "v1",
+ "cloud-type": "SharedNode",
+ "cloud-zone": "CloudZone",
+ "owner-defined-type": "OwnerType",
+ "resource-version": "1485465545"
+ },
+ "extra-properties": {}
+ }
+ ]
+ },
+ "tenant": {
+ "resource-version": "1485465545",
+ "tenant-id": "1015548",
+ "tenant-name": "1015548"
+ }
+ }
+ ]
+ },
+ "vserver": {
+ "in-maint": false,
+ "is-closed-loop-disabled": false,
+ "prov-status": "ACTIVE",
+ "resource-version": "1485546436",
+ "vserver-id": "70f081eb-2a87-4c81-9296-4b93d7d145c6",
+ "vserver-name": "vlb-lb-32c8",
+ "vserver-name2": "vlb-lb-32c8",
+ "vserver-selflink": "https://dfw.servers.api.rackspacecloud.com/v2/1015548/servers/70f081eb-2a87-4c81-9296-4b93d7d145c6"
+ }
+ }
+ ]
+}
diff --git a/controlloop/templates/template.demo/README.md b/controlloop/templates/template.demo/README.md
new file mode 100644
index 000000000..a037ba80d
--- /dev/null
+++ b/controlloop/templates/template.demo/README.md
@@ -0,0 +1,3 @@
+
+This is the ongoing implementation of template to support vFW/vDNS with integration with AAI.
+
diff --git a/controlloop/templates/template.demo/pom.xml b/controlloop/templates/template.demo/pom.xml
new file mode 100644
index 000000000..e7aab68b3
--- /dev/null
+++ b/controlloop/templates/template.demo/pom.xml
@@ -0,0 +1,112 @@
+<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>template.demo</artifactId>
+ <dependencies>
+ <dependency>
+ <groupId>org.drools</groupId>
+ <artifactId>drools-core</artifactId>
+ <version>6.3.0.Final</version>
+ </dependency>
+ <dependency>
+ <groupId>org.drools</groupId>
+ <artifactId>drools-compiler</artifactId>
+ <version>6.3.0.Final</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.policy.drools-applications</groupId>
+ <artifactId>appc</artifactId>
+ <version>1.1.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.policy.drools-applications</groupId>
+ <artifactId>events</artifactId>
+ <version>1.1.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.policy.drools-applications</groupId>
+ <artifactId>guard</artifactId>
+ <version>1.1.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.policy.drools-applications</groupId>
+ <artifactId>aai</artifactId>
+ <version>1.1.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.policy.drools-applications</groupId>
+ <artifactId>sdc</artifactId>
+ <version>1.1.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.policy.drools-applications</groupId>
+ <artifactId>events</artifactId>
+ <version>1.1.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.policy.drools-applications</groupId>
+ <artifactId>policy-yaml</artifactId>
+ <version>1.1.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.policy.drools-applications</groupId>
+ <artifactId>eventmanager</artifactId>
+ <version>1.1.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ <version>2.4</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.httpcomponents</groupId>
+ <artifactId>httpclient</artifactId>
+ <version>4.5.2</version>
+ </dependency>
+ <dependency>
+ <groupId>com.att.research.xacml</groupId>
+ <artifactId>xacml</artifactId>
+ <version>1.0.0</version>
+ </dependency>
+ <dependency>
+ <groupId>com.att.research.xacml</groupId>
+ <artifactId>xacml-pdp</artifactId>
+ <version>1.0.0</version>
+ </dependency>
+ <dependency>
+ <groupId>javax.persistence</groupId>
+ <artifactId>persistence-api</artifactId>
+ <version>1.0.2</version>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.persistence</groupId>
+ <artifactId>org.eclipse.persistence.jpa</artifactId>
+ <version>2.6.4</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.onap.policy.drools-applications</groupId>
+ <artifactId>actorServiceProvider</artifactId>
+ <version>1.1.0-SNAPSHOT</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.policy.drools-applications</groupId>
+ <artifactId>actor.appc</artifactId>
+ <version>1.1.0-SNAPSHOT</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.12</version>
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/controlloop/templates/template.demo/src/main/resources/ControlLoop_Template_1707_xacml_guard.drl b/controlloop/templates/template.demo/src/main/resources/ControlLoop_Template_1707_xacml_guard.drl
new file mode 100644
index 000000000..330f41b56
--- /dev/null
+++ b/controlloop/templates/template.demo/src/main/resources/ControlLoop_Template_1707_xacml_guard.drl
@@ -0,0 +1,917 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * demo
+ * ================================================================================
+ * 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 com.att.ecomp.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.eventmanager.ControlLoopEventManager;
+import org.onap.policy.controlloop.eventmanager.ControlLoopEventManager.NEW_EVENT_STATUS;
+import org.onap.policy.controlloop.eventmanager.ControlLoopOperationManager;
+import org.onap.policy.appc.Request;
+import org.onap.policy.appc.Response;
+import org.onap.policy.appc.CommonHeader;
+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 com.att.research.xacml.api.pdp.PDPEngine;
+import com.att.research.xacml.std.annotations.RequestParser;
+import org.onap.policy.guard.PolicyGuardXacmlHelper;
+import org.onap.policy.controlloop.policy.ControlLoopPolicy;
+import org.onap.policy.controlloop.policy.Policy;
+import java.net.URLDecoder;
+import org.eclipse.persistence.exceptions.DatabaseException;
+
+//
+// REPLACE THESE WITH PRODUCTION VERSIONS
+//
+import org.onap.policy.controlloop.ControlLoopLogger;
+import org.onap.policy.drools.PolicyEngine;
+import org.yaml.snakeyaml.Yaml;
+import org.yaml.snakeyaml.constructor.Constructor;
+
+global ControlLoopLogger Logger;
+global PolicyEngine Engine;
+global PDPEngine XacmlPdpEngine;
+
+import java.time.Instant;
+import java.util.LinkedList;
+import java.util.Iterator;
+
+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
+ //
+ // Logging
+ //
+ Logger.info("------------------------------------------------------------------------------------------------");
+ Logger.metrics(Instant.now() + " " + drools.getRule().getName() + " " + drools.getRule().getPackage());
+ Params params = new Params();
+ params.setClosedLoopControlName("${closedLoopControlName}");
+ params.setControlLoopYaml("${controlLoopYaml}");
+ insert(params);
+ Logger.metrics("Inserted " + params);
+ Logger.info("------------------------------------------------------------------------------------------------");
+
+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
+ try {
+ //
+ // Logging
+ //
+ Logger.info("------------------------------------------------------------------------------------------------");
+ Logger.metrics(Instant.now() + " " + drools.getRule().getName() + " " + drools.getRule().getPackage());
+ //
+ // 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
+ //
+ Engine.deliver("UEB", "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
+ //
+ Engine.deliver("UEB", "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
+ //
+ Engine.deliver("UEB", "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) {
+ e.printStackTrace();
+ 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}";
+ //
+ //
+ //
+ Engine.deliver("UEB", "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
+ //
+ // Logging
+ //
+ Logger.info("------------------------------------------------------------------------------------------------");
+ Logger.metrics(Instant.now() + " " + drools.getRule().getName() + " " + drools.getRule().getPackage());
+ Logger.metrics($params);
+ Logger.metrics($event);
+ Logger.metrics($manager);
+ Logger.metrics($clTimer);
+ //
+ // Check which event this is.
+ //
+ ControlLoopEventManager.NEW_EVENT_STATUS eventStatus = $manager.onNewEvent($event);
+ Logger.info("Event status is " + eventStatus);
+ //
+ // Check what kind of event this is
+ //
+ if (eventStatus == NEW_EVENT_STATUS.SUBSEQUENT_ONSET) {
+ //
+ // We don't care about subsequent onsets
+ //
+ Logger.info("Retracting Subsequent Onset " + $event);
+ retract($event);
+ return;
+ }
+ if (eventStatus == NEW_EVENT_STATUS.SYNTAX_ERROR) {
+ //
+ // Ignore any bad syntax events
+ //
+ Logger.info("Retracting Bad Syntax Event " + $event);
+ 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.info("Retracting Event " + $event);
+ retract($event);
+ }
+ Logger.info("Checking due to new event " + $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, close out the control loop for " + $event.requestID);
+ notification.from = "policy";
+ notification.policyName = drools.getRule().getName();
+ notification.policyScope = "${policyScope}";
+ notification.policyVersion = "${policyVersion}";
+ //
+ // In this case, we are done
+ //
+ Engine.deliver("UEB", "POLICY-CL-MGT", notification);
+ //
+ // Unlock the target
+ //
+ TargetLock lock = $manager.unlockCurrentOperation();
+ if (lock != null) {
+ System.out.println("retracting lock " + lock);
+ retract(lock);
+ }
+ //
+ // Retract everything from memory
+ //
+ System.out.println("retracting onset");
+ 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().abatement == true && notification.notification == ControlLoopNotificationType.FINAL_SUCCESS) {
+ Logger.info("Waiting for abatement.");
+ } else {
+ Logger.info("No abatement is promised to come, close out the control loop for " + $event.requestID);
+ notification.from = "policy";
+ notification.policyName = drools.getRule().getName();
+ notification.policyScope = "${policyScope}";
+ notification.policyVersion = "${policyVersion}";
+ //
+ // In this case, we are done
+ //
+ Engine.deliver("UEB", "POLICY-CL-MGT", notification);
+ //
+ // Unlock the target
+ //
+ TargetLock lock = $manager.unlockCurrentOperation();
+ if (lock != null) {
+ System.out.println("retracting lock " + lock);
+ retract(lock);
+ }
+ //
+ // Retract everything from memory
+ //
+ System.out.println("retracting onset");
+ 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 a new operation" + 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("manager returned lock " + result.getB());
+ //
+ // Insert into memory
+ //
+ insert(result.getB());
+ }
+ } else {
+ //
+ // Probably waiting for abatement
+ //
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ /*
+ VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event);
+ notification.notification = ControlLoopNotificationType.REJECTED;
+ notification.from = "policy";
+ notification.message = "Exception occurred " + e.getMessage();
+ notification.policyName = drools.getRule().getName();
+ notification.policyScope = "${policyScope}";
+ notification.policyVersion = "${policyVersion}";
+ //
+ //
+ //
+ Engine.deliver("UEB", "POLICY-CL-MGT", notification);
+ //
+ // 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
+ //
+ // Logging
+ //
+ Logger.info("------------------------------------------------------------------------------------------------");
+ Logger.metrics(Instant.now() + " " + drools.getRule().getName() + " " + drools.getRule().getPackage());
+ Logger.metrics($params);
+ Logger.metrics($manager);
+ Logger.metrics($operation);
+ //
+ // Need to ask for a Lock
+ //
+ LockResult<GuardResult, TargetLock> result = $manager.lockCurrentOperation();
+ if (result.getA().equals(GuardResult.LOCK_ACQUIRED)) {
+ Logger.info("Lock acquired: " + 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
+ //
+ // Logging
+ //
+ Logger.info("------------------------------------------------------------------------------------------------");
+ Logger.metrics(Instant.now() + " " + drools.getRule().getName() + " " + drools.getRule().getPackage());
+ Logger.metrics($params);
+ Logger.metrics($manager);
+ Logger.metrics($operation);
+ Logger.metrics($lock);
+
+
+ Object request = $operation.getOperationRequest();
+
+ if (request != null) {
+ Logger.info("Starting operation");
+ //
+ // 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}";
+ Engine.deliver("UEB", "POLICY-CL-MGT", notification);
+
+ switch ($operation.policy.actor){
+
+ case "APPC":
+
+ if (request instanceof Request) {
+ Engine.deliver("UEB", "APPC-CL", request);
+ }
+ case "SDNR":
+ default:
+ }
+
+
+ } else {
+ //
+ // What happens if its null?
+ //
+ }
+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
+ //
+ // Logging
+ //
+ Logger.info("------------------------------------------------------------------------------------------------");
+ Logger.metrics(Instant.now() + " " + drools.getRule().getName() + " " + drools.getRule().getPackage());
+ Logger.metrics($params);
+ Logger.metrics($manager);
+ Logger.metrics($operation);
+ Logger.metrics($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}";
+ Engine.deliver("UEB", "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 o the CallGuardTask() and set the first
+ // argument to null (instead of XacmlPdpEngine).
+ //
+ boolean guardEnabled = true;
+
+ if(guardEnabled){
+
+ Thread t = new Thread(new org.onap.policy.guard.CallGuardTask(
+ XacmlPdpEngine,
+ "",
+ drools.getWorkingMemory(),
+ $operation.policy.actor.toString(),
+ $operation.policy.recipe,
+ $manager.getTargetInstance($operation.policy),
+ //$event.target,
+ $event.requestID.toString()
+ ));
+ t.start();
+ }
+ else{
+ insert(new PolicyGuardResponse("Permit", $event.requestID, $operation.policy.recipe));
+ }
+
+
+
+
+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
+ //
+ // Logging
+ //
+ Logger.info("------------------------------------------------------------------------------------------------");
+ Logger.metrics(Instant.now() + " " + drools.getRule().getName() + " " + drools.getRule().getPackage());
+ Logger.metrics($params);
+ Logger.metrics($event);
+ Logger.metrics($operation);
+ Logger.metrics($lock);
+ Logger.metrics($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}";
+ Engine.deliver("UEB", "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
+ //
+ // Logging
+ //
+ Logger.info("------------------------------------------------------------------------------------------------");
+ Logger.metrics(Instant.now() + " " + drools.getRule().getName() + " " + drools.getRule().getPackage());
+ Logger.metrics($params);
+ Logger.metrics($event);
+ Logger.metrics($manager);
+ Logger.metrics($operation);
+ Logger.metrics($opTimer);
+ Logger.metrics($lock);
+ Logger.metrics($response);
+ //
+ // Get the result of the operation
+ //
+ PolicyResult policyResult = $operation.onResponse($response);
+ if (policyResult != null) {
+ Logger.info("operation finished with result: " + 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
+ //
+ Engine.deliver("UEB", "POLICY-CL-MGT", notification);
+ } else {
+ notification.notification = ControlLoopNotificationType.OPERATION_FAILURE;
+ //
+ // Let interested parties know
+ //
+ Engine.deliver("UEB", "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
+ //
+ // Logging
+ //
+ Logger.info("------------------------------------------------------------------------------------------------");
+ Logger.metrics(Instant.now() + " " + drools.getRule().getName() + " " + drools.getRule().getPackage());
+ Logger.metrics($params);
+ //
+ // Retract it
+ //
+ 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
+ //
+ // Logging
+ //
+ Logger.info("------------------------------------------------------------------------------------------------");
+ Logger.metrics(Instant.now() + " " + drools.getRule().getName() + " " + drools.getRule().getPackage());
+ Logger.metrics($params);
+ Logger.metrics($manager);
+ Logger.metrics($operation);
+ Logger.metrics($opTimer);
+ Logger.metrics($lock);
+ //
+ // 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
+ //
+ Engine.deliver("UEB", "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
+ //
+ // Logging
+ //
+ Logger.info("------------------------------------------------------------------------------------------------");
+ Logger.metrics(Instant.now() + " " + drools.getRule().getName() + " " + drools.getRule().getPackage());
+ Logger.metrics($params);
+ Logger.metrics($manager);
+ Logger.metrics($clTimer);
+ if ($operations == null) {
+ Logger.info("no operations found");
+ } else {
+ Logger.info("found " + $operations.size() + " operations");
+ }
+ //
+ // 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
+ //
+ Engine.deliver("UEB", "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/template.demo/src/main/resources/blacklist_template.xml b/controlloop/templates/template.demo/src/main/resources/blacklist_template.xml
new file mode 100644
index 000000000..560fa57f1
--- /dev/null
+++ b/controlloop/templates/template.demo/src/main/resources/blacklist_template.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<Policy xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" PolicyId="urn:com:att:xacml:policy:id:25e12b06-11d5-4895-b2a2-6f6c594de069" Version="1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:permit-unless-deny">
+ <Description>Policy for frequency limiter.</Description>
+ <Target>
+ <AnyOf>
+ <AllOf>
+ <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">${actor}</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="urn:oasis:names:tc:xacml:1.0:actor:actor-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+ </Match>
+ <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">${recipe}</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" AttributeId="urn:oasis:names:tc:xacml:1.0:operation:operation-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+ </Match>
+ </AllOf>
+ </AnyOf>
+ </Target>
+ <Rule RuleId="urn:com:att:xacml:rule:id:e1e8c5c0-e2ba-47d5-9289-6c015305ed21" Effect="Deny">
+ <Description>DENY - only if target is in black list and guard is active.</Description>
+ <Condition>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
+ <VariableReference VariableId="isGuardActive"/>
+ <VariableReference VariableId="isInBlackList"/>
+ </Apply>
+ </Condition>
+ </Rule>
+ <VariableDefinition VariableId="isInBlackList">
+ <Apply FunctionId="urn:oasis:names:tc:xacml:3.0:function:any-of">
+ <Function FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal"/>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="urn:oasis:names:tc:xacml:1.0:target:target-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+ </Apply>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-bag">
+ ${blackListElement}
+ <!-- <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">vserver.vserver-name</AttributeValue>-->
+ </Apply>
+ </Apply>
+ </VariableDefinition>
+ <VariableDefinition VariableId="isGuardActive">
+ <Apply FunctionId="urn:oasis:names:tc:xacml:2.0:function:time-in-range">
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:time-one-and-only">
+ <AttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:environment:current-time" DataType="http://www.w3.org/2001/XMLSchema#time" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:environment" MustBePresent="false"/>
+ </Apply>
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#time">${guardActiveStart}</AttributeValue>
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#time">${guardActiveEnd}</AttributeValue>
+ </Apply>
+ </VariableDefinition>
+</Policy>
diff --git a/controlloop/templates/template.demo/src/main/resources/frequency_limiter_template.xml b/controlloop/templates/template.demo/src/main/resources/frequency_limiter_template.xml
new file mode 100644
index 000000000..221fd6ddf
--- /dev/null
+++ b/controlloop/templates/template.demo/src/main/resources/frequency_limiter_template.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<Policy xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" PolicyId="urn:com:att:xacml:policy:id:25e12b06-11d5-4895-b2a2-6f6c594de069" Version="1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:permit-unless-deny">
+ <Description>Policy for frequency limiter.</Description>
+ <Target>
+ <AnyOf>
+ <AllOf>
+ <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">${actor}</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="urn:oasis:names:tc:xacml:1.0:actor:actor-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+ </Match>
+ <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">${recipe}</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" AttributeId="urn:oasis:names:tc:xacml:1.0:operation:operation-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+ </Match>
+ </AllOf>
+ </AnyOf>
+ </Target>
+ <Rule RuleId="urn:com:att:xacml:rule:id:e1e8c5c0-e2ba-47d5-9289-6c015305ed21" Effect="Deny">
+ <Description>DENY - only if number of operations performed in the past is larger than the limit and the Guard is active.</Description>
+ <Condition>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
+ <VariableReference VariableId="isGuardActive"/>
+ <VariableReference VariableId="isHistoryGreaterThanLimit"/>
+ </Apply>
+ </Condition>
+ </Rule>
+ <VariableDefinition VariableId="isGuardActive">
+ <Apply FunctionId="urn:oasis:names:tc:xacml:2.0:function:time-in-range">
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:time-one-and-only">
+ <AttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:environment:current-time" DataType="http://www.w3.org/2001/XMLSchema#time" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:environment" MustBePresent="false"/>
+ </Apply>
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#time">${guardActiveStart}</AttributeValue>
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#time">${guardActiveEnd}</AttributeValue>
+ </Apply>
+ </VariableDefinition>
+ <VariableDefinition VariableId="isHistoryGreaterThanLimit">
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal">
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="com:att:research:xacml:test:sql:resource:operations:count" DataType="http://www.w3.org/2001/XMLSchema#integer" Issuer="com:att:research:xacml:guard:historydb:tw:${twValue}:${twUnits}" MustBePresent="false"/>
+ </Apply>
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#integer">${limit}</AttributeValue>
+ </Apply>
+ </VariableDefinition>
+</Policy>
diff --git a/controlloop/templates/template.demo/src/main/resources/frequency_limiter_template_old.xml b/controlloop/templates/template.demo/src/main/resources/frequency_limiter_template_old.xml
new file mode 100644
index 000000000..45cc5d829
--- /dev/null
+++ b/controlloop/templates/template.demo/src/main/resources/frequency_limiter_template_old.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<Policy xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" PolicyId="urn:com:att:xacml:policy:id:25e12b06-11d5-4895-b2a2-6f6c594de069" Version="1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:permit-unless-deny">
+ <Description>Policy for frequency limiter.</Description>
+ <Target>
+ <AnyOf>
+ <AllOf>
+ <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">${actor}</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="urn:oasis:names:tc:xacml:1.0:actor:actor-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+ </Match>
+ <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">${recipe}</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" AttributeId="urn:oasis:names:tc:xacml:1.0:operation:operation-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+ </Match>
+ </AllOf>
+ </AnyOf>
+ </Target>
+ <Rule RuleId="urn:com:att:xacml:rule:id:e1e8c5c0-e2ba-47d5-9289-6c015305ed21" Effect="Deny">
+ <Description>DENY - only if number of operations performed in the past is larger than the limit and the Guard is active.</Description>
+ <Condition>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
+ <VariableReference VariableId="isGuardActive"/>
+ <VariableReference VariableId="isHistoryGreaterThanLimit"/>
+ </Apply>
+ </Condition>
+ </Rule>
+ <VariableDefinition VariableId="isGuardActive">
+ <Apply FunctionId="urn:oasis:names:tc:xacml:2.0:function:time-in-range">
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:time-one-and-only">
+ <AttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:environment:current-time" DataType="http://www.w3.org/2001/XMLSchema#time" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:environment" MustBePresent="false"/>
+ </Apply>
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#time">${guardActiveStart}</AttributeValue>
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#time">${guardActiveEnd}</AttributeValue>
+ </Apply>
+ </VariableDefinition>
+ <VariableDefinition VariableId="isHistoryGreaterThanLimit">
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal">
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="com:att:research:xacml:test:sql:resource:operations:count" DataType="http://www.w3.org/2001/XMLSchema#integer" Issuer="com:att:research:xacml:test:sql:${timeWindow}" MustBePresent="false"/>
+ </Apply>
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#integer">${limit}</AttributeValue>
+ </Apply>
+ </VariableDefinition>
+</Policy>
diff --git a/controlloop/templates/template.demo/src/main/resources/old/ControlLoop_Template_1610_v1.1_xacml_guard.drl b/controlloop/templates/template.demo/src/main/resources/old/ControlLoop_Template_1610_v1.1_xacml_guard.drl
new file mode 100644
index 000000000..a743502ce
--- /dev/null
+++ b/controlloop/templates/template.demo/src/main/resources/old/ControlLoop_Template_1610_v1.1_xacml_guard.drl
@@ -0,0 +1,867 @@
+/*
+ * AT&T - PROPRIETARY
+ * THIS FILE CONTAINS PROPRIETARY INFORMATION OF
+ * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN
+ * ACCORDANCE WITH APPLICABLE AGREEMENTS.
+ *
+ * Copyright (c) 2016 AT&T Knowledge Ventures
+ * Unpublished and Not for Publication
+ * All Rights Reserved
+ */
+package com.att.ecomp.policy.controlloop;
+
+import com.att.ecomp.policy.controlloop.ATTControlLoopEvent;
+import org.openecomp.policy.controlloop.VirtualControlLoopEvent;
+import org.openecomp.policy.controlloop.VirtualControlLoopNotification;
+import org.openecomp.policy.controlloop.ControlLoopEventStatus;
+import com.att.ecomp.policy.controlloop.ATTControlLoopNotification;
+import org.openecomp.policy.controlloop.ControlLoopNotificationType;
+import com.att.ecomp.policy.controlloop.ControlLoopLogger;
+import com.att.ecomp.policy.controlloop.policy.PolicyResult;
+import com.att.ecomp.policy.controlloop.eventmanager.ControlLoopEventManager;
+import com.att.ecomp.policy.controlloop.eventmanager.ControlLoopEventManager.NEW_EVENT_STATUS;
+import com.att.ecomp.policy.controlloop.eventmanager.ControlLoopOperationManager;
+import org.openecomp.policy.appc.Request;
+import org.openecomp.policy.appc.Response;
+import org.openecomp.policy.appc.CommonHeader;
+import com.att.ecomp.policy.guard.PolicyGuard;
+import com.att.ecomp.policy.guard.PolicyGuard.LockResult;
+import com.att.ecomp.policy.guard.TargetLock;
+import com.att.ecomp.policy.guard.GuardResult;
+import com.att.ecomp.policy.guard.PolicyGuardRequest;
+import com.att.ecomp.policy.guard.PolicyGuardResponse;
+import com.att.ecomp.policy.guard.PolicyGuardXacmlRequestAttributes;
+import com.att.research.xacml.api.pdp.PDPEngine;
+import com.att.research.xacml.std.annotations.RequestParser;
+import com.att.ecomp.policy.guard.PolicyGuardXacmlHelper;
+
+//
+// REPLACE THESE WITH PRODUCTION VERSIONS
+//
+import com.att.ecomp.policy.controlloop.ControlLoopLogger;
+import com.att.ecomp.policy.drools.PolicyEngine;
+
+global ControlLoopLogger Logger;
+global PolicyEngine Engine;
+global PDPEngine XacmlPdpEngine;
+
+import java.time.Instant;
+import java.util.LinkedList;
+import java.util.Iterator;
+
+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
+ //
+ // Logging
+ //
+ Logger.info("------------------------------------------------------------------------------------------------");
+ Logger.metrics(Instant.now() + " " + drools.getRule().getName() + " " + drools.getRule().getPackage());
+ Params params = new Params();
+ params.setClosedLoopControlName("${closedLoopControlName}");
+ params.setControlLoopYaml("${controlLoopYaml}");
+ insert(params);
+ Logger.metrics("Inserted " + params);
+ Logger.info("------------------------------------------------------------------------------------------------");
+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 : ATTControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName() )
+ not ( ControlLoopEventManager( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID ) )
+ then
+ try {
+ //
+ // Logging
+ //
+ Logger.info("------------------------------------------------------------------------------------------------");
+ Logger.metrics(Instant.now() + " " + drools.getRule().getName() + " " + drools.getRule().getPackage());
+ //
+ // 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) {
+ ATTControlLoopNotification notification = new ATTControlLoopNotification($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
+ //
+ Engine.deliver("UEB", "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
+ //
+ Engine.deliver("UEB", "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
+ //
+ Engine.deliver("UEB", "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) {
+ e.printStackTrace();
+ ATTControlLoopNotification notification = new ATTControlLoopNotification($event);
+ notification.notification = ControlLoopNotificationType.REJECTED;
+ notification.message = "Exception occurred " + e.getMessage();
+ notification.policyName = drools.getRule().getName();
+ notification.policyScope = "${policyScope}";
+ notification.policyVersion = "${policyVersion}";
+ //
+ //
+ //
+ Engine.deliver("UEB", "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 : ATTControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName() )
+ $manager : ControlLoopEventManager( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID )
+ $clTimer : ControlLoopTimer ( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID.toString() )
+ then
+ //
+ // Logging
+ //
+ Logger.info("------------------------------------------------------------------------------------------------");
+ Logger.metrics(Instant.now() + " " + drools.getRule().getName() + " " + drools.getRule().getPackage());
+ Logger.metrics($params);
+ Logger.metrics($event);
+ Logger.metrics($manager);
+ Logger.metrics($clTimer);
+ //
+ // Check which event this is.
+ //
+ ControlLoopEventManager.NEW_EVENT_STATUS eventStatus = $manager.onNewEvent($event);
+ Logger.info("Event status is " + eventStatus);
+ //
+ // Check what kind of event this is
+ //
+ if (eventStatus == NEW_EVENT_STATUS.SUBSEQUENT_ONSET) {
+ //
+ // We don't care about subsequent onsets
+ //
+ Logger.info("Retracting Subsequent Onset " + $event);
+ retract($event);
+ return;
+ }
+ if (eventStatus == NEW_EVENT_STATUS.SYNTAX_ERROR) {
+ //
+ // Ignore any bad syntax events
+ //
+ Logger.info("Retracting Bad Syntax Event " + $event);
+ 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.info("Retracting Event " + $event);
+ retract($event);
+ }
+ Logger.info("Checking due to new event " + $event.triggerID);
+ //
+ // Now start seeing if we need to process this event
+ //
+ try {
+ //
+ // Check if this is a Final Event
+ //
+ ATTControlLoopNotification notification = $manager.isControlLoopFinal();
+
+
+ if (notification != null) {
+ //
+ // Its final, but are we waiting for abatement?
+ //
+ if ($manager.getNumAbatements() > 0) {
+ Logger.info("Abatement received, close out the control loop for " + $event.requestID);
+ notification.from = "policy";
+ notification.policyName = drools.getRule().getName();
+ notification.policyScope = "${policyScope}";
+ notification.policyVersion = "${policyVersion}";
+ //
+ // In this case, we are done
+ //
+ Engine.deliver("UEB", "POLICY-CL-MGT", notification);
+ //
+ // Unlock the target
+ //
+ TargetLock lock = $manager.unlockCurrentOperation();
+ if (lock != null) {
+ System.out.println("retracting lock " + lock);
+ retract(lock);
+ }
+ //
+ // Retract everything from memory
+ //
+ System.out.println("retracting onset");
+ 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().abatement == true && notification.notification == ControlLoopNotificationType.FINAL_SUCCESS) {
+ Logger.info("Waiting for abatement.");
+ } else {
+ Logger.info("No abatement is promised to come, close out the control loop for " + $event.requestID);
+ notification.from = "policy";
+ notification.policyName = drools.getRule().getName();
+ notification.policyScope = "${policyScope}";
+ notification.policyVersion = "${policyVersion}";
+ //
+ // In this case, we are done
+ //
+ Engine.deliver("UEB", "POLICY-CL-MGT", notification);
+ //
+ // Unlock the target
+ //
+ TargetLock lock = $manager.unlockCurrentOperation();
+ if (lock != null) {
+ System.out.println("retracting lock " + lock);
+ retract(lock);
+ }
+ //
+ // Retract everything from memory
+ //
+ System.out.println("retracting onset");
+ 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 a new operation" + 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("manager returned lock " + result.getB());
+ //
+ // Insert into memory
+ //
+ insert(result.getB());
+ }
+ } else {
+ //
+ // Probably waiting for abatement
+ //
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ /*
+ ATTControlLoopNotification notification = new ATTControlLoopNotification($event);
+ notification.notification = ControlLoopNotificationType.REJECTED;
+ notification.from = "policy";
+ notification.message = "Exception occurred " + e.getMessage();
+ notification.policyName = drools.getRule().getName();
+ notification.policyScope = "${policyScope}";
+ notification.policyVersion = "${policyVersion}";
+ //
+ //
+ //
+ Engine.deliver("UEB", "POLICY-CL-MGT", notification);
+ //
+ // 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 : ATTControlLoopEvent( 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
+ //
+ // Logging
+ //
+ Logger.info("------------------------------------------------------------------------------------------------");
+ Logger.metrics(Instant.now() + " " + drools.getRule().getName() + " " + drools.getRule().getPackage());
+ Logger.metrics($params);
+ Logger.metrics($manager);
+ Logger.metrics($operation);
+ //
+ // Need to ask for a Lock
+ //
+ LockResult<GuardResult, TargetLock> result = $manager.lockCurrentOperation();
+ if (result.getA().equals(GuardResult.LOCK_ACQUIRED)) {
+ Logger.info("Lock acquired: " + result.getB());
+ //
+ // Insert into memory
+ //
+ insert(result.getB());
+ }
+end
+
+/*
+*
+*
+*
+*/
+rule "${policyName}.EVENT.MANAGER.OPERATION.LOCKED.GUARD_PERMITTED"
+ when
+ $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" )
+ $event : ATTControlLoopEvent( 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
+ //
+ // Logging
+ //
+ Logger.info("------------------------------------------------------------------------------------------------");
+ Logger.metrics(Instant.now() + " " + drools.getRule().getName() + " " + drools.getRule().getPackage());
+ Logger.metrics($params);
+ Logger.metrics($manager);
+ Logger.metrics($operation);
+ Logger.metrics($lock);
+ //
+ // Start the Operation
+ //
+ //Object request = $operation.startOperation($event);
+ //$operation.startOperation($event);
+ Object request = $operation.getOperationRequest();
+
+ if (request != null) {
+ Logger.info("Starting operation");
+ //
+ // Tell interested parties we are performing this Operation
+ //
+ ATTControlLoopNotification notification = new ATTControlLoopNotification($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}";
+ Engine.deliver("UEB", "POLICY-CL-MGT", notification);
+ //
+ // Send the APPC request
+ //
+ if (request instanceof Request) {
+ Engine.deliver("UEB", "APPC-CL", request);
+ }
+ //
+ // TODO: send different types of requests
+ //
+
+ } else {
+ //
+ // What happens if its null?
+ //
+ }
+end
+
+
+/*
+*
+*
+*
+*/
+rule "${policyName}.EVENT.MANAGER.OPERATION.LOCKED.GUARD_NOT_YET_QUERIED"
+ when
+ $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" )
+ $event : ATTControlLoopEvent( 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
+ //
+ // Logging
+ //
+ Logger.info("------------------------------------------------------------------------------------------------");
+ Logger.metrics(Instant.now() + " " + drools.getRule().getName() + " " + drools.getRule().getPackage());
+ Logger.metrics($params);
+ Logger.metrics($manager);
+ Logger.metrics($operation);
+ Logger.metrics($lock);
+
+ $operation.startOperation($event);
+ //
+ // Now send Guard Request to XACML Guard
+ //
+ PolicyGuardXacmlRequestAttributes xacmlReq = new PolicyGuardXacmlRequestAttributes($operation.policy.actor.toString(), $operation.policy.recipe, $event.target, $event.requestID.toString());
+ //Engine.deliver("UEB", "GUARD-CL", xacmlReq/*request*/);
+ System.out.println("\n********** XACML REQUEST START ********");
+ System.out.println(RequestParser.parseRequest(xacmlReq));
+ System.out.println("********** XACML REQUEST END ********\n");
+
+ com.att.research.xacml.api.Response xacmlResponse = PolicyGuardXacmlHelper.callPDP(XacmlPdpEngine, "", (com.att.research.xacml.api.Request) RequestParser.parseRequest(xacmlReq), false);
+
+ System.out.println("\n********** XACML RESPONSE 1 START ********");
+ System.out.println(xacmlResponse);
+ System.out.println("********** XACML RESPONSE 1 END ********\n");
+
+ PolicyGuardResponse guardResponse = PolicyGuardXacmlHelper.ParseXacmlPdpResponse(xacmlResponse);
+ System.out.println("\n\n============ Guard inserted with decision "+ guardResponse.result + " !!! ===========\n\n");
+
+
+ insert(guardResponse);
+
+end
+
+
+
+rule "${policyName}.GUARD.RESPONSE"
+ when
+ $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" )
+ $event : ATTControlLoopEvent( 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
+ //
+ // Logging
+ //
+ Logger.info("------------------------------------------------------------------------------------------------");
+ Logger.metrics(Instant.now() + " " + drools.getRule().getName() + " " + drools.getRule().getPackage());
+ Logger.metrics($params);
+ Logger.metrics($event);
+ Logger.metrics($operation);
+ Logger.metrics($lock);
+ Logger.metrics($guardResponse);
+
+
+ //we will permit the operation if there was no Guard for it
+ if($guardResponse.result == "Indeterminate"){
+ $guardResponse.result = "Permit";
+ }
+
+ ATTControlLoopNotification notification = new ATTControlLoopNotification($event);
+ notification.notification = ControlLoopNotificationType.OPERATION;
+ notification.message = $operation.getOperationMessage($guardResponse.result);//"Guard result: " + $guardResponse.result;
+ notification.history = $operation.getHistory();
+ notification.from = "policy";
+ notification.policyName = drools.getRule().getName();
+ notification.policyScope = "${policyScope}";
+ notification.policyVersion = "${policyVersion}";
+ Engine.deliver("UEB", "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 : ATTControlLoopEvent( 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
+ //
+ // Logging
+ //
+ Logger.info("------------------------------------------------------------------------------------------------");
+ Logger.metrics(Instant.now() + " " + drools.getRule().getName() + " " + drools.getRule().getPackage());
+ Logger.metrics($params);
+ Logger.metrics($event);
+ Logger.metrics($manager);
+ Logger.metrics($operation);
+ Logger.metrics($opTimer);
+ Logger.metrics($lock);
+ Logger.metrics($response);
+ //
+ // Get the result of the operation
+ //
+ PolicyResult policyResult = $operation.onResponse($response);
+ if (policyResult != null) {
+ Logger.info("operation finished with result: " + policyResult);
+ //
+ // This Operation has completed, construct a notification showing our results
+ //
+ ATTControlLoopNotification notification = new ATTControlLoopNotification($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
+ //
+ Engine.deliver("UEB", "POLICY-CL-MGT", notification);
+ } else {
+ notification.notification = ControlLoopNotificationType.OPERATION_FAILURE;
+ //
+ // Let interested parties know
+ //
+ Engine.deliver("UEB", "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 ( ATTControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName(), requestID == $id, closedLoopEventStatus == ControlLoopEventStatus.ONSET ) )
+ then
+ //
+ // Logging
+ //
+ Logger.info("------------------------------------------------------------------------------------------------");
+ Logger.metrics(Instant.now() + " " + drools.getRule().getName() + " " + drools.getRule().getPackage());
+ Logger.metrics($params);
+ //
+ // Retract it
+ //
+ 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 : ATTControlLoopEvent( 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
+ //
+ // Logging
+ //
+ Logger.info("------------------------------------------------------------------------------------------------");
+ Logger.metrics(Instant.now() + " " + drools.getRule().getName() + " " + drools.getRule().getPackage());
+ Logger.metrics($params);
+ Logger.metrics($manager);
+ Logger.metrics($operation);
+ Logger.metrics($opTimer);
+ Logger.metrics($lock);
+ //
+ // Tell it its timed out
+ //
+ $operation.setOperationHasTimedOut();
+ //
+ // Create a notification for it
+ //
+ ATTControlLoopNotification notification = new ATTControlLoopNotification($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
+ //
+ Engine.deliver("UEB", "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 : ATTControlLoopEvent( 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
+ //
+ // Logging
+ //
+ Logger.info("------------------------------------------------------------------------------------------------");
+ Logger.metrics(Instant.now() + " " + drools.getRule().getName() + " " + drools.getRule().getPackage());
+ Logger.metrics($params);
+ Logger.metrics($manager);
+ Logger.metrics($clTimer);
+ if ($operations == null) {
+ Logger.info("no operations found");
+ } else {
+ Logger.info("found " + $operations.size() + " operations");
+ }
+ //
+ // 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
+ //
+ Engine.deliver("UEB", "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/template.demo/src/main/resources/old/ControlLoop_Template_1707_xacml_guard_enodeb.drl b/controlloop/templates/template.demo/src/main/resources/old/ControlLoop_Template_1707_xacml_guard_enodeb.drl
new file mode 100644
index 000000000..b4f160951
--- /dev/null
+++ b/controlloop/templates/template.demo/src/main/resources/old/ControlLoop_Template_1707_xacml_guard_enodeb.drl
@@ -0,0 +1,952 @@
+/*
+ * AT&T - PROPRIETARY
+ * THIS FILE CONTAINS PROPRIETARY INFORMATION OF
+ * AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN
+ * ACCORDANCE WITH APPLICABLE AGREEMENTS.
+ *
+ * Copyright (c) 2016 AT&T Knowledge Ventures
+ * Unpublished and Not for Publication
+ * All Rights Reserved
+ */
+package com.att.ecomp.policy.controlloop;
+
+import com.att.ecomp.policy.controlloop.ATTControlLoopEvent;
+import org.openecomp.policy.controlloop.VirtualControlLoopEvent;
+import org.openecomp.policy.controlloop.VirtualControlLoopNotification;
+import org.openecomp.policy.controlloop.ControlLoopEventStatus;
+import com.att.ecomp.policy.controlloop.ATTControlLoopNotification;
+import org.openecomp.policy.controlloop.ControlLoopNotificationType;
+import com.att.ecomp.policy.controlloop.ControlLoopLogger;
+import com.att.ecomp.policy.controlloop.policy.PolicyResult;
+import com.att.ecomp.policy.controlloop.eventmanager.ControlLoopEventManager;
+import com.att.ecomp.policy.controlloop.eventmanager.ControlLoopEventManager.NEW_EVENT_STATUS;
+import com.att.ecomp.policy.controlloop.eventmanager.ControlLoopOperationManager;
+import org.openecomp.policy.appc.Request;
+import org.openecomp.policy.appc.Response;
+import org.openecomp.policy.appc.CommonHeader;
+import com.att.ecomp.policy.guard.PolicyGuard;
+import com.att.ecomp.policy.guard.PolicyGuard.LockResult;
+import com.att.ecomp.policy.guard.TargetLock;
+import com.att.ecomp.policy.guard.GuardResult;
+import com.att.ecomp.policy.guard.PolicyGuardRequest;
+import com.att.ecomp.policy.guard.PolicyGuardResponse;
+import com.att.ecomp.policy.guard.PolicyGuardXacmlRequestAttributes;
+import com.att.research.xacml.api.pdp.PDPEngine;
+import com.att.research.xacml.std.annotations.RequestParser;
+import com.att.ecomp.policy.guard.PolicyGuardXacmlHelper;
+import com.att.ecomp.policy.controlloop.policy.ControlLoopPolicy;
+import com.att.ecomp.policy.controlloop.policy.Policy;
+import java.net.URLDecoder;
+import org.eclipse.persistence.exceptions.DatabaseException;
+
+//
+// REPLACE THESE WITH PRODUCTION VERSIONS
+//
+import com.att.ecomp.policy.controlloop.ControlLoopLogger;
+import com.att.ecomp.policy.drools.PolicyEngine;
+import org.yaml.snakeyaml.Yaml;
+import org.yaml.snakeyaml.constructor.Constructor;
+
+global ControlLoopLogger Logger;
+global PolicyEngine Engine;
+global PDPEngine XacmlPdpEngine;
+
+import java.time.Instant;
+import java.util.LinkedList;
+import java.util.Iterator;
+
+declare Params
+ closedLoopControlName : String
+ controlLoopYaml : String
+end
+
+declare EnbParams
+ enbOperationsPeriodicTimer : 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
+ //
+ // Logging
+ //
+ Logger.info("------------------------------------------------------------------------------------------------");
+ Logger.metrics(Instant.now() + " " + drools.getRule().getName() + " " + drools.getRule().getPackage());
+ Params params = new Params();
+ params.setClosedLoopControlName("${closedLoopControlName}");
+ params.setControlLoopYaml("${controlLoopYaml}");
+ insert(params);
+ Logger.metrics("Inserted " + params);
+ Logger.info("------------------------------------------------------------------------------------------------");
+ EnbParams enbParams = new EnbParams();
+
+ //
+ //Fetching the eNodeB timer from the Yaml
+ //
+ Yaml yaml = new Yaml(new Constructor(ControlLoopPolicy.class));
+ Object obj = yaml.load(URLDecoder.decode(params.getControlLoopYaml(), "UTF-8"));
+
+ enbParams.setEnbOperationsPeriodicTimer("0s");
+ for(Policy policy : ((ControlLoopPolicy)obj).policies){
+ if(policy.actor.equals("APPC")){
+ if(policy.payload != null){
+ if(policy.payload.containsKey("enbOperationPeriodicTimer")){
+ enbParams.setEnbOperationsPeriodicTimer(policy.payload.get("enbOperationPeriodicTimer"));
+ }
+ }
+ break;
+ }
+ }
+ insert(enbParams);
+ System.out.println("################ got timer: " + enbParams.getEnbOperationsPeriodicTimer());
+
+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 : ATTControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName() )
+ not ( ControlLoopEventManager( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID ) )
+ then
+ try {
+ //
+ // Logging
+ //
+ Logger.info("------------------------------------------------------------------------------------------------");
+ Logger.metrics(Instant.now() + " " + drools.getRule().getName() + " " + drools.getRule().getPackage());
+ //
+ // 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) {
+ ATTControlLoopNotification notification = new ATTControlLoopNotification($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
+ //
+ Engine.deliver("UEB", "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
+ //
+ Engine.deliver("UEB", "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
+ //
+ Engine.deliver("UEB", "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) {
+ e.printStackTrace();
+ ATTControlLoopNotification notification = new ATTControlLoopNotification($event);
+ notification.notification = ControlLoopNotificationType.REJECTED;
+ notification.message = "Exception occurred " + e.getMessage();
+ notification.policyName = drools.getRule().getName();
+ notification.policyScope = "${policyScope}";
+ notification.policyVersion = "${policyVersion}";
+ //
+ //
+ //
+ Engine.deliver("UEB", "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 : ATTControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName() )
+ $manager : ControlLoopEventManager( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID )
+ $clTimer : ControlLoopTimer ( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID.toString() )
+ then
+ //
+ // Logging
+ //
+ Logger.info("------------------------------------------------------------------------------------------------");
+ Logger.metrics(Instant.now() + " " + drools.getRule().getName() + " " + drools.getRule().getPackage());
+ Logger.metrics($params);
+ Logger.metrics($event);
+ Logger.metrics($manager);
+ Logger.metrics($clTimer);
+ //
+ // Check which event this is.
+ //
+ ControlLoopEventManager.NEW_EVENT_STATUS eventStatus = $manager.onNewEvent($event);
+ Logger.info("Event status is " + eventStatus);
+ //
+ // Check what kind of event this is
+ //
+ if (eventStatus == NEW_EVENT_STATUS.SUBSEQUENT_ONSET) {
+ //
+ // We don't care about subsequent onsets
+ //
+ Logger.info("Retracting Subsequent Onset " + $event);
+ retract($event);
+ return;
+ }
+ if (eventStatus == NEW_EVENT_STATUS.SYNTAX_ERROR) {
+ //
+ // Ignore any bad syntax events
+ //
+ Logger.info("Retracting Bad Syntax Event " + $event);
+ 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.info("Retracting Event " + $event);
+ retract($event);
+ }
+ Logger.info("Checking due to new event " + $event.triggerID);
+ //
+ // Now start seeing if we need to process this event
+ //
+ try {
+ //
+ // Check if this is a Final Event
+ //
+ ATTControlLoopNotification notification = $manager.isControlLoopFinal();
+
+
+ if (notification != null) {
+ //
+ // Its final, but are we waiting for abatement?
+ //
+ if ($manager.getNumAbatements() > 0) {
+ Logger.info("Abatement received, close out the control loop for " + $event.requestID);
+ notification.from = "policy";
+ notification.policyName = drools.getRule().getName();
+ notification.policyScope = "${policyScope}";
+ notification.policyVersion = "${policyVersion}";
+ //
+ // In this case, we are done
+ //
+ Engine.deliver("UEB", "POLICY-CL-MGT", notification);
+ //
+ // Unlock the target
+ //
+ TargetLock lock = $manager.unlockCurrentOperation();
+ if (lock != null) {
+ System.out.println("retracting lock " + lock);
+ retract(lock);
+ }
+ //
+ // Retract everything from memory
+ //
+ System.out.println("retracting onset");
+ 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().abatement == true && notification.notification == ControlLoopNotificationType.FINAL_SUCCESS) {
+ Logger.info("Waiting for abatement.");
+ } else {
+ Logger.info("No abatement is promised to come, close out the control loop for " + $event.requestID);
+ notification.from = "policy";
+ notification.policyName = drools.getRule().getName();
+ notification.policyScope = "${policyScope}";
+ notification.policyVersion = "${policyVersion}";
+ //
+ // In this case, we are done
+ //
+ Engine.deliver("UEB", "POLICY-CL-MGT", notification);
+ //
+ // Unlock the target
+ //
+ TargetLock lock = $manager.unlockCurrentOperation();
+ if (lock != null) {
+ System.out.println("retracting lock " + lock);
+ retract(lock);
+ }
+ //
+ // Retract everything from memory
+ //
+ System.out.println("retracting onset");
+ 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 a new operation" + 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("manager returned lock " + result.getB());
+ //
+ // Insert into memory
+ //
+ insert(result.getB());
+ }
+ } else {
+ //
+ // Probably waiting for abatement
+ //
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ /*
+ ATTControlLoopNotification notification = new ATTControlLoopNotification($event);
+ notification.notification = ControlLoopNotificationType.REJECTED;
+ notification.from = "policy";
+ notification.message = "Exception occurred " + e.getMessage();
+ notification.policyName = drools.getRule().getName();
+ notification.policyScope = "${policyScope}";
+ notification.policyVersion = "${policyVersion}";
+ //
+ //
+ //
+ Engine.deliver("UEB", "POLICY-CL-MGT", notification);
+ //
+ // TODO should we abort if we get an exception?
+ //
+ */
+ }
+
+end
+
+/*
+*
+*
+*
+*/
+rule "${policyName}.PERIODIC_CHECK_OF_PENDING_ENB_OPERATIONS"
+ timer (expr: "0s", $t)
+ when
+ $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" )
+ $enbParams : EnbParams($t : getEnbOperationsPeriodicTimer())
+ $event : ATTControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName() )
+ $operations : LinkedList(size() > 0)
+ from collect( ControlLoopOperationManager( onset.closedLoopControlName == $event.closedLoopControlName) )
+
+ then
+ System.out.println(drools.getRule().getName() + " ********** operations size: " + $operations.size());
+ //System.out.println(drools.getRule().getName());
+ //The limt of 5 should also be defined in Yaml.
+end
+
+
+/*
+*
+*
+*
+*/
+rule "${policyName}.EVENT.MANAGER.OPERATION.NOT_LOCKED.TIMEOUT"
+ timer (int: 5s 5s)
+ when
+ $params : Params( getClosedLoopControlName() == "${closedLoopControlName}" )
+ $event : ATTControlLoopEvent( 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
+ //
+ // Logging
+ //
+ Logger.info("------------------------------------------------------------------------------------------------");
+ Logger.metrics(Instant.now() + " " + drools.getRule().getName() + " " + drools.getRule().getPackage());
+ Logger.metrics($params);
+ Logger.metrics($manager);
+ Logger.metrics($operation);
+ //
+ // Need to ask for a Lock
+ //
+ LockResult<GuardResult, TargetLock> result = $manager.lockCurrentOperation();
+ if (result.getA().equals(GuardResult.LOCK_ACQUIRED)) {
+ Logger.info("Lock acquired: " + 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 : ATTControlLoopEvent( 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
+ //
+ // Logging
+ //
+ Logger.info("------------------------------------------------------------------------------------------------");
+ Logger.metrics(Instant.now() + " " + drools.getRule().getName() + " " + drools.getRule().getPackage());
+ Logger.metrics($params);
+ Logger.metrics($manager);
+ Logger.metrics($operation);
+ Logger.metrics($lock);
+
+
+ Object request = $operation.getOperationRequest();
+
+ if (request != null) {
+ Logger.info("Starting operation");
+ //
+ // Tell interested parties we are performing this Operation
+ //
+ ATTControlLoopNotification notification = new ATTControlLoopNotification($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}";
+ Engine.deliver("UEB", "POLICY-CL-MGT", notification);
+
+ switch ($operation.policy.actor){
+
+ case "APPC":
+
+ if (request instanceof Request) {
+ Engine.deliver("UEB", "APPC-CL", request);
+ }
+ case "SDNR":
+ default:
+ }
+
+
+ } else {
+ //
+ // What happens if its null?
+ //
+ }
+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 : ATTControlLoopEvent( 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
+ //
+ // Logging
+ //
+ Logger.info("------------------------------------------------------------------------------------------------");
+ Logger.metrics(Instant.now() + " " + drools.getRule().getName() + " " + drools.getRule().getPackage());
+ Logger.metrics($params);
+ Logger.metrics($manager);
+ Logger.metrics($operation);
+ Logger.metrics($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")
+ //
+ ATTControlLoopNotification notification = new ATTControlLoopNotification($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}";
+ Engine.deliver("UEB", "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 o the CallGuardTask() and set the first
+ // argument to null (instead of XacmlPdpEngine).
+ //
+ boolean guardEnabled = true;
+
+ if(guardEnabled){
+
+ Thread t = new Thread(new com.att.ecomp.policy.guard.CallGuardTask(
+ XacmlPdpEngine,
+ "",
+ drools.getWorkingMemory(),
+ $operation.policy.actor.toString(),
+ $operation.policy.recipe,
+ $event.target,
+ $event.requestID.toString()
+ ));
+ t.start();
+ }
+ else{
+ insert(new PolicyGuardResponse("Permit", $event.requestID, $operation.policy.recipe));
+ }
+
+
+
+
+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 : ATTControlLoopEvent( 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
+ //
+ // Logging
+ //
+ Logger.info("------------------------------------------------------------------------------------------------");
+ Logger.metrics(Instant.now() + " " + drools.getRule().getName() + " " + drools.getRule().getPackage());
+ Logger.metrics($params);
+ Logger.metrics($event);
+ Logger.metrics($operation);
+ Logger.metrics($lock);
+ Logger.metrics($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")
+ //
+ ATTControlLoopNotification notification = new ATTControlLoopNotification($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}";
+ Engine.deliver("UEB", "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 : ATTControlLoopEvent( 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
+ //
+ // Logging
+ //
+ Logger.info("------------------------------------------------------------------------------------------------");
+ Logger.metrics(Instant.now() + " " + drools.getRule().getName() + " " + drools.getRule().getPackage());
+ Logger.metrics($params);
+ Logger.metrics($event);
+ Logger.metrics($manager);
+ Logger.metrics($operation);
+ Logger.metrics($opTimer);
+ Logger.metrics($lock);
+ Logger.metrics($response);
+ //
+ // Get the result of the operation
+ //
+ PolicyResult policyResult = $operation.onResponse($response);
+ if (policyResult != null) {
+ Logger.info("operation finished with result: " + policyResult);
+ //
+ // This Operation has completed, construct a notification showing our results. (DB write - end operation)
+ //
+ ATTControlLoopNotification notification = new ATTControlLoopNotification($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
+ //
+ Engine.deliver("UEB", "POLICY-CL-MGT", notification);
+ } else {
+ notification.notification = ControlLoopNotificationType.OPERATION_FAILURE;
+ //
+ // Let interested parties know
+ //
+ Engine.deliver("UEB", "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 ( ATTControlLoopEvent( closedLoopControlName == $params.getClosedLoopControlName(), requestID == $id, closedLoopEventStatus == ControlLoopEventStatus.ONSET ) )
+ then
+ //
+ // Logging
+ //
+ Logger.info("------------------------------------------------------------------------------------------------");
+ Logger.metrics(Instant.now() + " " + drools.getRule().getName() + " " + drools.getRule().getPackage());
+ Logger.metrics($params);
+ //
+ // Retract it
+ //
+ 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 : ATTControlLoopEvent( 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
+ //
+ // Logging
+ //
+ Logger.info("------------------------------------------------------------------------------------------------");
+ Logger.metrics(Instant.now() + " " + drools.getRule().getName() + " " + drools.getRule().getPackage());
+ Logger.metrics($params);
+ Logger.metrics($manager);
+ Logger.metrics($operation);
+ Logger.metrics($opTimer);
+ Logger.metrics($lock);
+ //
+ // Tell it its timed out
+ //
+ $operation.setOperationHasTimedOut();
+ //
+ // Create a notification for it ("DB Write - end operation")
+ //
+ ATTControlLoopNotification notification = new ATTControlLoopNotification($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
+ //
+ Engine.deliver("UEB", "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 : ATTControlLoopEvent( 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
+ //
+ // Logging
+ //
+ Logger.info("------------------------------------------------------------------------------------------------");
+ Logger.metrics(Instant.now() + " " + drools.getRule().getName() + " " + drools.getRule().getPackage());
+ Logger.metrics($params);
+ Logger.metrics($manager);
+ Logger.metrics($clTimer);
+ if ($operations == null) {
+ Logger.info("no operations found");
+ } else {
+ Logger.info("found " + $operations.size() + " operations");
+ }
+ //
+ // 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
+ //
+ Engine.deliver("UEB", "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/template.demo/src/test/java/org/onap/policy/controlloop/processor/ControlLoopXacmlGuardTest.java b/controlloop/templates/template.demo/src/test/java/org/onap/policy/controlloop/processor/ControlLoopXacmlGuardTest.java
new file mode 100644
index 000000000..1562c0ce6
--- /dev/null
+++ b/controlloop/templates/template.demo/src/test/java/org/onap/policy/controlloop/processor/ControlLoopXacmlGuardTest.java
@@ -0,0 +1,674 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * demo
+ * ================================================================================
+ * 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.processor;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.IOException;
+import java.net.URLEncoder;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.time.Instant;
+import java.util.HashMap;
+import java.util.UUID;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.junit.Ignore;
+import org.junit.Test;
+import org.kie.api.KieServices;
+import org.kie.api.builder.KieBuilder;
+import org.kie.api.builder.KieFileSystem;
+import org.kie.api.builder.Message;
+import org.kie.api.builder.ReleaseId;
+import org.kie.api.builder.Results;
+import org.kie.api.builder.model.KieModuleModel;
+import org.kie.api.event.rule.AfterMatchFiredEvent;
+import org.kie.api.event.rule.AgendaEventListener;
+import org.kie.api.event.rule.AgendaGroupPoppedEvent;
+import org.kie.api.event.rule.AgendaGroupPushedEvent;
+import org.kie.api.event.rule.BeforeMatchFiredEvent;
+import org.kie.api.event.rule.MatchCancelledEvent;
+import org.kie.api.event.rule.MatchCreatedEvent;
+import org.kie.api.event.rule.ObjectDeletedEvent;
+import org.kie.api.event.rule.ObjectInsertedEvent;
+import org.kie.api.event.rule.ObjectUpdatedEvent;
+import org.kie.api.event.rule.RuleFlowGroupActivatedEvent;
+import org.kie.api.event.rule.RuleFlowGroupDeactivatedEvent;
+import org.kie.api.event.rule.RuleRuntimeEventListener;
+import org.kie.api.runtime.KieContainer;
+import org.kie.api.runtime.KieSession;
+import org.kie.api.runtime.rule.FactHandle;
+import org.onap.policy.appc.Request;
+import org.onap.policy.appc.Response;
+import org.onap.policy.appc.ResponseCode;
+import org.onap.policy.appc.ResponseValue;
+import org.onap.policy.controlloop.ControlLoopEventStatus;
+import org.onap.policy.controlloop.ControlLoopNotificationType;
+
+import org.onap.policy.controlloop.VirtualControlLoopEvent;
+import org.onap.policy.controlloop.VirtualControlLoopNotification;
+import org.onap.policy.controlloop.ControlLoopLogger;
+import org.onap.policy.controlloop.impl.ControlLoopLoggerStdOutImpl;
+import org.onap.policy.controlloop.policy.ControlLoopPolicy;
+import org.onap.policy.controlloop.policy.TargetType;
+import org.onap.policy.drools.impl.PolicyEngineJUnitImpl;
+import org.onap.policy.guard.PolicyGuard;
+import org.onap.policy.guard.PolicyGuardYamlToXacml;
+import com.att.research.xacml.api.pdp.PDPEngine;
+import com.att.research.xacml.api.pdp.PDPEngineFactory;
+import com.att.research.xacml.util.FactoryException;
+import com.att.research.xacml.util.XACMLProperties;
+
+import org.onap.policy.controlloop.policy.guard.ControlLoopGuard;
+
+
+public class ControlLoopXacmlGuardTest {
+
+
+
+ @Ignore
+ @Test
+ public void test() {
+ try {
+ this.runTest("src/main/resources/ControlLoop_Template_1707_xacml_guard.drl",
+ "src/test/resources/yaml/policy_ControlLoop_vUSP_1707.yaml",
+ "service=vUSP;resource=vCTS;type=operational",
+ "CL_VUSP_8888",
+ "com.att.ecomp.closed_loop.vUSP:VNFS:0.0.1");
+ } catch (IOException e) {
+ e.printStackTrace();
+ fail(e.getMessage());
+ }
+ }
+
+ public void runTest(String droolsTemplate,
+ String yamlFile,
+ String policyScope,
+ String policyName,
+ String policyVersion) throws IOException {
+ //
+ // Pull info from the yaml
+ //
+ final Util.Pair<ControlLoopPolicy, String> pair = Util.loadYaml(yamlFile);
+ assertNotNull(pair);
+ assertNotNull(pair.a);
+ assertNotNull(pair.a.controlLoop);
+ assertNotNull(pair.a.controlLoop.controlLoopName);
+ assertTrue(pair.a.controlLoop.controlLoopName.length() > 0);
+ //
+ // Build a container
+ //
+ final KieSession kieSession = buildContainer(droolsTemplate,
+ pair.a.controlLoop.controlLoopName,
+ policyScope,
+ policyName,
+ policyVersion,
+ URLEncoder.encode(pair.b, "UTF-8"));
+
+
+
+ System.out.println("============");
+ System.out.println(URLEncoder.encode(pair.b, "UTF-8"));
+ System.out.println("============");
+
+
+ kieSession.addEventListener(new RuleRuntimeEventListener() {
+
+ @Override
+ public void objectInserted(ObjectInsertedEvent event) {
+ }
+
+ @Override
+ public void objectUpdated(ObjectUpdatedEvent event) {
+ }
+
+ @Override
+ public void objectDeleted(ObjectDeletedEvent event) {
+ }
+ });
+ kieSession.addEventListener(new AgendaEventListener() {
+
+ @Override
+ public void matchCreated(MatchCreatedEvent event) {
+ //System.out.println("matchCreated: " + event.getMatch().getRule());
+ }
+
+ @Override
+ public void matchCancelled(MatchCancelledEvent event) {
+ }
+
+ @Override
+ public void beforeMatchFired(BeforeMatchFiredEvent event) {
+ //System.out.println("beforeMatchFired: " + event.getMatch().getRule() + event.getMatch().getObjects());
+ }
+
+ @Override
+ public void afterMatchFired(AfterMatchFiredEvent event) {
+ }
+
+ @Override
+ public void agendaGroupPopped(AgendaGroupPoppedEvent event) {
+ }
+
+ @Override
+ public void agendaGroupPushed(AgendaGroupPushedEvent event) {
+ }
+
+ @Override
+ public void beforeRuleFlowGroupActivated(RuleFlowGroupActivatedEvent event) {
+ }
+
+ @Override
+ public void afterRuleFlowGroupActivated(RuleFlowGroupActivatedEvent event) {
+ }
+
+ @Override
+ public void beforeRuleFlowGroupDeactivated(RuleFlowGroupDeactivatedEvent event) {
+ }
+
+ @Override
+ public void afterRuleFlowGroupDeactivated(RuleFlowGroupDeactivatedEvent event) {
+ }
+
+ });
+
+ //
+ // Create XACML Guard policy from YAML
+ // We prepare 4 Guards. Notice that Rebuilds recipe has two Guards (for checking policy combining algorithm)
+ //
+ fromYamlToXacml("src/test/resources/yaml/policy_guard_vUSP_1707_appc_restart.yaml",
+ "src/main/resources/frequency_limiter_template.xml",
+ "src/test/resources/xacml/autogenerated_frequency_limiter_restart.xml");
+
+ fromYamlToXacml("src/test/resources/yaml/policy_guard_vUSP_1707_appc_rebuild.yaml",
+ "src/main/resources/frequency_limiter_template.xml",
+ "src/test/resources/xacml/autogenerated_frequency_limiter_rebuild.xml");
+
+ fromYamlToXacml("src/test/resources/yaml/policy_guard_vUSP_1707_appc_rebuild_1.yaml",
+ "src/main/resources/frequency_limiter_template.xml",
+ "src/test/resources/xacml/autogenerated_frequency_limiter_rebuild_1.xml");
+
+ fromYamlToXacml("src/test/resources/yaml/policy_guard_vUSP_1707_appc_migrate.yaml",
+ "src/main/resources/frequency_limiter_template.xml",
+ "src/test/resources/xacml/autogenerated_frequency_limiter_migrate.xml");
+
+ PolicyGuardYamlToXacml.fromYamlToXacmlBlacklist("src/test/resources/yaml/policy_guard_vUSP_1707_appc_restart_blacklist.yaml",
+ "src/main/resources/blacklist_template.xml",
+ "src/test/resources/xacml/autogenerated_blacklist.xml");
+
+
+ //
+ // Insert our globals
+ //
+ final ControlLoopLogger logger = new ControlLoopLoggerStdOutImpl();
+ kieSession.setGlobal("Logger", logger);
+ final PolicyEngineJUnitImpl engine = new PolicyEngineJUnitImpl();
+ kieSession.setGlobal("Engine", engine);
+
+
+ //
+ // Creating an embedded XACML PDP
+ //
+ final PDPEngine xacmlPdpEngine;
+ System.setProperty(XACMLProperties.XACML_PROPERTIES_NAME, "src/test/resources/xacml/xacml_guard.properties");
+
+ PDPEngineFactory factory;
+ try {
+ factory = PDPEngineFactory.newInstance();
+ xacmlPdpEngine = factory.newEngine();
+ kieSession.setGlobal("XacmlPdpEngine", xacmlPdpEngine);
+ } catch (FactoryException e1) {
+ e1.printStackTrace();
+ }
+
+
+
+ //
+ // Initial fire of rules
+ //
+ kieSession.fireAllRules();
+ //
+ // Kick a thread that starts testing
+ //
+ new Thread(new Runnable() {
+
+
+ @Override
+ public void run() {
+ try {
+
+
+ //
+ // Let's use a unique ID for the request and
+ // a unique trigger source.
+ //
+ UUID requestID = UUID.randomUUID();
+ String triggerSourceName = "foobartriggersource36";
+
+ Object obj = null;
+
+ sendGoodEvents(kieSession, pair.a, requestID, triggerSourceName);
+ obj = engine.subscribe("UEB", "POLICY-CL-MGT");
+ assertNotNull(obj);
+ assertTrue(obj instanceof VirtualControlLoopNotification);
+ assertTrue(((VirtualControlLoopNotification)obj).notification.equals(ControlLoopNotificationType.ACTIVE));
+ //
+ // Give the control loop a little time to acquire the lock and publish the request
+ //
+ Thread.sleep(2000);
+
+
+ // "About to query Guard" notification (Querying about Restart)
+ obj = engine.subscribe("UEB", "POLICY-CL-MGT");
+ assertNotNull(obj);
+ System.out.println("\n\n####################### GOING TO QUERY GUARD about Restart!!!!!!");
+ System.out.println("Rule: " + ((VirtualControlLoopNotification)obj).policyName +" Message: " + ((VirtualControlLoopNotification)obj).message);
+ assertTrue(obj instanceof VirtualControlLoopNotification);
+ assertTrue(((VirtualControlLoopNotification)obj).notification.equals(ControlLoopNotificationType.OPERATION));
+
+ Thread.sleep(2000);
+ // "Response from Guard" notification
+ obj = engine.subscribe("UEB", "POLICY-CL-MGT");
+ assertNotNull(obj);
+ System.out.println("Rule: " + ((VirtualControlLoopNotification)obj).policyName +" Message: " + ((VirtualControlLoopNotification)obj).message);
+ assertTrue(obj instanceof VirtualControlLoopNotification);
+ assertTrue(((VirtualControlLoopNotification)obj).notification.equals(ControlLoopNotificationType.OPERATION));
+
+
+ if(true == ((VirtualControlLoopNotification)obj).message.contains("Guard result: Deny")){
+
+ // "About to query Guard" notification (Querying about Rebuild)
+ obj = engine.subscribe("UEB", "POLICY-CL-MGT");
+ assertNotNull(obj);
+ System.out.println("\n\n####################### GOING TO QUERY GUARD about Rebuild!!!!!!");
+ System.out.println("Rule: " + ((VirtualControlLoopNotification)obj).policyName +" Message: " + ((VirtualControlLoopNotification)obj).message);
+ assertTrue(obj instanceof VirtualControlLoopNotification);
+ assertTrue(((VirtualControlLoopNotification)obj).notification.equals(ControlLoopNotificationType.OPERATION));
+
+ Thread.sleep(2000);
+
+ // "Response from Guard" notification
+ obj = engine.subscribe("UEB", "POLICY-CL-MGT");
+ assertNotNull(obj);
+ System.out.println("Rule: " + ((VirtualControlLoopNotification)obj).policyName +" Message: " + ((VirtualControlLoopNotification)obj).message);
+ assertTrue(obj instanceof VirtualControlLoopNotification);
+ assertTrue(((VirtualControlLoopNotification)obj).notification.equals(ControlLoopNotificationType.OPERATION));
+
+
+ if(true == ((VirtualControlLoopNotification)obj).message.contains("Guard result: Deny")){
+
+ // "About to query Guard" notification (Querying about Migrate)
+ obj = engine.subscribe("UEB", "POLICY-CL-MGT");
+ assertNotNull(obj);
+ System.out.println("\n\n####################### GOING TO QUERY GUARD!!!!!!");
+ System.out.println("Rule: " + ((VirtualControlLoopNotification)obj).policyName +" Message: " + ((VirtualControlLoopNotification)obj).message);
+ assertTrue(obj instanceof VirtualControlLoopNotification);
+ assertTrue(((VirtualControlLoopNotification)obj).notification.equals(ControlLoopNotificationType.OPERATION));
+
+ Thread.sleep(2000);
+
+ // "Response from Guard" notification
+ obj = engine.subscribe("UEB", "POLICY-CL-MGT");
+ assertNotNull(obj);
+ System.out.println("Rule: " + ((VirtualControlLoopNotification)obj).policyName +" Message: " + ((VirtualControlLoopNotification)obj).message);
+ assertTrue(obj instanceof VirtualControlLoopNotification);
+ assertTrue(((VirtualControlLoopNotification)obj).notification.equals(ControlLoopNotificationType.OPERATION));
+
+
+ if(true == ((VirtualControlLoopNotification)obj).message.contains("Guard result: Deny")){
+ //All the 3 operations were Denied by Guard
+ Thread.sleep(30000);
+
+ }
+ }
+ }
+
+ //
+ // In case one of the operations was permitted by Guard
+ //
+ if(true == ((VirtualControlLoopNotification)obj).message.contains("Guard result: Permit")){
+ obj = engine.subscribe("UEB", "POLICY-CL-MGT");
+ assertNotNull(obj);
+ System.out.println("Rule: " + ((VirtualControlLoopNotification)obj).policyName +" Message: " + ((VirtualControlLoopNotification)obj).message);
+ assertTrue(obj instanceof VirtualControlLoopNotification);
+ assertTrue(((VirtualControlLoopNotification)obj).notification.equals(ControlLoopNotificationType.OPERATION));
+
+ Thread.sleep(500);
+
+ obj = engine.subscribe("UEB", "APPC-CL");
+ assertNotNull(obj);
+ assertTrue(obj instanceof Request);
+ assertTrue(((Request)obj).CommonHeader.SubRequestID.equals("1"));
+
+ System.out.println("\n============ APP-C Got request!!! ===========\n");
+ //
+ // Ok - let's simulate ACCEPT
+ //
+
+ //
+ // now wait for it to finish
+ //
+ Thread.sleep(500);
+
+ //
+ // Now we are going to success it
+ //
+ Response response = new Response((Request) obj);
+ response.Status.Code = ResponseCode.SUCCESS.getValue();
+ response.Status.Value = ResponseValue.SUCCESS.toString();
+ response.Status.Description = "AppC success";
+ kieSession.insert(response);
+ //
+ // Give it some time to process
+ //
+ Thread.sleep(2000);
+ //
+ // Insert the abatement event
+ //
+ sendAbatement(kieSession, pair.a, requestID, triggerSourceName);
+ //
+ // now wait for it to finish
+ //
+ Thread.sleep(5000);
+ //
+ // Ensure they released the lock
+ //
+ assertFalse(PolicyGuard.isLocked(TargetType.VM, triggerSourceName, requestID));
+
+ }
+
+
+
+ } catch (InterruptedException e) {
+ System.err.println("Test thread got InterruptedException " + e.getLocalizedMessage());
+ } catch (AssertionError e) {
+ System.err.println("Test thread got AssertionError " + e.getLocalizedMessage());
+ e.printStackTrace();
+ } catch (Exception e) {
+ System.err.println("Test thread got Exception " + e.getLocalizedMessage());
+ e.printStackTrace();
+ }
+ kieSession.halt();
+ }
+
+ }).start();
+ //
+ // Start firing rules
+ //
+ kieSession.fireUntilHalt();
+ //
+ // Dump working memory
+ //
+ dumpFacts(kieSession);
+ //
+ // See if there is anything left in memory
+ //
+ assertEquals(1, kieSession.getFactCount());
+
+ for (FactHandle handle : kieSession.getFactHandles()) {
+ Object fact = kieSession.getObject(handle);
+ assertEquals("", "com.att.ecomp.policy.controlloop.Params", fact.getClass().getName());
+ }
+ }
+
+
+
+
+ public static void dumpFacts(KieSession kieSession) {
+ System.out.println("Fact Count: " + kieSession.getFactCount());
+ for (FactHandle handle : kieSession.getFactHandles()) {
+ System.out.println("FACT: " + handle);
+ }
+ }
+
+ protected void sendAbatement(KieSession kieSession, ControlLoopPolicy policy, UUID requestID, String triggerSourceName) throws InterruptedException {
+ VirtualControlLoopEvent event = new VirtualControlLoopEvent();
+ event.closedLoopControlName = policy.controlLoop.controlLoopName;
+ event.requestID = requestID;
+ event.target = "vserver.vserver-name";
+ event.closedLoopAlarmStart = Instant.now().minusSeconds(5);
+ event.closedLoopAlarmEnd = Instant.now();
+ event.AAI = new HashMap<String, String>();
+ event.AAI.put("cloud-region.identity-url", "foo");
+ event.AAI.put("vserver.selflink", "bar");
+ event.AAI.put("vserver.is-closed-loop-disabled", "false");
+ event.AAI.put("generic-vnf.vnf-name", "testGenericVnfName");
+ event.closedLoopEventStatus = ControlLoopEventStatus.ABATED;
+ kieSession.insert(event);
+ }
+
+ protected void sendGoodEvents(KieSession kieSession, ControlLoopPolicy policy, UUID requestID, String triggerSourceName) throws InterruptedException {
+ VirtualControlLoopEvent event = new VirtualControlLoopEvent();
+ event.closedLoopControlName = policy.controlLoop.controlLoopName;
+ event.requestID = requestID;
+ event.target = "vserver.vserver-name";
+ event.closedLoopAlarmStart = Instant.now();
+ event.AAI = new HashMap<String, String>();
+ event.AAI.put("cloud-region.identity-url", "foo");
+ event.AAI.put("vserver.selflink", "bar");
+ event.AAI.put("vserver.is-closed-loop-disabled", "false");
+ event.AAI.put("vserver.vserver-name", "testGenericVnfName");
+ event.closedLoopEventStatus = ControlLoopEventStatus.ONSET;
+ kieSession.insert(event);
+ Thread.sleep(1000);
+
+ /*
+ event = new ATTControlLoopEvent(event);
+ event.triggerID = "107.250.169.145_f5BigIP" + Instant.now().toEpochMilli();
+ kieSession.insert(event);
+ Thread.sleep(1000);
+
+ event = new ATTControlLoopEvent(event);
+ event.triggerID = "107.250.169.145_f5BigIP" + Instant.now().toEpochMilli();
+ kieSession.insert(event);
+ Thread.sleep(1000);
+
+ event = new ATTControlLoopEvent(event);
+ event.triggerID = "107.250.169.145_f5BigIP" + Instant.now().toEpochMilli();
+ kieSession.insert(event);
+ Thread.sleep(1000);
+ */
+
+ }
+
+ protected void sendBadEvents(KieSession kieSession, ControlLoopPolicy policy, UUID requestID, String triggerSourceName) throws InterruptedException {
+ //
+ // Insert a bad Event
+ //
+ VirtualControlLoopEvent event = new VirtualControlLoopEvent();
+ event.closedLoopControlName = policy.controlLoop.controlLoopName;
+ kieSession.insert(event);
+ Thread.sleep(250);
+ //
+ // add the request id
+ //
+ event.requestID = requestID;
+ kieSession.insert(event);
+ Thread.sleep(250);
+ //
+ // add some aai
+ //
+ event.AAI = new HashMap<String, String>();
+ event.AAI.put("cloud-region.identity-url", "foo");
+ event.AAI.put("vserver.selflink", "bar");
+ event.AAI.put("vserver.vserver-name", "vmfoo");
+ kieSession.insert(event);
+ Thread.sleep(250);
+ //
+ // set a valid status
+ //
+ event.closedLoopEventStatus = ControlLoopEventStatus.ONSET;
+ kieSession.insert(event);
+ Thread.sleep(250);
+ //
+ // add a trigger sourcename
+ //
+ kieSession.insert(event);
+ Thread.sleep(250);
+ //
+ // add is closed-loop-disabled
+ //
+ event.AAI.put("vserver.is-closed-loop-disabled", "true");
+ kieSession.insert(event);
+ Thread.sleep(250);
+ //
+ // now enable
+ //
+ event.AAI.put("vserver.is-closed-loop-disabled", "false");
+ kieSession.insert(event);
+ Thread.sleep(250);
+ //
+ // Add target, but bad.
+ //
+ event.target = "VM_BLAH";
+ kieSession.insert(event);
+ Thread.sleep(250);
+ }
+
+
+ public static void fromYamlToXacml(String yamlFile, String xacmlTemplate, String xacmlPolicyOutput){
+
+ ControlLoopGuard yamlGuardObject = Util.loadYamlGuard(yamlFile);
+ System.out.println("actor: " + yamlGuardObject.guards.getFirst().actor);
+ System.out.println("recipe: " + yamlGuardObject.guards.getFirst().recipe);
+ System.out.println("num: " + yamlGuardObject.guards.getFirst().limit_constraints.getFirst().num);
+ System.out.println("duration: " + yamlGuardObject.guards.getFirst().limit_constraints.getFirst().duration);
+ System.out.println("time_in_range: " + yamlGuardObject.guards.getFirst().limit_constraints.getFirst().time_in_range);
+
+ Path xacmlTemplatePath = Paths.get(xacmlTemplate);
+ String xacmlTemplateContent;
+
+ try {
+ xacmlTemplateContent = new String(Files.readAllBytes(xacmlTemplatePath));
+
+ String xacmlPolicyContent = PolicyGuardYamlToXacml.generateXacmlGuard(xacmlTemplateContent,
+ yamlGuardObject.guards.getFirst().actor,
+ yamlGuardObject.guards.getFirst().recipe,
+ yamlGuardObject.guards.getFirst().limit_constraints.getFirst().num,
+ yamlGuardObject.guards.getFirst().limit_constraints.getFirst().duration,
+ yamlGuardObject.guards.getFirst().limit_constraints.getFirst().time_in_range.get("arg2"),
+ yamlGuardObject.guards.getFirst().limit_constraints.getFirst().time_in_range.get("arg3")
+ );
+
+
+ Files.write(Paths.get(xacmlPolicyOutput), xacmlPolicyContent.getBytes());
+
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ }
+
+
+
+ public static String generatePolicy(String ruleContents,
+ String closedLoopControlName,
+ String policyScope,
+ String policyName,
+ String policyVersion,
+ String controlLoopYaml) {
+
+ Pattern p = Pattern.compile("\\$\\{closedLoopControlName\\}");
+ Matcher m = p.matcher(ruleContents);
+ ruleContents = m.replaceAll(closedLoopControlName);
+
+ p = Pattern.compile("\\$\\{policyScope\\}");
+ m = p.matcher(ruleContents);
+ ruleContents = m.replaceAll(policyScope);
+
+ p = Pattern.compile("\\$\\{policyName\\}");
+ m = p.matcher(ruleContents);
+ ruleContents = m.replaceAll(policyName);
+
+ p = Pattern.compile("\\$\\{policyVersion\\}");
+ m = p.matcher(ruleContents);
+ ruleContents = m.replaceAll(policyVersion);
+
+ p = Pattern.compile("\\$\\{controlLoopYaml\\}");
+ m = p.matcher(ruleContents);
+ ruleContents = m.replaceAll(controlLoopYaml);
+ System.out.println(ruleContents);
+
+ return ruleContents;
+ }
+
+ public static KieSession buildContainer(String droolsTemplate, String closedLoopControlName, String policyScope, String policyName, String policyVersion, String yamlSpecification) throws IOException {
+ //
+ // Get our Drools Kie factory
+ //
+ KieServices ks = KieServices.Factory.get();
+
+ KieModuleModel kModule = ks.newKieModuleModel();
+
+ System.out.println("KMODULE:" + System.lineSeparator() + kModule.toXML());
+
+ //
+ // Generate our drools rule from our template
+ //
+ KieFileSystem kfs = ks.newKieFileSystem();
+
+ kfs.writeKModuleXML(kModule.toXML());
+ {
+ Path rule = Paths.get(droolsTemplate);
+ String ruleTemplate = new String(Files.readAllBytes(rule));
+ String drlContents = generatePolicy(ruleTemplate,
+ closedLoopControlName,
+ policyScope,
+ policyName,
+ policyVersion,
+ yamlSpecification);
+
+ kfs.write("src/main/resources/" + policyName + ".drl", ks.getResources().newByteArrayResource(drlContents.getBytes()));
+ }
+ //
+ // Compile the rule
+ //
+ KieBuilder builder = ks.newKieBuilder(kfs).buildAll();
+ Results results = builder.getResults();
+ if (results.hasMessages(Message.Level.ERROR)) {
+ for (Message msg : results.getMessages()) {
+ System.err.println(msg.toString());
+ }
+ throw new RuntimeException("Drools Rule has Errors");
+ }
+ for (Message msg : results.getMessages()) {
+ System.out.println(msg.toString());
+ }
+ //
+ // Create our kie Session and container
+ //
+ ReleaseId releaseId = ks.getRepository().getDefaultReleaseId();
+ System.out.println(releaseId);
+ KieContainer kContainer = ks.newKieContainer(releaseId);
+
+ return kContainer.newKieSession();
+ }
+
+
+
+
+}
diff --git a/controlloop/templates/template.demo/src/test/java/org/onap/policy/controlloop/processor/Util.java b/controlloop/templates/template.demo/src/test/java/org/onap/policy/controlloop/processor/Util.java
new file mode 100644
index 000000000..afb1e9b22
--- /dev/null
+++ b/controlloop/templates/template.demo/src/test/java/org/onap/policy/controlloop/processor/Util.java
@@ -0,0 +1,90 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * demo
+ * ================================================================================
+ * 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.processor;
+
+import static org.junit.Assert.fail;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+
+import org.apache.commons.io.IOUtils;
+import org.yaml.snakeyaml.Yaml;
+import org.yaml.snakeyaml.constructor.Constructor;
+
+import org.onap.policy.controlloop.policy.ControlLoopPolicy;
+import org.onap.policy.controlloop.policy.guard.ControlLoopGuard;
+
+public final class Util {
+
+ public static class Pair<A, B> {
+ public final A a;
+ public final B b;
+
+ public Pair(A a, B b) {
+ this.a = a;
+ this.b = b;
+ }
+ }
+
+ public static Pair<ControlLoopPolicy, String> loadYaml(String testFile) {
+ try (InputStream is = new FileInputStream(new File(testFile))) {
+ String contents = IOUtils.toString(is, StandardCharsets.UTF_8);
+ //
+ // Read the yaml into our Java Object
+ //
+ Yaml yaml = new Yaml(new Constructor(ControlLoopPolicy.class));
+ Object obj = yaml.load(contents);
+
+ //String ttt = ((ControlLoopPolicy)obj).policies.getFirst().payload.get("asdas");
+ System.out.println(contents);
+ //for(Policy policy : ((ControlLoopPolicy)obj).policies){
+
+ return new Pair<ControlLoopPolicy, String>((ControlLoopPolicy) obj, contents);
+ } catch (FileNotFoundException e) {
+ fail(e.getLocalizedMessage());
+ } catch (IOException e) {
+ fail(e.getLocalizedMessage());
+ }
+ return null;
+ }
+
+ public static ControlLoopGuard loadYamlGuard(String testFile) {
+ try (InputStream is = new FileInputStream(new File(testFile))) {
+ String contents = IOUtils.toString(is, StandardCharsets.UTF_8);
+ //
+ // Read the yaml into our Java Object
+ //
+ Yaml yaml = new Yaml(new Constructor(ControlLoopGuard.class));
+ Object obj = yaml.load(contents);
+ return (ControlLoopGuard) obj;
+ } catch (FileNotFoundException e) {
+ fail(e.getLocalizedMessage());
+ } catch (IOException e) {
+ fail(e.getLocalizedMessage());
+ }
+ return null;
+ }
+
+}
diff --git a/controlloop/templates/template.demo/src/test/resources/xacml/old/frequency_limiter_1.xml b/controlloop/templates/template.demo/src/test/resources/xacml/old/frequency_limiter_1.xml
new file mode 100644
index 000000000..1a70d0468
--- /dev/null
+++ b/controlloop/templates/template.demo/src/test/resources/xacml/old/frequency_limiter_1.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<Policy xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" PolicyId="urn:com:att:xacml:policy:id:25e12b06-11d5-4895-b2a2-6f6c594de069" Version="1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable">
+ <Description>Policy for frequency limiter.</Description>
+ <Target>
+ <AnyOf>
+ <AllOf>
+ <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">APPC</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="urn:oasis:names:tc:xacml:1.0:actor:actor-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+ </Match>
+ <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Restart</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" AttributeId="urn:oasis:names:tc:xacml:1.0:operation:operation-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+ </Match>
+ </AllOf>
+ </AnyOf>
+ </Target>
+ <Rule RuleId="urn:com:att:xacml:rule:id:e1e8c5c0-e2ba-47d5-9289-6c015305ed21" Effect="Permit">
+ <Description>PERMIT - only if number of operations performed in the past is less than the limit.</Description>
+ <Target/>
+ <Condition>
+ <VariableReference VariableId="isHistoryLessOrEqual"/>
+ </Condition>
+ </Rule>
+ <VariableDefinition VariableId="isHistoryLessOrEqual">
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-less-than-or-equal">
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="com:att:research:xacml:test:sql:resource:operations:count" DataType="http://www.w3.org/2001/XMLSchema#integer" Issuer="com:att:research:xacml:test:sql" MustBePresent="false"/>
+ </Apply>
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#integer">1</AttributeValue>
+ </Apply>
+ </VariableDefinition>
+ <Rule RuleId="urn:com:att:xacml:rule:id:c9a3fb7d-d0b9-48bb-bdca-87eb4957120c" Effect="Deny">
+ <Description>DENY - default.</Description>
+ <Target/>
+ </Rule>
+</Policy>
diff --git a/controlloop/templates/template.demo/src/test/resources/xacml/old/frequency_limiter_2.xml b/controlloop/templates/template.demo/src/test/resources/xacml/old/frequency_limiter_2.xml
new file mode 100644
index 000000000..e7e34feeb
--- /dev/null
+++ b/controlloop/templates/template.demo/src/test/resources/xacml/old/frequency_limiter_2.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<Policy xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" PolicyId="urn:com:att:xacml:policy:id:25e12b06-11d5-4895-b2a2-6f6c594de069" Version="1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable">
+ <Description>Policy for frequency limiter.</Description>
+ <Target>
+ <AnyOf>
+ <AllOf>
+ <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">APPC</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="urn:oasis:names:tc:xacml:1.0:actor:actor-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+ </Match>
+ <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Restart</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" AttributeId="urn:oasis:names:tc:xacml:1.0:operation:operation-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+ </Match>
+ </AllOf>
+ </AnyOf>
+ </Target>
+ <Rule RuleId="urn:com:att:xacml:rule:id:e1e8c5c0-e2ba-47d5-9289-6c015305ed21" Effect="Permit">
+ <Description>PERMIT - only if number of operations performed in the past is less than the limit.</Description>
+
+ <Condition>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-equal">
+
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-bag-size">
+
+ <Apply FunctionId="urn:oasis:names:tc:xacml:3.0:function:map">
+
+ <Function FunctionId="urn:oasis:names:tc:xacml:1.0:function:dateTime-less-than-or-equal"/>
+
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:dateTime-subtract-dayTimeDuration">
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:dateTime-one-and-only">
+ <AttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:environment:current-dateTime" DataType="http://www.w3.org/2001/XMLSchema#dateTime" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:environment" MustBePresent="false"/>
+ </Apply>
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#dayTimeDuration">PT10M</AttributeValue>
+ </Apply>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="com:att:research:xacml:test:sql:resource:operations:starttimebag" DataType="http://www.w3.org/2001/XMLSchema#dateTime" Issuer="com:att:research:xacml:test:sql" MustBePresent="false"/>
+ </Apply>
+ </Apply>
+
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#integer">22</AttributeValue>
+
+ </Apply>
+ </Condition>
+ </Rule>
+
+
+ <Rule RuleId="urn:com:att:xacml:rule:id:c9a3fb7d-d0b9-48bb-bdca-87eb4957120c" Effect="Deny">
+ <Description>DENY - default.</Description>
+ <Target/>
+ </Rule>
+
+</Policy>
diff --git a/controlloop/templates/template.demo/src/test/resources/xacml/old/frequency_limiter_3.xml b/controlloop/templates/template.demo/src/test/resources/xacml/old/frequency_limiter_3.xml
new file mode 100644
index 000000000..c171968d2
--- /dev/null
+++ b/controlloop/templates/template.demo/src/test/resources/xacml/old/frequency_limiter_3.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<Policy xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" PolicyId="urn:com:att:xacml:policy:id:25e12b06-11d5-4895-b2a2-6f6c594de069" Version="1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable">
+ <Description>Policy for frequency limiter.</Description>
+ <Target>
+ <AnyOf>
+ <AllOf>
+ <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">APPC</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="urn:oasis:names:tc:xacml:1.0:actor:actor-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+ </Match>
+ <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Restart</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" AttributeId="urn:oasis:names:tc:xacml:1.0:operation:operation-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+ </Match>
+ </AllOf>
+ </AnyOf>
+ </Target>
+ <Rule RuleId="urn:com:att:xacml:rule:id:e1e8c5c0-e2ba-47d5-9289-6c015305ed21" Effect="Permit">
+ <Description>PERMIT - only if number of operations performed in the past is less than the limit.</Description>
+ <Target/>
+ <Condition>
+ <VariableReference VariableId="isHistoryLessOrEqual"/>
+ </Condition>
+ </Rule>
+ <VariableDefinition VariableId="isHistoryLessOrEqual">
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-less-than-or-equal">
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="com:att:research:xacml:test:sql:resource:operations:count" DataType="http://www.w3.org/2001/XMLSchema#integer" Issuer="com:att:research:xacml:test:sql:tw10min" MustBePresent="false"/>
+ </Apply>
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#integer">1</AttributeValue>
+ </Apply>
+ </VariableDefinition>
+ <Rule RuleId="urn:com:att:xacml:rule:id:c9a3fb7d-d0b9-48bb-bdca-87eb4957120c" Effect="Deny">
+ <Description>DENY - default.</Description>
+ <Target/>
+ </Rule>
+</Policy>
diff --git a/controlloop/templates/template.demo/src/test/resources/xacml/old/frequency_limiter_4.xml b/controlloop/templates/template.demo/src/test/resources/xacml/old/frequency_limiter_4.xml
new file mode 100644
index 000000000..53e83d9cd
--- /dev/null
+++ b/controlloop/templates/template.demo/src/test/resources/xacml/old/frequency_limiter_4.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<Policy xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" PolicyId="urn:com:att:xacml:policy:id:25e12b06-11d5-4895-b2a2-6f6c594de069" Version="1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable">
+ <Description>Policy for frequency limiter.</Description>
+ <Target>
+ <AnyOf>
+ <AllOf>
+ <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">APPC</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="urn:oasis:names:tc:xacml:1.0:actor:actor-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+ </Match>
+ <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Restart</AttributeValue>
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" AttributeId="urn:oasis:names:tc:xacml:1.0:operation:operation-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/>
+ </Match>
+ </AllOf>
+ </AnyOf>
+ </Target>
+ <Rule RuleId="urn:com:att:xacml:rule:id:e1e8c5c0-e2ba-47d5-9289-6c015305ed21" Effect="Permit">
+ <Description>PERMIT - only if number of operations performed in the past is less than the limit.</Description>
+ <Target/>
+ <Condition>
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:or">
+ <VariableReference VariableId="isGuardNotActive"/>
+ <VariableReference VariableId="isHistoryLessOrEqual"/>
+ </Apply>
+ </Condition>
+ </Rule>
+ <VariableDefinition VariableId="isGuardNotActive">
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:not">
+ <Apply FunctionId="urn:oasis:names:tc:xacml:2.0:function:time-in-range">
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:time-one-and-only">
+ <AttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:environment:current-time" DataType="http://www.w3.org/2001/XMLSchema#time" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:environment" MustBePresent="false"/>
+ </Apply>
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#time">05:00:00-05:00</AttributeValue>
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#time">23:59:59-05:00</AttributeValue>
+ </Apply>
+ </Apply>
+ </VariableDefinition>
+ <VariableDefinition VariableId="isHistoryLessOrEqual">
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-less-than-or-equal">
+ <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only">
+ <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="com:att:research:xacml:test:sql:resource:operations:count" DataType="http://www.w3.org/2001/XMLSchema#integer" Issuer="com:att:research:xacml:test:sql:tw10min" MustBePresent="false"/>
+ </Apply>
+ <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#integer">1</AttributeValue>
+ </Apply>
+ </VariableDefinition>
+ <Rule RuleId="urn:com:att:xacml:rule:id:c9a3fb7d-d0b9-48bb-bdca-87eb4957120c" Effect="Deny">
+ <Description>DENY - default.</Description>
+ <Target/>
+ </Rule>
+</Policy>
diff --git a/controlloop/templates/template.demo/src/test/resources/xacml/old/xacml.properties b/controlloop/templates/template.demo/src/test/resources/xacml/old/xacml.properties
new file mode 100644
index 000000000..e51f038e9
--- /dev/null
+++ b/controlloop/templates/template.demo/src/test/resources/xacml/old/xacml.properties
@@ -0,0 +1,119 @@
+#
+#
+# This is test set that tests configurable SQL PIP engine. It uses sample data from MySQL world database
+#
+# http://dev.mysql.com/doc/world-setup/en/index.html
+#
+# The Policy was created using the PAP Admin Tool.
+#
+#
+
+#
+# Default XACML Properties File
+# Standard API Factories
+#
+xacml.dataTypeFactory=com.att.research.xacml.std.StdDataTypeFactory
+xacml.pdpEngineFactory=com.att.research.xacmlatt.pdp.ATTPDPEngineFactory
+xacml.pepEngineFactory=com.att.research.xacml.std.pep.StdEngineFactory
+xacml.pipFinderFactory=com.att.research.xacml.std.pip.StdPIPFinderFactory
+xacml.traceEngineFactory=com.att.research.xacml.std.trace.LoggingTraceEngineFactory
+#
+# AT&T PDP Implementation Factories
+#
+xacml.att.evaluationContextFactory=com.att.research.xacmlatt.pdp.std.StdEvaluationContextFactory
+xacml.att.combiningAlgorithmFactory=com.att.research.xacmlatt.pdp.std.StdCombiningAlgorithmFactory
+xacml.att.functionDefinitionFactory=com.att.research.xacmlatt.pdp.std.StdFunctionDefinitionFactory
+xacml.att.policyFinderFactory=com.att.research.xacmlatt.pdp.std.StdPolicyFinderFactory
+
+#
+# NOTE: If you are testing against a RESTful PDP, then the PDP must be configured with the
+# policies and PIP configuration as defined below. Otherwise, this is the configuration that
+# the embedded PDP uses.
+#
+
+# Policies to load
+#
+xacml.rootPolicies=sql
+sql.file=src/test/resources/xacml/frequency_limiter_1.xml
+
+# PIP Engine Definition
+#
+xacml.pip.engines=sql1
+
+sql1.classname=com.att.research.xacml.std.pip.engines.jdbc.JDBCEngine
+sql1.name=World
+sql1.description=World Database from MySQL website. Copyright Statistics Finland, http://www.stat.fi/worldinfigures.
+# This will be the default issuer for the resolvers. NOTE: Issuer only used for attributes provided by the engine.
+sql1.issuer=com:att:research:xacml:test:sql
+#
+# This is the configuration for JDBC. You will have to setup the database and run the data\world*.sql script to
+# create the tables and load the data.
+#
+sql1.type=jdbc
+
+# Postgres DB
+#sql1.jdbc.driver=org.postgresql.Driver
+#sql1.jdbc.url=jdbc:postgresql://localhost:7778/postgres
+#sql1.jdbc.conn.user=postgres
+#sql1.jdbc.conn.password=
+
+# MariaDB
+sql1.jdbc.driver=org.mariadb.jdbc.Driver
+sql1.jdbc.url=jdbc:mariadb://localhost:7779/policy
+sql1.jdbc.conn.user=root
+sql1.jdbc.conn.password=lmpg
+
+#
+# This is the configuration for JNDI datasource.
+#
+#sql1.type=jndi
+#sql1.datasource=jdbc/xacml
+
+sql1.resolvers=langer
+
+sql1.resolver.langer.classname=com.att.research.xacml.std.pip.engines.jdbc.ConfigurableJDBCResolver
+sql1.resolver.langer.name=Language
+sql1.resolver.langer.description=This returns the number of previous operations within the given time window
+
+# Query for Postgres DB
+#sql1.resolver.langer.select=select count(*) from operationshistory where actor=? and operation=? and target=? and endtime between now()::timestamp with time zone - (interval '1000000000s') and now()::timestamp with time zone
+
+# Query for MariaDB
+#sql1.resolver.langer.select=select count(*) as count from operationshistory where actor=? and operation=? and target=? and convert_tz(endtime,@@session.time_zone,'-05:00') between date_sub(convert_tz(now(),@@session.time_zone,'-05:00'),interval 100 hour) and convert_tz(now(),@@session.time_zone,'-05:00')
+sql1.resolver.langer.select=select count(*) as count from operationshistory9 where actor=? and operation=? and target=? and endtime between date_sub(now(),interval 100 hour) and now()
+
+sql1.resolver.langer.fields=count
+sql1.resolver.langer.field.count.id=com:att:research:xacml:test:sql:resource:operations:count
+sql1.resolver.langer.field.count.datatype=http://www.w3.org/2001/XMLSchema#integer
+sql1.resolver.langer.field.count.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+
+
+#You can override the default issuer that is set in the JDBCEngine definition if you want.
+#sql1.resolver.langer.field.language.issuer=com:att:research:xacml:test:sql
+sql1.resolver.langer.parameters=actor,operation,target
+
+sql1.resolver.langer.parameter.actor.id=urn:oasis:names:tc:xacml:1.0:actor:actor-id
+sql1.resolver.langer.parameter.actor.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.langer.parameter.actor.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+sql1.resolver.langer.parameter.operation.id=urn:oasis:names:tc:xacml:1.0:operation:operation-id
+sql1.resolver.langer.parameter.operation.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.langer.parameter.operation.category=urn:oasis:names:tc:xacml:3.0:attribute-category:action
+
+sql1.resolver.langer.parameter.target.id=urn:oasis:names:tc:xacml:1.0:target:target-id
+sql1.resolver.langer.parameter.target.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.langer.parameter.target.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+
+#
+# These properties are for an attribute generator to build into requests.
+#
+xacml.attribute.generator=generate_subjectid
+
+xacml.attribute.generator.generate_subjectid.file=generate.data
+xacml.attribute.generator.generate_subjectid.attributes=city
+
+xacml.attribute.generator.generate_subjectid.attributes.city.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+xacml.attribute.generator.generate_subjectid.attributes.city.datatype=http://www.w3.org/2001/XMLSchema#string
+xacml.attribute.generator.generate_subjectid.attributes.city.id=urn:oasis:names:tc:xacml:1.0:resource:resource-id
+xacml.attribute.generator.generate_subjectid.attributes.city.field=0
+
diff --git a/controlloop/templates/template.demo/src/test/resources/xacml/old/xacml2.properties b/controlloop/templates/template.demo/src/test/resources/xacml/old/xacml2.properties
new file mode 100644
index 000000000..2d1276b51
--- /dev/null
+++ b/controlloop/templates/template.demo/src/test/resources/xacml/old/xacml2.properties
@@ -0,0 +1,120 @@
+#
+#
+# This is test set that tests configurable SQL PIP engine. It uses sample data from MySQL world database
+#
+# http://dev.mysql.com/doc/world-setup/en/index.html
+#
+# The Policy was created using the PAP Admin Tool.
+#
+#
+
+#
+# Default XACML Properties File
+# Standard API Factories
+#
+xacml.dataTypeFactory=com.att.research.xacml.std.StdDataTypeFactory
+xacml.pdpEngineFactory=com.att.research.xacmlatt.pdp.ATTPDPEngineFactory
+xacml.pepEngineFactory=com.att.research.xacml.std.pep.StdEngineFactory
+xacml.pipFinderFactory=com.att.research.xacml.std.pip.StdPIPFinderFactory
+xacml.traceEngineFactory=com.att.research.xacml.std.trace.LoggingTraceEngineFactory
+#
+# AT&T PDP Implementation Factories
+#
+xacml.att.evaluationContextFactory=com.att.research.xacmlatt.pdp.std.StdEvaluationContextFactory
+xacml.att.combiningAlgorithmFactory=com.att.research.xacmlatt.pdp.std.StdCombiningAlgorithmFactory
+xacml.att.functionDefinitionFactory=com.att.research.xacmlatt.pdp.std.StdFunctionDefinitionFactory
+xacml.att.policyFinderFactory=com.att.research.xacmlatt.pdp.std.StdPolicyFinderFactory
+
+#
+# NOTE: If you are testing against a RESTful PDP, then the PDP must be configured with the
+# policies and PIP configuration as defined below. Otherwise, this is the configuration that
+# the embedded PDP uses.
+#
+
+# Policies to load
+#
+xacml.rootPolicies=sql
+sql.file=src/test/resources/xacml/frequency_limiter_2.xml
+
+# PIP Engine Definition
+#
+xacml.pip.engines=sql1
+
+sql1.classname=com.att.research.xacml.std.pip.engines.jdbc.JDBCEngine
+sql1.name=World
+sql1.description=World Database from MySQL website. Copyright Statistics Finland, http://www.stat.fi/worldinfigures.
+# This will be the default issuer for the resolvers. NOTE: Issuer only used for attributes provided by the engine.
+sql1.issuer=com:att:research:xacml:test:sql
+#
+# This is the configuration for JDBC. You will have to setup the database and run the data\world*.sql script to
+# create the tables and load the data.
+#
+sql1.type=jdbc
+
+# Postgres DB
+#sql1.jdbc.driver=org.postgresql.Driver
+#sql1.jdbc.url=jdbc:postgresql://localhost:7778/postgres
+#sql1.jdbc.conn.user=postgres
+#sql1.jdbc.conn.password=
+
+# MariaDB
+sql1.jdbc.driver=org.mariadb.jdbc.Driver
+sql1.jdbc.url=jdbc:mariadb://localhost:7779/policy
+sql1.jdbc.conn.user=root
+sql1.jdbc.conn.password=lmpg
+
+#
+# This is the configuration for JNDI datasource.
+#
+#sql1.type=jndi
+#sql1.datasource=jdbc/xacml
+
+sql1.resolvers=langer
+
+sql1.resolver.langer.classname=com.att.research.xacml.std.pip.engines.jdbc.ConfigurableJDBCResolver
+sql1.resolver.langer.name=Language
+sql1.resolver.langer.description=This returns the number of previous operations within the given time window
+
+# Query for Postgres DB
+#sql1.resolver.langer.select=select count(*) from operationshistory where actor=? and operation=? and target=? and endtime between now()::timestamp with time zone - (interval '1000000000s') and now()::timestamp with time zone
+
+# Query for MariaDB
+#sql1.resolver.langer.select=select count(*) as count from operationshistory where actor=? and operation=? and target=? and convert_tz(endtime,@@session.time_zone,'-05:00') between date_sub(convert_tz(now(),@@session.time_zone,'-05:00'),interval 100 hour) and convert_tz(now(),@@session.time_zone,'-05:00')
+sql1.resolver.langer.select=select starttime as starttimebag from operationshistory9 where actor=? and operation=? and target=? and endtime between date_sub(now(),interval 100 hour) and now()
+
+#sql1.resolver.langer.fields=count
+sql1.resolver.langer.fields=starttimebag
+sql1.resolver.langer.field.starttimebag.id=com:att:research:xacml:test:sql:resource:operations:starttimebag
+sql1.resolver.langer.field.starttimebag.datatype=http://www.w3.org/2001/XMLSchema#dateTime
+sql1.resolver.langer.field.starttimebag.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+
+
+#You can override the default issuer that is set in the JDBCEngine definition if you want.
+#sql1.resolver.langer.field.language.issuer=com:att:research:xacml:test:sql
+sql1.resolver.langer.parameters=actor,operation,target
+
+sql1.resolver.langer.parameter.actor.id=urn:oasis:names:tc:xacml:1.0:actor:actor-id
+sql1.resolver.langer.parameter.actor.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.langer.parameter.actor.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+
+sql1.resolver.langer.parameter.operation.id=urn:oasis:names:tc:xacml:1.0:operation:operation-id
+sql1.resolver.langer.parameter.operation.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.langer.parameter.operation.category=urn:oasis:names:tc:xacml:3.0:attribute-category:action
+
+sql1.resolver.langer.parameter.target.id=urn:oasis:names:tc:xacml:1.0:target:target-id
+sql1.resolver.langer.parameter.target.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.langer.parameter.target.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+
+#
+# These properties are for an attribute generator to build into requests.
+#
+xacml.attribute.generator=generate_subjectid
+
+xacml.attribute.generator.generate_subjectid.file=generate.data
+xacml.attribute.generator.generate_subjectid.attributes=city
+
+xacml.attribute.generator.generate_subjectid.attributes.city.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+xacml.attribute.generator.generate_subjectid.attributes.city.datatype=http://www.w3.org/2001/XMLSchema#string
+xacml.attribute.generator.generate_subjectid.attributes.city.id=urn:oasis:names:tc:xacml:1.0:resource:resource-id
+xacml.attribute.generator.generate_subjectid.attributes.city.field=0
+
diff --git a/controlloop/templates/template.demo/src/test/resources/xacml/old/xacml3.properties b/controlloop/templates/template.demo/src/test/resources/xacml/old/xacml3.properties
new file mode 100644
index 000000000..a3e6f2f44
--- /dev/null
+++ b/controlloop/templates/template.demo/src/test/resources/xacml/old/xacml3.properties
@@ -0,0 +1,123 @@
+#
+#
+# This is test set that tests configurable SQL PIP engine. It uses sample data from MySQL world database
+#
+# http://dev.mysql.com/doc/world-setup/en/index.html
+#
+# The Policy was created using the PAP Admin Tool.
+#
+#
+
+#
+# Default XACML Properties File
+# Standard API Factories
+#
+xacml.dataTypeFactory=com.att.research.xacml.std.StdDataTypeFactory
+xacml.pdpEngineFactory=com.att.research.xacmlatt.pdp.ATTPDPEngineFactory
+xacml.pepEngineFactory=com.att.research.xacml.std.pep.StdEngineFactory
+xacml.pipFinderFactory=com.att.research.xacml.std.pip.StdPIPFinderFactory
+xacml.traceEngineFactory=com.att.research.xacml.std.trace.LoggingTraceEngineFactory
+#
+# AT&T PDP Implementation Factories
+#
+xacml.att.evaluationContextFactory=com.att.research.xacmlatt.pdp.std.StdEvaluationContextFactory
+xacml.att.combiningAlgorithmFactory=com.att.research.xacmlatt.pdp.std.StdCombiningAlgorithmFactory
+xacml.att.functionDefinitionFactory=com.att.research.xacmlatt.pdp.std.StdFunctionDefinitionFactory
+xacml.att.policyFinderFactory=com.att.research.xacmlatt.pdp.std.StdPolicyFinderFactory
+
+#
+# NOTE: If you are testing against a RESTful PDP, then the PDP must be configured with the
+# policies and PIP configuration as defined below. Otherwise, this is the configuration that
+# the embedded PDP uses.
+#
+
+# Policies to load
+#
+xacml.rootPolicies=sql
+sql.file=src/test/resources/xacml/frequency_limiter_3.xml
+
+# PIP Engine Definition
+#
+xacml.pip.engines=sql1
+
+sql1.classname=com.att.research.xacml.std.pip.engines.jdbc.JDBCEngine
+sql1.name=OperationsHistory
+sql1.description=Database of operations performed via closed loop.
+sql1.issuer=com:att:research:xacml:test:sql123
+sql1.type=jdbc
+sql1.jdbc.driver=org.mariadb.jdbc.Driver
+sql1.jdbc.url=jdbc:mariadb://localhost:7779/policy
+sql1.jdbc.conn.user=root
+sql1.jdbc.conn.password=lmpg
+
+#Each of the following resolvers corresponds to a specific time window. The only difference between them is the "interval" in the "select" SQL query and the "issuer".
+sql1.resolvers=tw10min,tw1h,tw100h
+
+##############################################
+sql1.resolver.tw10min.select=select count(*) as count from operationshistory10 where outcome<>'Failure_Guard' and actor=? and operation=? and target=? and endtime between date_sub(now(),interval 10 minute) and now()
+sql1.resolver.tw10min.field.count.issuer=com:att:research:xacml:test:sql:tw10min
+
+sql1.resolver.tw10min.classname=com.att.research.xacml.std.pip.engines.jdbc.ConfigurableJDBCResolver
+sql1.resolver.tw10min.name=OperationsCount
+sql1.resolver.tw10min.description=This returns the number of previous operations within the given time window
+sql1.resolver.tw10min.fields=count
+sql1.resolver.tw10min.field.count.id=com:att:research:xacml:test:sql:resource:operations:count
+sql1.resolver.tw10min.field.count.datatype=http://www.w3.org/2001/XMLSchema#integer
+sql1.resolver.tw10min.field.count.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+sql1.resolver.tw10min.parameters=actor,operation,target
+sql1.resolver.tw10min.parameter.actor.id=urn:oasis:names:tc:xacml:1.0:actor:actor-id
+sql1.resolver.tw10min.parameter.actor.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.tw10min.parameter.actor.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+sql1.resolver.tw10min.parameter.operation.id=urn:oasis:names:tc:xacml:1.0:operation:operation-id
+sql1.resolver.tw10min.parameter.operation.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.tw10min.parameter.operation.category=urn:oasis:names:tc:xacml:3.0:attribute-category:action
+sql1.resolver.tw10min.parameter.target.id=urn:oasis:names:tc:xacml:1.0:target:target-id
+sql1.resolver.tw10min.parameter.target.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.tw10min.parameter.target.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+
+##############################################
+sql1.resolver.tw1h.select=select count(*) as count from operationshistory10 where actor=? and operation=? and target=? and endtime between date_sub(now(),interval 1 hour) and now()
+sql1.resolver.tw1h.field.count.issuer=com:att:research:xacml:test:sql:tw1h
+
+sql1.resolver.tw1h.classname=com.att.research.xacml.std.pip.engines.jdbc.ConfigurableJDBCResolver
+sql1.resolver.tw1h.name=OperationsCount
+sql1.resolver.tw1h.description=This returns the number of previous operations within the given time window
+sql1.resolver.tw1h.fields=count
+sql1.resolver.tw1h.field.count.id=com:att:research:xacml:test:sql:resource:operations:count
+sql1.resolver.tw1h.field.count.datatype=http://www.w3.org/2001/XMLSchema#integer
+sql1.resolver.tw1h.field.count.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+sql1.resolver.tw1h.parameters=actor,operation,target
+sql1.resolver.tw1h.parameter.actor.id=urn:oasis:names:tc:xacml:1.0:actor:actor-id
+sql1.resolver.tw1h.parameter.actor.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.tw1h.parameter.actor.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+sql1.resolver.tw1h.parameter.operation.id=urn:oasis:names:tc:xacml:1.0:operation:operation-id
+sql1.resolver.tw1h.parameter.operation.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.tw1h.parameter.operation.category=urn:oasis:names:tc:xacml:3.0:attribute-category:action
+sql1.resolver.tw1h.parameter.target.id=urn:oasis:names:tc:xacml:1.0:target:target-id
+sql1.resolver.tw1h.parameter.target.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.tw1h.parameter.target.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+
+
+#############################
+sql1.resolver.tw100h.select=select count(*) as count from operationshistory10 where actor=? and operation=? and target=? and endtime between date_sub(now(),interval 100 hour) and now()
+sql1.resolver.tw100h.field.count.issuer=com:att:research:xacml:test:sql:tw100h
+
+sql1.resolver.tw100h.classname=com.att.research.xacml.std.pip.engines.jdbc.ConfigurableJDBCResolver
+sql1.resolver.tw100h.name=OperationsCount
+sql1.resolver.tw100h.description=This returns the number of previous operations within the given time window
+sql1.resolver.tw100h.fields=count
+sql1.resolver.tw100h.field.count.id=com:att:research:xacml:test:sql:resource:operations:count
+sql1.resolver.tw100h.field.count.datatype=http://www.w3.org/2001/XMLSchema#integer
+sql1.resolver.tw100h.field.count.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+sql1.resolver.tw100h.parameters=actor,operation,target
+sql1.resolver.tw100h.parameter.actor.id=urn:oasis:names:tc:xacml:1.0:actor:actor-id
+sql1.resolver.tw100h.parameter.actor.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.tw100h.parameter.actor.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+sql1.resolver.tw100h.parameter.operation.id=urn:oasis:names:tc:xacml:1.0:operation:operation-id
+sql1.resolver.tw100h.parameter.operation.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.tw100h.parameter.operation.category=urn:oasis:names:tc:xacml:3.0:attribute-category:action
+sql1.resolver.tw100h.parameter.target.id=urn:oasis:names:tc:xacml:1.0:target:target-id
+sql1.resolver.tw100h.parameter.target.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.tw100h.parameter.target.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+
+
diff --git a/controlloop/templates/template.demo/src/test/resources/xacml/xacml_guard.properties b/controlloop/templates/template.demo/src/test/resources/xacml/xacml_guard.properties
new file mode 100644
index 000000000..070258642
--- /dev/null
+++ b/controlloop/templates/template.demo/src/test/resources/xacml/xacml_guard.properties
@@ -0,0 +1,52 @@
+#
+#
+# This files defines PIPs that will be used by XACML Guard Policies. One PIP per time window (5 min, 10min,...,1 month).
+#
+#
+#
+
+#
+# Default XACML Properties File
+# Standard API Factories
+#
+xacml.dataTypeFactory=com.att.research.xacml.std.StdDataTypeFactory
+xacml.pdpEngineFactory=com.att.research.xacmlatt.pdp.ATTPDPEngineFactory
+xacml.pepEngineFactory=com.att.research.xacml.std.pep.StdEngineFactory
+xacml.pipFinderFactory=com.att.research.xacml.std.pip.StdPIPFinderFactory
+xacml.traceEngineFactory=com.att.research.xacml.std.trace.LoggingTraceEngineFactory
+#
+# AT&T PDP Implementation Factories
+#
+xacml.att.evaluationContextFactory=com.att.research.xacmlatt.pdp.std.StdEvaluationContextFactory
+xacml.att.combiningAlgorithmFactory=com.att.research.xacmlatt.pdp.std.StdCombiningAlgorithmFactory
+xacml.att.functionDefinitionFactory=com.att.research.xacmlatt.pdp.std.StdFunctionDefinitionFactory
+xacml.att.policyFinderFactory=com.att.research.xacmlatt.pdp.std.StdPolicyFinderFactory
+
+
+#
+# NOTE: If you are testing against a RESTful PDP, then the PDP must be configured with the
+# policies and PIP configuration as defined below. Otherwise, this is the configuration that
+# the embedded PDP uses.
+#
+
+# In case we have multiple applicable Guard policies, we will deny if any of them denies.
+#xacml.att.policyFinderFactory.combineRootPolicies=urn:com:att:xacml:3.0:policy-combining-algorithm:combined-deny-overrides
+xacml.att.policyFinderFactory.combineRootPolicies=urn:oasis:names:tc:xacml:3.0:policy-combining-algorithm:permit-unless-deny
+
+
+# Policies to load
+#
+xacml.rootPolicies=p1,p2,p3,p4,p5
+p1.file=src/test/resources/xacml/autogenerated_frequency_limiter_restart.xml
+p2.file=src/test/resources/xacml/autogenerated_frequency_limiter_rebuild.xml
+p3.file=src/test/resources/xacml/autogenerated_frequency_limiter_migrate.xml
+p4.file=src/test/resources/xacml/autogenerated_frequency_limiter_rebuild_1.xml
+p5.file=src/test/resources/xacml/autogenerated_blacklist.xml
+
+
+# PIP Engine Definition
+#
+xacml.pip.engines=historydb
+historydb.classname=org.onap.policy.guard.PIPEngineGetHistory
+historydb.issuer=com:att:research:xacml:guard:historydb
+
diff --git a/controlloop/templates/template.demo/src/test/resources/xacml/xacml_guard_old.properties b/controlloop/templates/template.demo/src/test/resources/xacml/xacml_guard_old.properties
new file mode 100644
index 000000000..0f858da8d
--- /dev/null
+++ b/controlloop/templates/template.demo/src/test/resources/xacml/xacml_guard_old.properties
@@ -0,0 +1,277 @@
+#
+#
+# This files defines PIPs that will be used by XACML Guard Policies. One PIP per time window (5 min, 10min,...,1 month).
+#
+#
+#
+
+#
+# Default XACML Properties File
+# Standard API Factories
+#
+xacml.dataTypeFactory=com.att.research.xacml.std.StdDataTypeFactory
+xacml.pdpEngineFactory=com.att.research.xacmlatt.pdp.ATTPDPEngineFactory
+xacml.pepEngineFactory=com.att.research.xacml.std.pep.StdEngineFactory
+xacml.pipFinderFactory=com.att.research.xacml.std.pip.StdPIPFinderFactory
+xacml.traceEngineFactory=com.att.research.xacml.std.trace.LoggingTraceEngineFactory
+#
+# AT&T PDP Implementation Factories
+#
+xacml.att.evaluationContextFactory=com.att.research.xacmlatt.pdp.std.StdEvaluationContextFactory
+xacml.att.combiningAlgorithmFactory=com.att.research.xacmlatt.pdp.std.StdCombiningAlgorithmFactory
+xacml.att.functionDefinitionFactory=com.att.research.xacmlatt.pdp.std.StdFunctionDefinitionFactory
+xacml.att.policyFinderFactory=com.att.research.xacmlatt.pdp.std.StdPolicyFinderFactory
+
+
+#
+# NOTE: If you are testing against a RESTful PDP, then the PDP must be configured with the
+# policies and PIP configuration as defined below. Otherwise, this is the configuration that
+# the embedded PDP uses.
+#
+
+# In case we have multiple applicable Guard policies, we will deny if any of them denies.
+#xacml.att.policyFinderFactory.combineRootPolicies=urn:com:att:xacml:3.0:policy-combining-algorithm:combined-deny-overrides
+xacml.att.policyFinderFactory.combineRootPolicies=urn:oasis:names:tc:xacml:3.0:policy-combining-algorithm:permit-unless-deny
+
+
+# Policies to load
+#
+xacml.rootPolicies=p1,p2,p3,p4
+p1.file=src/test/resources/xacml/autogenerated_frequency_limiter_restart.xml
+p2.file=src/test/resources/xacml/autogenerated_frequency_limiter_rebuild.xml
+p3.file=src/test/resources/xacml/autogenerated_frequency_limiter_migrate.xml
+p4.file=src/test/resources/xacml/autogenerated_frequency_limiter_rebuild_1.xml
+#p5.file=src/test/resources/xacml/autogenerated_blacklist.xml
+#p6.file=src/test/resources/xacml/new_restart1.xml
+#p7.file=src/test/resources/xacml/new_restart2.xml
+#p8.file=src/test/resources/xacml/new_rebuild1.xml
+#p9.file=src/test/resources/xacml/new_rebuild2.xml
+#p10.file=src/test/resources/xacml/new_migrate1.xml
+#p11.file=src/test/resources/xacml/new_migrate2.xml
+
+# PIP Engine Definition
+#
+xacml.pip.engines=sql1,test1
+test1.classname=com.att.ecomp.policy.guard.PIPEngineGetHistory
+test1.issuer=com:att:research:xacml:guard:historydb
+
+
+sql1.classname=com.att.research.xacml.std.pip.engines.jdbc.JDBCEngine
+sql1.name=OperationsHistory
+sql1.description=Database of operations performed via closed loop.
+sql1.issuer=com:att:research:xacml:test:sql123
+sql1.type=jdbc
+sql1.jdbc.driver=org.mariadb.jdbc.Driver
+#sql1.jdbc.url=jdbc:mariadb://localhost:7779/policy
+sql1.jdbc.url=jdbc:mariadb://135.207.129.112:3306/policy
+sql1.jdbc.conn.user=root
+sql1.jdbc.conn.password=lmpg
+
+#Each of the following resolvers corresponds to a specific time window. The only difference between them is the "interval" in the "select" SQL query and the "issuer".
+sql1.resolvers=tw5min,tw10min,tw30min,tw1h,tw12h,tw1d,tw5d,tw1w,tw1mon
+
+
+
+##############################################
+sql1.resolver.tw5min.select=select count(*) as count from operationshistory10 where outcome<>'Failure_Guard' and actor=? and operation=? and target=? and endtime between date_sub(now(),interval 5 minute) and now()
+sql1.resolver.tw5min.field.count.issuer=com:att:research:xacml:test:sql:tw5min
+
+sql1.resolver.tw5min.classname=com.att.research.xacml.std.pip.engines.jdbc.ConfigurableJDBCResolver
+sql1.resolver.tw5min.name=OperationsCount
+sql1.resolver.tw5min.description=This returns the number of previous operations within the given time window
+sql1.resolver.tw5min.fields=count
+sql1.resolver.tw5min.field.count.id=com:att:research:xacml:test:sql:resource:operations:count
+sql1.resolver.tw5min.field.count.datatype=http://www.w3.org/2001/XMLSchema#integer
+sql1.resolver.tw5min.field.count.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+sql1.resolver.tw5min.parameters=actor,operation,target
+sql1.resolver.tw5min.parameter.actor.id=urn:oasis:names:tc:xacml:1.0:actor:actor-id
+sql1.resolver.tw5min.parameter.actor.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.tw5min.parameter.actor.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+sql1.resolver.tw5min.parameter.operation.id=urn:oasis:names:tc:xacml:1.0:operation:operation-id
+sql1.resolver.tw5min.parameter.operation.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.tw5min.parameter.operation.category=urn:oasis:names:tc:xacml:3.0:attribute-category:action
+sql1.resolver.tw5min.parameter.target.id=urn:oasis:names:tc:xacml:1.0:target:target-id
+sql1.resolver.tw5min.parameter.target.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.tw5min.parameter.target.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+
+##############################################
+sql1.resolver.tw10min.select=select count(*) as count from operationshistory10 where outcome<>'Failure_Guard' and actor=? and operation=? and target=? and endtime between date_sub(now(),interval 10 minute) and now()
+sql1.resolver.tw10min.field.count.issuer=com:att:research:xacml:test:sql:tw10min
+
+sql1.resolver.tw10min.classname=com.att.research.xacml.std.pip.engines.jdbc.ConfigurableJDBCResolver
+sql1.resolver.tw10min.name=OperationsCount
+sql1.resolver.tw10min.description=This returns the number of previous operations within the given time window
+sql1.resolver.tw10min.fields=count
+sql1.resolver.tw10min.field.count.id=com:att:research:xacml:test:sql:resource:operations:count
+sql1.resolver.tw10min.field.count.datatype=http://www.w3.org/2001/XMLSchema#integer
+sql1.resolver.tw10min.field.count.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+sql1.resolver.tw10min.parameters=actor,operation,target
+sql1.resolver.tw10min.parameter.actor.id=urn:oasis:names:tc:xacml:1.0:actor:actor-id
+sql1.resolver.tw10min.parameter.actor.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.tw10min.parameter.actor.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+sql1.resolver.tw10min.parameter.operation.id=urn:oasis:names:tc:xacml:1.0:operation:operation-id
+sql1.resolver.tw10min.parameter.operation.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.tw10min.parameter.operation.category=urn:oasis:names:tc:xacml:3.0:attribute-category:action
+sql1.resolver.tw10min.parameter.target.id=urn:oasis:names:tc:xacml:1.0:target:target-id
+sql1.resolver.tw10min.parameter.target.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.tw10min.parameter.target.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+
+##############################################
+sql1.resolver.tw30min.select=select count(*) as count from operationshistory10 where outcome<>'Failure_Guard' and actor=? and operation=? and target=? and endtime between date_sub(now(),interval 30 minute) and now()
+sql1.resolver.tw30min.field.count.issuer=com:att:research:xacml:test:sql:tw30min
+
+sql1.resolver.tw30min.classname=com.att.research.xacml.std.pip.engines.jdbc.ConfigurableJDBCResolver
+sql1.resolver.tw30min.name=OperationsCount
+sql1.resolver.tw30min.description=This returns the number of previous operations within the given time window
+sql1.resolver.tw30min.fields=count
+sql1.resolver.tw30min.field.count.id=com:att:research:xacml:test:sql:resource:operations:count
+sql1.resolver.tw30min.field.count.datatype=http://www.w3.org/2001/XMLSchema#integer
+sql1.resolver.tw30min.field.count.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+sql1.resolver.tw30min.parameters=actor,operation,target
+sql1.resolver.tw30min.parameter.actor.id=urn:oasis:names:tc:xacml:1.0:actor:actor-id
+sql1.resolver.tw30min.parameter.actor.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.tw30min.parameter.actor.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+sql1.resolver.tw30min.parameter.operation.id=urn:oasis:names:tc:xacml:1.0:operation:operation-id
+sql1.resolver.tw30min.parameter.operation.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.tw30min.parameter.operation.category=urn:oasis:names:tc:xacml:3.0:attribute-category:action
+sql1.resolver.tw30min.parameter.target.id=urn:oasis:names:tc:xacml:1.0:target:target-id
+sql1.resolver.tw30min.parameter.target.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.tw30min.parameter.target.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+
+##############################################
+sql1.resolver.tw1h.select=select count(*) as count from operationshistory10 where outcome<>'Failure_Guard' and actor=? and operation=? and target=? and endtime between date_sub(now(),interval 1 hour) and now()
+sql1.resolver.tw1h.field.count.issuer=com:att:research:xacml:test:sql:tw1h
+
+sql1.resolver.tw1h.classname=com.att.research.xacml.std.pip.engines.jdbc.ConfigurableJDBCResolver
+sql1.resolver.tw1h.name=OperationsCount
+sql1.resolver.tw1h.description=This returns the number of previous operations within the given time window
+sql1.resolver.tw1h.fields=count
+sql1.resolver.tw1h.field.count.id=com:att:research:xacml:test:sql:resource:operations:count
+sql1.resolver.tw1h.field.count.datatype=http://www.w3.org/2001/XMLSchema#integer
+sql1.resolver.tw1h.field.count.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+sql1.resolver.tw1h.parameters=actor,operation,target
+sql1.resolver.tw1h.parameter.actor.id=urn:oasis:names:tc:xacml:1.0:actor:actor-id
+sql1.resolver.tw1h.parameter.actor.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.tw1h.parameter.actor.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+sql1.resolver.tw1h.parameter.operation.id=urn:oasis:names:tc:xacml:1.0:operation:operation-id
+sql1.resolver.tw1h.parameter.operation.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.tw1h.parameter.operation.category=urn:oasis:names:tc:xacml:3.0:attribute-category:action
+sql1.resolver.tw1h.parameter.target.id=urn:oasis:names:tc:xacml:1.0:target:target-id
+sql1.resolver.tw1h.parameter.target.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.tw1h.parameter.target.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+
+
+##############################################
+sql1.resolver.tw12h.select=select count(*) as count from operationshistory10 where outcome<>'Failure_Guard' and actor=? and operation=? and target=? and endtime between date_sub(now(),interval 12 hour) and now()
+sql1.resolver.tw12h.field.count.issuer=com:att:research:xacml:test:sql:tw12h
+
+sql1.resolver.tw12h.classname=com.att.research.xacml.std.pip.engines.jdbc.ConfigurableJDBCResolver
+sql1.resolver.tw12h.name=OperationsCount
+sql1.resolver.tw12h.description=This returns the number of previous operations within the given time window
+sql1.resolver.tw12h.fields=count
+sql1.resolver.tw12h.field.count.id=com:att:research:xacml:test:sql:resource:operations:count
+sql1.resolver.tw12h.field.count.datatype=http://www.w3.org/2001/XMLSchema#integer
+sql1.resolver.tw12h.field.count.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+sql1.resolver.tw12h.parameters=actor,operation,target
+sql1.resolver.tw12h.parameter.actor.id=urn:oasis:names:tc:xacml:1.0:actor:actor-id
+sql1.resolver.tw12h.parameter.actor.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.tw12h.parameter.actor.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+sql1.resolver.tw12h.parameter.operation.id=urn:oasis:names:tc:xacml:1.0:operation:operation-id
+sql1.resolver.tw12h.parameter.operation.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.tw12h.parameter.operation.category=urn:oasis:names:tc:xacml:3.0:attribute-category:action
+sql1.resolver.tw12h.parameter.target.id=urn:oasis:names:tc:xacml:1.0:target:target-id
+sql1.resolver.tw12h.parameter.target.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.tw12h.parameter.target.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+
+
+#############################
+sql1.resolver.tw1d.select=select count(*) as count from operationshistory10 where outcome<>'Failure_Guard' and actor=? and operation=? and target=? and endtime between date_sub(now(),interval 1 day) and now()
+sql1.resolver.tw1d.field.count.issuer=com:att:research:xacml:test:sql:tw1d
+
+sql1.resolver.tw1d.classname=com.att.research.xacml.std.pip.engines.jdbc.ConfigurableJDBCResolver
+sql1.resolver.tw1d.name=OperationsCount
+sql1.resolver.tw1d.description=This returns the number of previous operations within the given time window
+sql1.resolver.tw1d.fields=count
+sql1.resolver.tw1d.field.count.id=com:att:research:xacml:test:sql:resource:operations:count
+sql1.resolver.tw1d.field.count.datatype=http://www.w3.org/2001/XMLSchema#integer
+sql1.resolver.tw1d.field.count.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+sql1.resolver.tw1d.parameters=actor,operation,target
+sql1.resolver.tw1d.parameter.actor.id=urn:oasis:names:tc:xacml:1.0:actor:actor-id
+sql1.resolver.tw1d.parameter.actor.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.tw1d.parameter.actor.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+sql1.resolver.tw1d.parameter.operation.id=urn:oasis:names:tc:xacml:1.0:operation:operation-id
+sql1.resolver.tw1d.parameter.operation.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.tw1d.parameter.operation.category=urn:oasis:names:tc:xacml:3.0:attribute-category:action
+sql1.resolver.tw1d.parameter.target.id=urn:oasis:names:tc:xacml:1.0:target:target-id
+sql1.resolver.tw1d.parameter.target.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.tw1d.parameter.target.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+
+
+#############################
+sql1.resolver.tw5d.select=select count(*) as count from operationshistory10 where outcome<>'Failure_Guard' and actor=? and operation=? and target=? and endtime between date_sub(now(),interval 5 day) and now()
+sql1.resolver.tw5d.field.count.issuer=com:att:research:xacml:test:sql:tw5d
+
+sql1.resolver.tw5d.classname=com.att.research.xacml.std.pip.engines.jdbc.ConfigurableJDBCResolver
+sql1.resolver.tw5d.name=OperationsCount
+sql1.resolver.tw5d.description=This returns the number of previous operations within the given time window
+sql1.resolver.tw5d.fields=count
+sql1.resolver.tw5d.field.count.id=com:att:research:xacml:test:sql:resource:operations:count
+sql1.resolver.tw5d.field.count.datatype=http://www.w3.org/2001/XMLSchema#integer
+sql1.resolver.tw5d.field.count.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+sql1.resolver.tw5d.parameters=actor,operation,target
+sql1.resolver.tw5d.parameter.actor.id=urn:oasis:names:tc:xacml:1.0:actor:actor-id
+sql1.resolver.tw5d.parameter.actor.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.tw5d.parameter.actor.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+sql1.resolver.tw5d.parameter.operation.id=urn:oasis:names:tc:xacml:1.0:operation:operation-id
+sql1.resolver.tw5d.parameter.operation.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.tw5d.parameter.operation.category=urn:oasis:names:tc:xacml:3.0:attribute-category:action
+sql1.resolver.tw5d.parameter.target.id=urn:oasis:names:tc:xacml:1.0:target:target-id
+sql1.resolver.tw5d.parameter.target.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.tw5d.parameter.target.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+
+
+#############################
+sql1.resolver.tw1w.select=select count(*) as count from operationshistory10 where outcome<>'Failure_Guard' and actor=? and operation=? and target=? and endtime between date_sub(now(),interval 1 week) and now()
+sql1.resolver.tw1w.field.count.issuer=com:att:research:xacml:test:sql:tw1w
+
+sql1.resolver.tw1w.classname=com.att.research.xacml.std.pip.engines.jdbc.ConfigurableJDBCResolver
+sql1.resolver.tw1w.name=OperationsCount
+sql1.resolver.tw1w.description=This returns the number of previous operations within the given time window
+sql1.resolver.tw1w.fields=count
+sql1.resolver.tw1w.field.count.id=com:att:research:xacml:test:sql:resource:operations:count
+sql1.resolver.tw1w.field.count.datatype=http://www.w3.org/2001/XMLSchema#integer
+sql1.resolver.tw1w.field.count.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+sql1.resolver.tw1w.parameters=actor,operation,target
+sql1.resolver.tw1w.parameter.actor.id=urn:oasis:names:tc:xacml:1.0:actor:actor-id
+sql1.resolver.tw1w.parameter.actor.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.tw1w.parameter.actor.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+sql1.resolver.tw1w.parameter.operation.id=urn:oasis:names:tc:xacml:1.0:operation:operation-id
+sql1.resolver.tw1w.parameter.operation.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.tw1w.parameter.operation.category=urn:oasis:names:tc:xacml:3.0:attribute-category:action
+sql1.resolver.tw1w.parameter.target.id=urn:oasis:names:tc:xacml:1.0:target:target-id
+sql1.resolver.tw1w.parameter.target.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.tw1w.parameter.target.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+
+#############################
+sql1.resolver.tw1mon.select=select count(*) as count from operationshistory10 where outcome<>'Failure_Guard' and actor=? and operation=? and target=? and endtime between date_sub(now(),interval 1 month) and now()
+sql1.resolver.tw1mon.field.count.issuer=com:att:research:xacml:test:sql:tw1mon
+
+sql1.resolver.tw1mon.classname=com.att.research.xacml.std.pip.engines.jdbc.ConfigurableJDBCResolver
+sql1.resolver.tw1mon.name=OperationsCount
+sql1.resolver.tw1mon.description=This returns the number of previous operations within the given time window
+sql1.resolver.tw1mon.fields=count
+sql1.resolver.tw1mon.field.count.id=com:att:research:xacml:test:sql:resource:operations:count
+sql1.resolver.tw1mon.field.count.datatype=http://www.w3.org/2001/XMLSchema#integer
+sql1.resolver.tw1mon.field.count.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+sql1.resolver.tw1mon.parameters=actor,operation,target
+sql1.resolver.tw1mon.parameter.actor.id=urn:oasis:names:tc:xacml:1.0:actor:actor-id
+sql1.resolver.tw1mon.parameter.actor.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.tw1mon.parameter.actor.category=urn:oasis:names:tc:xacml:1.0:subject-category:access-subject
+sql1.resolver.tw1mon.parameter.operation.id=urn:oasis:names:tc:xacml:1.0:operation:operation-id
+sql1.resolver.tw1mon.parameter.operation.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.tw1mon.parameter.operation.category=urn:oasis:names:tc:xacml:3.0:attribute-category:action
+sql1.resolver.tw1mon.parameter.target.id=urn:oasis:names:tc:xacml:1.0:target:target-id
+sql1.resolver.tw1mon.parameter.target.datatype=http://www.w3.org/2001/XMLSchema#string
+sql1.resolver.tw1mon.parameter.target.category=urn:oasis:names:tc:xacml:3.0:attribute-category:resource
+
+
diff --git a/controlloop/templates/template.demo/src/test/resources/yaml/policy_ControlLoop_vUSP_1707.yaml b/controlloop/templates/template.demo/src/test/resources/yaml/policy_ControlLoop_vUSP_1707.yaml
new file mode 100644
index 000000000..62bf986bd
--- /dev/null
+++ b/controlloop/templates/template.demo/src/test/resources/yaml/policy_ControlLoop_vUSP_1707.yaml
@@ -0,0 +1,68 @@
+controlLoop:
+ version: 1.0.0
+ controlLoopName: ControlLoop-vUSP-vCTS-cbed919f-2212-4ef7-8051-fe6308da1bda
+ services:
+ - serviceName: vUSP
+ resources:
+ - resourceName: vCTS
+ resourceType: VF
+ - resourceName: vCOM
+ resourceType: VF
+ - resourceName: vRAR
+ resourceType: VF
+ - resourceName: vLCS
+ resourceType: VF
+ - resourceName: v3CB
+ resourceType: VF
+ trigger_policy: unique-policy-id-1-restart
+ timeout: 60
+ abatement: true
+
+policies:
+ - id: unique-policy-id-1-restart
+ name: Restart Policy
+ description:
+ actor: APPC
+ recipe: Restart
+ target:
+ type: VM
+ retry: 3
+ timeout: 20
+ success: final_success
+ failure: unique-policy-id-2-rebuild
+ failure_timeout: unique-policy-id-2-rebuild
+ failure_retries: unique-policy-id-2-rebuild
+ failure_guard: unique-policy-id-2-rebuild
+ failure_exception: final_failure_exception
+
+ - id: unique-policy-id-2-rebuild
+ name: Rebuild Policy
+ description:
+ actor: APPC
+ recipe: Rebuild
+ target:
+ type: VM
+ retry: 0
+ timeout: 10
+ success: final_success
+ failure: unique-policy-id-3-migrate
+ failure_timeout: unique-policy-id-3-migrate
+ failure_retries: unique-policy-id-3-migrate
+ failure_guard: unique-policy-id-3-migrate
+ failure_exception: final_failure_exception
+
+ - id: unique-policy-id-3-migrate
+ name: Migrate Policy
+ description:
+ actor: APPC
+ recipe: Migrate
+ target:
+ type: VM
+ retry: 0
+ timeout: 30
+ success: final_success
+ failure: final_failure
+ failure_timeout: final_failure_timeout
+ failure_retries: final_failure_retries
+ failure_guard: final_failure_guard
+ failure_exception: final_failure_exception
diff --git a/controlloop/templates/template.demo/src/test/resources/yaml/policy_guard_vUSP_1707_appc_migrate.yaml b/controlloop/templates/template.demo/src/test/resources/yaml/policy_guard_vUSP_1707_appc_migrate.yaml
new file mode 100644
index 000000000..333895b2e
--- /dev/null
+++ b/controlloop/templates/template.demo/src/test/resources/yaml/policy_guard_vUSP_1707_appc_migrate.yaml
@@ -0,0 +1,24 @@
+guard:
+ version: 2.0.0
+
+guards:
+ - id: unique_guard_vUSP_1
+ name: APPC 5 Migrate
+ description: |
+ We only allow 2 restarts over 10 minute window during the day time hours (avoid midnight to 5am)
+ actor: APPC
+ recipe: Migrate
+ limit_constraints:
+ - num: 1
+ duration:
+ value: 10
+ units: minute
+ time_in_range:
+ arg2: 00:00:00-05:00
+ arg3: 23:59:59-05:00
+
+
+
+
+
+ \ No newline at end of file
diff --git a/controlloop/templates/template.demo/src/test/resources/yaml/policy_guard_vUSP_1707_appc_rebuild.yaml b/controlloop/templates/template.demo/src/test/resources/yaml/policy_guard_vUSP_1707_appc_rebuild.yaml
new file mode 100644
index 000000000..865915f82
--- /dev/null
+++ b/controlloop/templates/template.demo/src/test/resources/yaml/policy_guard_vUSP_1707_appc_rebuild.yaml
@@ -0,0 +1,24 @@
+guard:
+ version: 2.0.0
+
+guards:
+ - id: unique_guard_vUSP_1
+ name: APPC 5 Rebuild
+ description: |
+ We only allow 2 restarts over 10 minute window during the day time hours (avoid midnight to 5am)
+ actor: APPC
+ recipe: Rebuild
+ limit_constraints:
+ - num: 2
+ duration:
+ value: 10
+ units: minute
+ time_in_range:
+ arg2: 00:00:00-05:00
+ arg3: 23:59:59-05:00
+
+
+
+
+
+ \ No newline at end of file
diff --git a/controlloop/templates/template.demo/src/test/resources/yaml/policy_guard_vUSP_1707_appc_rebuild_1.yaml b/controlloop/templates/template.demo/src/test/resources/yaml/policy_guard_vUSP_1707_appc_rebuild_1.yaml
new file mode 100644
index 000000000..6905d733f
--- /dev/null
+++ b/controlloop/templates/template.demo/src/test/resources/yaml/policy_guard_vUSP_1707_appc_rebuild_1.yaml
@@ -0,0 +1,24 @@
+guard:
+ version: 2.0.0
+
+guards:
+ - id: unique_guard_vUSP_1
+ name: APPC 5 Rebuild
+ description: |
+ We only allow 2 restarts over 10 minute window during the day time hours (avoid midnight to 5am)
+ actor: APPC
+ recipe: Rebuild
+ limit_constraints:
+ - num: 25
+ duration:
+ value: 1
+ units: week
+ time_in_range:
+ arg2: 00:00:00-05:00
+ arg3: 23:59:59-05:00
+
+
+
+
+
+ \ No newline at end of file
diff --git a/controlloop/templates/template.demo/src/test/resources/yaml/policy_guard_vUSP_1707_appc_restart.yaml b/controlloop/templates/template.demo/src/test/resources/yaml/policy_guard_vUSP_1707_appc_restart.yaml
new file mode 100644
index 000000000..b44ff00df
--- /dev/null
+++ b/controlloop/templates/template.demo/src/test/resources/yaml/policy_guard_vUSP_1707_appc_restart.yaml
@@ -0,0 +1,24 @@
+guard:
+ version: 2.0.0
+
+guards:
+ - id: unique_guard_vUSP_1
+ name: APPC 5 Restart
+ description: |
+ We only allow 2 restarts over 10 minute window during the day time hours (avoid midnight to 5am)
+ actor: APPC
+ recipe: Restart
+ limit_constraints:
+ - num: 2
+ duration:
+ value: 10
+ units: minute
+ time_in_range:
+ arg2: 00:00:00-05:00
+ arg3: 23:59:59-05:00
+
+
+
+
+
+ \ No newline at end of file
diff --git a/controlloop/templates/template.demo/src/test/resources/yaml/policy_guard_vUSP_1707_appc_restart_blacklist.yaml b/controlloop/templates/template.demo/src/test/resources/yaml/policy_guard_vUSP_1707_appc_restart_blacklist.yaml
new file mode 100644
index 000000000..50af17af6
--- /dev/null
+++ b/controlloop/templates/template.demo/src/test/resources/yaml/policy_guard_vUSP_1707_appc_restart_blacklist.yaml
@@ -0,0 +1,26 @@
+guard:
+ version: 2.0.0
+
+guards:
+ - id: unique_guard_vUSP_1_Blacklist
+ name: APPC Restart Blacklist
+ description: |
+ We deny restart of the blacklisted targets (avoid midnight to 5am)
+ actor: APPC
+ recipe: Restart
+ limit_constraints:
+ - blacklist:
+ - server123
+ - server2234
+ - vserver.vserver-name22
+ - aaabbbccc
+ - foobartriggersource35
+ time_in_range:
+ arg2: 00:00:00-05:00
+ arg3: 23:59:59-05:00
+
+
+
+
+
+ \ No newline at end of file