summaryrefslogtreecommitdiffstats
path: root/controlloop/templates/template.demo/src
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/template.demo/src
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/template.demo/src')
-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
23 files changed, 4694 insertions, 0 deletions
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