[POLICY-73] replace openecomp for policy-engine

Change-Id: I54072f6bcd388c0e05562614ee89b4ae7ad67004
Signed-off-by: Guo Ruijing <ruijing.guo@intel.com>
Signed-off-by: Pamela Dragosh <pdragosh@research.att.com>
diff --git a/ONAP-ControlloopPolicy/pom.xml b/ONAP-ControlloopPolicy/pom.xml
new file mode 100644
index 0000000..2c973cf
--- /dev/null
+++ b/ONAP-ControlloopPolicy/pom.xml
@@ -0,0 +1,62 @@
+<!--
+  ============LICENSE_START=======================================================
+  ONAP Policy Engine
+  ================================================================================
+  Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+  ================================================================================
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+  
+       http://www.apache.org/licenses/LICENSE-2.0
+  
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  ============LICENSE_END=========================================================
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<artifactId>ControlloopPolicy</artifactId>
+	<parent>
+		<groupId>org.onap.policy.engine</groupId>
+		<artifactId>PolicyEngineSuite</artifactId>
+		<version>1.1.0-SNAPSHOT</version>
+	</parent>
+	<dependencies>
+		<dependency>
+			<groupId>org.onap.policy.engine</groupId>
+			<artifactId>asdc</artifactId>
+			<version>${project.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>junit</groupId>
+			<artifactId>junit</artifactId>
+			<version>4.12</version>
+			<scope>provided</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.yaml</groupId>
+			<artifactId>snakeyaml</artifactId>
+			<version>1.17</version>
+		</dependency>
+		<dependency>
+			<groupId>org.jgrapht</groupId>
+			<artifactId>jgrapht-core</artifactId>
+			<version>0.9.2</version>
+		</dependency>
+		<dependency>
+			<groupId>com.google.guava</groupId>
+			<artifactId>guava</artifactId>
+			<version>19.0</version>
+		</dependency>
+		<dependency>
+			<groupId>org.onap.policy.common</groupId>
+			<artifactId>ONAP-Logging</artifactId>
+			<version>${common-modules.version}</version>
+		</dependency>
+	</dependencies>
+</project>
diff --git a/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/compiler/CompilerException.java b/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/compiler/CompilerException.java
new file mode 100644
index 0000000..4a86b3b
--- /dev/null
+++ b/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/compiler/CompilerException.java
@@ -0,0 +1,47 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP Policy Engine
+ * ================================================================================
+ * 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.compiler;
+
+public class CompilerException extends Exception {
+
+	private static final long serialVersionUID = -7262217239867898601L;
+
+	public CompilerException() {
+		//Empty Constructor
+	}
+
+	public CompilerException(String message) {
+		super(message);
+	}
+
+	public CompilerException(Throwable cause) {
+		super(cause);
+	}
+
+	public CompilerException(String message, Throwable cause) {
+		super(message, cause);
+	}
+
+	public CompilerException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
+		super(message, cause, enableSuppression, writableStackTrace);
+	}
+
+}
diff --git a/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/compiler/ControlLoopCompiler.java b/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/compiler/ControlLoopCompiler.java
new file mode 100644
index 0000000..18f56d5
--- /dev/null
+++ b/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/compiler/ControlLoopCompiler.java
@@ -0,0 +1,617 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP Policy Engine
+ * ================================================================================
+ * 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.compiler;
+
+import java.io.InputStream;
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.jgrapht.DirectedGraph;
+import org.jgrapht.graph.ClassBasedEdgeFactory;
+import org.jgrapht.graph.DefaultEdge;
+import org.jgrapht.graph.DirectedMultigraph;
+import org.onap.policy.common.logging.flexlogger.FlexLogger;
+import org.onap.policy.common.logging.flexlogger.Logger;
+import org.onap.policy.controlloop.policy.ControlLoop;
+import org.onap.policy.controlloop.policy.ControlLoopPolicy;
+import org.onap.policy.controlloop.policy.FinalResult;
+import org.onap.policy.controlloop.policy.Policy;
+import org.onap.policy.controlloop.policy.PolicyResult;
+import org.onap.policy.controlloop.policy.TargetType;
+import org.yaml.snakeyaml.Yaml;
+import org.yaml.snakeyaml.constructor.Constructor;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+
+public class ControlLoopCompiler implements Serializable{
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+	private static Logger LOGGER = FlexLogger.getLogger(ControlLoopCompiler.class.getName());
+	
+	public static ControlLoopPolicy compile(ControlLoopPolicy policy, ControlLoopCompilerCallback callback) throws CompilerException {
+		//
+		// Ensure the control loop is sane
+		//
+		validateControlLoop(policy.getControlLoop(), callback);
+		//
+		// Validate the policies
+		//
+		validatePolicies(policy, callback);
+		
+		return policy;
+	}
+	
+	public static ControlLoopPolicy	compile(InputStream yamlSpecification, ControlLoopCompilerCallback callback) throws CompilerException {
+		Yaml yaml = new Yaml(new Constructor(ControlLoopPolicy.class));
+		Object obj = yaml.load(yamlSpecification);
+		if (obj == null) {
+			throw new CompilerException("Could not parse yaml specification.");
+		}
+		if (! (obj instanceof ControlLoopPolicy)) {
+			throw new CompilerException("Yaml could not parse specification into required ControlLoopPolicy object");
+		}
+		return ControlLoopCompiler.compile((ControlLoopPolicy) obj, callback);
+	}
+	
+	private static void validateControlLoop(ControlLoop controlLoop, ControlLoopCompilerCallback callback) throws CompilerException {
+		if (controlLoop == null && callback != null) {
+			callback.onError("controlLoop cannot be null");
+		}
+		if (controlLoop!=null){
+			if ((controlLoop.getControlLoopName() == null || controlLoop.getControlLoopName().length() < 1) && callback != null) {
+				callback.onError("Missing controlLoopName");
+			}
+			if ((!controlLoop.getVersion().contentEquals(ControlLoop.getVERSION())) && callback != null) {
+				callback.onError("Unsupported version for this compiler");
+			}
+			if (controlLoop.getTrigger_policy() == null || controlLoop.getTrigger_policy().length() < 1) {
+				throw new CompilerException("trigger_policy is not valid");
+			}
+		}
+	}
+
+	private static void validatePolicies(ControlLoopPolicy policy, ControlLoopCompilerCallback callback) throws CompilerException {
+		if (policy == null) {
+			throw new CompilerException("policy cannot be null");
+		}
+		//
+		// verify controlLoop overall timeout should be no less than the sum of operational policy timeouts
+		//
+		if (policy.getPolicies() == null) {
+            callback.onWarning("controlLoop is an open loop.");   
+        }
+        else{
+            int sum = 0;
+		    for (Policy operPolicy : policy.getPolicies()) {
+		    	sum += operPolicy.getTimeout().intValue();
+		    }
+		    if (policy.getControlLoop().getTimeout().intValue() < sum && callback != null) {
+		    	callback.onError("controlLoop overall timeout is less than the sum of operational policy timeouts.");
+		    }
+		    //
+		    // For this version we can use a directed multigraph, in the future we may not be able to
+		    //
+		    DirectedGraph<NodeWrapper, LabeledEdge> graph = new DirectedMultigraph<>(new ClassBasedEdgeFactory<NodeWrapper, LabeledEdge>(LabeledEdge.class));
+		    //
+		    // Check to see if the trigger Event is for OpenLoop, we do so by
+		    // attempting to create a FinalResult object from it. If its a policy id, this should
+		    // return null.
+		    //
+		    FinalResult triggerResult = FinalResult.toResult(policy.getControlLoop().getTrigger_policy());
+		    TriggerNodeWrapper triggerNode;
+		    //
+		    // Did this turn into a FinalResult object?
+		    //
+		    if (triggerResult != null) {
+		    	//
+		    	// Ensure they didn't use some other FinalResult code
+		    	//
+		    	if (triggerResult != FinalResult.FINAL_OPENLOOP) {
+		    		throw new CompilerException("Unexpected Final Result for trigger_policy, should only be " + FinalResult.FINAL_OPENLOOP.toString() + " or a valid Policy ID");
+		    	}
+		    	//
+		    	// They really shouldn't have any policies attached.
+		    	//
+		    	if ((policy.getPolicies() != null || policy.getPolicies().isEmpty())&& callback != null ) {
+		    		callback.onWarning("Open Loop policy contains policies. The policies will never be invoked.");
+		    	}
+		    	return;
+		    	//
+		    } else {
+		    	//
+		    	// Ok, not a FinalResult object so let's assume that it is a Policy. Which it should be.
+		    	//
+		    	triggerNode = new TriggerNodeWrapper(policy.getControlLoop().getControlLoopName());
+		    }
+		    //
+		    // Add in the trigger node
+		    //
+		    graph.addVertex(triggerNode);
+		    //
+		    // Add in our Final Result nodes. All paths should end to these nodes.
+		    //
+		    FinalResultNodeWrapper finalSuccess = new FinalResultNodeWrapper(FinalResult.FINAL_SUCCESS);
+		    FinalResultNodeWrapper finalFailure = new FinalResultNodeWrapper(FinalResult.FINAL_FAILURE);
+		    FinalResultNodeWrapper finalFailureTimeout = new FinalResultNodeWrapper(FinalResult.FINAL_FAILURE_TIMEOUT);
+		    FinalResultNodeWrapper finalFailureRetries = new FinalResultNodeWrapper(FinalResult.FINAL_FAILURE_RETRIES);
+		    FinalResultNodeWrapper finalFailureException = new FinalResultNodeWrapper(FinalResult.FINAL_FAILURE_EXCEPTION);
+		    FinalResultNodeWrapper finalFailureGuard = new FinalResultNodeWrapper(FinalResult.FINAL_FAILURE_GUARD);
+		    graph.addVertex(finalSuccess);
+		    graph.addVertex(finalFailure);
+		    graph.addVertex(finalFailureTimeout);
+		    graph.addVertex(finalFailureRetries);
+		    graph.addVertex(finalFailureException);
+		    graph.addVertex(finalFailureGuard);
+		    //
+		    // Work through the policies and add them in as nodes.
+		    //
+		    Map<Policy, PolicyNodeWrapper> mapNodes = new HashMap<>();
+		    for (Policy operPolicy : policy.getPolicies()) {
+		    	//
+		    	// Is it still ok to add?
+		    	//
+		    	if (!okToAdd(operPolicy, callback)) {
+		    		//
+		    		// Do not add it in
+		    		//
+		    		continue;
+		    	}
+		    	//
+		    	// Create wrapper policy node and save it into our map so we can
+		    	// easily retrieve it.
+		    	//
+		    	PolicyNodeWrapper node = new PolicyNodeWrapper(operPolicy);
+		    	mapNodes.put(operPolicy, node);
+		    	graph.addVertex(node);
+		    	//
+		    	// Is this the trigger policy?
+		    	//
+		    	if (operPolicy.getId().equals(policy.getControlLoop().getTrigger_policy())) {
+		    		//
+		    		// Yes add an edge from our trigger event node to this policy
+		    		//
+		    		graph.addEdge(triggerNode, node, new LabeledEdge(triggerNode, node, new TriggerEdgeWrapper("ONSET")));
+		    	}
+		    }
+		    //
+		    // last sweep to connect remaining edges for policy results
+		    //
+		    for (Policy operPolicy : policy.getPolicies()) {
+		    	PolicyNodeWrapper node = mapNodes.get(operPolicy);
+		    	//
+		    	// Just ensure this has something
+		    	//
+		    	if (node == null) {
+		    		continue;
+		    	}
+	    		if (FinalResult.isResult(operPolicy.getSuccess(), FinalResult.FINAL_SUCCESS)) {
+	    			graph.addEdge(node, finalSuccess, new LabeledEdge(node, finalSuccess, new FinalResultEdgeWrapper(FinalResult.FINAL_SUCCESS)));
+	    		} else {
+	    			PolicyNodeWrapper toNode = findPolicyNode(mapNodes, operPolicy.getSuccess());
+	    			if (toNode == null) {
+	    				throw new CompilerException("Operation Policy " + operPolicy.getId() + " success is connected to unknown policy " + operPolicy.getSuccess());
+	    			} else {
+	    			 graph.addEdge(node, toNode, new LabeledEdge(node, toNode, new PolicyResultEdgeWrapper(PolicyResult.SUCCESS)));
+	    			}
+	    		}
+	    		if (FinalResult.isResult(operPolicy.getFailure(), FinalResult.FINAL_FAILURE)) {
+	    			graph.addEdge(node, finalFailure, new LabeledEdge(node, finalFailure, new FinalResultEdgeWrapper(FinalResult.FINAL_FAILURE)));
+	    		} else {
+	    			PolicyNodeWrapper toNode = findPolicyNode(mapNodes, operPolicy.getFailure());
+	    			if (toNode == null) {
+	    				throw new CompilerException("Operation Policy " + operPolicy.getId() + " failure is connected to unknown policy " + operPolicy.getFailure());
+	    			} else {
+	    				graph.addEdge(node, toNode, new LabeledEdge(node, toNode, new PolicyResultEdgeWrapper(PolicyResult.FAILURE)));
+	    			}
+	    		}
+	    		if (FinalResult.isResult(operPolicy.getFailure_timeout(), FinalResult.FINAL_FAILURE_TIMEOUT)) {
+	    			graph.addEdge(node, finalFailureTimeout, new LabeledEdge(node, finalFailureTimeout, new FinalResultEdgeWrapper(FinalResult.FINAL_FAILURE_TIMEOUT)));
+	    		} else {
+	    			PolicyNodeWrapper toNode = findPolicyNode(mapNodes, operPolicy.getFailure_timeout());
+	    			if (toNode == null) {
+	    				throw new CompilerException("Operation Policy " + operPolicy.getId() + " failure_timeout is connected to unknown policy " + operPolicy.getFailure_timeout());
+	    			} else {
+	    				graph.addEdge(node, toNode, new LabeledEdge(node, toNode, new PolicyResultEdgeWrapper(PolicyResult.FAILURE_TIMEOUT)));
+	    			}
+	    		}
+	    		if (FinalResult.isResult(operPolicy.getFailure_retries(), FinalResult.FINAL_FAILURE_RETRIES)) {
+	    			graph.addEdge(node, finalFailureRetries, new LabeledEdge(node, finalFailureRetries, new FinalResultEdgeWrapper(FinalResult.FINAL_FAILURE_RETRIES)));
+	    		} else {
+	    			PolicyNodeWrapper toNode = findPolicyNode(mapNodes, operPolicy.getFailure_retries());
+	    			if (toNode == null) {
+	    				throw new CompilerException("Operation Policy " + operPolicy.getId() + " failure_retries is connected to unknown policy " + operPolicy.getFailure_retries());
+	    			} else {
+	    				graph.addEdge(node, toNode, new LabeledEdge(node, toNode, new PolicyResultEdgeWrapper(PolicyResult.FAILURE_RETRIES)));
+	    			}
+	    		}
+	    		if (FinalResult.isResult(operPolicy.getFailure_exception(), FinalResult.FINAL_FAILURE_EXCEPTION)) {
+	    			graph.addEdge(node, finalFailureException, new LabeledEdge(node, finalFailureException, new FinalResultEdgeWrapper(FinalResult.FINAL_FAILURE_EXCEPTION)));
+	    		} else {
+	    			PolicyNodeWrapper toNode = findPolicyNode(mapNodes, operPolicy.getFailure_exception());
+	    			if (toNode == null) {
+	    				throw new CompilerException("Operation Policy " + operPolicy.getId() + " failure_exception is connected to unknown policy " + operPolicy.getFailure_exception());
+	    			} else {
+	    				graph.addEdge(node, toNode, new LabeledEdge(node, toNode, new PolicyResultEdgeWrapper(PolicyResult.FAILURE_EXCEPTION)));
+	    			}
+	    		}
+	    		if (FinalResult.isResult(operPolicy.getFailure_guard(), FinalResult.FINAL_FAILURE_GUARD)) {
+	    			graph.addEdge(node, finalFailureGuard, new LabeledEdge(node, finalFailureGuard, new FinalResultEdgeWrapper(FinalResult.FINAL_FAILURE_GUARD)));
+	    		} else {
+	    			PolicyNodeWrapper toNode = findPolicyNode(mapNodes, operPolicy.getFailure_guard());
+	    			if (toNode == null) {
+	    				throw new CompilerException("Operation Policy " + operPolicy.getId() + " failure_guard is connected to unknown policy " + operPolicy.getFailure_guard());
+	    			} else {
+	    				graph.addEdge(node, toNode, new LabeledEdge(node, toNode, new PolicyResultEdgeWrapper(PolicyResult.FAILURE_GUARD)));
+	    			}
+	    		}
+	    	}
+		    //
+		    // Now validate all the nodes/edges
+		    //
+		    for (NodeWrapper node : graph.vertexSet()) {
+		    	if (node instanceof TriggerNodeWrapper) {
+		    		LOGGER.info("Trigger Node " + node.toString());
+		    		if (graph.inDegreeOf(node) > 0 ) {
+		    			//
+		    			// Really should NEVER get here unless someone messed up the code above.
+		    			//
+		    			throw new CompilerException("No inputs to event trigger");
+		    		}
+		    		//
+		    		// Should always be 1, except in the future we may support multiple events
+		    		//
+		    		if (graph.outDegreeOf(node) > 1) {
+		    			throw new CompilerException("The event trigger should only go to ONE node");
+		    		}
+		    	} else if (node instanceof FinalResultNodeWrapper) {
+		    		LOGGER.info("FinalResult Node " + node.toString());
+		    		//
+		    		// FinalResult nodes should NEVER have an out edge
+		    		//
+		    		if (graph.outDegreeOf(node) > 0) {
+		    			throw new CompilerException("FinalResult nodes should never have any out edges.");
+		    		}
+		    	} else if (node instanceof PolicyNodeWrapper) {
+		    		LOGGER.info("Policy Node " + node.toString());
+		    		//
+		    		// All Policy Nodes should have the 5 out degrees defined.
+		    		//
+		    		if (graph.outDegreeOf(node) != 6) {
+		    			throw new CompilerException("Policy node should ALWAYS have 6 out degrees.");
+		    		}
+		    		//
+		    		// All Policy Nodes should have at least 1 in degrees 
+		    		// 
+		    		if (graph.inDegreeOf(node) == 0 && callback != null) {
+		    			callback.onWarning("Policy " + node.getID() + " is not reachable.");
+		    		}
+		    	}
+		    	for (LabeledEdge edge : graph.outgoingEdgesOf(node)){
+		    		LOGGER.info(edge.from.getID() + " invokes " + edge.to.getID() + " upon " + edge.edge.getID());
+		    	}
+		    }
+	    }	
+	}
+	
+	private static boolean okToAdd(Policy operPolicy, ControlLoopCompilerCallback callback) {
+		//
+    	// Check the policy id and make sure its sane
+    	//
+    	boolean okToAdd = true;
+    	if (operPolicy.getId() == null || operPolicy.getId().length() < 1) {
+    		if (callback != null) {
+    			callback.onError("Operational Policy has an bad ID");
+    		}
+    		okToAdd = false;
+    	}
+    	//
+    	// Check if they decided to make the ID a result object
+    	//
+    	if (PolicyResult.toResult(operPolicy.getId()) != null) {
+    		if (callback != null) {
+    			callback.onError("Policy id is set to a PolicyResult " + operPolicy.getId());
+    		}
+    		okToAdd = false;
+    	}
+    	if (FinalResult.toResult(operPolicy.getId()) != null) {
+    		if (callback != null) {
+    			callback.onError("Policy id is set to a FinalResult " + operPolicy.getId());
+    		}
+    		okToAdd = false;
+    	}
+    	//
+    	// Check that the actor/recipe/target are valid
+    	// 
+    	if (operPolicy.getActor() == null) {
+    		if (callback != null) {
+    			callback.onError("Policy actor is null");
+    		}
+    		okToAdd = false;
+    	}
+    	//
+    	// Construct a list for all valid actors
+    	//
+    	ImmutableList<String> actors = ImmutableList.of("APPC", "AOTS", "MSO", "SDNO", "SDNR", "AAI");
+    	//
+    	if (operPolicy.getActor() != null && (!actors.contains(operPolicy.getActor())) ) {
+    		if (callback != null) {
+    			callback.onError("Policy actor is invalid");
+    		}
+    		okToAdd = false;
+    	}
+    	if (operPolicy.getRecipe() == null) {
+    		if (callback != null) {
+    			callback.onError("Policy recipe is null");
+    		}
+    		okToAdd = false;
+    	}
+    	//
+    	// NOTE: We need a way to find the acceptable recipe values (either Enum or a database that has these)
+    	// 
+    	ImmutableMap<String, List<String>> recipes = new ImmutableMap.Builder<String, List<String>>()
+				.put("APPC", ImmutableList.of("Restart", "Rebuild", "Migrate", "ModifyConfig"))
+    			.put("AOTS", ImmutableList.of("checkMaintenanceWindow", "checkENodeBTicketHours", "checkEquipmentStatus", "checkEimStatus", "checkEquipmentMaintenance"))
+    			.put("MSO", ImmutableList.of("VF Module Create"))
+    			.put("SDNO", ImmutableList.of("health-diagnostic-type", "health-diagnostic", "health-diagnostic-history", "health-diagnostic-commands", "health-diagnostic-aes"))
+    			.put("SDNR", ImmutableList.of("Restart", "Reboot"))
+    			.build();
+    	//
+    	if (operPolicy.getRecipe() != null && (!recipes.getOrDefault(operPolicy.getActor(), Collections.emptyList()).contains(operPolicy.getRecipe()))) {
+    		if (callback != null) {
+    			callback.onError("Policy recipe is invalid");
+    		}
+    		okToAdd = false;
+    	}
+    	if (operPolicy.getTarget() == null) {
+    		if (callback != null) {
+    			callback.onError("Policy target is null");
+    		}
+    		okToAdd = false;
+    	}
+    	if (operPolicy.getTarget() != null && operPolicy.getTarget().getType() != TargetType.VM && operPolicy.getTarget().getType() != TargetType.VFC && operPolicy.getTarget().getType() != TargetType.PNF) {
+    		if (callback != null) {
+    			callback.onError("Policy target is invalid");
+    		}
+    		okToAdd = false;
+    	}
+    	//
+    	// Check that policy results are connected to either default final * or another policy
+    	//
+    	if (FinalResult.toResult(operPolicy.getSuccess()) != null && operPolicy.getSuccess() != FinalResult.FINAL_SUCCESS.toString()) {
+    		if (callback != null) {
+    			callback.onError("Policy success is neither another policy nor FINAL_SUCCESS");
+    		}
+    		okToAdd = false;
+    	}
+    	if (FinalResult.toResult(operPolicy.getFailure()) != null && operPolicy.getFailure() != FinalResult.FINAL_FAILURE.toString()) {
+    		if (callback != null) {
+    			callback.onError("Policy failure is neither another policy nor FINAL_FAILURE");
+    		}
+    		okToAdd = false;
+    	}
+    	if (FinalResult.toResult(operPolicy.getFailure_retries()) != null && operPolicy.getFailure_retries() != FinalResult.FINAL_FAILURE_RETRIES.toString()) {
+    		if (callback != null) {
+    			callback.onError("Policy failure retries is neither another policy nor FINAL_FAILURE_RETRIES");
+    		}
+    		okToAdd = false;
+    	}
+    	if (FinalResult.toResult(operPolicy.getFailure_timeout()) != null && operPolicy.getFailure_timeout() != FinalResult.FINAL_FAILURE_TIMEOUT.toString()) {
+    		if (callback != null) {
+    			callback.onError("Policy failure timeout is neither another policy nor FINAL_FAILURE_TIMEOUT");
+    		}
+    		okToAdd = false;
+    	}
+    	if (FinalResult.toResult(operPolicy.getFailure_exception()) != null && operPolicy.getFailure_exception() != FinalResult.FINAL_FAILURE_EXCEPTION.toString()) {
+    		if (callback != null) {
+    			callback.onError("Policy failure exception is neither another policy nor FINAL_FAILURE_EXCEPTION");
+    		}
+    		okToAdd = false;
+    	}
+    	if (FinalResult.toResult(operPolicy.getFailure_guard()) != null && operPolicy.getFailure_guard() != FinalResult.FINAL_FAILURE_GUARD.toString()) {
+    		if (callback != null) {
+    			callback.onError("Policy failure guard is neither another policy nor FINAL_FAILURE_GUARD");
+    		}
+    		okToAdd = false;
+    	}
+    	return okToAdd;
+	}
+
+	private static PolicyNodeWrapper findPolicyNode(Map<Policy, PolicyNodeWrapper> mapNodes, String id) {
+		for (Entry<Policy, PolicyNodeWrapper> entry : mapNodes.entrySet()) {
+			if (entry.getKey().getId().equals(id)) {
+				return entry.getValue();
+			}
+		}
+		return null;
+	}
+	
+	@FunctionalInterface
+	private interface NodeWrapper extends Serializable{
+		public String	getID();
+	}
+	
+	private static class TriggerNodeWrapper implements NodeWrapper {
+		private static final long serialVersionUID = -187644087811478349L;
+		private String closedLoopControlName;
+		
+		public TriggerNodeWrapper(String closedLoopControlName) {
+			this.closedLoopControlName = closedLoopControlName;
+		}
+
+		@Override
+		public String toString() {
+			return "TriggerNodeWrapper [closedLoopControlName=" + closedLoopControlName + "]";
+		}
+
+		@Override
+		public String getID() {
+			return closedLoopControlName;
+		}
+		
+	}
+		
+	private static class FinalResultNodeWrapper implements NodeWrapper {
+		private static final long serialVersionUID = 8540008796302474613L;
+		private FinalResult result;
+
+		public FinalResultNodeWrapper(FinalResult result) {
+			this.result = result;
+		}
+
+		@Override
+		public String toString() {
+			return "FinalResultNodeWrapper [result=" + result + "]";
+		}
+
+		@Override
+		public String getID() {
+			return result.toString();
+		}
+	}
+	
+	private static class PolicyNodeWrapper implements NodeWrapper {
+		private static final long serialVersionUID = 8170162175653823082L;
+		private Policy policy;
+		
+		public PolicyNodeWrapper(Policy operPolicy) {
+			this.policy = operPolicy;
+		}
+
+		@Override
+		public String toString() {
+			return "PolicyNodeWrapper [policy=" + policy + "]";
+		}
+
+		@Override
+		public String getID() {
+			return policy.getId();
+		}
+	}
+	
+	@FunctionalInterface
+	private interface EdgeWrapper extends Serializable{
+		public String getID();
+		
+	}
+	
+	private static class TriggerEdgeWrapper implements EdgeWrapper {
+		private static final long serialVersionUID = 2678151552623278863L;
+		private String trigger;
+		
+		public TriggerEdgeWrapper(String trigger) {
+			this.trigger = trigger;
+		}
+
+		@Override
+		public String getID() {
+			return trigger;
+		}
+
+		@Override
+		public String toString() {
+			return "TriggerEdgeWrapper [trigger=" + trigger + "]";
+		}
+		
+	}
+	
+	private static class PolicyResultEdgeWrapper implements EdgeWrapper {
+		private static final long serialVersionUID = 6078569477021558310L;
+		private PolicyResult policyResult;
+
+		public PolicyResultEdgeWrapper(PolicyResult policyResult) {
+			super();
+			this.policyResult = policyResult;
+		}
+
+		@Override
+		public String toString() {
+			return "PolicyResultEdgeWrapper [policyResult=" + policyResult + "]";
+		}
+
+		@Override
+		public String getID() {
+			return policyResult.toString();
+		}
+		
+		
+	}
+	
+	private static class FinalResultEdgeWrapper implements EdgeWrapper {
+		private static final long serialVersionUID = -1486381946896779840L;
+		private FinalResult finalResult;
+		public FinalResultEdgeWrapper(FinalResult result) {
+			this.finalResult = result;
+		}
+
+		@Override
+		public String toString() {
+			return "FinalResultEdgeWrapper [finalResult=" + finalResult + "]";
+		}
+		
+		@Override
+		public String getID() {
+			return finalResult.toString();
+		}
+	}
+	
+	
+	private static class LabeledEdge extends DefaultEdge {
+		private static final long serialVersionUID = 579384429573385524L;
+		
+		private NodeWrapper from;
+		private NodeWrapper to;
+		private EdgeWrapper edge;
+		
+		public LabeledEdge(NodeWrapper from, NodeWrapper to, EdgeWrapper edge) {
+			this.from = from;
+			this.to = to;
+			this.edge = edge;
+		}
+		
+		@SuppressWarnings("unused")
+		public NodeWrapper from() {
+			return from;
+		}
+		
+		@SuppressWarnings("unused")
+		public NodeWrapper to() {
+			return to;
+		}
+		
+		@SuppressWarnings("unused")
+		public EdgeWrapper edge() {
+			return edge;
+		}
+
+		@Override
+		public String toString() {
+			return "LabeledEdge [from=" + from + ", to=" + to + ", edge=" + edge + "]";
+		}
+	}
+
+}
diff --git a/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/compiler/ControlLoopCompilerCallback.java b/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/compiler/ControlLoopCompilerCallback.java
new file mode 100644
index 0000000..ab4bf5e
--- /dev/null
+++ b/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/compiler/ControlLoopCompilerCallback.java
@@ -0,0 +1,29 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP Policy Engine
+ * ================================================================================
+ * 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.compiler;
+
+public interface ControlLoopCompilerCallback {
+	
+	public boolean	onWarning(String message);
+	
+	public boolean	onError(String message);
+	
+}
diff --git a/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/guard/compiler/ControlLoopGuardCompiler.java b/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/guard/compiler/ControlLoopGuardCompiler.java
new file mode 100644
index 0000000..de5b476
--- /dev/null
+++ b/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/guard/compiler/ControlLoopGuardCompiler.java
@@ -0,0 +1,133 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP Policy Engine
+ * ================================================================================
+ * 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.guard.compiler;
+
+
+import java.io.InputStream;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.onap.policy.controlloop.compiler.CompilerException;
+import org.onap.policy.controlloop.compiler.ControlLoopCompilerCallback;
+import org.onap.policy.controlloop.policy.guard.Constraint;
+import org.onap.policy.controlloop.policy.guard.ControlLoopGuard;
+import org.onap.policy.controlloop.policy.guard.GuardPolicy;
+import org.yaml.snakeyaml.Yaml;
+import org.yaml.snakeyaml.constructor.Constructor;
+
+public class ControlLoopGuardCompiler {
+	
+	private ControlLoopGuardCompiler(){
+		// Private Constructor 
+	}
+	
+	public static ControlLoopGuard compile(ControlLoopGuard cLGuard, ControlLoopCompilerCallback callback) throws CompilerException {
+		//
+		// Ensure ControlLoopGuard has at least one guard policies
+		//
+		validateControlLoopGuard(cLGuard, callback);
+		//
+		// Ensure each guard policy has at least one constraints and all guard policies are unique
+		//
+		validateGuardPolicies(cLGuard.getGuards(), callback);
+		//
+		// Ensure constraints for each guard policy are unique
+		//
+		validateConstraints(cLGuard.getGuards(), callback);
+		
+		return cLGuard;
+	}
+	
+	public static ControlLoopGuard	compile(InputStream yamlSpecification, ControlLoopCompilerCallback callback) throws CompilerException {
+		Yaml yaml = new Yaml(new Constructor(ControlLoopGuard.class));
+		Object obj = yaml.load(yamlSpecification);
+		if (obj == null) {
+			throw new CompilerException("Could not parse yaml specification.");
+		}
+		if (! (obj instanceof ControlLoopGuard)) {
+			throw new CompilerException("Yaml could not parse specification into required ControlLoopGuard object");
+		}
+		return ControlLoopGuardCompiler.compile((ControlLoopGuard) obj, callback);
+	}
+	
+	private static void validateControlLoopGuard(ControlLoopGuard cLGuard, ControlLoopCompilerCallback callback) throws CompilerException {
+		if (cLGuard == null) {
+			if (callback != null) {
+				callback.onError("ControlLoop Guard cannot be null");
+			}
+			throw new CompilerException("ControlLoop Guard cannot be null");
+		}
+		if (cLGuard.getGuard() == null && callback != null) {
+			callback.onError("Guard version cannot be null");
+		}
+		if (cLGuard.getGuards() == null) {
+			if (callback != null) {
+				callback.onError("ControlLoop Guard should have at least one guard policies");
+			}
+		} else if (cLGuard.getGuards().isEmpty() && callback != null) {
+			callback.onError("ControlLoop Guard should have at least one guard policies");
+		}
+	}
+	
+	private static void validateGuardPolicies(List<GuardPolicy> policies, ControlLoopCompilerCallback callback) throws CompilerException {
+		if (policies == null) {
+			if (callback != null) {
+				callback.onError("Guard policies should not be null");
+			}
+			throw new CompilerException("Guard policies should not be null");
+		}
+		//
+		// Ensure all guard policies are unique
+		//
+		Set<GuardPolicy> newSet = new HashSet<>(policies);
+		if (newSet.size() != policies.size() && callback != null) {
+			callback.onWarning("There are duplicate guard policies");
+		}
+		//
+		// Ensure each guard policy has at least one constraints
+		//
+		for (GuardPolicy policy : policies) {
+			if (policy.getLimit_constraints() == null || policy.getLimit_constraints().isEmpty()) {
+				if (callback != null) {
+					callback.onError("Guard policy " + policy.getName() + " does not have any limit constraint");
+				}
+				throw new CompilerException("Guard policy " + policy.getName() + " does not have any limit constraint");
+			}
+		}
+	}
+	
+	private static void validateConstraints(List<GuardPolicy> policies, ControlLoopCompilerCallback callback) throws CompilerException {
+		if (policies == null) {
+			if (callback != null) {
+				callback.onError("Guard policies should not be null");
+			}
+			throw new CompilerException("Guard policies should not be null");
+		}
+		for (GuardPolicy policy : policies) {
+			Set<Constraint> newSet = new HashSet<>(policy.getLimit_constraints());
+			if (newSet.size() != policy.getLimit_constraints().size() && callback != null) {
+				callback.onWarning("Guard policy " + policy.getName() + " has duplicate limit constraints");
+			}
+		}
+	}
+	
+}
diff --git a/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/ControlLoop.java b/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/ControlLoop.java
new file mode 100644
index 0000000..3d45c21
--- /dev/null
+++ b/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/ControlLoop.java
@@ -0,0 +1,189 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP Policy Engine
+ * ================================================================================
+ * 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.policy;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import org.onap.policy.asdc.Resource;
+import org.onap.policy.asdc.Service;
+
+public class ControlLoop {
+	
+	private static String VERSION = "2.0.0";
+
+	private String controlLoopName;
+	private String version = VERSION;
+	private List<Service> services;
+	private List<Resource> resources;
+	private String trigger_policy = FinalResult.FINAL_OPENLOOP.toString();
+	private Integer timeout;
+	private Boolean abatement = false;
+	
+	public ControlLoop() {
+		// Empty Constructor.
+	}
+	
+	public static String getVERSION(){
+		return ControlLoop.VERSION;
+	}
+	
+	public String getControlLoopName() {
+		return controlLoopName;
+	}
+
+	public void setControlLoopName(String controlLoopName) {
+		this.controlLoopName = controlLoopName;
+	}
+
+	public List<Service> getServices() {
+		return services;
+	}
+
+	public void setServices(List<Service> services) {
+		this.services = services;
+	}
+
+	public List<Resource> getResources() {
+		return resources;
+	}
+
+	public void setResources(List<Resource> resources) {
+		this.resources = resources;
+	}
+
+	public String getTrigger_policy() {
+		return trigger_policy;
+	}
+
+	public void setTrigger_policy(String trigger_policy) {
+		this.trigger_policy = trigger_policy;
+	}
+
+	public Integer getTimeout() {
+		return timeout;
+	}
+
+	public void setTimeout(Integer timeout) {
+		this.timeout = timeout;
+	}
+
+	public Boolean getAbatement() {
+		return abatement;
+	}
+
+	public void setAbatement(Boolean abatement) {
+		this.abatement = abatement;
+	}
+
+	public String getVersion() {
+		return version;
+	}
+	
+	public void setVersion(String version){
+		this.version = version;
+	}
+
+	public ControlLoop(ControlLoop controlLoop) {
+		this.controlLoopName = controlLoop.controlLoopName;
+		this.services = new LinkedList<>();
+		if (controlLoop.services != null) {
+			for (Service service : controlLoop.services) {
+				this.services.add(service);
+			}
+		}
+		this.resources = new LinkedList<>();
+		if (controlLoop.resources != null) {
+			for (Resource resource: controlLoop.resources) {
+				this.resources.add(resource);
+			}
+		}
+		this.trigger_policy = controlLoop.trigger_policy;
+		this.timeout = controlLoop.timeout;
+		this.abatement = controlLoop.abatement;
+	}
+	@Override
+	public String toString() {
+		return "ControlLoop [controlLoopName=" + controlLoopName + ", version=" + version + ", services=" + services
+				+ ", resources=" + resources + ", trigger_policy=" + trigger_policy + ", timeout="
+				+ timeout + ", abatement=" + abatement + "]";
+	}
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((controlLoopName == null) ? 0 : controlLoopName.hashCode());
+		result = prime * result + ((resources == null) ? 0 : resources.hashCode());
+		result = prime * result + ((services == null) ? 0 : services.hashCode());
+		result = prime * result + ((timeout == null) ? 0 : timeout.hashCode());
+		result = prime * result + ((trigger_policy == null) ? 0 : trigger_policy.hashCode());
+		result = prime * result + ((version == null) ? 0 : version.hashCode());
+		result = prime * result + ((abatement == null) ? 0 : abatement.hashCode());
+		return result;
+	}
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		ControlLoop other = (ControlLoop) obj;
+		if (controlLoopName == null) {
+			if (other.controlLoopName != null)
+				return false;
+		} else if (!controlLoopName.equals(other.controlLoopName))
+			return false;
+		if (resources == null) {
+			if (other.resources != null)
+				return false;
+		} else if (!resources.equals(other.resources))
+			return false;
+		if (services == null) {
+			if (other.services != null)
+				return false;
+		} else if (!services.equals(other.services))
+			return false;
+		if (timeout == null) {
+			if (other.timeout != null)
+				return false;
+		} else if (!timeout.equals(other.timeout))
+			return false;
+		if (trigger_policy == null) {
+			if (other.trigger_policy != null)
+				return false;
+		} else if (!trigger_policy.equals(other.trigger_policy))
+			return false;
+		if (version == null) {
+			if (other.version != null)
+				return false;
+		} else if (!version.equals(other.version))
+			return false;
+		if (abatement == null) {
+			if (other.abatement != null)
+				return false;
+		} else if (!abatement.equals(other.abatement))
+			return false;
+		return true;
+	}
+	
+}
diff --git a/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/ControlLoopPolicy.java b/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/ControlLoopPolicy.java
new file mode 100644
index 0000000..712a441
--- /dev/null
+++ b/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/ControlLoopPolicy.java
@@ -0,0 +1,83 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP Policy Engine
+ * ================================================================================
+ * 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.policy;
+
+import java.util.List;
+
+public class ControlLoopPolicy {
+	
+	private ControlLoop controlLoop;
+
+	private List<Policy> policies;
+
+	public ControlLoop getControlLoop() {
+		return controlLoop;
+	}
+
+	public void setControlLoop(ControlLoop controlLoop) {
+		this.controlLoop = controlLoop;
+	}
+
+	public List<Policy> getPolicies() {
+		return policies;
+	}
+
+	public void setPolicies(List<Policy> policies) {
+		this.policies = policies;
+	}
+
+	@Override
+	public String toString() {
+		return "ControlLoopPolicy [controlLoop=" + controlLoop + ", policies=" + policies + "]";
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((controlLoop == null) ? 0 : controlLoop.hashCode());
+		result = prime * result + ((policies == null) ? 0 : policies.hashCode());
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		ControlLoopPolicy other = (ControlLoopPolicy) obj;
+		if (controlLoop == null) {
+			if (other.controlLoop != null)
+				return false;
+		} else if (!controlLoop.equals(other.controlLoop))
+			return false;
+		if (policies == null) {
+			if (other.policies != null)
+				return false;
+		} else if (!policies.equals(other.policies))
+			return false;
+		return true;
+	}
+
+}
diff --git a/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/FinalResult.java b/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/FinalResult.java
new file mode 100644
index 0000000..cad9945
--- /dev/null
+++ b/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/FinalResult.java
@@ -0,0 +1,93 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP Policy Engine
+ * ================================================================================
+ * 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.policy;
+
+public enum FinalResult {
+	/**
+	 * The Control Loop Policy successfully completed its Operations.
+	 */
+	FINAL_SUCCESS("Final_Success"),
+	/**
+	 * The Control Loop Policy was an Open Loop and is finished.
+	 */
+	FINAL_OPENLOOP("Final_OpenLoop"),
+	/**
+	 * The Control Loop Policy failed in its last Operation Policy. NOTE: Previous Operation Policies may have been successful.
+	 */
+	FINAL_FAILURE("Final_Failure"),
+	/**
+	 * The Control Loop Policy failed because the overall timeout was met.
+	 */
+	FINAL_FAILURE_TIMEOUT("Final_Failure_Timeout"),
+	/**
+	 * The Control Loop Policy failed because an Operation Policy met its retry limit.
+	 */
+	FINAL_FAILURE_RETRIES("Final_Failure_Retries"),
+	/**
+	 * The Control Loop Policy failed due to an exception.
+	 */
+	FINAL_FAILURE_EXCEPTION("Final_Failure_Exception"), 
+	/**
+	 *  The Control Loop Policy failed due to guard denied
+	 */
+	FINAL_FAILURE_GUARD("Final_Failure_Guard")
+	;
+	
+	String result;
+	
+	private FinalResult(String result) {
+		this.result = result;
+	}
+	
+	public static FinalResult	toResult(String result) {
+		if (result.equalsIgnoreCase(FINAL_SUCCESS.toString())) {
+			return FINAL_SUCCESS;
+		}
+		if (result.equalsIgnoreCase(FINAL_OPENLOOP.toString())) {
+			return FINAL_OPENLOOP;
+		}
+		if (result.equalsIgnoreCase(FINAL_FAILURE.toString())) {
+			return FINAL_FAILURE;
+		}
+		if (result.equalsIgnoreCase(FINAL_FAILURE_TIMEOUT.toString())) {
+			return FINAL_FAILURE_TIMEOUT;
+		}
+		if (result.equalsIgnoreCase(FINAL_FAILURE_RETRIES.toString())) {
+			return FINAL_FAILURE_RETRIES;
+		}
+		if (result.equalsIgnoreCase(FINAL_FAILURE_EXCEPTION.toString())) {
+			return FINAL_FAILURE_EXCEPTION;
+		}
+		if (result.equalsIgnoreCase(FINAL_FAILURE_GUARD.toString())) {
+			return FINAL_FAILURE_GUARD;
+		}
+		return null;
+	}
+	
+	public static boolean isResult(String result, FinalResult finalResult) {
+		FinalResult toResult = FinalResult.toResult(result);
+		if (toResult == null) {
+			return false;
+		}
+		return toResult.equals(finalResult);
+	}
+
+}
diff --git a/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/OperationsAccumulateParams.java b/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/OperationsAccumulateParams.java
new file mode 100644
index 0000000..b27d72e
--- /dev/null
+++ b/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/OperationsAccumulateParams.java
@@ -0,0 +1,99 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP Policy Engine
+ * ================================================================================
+ * 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.policy;
+
+import java.io.Serializable;
+
+public class OperationsAccumulateParams implements Serializable {
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = -3597358159130168247L;
+	
+	private String period;
+	private Integer limit;
+	
+	public OperationsAccumulateParams() {
+		// Does Nothing 
+	} 
+	
+	public OperationsAccumulateParams(OperationsAccumulateParams ops) {
+		this.period = ops.period;
+		this.limit = ops.limit;
+	}
+	
+	public OperationsAccumulateParams(String period, Integer limit) {
+		this.period = period;
+		this.limit = limit;
+	}
+	
+	public String getPeriod() {
+		return period;
+	}
+
+	public void setPeriod(String period) {
+		this.period = period;
+	}
+
+	public Integer getLimit() {
+		return limit;
+	}
+
+	public void setLimit(Integer limit) {
+		this.limit = limit;
+	}
+
+	@Override
+	public String toString() {
+		return "OperationsAccumulateParams [period=" + period + ", limit=" + limit + "]";
+	}
+	
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((period == null) ? 0 : period.hashCode());
+		result = prime * result + ((limit == null) ? 0 : limit.hashCode());
+		return result;
+	}
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		OperationsAccumulateParams other = (OperationsAccumulateParams) obj;
+		if (period == null) {
+			if (other.period != null)
+				return false;
+		} else if (!period.equals(other.period))
+			return false;
+		if (limit == null) {
+			if (other.limit != null)
+				return false;
+		} else if (!limit.equals(other.limit))
+			return false;
+		return true;
+	}
+
+}
diff --git a/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/Policy.java b/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/Policy.java
new file mode 100644
index 0000000..96799e9
--- /dev/null
+++ b/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/Policy.java
@@ -0,0 +1,353 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP Policy Engine
+ * ================================================================================
+ * 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.policy;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.UUID;
+
+public class Policy {
+
+	private String id = UUID.randomUUID().toString();
+	private String name;
+	private String description;
+	private String actor;
+	private String recipe;
+	private Map<String, String> payload;
+	private Target target;
+	private OperationsAccumulateParams operationsAccumulateParams;
+	private Integer retry = 0;
+	private Integer timeout = 300;
+	private String success = FinalResult.FINAL_SUCCESS.toString();
+	private String failure = FinalResult.FINAL_FAILURE.toString();
+	private String failure_retries = FinalResult.FINAL_FAILURE_RETRIES.toString();
+	private String failure_timeout = FinalResult.FINAL_FAILURE_TIMEOUT.toString();
+	private String failure_exception = FinalResult.FINAL_FAILURE_EXCEPTION.toString();
+	private String failure_guard = FinalResult.FINAL_FAILURE_GUARD.toString();
+	
+	
+	public Policy() {
+		//Does Nothing Empty Constructor
+	}
+	
+	public String getId() {
+		return id;
+	}
+
+	public void setId(String id) {
+		this.id = id;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public String getDescription() {
+		return description;
+	}
+
+	public void setDescription(String description) {
+		this.description = description;
+	}
+
+	public String getActor() {
+		return actor;
+	}
+
+	public void setActor(String actor) {
+		this.actor = actor;
+	}
+
+	public String getRecipe() {
+		return recipe;
+	}
+
+	public void setRecipe(String recipe) {
+		this.recipe = recipe;
+	}
+
+	public Map<String, String> getPayload() {
+		return payload;
+	}
+
+	public void setPayload(Map<String, String> payload) {
+		this.payload = payload;
+	}
+
+	public Target getTarget() {
+		return target;
+	}
+
+	public void setTarget(Target target) {
+		this.target = target;
+	}
+
+	public OperationsAccumulateParams getOperationsAccumulateParams() {
+		return operationsAccumulateParams;
+	}
+
+	public void setOperationsAccumulateParams(OperationsAccumulateParams operationsAccumulateParams) {
+		this.operationsAccumulateParams = operationsAccumulateParams;
+	}
+
+	public Integer getRetry() {
+		return retry;
+	}
+
+	public void setRetry(Integer retry) {
+		this.retry = retry;
+	}
+
+	public Integer getTimeout() {
+		return timeout;
+	}
+
+	public void setTimeout(Integer timeout) {
+		this.timeout = timeout;
+	}
+
+	public String getSuccess() {
+		return success;
+	}
+
+	public void setSuccess(String success) {
+		this.success = success;
+	}
+
+	public String getFailure() {
+		return failure;
+	}
+
+	public void setFailure(String failure) {
+		this.failure = failure;
+	}
+
+	public String getFailure_retries() {
+		return failure_retries;
+	}
+
+	public void setFailure_retries(String failure_retries) {
+		this.failure_retries = failure_retries;
+	}
+
+	public String getFailure_timeout() {
+		return failure_timeout;
+	}
+
+	public void setFailure_timeout(String failure_timeout) {
+		this.failure_timeout = failure_timeout;
+	}
+
+	public String getFailure_exception() {
+		return failure_exception;
+	}
+
+	public void setFailure_exception(String failure_exception) {
+		this.failure_exception = failure_exception;
+	}
+
+	public String getFailure_guard() {
+		return failure_guard;
+	}
+
+	public void setFailure_guard(String failure_guard) {
+		this.failure_guard = failure_guard;
+	}
+
+	public Policy(String id) {
+		this.id = id;
+	}
+	
+	public Policy(String name, String actor, String recipe, Map<String, String> payload, Target target) {
+		this.name = name;
+		this.actor = actor;
+		this.recipe = recipe;
+		this.target = target;
+		if (payload != null) {
+			this.payload = Collections.unmodifiableMap(payload);
+		}
+	}
+	
+	public Policy(String name, String actor, String recipe, Map<String, String> payload, Target target, Integer retries, Integer timeout) {
+		this(name, actor, recipe, payload, target);
+		this.retry = retries;
+		this.timeout = timeout;
+	}
+	
+	public Policy(String id, String name, String description, String actor, Map<String, String> payload, Target target, String recipe, Integer retries, Integer timeout) {
+		this(name, actor, recipe, payload, target, retries, timeout);
+		this.id = id;
+		this.description = description;
+	}
+	
+	public Policy(Policy policy) {
+		this.id = policy.id;
+		this.name = policy.name;
+		this.description = policy.description;
+		this.actor = policy.actor;
+		this.recipe = policy.recipe;
+		if (policy.payload != null) {
+			this.payload = Collections.unmodifiableMap(policy.payload);
+		}
+		this.target = policy.target;
+		this.operationsAccumulateParams = policy.operationsAccumulateParams;
+		this.retry = policy.retry;
+		this.timeout = policy.timeout;
+		this.success = policy.success;
+		this.failure = policy.failure;
+		this.failure_exception = policy.failure_exception;
+		this.failure_guard = policy.failure_guard;
+		this.failure_retries = policy.failure_retries;
+		this.failure_timeout = policy.failure_timeout;
+	}
+
+	public boolean isValid() {
+		if(id==null || name==null || actor==null|| recipe==null || target==null){
+			return false;
+		}
+		return true;
+	}
+
+	@Override
+	public String toString() {
+		return "Policy [id=" + id + ", name=" + name + ", description=" + description + ", actor=" + actor + ", recipe="
+				+ recipe + ", payload=" + payload + ", target=" + target + ", operationsAccumulateParams=" + operationsAccumulateParams + ", retry=" + retry + ", timeout=" + timeout
+				+ ", success=" + success + ", failure=" + failure + ", failure_retries=" + failure_retries
+				+ ", failure_timeout=" + failure_timeout + ", failure_exception=" + failure_exception + ", failure_guard=" + failure_guard + "]";
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((actor == null) ? 0 : actor.hashCode());
+		result = prime * result + ((description == null) ? 0 : description.hashCode());
+		result = prime * result + ((failure == null) ? 0 : failure.hashCode());
+		result = prime * result + ((failure_exception == null) ? 0 : failure_exception.hashCode());
+		result = prime * result + ((failure_guard == null) ? 0 : failure_guard.hashCode());
+		result = prime * result + ((failure_retries == null) ? 0 : failure_retries.hashCode());
+		result = prime * result + ((failure_timeout == null) ? 0 : failure_timeout.hashCode());
+		result = prime * result + ((id == null) ? 0 : id.hashCode());
+		result = prime * result + ((name == null) ? 0 : name.hashCode());
+		result = prime * result + ((payload == null) ? 0 : payload.hashCode());
+		result = prime * result + ((recipe == null) ? 0 : recipe.hashCode());
+		result = prime * result + ((retry == null) ? 0 : retry.hashCode());
+		result = prime * result + ((success == null) ? 0 : success.hashCode());
+		result = prime * result + ((target == null) ? 0 : target.hashCode());
+		result = prime * result + ((operationsAccumulateParams == null) ? 0 : operationsAccumulateParams.hashCode());
+		result = prime * result + ((timeout == null) ? 0 : timeout.hashCode());
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		Policy other = (Policy) obj;
+		if (actor != other.actor)
+			return false;
+		if (description == null) {
+			if (other.description != null)
+				return false;
+		} else if (!description.equals(other.description))
+			return false;
+		if (failure == null) {
+			if (other.failure != null)
+				return false;
+		} else if (!failure.equals(other.failure))
+			return false;
+		if (failure_exception == null) {
+			if (other.failure_exception != null)
+				return false;
+		} else if (!failure_exception.equals(other.failure_exception))
+			return false;
+		if (failure_guard == null) {
+			if (other.failure_guard != null)
+				return false;
+		} else if (!failure_guard.equals(other.failure_guard))
+			return false;
+		if (failure_retries == null) {
+			if (other.failure_retries != null)
+				return false;
+		} else if (!failure_retries.equals(other.failure_retries))
+			return false;
+		if (failure_timeout == null) {
+			if (other.failure_timeout != null)
+				return false;
+		} else if (!failure_timeout.equals(other.failure_timeout))
+			return false;
+		if (id == null) {
+			if (other.id != null)
+				return false;
+		} else if (!id.equals(other.id))
+			return false;
+		if (name == null) {
+			if (other.name != null)
+				return false;
+		} else if (!name.equals(other.name))
+			return false;
+		if (payload == null) {
+			if (other.payload != null)
+				return false;
+		} else if (!payload.equals(other.payload))
+			return false;
+		if (recipe == null) {
+			if (other.recipe != null)
+				return false;
+		} else if (!recipe.equals(other.recipe))
+			return false;
+		if (retry == null) {
+			if (other.retry != null)
+				return false;
+		} else if (!retry.equals(other.retry))
+			return false;
+		if (success == null) {
+			if (other.success != null)
+				return false;
+		} else if (!success.equals(other.success))
+			return false;
+		if (operationsAccumulateParams == null) {
+			if (other.operationsAccumulateParams != null)
+				return false;
+		} else if (!operationsAccumulateParams.equals(other.operationsAccumulateParams))
+			return false;
+		if (target == null) {
+			if (other.target != null)
+				return false;
+		} else if (!target.equals(other.target))
+			return false;	
+		if (timeout == null) {
+			if (other.timeout != null)
+				return false;
+		} else if (!timeout.equals(other.timeout))
+			return false;
+		return true;
+	}
+	
+}
diff --git a/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/PolicyResult.java b/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/PolicyResult.java
new file mode 100644
index 0000000..5ff2d68
--- /dev/null
+++ b/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/PolicyResult.java
@@ -0,0 +1,82 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP Policy Engine
+ * ================================================================================
+ * 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.policy;
+
+public enum PolicyResult {
+	/**
+	 * Operation was successful.
+	 */
+	SUCCESS("Success"),
+	/**
+	 * Operation failed.
+	 */
+	FAILURE("Failure"),
+	/**
+	 * Operation failed due to maximum retries being met.
+	 */
+	FAILURE_RETRIES("Failure_Retries"),
+	/**
+	 * Operation failed due to timeout occurring.
+	 */
+	FAILURE_TIMEOUT("Failure_Timeout"),
+	/**
+	 * Operation failed due to an exception.
+	 */
+	FAILURE_EXCEPTION("Failure_Exception"), 
+	/**
+	 * Operation failed since Guard did not permit.
+	 */
+	FAILURE_GUARD("Failure_Guard")
+	;
+	
+	private String result;
+	
+	private PolicyResult(String result) {
+		this.result = result;
+	}
+	
+	@Override
+	public String toString() {
+		return this.result;
+	}
+	
+	public static PolicyResult toResult(String result) {
+		if (result.equalsIgnoreCase(SUCCESS.toString())) {
+			return SUCCESS;
+		}
+		if (result.equalsIgnoreCase(FAILURE.toString())) {
+			return FAILURE;
+		}
+		if (result.equalsIgnoreCase(FAILURE_RETRIES.toString())) {
+			return FAILURE_RETRIES;
+		}
+		if (result.equalsIgnoreCase(FAILURE_TIMEOUT.toString())) {
+			return FAILURE_TIMEOUT;
+		}
+		if (result.equalsIgnoreCase(FAILURE_EXCEPTION.toString())) {
+			return FAILURE_EXCEPTION;
+		}
+		if (result.equalsIgnoreCase(FAILURE_GUARD.toString())) {
+			return FAILURE_GUARD;
+		}
+		return null;
+	}
+
+}
diff --git a/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/Target.java b/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/Target.java
new file mode 100644
index 0000000..2a8817d
--- /dev/null
+++ b/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/Target.java
@@ -0,0 +1,106 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP Policy Engine
+ * ================================================================================
+ * 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.policy;
+
+import java.io.Serializable;
+
+public class Target implements Serializable {
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 2180988443264988319L;
+	 
+	private String resourceID;
+	private TargetType type;
+
+	public Target() {
+		//Does Nothing Empty Constructor
+	}
+	
+	public String getResourceID() {
+		return resourceID;
+	}
+
+	public void setResourceID(String resourceID) {
+		this.resourceID = resourceID;
+	}
+
+	public TargetType getType() {
+		return type;
+	}
+
+	public void setType(TargetType type) {
+		this.type = type;
+	}
+
+	public Target(TargetType type) {
+		this.type = type;
+	}
+	
+	public Target(String resourceID) {
+		this.resourceID = resourceID;
+	}
+	
+	public Target(TargetType type, String resourceID) {
+		this.type = type;
+		this.resourceID = resourceID;
+	}
+	
+	public Target(Target target) {
+		this.type = target.type;
+		this.resourceID = target.resourceID;
+	}
+	
+	@Override
+	public String toString() {
+		return "Target [type=" + type + ", resourceID=" + resourceID + "]";
+	}
+	
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((type == null) ? 0 : type.hashCode());
+		result = prime * result + ((resourceID == null) ? 0 : resourceID.hashCode());
+		return result;
+	}
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		Target other = (Target) obj;
+		if (type == null) {
+			if (other.type != null)
+				return false;
+		} else if (!type.equals(other.type))
+			return false;
+		if (resourceID == null) {
+			if (other.resourceID != null)
+				return false;
+		} else if (!resourceID.equals(other.resourceID))
+			return false;
+		return true;
+	}
+}
diff --git a/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/TargetType.java b/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/TargetType.java
new file mode 100644
index 0000000..875ca2e
--- /dev/null
+++ b/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/TargetType.java
@@ -0,0 +1,39 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP Policy Engine
+ * ================================================================================
+ * 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.policy;
+
+public enum TargetType {
+	VM("VM"),
+	PNF("PNF"),
+	VFC("VFC")
+	;
+	
+	private String target;
+	
+	private TargetType(String targetType) {
+		this.target = targetType;
+	}
+	
+	@Override
+	public String toString() {
+		return this.target;
+	}
+
+}
diff --git a/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/builder/BuilderException.java b/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/builder/BuilderException.java
new file mode 100644
index 0000000..7cf2f49
--- /dev/null
+++ b/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/builder/BuilderException.java
@@ -0,0 +1,31 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP Policy Engine
+ * ================================================================================
+ * 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.policy.builder;
+
+public class BuilderException extends Exception {
+
+	private static final long serialVersionUID = 610064813684337895L;
+	
+	public BuilderException(String string) {
+		super(string);
+	}
+
+}
diff --git a/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/builder/ControlLoopPolicyBuilder.java b/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/builder/ControlLoopPolicyBuilder.java
new file mode 100644
index 0000000..93ecbc6
--- /dev/null
+++ b/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/builder/ControlLoopPolicyBuilder.java
@@ -0,0 +1,287 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP Policy Engine
+ * ================================================================================
+ * 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.policy.builder;
+
+import java.util.Map;
+
+import org.onap.policy.asdc.Resource;
+import org.onap.policy.asdc.Service;
+import org.onap.policy.controlloop.policy.ControlLoop;
+import org.onap.policy.controlloop.policy.OperationsAccumulateParams;
+import org.onap.policy.controlloop.policy.Policy;
+import org.onap.policy.controlloop.policy.PolicyResult;
+import org.onap.policy.controlloop.policy.Target;
+import org.onap.policy.controlloop.policy.builder.impl.ControlLoopPolicyBuilderImpl;
+
+public interface ControlLoopPolicyBuilder {
+	
+	/**
+	 * Adds one or more services to the ControlLoop
+	 * 
+	 * 
+	 * @param service
+	 * @return
+	 * @throws BuilderException
+	 */
+	public ControlLoopPolicyBuilder	addService(Service... services) throws BuilderException;
+	
+	/**
+	 * @param services
+	 * @return
+	 * @throws BuilderException
+	 */
+	public ControlLoopPolicyBuilder removeService(Service... services) throws BuilderException;
+	
+	/**
+	 * @return
+	 * @throws BuilderException
+	 */
+	public ControlLoopPolicyBuilder removeAllServices() throws BuilderException;
+	
+	/**
+	 * Adds one or more resources to the ControlLoop
+	 * 
+	 * 
+	 * @param resource
+	 * @return
+	 * @throws BuilderException
+	 */
+	public ControlLoopPolicyBuilder	addResource(Resource... resources) throws BuilderException;
+	
+	/**
+	 * @param resources
+	 * @return
+	 * @throws BuilderException
+	 */
+	public ControlLoopPolicyBuilder removeResource(Resource... resources) throws BuilderException;
+	
+	/**
+	 * @return
+	 * @throws BuilderException
+	 */
+	public ControlLoopPolicyBuilder removeAllResources() throws BuilderException;
+	
+	/**
+	 *  @param abatement
+	 *  @return
+	 *  @throws BuilderException
+	 */
+	public ControlLoopPolicyBuilder setAbatement(Boolean abatement) throws BuilderException;
+	
+	
+	/**
+	 * Sets the overall timeout value for the Control Loop. If any operational policies have retries and timeouts,
+	 * then this overall timeout value should exceed all those values.
+	 * 
+	 * @param timeout
+	 * @return
+	 * @throws BuilderException
+	 */
+	public ControlLoopPolicyBuilder	setTimeout(Integer timeout) throws BuilderException;
+	
+	/**
+	 * Scans the operational policies and calculate an minimum overall timeout for the Control Loop.
+	 * 
+	 * 
+	 * @return Integer
+	 */
+	public Integer calculateTimeout();
+	
+	/**
+	 * Sets the initial trigger policy when a DCAE Closed Loop Event arrives in the ONAP Policy Platform.
+	 * 
+	 * 
+	 * @param name
+	 * @param description
+	 * @param actor
+	 * @param target
+	 * @param recipe
+	 * @param retries
+	 * @param timeout
+	 * @return Policy
+	 * @throws BuilderException
+	 */
+	public Policy setTriggerPolicy(String name, String description, String actor, Target target, String recipe, Map<String, String> payload, Integer retries, Integer timeout) throws BuilderException;
+	
+	/**
+	 * 
+	 * Changes the trigger policy to point to another existing Policy.
+	 * 
+	 * 
+	 * @param id
+	 * @return ControlLoop
+	 * @throws BuilderException
+	 */
+	public ControlLoop	setTriggerPolicy(String id) throws BuilderException;
+	
+	/**
+	 * @return
+	 */
+	public boolean	isOpenLoop();
+	
+	/**
+	 * @return
+	 * @throws BuilderException
+	 */
+	public Policy	getTriggerPolicy() throws BuilderException;
+	
+	/**
+	 * Simply returns a copy of the ControlLoop information.
+	 * 
+	 * 
+	 * @return ControlLoop
+	 */
+	public ControlLoop	getControlLoop();
+	
+	/**
+	 * Creates a policy that is chained to the result of another Policy.
+	 * 
+	 * 
+	 * @param name
+	 * @param description
+	 * @param actor
+	 * @param target
+	 * @param recipe
+	 * @param retries
+	 * @param timeout
+	 * @param policyID
+	 * @param results
+	 * @return
+	 * @throws BuilderException
+	 */
+	public Policy setPolicyForPolicyResult(String name, String description, String actor,
+			Target target, String recipe, Map<String, String> payload, Integer retries, Integer timeout, String policyID, PolicyResult... results) throws BuilderException;
+	
+	
+	/**
+	 * Sets the policy result(s) to an existing Operational Policy.
+	 * 
+	 * 
+	 * @param policyResultID
+	 * @param policyID
+	 * @param results
+	 * @return
+	 * @throws BuilderException
+	 */
+	public Policy setPolicyForPolicyResult(String policyResultID, String policyID, PolicyResult... results) throws BuilderException;
+	
+	/**
+	 * Removes an Operational Policy. Be mindful that if any other Operational Policies have results that point to this policy, any
+	 * policies that have results pointing to this policy will have their result reset to the appropriate default FINAL_* result.
+	 * 
+	 * 
+	 * @param policyID
+	 * @return
+	 * @throws BuilderException
+	 */
+	public boolean removePolicy(String policyID) throws BuilderException;
+	
+	/**
+	 * Resets a policy's results to defualt FINAL_* codes.
+	 * 
+	 * 
+	 * @return Policy
+	 * @throws BuilderException - Policy does not exist
+	 */
+	public Policy	resetPolicyResults(String policyID) throws BuilderException;
+	
+	/**
+	 * Removes all existing Operational Policies and reverts back to an Open Loop.
+	 * 
+	 * @return
+	 */
+	public ControlLoopPolicyBuilder	removeAllPolicies();
+		
+	/**
+	 * Adds an operationsAccumulateParams to an existing operational policy
+	 * 
+	 * @return Policy
+	 * @throws BuilderException - Policy does not exist
+	 */
+	public Policy addOperationsAccumulateParams(String policyID, OperationsAccumulateParams operationsAccumulateParams) throws BuilderException;
+	
+	/**
+	 * This will compile and build the YAML specification for the Control Loop Policy. Please iterate the Results object for details.
+	 * The Results object will contains warnings and errors. If the specification compiled successfully, you will be able to retrieve the
+	 * YAML.
+	 * 
+	 * @return Results
+	 */
+	public Results	buildSpecification();
+	
+	/**
+	 * The Factory is used to build a ControlLoopPolicyBuilder implementation.
+	 * 
+	 * @author pameladragosh
+	 *
+	 */
+	public static class Factory {
+		private Factory(){
+			// Private Constructor.
+		}
+		
+		/**
+		 * Builds a basic Control Loop with an overall timeout. Use this method if you wish to create an OpenLoop, or if you 
+		 * want to interactively build a Closed Loop.
+		 * 
+		 * @param controlLoopName - Per Closed Loop AID v1.0, unique string for the closed loop.
+		 * @param timeout - Overall timeout for the Closed Loop to execute.
+		 * @return ControlLoopPolicyBuilder object
+		 * @throws BuilderException
+		 */
+		public static ControlLoopPolicyBuilder	buildControlLoop (String controlLoopName, Integer timeout) throws BuilderException {
+			return new ControlLoopPolicyBuilderImpl(controlLoopName, timeout);
+		}
+		
+		/**
+		 * Build a Control Loop for a resource and services associated with the resource.
+		 * 
+		 * @param controlLoopName - Per Closed Loop AID v1.0, unique string for the closed loop.
+		 * @param timeout - Overall timeout for the Closed Loop to execute.
+		 * @param resource - Resource this closed loop is for. Should come from ASDC, but if not available use resourceName to distinguish.
+		 * @param services - Zero or more services associated with this resource. Should come from ASDC, but if not available use serviceName to distinguish.
+		 * @return ControlLoopPolicyBuilder object
+		 * @throws BuilderException
+		 */
+		public static ControlLoopPolicyBuilder	buildControlLoop (String controlLoopName, Integer timeout, Resource resource, Service... services) throws BuilderException {
+			
+			ControlLoopPolicyBuilder builder = new ControlLoopPolicyBuilderImpl(controlLoopName, timeout, resource, services);
+			
+			return builder;
+		}
+		
+		/**
+		 * @param controlLoopName
+		 * @param timeout
+		 * @param service
+		 * @param resources
+		 * @return
+		 * @throws BuilderException
+		 */
+		public static ControlLoopPolicyBuilder	buildControlLoop (String controlLoopName, Integer timeout, Service service, Resource... resources) throws BuilderException {
+			
+			ControlLoopPolicyBuilder builder = new ControlLoopPolicyBuilderImpl(controlLoopName, timeout, service, resources);
+			
+			return builder;
+		}
+	}
+
+}
diff --git a/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/builder/Message.java b/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/builder/Message.java
new file mode 100644
index 0000000..4bf2665
--- /dev/null
+++ b/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/builder/Message.java
@@ -0,0 +1,29 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP Policy Engine
+ * ================================================================================
+ * 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.policy.builder;
+
+public interface Message {
+	
+	public String	getMessage();
+	
+	public MessageLevel	getLevel();
+
+}
diff --git a/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/builder/MessageLevel.java b/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/builder/MessageLevel.java
new file mode 100644
index 0000000..37ecfa1
--- /dev/null
+++ b/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/builder/MessageLevel.java
@@ -0,0 +1,29 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP Policy Engine
+ * ================================================================================
+ * 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.policy.builder;
+
+public enum MessageLevel {
+	INFO,
+	WARNING,
+	ERROR,
+	EXCEPTION
+	;
+
+}
diff --git a/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/builder/Results.java b/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/builder/Results.java
new file mode 100644
index 0000000..37bd932
--- /dev/null
+++ b/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/builder/Results.java
@@ -0,0 +1,33 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP Policy Engine
+ * ================================================================================
+ * 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.policy.builder;
+
+import java.util.List;
+
+public interface Results {
+	
+	public List<Message>	getMessages();
+	
+	public String	getSpecification();
+	
+	public boolean	isValid();
+
+}
diff --git a/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/builder/impl/ControlLoopPolicyBuilderImpl.java b/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/builder/impl/ControlLoopPolicyBuilderImpl.java
new file mode 100644
index 0000000..dae56f3
--- /dev/null
+++ b/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/builder/impl/ControlLoopPolicyBuilderImpl.java
@@ -0,0 +1,496 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP Policy Engine
+ * ================================================================================
+ * 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.policy.builder.impl;
+
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.UUID;
+
+import org.onap.policy.asdc.Resource;
+import org.onap.policy.asdc.Service;
+import org.onap.policy.common.logging.flexlogger.FlexLogger;
+import org.onap.policy.common.logging.flexlogger.Logger;
+import org.onap.policy.controlloop.compiler.CompilerException;
+import org.onap.policy.controlloop.compiler.ControlLoopCompiler;
+import org.onap.policy.controlloop.compiler.ControlLoopCompilerCallback;
+import org.onap.policy.controlloop.policy.ControlLoop;
+import org.onap.policy.controlloop.policy.ControlLoopPolicy;
+import org.onap.policy.controlloop.policy.FinalResult;
+import org.onap.policy.controlloop.policy.OperationsAccumulateParams;
+import org.onap.policy.controlloop.policy.Policy;
+import org.onap.policy.controlloop.policy.PolicyResult;
+import org.onap.policy.controlloop.policy.Target;
+import org.onap.policy.controlloop.policy.builder.BuilderException;
+import org.onap.policy.controlloop.policy.builder.ControlLoopPolicyBuilder;
+import org.onap.policy.controlloop.policy.builder.MessageLevel;
+import org.onap.policy.controlloop.policy.builder.Results;
+import org.yaml.snakeyaml.DumperOptions;
+import org.yaml.snakeyaml.DumperOptions.FlowStyle;
+import org.yaml.snakeyaml.Yaml;
+
+public class ControlLoopPolicyBuilderImpl implements ControlLoopPolicyBuilder {
+	private static Logger logger = FlexLogger.getLogger(ControlLoopPolicyBuilderImpl.class.getName());
+	private ControlLoopPolicy policy;
+	
+	public ControlLoopPolicyBuilderImpl(String controlLoopName, Integer timeout) throws BuilderException {
+		policy = new ControlLoopPolicy();
+		ControlLoop controlLoop = new ControlLoop();
+		controlLoop.setControlLoopName(controlLoopName);
+		controlLoop.setTimeout(timeout);
+		policy.setControlLoop(controlLoop);
+	}
+	
+	public ControlLoopPolicyBuilderImpl(String controlLoopName, Integer timeout, Resource resource, Service... services) throws BuilderException {
+		this(controlLoopName, timeout);
+		this.addResource(resource);
+		this.addService(services);
+	}
+	
+	public ControlLoopPolicyBuilderImpl(String controlLoopName, Integer timeout, Service service, Resource[] resources) throws BuilderException {
+		this(controlLoopName, timeout);
+		this.addService(service);
+		this.addResource(resources);
+	}
+
+	@Override
+	public ControlLoopPolicyBuilder	addService(Service... services) throws BuilderException {
+		if (services == null) {
+			throw new BuilderException("Service must not be null");
+		}
+		for (Service service : services) {
+			if (service.getServiceUUID() == null) {
+				if (service.getServiceName() == null || service.getServiceName().length() < 1) {
+					throw new BuilderException("Invalid service - need either a serviceUUID or serviceName");
+				}
+				if(policy.getControlLoop().getServices()==null){
+					policy.getControlLoop().setServices(new LinkedList<>());
+				}
+				policy.getControlLoop().getServices().add(service);
+			}
+		}
+		return this;
+	}
+	
+	@Override
+	public ControlLoopPolicyBuilder removeService(Service... services) throws BuilderException {
+		if (services == null) {
+            throw new BuilderException("Service must not be null");
+        }
+        if (policy.getControlLoop().getServices() == null) {
+            throw new BuilderException("No existing services to remove");
+        }
+        for (Service service : services) {
+            if (service.getServiceUUID() == null) {
+                if (service.getServiceName() == null || service.getServiceName().length() < 1) {
+                    throw new BuilderException("Invalid service - need either a serviceUUID or serviceName");
+                }
+            }
+            boolean removed = policy.getControlLoop().getServices().remove(service);
+            if (!removed) {
+                throw new BuilderException("Unknown service " + service.getServiceName());
+            }
+        }
+        return this;
+	}
+
+	@Override
+	public ControlLoopPolicyBuilder removeAllServices() throws BuilderException {
+		policy.getControlLoop().getServices().clear();
+        return this;
+	}
+
+	
+	@Override
+	public ControlLoopPolicyBuilder	addResource(Resource... resources) throws BuilderException {
+		if (resources == null) {
+			throw new BuilderException("resources must not be null");
+		}
+		for (Resource resource : resources) {
+			if (resource.getResourceUUID() == null) {
+				if (resource.getResourceName() == null || resource.getResourceName().length() <= 0) {
+					throw new BuilderException("Invalid resource - need either resourceUUID or resourceName");
+				}
+			}
+			if(policy.getControlLoop().getResources()==null){
+				policy.getControlLoop().setResources(new LinkedList<>());
+			}
+			policy.getControlLoop().getResources().add(resource);
+		}
+		return this;
+	}
+	
+	@Override
+	public ControlLoopPolicyBuilder setAbatement(Boolean abatement) throws BuilderException{
+		if (abatement == null) {
+			throw new BuilderException("abatement must not be null");
+		}
+		policy.getControlLoop().setAbatement(abatement);
+		return this;
+	}
+	
+	@Override
+	public ControlLoopPolicyBuilder	setTimeout(Integer timeout) {
+		policy.getControlLoop().setTimeout(timeout);
+		return this;
+	}
+	
+	@Override
+	public Policy setTriggerPolicy(String name, String description, String actor, Target target, String recipe,
+			Map<String, String> payload, Integer retries, Integer timeout) throws BuilderException {
+		
+		Policy trigger = new Policy(UUID.randomUUID().toString(), name, description, actor, payload, target, recipe, retries, timeout);
+		
+		policy.getControlLoop().setTrigger_policy(trigger.getId());
+		
+		this.addNewPolicy(trigger);
+		//
+		// Return a copy of the policy
+		//
+		return new Policy(trigger);
+	}
+
+	@Override
+	public Policy setPolicyForPolicyResult(String name, String description, String actor,
+			Target target, String recipe, Map<String, String> payload, Integer retries, Integer timeout, String policyID, PolicyResult... results) throws BuilderException {
+		//
+		// Find the existing policy
+		//
+		Policy existingPolicy = this.findPolicy(policyID);
+		if (existingPolicy == null) {
+			throw new BuilderException("Unknown policy " + policyID);
+		}
+		//
+		// Create the new Policy
+		//
+		Policy newPolicy = new Policy(UUID.randomUUID().toString(), name, description, actor, payload, target, recipe, retries, timeout);
+		//
+		// Connect the results
+		//
+		for (PolicyResult result : results) {
+			switch (result) {
+			case FAILURE:
+				existingPolicy.setFailure(newPolicy.getId());
+				break;
+			case FAILURE_EXCEPTION:
+				existingPolicy.setFailure_exception(newPolicy.getId());
+				break;
+			case FAILURE_RETRIES:
+				existingPolicy.setFailure_retries(newPolicy.getId());
+				break;
+			case FAILURE_TIMEOUT:
+				existingPolicy.setFailure_timeout(newPolicy.getId());
+				break;
+			case FAILURE_GUARD:
+				existingPolicy.setFailure_guard(newPolicy.getId());
+				break;
+			case SUCCESS:
+				existingPolicy.setSuccess(newPolicy.getId());
+				break;
+			default:
+				throw new BuilderException("Invalid PolicyResult " + result);
+			}
+		}
+		//
+		// Add it to our list
+		//
+		this.policy.getPolicies().add(newPolicy);
+		//
+		// Return a policy to them
+		//
+		return new Policy(newPolicy);
+	}
+	
+	private class BuilderCompilerCallback implements ControlLoopCompilerCallback {
+
+		private ResultsImpl results = new ResultsImpl();
+		
+		@Override
+		public boolean onWarning(String message) {
+			results.addMessage(new MessageImpl(message, MessageLevel.WARNING));
+			return false;
+		}
+
+		@Override
+		public boolean onError(String message) {
+			results.addMessage(new MessageImpl(message, MessageLevel.ERROR));
+			return false;
+		}
+	}
+
+	@Override
+	public Results	buildSpecification() {
+		//
+		// Dump the specification
+		//
+		DumperOptions options = new DumperOptions();
+		options.setDefaultFlowStyle(FlowStyle.BLOCK);
+		options.setPrettyFlow(true);
+		Yaml yaml = new Yaml(options);
+		String dumpedYaml = yaml.dump(policy);
+		//
+		// This is our callback class for our compiler
+		//
+		BuilderCompilerCallback callback = new BuilderCompilerCallback();
+		//
+		// Compile it
+		//
+		try {
+			ControlLoopCompiler.compile(policy, callback);
+		} catch (CompilerException e) {
+			logger.error(e.getMessage() + e);
+			callback.results.addMessage(new MessageImpl(e.getMessage(), MessageLevel.EXCEPTION));
+		}
+		//
+		// Save the spec
+		//
+		callback.results.setSpecification(dumpedYaml);
+		return callback.results;
+	}
+
+	private void addNewPolicy(Policy policy) {
+		if (this.policy.getPolicies() == null) {
+			this.policy.setPolicies(new LinkedList<>());
+		}
+		this.policy.getPolicies().add(policy);
+	}
+	
+	private Policy findPolicy(String id) {
+		for (Policy policy : this.policy.getPolicies()) {
+			if (policy.getId().equals(id)) {
+				return policy;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public ControlLoopPolicyBuilder removeResource(Resource... resources) throws BuilderException {
+	    if (resources == null) {
+            throw new BuilderException("Resource must not be null");
+        }
+        if (policy.getControlLoop().getResources() == null) {
+            throw new BuilderException("No existing resources to remove");
+        }
+        for (Resource resource : resources) {
+            if (resource.getResourceUUID() == null) {
+                if (resource.getResourceName() == null || resource.getResourceName().length() < 1) {
+                    throw new BuilderException("Invalid resource - need either a resourceUUID or resourceName");
+                }
+            }
+            boolean removed = policy.getControlLoop().getResources().remove(resource); 
+            if (!removed) {
+                throw new BuilderException("Unknown resource " + resource.getResourceName());
+            }
+        }
+        return this; 
+    }
+
+	@Override
+	public ControlLoopPolicyBuilder removeAllResources() throws BuilderException {
+	    policy.getControlLoop().getResources().clear();
+        return this;
+    }
+
+	@Override
+	public Integer calculateTimeout() {
+		int sum = 0;
+        for (Policy policy : this.policy.getPolicies()) {
+            sum += policy.getTimeout().intValue();
+        }
+        return new Integer(sum);
+	}
+
+	@Override
+	public ControlLoop setTriggerPolicy(String id) throws BuilderException {
+		if (id == null) {
+            throw new BuilderException("Id must not be null");
+        }
+	    Policy trigger = this.findPolicy(id);
+        if (trigger == null) {
+            throw new BuilderException("Unknown policy " + id);
+        }
+        else {
+            this.policy.getControlLoop().setTrigger_policy(id);
+        }
+        return new ControlLoop(this.policy.getControlLoop());
+    }
+
+	@Override
+	public boolean isOpenLoop() {
+        if (this.policy.getControlLoop().getTrigger_policy().equals(FinalResult.FINAL_OPENLOOP.toString())) {
+            return true;
+        }	
+        else {
+            return false;
+        }
+	}
+
+	@Override
+	public Policy getTriggerPolicy() throws BuilderException {
+	    if (this.policy.getControlLoop().getTrigger_policy().equals(FinalResult.FINAL_OPENLOOP.toString())) {
+            return null;
+        }
+        else {
+            Policy trigger = new Policy(this.findPolicy(this.policy.getControlLoop().getTrigger_policy()));
+            return trigger;
+        }
+    }
+
+	@Override
+	public ControlLoop getControlLoop() {
+		ControlLoop loop = new ControlLoop(this.policy.getControlLoop());
+		return loop;
+	}
+
+	@Override
+	public Policy setPolicyForPolicyResult(String policyResultID, String policyID, PolicyResult... results)
+			throws BuilderException {
+		//
+        // Find the existing policy
+        //
+        Policy existingPolicy = this.findPolicy(policyID);
+        if (existingPolicy == null) {
+            throw new BuilderException(policyID + " does not exist");
+        }
+        if (this.findPolicy(policyResultID) == null) {
+            throw new BuilderException("Operational policy " + policyResultID + " does not exist");
+        }
+        //
+        // Connect the results
+        //
+        for (PolicyResult result : results) {
+            switch (result) {
+            case FAILURE:
+                existingPolicy.setFailure(policyResultID);
+                break;
+            case FAILURE_EXCEPTION:
+                existingPolicy.setFailure_exception(policyResultID);
+                break;
+            case FAILURE_RETRIES:
+            	existingPolicy.setFailure_retries(policyResultID);
+            	break;
+            case FAILURE_TIMEOUT:
+            	existingPolicy.setFailure_timeout(policyResultID);
+            	break;
+            case FAILURE_GUARD:
+            	existingPolicy.setFailure_guard(policyResultID);
+            	break;
+            case SUCCESS:
+            	existingPolicy.setSuccess(policyResultID);
+            	break;
+            default:
+            	throw new BuilderException("Invalid PolicyResult " + result);
+            }
+        }
+        return new Policy(this.findPolicy(policyResultID));
+	}
+
+	@Override
+	public boolean removePolicy(String policyID) throws BuilderException {
+		Policy existingPolicy = this.findPolicy(policyID);
+        if (existingPolicy == null) {
+            throw new BuilderException("Unknown policy " + policyID);
+        }
+        //
+        // Check if the policy to remove is trigger_policy
+        //
+        if (this.policy.getControlLoop().getTrigger_policy().equals(policyID)) {
+            this.policy.getControlLoop().setTrigger_policy(FinalResult.FINAL_OPENLOOP.toString());
+        }
+        else {
+            //
+            // Update policies
+            //
+            for (Policy policy : this.policy.getPolicies()) {
+                int index = this.policy.getPolicies().indexOf(policy);
+                if (policy.getSuccess().equals(policyID)) {
+                    policy.setSuccess(FinalResult.FINAL_SUCCESS.toString());
+                }
+                if (policy.getFailure().equals(policyID)) {
+                    policy.setFailure(FinalResult.FINAL_FAILURE.toString());
+                }
+                if (policy.getFailure_retries().equals(policyID)) {
+                    policy.setFailure_retries(FinalResult.FINAL_FAILURE_RETRIES.toString());
+                }
+                if (policy.getFailure_timeout().equals(policyID)) {
+                    policy.setFailure_timeout(FinalResult.FINAL_FAILURE_TIMEOUT.toString());
+                }
+                if (policy.getFailure_exception().equals(policyID)) {
+                    policy.setFailure_exception(FinalResult.FINAL_FAILURE_EXCEPTION.toString());
+                }
+                if (policy.getFailure_guard().equals(policyID)) {
+                    policy.setFailure_guard(FinalResult.FINAL_FAILURE_GUARD.toString());
+                }
+                this.policy.getPolicies().set(index, policy);
+            }
+        }
+        //
+        // remove the policy
+        //
+        boolean removed = this.policy.getPolicies().remove(existingPolicy);
+        return removed;
+	}
+
+	@Override
+	public Policy resetPolicyResults(String policyID) throws BuilderException {
+        Policy existingPolicy = this.findPolicy(policyID);
+        if (existingPolicy == null) {
+            throw new BuilderException("Unknown policy " + policyID);
+        }
+        //
+        // reset policy results
+        //
+        existingPolicy.setSuccess(FinalResult.FINAL_SUCCESS.toString());
+        existingPolicy.setFailure(FinalResult.FINAL_FAILURE.toString());
+        existingPolicy.setFailure_retries(FinalResult.FINAL_FAILURE_RETRIES.toString());
+        existingPolicy.setFailure_timeout(FinalResult.FINAL_FAILURE_TIMEOUT.toString());
+        existingPolicy.setFailure_exception(FinalResult.FINAL_FAILURE_EXCEPTION.toString());
+        existingPolicy.setFailure_guard(FinalResult.FINAL_FAILURE_GUARD.toString());
+        return new Policy(existingPolicy);
+	}
+
+	@Override
+	public ControlLoopPolicyBuilder removeAllPolicies() {
+		//
+        // Remove all existing operational policies
+        //
+        this.policy.getPolicies().clear();
+        //
+        // Revert controlLoop back to an open loop
+        //
+        this.policy.getControlLoop().setTrigger_policy(FinalResult.FINAL_OPENLOOP.toString());
+        return this;
+	}
+	
+	@Override
+	public Policy addOperationsAccumulateParams(String policyID, OperationsAccumulateParams operationsAccumulateParams) throws BuilderException {
+		Policy existingPolicy = this.findPolicy(policyID);
+        if (existingPolicy == null) {
+            throw new BuilderException("Unknown policy " + policyID);
+        }
+        //
+        // Add operationsAccumulateParams to existingPolicy
+        //
+        existingPolicy.setOperationsAccumulateParams(operationsAccumulateParams);
+        return new Policy(existingPolicy);
+	}
+
+}
diff --git a/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/builder/impl/MessageImpl.java b/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/builder/impl/MessageImpl.java
new file mode 100644
index 0000000..4d3aa70
--- /dev/null
+++ b/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/builder/impl/MessageImpl.java
@@ -0,0 +1,46 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP Policy Engine
+ * ================================================================================
+ * 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.policy.builder.impl;
+
+import org.onap.policy.controlloop.policy.builder.Message;
+import org.onap.policy.controlloop.policy.builder.MessageLevel;
+
+public class MessageImpl implements Message {
+	
+	private String message;
+	private MessageLevel level;
+	
+	public MessageImpl(String message, MessageLevel level) {
+		this.message = message;
+		this.level = level;
+	}
+
+	@Override
+	public String getMessage() {
+		return message;
+	}
+
+	@Override
+	public MessageLevel getLevel() {
+		return level;
+	}
+
+}
diff --git a/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/builder/impl/ResultsImpl.java b/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/builder/impl/ResultsImpl.java
new file mode 100644
index 0000000..18732f4
--- /dev/null
+++ b/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/builder/impl/ResultsImpl.java
@@ -0,0 +1,55 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP Policy Engine
+ * ================================================================================
+ * 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.policy.builder.impl;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import org.onap.policy.controlloop.policy.builder.Message;
+import org.onap.policy.controlloop.policy.builder.Results;
+
+public class ResultsImpl implements Results {
+	
+	private String specification;
+	private List<Message>	messages = new LinkedList<>();
+
+	@Override
+	public List<Message> getMessages() {
+		return messages;
+	}
+
+	@Override
+	public String getSpecification() {
+		return specification;
+	}
+
+	@Override
+	public boolean isValid() {
+		return this.specification != null;
+	}
+
+	public void addMessage(Message message) {
+		this.messages.add(message);
+	}
+	
+	public void setSpecification(String spec) {
+		this.specification = spec;
+	}
+}
diff --git a/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/guard/Constraint.java b/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/guard/Constraint.java
new file mode 100644
index 0000000..ac3dbb0
--- /dev/null
+++ b/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/guard/Constraint.java
@@ -0,0 +1,171 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP Policy Engine
+ * ================================================================================
+ * 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.policy.guard;
+
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+public class Constraint {
+
+	private Integer freq_limit_per_target;
+	private Map<String,String> time_window;
+	private Map<String, String> active_time_range;
+	
+	private List<String> blacklist;
+	
+	public Constraint() {
+		// Do Nothing empty constructor. 
+	}
+
+	public Integer getFreq_limit_per_target() {
+		return freq_limit_per_target;
+	}
+
+
+	public void setFreq_limit_per_target(Integer freq_limit_per_target) {
+		this.freq_limit_per_target = freq_limit_per_target;
+	}
+
+
+	public Map<String, String> getTime_window() {
+		return time_window;
+	}
+
+
+	public void setTime_window(Map<String, String> time_window) {
+		this.time_window = time_window;
+	}
+
+
+	public Map<String, String> getActive_time_range() {
+		return active_time_range;
+	}
+
+
+	public void setActive_time_range(Map<String, String> active_time_range) {
+		this.active_time_range = active_time_range;
+	}
+
+
+	public List<String> getBlacklist() {
+		return blacklist;
+	}
+
+	public void setBlacklist(List<String> blacklist) {
+		this.blacklist = blacklist;
+	}
+
+	public Constraint(Integer freq_limit_per_target, Map<String, String> time_window) {
+		this.freq_limit_per_target = freq_limit_per_target;
+		if(time_window!=null){
+			this.time_window = Collections.unmodifiableMap(time_window);
+		}
+	}
+	
+	public Constraint(List<String> blacklist) {
+		this.blacklist = new LinkedList<>(blacklist);
+	}
+	
+	public Constraint(Integer freq_limit_per_target, Map<String, String> time_window, List<String> blacklist) {
+		this.freq_limit_per_target = freq_limit_per_target;
+		this.time_window = Collections.unmodifiableMap(time_window);
+		this.blacklist = new LinkedList<>(blacklist);
+	}
+	
+	public Constraint(Integer freq_limit_per_target, Map<String, String> time_window, Map<String, String> active_time_range) {
+		this(freq_limit_per_target, time_window);
+		if (active_time_range != null) {
+			this.active_time_range = Collections.unmodifiableMap(active_time_range);
+		}
+	}
+	
+	public Constraint(Integer freq_limit_per_target, Map<String, String> time_window, Map<String, String> active_time_range, List<String> blacklist) {
+		this(freq_limit_per_target, time_window);
+		if (active_time_range != null) {
+			this.active_time_range = Collections.unmodifiableMap(active_time_range);
+		}
+		if(blacklist!=null){
+			this.blacklist = new LinkedList<>(blacklist);
+		}
+	}
+	
+	public Constraint(Constraint constraint) {
+		this.freq_limit_per_target = constraint.freq_limit_per_target;
+		this.time_window = constraint.time_window;
+		if (constraint.active_time_range != null) {
+			this.active_time_range = Collections.unmodifiableMap(constraint.active_time_range);
+		}
+		this.blacklist = new LinkedList<>(constraint.blacklist);
+	}
+	
+	public boolean isValid() {
+		return ((freq_limit_per_target == null && time_window != null)|| (time_window == null && freq_limit_per_target != null))? false : true;
+	}
+	
+	@Override
+	public String toString() {
+		return "Constraint [freq_limit_per_target=" + freq_limit_per_target + ", time_window=" + time_window + ", active_time_range=" + active_time_range + ", blacklist=" + blacklist + "]";
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((freq_limit_per_target == null) ? 0 : freq_limit_per_target.hashCode());
+		result = prime * result + ((time_window == null) ? 0 : time_window.hashCode());
+		result = prime * result + ((active_time_range == null) ? 0 : active_time_range.hashCode());
+		result = prime * result + ((blacklist == null) ? 0 : blacklist.hashCode());
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		Constraint other = (Constraint) obj;
+		if (freq_limit_per_target == null) {
+			if (other.freq_limit_per_target != null) 
+				return false;
+		} else if (!freq_limit_per_target.equals(other.freq_limit_per_target))
+			return false;
+		if (time_window == null) {
+			if (other.time_window != null)
+				return false;
+		} else if (!time_window.equals(other.time_window))
+			return false;
+		if (active_time_range == null) {
+			if (other.active_time_range != null)
+				return false;
+		} else if (!active_time_range.equals(other.active_time_range))
+			return false;
+		if (blacklist == null) {
+			if (other.blacklist != null)
+				return false;
+		} else if (!blacklist.equals(other.blacklist))
+			return false;
+		return true;
+	}
+}
diff --git a/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/guard/ControlLoopGuard.java b/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/guard/ControlLoopGuard.java
new file mode 100644
index 0000000..5d83214
--- /dev/null
+++ b/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/guard/ControlLoopGuard.java
@@ -0,0 +1,92 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP Policy Engine
+ * ================================================================================
+ * 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.policy.guard;
+
+import java.util.LinkedList;
+
+public class ControlLoopGuard {
+	
+	private Guard guard;
+	
+	private LinkedList<GuardPolicy> guards;
+	
+	public ControlLoopGuard() {
+		//DO Nothing Empty Constructor
+	}
+	
+	public Guard getGuard() {
+		return guard;
+	}
+
+	public void setGuard(Guard guard) {
+		this.guard = guard;
+	}
+
+	public LinkedList<GuardPolicy> getGuards() {
+		return guards;
+	}
+
+	public void setGuards(LinkedList<GuardPolicy> guards) {
+		this.guards = guards;
+	}
+
+	public ControlLoopGuard(ControlLoopGuard cLGuard) {
+		this.guard = new Guard();
+		this.guards = new LinkedList<>(cLGuard.guards);
+	}
+	
+	@Override
+	public String toString() {
+		return "Guard [guard=" + guard + ", GuardPolicies=" + guards + "]";
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((guard == null) ? 0 : guard.hashCode());
+		result = prime * result + ((guards == null) ? 0 : guards.hashCode());
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		ControlLoopGuard other = (ControlLoopGuard) obj;
+		if (guard == null) {
+			if (other.guard != null)
+				return false;
+		} else if (!guard.equals(other.guard))
+			return false;
+		if (guards == null) {
+			if (other.guards != null)
+				return false;
+		} else if (!guards.equals(other.guards))
+			return false;
+		return true;
+	}
+
+	
+}
diff --git a/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/guard/ControlLoopParameter.java b/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/guard/ControlLoopParameter.java
new file mode 100644
index 0000000..dafa950
--- /dev/null
+++ b/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/guard/ControlLoopParameter.java
@@ -0,0 +1,89 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP Policy Engine
+ * ================================================================================
+ * 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.policy.guard;
+
+public class ControlLoopParameter {
+	private String controlLoopName;
+	private String version;
+	
+	public String getControlLoopName() {
+		return controlLoopName;
+	}
+
+	public void setControlLoopName(String controlLoopName) {
+		this.controlLoopName = controlLoopName;
+	}
+
+	public String getVersion() {
+		return version;
+	}
+
+	public void setVersion(String version) {
+		this.version = version;
+	}
+
+	public ControlLoopParameter(String controlLoopName, String version) {
+		super();
+		this.controlLoopName = controlLoopName;
+		this.version = version;
+	}
+
+	public ControlLoopParameter(ControlLoopParameter cl) {
+
+		this.controlLoopName = cl.controlLoopName;
+		this.version = cl.version;
+	}
+
+	@Override
+	public String toString() {
+		return "ControlLoopParameter [controlLoopName=" + controlLoopName + ", version=" + version + "]";
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((controlLoopName == null) ? 0 : controlLoopName.hashCode());
+		result = prime * result + ((version == null) ? 0 : version.hashCode());
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		ControlLoopParameter other = (ControlLoopParameter) obj;
+		if (controlLoopName == null) {
+			if (other.controlLoopName != null)
+				return false;
+		} else if (!controlLoopName.equals(other.controlLoopName))
+			return false;
+		if (version == null) {
+			if (other.version != null)
+				return false;
+		} else if (!version.equals(other.version))
+			return false;
+		return true;
+	}
+}
diff --git a/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/guard/Guard.java b/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/guard/Guard.java
new file mode 100644
index 0000000..4534669
--- /dev/null
+++ b/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/guard/Guard.java
@@ -0,0 +1,67 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP Policy Engine
+ * ================================================================================
+ * 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.policy.guard;
+
+public class Guard {
+
+	private static final String DEFAULTVERSION = "2.0.0";
+	
+	private String version = DEFAULTVERSION;
+	
+	public Guard() {
+		//DO Nothing empty Constructor. 
+	}
+	
+	public String getVersion() {
+		return version;
+	}
+
+	public void setVersion(String version) {
+		this.version = version;
+	}
+
+	@Override
+	public String toString() {
+		return "Guard [version=" + version + "]";
+	}
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((version == null) ? 0 : version.hashCode());
+		return result;
+	}
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		Guard other = (Guard) obj;
+		if (version == null) {
+			if (other.version != null)
+				return false;
+		} else if (!version.equals(other.version))
+			return false;
+		return true;
+	}
+}
diff --git a/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/guard/GuardPolicy.java b/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/guard/GuardPolicy.java
new file mode 100644
index 0000000..2068a46
--- /dev/null
+++ b/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/guard/GuardPolicy.java
@@ -0,0 +1,181 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP Policy Engine
+ * ================================================================================
+ * 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.policy.guard;
+
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.UUID;
+
+public class GuardPolicy {
+
+	private String id = UUID.randomUUID().toString();
+	private String name;
+	private String description;
+	private MatchParameters match_parameters;
+	private LinkedList<Constraint> limit_constraints;
+	
+	public GuardPolicy() {
+		//Do Nothing Empty Constructor. 
+	}
+	
+	public String getId() {
+		return id;
+	}
+
+	public void setId(String id) {
+		this.id = id;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public String getDescription() {
+		return description;
+	}
+
+	public void setDescription(String description) {
+		this.description = description;
+	}
+
+	public MatchParameters getMatch_parameters() {
+		return match_parameters;
+	}
+
+	public void setMatch_parameters(MatchParameters match_parameters) {
+		this.match_parameters = match_parameters;
+	}
+
+	public LinkedList<Constraint> getLimit_constraints() {
+		return  limit_constraints;
+	}
+
+	public void setLimit_constraints(LinkedList<Constraint> limit_constraints) {
+		this.limit_constraints = limit_constraints;
+	}
+
+	public GuardPolicy(String id) {
+		this.id = id;
+	}
+	
+	public GuardPolicy(String name, MatchParameters matchParameters) {
+		this.name = name;
+		this.match_parameters = matchParameters;
+	}
+	
+	public GuardPolicy(String id, String name, String description, MatchParameters matchParameters) {
+		this(name, matchParameters);
+		this.id = id;
+		this.description = description;
+	}
+	
+	public GuardPolicy(String name, MatchParameters matchParameters, List<Constraint> limitConstraints) {
+		this(name, matchParameters);
+		if (limit_constraints != null) {
+			this.limit_constraints = (LinkedList<Constraint>) Collections.unmodifiableList(limitConstraints);
+		}
+	}
+	
+	public GuardPolicy(String name, String description, MatchParameters matchParameters, List<Constraint> limitConstraints) {
+		this(name, matchParameters, limitConstraints);
+		this.description = description;
+	}
+	
+	public GuardPolicy(String id, String name, String description, MatchParameters matchParameters, List<Constraint> limitConstraints) {
+		this(name, description, matchParameters, limitConstraints);
+		this.id = id;
+	}
+	
+	public GuardPolicy(GuardPolicy policy) {
+		this.id = policy.id;
+		this.name = policy.name;
+		this.description = policy.description;
+		this.match_parameters = new MatchParameters(policy.match_parameters);
+		if (policy.limit_constraints != null) {
+			this.limit_constraints = (LinkedList<Constraint>) Collections.unmodifiableList(policy.limit_constraints);
+		}
+	}
+	
+	public boolean isValid() {
+		return (id==null || name ==null)? false : true;
+	}
+	
+	@Override
+	public String toString() {
+		return "Policy [id=" + id + ", name=" + name + ", description=" + description + ", match_parameters=" 
+				+match_parameters + ", limitConstraints=" + limit_constraints + "]";
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((description == null) ? 0 : description.hashCode());
+		result = prime * result + ((id == null) ? 0 : id.hashCode());
+		result = prime * result + ((name == null) ? 0 : name.hashCode());
+		result = prime * result + ((limit_constraints == null) ? 0 : limit_constraints.hashCode());
+		result = prime * result + ((match_parameters == null) ? 0 : match_parameters.hashCode());
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		GuardPolicy other = (GuardPolicy) obj;
+		if (description == null) {
+			if (other.description != null)
+				return false;
+		} else if (!description.equals(other.description))
+			return false;
+		if (id == null) {
+			if (other.id != null)
+				return false;
+		} else if (!id.equals(other.id))
+			return false;
+		if (name == null) {
+			if (other.name != null)
+				return false;
+		} else if (!name.equals(other.name))
+			return false;
+		if (limit_constraints == null) {
+			if (other.limit_constraints != null)
+				return false;
+		} else if (!limit_constraints.equals(other.limit_constraints))
+			return false;
+		if (match_parameters==null){
+			if(other.match_parameters !=null)
+				return false;
+		} else if(!match_parameters.equals(other.match_parameters))
+			return false;
+		return true;
+	}
+	
+	
+}
diff --git a/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/guard/MatchParameters.java b/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/guard/MatchParameters.java
new file mode 100644
index 0000000..da64cfc
--- /dev/null
+++ b/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/guard/MatchParameters.java
@@ -0,0 +1,142 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP Policy Engine
+ * ================================================================================
+ * 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.policy.guard;
+
+import java.util.LinkedList;
+import java.util.List;
+
+public class MatchParameters {
+	private String controlLoopName;
+	private String actor;
+	private String recipe;
+	private List<String> targets;
+
+	public MatchParameters() {
+		// Do Nothing Empty Constructor.
+	}	
+	
+	public String getControlLoopName() {
+		return controlLoopName;
+	}
+
+	public void setControlLoopName(String controlLoopName) {
+		this.controlLoopName = controlLoopName;
+	}
+
+	public String getActor() {
+		return actor;
+	}
+
+	public void setActor(String actor) {
+		this.actor = actor;
+	}
+
+	public String getRecipe() {
+		return recipe;
+	}
+
+	public void setRecipe(String recipe) {
+		this.recipe = recipe;
+	}
+
+	public List<String> getTargets() {
+		return targets;
+	}
+
+	public void setTargets(List<String> targets) {
+		this.targets = targets;
+	}
+
+	public MatchParameters(String actor, String recipe) {
+		this.actor = actor;
+		this.recipe = recipe;
+	}
+
+	public MatchParameters(String actor, String recipe, List<String> targets) {
+		this(actor, recipe);
+		if (targets != null) {
+			this.targets = new LinkedList<>(targets);
+		}
+	}
+
+	public MatchParameters(String controlLoopName, String actor, String recipe, List<String> targets) {
+		this(actor, recipe, targets);
+		this.controlLoopName = controlLoopName;
+	}
+
+	public MatchParameters(MatchParameters matchParameters) {
+
+		this.controlLoopName = matchParameters.controlLoopName;
+		this.actor = matchParameters.actor;
+		this.recipe = matchParameters.recipe;
+		if (matchParameters.targets != null) {
+			this.targets = new LinkedList<>(matchParameters.targets);
+		}
+	}
+
+	@Override
+	public String toString() {
+		return "MatchParameters [controlLoopName=" + controlLoopName + ", actor=" + actor + ", recipe=" + recipe
+				+ ", targets=" + targets + "]";
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((actor == null) ? 0 : actor.hashCode());
+		result = prime * result + ((controlLoopName == null) ? 0 : controlLoopName.hashCode());
+		result = prime * result + ((recipe == null) ? 0 : recipe.hashCode());
+		result = prime * result + ((targets == null) ? 0 : targets.hashCode());
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		MatchParameters other = (MatchParameters) obj;
+		if (actor == null) {
+			if (other.actor != null)
+				return false;
+		} else if (!actor.equals(other.actor))
+			return false;
+		if (controlLoopName == null) {
+			if (other.controlLoopName != null)
+				return false;
+		} else if (!controlLoopName.equals(other.controlLoopName))
+			return false;
+		if (recipe == null) {
+			if (other.recipe != null)
+				return false;
+		} else if (!recipe.equals(other.recipe))
+			return false;
+		if (targets == null) {
+			if (other.targets != null)
+				return false;
+		} else if (!targets.equals(other.targets))
+			return false;
+		return true;
+	}
+}
\ No newline at end of file
diff --git a/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/guard/builder/ControlLoopGuardBuilder.java b/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/guard/builder/ControlLoopGuardBuilder.java
new file mode 100644
index 0000000..e0e240d
--- /dev/null
+++ b/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/guard/builder/ControlLoopGuardBuilder.java
@@ -0,0 +1,130 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP Policy Engine
+ * ================================================================================
+ * 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.policy.guard.builder;
+
+import org.onap.policy.controlloop.policy.builder.BuilderException;
+import org.onap.policy.controlloop.policy.builder.Results;
+import org.onap.policy.controlloop.policy.guard.Constraint;
+import org.onap.policy.controlloop.policy.guard.ControlLoopGuard;
+import org.onap.policy.controlloop.policy.guard.Guard;
+import org.onap.policy.controlloop.policy.guard.GuardPolicy;
+import org.onap.policy.controlloop.policy.guard.builder.impl.ControlLoopGuardBuilderImpl;
+
+public interface ControlLoopGuardBuilder {
+	
+	/**
+	 * Adds one or more guard policies to the Control Loop Guard
+	 * 
+	 * 
+	 * @param policies
+	 * @return 
+	 * @throws BuilderException
+	 */
+	public ControlLoopGuardBuilder	addGuardPolicy(GuardPolicy... policies) throws BuilderException;
+	
+	/**
+	 * Removes one or more guard policies from the Control Loop Guard
+	 * 
+	 * 
+	 * @param policies
+	 * @return 
+	 * @throws BuilderException
+	 */
+	public ControlLoopGuardBuilder	removeGuardPolicy(GuardPolicy... policies) throws BuilderException;
+	
+	/**
+	 * Removes all guard policies from the Control Loop Guard
+	 * 
+	 * 
+	 * @param 
+	 * @return 
+	 * @throws BuilderException
+	 */
+	public ControlLoopGuardBuilder	removeAllGuardPolicies() throws BuilderException;
+	
+	/**
+	 * Adds one or more time limit constraints to the guard policy
+	 * 
+	 * 
+	 * @param id (guard policy id)
+	 * @param constraints
+	 * @return 
+	 * @throws BuilderException
+	 */
+	public ControlLoopGuardBuilder	addLimitConstraint(String id, Constraint... constraints) throws BuilderException;
+	
+	/**
+	 * Removes one or more time limit constraints from the guard policy
+	 * 
+	 * 
+	 * @param id (guard policy id)
+	 * @param constraints
+	 * @return 
+	 * @throws BuilderException
+	 */
+	public ControlLoopGuardBuilder	removeLimitConstraint(String id, Constraint... constraints) throws BuilderException;
+	
+	/**
+	 * Removes all time limit constraints from the guard policy
+	 * 
+	 * 
+	 * @param id (guard policy id)
+	 * @return 
+	 * @throws BuilderException
+	 */
+	public ControlLoopGuardBuilder	removeAllLimitConstraints(String id) throws BuilderException;
+	
+	/**
+	 *  Simply return a copy of control loop guard
+	 *  
+	 *  @return ControlLoopGuard
+	 */
+	public ControlLoopGuard getControlLoopGuard();	
+	
+	/**
+	 * This will compile and build the YAML specification for the Control Loop Guard. Please iterate the Results object for details.
+	 * The Results object will contains warnings and errors. If the specification compiled successfully, you will be able to retrieve the
+	 * YAML.
+	 * 
+	 * @return Results
+	 */
+	public Results	buildSpecification();
+	
+	/**
+	 * The Factory is used to build a ControlLoopGuardBuilder implementation.
+	 *
+	 */
+	public static class Factory {
+		
+		private Factory(){
+			//Do Nothing Private Constructor. 
+		}
+		/**
+		 * @param guard
+		 * @return ControlLoopGuardBuilder object
+		 * @throws BuilderException
+		 */
+		public static ControlLoopGuardBuilder	buildControlLoopGuard (Guard guard) throws BuilderException {
+			
+			return  new ControlLoopGuardBuilderImpl(guard);
+			
+		}
+	}
+}
diff --git a/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/guard/builder/impl/ControlLoopGuardBuilderImpl.java b/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/guard/builder/impl/ControlLoopGuardBuilderImpl.java
new file mode 100644
index 0000000..6152a4d
--- /dev/null
+++ b/ONAP-ControlloopPolicy/src/main/java/org/onap/policy/controlloop/policy/guard/builder/impl/ControlLoopGuardBuilderImpl.java
@@ -0,0 +1,244 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP Policy Engine
+ * ================================================================================
+ * 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.policy.guard.builder.impl;
+
+import java.util.LinkedList;
+
+import org.onap.policy.common.logging.flexlogger.FlexLogger;
+import org.onap.policy.common.logging.flexlogger.Logger;
+import org.onap.policy.controlloop.compiler.CompilerException;
+import org.onap.policy.controlloop.compiler.ControlLoopCompilerCallback;
+import org.onap.policy.controlloop.guard.compiler.ControlLoopGuardCompiler;
+import org.onap.policy.controlloop.policy.builder.BuilderException;
+import org.onap.policy.controlloop.policy.builder.MessageLevel;
+import org.onap.policy.controlloop.policy.builder.Results;
+import org.onap.policy.controlloop.policy.builder.impl.MessageImpl;
+import org.onap.policy.controlloop.policy.builder.impl.ResultsImpl;
+import org.onap.policy.controlloop.policy.guard.Constraint;
+import org.onap.policy.controlloop.policy.guard.ControlLoopGuard;
+import org.onap.policy.controlloop.policy.guard.Guard;
+import org.onap.policy.controlloop.policy.guard.GuardPolicy;
+import org.onap.policy.controlloop.policy.guard.builder.ControlLoopGuardBuilder;
+import org.yaml.snakeyaml.DumperOptions;
+import org.yaml.snakeyaml.DumperOptions.FlowStyle;
+import org.yaml.snakeyaml.Yaml;
+
+public class ControlLoopGuardBuilderImpl implements ControlLoopGuardBuilder {
+	private static Logger logger = FlexLogger.getLogger(ControlLoopGuardBuilderImpl.class.getName());
+	private ControlLoopGuard cLGuard;
+	
+	public ControlLoopGuardBuilderImpl(Guard guard) {
+		cLGuard = new ControlLoopGuard();
+		cLGuard.setGuard(guard);
+	}
+	
+	@Override
+	public ControlLoopGuardBuilder addGuardPolicy(GuardPolicy... policies) throws BuilderException {
+		if (policies == null) {
+			throw new BuilderException("GuardPolicy must not be null");
+		}
+		for (GuardPolicy policy : policies) {
+			if (!policy.isValid()) {
+				throw new BuilderException("Invalid guard policy - some required fields are missing");
+			}
+			if (cLGuard.getGuards() == null) {
+				cLGuard.setGuards(new LinkedList<>());
+			}
+			cLGuard.getGuards().add(policy);
+		}
+		return this;
+	}
+
+	@Override
+	public ControlLoopGuardBuilder removeGuardPolicy(GuardPolicy... policies) throws BuilderException {
+		if (policies == null) {
+            throw new BuilderException("GuardPolicy must not be null");
+        }
+        if (cLGuard.getGuards() == null) {
+            throw new BuilderException("No existing guard policies to remove");
+        }
+        for (GuardPolicy policy : policies) {
+        	if (!policy.isValid()) {
+				throw new BuilderException("Invalid guard policy - some required fields are missing");
+			}
+            boolean removed = cLGuard.getGuards().remove(policy);
+            if (!removed) {
+                throw new BuilderException("Unknown guard policy: " + policy.getName());
+            }
+        }
+        return this;
+	}
+
+	@Override
+	public ControlLoopGuardBuilder removeAllGuardPolicies() throws BuilderException {
+		cLGuard.getGuards().clear();
+        return this;
+	}
+
+	@Override
+	public ControlLoopGuardBuilder addLimitConstraint(String id, Constraint... constraints) throws BuilderException {
+		if (id == null) {
+			throw new BuilderException("The id of target guard policy must not be null");
+		}
+		if (constraints == null) {
+			throw new BuilderException("Constraint much not be null");
+		}
+		if (!addLimitConstraints(id,constraints)) {
+			throw new BuilderException("No existing guard policy matching the id: " + id);
+		}
+		return this;
+	}
+
+	private boolean addLimitConstraints(String id, Constraint... constraints) throws BuilderException {
+		boolean exist = false;
+		for (GuardPolicy policy: cLGuard.getGuards()) {
+			//
+			// We could have only one guard policy matching the id
+			//
+			if (policy.getId().equals(id)) {
+				exist = true;
+				for (Constraint cons: constraints) {
+					if (!cons.isValid()) {
+						throw new BuilderException("Invalid guard constraint - some required fields are missing");
+					}
+					if (policy.getLimit_constraints() == null) {
+						policy.setLimit_constraints(new LinkedList<>());
+					}
+					policy.getLimit_constraints().add(cons);
+				}
+				break;
+			}
+		}
+		return exist;
+	}
+
+	@Override
+	public ControlLoopGuardBuilder removeLimitConstraint(String id, Constraint... constraints) throws BuilderException {
+		if (id == null) {
+			throw new BuilderException("The id of target guard policy must not be null");
+		}
+		if (constraints == null) {
+			throw new BuilderException("Constraint much not be null");
+		}
+		if (!removeConstraints(id, constraints)) {
+			throw new BuilderException("No existing guard policy matching the id: " + id);
+		}
+		return this;
+	}
+
+	private boolean removeConstraints(String id, Constraint... constraints) throws BuilderException {
+		boolean exist = false;
+		for (GuardPolicy policy: cLGuard.getGuards()) {
+			//
+			// We could have only one guard policy matching the id
+			//
+			if (policy.getId().equals(id)) {
+				exist = true;
+				for (Constraint cons: constraints) {
+					if (!cons.isValid()) {
+						throw new BuilderException("Invalid guard constraint - some required fields are missing");
+					}
+					boolean removed = policy.getLimit_constraints().remove(cons);
+					if (!removed) {
+						throw new BuilderException("Unknown guard constraint: " + cons);
+					}
+				}
+				break;
+			}
+		}
+		return exist;
+	}
+
+	@Override
+	public ControlLoopGuardBuilder removeAllLimitConstraints(String id) throws BuilderException {
+		if (cLGuard.getGuards() == null || cLGuard.getGuards().isEmpty()) {
+			throw new BuilderException("No guard policies exist");
+		} 
+		if (id == null) {
+			throw new BuilderException("The id of target guard policy must not be null");
+		}
+		boolean exist = false;
+		for (GuardPolicy policy: cLGuard.getGuards()) {
+			if (policy.getId().equals(id)) {
+				exist = true;
+				policy.getLimit_constraints().clear();
+			}
+		}
+		if (!exist) {
+			throw new BuilderException("No existing guard policy matching the id: " + id);
+		}
+		return this;
+	}
+
+	
+	private class BuilderCompilerCallback implements ControlLoopCompilerCallback {
+
+		private ResultsImpl results = new ResultsImpl();
+		
+		@Override
+		public boolean onWarning(String message) {
+			results.addMessage(new MessageImpl(message, MessageLevel.WARNING));
+			return false;
+		}
+
+		@Override
+		public boolean onError(String message) {
+			results.addMessage(new MessageImpl(message, MessageLevel.ERROR));
+			return false;
+		}
+	}
+	
+	@Override
+	public ControlLoopGuard getControlLoopGuard() {
+		return new ControlLoopGuard(this.cLGuard);
+	}	
+	
+	
+	@Override
+	public Results buildSpecification() {
+		//
+		// Dump the specification
+		//
+		DumperOptions options = new DumperOptions();
+		options.setDefaultFlowStyle(FlowStyle.BLOCK);
+		options.setPrettyFlow(true);
+		Yaml yaml = new Yaml(options);
+		String dumpedYaml = yaml.dump(cLGuard);
+		//
+		// This is our callback class for our compiler
+		//
+		BuilderCompilerCallback callback = new BuilderCompilerCallback();
+		//
+		// Compile it
+		//
+		try {
+			ControlLoopGuardCompiler.compile(cLGuard, callback);
+		} catch (CompilerException e) {
+			logger.error(e.getMessage() + e);
+			callback.results.addMessage(new MessageImpl(e.getMessage(), MessageLevel.EXCEPTION));
+		}
+		//
+		// Save the spec
+		//
+		callback.results.setSpecification(dumpedYaml);
+		return callback.results;
+	}
+
+}
diff --git a/ONAP-ControlloopPolicy/src/test/java/org/onap/policy/controlloop/compiler/ControlLoopCompilerTest.java b/ONAP-ControlloopPolicy/src/test/java/org/onap/policy/controlloop/compiler/ControlLoopCompilerTest.java
new file mode 100644
index 0000000..40111ca
--- /dev/null
+++ b/ONAP-ControlloopPolicy/src/test/java/org/onap/policy/controlloop/compiler/ControlLoopCompilerTest.java
@@ -0,0 +1,80 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP Policy Engine
+ * ================================================================================
+ * 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.compiler;
+
+import static org.junit.Assert.*;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.junit.Test;
+
+public class ControlLoopCompilerTest {
+
+	@Test 
+	public void testTest() {
+		try {
+			this.test("src/test/resources/v1.0.0/test.yaml");
+		} catch (Exception e) {
+			fail(e.getMessage());
+		}
+	}
+	
+	@Test 
+	public void testBad1() {
+		try {
+			this.test("src/test/resources/v1.0.0/bad_trigger_1.yaml");
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+	}
+	@Test 
+	public void testBad2() {
+		try {
+			this.test("src/test/resources/v1.0.0/bad_trigger_2.yaml");
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+	}
+	
+	@Test 
+	public void testBad() {
+		try {
+			this.test("src/test/resources/v1.0.0/bad_policies_1.yaml");
+		} catch (Exception e) {
+		}
+	}
+	
+	public void test(String testFile) throws Exception {
+		try (InputStream is = new FileInputStream(new File(testFile))) {
+			ControlLoopCompiler.compile(is, null);
+		} catch (FileNotFoundException e) {
+			fail(e.getMessage());
+		} catch (IOException e) {
+			fail(e.getMessage());
+		} catch (Exception e) {
+			throw e;
+		}
+	}
+
+}
diff --git a/ONAP-ControlloopPolicy/src/test/java/org/onap/policy/controlloop/compiler/ControlLoopGuardCompilerTest.java b/ONAP-ControlloopPolicy/src/test/java/org/onap/policy/controlloop/compiler/ControlLoopGuardCompilerTest.java
new file mode 100644
index 0000000..5a834aa
--- /dev/null
+++ b/ONAP-ControlloopPolicy/src/test/java/org/onap/policy/controlloop/compiler/ControlLoopGuardCompilerTest.java
@@ -0,0 +1,101 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP Policy Engine
+ * ================================================================================
+ * 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.compiler;
+
+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 org.junit.Test;
+import org.onap.policy.controlloop.guard.compiler.ControlLoopGuardCompiler;
+
+public class ControlLoopGuardCompilerTest {
+	
+	@Test 
+	public void testTest1() {
+		try {
+			this.test("src/test/resources/v2.0.0-guard/policy_guard_ONAP_demo_vDNS.yaml");
+		} catch (Exception e) {
+			fail(e.getMessage());
+		}
+	}
+	
+	@Test 
+	public void testTest2() {
+		try {
+			this.test("src/test/resources/v2.0.0-guard/policy_guard_1707_appc.yaml");
+		} catch (Exception e) {
+			fail(e.getMessage());
+		}
+	}
+	
+	@Test 
+	public void testBad1() {
+		try {
+			this.test("src/test/resources/v2.0.0-guard/no_guard_policy.yaml");
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+	}
+	
+	@Test 
+	public void testBad2() {
+		try {
+			this.test("src/test/resources/v2.0.0-guard/duplicate_guard_policy.yaml");
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+	}
+	
+	@Test 
+	public void testBad3() {
+		try {
+			this.test("src/test/resources/v2.0.0-guard/no_guard_constraint.yaml");
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+	}
+	
+	@Test 
+	public void testBad4() {
+		try {
+			this.test("src/test/resources/v2.0.0-guard/duplicate_guard_constraint.yaml");
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+	}
+	
+	public void test(String testFile) throws Exception {
+		try (InputStream is = new FileInputStream(new File(testFile))) {
+			ControlLoopGuardCompiler.compile(is, null);
+		} catch (FileNotFoundException e) {
+			fail(e.getMessage());
+		} catch (IOException e) {
+			fail(e.getMessage());
+		} catch (Exception e) {
+			throw e;
+		}
+	}
+	
+}
diff --git a/ONAP-ControlloopPolicy/src/test/java/org/onap/policy/controlloop/policy/ControlLoopPolicyBuilderTest.java b/ONAP-ControlloopPolicy/src/test/java/org/onap/policy/controlloop/policy/ControlLoopPolicyBuilderTest.java
new file mode 100644
index 0000000..c933840
--- /dev/null
+++ b/ONAP-ControlloopPolicy/src/test/java/org/onap/policy/controlloop/policy/ControlLoopPolicyBuilderTest.java
@@ -0,0 +1,516 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP Policy Engine
+ * ================================================================================
+ * 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.policy;
+
+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.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.UUID;
+
+import org.junit.Test;
+import org.onap.policy.asdc.Resource;
+import org.onap.policy.asdc.ResourceType;
+import org.onap.policy.asdc.Service;
+import org.onap.policy.controlloop.policy.builder.BuilderException;
+import org.onap.policy.controlloop.policy.builder.ControlLoopPolicyBuilder;
+import org.onap.policy.controlloop.policy.builder.Message;
+import org.onap.policy.controlloop.policy.builder.MessageLevel;
+import org.onap.policy.controlloop.policy.builder.Results;
+import org.yaml.snakeyaml.Yaml;
+import org.yaml.snakeyaml.constructor.Constructor;
+import org.yaml.snakeyaml.error.YAMLException;
+
+
+public class ControlLoopPolicyBuilderTest {
+	
+	@Test
+	public void testControlLoop() {
+        try {
+			//
+			// Create a builder for our policy
+			//
+			ControlLoopPolicyBuilder builder = ControlLoopPolicyBuilder.Factory.buildControlLoop(UUID.randomUUID().toString(), 2400);
+			//
+			// Test add services
+			//
+			Service vSCP = new Service("vSCP");
+			Service vUSP = new Service("vUSP");
+			Service vTrinity = new Service("Trinity");
+			builder = builder.addService(vSCP, vUSP, vTrinity);
+			assertTrue(builder.getControlLoop().getServices().size() == 3);
+			//
+			// Test remove services
+			//
+			builder = builder.removeService(vSCP);
+			assertTrue(builder.getControlLoop().getServices().size() == 2);
+			builder = builder.removeAllServices();
+			assertTrue(builder.getControlLoop().getServices().size() == 0);
+			//
+			// Test add resources
+			//
+			Resource vCTS = new Resource("vCTS", ResourceType.VF);
+			Resource vCOM = new Resource("vCTS", ResourceType.VF);
+			Resource vRAR = new Resource("vCTS", ResourceType.VF);
+			builder = builder.addResource(vCTS, vCOM, vRAR);
+			assertTrue(builder.getControlLoop().getResources().size() == 3);
+			//
+			// Test remove resources
+			//
+			builder = builder.removeResource(vCTS);
+			assertTrue(builder.getControlLoop().getResources().size() == 2);
+			builder = builder.removeAllResources();
+			assertTrue(builder.getControlLoop().getResources().size() == 0);
+            //
+            // Test set abatement
+            //
+            assertFalse(builder.getControlLoop().getAbatement());
+            builder = builder.setAbatement(true);
+            assertTrue(builder.getControlLoop().getAbatement());
+		} catch (BuilderException e) {
+			fail(e.getMessage());
+		}
+	}
+	
+	@Test
+	public void testTimeout() {
+        try {
+            //
+            // Create a builder for our policy
+            //
+			ControlLoopPolicyBuilder builder = ControlLoopPolicyBuilder.Factory.buildControlLoop(UUID.randomUUID().toString(), 2400);
+            //
+            // Test setTimeout
+            //
+            assertTrue(builder.getControlLoop().getTimeout() == 2400);
+            builder = builder.setTimeout(800);
+            assertTrue(builder.getControlLoop().getTimeout() == 800);
+            // 
+            // Test calculateTimeout
+            //
+            Policy trigger = builder.setTriggerPolicy(
+                    "Restart the VM",
+                    "Upon getting the trigger event, restart the VM",
+                    "APPC",
+                    new Target(TargetType.VM),
+                    "Restart",
+                    null,
+                    2,
+                    300);
+            @SuppressWarnings("unused")
+			Policy onRestartFailurePolicy = builder.setPolicyForPolicyResult(
+                    "Rebuild VM",
+                    "If the restart fails, rebuild it",
+                    "APPC",
+                    new Target(TargetType.VM),
+                    "Rebuild",
+                    null,
+                    1,
+                    600,
+                    trigger.getId(),
+                    PolicyResult.FAILURE,
+                    PolicyResult.FAILURE_RETRIES,
+                    PolicyResult.FAILURE_TIMEOUT); 
+            assertTrue(builder.calculateTimeout().equals(new Integer(300 + 600)));
+            //
+        } catch (BuilderException e) {
+            fail(e.getMessage());
+        }
+	}
+	
+	@Test
+	public void testTriggerPolicyMethods() {
+	    try {
+            ControlLoopPolicyBuilder builder = ControlLoopPolicyBuilder.Factory.buildControlLoop(UUID.randomUUID().toString(), 2400);
+            //
+            // Test isOpenLoop
+            //
+            assertTrue(builder.isOpenLoop());
+            //
+            // Test set initial trigger policy
+            //
+            Policy triggerPolicy1 = builder.setTriggerPolicy( 
+                    "Restart the VM",
+                    "Upon getting the trigger event, restart the VM",
+                    "APPC",
+                    new Target(TargetType.VM),
+                    "Restart",
+                    null,
+                    2,
+                    300);
+            assertTrue(builder.isOpenLoop() == false);
+            assertTrue(builder.getControlLoop().getTrigger_policy().equals(triggerPolicy1.getId()));
+            //
+            // Set trigger policy to a new policy 
+            //
+            @SuppressWarnings("unused")
+			Policy triggerPolicy2 = builder.setTriggerPolicy(
+                    "Rebuild the VM",
+                    "Upon getting the trigger event, rebuild the VM",
+                    "APPC",
+                    new Target(TargetType.VM),
+                    "Rebuild",
+                    null,
+                    2,
+                    300);
+            // 
+            // Test set trigger policy to another existing policy
+            //
+            @SuppressWarnings("unused")
+			ControlLoop cl = builder.setTriggerPolicy(triggerPolicy1.getId());
+            assertTrue(builder.getControlLoop().getTrigger_policy().equals(triggerPolicy1.getId()));
+            //
+            // Test get trigger policy
+            //
+            assertTrue(builder.getTriggerPolicy().equals(triggerPolicy1));
+            //
+        } catch (BuilderException e) {
+            fail(e.getMessage());
+        }
+    }
+	
+	@Test
+	public void testAddRemovePolicies() {
+	    try {
+			ControlLoopPolicyBuilder builder = ControlLoopPolicyBuilder.Factory.buildControlLoop(UUID.randomUUID().toString(), 2400);
+            Policy triggerPolicy = builder.setTriggerPolicy(
+                    "Restart the VM",
+                    "Upon getting the trigger event, restart the VM",
+                    "APPC",
+                    new Target(TargetType.VM),
+                    "Restart",
+                    null,
+                    2,
+                    300);
+            //
+            // Test create a policy and chain it to the results of trigger policy
+            //
+            Policy onRestartFailurePolicy1 = builder.setPolicyForPolicyResult(
+                    "Rebuild VM",
+                    "If the restart fails, rebuild it.",
+                    "APPC",
+                    new Target(TargetType.VM),
+                    "Rebuild",
+                    null,
+                    1,
+                    600,
+                    triggerPolicy.getId(),
+                    PolicyResult.FAILURE,
+                    PolicyResult.FAILURE_RETRIES,
+                    PolicyResult.FAILURE_TIMEOUT,
+                    PolicyResult.FAILURE_GUARD);
+            //
+            assertTrue(builder.getTriggerPolicy().getFailure().equals(onRestartFailurePolicy1.getId()));
+            assertTrue(builder.getTriggerPolicy().getFailure_retries().equals(onRestartFailurePolicy1.getId()));
+            assertTrue(builder.getTriggerPolicy().getFailure_timeout().equals(onRestartFailurePolicy1.getId()));
+            assertTrue(builder.getTriggerPolicy().getFailure_guard().equals(onRestartFailurePolicy1.getId()));
+            //
+            // Test remove policy
+            //
+            boolean removed = builder.removePolicy(onRestartFailurePolicy1.getId());
+            assertTrue(removed);
+            assertTrue(builder.getTriggerPolicy().getFailure().equals(FinalResult.FINAL_FAILURE.toString()));
+            assertTrue(builder.getTriggerPolicy().getFailure_retries().equals(FinalResult.FINAL_FAILURE_RETRIES.toString()));
+            assertTrue(builder.getTriggerPolicy().getFailure_timeout().equals(FinalResult.FINAL_FAILURE_TIMEOUT.toString()));
+            assertTrue(builder.getTriggerPolicy().getFailure_guard().equals(FinalResult.FINAL_FAILURE_GUARD.toString()));
+            //
+            // Create another policy and chain it to the results of trigger policy
+            //
+            Policy onRestartFailurePolicy2 = builder.setPolicyForPolicyResult( 
+                    "Rebuild VM",
+                    "If the restart fails, rebuild it.",
+                    "APPC",
+                    new Target(TargetType.VM),
+                    "Rebuild",
+                    null,
+                    2,
+                    600,
+                    triggerPolicy.getId(),
+                    PolicyResult.FAILURE,
+                    PolicyResult.FAILURE_RETRIES,
+                    PolicyResult.FAILURE_TIMEOUT);
+            //
+            // Test reset policy results
+            //
+            triggerPolicy = builder.resetPolicyResults(triggerPolicy.getId());
+            assertTrue(builder.getTriggerPolicy().getFailure().equals(FinalResult.FINAL_FAILURE.toString()));
+            assertTrue(builder.getTriggerPolicy().getFailure_retries().equals(FinalResult.FINAL_FAILURE_RETRIES.toString()));
+            assertTrue(builder.getTriggerPolicy().getFailure_timeout().equals(FinalResult.FINAL_FAILURE_TIMEOUT.toString()));
+            //                                                               
+            // Test set the policy results to an existing operational policy
+            //
+            onRestartFailurePolicy2 = builder.setPolicyForPolicyResult(
+                    onRestartFailurePolicy2.getId(), 
+                    triggerPolicy.getId(), 
+                    PolicyResult.FAILURE,
+                    PolicyResult.FAILURE_RETRIES,
+                    PolicyResult.FAILURE_TIMEOUT);
+            assertTrue(builder.getTriggerPolicy().getFailure().equals(onRestartFailurePolicy2.getId()));
+            assertTrue(builder.getTriggerPolicy().getFailure_retries().equals(onRestartFailurePolicy2.getId()));
+            assertTrue(builder.getTriggerPolicy().getFailure_timeout().equals(onRestartFailurePolicy2.getId()));
+            
+            //
+            // Test remove all existing operational policies
+            //
+            builder = builder.removeAllPolicies();
+            assertTrue(builder.getControlLoop().getTrigger_policy().equals(FinalResult.FINAL_OPENLOOP.toString()));
+            //
+        } catch (BuilderException e) {
+            fail(e.getMessage());
+        }
+    }
+
+	@Test
+	public void testAddOperationsAccumulateParams() {
+		try {
+			ControlLoopPolicyBuilder builder = ControlLoopPolicyBuilder.Factory.buildControlLoop(UUID.randomUUID().toString(), 2400);
+            Policy triggerPolicy = builder.setTriggerPolicy(
+                    "Restart the eNodeB",
+                    "Upon getting the trigger event, restart the eNodeB",
+                    "SDNR",
+                    new Target(TargetType.PNF),
+                    "Restart",
+                    null,
+                    2,
+                    300);
+            //
+            // Add the operationsAccumulateParams
+            //
+            triggerPolicy = builder.addOperationsAccumulateParams(triggerPolicy.getId(), new OperationsAccumulateParams("15m", 5));
+            assertNotNull(builder.getTriggerPolicy().getOperationsAccumulateParams());
+            assertTrue(builder.getTriggerPolicy().getOperationsAccumulateParams().getPeriod().equals("15m"));
+            assertTrue(builder.getTriggerPolicy().getOperationsAccumulateParams().getLimit() == 5);
+            //
+		} catch (BuilderException e) {
+            fail(e.getMessage());
+        }
+	}
+	
+	
+	@Test
+	public void testBuildSpecification() {
+		try {
+			//
+			// Create the builder
+			//
+			ControlLoopPolicyBuilder builder = ControlLoopPolicyBuilder.Factory.buildControlLoop(UUID.randomUUID().toString(), 800);
+			//
+			// Set the first invalid trigger policy
+			//
+			Policy policy1 = builder.setTriggerPolicy(
+                    "Restart the VM",
+                    "Upon getting the trigger event, restart the VM",
+                    null,
+                    null,
+                    "Instantiate",
+                    null,
+                    2,
+                    300);
+			Results results = builder.buildSpecification();
+			//
+			// Check that ERRORs are in results for invalid policy arguments
+			//
+			boolean invalid_actor = false;
+			boolean invalid_recipe = false;
+			boolean invalid_target = false;
+			for (Message m : results.getMessages()) {
+				if (m.getMessage().equals("Policy actor is null") && m.getLevel() == MessageLevel.ERROR) {
+					invalid_actor = true;
+				}
+				if (m.getMessage().equals("Policy recipe is invalid") && m.getLevel() == MessageLevel.ERROR) {
+					invalid_recipe = true;
+				}
+				if (m.getMessage().equals("Policy target is null") && m.getLevel() == MessageLevel.ERROR) {
+					invalid_target = true;
+				}
+			}
+			//
+			assertTrue(invalid_actor);
+			assertTrue(invalid_recipe);
+			assertTrue(invalid_target);
+			//
+			// Remove the invalid policy
+			//
+			//@SuppressWarnings("unused")
+			boolean removed = builder.removePolicy(policy1.getId());
+			assertTrue(removed);
+			assertTrue(builder.getTriggerPolicy() == null);
+			//
+			// Set a valid trigger policy
+			//
+			policy1 = builder.setTriggerPolicy(
+                    "Rebuild VM",
+                    "If the restart fails, rebuild it.",
+                    "APPC",
+                    new Target(TargetType.VM),
+                    "Rebuild",
+                    null,
+                    1,
+                    600);
+			//
+			// Set a second valid trigger policy
+			//
+			Policy policy2 = builder.setTriggerPolicy(
+					"Restart the VM",
+                    "Upon getting the trigger event, restart the VM",
+                    "APPC",
+                    new Target(TargetType.VM),
+                    "Restart",
+                    null,
+                    2,
+                    300);
+			//
+			// Now, we have policy1 unreachable
+			//
+			results = builder.buildSpecification();
+			boolean unreachable = false;
+			for (Message m : results.getMessages()) {
+				if (m.getMessage().equals("Policy " + policy1.getId() + " is not reachable.") && m.getLevel() == MessageLevel.WARNING) {
+					unreachable = true;
+					break;
+				}
+			}
+			assertTrue(unreachable);
+			//
+			// Set policy1 for the failure results of policy2
+			//
+			policy1 = builder.setPolicyForPolicyResult(
+					policy1.getId(), 
+					policy2.getId(),
+					PolicyResult.FAILURE,
+                    PolicyResult.FAILURE_RETRIES,
+                    PolicyResult.FAILURE_TIMEOUT);
+			results = builder.buildSpecification();
+			boolean invalid_timeout = false;
+			for (Message m : results.getMessages()) {
+				if (m.getMessage().equals("controlLoop overall timeout is less than the sum of operational policy timeouts.") && m.getLevel() == MessageLevel.ERROR) {
+					invalid_timeout = true;
+					break;
+				}
+			}
+			assertTrue(invalid_timeout);
+			//
+			// Remove policy2 (revert controlLoop back to open loop) 
+			//
+			removed = builder.removePolicy(policy2.getId());
+			//
+			// ControlLoop is open loop now, but it still has policies (policy1)
+			//
+			results = builder.buildSpecification();
+			unreachable = false;
+			for (Message m : results.getMessages()) {
+				if (m.getMessage().equals("Open Loop policy contains policies. The policies will never be invoked.") && m.getLevel() == MessageLevel.WARNING) {
+					unreachable = true;
+					break;
+				}
+			}
+			assertTrue(unreachable);
+			//
+		} catch (BuilderException e) {
+            fail(e.getMessage());
+        }
+	}
+	
+	
+	@Test
+	public void test() {
+		this.test("src/test/resources/v1.0.0/policy_Test.yaml");
+	}
+	
+	@Test
+	public void testEvilYaml() {
+		try (InputStream is = new FileInputStream(new File("src/test/resources/v1.0.0/test_evil.yaml"))) {
+			//
+			// Read the yaml into our Java Object
+			//
+			Yaml yaml = new Yaml(new Constructor(ControlLoopPolicy.class));
+			yaml.load(is);
+		} catch (FileNotFoundException e) {
+			fail(e.getLocalizedMessage());
+		} catch (IOException e) {
+			fail(e.getLocalizedMessage());
+		} catch (YAMLException e) {
+			//
+			// Should have this
+			//
+		}
+	}
+	
+	public void test(String testFile) {
+		try (InputStream is = new FileInputStream(new File(testFile))) {
+			//
+			// Read the yaml into our Java Object
+			//
+			Yaml yaml = new Yaml(new Constructor(ControlLoopPolicy.class));
+			Object obj = yaml.load(is);
+			assertNotNull(obj);
+			assertTrue(obj instanceof ControlLoopPolicy);
+			ControlLoopPolicy policyTobuild = (ControlLoopPolicy) obj;
+			//
+			// Now we're going to try to use the builder to build this.
+			//
+			ControlLoopPolicyBuilder builder = ControlLoopPolicyBuilder.Factory.buildControlLoop(
+					policyTobuild.getControlLoop().getControlLoopName(),
+					policyTobuild.getControlLoop().getTimeout());
+			//
+			// Add services
+			//
+			if (policyTobuild.getControlLoop().getServices() != null) {
+				builder = builder.addService(policyTobuild.getControlLoop().getServices().toArray(new Service[policyTobuild.getControlLoop().getServices().size()]));
+			}
+			//
+			// Add resources
+			//
+			if (policyTobuild.getControlLoop().getResources() != null) {
+				builder = builder.addResource(policyTobuild.getControlLoop().getResources().toArray(new Resource[policyTobuild.getControlLoop().getResources().size()]));
+			}
+			//
+			// Add the policies and be sure to set the trigger policy
+			//
+			if (policyTobuild.getPolicies() != null) {
+				for (Policy policy : policyTobuild.getPolicies()) {
+					if (policy.getId() == policyTobuild.getControlLoop().getTrigger_policy()) {
+						builder.setTriggerPolicy(policy.getName(), policy.getDescription(), policy.getActor(), policy.getTarget(), policy.getRecipe(), null, policy.getRetry(), policy.getTimeout());
+					}
+				}
+			}
+		
+			// Question : how to change policy ID and results by using builder ??
+		
+			@SuppressWarnings("unused")
+			Results results = builder.buildSpecification();
+			
+		} catch (FileNotFoundException e) {
+			fail(e.getLocalizedMessage());
+		} catch (IOException e) {
+			fail(e.getLocalizedMessage());
+		} catch (BuilderException e) {
+			fail(e.getLocalizedMessage());
+		}
+		
+	}
+
+}
diff --git a/ONAP-ControlloopPolicy/src/test/java/org/onap/policy/controlloop/policy/ControlLoopPolicyTest.java b/ONAP-ControlloopPolicy/src/test/java/org/onap/policy/controlloop/policy/ControlLoopPolicyTest.java
new file mode 100644
index 0000000..a7cb668
--- /dev/null
+++ b/ONAP-ControlloopPolicy/src/test/java/org/onap/policy/controlloop/policy/ControlLoopPolicyTest.java
@@ -0,0 +1,101 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP Policy Engine
+ * ================================================================================
+ * 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.policy;
+
+import static org.junit.Assert.*;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.junit.Test;
+import org.yaml.snakeyaml.DumperOptions;
+import org.yaml.snakeyaml.DumperOptions.FlowStyle;
+import org.yaml.snakeyaml.Yaml;
+import org.yaml.snakeyaml.constructor.Constructor;
+
+
+public class ControlLoopPolicyTest {
+
+	@Test 
+	public void test() {
+		this.test("src/test/resources/v1.0.0/policy_Test.yaml");
+	}
+
+	@Test 
+	public void testMultipleService() {
+		this.test("src/test/resources/v1.0.0/policy_Test_MultipleService.yaml");
+	}
+
+	@Test 
+	public void testOpenLoop() {
+		this.test("src/test/resources/v1.0.0/policy_OpenLoop_1610.yaml");
+	}
+	
+	@Test 
+	public void testONAPvDNS() {
+		this.test("src/test/resources/v2.0.0/policy_ONAP_demo_vDNS.yaml");
+	}
+
+	public void test(String testFile) {
+		try (InputStream is = new FileInputStream(new File(testFile))) {
+			//
+			// Read the yaml into our Java Object
+			//
+			Yaml yaml = new Yaml(new Constructor(ControlLoopPolicy.class));
+			Object obj = yaml.load(is);
+			assertNotNull(obj);
+			assertTrue(obj instanceof ControlLoopPolicy);
+			dump(obj);
+			//
+			// Now dump it to a yaml string
+			//
+			DumperOptions options = new DumperOptions();
+			options.setDefaultFlowStyle(FlowStyle.BLOCK);
+			options.setPrettyFlow(true);
+			yaml = new Yaml(options);
+			String dumpedYaml = yaml.dump(obj);
+			System.out.println(dumpedYaml);
+			//
+			// Read that string back into our java object
+			//
+			Object newObject = yaml.load(dumpedYaml);
+			dump(newObject);
+			assertNotNull(newObject);
+			assertTrue(newObject instanceof ControlLoopPolicy);
+			//
+			// Have to comment it out tentatively since it causes junit to fail. 
+			// Seems we cannot use assertEquals here. Need advice.
+			//
+			//assertEquals(newObject, obj);
+		} catch (FileNotFoundException e) {
+			fail(e.getLocalizedMessage());
+		} catch (IOException e) {
+			fail(e.getLocalizedMessage());
+		}
+	}
+	
+	public void dump(Object obj) {
+		System.out.println("Dumping " + obj.getClass().getCanonicalName());
+		System.out.println(obj.toString());
+	}
+}
diff --git a/ONAP-ControlloopPolicy/src/test/java/org/onap/policy/controlloop/policy/guard/ControlLoopGuardBuilderTest.java b/ONAP-ControlloopPolicy/src/test/java/org/onap/policy/controlloop/policy/guard/ControlLoopGuardBuilderTest.java
new file mode 100644
index 0000000..0dfb1cc
--- /dev/null
+++ b/ONAP-ControlloopPolicy/src/test/java/org/onap/policy/controlloop/policy/guard/ControlLoopGuardBuilderTest.java
@@ -0,0 +1,202 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP Policy Engine
+ * ================================================================================
+ * 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.policy.guard;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+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.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import org.junit.Test;
+import org.onap.policy.controlloop.policy.builder.BuilderException;
+import org.onap.policy.controlloop.policy.builder.Message;
+import org.onap.policy.controlloop.policy.builder.MessageLevel;
+import org.onap.policy.controlloop.policy.builder.Results;
+import org.onap.policy.controlloop.policy.guard.builder.ControlLoopGuardBuilder;
+import org.yaml.snakeyaml.Yaml;
+import org.yaml.snakeyaml.constructor.Constructor;
+
+public class ControlLoopGuardBuilderTest {
+	
+	@Test
+	public void testControlLoopGuard() {
+		try {
+			//
+			// Create a builder
+			//
+			ControlLoopGuardBuilder builder = ControlLoopGuardBuilder.Factory.buildControlLoopGuard(new Guard());
+			//
+			// Assert there is no guard policies yet
+			//
+			Results results = builder.buildSpecification();
+			boolean no_guard_policies = false;
+			for (Message m : results.getMessages()) {
+				if (m.getMessage().equals("ControlLoop Guard should have at least one guard policies") && m.getLevel() == MessageLevel.ERROR) {
+					no_guard_policies = true;
+					break;
+				}
+			}
+			assertTrue(no_guard_policies);
+			//
+			// Add a guard policy without limit constraint
+			//
+            String clname = "CL_vUSP123";
+            LinkedList<String> targets = new LinkedList<String>();
+            targets.add("s1");
+            targets.add("s2");
+            targets.add("s3");
+            MatchParameters matchParameters = new MatchParameters(clname, "APPC", "Restart", targets);
+            GuardPolicy policy1 = new GuardPolicy("id123", "guardpolicy1", "description aaa", matchParameters);
+			builder = builder.addGuardPolicy(policy1);
+			//
+			// Assert there is no limit constraint associated with the only guard policy
+			//
+			results = builder.buildSpecification();
+			boolean no_constraint = false;
+			for (Message m : results.getMessages()) {
+				if (m.getMessage().equals("Guard policy guardpolicy1 does not have any limit constraint") && m.getLevel() == MessageLevel.ERROR) {
+					no_constraint = true;
+					break;
+				}
+			}
+			assertTrue(no_constraint);
+			//
+			// Add a constraint to policy1
+			//
+            Map<String, String> active_time_range = new HashMap<String, String>();
+            active_time_range.put("start", "00:00:00-05:00");
+            active_time_range.put("end", "23:59:59-05:00");
+			List<String> blacklist = new LinkedList<String>();
+			blacklist.add("eNodeB_common_id1");
+			blacklist.add("eNodeB_common_id2");
+            Map<String, String> time_window = new HashMap<String, String>();
+            time_window.put("value", "10");
+            time_window.put("units", "minute");
+            Constraint cons = new Constraint(5, time_window, active_time_range, blacklist);
+			builder = builder.addLimitConstraint(policy1.getId(), cons);
+			//
+			// Add a duplicate constraint to policy1
+			//
+			builder = builder.addLimitConstraint(policy1.getId(), cons);
+			//
+			// Assert there are duplicate constraints associated with the only guard policy
+			//
+			results = builder.buildSpecification();
+			boolean duplicate_constraint = false;
+			for (Message m : results.getMessages()) {
+				if (m.getMessage().equals("Guard policy guardpolicy1 has duplicate limit constraints") && m.getLevel() == MessageLevel.WARNING) {
+					duplicate_constraint = true;
+					break;
+				}
+			}
+			assertTrue(duplicate_constraint);
+			//
+			// Remove the duplicate constraint
+			//
+			builder = builder.removeLimitConstraint(policy1.getId(), cons);
+			//
+			// Add a duplicate guard policy 
+			//
+			builder = builder.addGuardPolicy(policy1);
+			builder = builder.addLimitConstraint(policy1.getId(), cons);
+			//
+			// Assert there are duplicate guard policies
+			//
+			results = builder.buildSpecification();
+			boolean duplicate_guard_policy = false;
+			for (Message m : results.getMessages()) {
+				if (m.getMessage().equals("There are duplicate guard policies") && m.getLevel() == MessageLevel.WARNING) {
+					duplicate_guard_policy = true;
+					break;
+				}
+			}
+			assertTrue(duplicate_guard_policy);
+			//
+			// Remove the duplicate guard policy
+			//
+			builder = builder.removeGuardPolicy(policy1);
+			//
+			// Assert there are no Error/Warning message
+			//
+			results = builder.buildSpecification();
+			assertTrue(results.getMessages().size() == 1);
+			//
+		} catch (BuilderException e) {
+			fail(e.getMessage());
+		}
+	}
+	
+	@Test
+	public void test1() {
+		this.test("src/test/resources/v2.0.0-guard/policy_guard_ONAP_demo_vDNS.yaml");
+	}
+	
+	@Test
+	public void test2() {
+		this.test("src/test/resources/v2.0.0-guard/policy_guard_1707_appc.yaml");
+	}
+	
+	public void test(String testFile) {
+		try (InputStream is = new FileInputStream(new File(testFile))) {
+			//
+			// Read the yaml into our Java Object
+			//
+			Yaml yaml = new Yaml(new Constructor(ControlLoopGuard.class));
+			Object obj = yaml.load(is);
+			assertNotNull(obj);
+			assertTrue(obj instanceof ControlLoopGuard);
+			ControlLoopGuard guardTobuild = (ControlLoopGuard) obj;
+			//
+			// Now we're going to try to use the builder to build this.
+			//
+			ControlLoopGuardBuilder builder = ControlLoopGuardBuilder.Factory.buildControlLoopGuard(guardTobuild.getGuard());
+			//
+			// Add guard policy
+			//
+			if (guardTobuild.getGuards() != null) {
+				builder = builder.addGuardPolicy(guardTobuild.getGuards().toArray(new GuardPolicy[guardTobuild.getGuards().size()]));
+			}
+			//
+			// Build the specification
+			//
+			Results results = builder.buildSpecification();
+			//
+			// Print out the specification
+			//
+			System.out.println(results.getSpecification());
+			//
+		} catch (FileNotFoundException e) {
+			fail(e.getLocalizedMessage());
+		} catch (IOException e) {
+			fail(e.getLocalizedMessage());
+		} catch (BuilderException e) {
+			fail(e.getLocalizedMessage());
+		}
+	}
+}
diff --git a/ONAP-ControlloopPolicy/src/test/java/org/onap/policy/controlloop/policy/guard/ControlLoopGuardTest.java b/ONAP-ControlloopPolicy/src/test/java/org/onap/policy/controlloop/policy/guard/ControlLoopGuardTest.java
new file mode 100644
index 0000000..5cb0007
--- /dev/null
+++ b/ONAP-ControlloopPolicy/src/test/java/org/onap/policy/controlloop/policy/guard/ControlLoopGuardTest.java
@@ -0,0 +1,93 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP Policy Engine
+ * ================================================================================
+ * 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.policy.guard;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+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 org.junit.Test;
+import org.yaml.snakeyaml.DumperOptions;
+import org.yaml.snakeyaml.DumperOptions.FlowStyle;
+import org.yaml.snakeyaml.Yaml;
+import org.yaml.snakeyaml.constructor.Constructor;
+
+
+public class ControlLoopGuardTest {
+
+	@Test 
+	public void testGuardvDNS() {
+		this.test("src/test/resources/v2.0.0-guard/policy_guard_ONAP_demo_vDNS.yaml");
+	}
+
+	@Test 
+	public void testGuardvUSP() {
+		this.test("src/test/resources/v2.0.0-guard/policy_guard_1707_appc.yaml");
+	}
+	
+	public void test(String testFile) {
+		try (InputStream is = new FileInputStream(new File(testFile))) {
+			//
+			// Read the yaml into our Java Object
+			//
+			Yaml yaml = new Yaml(new Constructor(ControlLoopGuard.class));
+			Object obj = yaml.load(is);
+			assertNotNull(obj);
+			assertTrue(obj instanceof ControlLoopGuard);
+			dump(obj);
+			//
+			// Now dump it to a yaml string
+			//
+			DumperOptions options = new DumperOptions();
+			options.setDefaultFlowStyle(FlowStyle.BLOCK);
+			options.setPrettyFlow(true);
+			yaml = new Yaml(options);
+			String dumpedYaml = yaml.dump(obj);
+			System.out.println(dumpedYaml);
+			//
+			// Read that string back into our java object
+			//
+			Object newObject = yaml.load(dumpedYaml);
+			dump(newObject);
+			assertNotNull(newObject);
+			assertTrue(newObject instanceof ControlLoopGuard);
+			//
+			// Have to comment it out tentatively since it causes junit to fail. 
+			// Seems we cannot use assertEquals here. Need advice.
+			//
+			//assertEquals(newObject, obj);
+		} catch (FileNotFoundException e) {
+			fail(e.getLocalizedMessage());
+		} catch (IOException e) {
+			fail(e.getLocalizedMessage());
+		}
+	}
+	
+	public void dump(Object obj) {
+		System.out.println("Dumping " + obj.getClass().getCanonicalName());
+		System.out.println(obj.toString());
+	}
+}
diff --git a/ONAP-ControlloopPolicy/src/test/resources/v1.0.0/bad_policies_1.yaml b/ONAP-ControlloopPolicy/src/test/resources/v1.0.0/bad_policies_1.yaml
new file mode 100644
index 0000000..f6ad684
--- /dev/null
+++ b/ONAP-ControlloopPolicy/src/test/resources/v1.0.0/bad_policies_1.yaml
@@ -0,0 +1,25 @@
+controlLoop:
+  controlLoopName: ControlLoop-TEST-5dfa8fce-bd7a-4424-b60d-ee2ad2f254a3
+  version: 1.0.0
+  services: 
+    - serviceName: Foo Service
+  resources: 
+    - resourceName: Bar VNF
+      resourceType: VF
+  trigger_policy: unique-policy-id-1-restart
+  timeout: 1200
+
+policies:
+  - id: unique-policy-id-1-restart
+    name: Restart Policy for Trigger Event
+    description:
+    actor: APPC
+    recipe: Restart
+    target: VM
+    retry: 2
+    timeout: 300
+    success: FINAL_FAILURE
+    failure: unique-policy-id-3-rebuild
+    failure_timeout: unique-policy-id-3-rebuild
+    failure_retries: unique-policy-id-3-rebuild
+    failure_exception: final_failure_exception
diff --git a/ONAP-ControlloopPolicy/src/test/resources/v1.0.0/bad_trigger_1.yaml b/ONAP-ControlloopPolicy/src/test/resources/v1.0.0/bad_trigger_1.yaml
new file mode 100644
index 0000000..981229c
--- /dev/null
+++ b/ONAP-ControlloopPolicy/src/test/resources/v1.0.0/bad_trigger_1.yaml
@@ -0,0 +1,95 @@
+controlLoop:
+  controlLoopName: ControlLoop-TEST-5dfa8fce-bd7a-4424-b60d-ee2ad2f254a3
+  version: 1.0.0
+  services: 
+    - serviceName: Foo Service
+  resources: 
+    - resourceName: Bar VNF
+      resourceType: VF
+  trigger_policy: FOO
+  timeout: 1200
+
+policies:
+  - id: unique-policy-id-1-restart
+    name: Restart Policy for Trigger Event
+    description:
+    actor: APPC
+    recipe: Restart
+    target: VM
+    retry: 2
+    timeout: 300
+    success: unique-policy-id-2-healthcheck-restart
+    failure: unique-policy-id-3-rebuild
+    failure_timeout: unique-policy-id-3-rebuild
+    failure_retries: unique-policy-id-3-rebuild
+    failure_exception: final_failure_exception
+  
+  - id: unique-policy-id-2-healthcheck-restart
+    name: HealthCheck Policy
+    description:
+    actor: APPC
+    recipe: HealthCheck
+    target: VM
+    retry: 2
+    timeout: 300
+    success: final_success
+    failure: unique-policy-id-3-rebuild
+    failure_timeout: unique-policy-id-3-rebuild
+    failure_retries: unique-policy-id-3-rebuild
+    failure_exception: final_failure_exception
+  
+  - id: unique-policy-id-3-rebuild
+    name: Rebuild Policy
+    description:
+    actor: APPC
+    recipe: Rebuild
+    target: VM
+    retry: 0
+    timeout: 600
+    success: unique-policy-id-4-healthcheck-rebuild
+    failure: unique-policy-id-5-migrate
+    failure_timeout: unique-policy-id-5-migrate
+    failure_retries: unique-policy-id-5-migrate
+    failure_exception: final_failure_exception
+  
+  - id: unique-policy-id-4-healthcheck-rebuild
+    name: HealthCheck the Rebuild Policy
+    description:
+    actor: APPC
+    recipe: HealthCheck
+    target: VM
+    retry: 2
+    timeout: 300
+    success: final_success
+    failure: unique-policy-id-5-migrate
+    failure_timeout: unique-policy-id-5-migrate
+    failure_retries: unique-policy-id-5-migrate
+    failure_exception: final_failure_exception
+  
+  - id: unique-policy-id-5-migrate
+    name: Migrate Policy
+    description:
+    actor: APPC
+    recipe: Migrate
+    target: VM
+    retry: 0
+    timeout: 600
+    success: unique-policy-id-6-healthcheck-migrate
+    failure: final_failure
+    failure_timeout: final_failure_timeout
+    failure_retries: final_failure_retries
+    failure_exception: final_failure_exception
+
+  - id: unique-policy-id-6-healthcheck-migrate
+    name: Healthcheck the Migrate Policy
+    description:
+    actor: APPC
+    recipe: HealthCheck
+    target: VM
+    retry: 2
+    timeout: 300
+    success: final_success
+    failure: final_failure
+    failure_timeout: final_failure_timeout
+    failure_retries: final_failure_retries
+    failure_exception: final_failure_exception
diff --git a/ONAP-ControlloopPolicy/src/test/resources/v1.0.0/bad_trigger_2.yaml b/ONAP-ControlloopPolicy/src/test/resources/v1.0.0/bad_trigger_2.yaml
new file mode 100644
index 0000000..1f9715b
--- /dev/null
+++ b/ONAP-ControlloopPolicy/src/test/resources/v1.0.0/bad_trigger_2.yaml
@@ -0,0 +1,95 @@
+controlLoop:
+  controlLoopName: ControlLoop-TEST-5dfa8fce-bd7a-4424-b60d-ee2ad2f254a3
+  version: 1.0.0
+  services: 
+    - serviceName: Foo Service
+  resources: 
+    - resourceName: Bar VNF
+      resourceType: VF
+  trigger_policy: FINAL_SUCCESS
+  timeout: 1200
+
+policies:
+  - id: unique-policy-id-1-restart
+    name: Restart Policy for Trigger Event
+    description:
+    actor: APPC
+    recipe: Restart
+    target: VM
+    retry: 2
+    timeout: 300
+    success: unique-policy-id-2-healthcheck-restart
+    failure: unique-policy-id-3-rebuild
+    failure_timeout: unique-policy-id-3-rebuild
+    failure_retries: unique-policy-id-3-rebuild
+    failure_exception: final_failure_exception
+  
+  - id: unique-policy-id-2-healthcheck-restart
+    name: HealthCheck Policy
+    description:
+    actor: APPC
+    recipe: HealthCheck
+    target: VM
+    retry: 2
+    timeout: 300
+    success: final_success
+    failure: unique-policy-id-3-rebuild
+    failure_timeout: unique-policy-id-3-rebuild
+    failure_retries: unique-policy-id-3-rebuild
+    failure_exception: final_failure_exception
+  
+  - id: unique-policy-id-3-rebuild
+    name: Rebuild Policy
+    description:
+    actor: APPC
+    recipe: Rebuild
+    target: VM
+    retry: 0
+    timeout: 600
+    success: unique-policy-id-4-healthcheck-rebuild
+    failure: unique-policy-id-5-migrate
+    failure_timeout: unique-policy-id-5-migrate
+    failure_retries: unique-policy-id-5-migrate
+    failure_exception: final_failure_exception
+  
+  - id: unique-policy-id-4-healthcheck-rebuild
+    name: HealthCheck the Rebuild Policy
+    description:
+    actor: APPC
+    recipe: HealthCheck
+    target: VM
+    retry: 2
+    timeout: 300
+    success: final_success
+    failure: unique-policy-id-5-migrate
+    failure_timeout: unique-policy-id-5-migrate
+    failure_retries: unique-policy-id-5-migrate
+    failure_exception: final_failure_exception
+  
+  - id: unique-policy-id-5-migrate
+    name: Migrate Policy
+    description:
+    actor: APPC
+    recipe: Migrate
+    target: VM
+    retry: 0
+    timeout: 600
+    success: unique-policy-id-6-healthcheck-migrate
+    failure: final_failure
+    failure_timeout: final_failure_timeout
+    failure_retries: final_failure_retries
+    failure_exception: final_failure_exception
+
+  - id: unique-policy-id-6-healthcheck-migrate
+    name: Healthcheck the Migrate Policy
+    description:
+    actor: APPC
+    recipe: HealthCheck
+    target: VM
+    retry: 2
+    timeout: 300
+    success: final_success
+    failure: final_failure
+    failure_timeout: final_failure_timeout
+    failure_retries: final_failure_retries
+    failure_exception: final_failure_exception
diff --git a/ONAP-ControlloopPolicy/src/test/resources/v1.0.0/policy_OpenLoop_1610.yaml b/ONAP-ControlloopPolicy/src/test/resources/v1.0.0/policy_OpenLoop_1610.yaml
new file mode 100644
index 0000000..7fd27fa
--- /dev/null
+++ b/ONAP-ControlloopPolicy/src/test/resources/v1.0.0/policy_OpenLoop_1610.yaml
@@ -0,0 +1,12 @@
+controlLoop:
+  version: 1.0.0
+  controlLoopName: ControlLoop-Open-fac4ae3d-c3f5-4bab-8e54-0a8581ede132
+  services:
+    - serviceName: Service
+  resources:
+    - resourceType: VF
+      resourceName: Example
+  trigger_policy: final_openloop
+  timeout: 0
+
+policies:
diff --git a/ONAP-ControlloopPolicy/src/test/resources/v1.0.0/policy_Test.yaml b/ONAP-ControlloopPolicy/src/test/resources/v1.0.0/policy_Test.yaml
new file mode 100644
index 0000000..b89a725
--- /dev/null
+++ b/ONAP-ControlloopPolicy/src/test/resources/v1.0.0/policy_Test.yaml
@@ -0,0 +1,95 @@
+controlLoop:
+  controlLoopName: ControlLoop-TEST-5dfa8fce-bd7a-4424-b60d-ee2ad2f254a3
+  version: 1.0.0
+  services: 
+    - serviceName: Foo Service
+  resources: 
+    - resourceName: Bar VNF
+      resourceType: VF
+  trigger_policy: unique-policy-id-1-restart
+  timeout: 1200
+
+policies:
+  - id: unique-policy-id-1-restart
+    name: Restart Policy for Trigger Event
+    description:
+    actor: APPC
+    recipe: Restart
+    target: VM
+    retry: 2
+    timeout: 300
+    success: unique-policy-id-2-healthcheck-restart
+    failure: unique-policy-id-3-rebuild
+    failure_timeout: unique-policy-id-3-rebuild
+    failure_retries: unique-policy-id-3-rebuild
+    failure_exception: final_failure_exception
+  
+  - id: unique-policy-id-2-healthcheck-restart
+    name: HealthCheck Policy
+    description:
+    actor: APPC
+    recipe: HealthCheck
+    target: VM
+    retry: 2
+    timeout: 300
+    success: final_success
+    failure: unique-policy-id-3-rebuild
+    failure_timeout: unique-policy-id-3-rebuild
+    failure_retries: unique-policy-id-3-rebuild
+    failure_exception: final_failure_exception
+  
+  - id: unique-policy-id-3-rebuild
+    name: Rebuild Policy
+    description:
+    actor: APPC
+    recipe: Rebuild
+    target: VM
+    retry: 0
+    timeout: 600
+    success: unique-policy-id-4-healthcheck-rebuild
+    failure: unique-policy-id-5-migrate
+    failure_timeout: unique-policy-id-5-migrate
+    failure_retries: unique-policy-id-5-migrate
+    failure_exception: final_failure_exception
+  
+  - id: unique-policy-id-4-healthcheck-rebuild
+    name: HealthCheck the Rebuild Policy
+    description:
+    actor: APPC
+    recipe: HealthCheck
+    target: VM
+    retry: 2
+    timeout: 300
+    success: final_success
+    failure: unique-policy-id-5-migrate
+    failure_timeout: unique-policy-id-5-migrate
+    failure_retries: unique-policy-id-5-migrate
+    failure_exception: final_failure_exception
+  
+  - id: unique-policy-id-5-migrate
+    name: Migrate Policy
+    description:
+    actor: APPC
+    recipe: Migrate
+    target: VM
+    retry: 0
+    timeout: 600
+    success: unique-policy-id-6-healthcheck-migrate
+    failure: final_failure
+    failure_timeout: final_failure_timeout
+    failure_retries: final_failure_retries
+    failure_exception: final_failure_exception
+
+  - id: unique-policy-id-6-healthcheck-migrate
+    name: Healthcheck the Migrate Policy
+    description:
+    actor: APPC
+    recipe: HealthCheck
+    target: VM
+    retry: 2
+    timeout: 300
+    success: final_success
+    failure: final_failure
+    failure_timeout: final_failure_timeout
+    failure_retries: final_failure_retries
+    failure_exception: final_failure_exception
diff --git a/ONAP-ControlloopPolicy/src/test/resources/v1.0.0/policy_Test_MultipleService.yaml b/ONAP-ControlloopPolicy/src/test/resources/v1.0.0/policy_Test_MultipleService.yaml
new file mode 100644
index 0000000..8ce7077
--- /dev/null
+++ b/ONAP-ControlloopPolicy/src/test/resources/v1.0.0/policy_Test_MultipleService.yaml
@@ -0,0 +1,26 @@
+controlLoop:
+  version: 1.0.0
+  controlLoopName: ClosedLoop-FRWL-SIG-d925ed73-8231-4d02-9545-db4e101f88f8
+  services: 
+    - serviceName: vSCP
+    - serviceName: vSBG
+  resources: 
+    - resourceName: F5FW
+      resourceType: VF
+  trigger_policy: unique-policy-id-1-restart
+  timeout: 1200
+
+policies:
+  - id: unique-policy-id-1-restart
+    name: Restart Policy
+    description:
+    actor: APPC
+    recipe: Restart
+    target: VM
+    retry: 2
+    timeout: 300
+    success: final_success
+    failure: final_failure
+    failure_timeout: final_failure_timeout
+    failure_retries: final_failure_retries
+    failure_exception: final_failure_exception
diff --git a/ONAP-ControlloopPolicy/src/test/resources/v1.0.0/test.yaml b/ONAP-ControlloopPolicy/src/test/resources/v1.0.0/test.yaml
new file mode 100644
index 0000000..b89a725
--- /dev/null
+++ b/ONAP-ControlloopPolicy/src/test/resources/v1.0.0/test.yaml
@@ -0,0 +1,95 @@
+controlLoop:
+  controlLoopName: ControlLoop-TEST-5dfa8fce-bd7a-4424-b60d-ee2ad2f254a3
+  version: 1.0.0
+  services: 
+    - serviceName: Foo Service
+  resources: 
+    - resourceName: Bar VNF
+      resourceType: VF
+  trigger_policy: unique-policy-id-1-restart
+  timeout: 1200
+
+policies:
+  - id: unique-policy-id-1-restart
+    name: Restart Policy for Trigger Event
+    description:
+    actor: APPC
+    recipe: Restart
+    target: VM
+    retry: 2
+    timeout: 300
+    success: unique-policy-id-2-healthcheck-restart
+    failure: unique-policy-id-3-rebuild
+    failure_timeout: unique-policy-id-3-rebuild
+    failure_retries: unique-policy-id-3-rebuild
+    failure_exception: final_failure_exception
+  
+  - id: unique-policy-id-2-healthcheck-restart
+    name: HealthCheck Policy
+    description:
+    actor: APPC
+    recipe: HealthCheck
+    target: VM
+    retry: 2
+    timeout: 300
+    success: final_success
+    failure: unique-policy-id-3-rebuild
+    failure_timeout: unique-policy-id-3-rebuild
+    failure_retries: unique-policy-id-3-rebuild
+    failure_exception: final_failure_exception
+  
+  - id: unique-policy-id-3-rebuild
+    name: Rebuild Policy
+    description:
+    actor: APPC
+    recipe: Rebuild
+    target: VM
+    retry: 0
+    timeout: 600
+    success: unique-policy-id-4-healthcheck-rebuild
+    failure: unique-policy-id-5-migrate
+    failure_timeout: unique-policy-id-5-migrate
+    failure_retries: unique-policy-id-5-migrate
+    failure_exception: final_failure_exception
+  
+  - id: unique-policy-id-4-healthcheck-rebuild
+    name: HealthCheck the Rebuild Policy
+    description:
+    actor: APPC
+    recipe: HealthCheck
+    target: VM
+    retry: 2
+    timeout: 300
+    success: final_success
+    failure: unique-policy-id-5-migrate
+    failure_timeout: unique-policy-id-5-migrate
+    failure_retries: unique-policy-id-5-migrate
+    failure_exception: final_failure_exception
+  
+  - id: unique-policy-id-5-migrate
+    name: Migrate Policy
+    description:
+    actor: APPC
+    recipe: Migrate
+    target: VM
+    retry: 0
+    timeout: 600
+    success: unique-policy-id-6-healthcheck-migrate
+    failure: final_failure
+    failure_timeout: final_failure_timeout
+    failure_retries: final_failure_retries
+    failure_exception: final_failure_exception
+
+  - id: unique-policy-id-6-healthcheck-migrate
+    name: Healthcheck the Migrate Policy
+    description:
+    actor: APPC
+    recipe: HealthCheck
+    target: VM
+    retry: 2
+    timeout: 300
+    success: final_success
+    failure: final_failure
+    failure_timeout: final_failure_timeout
+    failure_retries: final_failure_retries
+    failure_exception: final_failure_exception
diff --git a/ONAP-ControlloopPolicy/src/test/resources/v1.0.0/test_evil.yaml b/ONAP-ControlloopPolicy/src/test/resources/v1.0.0/test_evil.yaml
new file mode 100644
index 0000000..347e84e
--- /dev/null
+++ b/ONAP-ControlloopPolicy/src/test/resources/v1.0.0/test_evil.yaml
@@ -0,0 +1,25 @@
+controlLoop:
+  controlLoopName: ControlLoop-TEST-5dfa8fce-bd7a-4424-b60d-ee2ad2f254a3
+  version: 1.0.0
+  services: 
+    - serviceName: Foo Service
+  resources: 
+    - resourceName: Bar VNF
+      resourceType: VF
+  trigger_policy: unique-policy-id-1-restart
+  timeout: 1200
+
+policies:
+  - id: unique-policy-id-1-restart
+    name: Restart Policy for Trigger Event
+    description:
+    actor: MSO
+    recipe: Instantiate
+    target: VM
+    retry: 2
+    timeout: 300
+    success: final_failure_exception
+    failure: final_success
+    failure_timeout: final_success
+    failure_retries: final_success
+    failure_exception: final_failure_exception
diff --git a/ONAP-ControlloopPolicy/src/test/resources/v2.0.0-guard/duplicate_guard_constraint.yaml b/ONAP-ControlloopPolicy/src/test/resources/v2.0.0-guard/duplicate_guard_constraint.yaml
new file mode 100644
index 0000000..adb1ca1
--- /dev/null
+++ b/ONAP-ControlloopPolicy/src/test/resources/v2.0.0-guard/duplicate_guard_constraint.yaml
@@ -0,0 +1,21 @@
+guard:
+  version: 2.0.0
+
+guards:
+  - id: unique_guard_vUSP_1
+    name: APPC 5 Restart
+    description: 
+      We only allow 5 restarts over 15 minute window during the day time hours (i.e. avoid midnight to 5am)
+    actor: APPC
+    recipe: Restart
+    limit_constraints:
+      #
+      - num: 5
+        time_in_range:
+          arg2: PT5H
+          arg3: PT24H
+      #
+      - num: 5
+        time_in_range:
+          arg2: PT5H
+          arg3: PT24H
\ No newline at end of file
diff --git a/ONAP-ControlloopPolicy/src/test/resources/v2.0.0-guard/duplicate_guard_policy.yaml b/ONAP-ControlloopPolicy/src/test/resources/v2.0.0-guard/duplicate_guard_policy.yaml
new file mode 100644
index 0000000..2d54e85
--- /dev/null
+++ b/ONAP-ControlloopPolicy/src/test/resources/v2.0.0-guard/duplicate_guard_policy.yaml
@@ -0,0 +1,27 @@
+guard:
+  version: 2.0.0
+
+guards:
+  - id: unique_guard_vUSP_1
+    name: APPC 5 Restart
+    description: 
+      We only allow 5 restarts over 15 minute window during the day time hours (i.e. avoid midnight to 5am)
+    actor: APPC
+    recipe: Restart
+    limit_constraints:
+      - num: 5
+        time_in_range:
+          arg2: PT5H
+          arg3: PT24H
+  #
+  - id: unique_guard_vUSP_1
+    name: APPC 5 Restart
+    description: 
+      We only allow 5 restarts over 15 minute window during the day time hours (i.e. avoid midnight to 5am)
+    actor: APPC
+    recipe: Restart
+    limit_constraints:
+      - num: 5
+        time_in_range:
+          arg2: PT5H
+          arg3: PT24H
\ No newline at end of file
diff --git a/ONAP-ControlloopPolicy/src/test/resources/v2.0.0-guard/no_guard_constraint.yaml b/ONAP-ControlloopPolicy/src/test/resources/v2.0.0-guard/no_guard_constraint.yaml
new file mode 100644
index 0000000..6ab3d67
--- /dev/null
+++ b/ONAP-ControlloopPolicy/src/test/resources/v2.0.0-guard/no_guard_constraint.yaml
@@ -0,0 +1,11 @@
+guard:
+  version: 2.0.0
+
+guards:
+  - id: unique_guard_vUSP_1
+    name: APPC 5 Restart
+    description: 
+      We only allow 5 restarts over 15 minute window during the day time hours (i.e. avoid midnight to 5am)
+    actor: APPC
+    recipe: Restart
+  
\ No newline at end of file
diff --git a/ONAP-ControlloopPolicy/src/test/resources/v2.0.0-guard/no_guard_policy.yaml b/ONAP-ControlloopPolicy/src/test/resources/v2.0.0-guard/no_guard_policy.yaml
new file mode 100644
index 0000000..51f41d4
--- /dev/null
+++ b/ONAP-ControlloopPolicy/src/test/resources/v2.0.0-guard/no_guard_policy.yaml
@@ -0,0 +1,2 @@
+guard:
+  version: 2.0.0
diff --git a/ONAP-ControlloopPolicy/src/test/resources/v2.0.0-guard/policy_guard_1707_appc.yaml b/ONAP-ControlloopPolicy/src/test/resources/v2.0.0-guard/policy_guard_1707_appc.yaml
new file mode 100644
index 0000000..6442cd5
--- /dev/null
+++ b/ONAP-ControlloopPolicy/src/test/resources/v2.0.0-guard/policy_guard_1707_appc.yaml
@@ -0,0 +1,24 @@
+guard:
+  version: 2.0.0
+
+guards:
+  - id: unique_guard_vUSP_1
+    name: APPC 5 Restart
+    description: 
+      We only allow 5 restarts over 15 minute window during the day time hours (i.e. avoid midnight to 5am)
+    match_parameters:
+      controlLoopName: CL_NAME_ABC_123
+      actor: APPC
+      recipe: Restart
+      targets:
+        - s1
+          s2
+          s3
+    limit_constraints:
+      - freq_limit_per_target: 5
+        time_window: 
+          value: 15
+          units: minute
+        active_time_range:
+          start: 00:00:00-05:00
+          end: 23:59:59-05:00
\ No newline at end of file
diff --git a/ONAP-ControlloopPolicy/src/test/resources/v2.0.0-guard/policy_guard_ONAP_demo_vDNS.yaml b/ONAP-ControlloopPolicy/src/test/resources/v2.0.0-guard/policy_guard_ONAP_demo_vDNS.yaml
new file mode 100644
index 0000000..f2390fa
--- /dev/null
+++ b/ONAP-ControlloopPolicy/src/test/resources/v2.0.0-guard/policy_guard_ONAP_demo_vDNS.yaml
@@ -0,0 +1,19 @@
+guard:
+  version: 2.0.0
+
+guards:
+  - id: unique_guard_ONAP_vDNS_1
+    name: MSO Spinup
+    description: We only spin up 1 instance over a 10 minute window
+    match_parameters:
+      actor: MSO
+      recipe: VF Module Create
+    limit_constraints:
+      - freq_limit_per_target: 1
+        #
+        # https://www.w3.org/TR/xmlschema-2/#duration
+        #
+        time_window:
+          value: 10
+          units: hour
+        
\ No newline at end of file
diff --git a/ONAP-ControlloopPolicy/src/test/resources/v2.0.0/Demo-1.0.0-HeatTemplates/resource-59a2ee3fB58045feB5a1-template.yml b/ONAP-ControlloopPolicy/src/test/resources/v2.0.0/Demo-1.0.0-HeatTemplates/resource-59a2ee3fB58045feB5a1-template.yml
new file mode 100644
index 0000000..4b50195
--- /dev/null
+++ b/ONAP-ControlloopPolicy/src/test/resources/v2.0.0/Demo-1.0.0-HeatTemplates/resource-59a2ee3fB58045feB5a1-template.yml
@@ -0,0 +1,1698 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+metadata:
+  invariantUUID: 4b8d4018-068b-4c33-b9bb-d980798e52c2
+  UUID: d7d28881-b24d-4512-bfee-1e2eb335591f
+  name: 59a2ee3f-b580-45fe-b5a1
+  description: vendor software product
+  type: VF
+  category: Generic
+  subcategory: Abstract
+  resourceVendor: 185c637a-3885-463e-8fd0
+  resourceVendorRelease: '1.0'
+imports:
+- NeutronNet:
+    file: resource-Neutronnet-template.yml
+- NeutronPort:
+    file: resource-Neutronport-template.yml
+- 59a2ee3fB58045feB5a1.nodes.heat.vlb:
+    file: resource-59a2ee3fb58045feb5a1NodesHeatVlb-template.yml
+- 59a2ee3fB58045feB5a1.nodes.heat.vdns:
+    file: resource-59a2ee3fb58045feb5a1NodesHeatVdns-template.yml
+topology_template:
+  inputs:
+    vf_module_id:
+      type: string
+      description: The vLoadBalancer Module ID is provided by ONAP
+    onap_private_subnet_id:
+      type: string
+      description: Private sub-network that connects ONAP component and the VNF
+    repo_url_blob:
+      type: string
+      description: URL of the repository that hosts the demo packages
+    vlb_private_net_cidr:
+      type: string
+      description: The CIDR of the vLoadBalancer private network
+    vlb_private_net_id:
+      type: string
+      description: Private network that connects vLoadBalancer with vDNSs
+    public_net_id:
+      type: string
+      default: 00000000-0000-0000-0000-000000000000
+      description: Public network that enables remote connection to VNF
+    demo_artifacts_version:
+      type: string
+      description: Artifacts (jar, tar.gz) version used in demo vnfs
+    onap_private_net_id:
+      type: string
+      description: Private network that connects ONAP component and the VNF
+    pub_key:
+      type: string
+      description: Public key to be installed on the compute instance
+    vlb_private_ip_1:
+      type: string
+      description: Private IP address that is assigned to the vLoadBalancer to communicate with ONAP components
+    key_name:
+      type: string
+      description: Public/Private key pair name
+    vdns_name_0:
+      type: string
+      description: Name of the vDNS
+    repo_url_artifacts:
+      type: string
+      description: URL of the repository that hosts the demo packages
+    vlb_name_0:
+      type: string
+      description: Name of the vLoadBalancer
+    vdns_private_ip_0:
+      type: string
+      description: Private IP address that is assigned to the vDNS to communicate with the vLoadBalancer
+    vnf_id:
+      type: string
+      description: The VNF ID is provided by ONAP
+    dcae_collector_ip:
+      type: string
+      description: IP address of the DCAE collector
+    vdns_private_ip_1:
+      type: string
+      description: Private IP address that is assigned to the vDNS to communicate with ONAP components
+    dcae_collector_port:
+      type: string
+      description: Port of the DCAE collector
+    vlb_image_name:
+      type: string
+      default: Ubuntu 14.04 LTS (Trusty Tahr) (PVHVM)
+      description: Image to be used for compute instance
+    vlb_flavor_name:
+      type: string
+      default: 4 GB General Purpose v1
+      description: Type of instance (flavor) to be used
+    vlb_private_ip_0:
+      type: string
+      description: Private IP address that is assigned to the vLoadBalancer to communicate with the vDNSs
+    onap_private_net_cidr:
+      type: string
+      description: The CIDR of the protected private network
+  node_templates:
+    vdns_private_1_port:
+      type: org.onap.resource.cp.nodes.heat.network.neutron.Port
+      metadata:
+        invariantUUID: 7feb77d3-dcc5-4826-8a78-0c9089814a45
+        UUID: 06bc8ea7-0f6a-489a-9f8f-c7253653b457
+        version: '1.0'
+        name: NeutronPort
+        description: Represents a logical entity that associates between Compute and Network normative types.
+        type: CP
+        category: Generic
+        subcategory: Network Elements
+      properties:
+        fixed_ips:
+        - subnet:
+            get_input: onap_private_subnet_id
+          ip_address:
+            get_input: vdns_private_ip_1
+        network:
+          get_input: onap_private_net_id
+      requirements:
+      - binding:
+          capability: tosca.capabilities.network.Bindable
+          node: vdns_0
+          relationship: tosca.relationships.network.BindsTo
+    vlb_private_network:
+      type: org.onap.resource.vl.nodes.heat.network.neutron.Net
+      metadata:
+        invariantUUID: 2870cc3a-d6cd-4423-b7f6-2d63619b0eeb
+        UUID: b7e764ba-17f9-4f0a-ad29-29877766ef21
+        version: '1.0'
+        name: NeutronNet
+        description: Represents a network service with optional subnets and advanced configurations.
+        type: VL
+        category: Generic
+        subcategory: Network Elements
+      properties:
+        network_name:
+          get_input: vlb_private_net_id
+        subnets:
+          vlb_private_subnet:
+            name:
+              get_input: vlb_private_net_id
+            cidr:
+              get_input: vlb_private_net_cidr
+    vlb_private_1_port:
+      type: org.onap.resource.cp.nodes.heat.network.neutron.Port
+      metadata:
+        invariantUUID: 7feb77d3-dcc5-4826-8a78-0c9089814a45
+        UUID: 06bc8ea7-0f6a-489a-9f8f-c7253653b457
+        version: '1.0'
+        name: NeutronPort
+        description: Represents a logical entity that associates between Compute and Network normative types.
+        type: CP
+        category: Generic
+        subcategory: Network Elements
+      properties:
+        fixed_ips:
+        - subnet:
+            get_input: onap_private_subnet_id
+          ip_address:
+            get_input: vlb_private_ip_1
+        network:
+          get_input: onap_private_net_id
+      requirements:
+      - binding:
+          capability: tosca.capabilities.network.Bindable
+          node: vlb_0
+          relationship: tosca.relationships.network.BindsTo
+    vdns_0:
+      type: org.onap.resource.vfc.59a2ee3fB58045feB5a1.abstact.nodes.heat.vdns
+      metadata:
+        invariantUUID: ee585c30-127b-492e-b2c1-871dc61d1dde
+        UUID: d816cb01-b5d0-4bbb-b614-f7c3e230ab19
+        version: '1.0'
+        name: 59a2ee3fB58045feB5a1.nodes.heat.vdns
+        description: Not reusable inner VFC
+        type: VFC
+        category: Generic
+        subcategory: Abstract
+      properties:
+        key_name: UNSUPPORTED_RESOURCE_my_keypair
+        flavor:
+          get_input: vlb_flavor_name
+        image:
+          get_input: vlb_image_name
+        metadata:
+          vf_module_id:
+            get_input: vf_module_id
+          vnf_id:
+            get_input: vnf_id
+        user_data_format: RAW
+        name:
+          get_input: vdns_name_0
+    vlb_private_0_port:
+      type: org.onap.resource.cp.nodes.heat.network.neutron.Port
+      metadata:
+        invariantUUID: 7feb77d3-dcc5-4826-8a78-0c9089814a45
+        UUID: 06bc8ea7-0f6a-489a-9f8f-c7253653b457
+        version: '1.0'
+        name: NeutronPort
+        description: Represents a logical entity that associates between Compute and Network normative types.
+        type: CP
+        category: Generic
+        subcategory: Network Elements
+      properties:
+        fixed_ips:
+        - subnet: vlb_private_network
+          ip_address:
+            get_input: vlb_private_ip_0
+        network: vlb_private_network
+      requirements:
+      - link:
+          capability: tosca.capabilities.network.Linkable
+          node: vlb_private_network
+          relationship: tosca.relationships.network.LinksTo
+      - binding:
+          capability: tosca.capabilities.network.Bindable
+          node: vlb_0
+          relationship: tosca.relationships.network.BindsTo
+    vdns_private_0_port:
+      type: org.onap.resource.cp.nodes.heat.network.neutron.Port
+      metadata:
+        invariantUUID: 7feb77d3-dcc5-4826-8a78-0c9089814a45
+        UUID: 06bc8ea7-0f6a-489a-9f8f-c7253653b457
+        version: '1.0'
+        name: NeutronPort
+        description: Represents a logical entity that associates between Compute and Network normative types.
+        type: CP
+        category: Generic
+        subcategory: Network Elements
+      properties:
+        fixed_ips:
+        - subnet:
+            get_input: vlb_private_net_id
+          ip_address:
+            get_input: vdns_private_ip_0
+        network:
+          get_input: vlb_private_net_id
+      requirements:
+      - binding:
+          capability: tosca.capabilities.network.Bindable
+          node: vdns_0
+          relationship: tosca.relationships.network.BindsTo
+    vlb_0:
+      type: org.onap.resource.vfc.59a2ee3fB58045feB5a1.abstact.nodes.heat.vlb
+      metadata:
+        invariantUUID: f7f1d745-cfb1-4aa9-83fc-31280d0ce513
+        UUID: 1821f13e-411f-4b29-87a5-ae935897b2e1
+        version: '1.0'
+        name: 59a2ee3fB58045feB5a1.nodes.heat.vlb
+        description: Not reusable inner VFC
+        type: VFC
+        category: Generic
+        subcategory: Abstract
+      properties:
+        key_name: UNSUPPORTED_RESOURCE_my_keypair
+        flavor:
+          get_input: vlb_flavor_name
+        image:
+          get_input: vlb_image_name
+        metadata:
+          vf_module_id:
+            get_input: vf_module_id
+          vnf_id:
+            get_input: vnf_id
+        user_data_format: RAW
+        name:
+          get_input: vlb_name_0
+  groups:
+    base_vlb:
+      type: org.onap.groups.heat.HeatStack
+      members:
+      - vdns_private_1_port
+      - vlb_private_network
+      - vlb_private_1_port
+      - vdns_0
+      - vlb_private_0_port
+      - vdns_private_0_port
+      - vlb_0
+      metadata:
+        invariantUUID: 097f71b3-90a1-4064-bc83-f76bf30195fe
+        UUID: 4daf7600-0a06-4515-859a-c45ec11abd29
+        version: '1'
+        name: base_vlb
+    59a2ee3fB58045feB5a1..dnsscaling..module-1:
+      type: org.onap.groups.VfModule
+      members:
+      - vdns_private_1_port
+      - vdns_0
+      - vdns_private_0_port
+      metadata:
+        vfModuleModelName: 59a2ee3fB58045feB5a1..dnsscaling..module-1
+        vfModuleModelInvariantUUID: 395d61a9-309b-4c0f-a442-ca47903e231e
+        vfModuleModelUUID: 40846490-abf4-4e1d-8f1a-2286968fa231
+        vfModuleModelVersion: '1'
+      properties:
+        vf_module_type: Expansion
+        vf_module_description:
+        volume_group: false
+    59a2ee3fB58045feB5a1..base_vlb..module-0:
+      type: org.onap.groups.VfModule
+      members:
+      - vdns_private_1_port
+      - vlb_private_network
+      - vlb_private_1_port
+      - vdns_0
+      - vlb_private_0_port
+      - vdns_private_0_port
+      - vlb_0
+      metadata:
+        vfModuleModelName: 59a2ee3fB58045feB5a1..base_vlb..module-0
+        vfModuleModelInvariantUUID: 5ae76f74-6324-4835-a86c-0c96d16afd38
+        vfModuleModelUUID: 17c4f752-a3da-4f3d-9cc5-1c4d28e5442d
+        vfModuleModelVersion: '1'
+      properties:
+        vf_module_type: Base
+        vf_module_description:
+        volume_group: false
+    dnsscaling:
+      type: org.onap.groups.heat.HeatStack
+      members:
+      - vdns_private_1_port
+      - vdns_0
+      - vdns_private_0_port
+      metadata:
+        invariantUUID: 7c2971fa-9369-4fed-a449-a5e21c022f97
+        UUID: ae8c3b79-77d3-425a-8bab-6558007f8392
+        version: '1'
+        name: dnsscaling
+  substitution_mappings:
+    node_type: org.onap.resource.vf.59a2ee3fB58045feB5a1
+    capabilities:
+      vdns_0.memory:
+        type: org.onap.capabilities.metric.Ceilometer
+        description: Volume of RAM allocated to the instance
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          description:
+            type: string
+            description: Description of the metric
+            required: false
+          type:
+            type: string
+            default: Gauge
+            description: Type of the metric value, for an example, Cumulative, Delta, Gauge and etc.
+            required: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          secure:
+            type: boolean
+            default: false
+          port_name:
+            type: string
+            required: false
+          unit:
+            type: string
+            default: MB
+            description: Unit of the metric value
+            required: true
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          name:
+            type: string
+            default: memory
+            description: Ceilometer metric type name to monitor. (The name ceilometer is using)
+            required: true
+          category:
+            type: string
+            default: compute
+            description: Category of the metric, for an example, compute, disk, network, storage and etc.
+            required: false
+          url_path:
+            type: string
+            required: false
+      vdns_0.memory.resident:
+        type: org.onap.capabilities.metric.Ceilometer
+        description: Volume of RAM used by the instance on the physical machine
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          description:
+            type: string
+            description: Description of the metric
+            required: false
+          type:
+            type: string
+            default: Gauge
+            description: Type of the metric value, for an example, Cumulative, Delta, Gauge and etc.
+            required: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          secure:
+            type: boolean
+            default: false
+          port_name:
+            type: string
+            required: false
+          unit:
+            type: string
+            default: MB
+            description: Unit of the metric value
+            required: true
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          name:
+            type: string
+            default: memory.resident
+            description: Ceilometer metric type name to monitor. (The name ceilometer is using)
+            required: true
+          category:
+            type: string
+            default: compute
+            description: Category of the metric, for an example, compute, disk, network, storage and etc.
+            required: false
+          url_path:
+            type: string
+            required: false
+      vdns_0.cpu:
+        type: org.onap.capabilities.metric.Ceilometer
+        description: CPU time used
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          description:
+            type: string
+            description: Description of the metric
+            required: false
+          type:
+            type: string
+            default: Cumulative
+            description: Type of the metric value, for an example, Cumulative, Delta, Gauge and etc.
+            required: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          secure:
+            type: boolean
+            default: false
+          port_name:
+            type: string
+            required: false
+          unit:
+            type: string
+            default: ns
+            description: Unit of the metric value
+            required: true
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          name:
+            type: string
+            default: cpu
+            description: Ceilometer metric type name to monitor. (The name ceilometer is using)
+            required: true
+          category:
+            type: string
+            default: compute
+            description: Category of the metric, for an example, compute, disk, network, storage and etc.
+            required: false
+          url_path:
+            type: string
+            required: false
+      vdns_0.feature:
+        type: tosca.capabilities.Node
+        occurrences:
+        - 1
+        - UNBOUNDED
+      vdns_private_0_port.feature:
+        type: tosca.capabilities.Node
+        occurrences:
+        - 1
+        - UNBOUNDED
+      vdns_0.host:
+        type: tosca.capabilities.Container
+        occurrences:
+        - 1
+        - UNBOUNDED
+        valid_source_types:
+        - tosca.nodes.SoftwareComponent
+        properties:
+          num_cpus:
+            type: integer
+            required: false
+          disk_size:
+            type: scalar-unit.size
+            required: false
+          cpu_frequency:
+            type: scalar-unit.frequency
+            required: false
+          mem_size:
+            type: scalar-unit.size
+            required: false
+      vdns_0.endpoint:
+        type: tosca.capabilities.Endpoint.Admin
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          port_name:
+            type: string
+            required: false
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          secure:
+            type: boolean
+            default: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          url_path:
+            type: string
+            required: false
+      vlb_private_1_port.attachment:
+        type: tosca.capabilities.Attachment
+        occurrences:
+        - 1
+        - UNBOUNDED
+      vlb_0.memory:
+        type: org.onap.capabilities.metric.Ceilometer
+        description: Volume of RAM allocated to the instance
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          description:
+            type: string
+            description: Description of the metric
+            required: false
+          type:
+            type: string
+            default: Gauge
+            description: Type of the metric value, for an example, Cumulative, Delta, Gauge and etc.
+            required: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          secure:
+            type: boolean
+            default: false
+          port_name:
+            type: string
+            required: false
+          unit:
+            type: string
+            default: MB
+            description: Unit of the metric value
+            required: true
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          name:
+            type: string
+            default: memory
+            description: Ceilometer metric type name to monitor. (The name ceilometer is using)
+            required: true
+          category:
+            type: string
+            default: compute
+            description: Category of the metric, for an example, compute, disk, network, storage and etc.
+            required: false
+          url_path:
+            type: string
+            required: false
+      vdns_private_1_port.attachment:
+        type: tosca.capabilities.Attachment
+        occurrences:
+        - 1
+        - UNBOUNDED
+      vlb_0.scalable:
+        type: tosca.capabilities.Scalable
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          max_instances:
+            type: integer
+            default: 1
+          min_instances:
+            type: integer
+            default: 1
+          default_instances:
+            type: integer
+      vlb_0.binding:
+        type: tosca.capabilities.network.Bindable
+        occurrences:
+        - 0
+        - UNBOUNDED
+      vlb_0.vcpus:
+        type: org.onap.capabilities.metric.Ceilometer
+        description: Average disk latency
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          description:
+            type: string
+            description: Description of the metric
+            required: false
+          type:
+            type: string
+            default: Gauge
+            description: Type of the metric value, for an example, Cumulative, Delta, Gauge and etc.
+            required: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          secure:
+            type: boolean
+            default: false
+          port_name:
+            type: string
+            required: false
+          unit:
+            type: string
+            default: ms
+            description: Unit of the metric value
+            required: true
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          name:
+            type: string
+            default: vcpus
+            description: Ceilometer metric type name to monitor. (The name ceilometer is using)
+            required: true
+          category:
+            type: string
+            default: compute
+            description: Category of the metric, for an example, compute, disk, network, storage and etc.
+            required: false
+          url_path:
+            type: string
+            required: false
+      vlb_0.instance:
+        type: org.onap.capabilities.metric.Ceilometer
+        description: Existence of instance
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          description:
+            type: string
+            description: Description of the metric
+            required: false
+          type:
+            type: string
+            default: Gauge
+            description: Type of the metric value, for an example, Cumulative, Delta, Gauge and etc.
+            required: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          secure:
+            type: boolean
+            default: false
+          port_name:
+            type: string
+            required: false
+          unit:
+            type: string
+            default: instance
+            description: Unit of the metric value
+            required: true
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          name:
+            type: string
+            default: instance
+            description: Ceilometer metric type name to monitor. (The name ceilometer is using)
+            required: true
+          category:
+            type: string
+            default: compute
+            description: Category of the metric, for an example, compute, disk, network, storage and etc.
+            required: false
+          url_path:
+            type: string
+            required: false
+      vdns_0.os:
+        type: tosca.capabilities.OperatingSystem
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          distribution:
+            type: string
+            required: false
+          type:
+            type: string
+            required: false
+          version:
+            type: version
+            required: false
+          architecture:
+            type: string
+            required: false
+      vlb_private_0_port.feature:
+        type: tosca.capabilities.Node
+        occurrences:
+        - 1
+        - UNBOUNDED
+      vlb_private_1_port.feature:
+        type: tosca.capabilities.Node
+        occurrences:
+        - 1
+        - UNBOUNDED
+      vlb_0.cpu:
+        type: org.onap.capabilities.metric.Ceilometer
+        description: CPU time used
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          description:
+            type: string
+            description: Description of the metric
+            required: false
+          type:
+            type: string
+            default: Cumulative
+            description: Type of the metric value, for an example, Cumulative, Delta, Gauge and etc.
+            required: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          secure:
+            type: boolean
+            default: false
+          port_name:
+            type: string
+            required: false
+          unit:
+            type: string
+            default: ns
+            description: Unit of the metric value
+            required: true
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          name:
+            type: string
+            default: cpu
+            description: Ceilometer metric type name to monitor. (The name ceilometer is using)
+            required: true
+          category:
+            type: string
+            default: compute
+            description: Category of the metric, for an example, compute, disk, network, storage and etc.
+            required: false
+          url_path:
+            type: string
+            required: false
+      vdns_0.cpu.delta:
+        type: org.onap.capabilities.metric.Ceilometer
+        description: CPU time used since previous datapoint
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          description:
+            type: string
+            description: Description of the metric
+            required: false
+          type:
+            type: string
+            default: Delta
+            description: Type of the metric value, for an example, Cumulative, Delta, Gauge and etc.
+            required: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          secure:
+            type: boolean
+            default: false
+          port_name:
+            type: string
+            required: false
+          unit:
+            type: string
+            default: ns
+            description: Unit of the metric value
+            required: true
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          name:
+            type: string
+            default: cpu.delta
+            description: Ceilometer metric type name to monitor. (The name ceilometer is using)
+            required: true
+          category:
+            type: string
+            default: compute
+            description: Category of the metric, for an example, compute, disk, network, storage and etc.
+            required: false
+          url_path:
+            type: string
+            required: false
+      vlb_0.memory.resident:
+        type: org.onap.capabilities.metric.Ceilometer
+        description: Volume of RAM used by the instance on the physical machine
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          description:
+            type: string
+            description: Description of the metric
+            required: false
+          type:
+            type: string
+            default: Gauge
+            description: Type of the metric value, for an example, Cumulative, Delta, Gauge and etc.
+            required: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          secure:
+            type: boolean
+            default: false
+          port_name:
+            type: string
+            required: false
+          unit:
+            type: string
+            default: MB
+            description: Unit of the metric value
+            required: true
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          name:
+            type: string
+            default: memory.resident
+            description: Ceilometer metric type name to monitor. (The name ceilometer is using)
+            required: true
+          category:
+            type: string
+            default: compute
+            description: Category of the metric, for an example, compute, disk, network, storage and etc.
+            required: false
+          url_path:
+            type: string
+            required: false
+      vdns_0.vcpus:
+        type: org.onap.capabilities.metric.Ceilometer
+        description: Average disk latency
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          description:
+            type: string
+            description: Description of the metric
+            required: false
+          type:
+            type: string
+            default: Gauge
+            description: Type of the metric value, for an example, Cumulative, Delta, Gauge and etc.
+            required: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          secure:
+            type: boolean
+            default: false
+          port_name:
+            type: string
+            required: false
+          unit:
+            type: string
+            default: ms
+            description: Unit of the metric value
+            required: true
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          name:
+            type: string
+            default: vcpus
+            description: Ceilometer metric type name to monitor. (The name ceilometer is using)
+            required: true
+          category:
+            type: string
+            default: compute
+            description: Category of the metric, for an example, compute, disk, network, storage and etc.
+            required: false
+          url_path:
+            type: string
+            required: false
+      vdns_0.memory.usage:
+        type: org.onap.capabilities.metric.Ceilometer
+        description: Volume of RAM used by the instance from the amount of its allocated memory
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          description:
+            type: string
+            description: Description of the metric
+            required: false
+          type:
+            type: string
+            default: Gauge
+            description: Type of the metric value, for an example, Cumulative, Delta, Gauge and etc.
+            required: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          secure:
+            type: boolean
+            default: false
+          port_name:
+            type: string
+            required: false
+          unit:
+            type: string
+            default: MB
+            description: Unit of the metric value
+            required: true
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          name:
+            type: string
+            default: memory.usage
+            description: Ceilometer metric type name to monitor. (The name ceilometer is using)
+            required: true
+          category:
+            type: string
+            default: compute
+            description: Category of the metric, for an example, compute, disk, network, storage and etc.
+            required: false
+          url_path:
+            type: string
+            required: false
+      vlb_0.cpu.delta:
+        type: org.onap.capabilities.metric.Ceilometer
+        description: CPU time used since previous datapoint
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          description:
+            type: string
+            description: Description of the metric
+            required: false
+          type:
+            type: string
+            default: Delta
+            description: Type of the metric value, for an example, Cumulative, Delta, Gauge and etc.
+            required: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          secure:
+            type: boolean
+            default: false
+          port_name:
+            type: string
+            required: false
+          unit:
+            type: string
+            default: ns
+            description: Unit of the metric value
+            required: true
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          name:
+            type: string
+            default: cpu.delta
+            description: Ceilometer metric type name to monitor. (The name ceilometer is using)
+            required: true
+          category:
+            type: string
+            default: compute
+            description: Category of the metric, for an example, compute, disk, network, storage and etc.
+            required: false
+          url_path:
+            type: string
+            required: false
+      vdns_0.instance:type:
+        type: org.onap.capabilities.metric.Ceilometer
+        description: Existence of instance <type> (OpenStack types)
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          description:
+            type: string
+            description: Description of the metric
+            required: false
+          type:
+            type: string
+            default: Gauge
+            description: Type of the metric value, for an example, Cumulative, Delta, Gauge and etc.
+            required: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          secure:
+            type: boolean
+            default: false
+          port_name:
+            type: string
+            required: false
+          unit:
+            type: string
+            default: instance
+            description: Unit of the metric value
+            required: true
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          name:
+            type: string
+            default: instance:type
+            description: Ceilometer metric type name to monitor. (The name ceilometer is using)
+            required: true
+          category:
+            type: string
+            default: compute
+            description: Category of the metric, for an example, compute, disk, network, storage and etc.
+            required: false
+          url_path:
+            type: string
+            required: false
+      vlb_0.os:
+        type: tosca.capabilities.OperatingSystem
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          distribution:
+            type: string
+            required: false
+          type:
+            type: string
+            required: false
+          version:
+            type: version
+            required: false
+          architecture:
+            type: string
+            required: false
+      vlb_private_0_port.attachment:
+        type: tosca.capabilities.Attachment
+        occurrences:
+        - 1
+        - UNBOUNDED
+      vlb_0.host:
+        type: tosca.capabilities.Container
+        occurrences:
+        - 1
+        - UNBOUNDED
+        valid_source_types:
+        - tosca.nodes.SoftwareComponent
+        properties:
+          num_cpus:
+            type: integer
+            required: false
+          disk_size:
+            type: scalar-unit.size
+            required: false
+          cpu_frequency:
+            type: scalar-unit.frequency
+            required: false
+          mem_size:
+            type: scalar-unit.size
+            required: false
+      vlb_0.instance:type:
+        type: org.onap.capabilities.metric.Ceilometer
+        description: Existence of instance <type> (OpenStack types)
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          description:
+            type: string
+            description: Description of the metric
+            required: false
+          type:
+            type: string
+            default: Gauge
+            description: Type of the metric value, for an example, Cumulative, Delta, Gauge and etc.
+            required: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          secure:
+            type: boolean
+            default: false
+          port_name:
+            type: string
+            required: false
+          unit:
+            type: string
+            default: instance
+            description: Unit of the metric value
+            required: true
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          name:
+            type: string
+            default: instance:type
+            description: Ceilometer metric type name to monitor. (The name ceilometer is using)
+            required: true
+          category:
+            type: string
+            default: compute
+            description: Category of the metric, for an example, compute, disk, network, storage and etc.
+            required: false
+          url_path:
+            type: string
+            required: false
+      vlb_private_network.feature:
+        type: tosca.capabilities.Node
+        occurrences:
+        - 1
+        - UNBOUNDED
+      vdns_0.binding:
+        type: tosca.capabilities.network.Bindable
+        occurrences:
+        - 0
+        - UNBOUNDED
+      vlb_private_network.link:
+        type: tosca.capabilities.network.Linkable
+        occurrences:
+        - 0
+        - UNBOUNDED
+      vlb_0.cpu_util:
+        type: org.onap.capabilities.metric.Ceilometer
+        description: Average CPU utilization
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          description:
+            type: string
+            description: Description of the metric
+            required: false
+          type:
+            type: string
+            default: Gauge
+            description: Type of the metric value, for an example, Cumulative, Delta, Gauge and etc.
+            required: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          secure:
+            type: boolean
+            default: false
+          port_name:
+            type: string
+            required: false
+          unit:
+            type: string
+            default: '%'
+            description: Unit of the metric value
+            required: true
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          name:
+            type: string
+            default: cpu_util
+            description: Ceilometer metric type name to monitor. (The name ceilometer is using)
+            required: true
+          category:
+            type: string
+            default: compute
+            description: Category of the metric, for an example, compute, disk, network, storage and etc.
+            required: false
+          url_path:
+            type: string
+            required: false
+      vlb_0.feature:
+        type: tosca.capabilities.Node
+        occurrences:
+        - 1
+        - UNBOUNDED
+      vdns_private_0_port.attachment:
+        type: tosca.capabilities.Attachment
+        occurrences:
+        - 1
+        - UNBOUNDED
+      vdns_0.cpu_util:
+        type: org.onap.capabilities.metric.Ceilometer
+        description: Average CPU utilization
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          description:
+            type: string
+            description: Description of the metric
+            required: false
+          type:
+            type: string
+            default: Gauge
+            description: Type of the metric value, for an example, Cumulative, Delta, Gauge and etc.
+            required: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          secure:
+            type: boolean
+            default: false
+          port_name:
+            type: string
+            required: false
+          unit:
+            type: string
+            default: '%'
+            description: Unit of the metric value
+            required: true
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          name:
+            type: string
+            default: cpu_util
+            description: Ceilometer metric type name to monitor. (The name ceilometer is using)
+            required: true
+          category:
+            type: string
+            default: compute
+            description: Category of the metric, for an example, compute, disk, network, storage and etc.
+            required: false
+          url_path:
+            type: string
+            required: false
+      vdns_0.instance:
+        type: org.onap.capabilities.metric.Ceilometer
+        description: Existence of instance
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          description:
+            type: string
+            description: Description of the metric
+            required: false
+          type:
+            type: string
+            default: Gauge
+            description: Type of the metric value, for an example, Cumulative, Delta, Gauge and etc.
+            required: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          secure:
+            type: boolean
+            default: false
+          port_name:
+            type: string
+            required: false
+          unit:
+            type: string
+            default: instance
+            description: Unit of the metric value
+            required: true
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          name:
+            type: string
+            default: instance
+            description: Ceilometer metric type name to monitor. (The name ceilometer is using)
+            required: true
+          category:
+            type: string
+            default: compute
+            description: Category of the metric, for an example, compute, disk, network, storage and etc.
+            required: false
+          url_path:
+            type: string
+            required: false
+      vlb_private_network.attachment:
+        type: tosca.capabilities.Attachment
+        occurrences:
+        - 1
+        - UNBOUNDED
+      vdns_0.scalable:
+        type: tosca.capabilities.Scalable
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          max_instances:
+            type: integer
+            default: 1
+          min_instances:
+            type: integer
+            default: 1
+          default_instances:
+            type: integer
+      vdns_private_1_port.feature:
+        type: tosca.capabilities.Node
+        occurrences:
+        - 1
+        - UNBOUNDED
+      vlb_0.memory.usage:
+        type: org.onap.capabilities.metric.Ceilometer
+        description: Volume of RAM used by the instance from the amount of its allocated memory
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          description:
+            type: string
+            description: Description of the metric
+            required: false
+          type:
+            type: string
+            default: Gauge
+            description: Type of the metric value, for an example, Cumulative, Delta, Gauge and etc.
+            required: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          secure:
+            type: boolean
+            default: false
+          port_name:
+            type: string
+            required: false
+          unit:
+            type: string
+            default: MB
+            description: Unit of the metric value
+            required: true
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          name:
+            type: string
+            default: memory.usage
+            description: Ceilometer metric type name to monitor. (The name ceilometer is using)
+            required: true
+          category:
+            type: string
+            default: compute
+            description: Category of the metric, for an example, compute, disk, network, storage and etc.
+            required: false
+          url_path:
+            type: string
+            required: false
+      vlb_0.endpoint:
+        type: tosca.capabilities.Endpoint.Admin
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          port_name:
+            type: string
+            required: false
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          secure:
+            type: boolean
+            default: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          url_path:
+            type: string
+            required: false
+    requirements:
+      vdns_0.dependency:
+        occurrences:
+        - 0
+        - UNBOUNDED
+        capability: tosca.capabilities.Node
+        node: tosca.nodes.Root
+        relationship: tosca.relationships.DependsOn
+      vlb_private_1_port.link:
+        occurrences:
+        - 1
+        - 1
+        capability: tosca.capabilities.network.Linkable
+        relationship: tosca.relationships.network.LinksTo
+      vlb_private_0_port.dependency:
+        occurrences:
+        - 0
+        - UNBOUNDED
+        capability: tosca.capabilities.Node
+        node: tosca.nodes.Root
+        relationship: tosca.relationships.DependsOn
+      vdns_private_0_port.dependency:
+        occurrences:
+        - 0
+        - UNBOUNDED
+        capability: tosca.capabilities.Node
+        node: tosca.nodes.Root
+        relationship: tosca.relationships.DependsOn
+      vlb_0.dependency:
+        occurrences:
+        - 0
+        - UNBOUNDED
+        capability: tosca.capabilities.Node
+        node: tosca.nodes.Root
+        relationship: tosca.relationships.DependsOn
+      vdns_private_0_port.link:
+        occurrences:
+        - 1
+        - 1
+        capability: tosca.capabilities.network.Linkable
+        relationship: tosca.relationships.network.LinksTo
+      vdns_0.local_storage:
+        occurrences:
+        - 0
+        - UNBOUNDED
+        capability: tosca.capabilities.Attachment
+        node: tosca.nodes.BlockStorage
+        relationship: tosca.relationships.AttachesTo
+      vlb_private_1_port.dependency:
+        occurrences:
+        - 0
+        - UNBOUNDED
+        capability: tosca.capabilities.Node
+        node: tosca.nodes.Root
+        relationship: tosca.relationships.DependsOn
+      vlb_private_network.dependency:
+        occurrences:
+        - 0
+        - UNBOUNDED
+        capability: tosca.capabilities.Node
+        node: tosca.nodes.Root
+        relationship: tosca.relationships.DependsOn
+      vlb_0.local_storage:
+        occurrences:
+        - 0
+        - UNBOUNDED
+        capability: tosca.capabilities.Attachment
+        node: tosca.nodes.BlockStorage
+        relationship: tosca.relationships.AttachesTo
+      vdns_private_1_port.link:
+        occurrences:
+        - 1
+        - 1
+        capability: tosca.capabilities.network.Linkable
+        relationship: tosca.relationships.network.LinksTo
+      vdns_private_1_port.dependency:
+        occurrences:
+        - 0
+        - UNBOUNDED
+        capability: tosca.capabilities.Node
+        node: tosca.nodes.Root
+        relationship: tosca.relationships.DependsOn
diff --git a/ONAP-ControlloopPolicy/src/test/resources/v2.0.0/Demo-1.0.0-HeatTemplates/resource-Eace933104d443b496b8-template.yml b/ONAP-ControlloopPolicy/src/test/resources/v2.0.0/Demo-1.0.0-HeatTemplates/resource-Eace933104d443b496b8-template.yml
new file mode 100644
index 0000000..38e6b01
--- /dev/null
+++ b/ONAP-ControlloopPolicy/src/test/resources/v2.0.0/Demo-1.0.0-HeatTemplates/resource-Eace933104d443b496b8-template.yml
@@ -0,0 +1,2525 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+metadata:
+  invariantUUID: 06fe411e-d006-4ac3-8b0e-fb4f13cd78d3
+  UUID: 172ce7c5-c2e4-4f8d-b66c-edb49e8e548a
+  name: eace9331-04d4-43b4-96b8
+  description: vendor software product
+  type: VF
+  category: Generic
+  subcategory: Abstract
+  resourceVendor: 31125954-23a0-4d41-95e5
+  resourceVendorRelease: '1.0'
+imports:
+- NeutronPort:
+    file: resource-Neutronport-template.yml
+- Eace933104d443b496b8.nodes.heat.vfw:
+    file: resource-Eace933104d443b496b8NodesHeatVfw-template.yml
+- Eace933104d443b496b8.nodes.heat.vpg:
+    file: resource-Eace933104d443b496b8NodesHeatVpg-template.yml
+- NeutronNet:
+    file: resource-Neutronnet-template.yml
+- Eace933104d443b496b8.nodes.heat.vsn:
+    file: resource-Eace933104d443b496b8NodesHeatVsn-template.yml
+topology_template:
+  inputs:
+    vf_module_id:
+      type: string
+      description: The vFirewall Module ID is provided by ONAP
+    repo_url_blob:
+      type: string
+      description: URL of the repository that hosts the demo packages
+    public_net_id:
+      type: string
+      default: 00000000-0000-0000-0000-000000000000
+      description: Public network that enables remote connection to VNF
+    vfw_private_ip_1:
+      type: string
+      description: Private IP address that is assigned to the vFirewall to communicate with the vSink
+    vfw_private_ip_0:
+      type: string
+      description: Private IP address that is assigned to the vFirewall to communicate with the vPacketGenerator
+    vfw_private_ip_2:
+      type: string
+      description: Private IP address that is assigned to the vFirewall to communicate with ONAP components
+    vfw_name_0:
+      type: string
+      description: Name of the vFirewall
+    vnf_id:
+      type: string
+      description: The VNF ID is provided by ONAP
+    dcae_collector_ip:
+      type: string
+      description: IP address of the DCAE collector
+    dcae_collector_port:
+      type: string
+      description: Port of the DCAE collector
+    vpg_private_ip_1:
+      type: string
+      description: Private IP address that is assigned to the vPacketGenerator to communicate with ONAP components
+    vsn_private_ip_0:
+      type: string
+      description: Private IP address that is assigned to the vSink to communicate with the vFirewall
+    vpg_name_0:
+      type: string
+      description: Name of the vPacketGenerator
+    vpg_private_ip_0:
+      type: string
+      description: Private IP address that is assigned to the vPacketGenerator to communicate with the vFirewall
+    vsn_private_ip_1:
+      type: string
+      description: Private IP address that is assigned to the vSink to communicate with ONAP components
+    protected_private_net_cidr:
+      type: string
+      description: The CIDR of the protected private network
+    onap_private_net_cidr:
+      type: string
+      description: The CIDR of the protected private network
+    unprotected_private_net_cidr:
+      type: string
+      description: The CIDR of the unprotected private network
+    onap_private_subnet_id:
+      type: string
+      description: Private sub-network that connects ONAP component and the VNF
+    vsn_name_0:
+      type: string
+      description: Name of the vSink
+    unprotected_private_net_id:
+      type: string
+      description: Private network that connects vPacketGenerator with vFirewall
+    vfw_flavor_name:
+      type: string
+      default: 4 GB General Purpose v1
+      description: Type of instance (flavor) to be used
+    demo_artifacts_version:
+      type: string
+      description: Artifacts (jar, tar.gz) version used in demo vnfs
+    onap_private_net_id:
+      type: string
+      description: Private network that connects ONAP component and the VNF
+    pub_key:
+      type: string
+      description: Public key to be installed on the compute instance
+    key_name:
+      type: string
+      description: Public/Private key pair name
+    repo_url_artifacts:
+      type: string
+      description: URL of the repository that hosts the demo packages
+    vfw_image_name:
+      type: string
+      default: Ubuntu 14.04 LTS (Trusty Tahr) (PVHVM)
+      description: Image to be used for compute instance
+    protected_private_net_id:
+      type: string
+      description: Private network that connects vFirewall with vSink
+  node_templates:
+    vfw_private_0_port:
+      type: org.onap.resource.cp.nodes.heat.network.neutron.Port
+      metadata:
+        invariantUUID: 7feb77d3-dcc5-4826-8a78-0c9089814a45
+        UUID: 06bc8ea7-0f6a-489a-9f8f-c7253653b457
+        version: '1.0'
+        name: NeutronPort
+        description: Represents a logical entity that associates between Compute and Network normative types.
+        type: CP
+        category: Generic
+        subcategory: Network Elements
+      properties:
+        fixed_ips:
+        - subnet: unprotected_private_network
+          ip_address:
+            get_input: vfw_private_ip_0
+        network: unprotected_private_network
+      requirements:
+      - link:
+          capability: tosca.capabilities.network.Linkable
+          node: unprotected_private_network
+          relationship: tosca.relationships.network.LinksTo
+      - binding:
+          capability: tosca.capabilities.network.Bindable
+          node: vfw_0
+          relationship: tosca.relationships.network.BindsTo
+    vsn_private_1_port:
+      type: org.onap.resource.cp.nodes.heat.network.neutron.Port
+      metadata:
+        invariantUUID: 7feb77d3-dcc5-4826-8a78-0c9089814a45
+        UUID: 06bc8ea7-0f6a-489a-9f8f-c7253653b457
+        version: '1.0'
+        name: NeutronPort
+        description: Represents a logical entity that associates between Compute and Network normative types.
+        type: CP
+        category: Generic
+        subcategory: Network Elements
+      properties:
+        fixed_ips:
+        - subnet:
+            get_input: onap_private_subnet_id
+          ip_address:
+            get_input: vsn_private_ip_1
+        network:
+          get_input: onap_private_net_id
+      requirements:
+      - binding:
+          capability: tosca.capabilities.network.Bindable
+          node: vsn_0
+          relationship: tosca.relationships.network.BindsTo
+    unprotected_private_network:
+      type: org.onap.resource.vl.nodes.heat.network.neutron.Net
+      metadata:
+        invariantUUID: 2870cc3a-d6cd-4423-b7f6-2d63619b0eeb
+        UUID: b7e764ba-17f9-4f0a-ad29-29877766ef21
+        version: '1.0'
+        name: NeutronNet
+        description: Represents a network service with optional subnets and advanced configurations.
+        type: VL
+        category: Generic
+        subcategory: Network Elements
+      properties:
+        network_name:
+          get_input: unprotected_private_net_id
+        subnets:
+          unprotected_private_subnet:
+            cidr:
+              get_input: unprotected_private_net_cidr
+    vpg_private_1_port:
+      type: org.onap.resource.cp.nodes.heat.network.neutron.Port
+      metadata:
+        invariantUUID: 7feb77d3-dcc5-4826-8a78-0c9089814a45
+        UUID: 06bc8ea7-0f6a-489a-9f8f-c7253653b457
+        version: '1.0'
+        name: NeutronPort
+        description: Represents a logical entity that associates between Compute and Network normative types.
+        type: CP
+        category: Generic
+        subcategory: Network Elements
+      properties:
+        fixed_ips:
+        - subnet:
+            get_input: onap_private_subnet_id
+          ip_address:
+            get_input: vpg_private_ip_1
+        network:
+          get_input: onap_private_net_id
+      requirements:
+      - binding:
+          capability: tosca.capabilities.network.Bindable
+          node: vpg_0
+          relationship: tosca.relationships.network.BindsTo
+    vfw_0:
+      type: org.onap.resource.vfc.Eace933104d443b496b8.abstact.nodes.heat.vfw
+      metadata:
+        invariantUUID: 0129e34c-d9fa-442d-bb2c-f925d018000a
+        UUID: 7fa1f6c7-c6bd-4444-8db2-63334a5aed1b
+        version: '1.0'
+        name: Eace933104d443b496b8.nodes.heat.vfw
+        description: Not reusable inner VFC
+        type: VFC
+        category: Generic
+        subcategory: Abstract
+      properties:
+        key_name: UNSUPPORTED_RESOURCE_my_keypair
+        flavor:
+          get_input: vfw_flavor_name
+        image:
+          get_input: vfw_image_name
+        metadata:
+          vf_module_id:
+            get_input: vf_module_id
+          vnf_id:
+            get_input: vnf_id
+        user_data_format: RAW
+        name:
+          get_input: vfw_name_0
+    vsn_0:
+      type: org.onap.resource.vfc.Eace933104d443b496b8.abstact.nodes.heat.vsn
+      metadata:
+        invariantUUID: b19f6643-3db0-4d73-b280-94d6f21caa71
+        UUID: 6dca6eb9-330c-4090-a542-7aca5f446e21
+        version: '1.0'
+        name: Eace933104d443b496b8.nodes.heat.vsn
+        description: Not reusable inner VFC
+        type: VFC
+        category: Generic
+        subcategory: Abstract
+      properties:
+        key_name: UNSUPPORTED_RESOURCE_my_keypair
+        flavor:
+          get_input: vfw_flavor_name
+        image:
+          get_input: vfw_image_name
+        metadata:
+          vf_module_id:
+            get_input: vf_module_id
+          vnf_id:
+            get_input: vnf_id
+        user_data_format: RAW
+        name:
+          get_input: vsn_name_0
+    vpg_private_0_port:
+      type: org.onap.resource.cp.nodes.heat.network.neutron.Port
+      metadata:
+        invariantUUID: 7feb77d3-dcc5-4826-8a78-0c9089814a45
+        UUID: 06bc8ea7-0f6a-489a-9f8f-c7253653b457
+        version: '1.0'
+        name: NeutronPort
+        description: Represents a logical entity that associates between Compute and Network normative types.
+        type: CP
+        category: Generic
+        subcategory: Network Elements
+      properties:
+        fixed_ips:
+        - subnet: unprotected_private_network
+          ip_address:
+            get_input: vpg_private_ip_0
+        network: unprotected_private_network
+      requirements:
+      - link:
+          capability: tosca.capabilities.network.Linkable
+          node: unprotected_private_network
+          relationship: tosca.relationships.network.LinksTo
+      - binding:
+          capability: tosca.capabilities.network.Bindable
+          node: vpg_0
+          relationship: tosca.relationships.network.BindsTo
+    vsn_private_0_port:
+      type: org.onap.resource.cp.nodes.heat.network.neutron.Port
+      metadata:
+        invariantUUID: 7feb77d3-dcc5-4826-8a78-0c9089814a45
+        UUID: 06bc8ea7-0f6a-489a-9f8f-c7253653b457
+        version: '1.0'
+        name: NeutronPort
+        description: Represents a logical entity that associates between Compute and Network normative types.
+        type: CP
+        category: Generic
+        subcategory: Network Elements
+      properties:
+        fixed_ips:
+        - subnet: protected_private_network
+          ip_address:
+            get_input: vsn_private_ip_0
+        network: protected_private_network
+      requirements:
+      - link:
+          capability: tosca.capabilities.network.Linkable
+          node: protected_private_network
+          relationship: tosca.relationships.network.LinksTo
+      - binding:
+          capability: tosca.capabilities.network.Bindable
+          node: vsn_0
+          relationship: tosca.relationships.network.BindsTo
+    vfw_private_1_port:
+      type: org.onap.resource.cp.nodes.heat.network.neutron.Port
+      metadata:
+        invariantUUID: 7feb77d3-dcc5-4826-8a78-0c9089814a45
+        UUID: 06bc8ea7-0f6a-489a-9f8f-c7253653b457
+        version: '1.0'
+        name: NeutronPort
+        description: Represents a logical entity that associates between Compute and Network normative types.
+        type: CP
+        category: Generic
+        subcategory: Network Elements
+      properties:
+        fixed_ips:
+        - subnet: protected_private_network
+          ip_address:
+            get_input: vfw_private_ip_1
+        network: protected_private_network
+      requirements:
+      - link:
+          capability: tosca.capabilities.network.Linkable
+          node: protected_private_network
+          relationship: tosca.relationships.network.LinksTo
+      - binding:
+          capability: tosca.capabilities.network.Bindable
+          node: vfw_0
+          relationship: tosca.relationships.network.BindsTo
+    vfw_private_2_port:
+      type: org.onap.resource.cp.nodes.heat.network.neutron.Port
+      metadata:
+        invariantUUID: 7feb77d3-dcc5-4826-8a78-0c9089814a45
+        UUID: 06bc8ea7-0f6a-489a-9f8f-c7253653b457
+        version: '1.0'
+        name: NeutronPort
+        description: Represents a logical entity that associates between Compute and Network normative types.
+        type: CP
+        category: Generic
+        subcategory: Network Elements
+      properties:
+        fixed_ips:
+        - subnet:
+            get_input: onap_private_subnet_id
+          ip_address:
+            get_input: vfw_private_ip_2
+        network:
+          get_input: onap_private_net_id
+      requirements:
+      - binding:
+          capability: tosca.capabilities.network.Bindable
+          node: vfw_0
+          relationship: tosca.relationships.network.BindsTo
+    vpg_0:
+      type: org.onap.resource.vfc.Eace933104d443b496b8.abstact.nodes.heat.vpg
+      metadata:
+        invariantUUID: 7654ae14-4e98-45bc-a8c0-2c43e1805bb4
+        UUID: 5267d6dd-f676-4f98-abec-6387ce6beaf2
+        version: '1.0'
+        name: Eace933104d443b496b8.nodes.heat.vpg
+        description: Not reusable inner VFC
+        type: VFC
+        category: Generic
+        subcategory: Abstract
+      properties:
+        key_name: UNSUPPORTED_RESOURCE_my_keypair
+        flavor:
+          get_input: vfw_flavor_name
+        image:
+          get_input: vfw_image_name
+        metadata:
+          vf_module_id:
+            get_input: vf_module_id
+          vnf_id:
+            get_input: vnf_id
+        user_data_format: RAW
+        name:
+          get_input: vpg_name_0
+    protected_private_network:
+      type: org.onap.resource.vl.nodes.heat.network.neutron.Net
+      metadata:
+        invariantUUID: 2870cc3a-d6cd-4423-b7f6-2d63619b0eeb
+        UUID: b7e764ba-17f9-4f0a-ad29-29877766ef21
+        version: '1.0'
+        name: NeutronNet
+        description: Represents a network service with optional subnets and advanced configurations.
+        type: VL
+        category: Generic
+        subcategory: Network Elements
+      properties:
+        network_name:
+          get_input: protected_private_net_id
+        subnets:
+          protected_private_subnet:
+            cidr:
+              get_input: protected_private_net_cidr
+  groups:
+    base_vfw:
+      type: org.onap.groups.heat.HeatStack
+      members:
+      - vfw_private_0_port
+      - vsn_private_1_port
+      - unprotected_private_network
+      - vpg_private_1_port
+      - vfw_0
+      - vsn_0
+      - vpg_private_0_port
+      - vsn_private_0_port
+      - vfw_private_1_port
+      - vfw_private_2_port
+      - vpg_0
+      - protected_private_network
+      metadata:
+        invariantUUID: 44b0c172-7b61-49b5-a68a-810042087e1f
+        UUID: 24cb02f0-1d72-441f-a327-22d80180deaa
+        version: '1'
+        name: base_vfw
+    Eace933104d443b496b8..base_vfw..module-0:
+      type: org.onap.groups.VfModule
+      members:
+      - vfw_private_0_port
+      - vsn_private_1_port
+      - unprotected_private_network
+      - vpg_private_1_port
+      - vfw_0
+      - vsn_0
+      - vpg_private_0_port
+      - vsn_private_0_port
+      - vfw_private_1_port
+      - vfw_private_2_port
+      - vpg_0
+      - protected_private_network
+      metadata:
+        vfModuleModelName: Eace933104d443b496b8..base_vfw..module-0
+        vfModuleModelInvariantUUID: 58c105fd-9c12-4fb7-8a3e-a5ec280183fb
+        vfModuleModelUUID: ab251d24-4001-4926-aa5c-c01736b36c68
+        vfModuleModelVersion: '1'
+      properties:
+        vf_module_type: Base
+        vf_module_description:
+        volume_group: false
+  substitution_mappings:
+    node_type: org.onap.resource.vf.Eace933104d443b496b8
+    capabilities:
+      vfw_0.instance:
+        type: org.onap.capabilities.metric.Ceilometer
+        description: Existence of instance
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          description:
+            type: string
+            description: Description of the metric
+            required: false
+          type:
+            type: string
+            default: Gauge
+            description: Type of the metric value, for an example, Cumulative, Delta, Gauge and etc.
+            required: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          secure:
+            type: boolean
+            default: false
+          port_name:
+            type: string
+            required: false
+          unit:
+            type: string
+            default: instance
+            description: Unit of the metric value
+            required: true
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          name:
+            type: string
+            default: instance
+            description: Ceilometer metric type name to monitor. (The name ceilometer is using)
+            required: true
+          category:
+            type: string
+            default: compute
+            description: Category of the metric, for an example, compute, disk, network, storage and etc.
+            required: false
+          url_path:
+            type: string
+            required: false
+      vfw_0.scalable:
+        type: tosca.capabilities.Scalable
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          max_instances:
+            type: integer
+            default: 1
+          min_instances:
+            type: integer
+            default: 1
+          default_instances:
+            type: integer
+      vfw_0.instance:type:
+        type: org.onap.capabilities.metric.Ceilometer
+        description: Existence of instance <type> (OpenStack types)
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          description:
+            type: string
+            description: Description of the metric
+            required: false
+          type:
+            type: string
+            default: Gauge
+            description: Type of the metric value, for an example, Cumulative, Delta, Gauge and etc.
+            required: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          secure:
+            type: boolean
+            default: false
+          port_name:
+            type: string
+            required: false
+          unit:
+            type: string
+            default: instance
+            description: Unit of the metric value
+            required: true
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          name:
+            type: string
+            default: instance:type
+            description: Ceilometer metric type name to monitor. (The name ceilometer is using)
+            required: true
+          category:
+            type: string
+            default: compute
+            description: Category of the metric, for an example, compute, disk, network, storage and etc.
+            required: false
+          url_path:
+            type: string
+            required: false
+      protected_private_network.link:
+        type: tosca.capabilities.network.Linkable
+        occurrences:
+        - 0
+        - UNBOUNDED
+      vsn_0.cpu:
+        type: org.onap.capabilities.metric.Ceilometer
+        description: CPU time used
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          description:
+            type: string
+            description: Description of the metric
+            required: false
+          type:
+            type: string
+            default: Cumulative
+            description: Type of the metric value, for an example, Cumulative, Delta, Gauge and etc.
+            required: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          secure:
+            type: boolean
+            default: false
+          port_name:
+            type: string
+            required: false
+          unit:
+            type: string
+            default: ns
+            description: Unit of the metric value
+            required: true
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          name:
+            type: string
+            default: cpu
+            description: Ceilometer metric type name to monitor. (The name ceilometer is using)
+            required: true
+          category:
+            type: string
+            default: compute
+            description: Category of the metric, for an example, compute, disk, network, storage and etc.
+            required: false
+          url_path:
+            type: string
+            required: false
+      vpg_0.instance:type:
+        type: org.onap.capabilities.metric.Ceilometer
+        description: Existence of instance <type> (OpenStack types)
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          description:
+            type: string
+            description: Description of the metric
+            required: false
+          type:
+            type: string
+            default: Gauge
+            description: Type of the metric value, for an example, Cumulative, Delta, Gauge and etc.
+            required: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          secure:
+            type: boolean
+            default: false
+          port_name:
+            type: string
+            required: false
+          unit:
+            type: string
+            default: instance
+            description: Unit of the metric value
+            required: true
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          name:
+            type: string
+            default: instance:type
+            description: Ceilometer metric type name to monitor. (The name ceilometer is using)
+            required: true
+          category:
+            type: string
+            default: compute
+            description: Category of the metric, for an example, compute, disk, network, storage and etc.
+            required: false
+          url_path:
+            type: string
+            required: false
+      unprotected_private_network.attachment:
+        type: tosca.capabilities.Attachment
+        occurrences:
+        - 1
+        - UNBOUNDED
+      vfw_0.memory:
+        type: org.onap.capabilities.metric.Ceilometer
+        description: Volume of RAM allocated to the instance
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          description:
+            type: string
+            description: Description of the metric
+            required: false
+          type:
+            type: string
+            default: Gauge
+            description: Type of the metric value, for an example, Cumulative, Delta, Gauge and etc.
+            required: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          secure:
+            type: boolean
+            default: false
+          port_name:
+            type: string
+            required: false
+          unit:
+            type: string
+            default: MB
+            description: Unit of the metric value
+            required: true
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          name:
+            type: string
+            default: memory
+            description: Ceilometer metric type name to monitor. (The name ceilometer is using)
+            required: true
+          category:
+            type: string
+            default: compute
+            description: Category of the metric, for an example, compute, disk, network, storage and etc.
+            required: false
+          url_path:
+            type: string
+            required: false
+      vpg_0.cpu_util:
+        type: org.onap.capabilities.metric.Ceilometer
+        description: Average CPU utilization
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          description:
+            type: string
+            description: Description of the metric
+            required: false
+          type:
+            type: string
+            default: Gauge
+            description: Type of the metric value, for an example, Cumulative, Delta, Gauge and etc.
+            required: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          secure:
+            type: boolean
+            default: false
+          port_name:
+            type: string
+            required: false
+          unit:
+            type: string
+            default: '%'
+            description: Unit of the metric value
+            required: true
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          name:
+            type: string
+            default: cpu_util
+            description: Ceilometer metric type name to monitor. (The name ceilometer is using)
+            required: true
+          category:
+            type: string
+            default: compute
+            description: Category of the metric, for an example, compute, disk, network, storage and etc.
+            required: false
+          url_path:
+            type: string
+            required: false
+      vpg_0.endpoint:
+        type: tosca.capabilities.Endpoint.Admin
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          port_name:
+            type: string
+            required: false
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          secure:
+            type: boolean
+            default: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          url_path:
+            type: string
+            required: false
+      vpg_private_0_port.attachment:
+        type: tosca.capabilities.Attachment
+        occurrences:
+        - 1
+        - UNBOUNDED
+      vfw_private_1_port.feature:
+        type: tosca.capabilities.Node
+        occurrences:
+        - 1
+        - UNBOUNDED
+      vfw_private_0_port.attachment:
+        type: tosca.capabilities.Attachment
+        occurrences:
+        - 1
+        - UNBOUNDED
+      vpg_0.cpu:
+        type: org.onap.capabilities.metric.Ceilometer
+        description: CPU time used
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          description:
+            type: string
+            description: Description of the metric
+            required: false
+          type:
+            type: string
+            default: Cumulative
+            description: Type of the metric value, for an example, Cumulative, Delta, Gauge and etc.
+            required: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          secure:
+            type: boolean
+            default: false
+          port_name:
+            type: string
+            required: false
+          unit:
+            type: string
+            default: ns
+            description: Unit of the metric value
+            required: true
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          name:
+            type: string
+            default: cpu
+            description: Ceilometer metric type name to monitor. (The name ceilometer is using)
+            required: true
+          category:
+            type: string
+            default: compute
+            description: Category of the metric, for an example, compute, disk, network, storage and etc.
+            required: false
+          url_path:
+            type: string
+            required: false
+      vpg_private_1_port.attachment:
+        type: tosca.capabilities.Attachment
+        occurrences:
+        - 1
+        - UNBOUNDED
+      vsn_0.vcpus:
+        type: org.onap.capabilities.metric.Ceilometer
+        description: Average disk latency
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          description:
+            type: string
+            description: Description of the metric
+            required: false
+          type:
+            type: string
+            default: Gauge
+            description: Type of the metric value, for an example, Cumulative, Delta, Gauge and etc.
+            required: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          secure:
+            type: boolean
+            default: false
+          port_name:
+            type: string
+            required: false
+          unit:
+            type: string
+            default: ms
+            description: Unit of the metric value
+            required: true
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          name:
+            type: string
+            default: vcpus
+            description: Ceilometer metric type name to monitor. (The name ceilometer is using)
+            required: true
+          category:
+            type: string
+            default: compute
+            description: Category of the metric, for an example, compute, disk, network, storage and etc.
+            required: false
+          url_path:
+            type: string
+            required: false
+      vpg_0.cpu.delta:
+        type: org.onap.capabilities.metric.Ceilometer
+        description: CPU time used since previous datapoint
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          description:
+            type: string
+            description: Description of the metric
+            required: false
+          type:
+            type: string
+            default: Delta
+            description: Type of the metric value, for an example, Cumulative, Delta, Gauge and etc.
+            required: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          secure:
+            type: boolean
+            default: false
+          port_name:
+            type: string
+            required: false
+          unit:
+            type: string
+            default: ns
+            description: Unit of the metric value
+            required: true
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          name:
+            type: string
+            default: cpu.delta
+            description: Ceilometer metric type name to monitor. (The name ceilometer is using)
+            required: true
+          category:
+            type: string
+            default: compute
+            description: Category of the metric, for an example, compute, disk, network, storage and etc.
+            required: false
+          url_path:
+            type: string
+            required: false
+      vsn_private_1_port.attachment:
+        type: tosca.capabilities.Attachment
+        occurrences:
+        - 1
+        - UNBOUNDED
+      vsn_0.cpu_util:
+        type: org.onap.capabilities.metric.Ceilometer
+        description: Average CPU utilization
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          description:
+            type: string
+            description: Description of the metric
+            required: false
+          type:
+            type: string
+            default: Gauge
+            description: Type of the metric value, for an example, Cumulative, Delta, Gauge and etc.
+            required: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          secure:
+            type: boolean
+            default: false
+          port_name:
+            type: string
+            required: false
+          unit:
+            type: string
+            default: '%'
+            description: Unit of the metric value
+            required: true
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          name:
+            type: string
+            default: cpu_util
+            description: Ceilometer metric type name to monitor. (The name ceilometer is using)
+            required: true
+          category:
+            type: string
+            default: compute
+            description: Category of the metric, for an example, compute, disk, network, storage and etc.
+            required: false
+          url_path:
+            type: string
+            required: false
+      vpg_0.instance:
+        type: org.onap.capabilities.metric.Ceilometer
+        description: Existence of instance
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          description:
+            type: string
+            description: Description of the metric
+            required: false
+          type:
+            type: string
+            default: Gauge
+            description: Type of the metric value, for an example, Cumulative, Delta, Gauge and etc.
+            required: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          secure:
+            type: boolean
+            default: false
+          port_name:
+            type: string
+            required: false
+          unit:
+            type: string
+            default: instance
+            description: Unit of the metric value
+            required: true
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          name:
+            type: string
+            default: instance
+            description: Ceilometer metric type name to monitor. (The name ceilometer is using)
+            required: true
+          category:
+            type: string
+            default: compute
+            description: Category of the metric, for an example, compute, disk, network, storage and etc.
+            required: false
+          url_path:
+            type: string
+            required: false
+      vpg_0.feature:
+        type: tosca.capabilities.Node
+        occurrences:
+        - 1
+        - UNBOUNDED
+      vpg_0.scalable:
+        type: tosca.capabilities.Scalable
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          max_instances:
+            type: integer
+            default: 1
+          min_instances:
+            type: integer
+            default: 1
+          default_instances:
+            type: integer
+      vpg_0.memory:
+        type: org.onap.capabilities.metric.Ceilometer
+        description: Volume of RAM allocated to the instance
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          description:
+            type: string
+            description: Description of the metric
+            required: false
+          type:
+            type: string
+            default: Gauge
+            description: Type of the metric value, for an example, Cumulative, Delta, Gauge and etc.
+            required: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          secure:
+            type: boolean
+            default: false
+          port_name:
+            type: string
+            required: false
+          unit:
+            type: string
+            default: MB
+            description: Unit of the metric value
+            required: true
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          name:
+            type: string
+            default: memory
+            description: Ceilometer metric type name to monitor. (The name ceilometer is using)
+            required: true
+          category:
+            type: string
+            default: compute
+            description: Category of the metric, for an example, compute, disk, network, storage and etc.
+            required: false
+          url_path:
+            type: string
+            required: false
+      vfw_private_2_port.attachment:
+        type: tosca.capabilities.Attachment
+        occurrences:
+        - 1
+        - UNBOUNDED
+      vsn_0.os:
+        type: tosca.capabilities.OperatingSystem
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          distribution:
+            type: string
+            required: false
+          type:
+            type: string
+            required: false
+          version:
+            type: version
+            required: false
+          architecture:
+            type: string
+            required: false
+      vfw_0.memory.resident:
+        type: org.onap.capabilities.metric.Ceilometer
+        description: Volume of RAM used by the instance on the physical machine
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          description:
+            type: string
+            description: Description of the metric
+            required: false
+          type:
+            type: string
+            default: Gauge
+            description: Type of the metric value, for an example, Cumulative, Delta, Gauge and etc.
+            required: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          secure:
+            type: boolean
+            default: false
+          port_name:
+            type: string
+            required: false
+          unit:
+            type: string
+            default: MB
+            description: Unit of the metric value
+            required: true
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          name:
+            type: string
+            default: memory.resident
+            description: Ceilometer metric type name to monitor. (The name ceilometer is using)
+            required: true
+          category:
+            type: string
+            default: compute
+            description: Category of the metric, for an example, compute, disk, network, storage and etc.
+            required: false
+          url_path:
+            type: string
+            required: false
+      vsn_0.scalable:
+        type: tosca.capabilities.Scalable
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          max_instances:
+            type: integer
+            default: 1
+          min_instances:
+            type: integer
+            default: 1
+          default_instances:
+            type: integer
+      vsn_0.instance:
+        type: org.onap.capabilities.metric.Ceilometer
+        description: Existence of instance
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          description:
+            type: string
+            description: Description of the metric
+            required: false
+          type:
+            type: string
+            default: Gauge
+            description: Type of the metric value, for an example, Cumulative, Delta, Gauge and etc.
+            required: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          secure:
+            type: boolean
+            default: false
+          port_name:
+            type: string
+            required: false
+          unit:
+            type: string
+            default: instance
+            description: Unit of the metric value
+            required: true
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          name:
+            type: string
+            default: instance
+            description: Ceilometer metric type name to monitor. (The name ceilometer is using)
+            required: true
+          category:
+            type: string
+            default: compute
+            description: Category of the metric, for an example, compute, disk, network, storage and etc.
+            required: false
+          url_path:
+            type: string
+            required: false
+      vfw_0.endpoint:
+        type: tosca.capabilities.Endpoint.Admin
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          port_name:
+            type: string
+            required: false
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          secure:
+            type: boolean
+            default: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          url_path:
+            type: string
+            required: false
+      vsn_0.cpu.delta:
+        type: org.onap.capabilities.metric.Ceilometer
+        description: CPU time used since previous datapoint
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          description:
+            type: string
+            description: Description of the metric
+            required: false
+          type:
+            type: string
+            default: Delta
+            description: Type of the metric value, for an example, Cumulative, Delta, Gauge and etc.
+            required: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          secure:
+            type: boolean
+            default: false
+          port_name:
+            type: string
+            required: false
+          unit:
+            type: string
+            default: ns
+            description: Unit of the metric value
+            required: true
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          name:
+            type: string
+            default: cpu.delta
+            description: Ceilometer metric type name to monitor. (The name ceilometer is using)
+            required: true
+          category:
+            type: string
+            default: compute
+            description: Category of the metric, for an example, compute, disk, network, storage and etc.
+            required: false
+          url_path:
+            type: string
+            required: false
+      vfw_0.os:
+        type: tosca.capabilities.OperatingSystem
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          distribution:
+            type: string
+            required: false
+          type:
+            type: string
+            required: false
+          version:
+            type: version
+            required: false
+          architecture:
+            type: string
+            required: false
+      vsn_private_1_port.feature:
+        type: tosca.capabilities.Node
+        occurrences:
+        - 1
+        - UNBOUNDED
+      vsn_private_0_port.feature:
+        type: tosca.capabilities.Node
+        occurrences:
+        - 1
+        - UNBOUNDED
+      vfw_0.memory.usage:
+        type: org.onap.capabilities.metric.Ceilometer
+        description: Volume of RAM used by the instance from the amount of its allocated memory
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          description:
+            type: string
+            description: Description of the metric
+            required: false
+          type:
+            type: string
+            default: Gauge
+            description: Type of the metric value, for an example, Cumulative, Delta, Gauge and etc.
+            required: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          secure:
+            type: boolean
+            default: false
+          port_name:
+            type: string
+            required: false
+          unit:
+            type: string
+            default: MB
+            description: Unit of the metric value
+            required: true
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          name:
+            type: string
+            default: memory.usage
+            description: Ceilometer metric type name to monitor. (The name ceilometer is using)
+            required: true
+          category:
+            type: string
+            default: compute
+            description: Category of the metric, for an example, compute, disk, network, storage and etc.
+            required: false
+          url_path:
+            type: string
+            required: false
+      vsn_0.host:
+        type: tosca.capabilities.Container
+        occurrences:
+        - 1
+        - UNBOUNDED
+        valid_source_types:
+        - tosca.nodes.SoftwareComponent
+        properties:
+          num_cpus:
+            type: integer
+            required: false
+          disk_size:
+            type: scalar-unit.size
+            required: false
+          cpu_frequency:
+            type: scalar-unit.frequency
+            required: false
+          mem_size:
+            type: scalar-unit.size
+            required: false
+      vsn_0.memory:
+        type: org.onap.capabilities.metric.Ceilometer
+        description: Volume of RAM allocated to the instance
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          description:
+            type: string
+            description: Description of the metric
+            required: false
+          type:
+            type: string
+            default: Gauge
+            description: Type of the metric value, for an example, Cumulative, Delta, Gauge and etc.
+            required: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          secure:
+            type: boolean
+            default: false
+          port_name:
+            type: string
+            required: false
+          unit:
+            type: string
+            default: MB
+            description: Unit of the metric value
+            required: true
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          name:
+            type: string
+            default: memory
+            description: Ceilometer metric type name to monitor. (The name ceilometer is using)
+            required: true
+          category:
+            type: string
+            default: compute
+            description: Category of the metric, for an example, compute, disk, network, storage and etc.
+            required: false
+          url_path:
+            type: string
+            required: false
+      unprotected_private_network.link:
+        type: tosca.capabilities.network.Linkable
+        occurrences:
+        - 0
+        - UNBOUNDED
+      vfw_0.host:
+        type: tosca.capabilities.Container
+        occurrences:
+        - 1
+        - UNBOUNDED
+        valid_source_types:
+        - tosca.nodes.SoftwareComponent
+        properties:
+          num_cpus:
+            type: integer
+            required: false
+          disk_size:
+            type: scalar-unit.size
+            required: false
+          cpu_frequency:
+            type: scalar-unit.frequency
+            required: false
+          mem_size:
+            type: scalar-unit.size
+            required: false
+      vsn_private_0_port.attachment:
+        type: tosca.capabilities.Attachment
+        occurrences:
+        - 1
+        - UNBOUNDED
+      vfw_private_2_port.feature:
+        type: tosca.capabilities.Node
+        occurrences:
+        - 1
+        - UNBOUNDED
+      unprotected_private_network.feature:
+        type: tosca.capabilities.Node
+        occurrences:
+        - 1
+        - UNBOUNDED
+      vpg_0.vcpus:
+        type: org.onap.capabilities.metric.Ceilometer
+        description: Average disk latency
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          description:
+            type: string
+            description: Description of the metric
+            required: false
+          type:
+            type: string
+            default: Gauge
+            description: Type of the metric value, for an example, Cumulative, Delta, Gauge and etc.
+            required: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          secure:
+            type: boolean
+            default: false
+          port_name:
+            type: string
+            required: false
+          unit:
+            type: string
+            default: ms
+            description: Unit of the metric value
+            required: true
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          name:
+            type: string
+            default: vcpus
+            description: Ceilometer metric type name to monitor. (The name ceilometer is using)
+            required: true
+          category:
+            type: string
+            default: compute
+            description: Category of the metric, for an example, compute, disk, network, storage and etc.
+            required: false
+          url_path:
+            type: string
+            required: false
+      vpg_0.binding:
+        type: tosca.capabilities.network.Bindable
+        occurrences:
+        - 0
+        - UNBOUNDED
+      vpg_0.host:
+        type: tosca.capabilities.Container
+        occurrences:
+        - 1
+        - UNBOUNDED
+        valid_source_types:
+        - tosca.nodes.SoftwareComponent
+        properties:
+          num_cpus:
+            type: integer
+            required: false
+          disk_size:
+            type: scalar-unit.size
+            required: false
+          cpu_frequency:
+            type: scalar-unit.frequency
+            required: false
+          mem_size:
+            type: scalar-unit.size
+            required: false
+      vsn_0.binding:
+        type: tosca.capabilities.network.Bindable
+        occurrences:
+        - 0
+        - UNBOUNDED
+      protected_private_network.attachment:
+        type: tosca.capabilities.Attachment
+        occurrences:
+        - 1
+        - UNBOUNDED
+      vfw_0.binding:
+        type: tosca.capabilities.network.Bindable
+        occurrences:
+        - 0
+        - UNBOUNDED
+      vpg_0.memory.usage:
+        type: org.onap.capabilities.metric.Ceilometer
+        description: Volume of RAM used by the instance from the amount of its allocated memory
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          description:
+            type: string
+            description: Description of the metric
+            required: false
+          type:
+            type: string
+            default: Gauge
+            description: Type of the metric value, for an example, Cumulative, Delta, Gauge and etc.
+            required: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          secure:
+            type: boolean
+            default: false
+          port_name:
+            type: string
+            required: false
+          unit:
+            type: string
+            default: MB
+            description: Unit of the metric value
+            required: true
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          name:
+            type: string
+            default: memory.usage
+            description: Ceilometer metric type name to monitor. (The name ceilometer is using)
+            required: true
+          category:
+            type: string
+            default: compute
+            description: Category of the metric, for an example, compute, disk, network, storage and etc.
+            required: false
+          url_path:
+            type: string
+            required: false
+      vfw_private_0_port.feature:
+        type: tosca.capabilities.Node
+        occurrences:
+        - 1
+        - UNBOUNDED
+      vsn_0.endpoint:
+        type: tosca.capabilities.Endpoint.Admin
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          port_name:
+            type: string
+            required: false
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          secure:
+            type: boolean
+            default: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          url_path:
+            type: string
+            required: false
+      vfw_0.feature:
+        type: tosca.capabilities.Node
+        occurrences:
+        - 1
+        - UNBOUNDED
+      protected_private_network.feature:
+        type: tosca.capabilities.Node
+        occurrences:
+        - 1
+        - UNBOUNDED
+      vfw_0.cpu:
+        type: org.onap.capabilities.metric.Ceilometer
+        description: CPU time used
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          description:
+            type: string
+            description: Description of the metric
+            required: false
+          type:
+            type: string
+            default: Cumulative
+            description: Type of the metric value, for an example, Cumulative, Delta, Gauge and etc.
+            required: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          secure:
+            type: boolean
+            default: false
+          port_name:
+            type: string
+            required: false
+          unit:
+            type: string
+            default: ns
+            description: Unit of the metric value
+            required: true
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          name:
+            type: string
+            default: cpu
+            description: Ceilometer metric type name to monitor. (The name ceilometer is using)
+            required: true
+          category:
+            type: string
+            default: compute
+            description: Category of the metric, for an example, compute, disk, network, storage and etc.
+            required: false
+          url_path:
+            type: string
+            required: false
+      vsn_0.instance:type:
+        type: org.onap.capabilities.metric.Ceilometer
+        description: Existence of instance <type> (OpenStack types)
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          description:
+            type: string
+            description: Description of the metric
+            required: false
+          type:
+            type: string
+            default: Gauge
+            description: Type of the metric value, for an example, Cumulative, Delta, Gauge and etc.
+            required: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          secure:
+            type: boolean
+            default: false
+          port_name:
+            type: string
+            required: false
+          unit:
+            type: string
+            default: instance
+            description: Unit of the metric value
+            required: true
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          name:
+            type: string
+            default: instance:type
+            description: Ceilometer metric type name to monitor. (The name ceilometer is using)
+            required: true
+          category:
+            type: string
+            default: compute
+            description: Category of the metric, for an example, compute, disk, network, storage and etc.
+            required: false
+          url_path:
+            type: string
+            required: false
+      vpg_0.os:
+        type: tosca.capabilities.OperatingSystem
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          distribution:
+            type: string
+            required: false
+          type:
+            type: string
+            required: false
+          version:
+            type: version
+            required: false
+          architecture:
+            type: string
+            required: false
+      vsn_0.feature:
+        type: tosca.capabilities.Node
+        occurrences:
+        - 1
+        - UNBOUNDED
+      vfw_0.vcpus:
+        type: org.onap.capabilities.metric.Ceilometer
+        description: Average disk latency
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          description:
+            type: string
+            description: Description of the metric
+            required: false
+          type:
+            type: string
+            default: Gauge
+            description: Type of the metric value, for an example, Cumulative, Delta, Gauge and etc.
+            required: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          secure:
+            type: boolean
+            default: false
+          port_name:
+            type: string
+            required: false
+          unit:
+            type: string
+            default: ms
+            description: Unit of the metric value
+            required: true
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          name:
+            type: string
+            default: vcpus
+            description: Ceilometer metric type name to monitor. (The name ceilometer is using)
+            required: true
+          category:
+            type: string
+            default: compute
+            description: Category of the metric, for an example, compute, disk, network, storage and etc.
+            required: false
+          url_path:
+            type: string
+            required: false
+      vfw_0.cpu.delta:
+        type: org.onap.capabilities.metric.Ceilometer
+        description: CPU time used since previous datapoint
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          description:
+            type: string
+            description: Description of the metric
+            required: false
+          type:
+            type: string
+            default: Delta
+            description: Type of the metric value, for an example, Cumulative, Delta, Gauge and etc.
+            required: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          secure:
+            type: boolean
+            default: false
+          port_name:
+            type: string
+            required: false
+          unit:
+            type: string
+            default: ns
+            description: Unit of the metric value
+            required: true
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          name:
+            type: string
+            default: cpu.delta
+            description: Ceilometer metric type name to monitor. (The name ceilometer is using)
+            required: true
+          category:
+            type: string
+            default: compute
+            description: Category of the metric, for an example, compute, disk, network, storage and etc.
+            required: false
+          url_path:
+            type: string
+            required: false
+      vsn_0.memory.resident:
+        type: org.onap.capabilities.metric.Ceilometer
+        description: Volume of RAM used by the instance on the physical machine
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          description:
+            type: string
+            description: Description of the metric
+            required: false
+          type:
+            type: string
+            default: Gauge
+            description: Type of the metric value, for an example, Cumulative, Delta, Gauge and etc.
+            required: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          secure:
+            type: boolean
+            default: false
+          port_name:
+            type: string
+            required: false
+          unit:
+            type: string
+            default: MB
+            description: Unit of the metric value
+            required: true
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          name:
+            type: string
+            default: memory.resident
+            description: Ceilometer metric type name to monitor. (The name ceilometer is using)
+            required: true
+          category:
+            type: string
+            default: compute
+            description: Category of the metric, for an example, compute, disk, network, storage and etc.
+            required: false
+          url_path:
+            type: string
+            required: false
+      vsn_0.memory.usage:
+        type: org.onap.capabilities.metric.Ceilometer
+        description: Volume of RAM used by the instance from the amount of its allocated memory
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          description:
+            type: string
+            description: Description of the metric
+            required: false
+          type:
+            type: string
+            default: Gauge
+            description: Type of the metric value, for an example, Cumulative, Delta, Gauge and etc.
+            required: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          secure:
+            type: boolean
+            default: false
+          port_name:
+            type: string
+            required: false
+          unit:
+            type: string
+            default: MB
+            description: Unit of the metric value
+            required: true
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          name:
+            type: string
+            default: memory.usage
+            description: Ceilometer metric type name to monitor. (The name ceilometer is using)
+            required: true
+          category:
+            type: string
+            default: compute
+            description: Category of the metric, for an example, compute, disk, network, storage and etc.
+            required: false
+          url_path:
+            type: string
+            required: false
+      vfw_private_1_port.attachment:
+        type: tosca.capabilities.Attachment
+        occurrences:
+        - 1
+        - UNBOUNDED
+      vfw_0.cpu_util:
+        type: org.onap.capabilities.metric.Ceilometer
+        description: Average CPU utilization
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          description:
+            type: string
+            description: Description of the metric
+            required: false
+          type:
+            type: string
+            default: Gauge
+            description: Type of the metric value, for an example, Cumulative, Delta, Gauge and etc.
+            required: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          secure:
+            type: boolean
+            default: false
+          port_name:
+            type: string
+            required: false
+          unit:
+            type: string
+            default: '%'
+            description: Unit of the metric value
+            required: true
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          name:
+            type: string
+            default: cpu_util
+            description: Ceilometer metric type name to monitor. (The name ceilometer is using)
+            required: true
+          category:
+            type: string
+            default: compute
+            description: Category of the metric, for an example, compute, disk, network, storage and etc.
+            required: false
+          url_path:
+            type: string
+            required: false
+      vpg_0.memory.resident:
+        type: org.onap.capabilities.metric.Ceilometer
+        description: Volume of RAM used by the instance on the physical machine
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          description:
+            type: string
+            description: Description of the metric
+            required: false
+          type:
+            type: string
+            default: Gauge
+            description: Type of the metric value, for an example, Cumulative, Delta, Gauge and etc.
+            required: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          secure:
+            type: boolean
+            default: false
+          port_name:
+            type: string
+            required: false
+          unit:
+            type: string
+            default: MB
+            description: Unit of the metric value
+            required: true
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          name:
+            type: string
+            default: memory.resident
+            description: Ceilometer metric type name to monitor. (The name ceilometer is using)
+            required: true
+          category:
+            type: string
+            default: compute
+            description: Category of the metric, for an example, compute, disk, network, storage and etc.
+            required: false
+          url_path:
+            type: string
+            required: false
+      vpg_private_0_port.feature:
+        type: tosca.capabilities.Node
+        occurrences:
+        - 1
+        - UNBOUNDED
+      vpg_private_1_port.feature:
+        type: tosca.capabilities.Node
+        occurrences:
+        - 1
+        - UNBOUNDED
+    requirements:
+      vsn_private_1_port.link:
+        occurrences:
+        - 1
+        - 1
+        capability: tosca.capabilities.network.Linkable
+        relationship: tosca.relationships.network.LinksTo
+      vfw_0.local_storage:
+        occurrences:
+        - 0
+        - UNBOUNDED
+        capability: tosca.capabilities.Attachment
+        node: tosca.nodes.BlockStorage
+        relationship: tosca.relationships.AttachesTo
+      vfw_private_1_port.dependency:
+        occurrences:
+        - 0
+        - UNBOUNDED
+        capability: tosca.capabilities.Node
+        node: tosca.nodes.Root
+        relationship: tosca.relationships.DependsOn
+      vpg_private_1_port.link:
+        occurrences:
+        - 1
+        - 1
+        capability: tosca.capabilities.network.Linkable
+        relationship: tosca.relationships.network.LinksTo
+      vsn_0.local_storage:
+        occurrences:
+        - 0
+        - UNBOUNDED
+        capability: tosca.capabilities.Attachment
+        node: tosca.nodes.BlockStorage
+        relationship: tosca.relationships.AttachesTo
+      protected_private_network.dependency:
+        occurrences:
+        - 0
+        - UNBOUNDED
+        capability: tosca.capabilities.Node
+        node: tosca.nodes.Root
+        relationship: tosca.relationships.DependsOn
+      vfw_private_2_port.dependency:
+        occurrences:
+        - 0
+        - UNBOUNDED
+        capability: tosca.capabilities.Node
+        node: tosca.nodes.Root
+        relationship: tosca.relationships.DependsOn
+      vfw_private_2_port.link:
+        occurrences:
+        - 1
+        - 1
+        capability: tosca.capabilities.network.Linkable
+        relationship: tosca.relationships.network.LinksTo
+      unprotected_private_network.dependency:
+        occurrences:
+        - 0
+        - UNBOUNDED
+        capability: tosca.capabilities.Node
+        node: tosca.nodes.Root
+        relationship: tosca.relationships.DependsOn
+      vsn_private_0_port.dependency:
+        occurrences:
+        - 0
+        - UNBOUNDED
+        capability: tosca.capabilities.Node
+        node: tosca.nodes.Root
+        relationship: tosca.relationships.DependsOn
+      vpg_0.local_storage:
+        occurrences:
+        - 0
+        - UNBOUNDED
+        capability: tosca.capabilities.Attachment
+        node: tosca.nodes.BlockStorage
+        relationship: tosca.relationships.AttachesTo
+      vsn_private_1_port.dependency:
+        occurrences:
+        - 0
+        - UNBOUNDED
+        capability: tosca.capabilities.Node
+        node: tosca.nodes.Root
+        relationship: tosca.relationships.DependsOn
+      vfw_0.dependency:
+        occurrences:
+        - 0
+        - UNBOUNDED
+        capability: tosca.capabilities.Node
+        node: tosca.nodes.Root
+        relationship: tosca.relationships.DependsOn
+      vpg_0.dependency:
+        occurrences:
+        - 0
+        - UNBOUNDED
+        capability: tosca.capabilities.Node
+        node: tosca.nodes.Root
+        relationship: tosca.relationships.DependsOn
+      vpg_private_1_port.dependency:
+        occurrences:
+        - 0
+        - UNBOUNDED
+        capability: tosca.capabilities.Node
+        node: tosca.nodes.Root
+        relationship: tosca.relationships.DependsOn
+      vsn_0.dependency:
+        occurrences:
+        - 0
+        - UNBOUNDED
+        capability: tosca.capabilities.Node
+        node: tosca.nodes.Root
+        relationship: tosca.relationships.DependsOn
+      vpg_private_0_port.dependency:
+        occurrences:
+        - 0
+        - UNBOUNDED
+        capability: tosca.capabilities.Node
+        node: tosca.nodes.Root
+        relationship: tosca.relationships.DependsOn
+      vfw_private_0_port.dependency:
+        occurrences:
+        - 0
+        - UNBOUNDED
+        capability: tosca.capabilities.Node
+        node: tosca.nodes.Root
+        relationship: tosca.relationships.DependsOn
diff --git a/ONAP-ControlloopPolicy/src/test/resources/v2.0.0/Demo-1.0.0-HeatTemplates/service-57e66ea70ed645c7970f-template.yml b/ONAP-ControlloopPolicy/src/test/resources/v2.0.0/Demo-1.0.0-HeatTemplates/service-57e66ea70ed645c7970f-template.yml
new file mode 100644
index 0000000..4bfd629
--- /dev/null
+++ b/ONAP-ControlloopPolicy/src/test/resources/v2.0.0/Demo-1.0.0-HeatTemplates/service-57e66ea70ed645c7970f-template.yml
@@ -0,0 +1,677 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+metadata:
+  invariantUUID: 5cfe6f4a-41bc-4247-8674-ebd4b98e35cc
+  UUID: 0f40bba5-986e-4b3c-803f-ddd1b7b25f24
+  name: 57e66ea7-0ed6-45c7-970f
+  description: catalog service description
+  type: Service
+  category: Network L1-3
+  serviceOnapNaming: false
+  serviceHoming: false
+imports:
+- eace9331-04d4-43b4-96b8:
+    file: resource-Eace933104d443b496b8-template.yml
+topology_template:
+  node_templates:
+    eace9331-04d4-43b4-96b8 1:
+      type: org.onap.resource.vf.Eace933104d443b496b8
+      metadata:
+        invariantUUID: 06fe411e-d006-4ac3-8b0e-fb4f13cd78d3
+        UUID: 172ce7c5-c2e4-4f8d-b66c-edb49e8e548a
+        version: '1.0'
+        name: eace9331-04d4-43b4-96b8
+        description: vendor software product
+        type: VF
+        category: Generic
+        subcategory: Abstract
+  substitution_mappings:
+    node_type: org.onap.service.57e66ea70ed645c7970f
+    capabilities:
+      eace9331-04d4-43b4-96b8 1.memory.resident:
+        type: org.onap.capabilities.metric.Ceilometer
+        description: Volume of RAM used by the instance on the physical machine
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          description:
+            type: string
+            description: Description of the metric
+            required: false
+          type:
+            type: string
+            default: Gauge
+            description: Type of the metric value, for an example, Cumulative, Delta, Gauge and etc.
+            required: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          secure:
+            type: boolean
+            default: false
+          port_name:
+            type: string
+            required: false
+          unit:
+            type: string
+            default: MB
+            description: Unit of the metric value
+            required: true
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          name:
+            type: string
+            default: memory.resident
+            description: Ceilometer metric type name to monitor. (The name ceilometer is using)
+            required: true
+          category:
+            type: string
+            default: compute
+            description: Category of the metric, for an example, compute, disk, network, storage and etc.
+            required: false
+          url_path:
+            type: string
+            required: false
+      eace9331-04d4-43b4-96b8 1.os:
+        type: tosca.capabilities.OperatingSystem
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          distribution:
+            type: string
+            required: false
+          type:
+            type: string
+            required: false
+          version:
+            type: version
+            required: false
+          architecture:
+            type: string
+            required: false
+      eace9331-04d4-43b4-96b8 1.binding:
+        type: tosca.capabilities.network.Bindable
+        occurrences:
+        - 0
+        - UNBOUNDED
+      eace9331-04d4-43b4-96b8 1.host:
+        type: tosca.capabilities.Container
+        occurrences:
+        - 1
+        - UNBOUNDED
+        valid_source_types:
+        - tosca.nodes.SoftwareComponent
+        properties:
+          num_cpus:
+            type: integer
+            required: false
+          disk_size:
+            type: scalar-unit.size
+            required: false
+          cpu_frequency:
+            type: scalar-unit.frequency
+            required: false
+          mem_size:
+            type: scalar-unit.size
+            required: false
+      eace9331-04d4-43b4-96b8 1.instance:
+        type: org.onap.capabilities.metric.Ceilometer
+        description: Existence of instance
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          description:
+            type: string
+            description: Description of the metric
+            required: false
+          type:
+            type: string
+            default: Gauge
+            description: Type of the metric value, for an example, Cumulative, Delta, Gauge and etc.
+            required: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          secure:
+            type: boolean
+            default: false
+          port_name:
+            type: string
+            required: false
+          unit:
+            type: string
+            default: instance
+            description: Unit of the metric value
+            required: true
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          name:
+            type: string
+            default: instance
+            description: Ceilometer metric type name to monitor. (The name ceilometer is using)
+            required: true
+          category:
+            type: string
+            default: compute
+            description: Category of the metric, for an example, compute, disk, network, storage and etc.
+            required: false
+          url_path:
+            type: string
+            required: false
+      eace9331-04d4-43b4-96b8 1.scalable:
+        type: tosca.capabilities.Scalable
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          max_instances:
+            type: integer
+            default: 1
+          min_instances:
+            type: integer
+            default: 1
+          default_instances:
+            type: integer
+      eace9331-04d4-43b4-96b8 1.memory:
+        type: org.onap.capabilities.metric.Ceilometer
+        description: Volume of RAM allocated to the instance
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          description:
+            type: string
+            description: Description of the metric
+            required: false
+          type:
+            type: string
+            default: Gauge
+            description: Type of the metric value, for an example, Cumulative, Delta, Gauge and etc.
+            required: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          secure:
+            type: boolean
+            default: false
+          port_name:
+            type: string
+            required: false
+          unit:
+            type: string
+            default: MB
+            description: Unit of the metric value
+            required: true
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          name:
+            type: string
+            default: memory
+            description: Ceilometer metric type name to monitor. (The name ceilometer is using)
+            required: true
+          category:
+            type: string
+            default: compute
+            description: Category of the metric, for an example, compute, disk, network, storage and etc.
+            required: false
+          url_path:
+            type: string
+            required: false
+      eace9331-04d4-43b4-96b8 1.feature:
+        type: tosca.capabilities.Node
+        occurrences:
+        - 1
+        - UNBOUNDED
+      eace9331-04d4-43b4-96b8 1.vcpus:
+        type: org.onap.capabilities.metric.Ceilometer
+        description: Average disk latency
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          description:
+            type: string
+            description: Description of the metric
+            required: false
+          type:
+            type: string
+            default: Gauge
+            description: Type of the metric value, for an example, Cumulative, Delta, Gauge and etc.
+            required: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          secure:
+            type: boolean
+            default: false
+          port_name:
+            type: string
+            required: false
+          unit:
+            type: string
+            default: ms
+            description: Unit of the metric value
+            required: true
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          name:
+            type: string
+            default: vcpus
+            description: Ceilometer metric type name to monitor. (The name ceilometer is using)
+            required: true
+          category:
+            type: string
+            default: compute
+            description: Category of the metric, for an example, compute, disk, network, storage and etc.
+            required: false
+          url_path:
+            type: string
+            required: false
+      eace9331-04d4-43b4-96b8 1.cpu_util:
+        type: org.onap.capabilities.metric.Ceilometer
+        description: Average CPU utilization
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          description:
+            type: string
+            description: Description of the metric
+            required: false
+          type:
+            type: string
+            default: Gauge
+            description: Type of the metric value, for an example, Cumulative, Delta, Gauge and etc.
+            required: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          secure:
+            type: boolean
+            default: false
+          port_name:
+            type: string
+            required: false
+          unit:
+            type: string
+            default: '%'
+            description: Unit of the metric value
+            required: true
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          name:
+            type: string
+            default: cpu_util
+            description: Ceilometer metric type name to monitor. (The name ceilometer is using)
+            required: true
+          category:
+            type: string
+            default: compute
+            description: Category of the metric, for an example, compute, disk, network, storage and etc.
+            required: false
+          url_path:
+            type: string
+            required: false
+      eace9331-04d4-43b4-96b8 1.cpu.delta:
+        type: org.onap.capabilities.metric.Ceilometer
+        description: CPU time used since previous datapoint
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          description:
+            type: string
+            description: Description of the metric
+            required: false
+          type:
+            type: string
+            default: Delta
+            description: Type of the metric value, for an example, Cumulative, Delta, Gauge and etc.
+            required: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          secure:
+            type: boolean
+            default: false
+          port_name:
+            type: string
+            required: false
+          unit:
+            type: string
+            default: ns
+            description: Unit of the metric value
+            required: true
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          name:
+            type: string
+            default: cpu.delta
+            description: Ceilometer metric type name to monitor. (The name ceilometer is using)
+            required: true
+          category:
+            type: string
+            default: compute
+            description: Category of the metric, for an example, compute, disk, network, storage and etc.
+            required: false
+          url_path:
+            type: string
+            required: false
+      eace9331-04d4-43b4-96b8 1.attachment:
+        type: tosca.capabilities.Attachment
+        occurrences:
+        - 1
+        - UNBOUNDED
+      eace9331-04d4-43b4-96b8 1.cpu:
+        type: org.onap.capabilities.metric.Ceilometer
+        description: CPU time used
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          description:
+            type: string
+            description: Description of the metric
+            required: false
+          type:
+            type: string
+            default: Cumulative
+            description: Type of the metric value, for an example, Cumulative, Delta, Gauge and etc.
+            required: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          secure:
+            type: boolean
+            default: false
+          port_name:
+            type: string
+            required: false
+          unit:
+            type: string
+            default: ns
+            description: Unit of the metric value
+            required: true
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          name:
+            type: string
+            default: cpu
+            description: Ceilometer metric type name to monitor. (The name ceilometer is using)
+            required: true
+          category:
+            type: string
+            default: compute
+            description: Category of the metric, for an example, compute, disk, network, storage and etc.
+            required: false
+          url_path:
+            type: string
+            required: false
+      eace9331-04d4-43b4-96b8 1.instance:type:
+        type: org.onap.capabilities.metric.Ceilometer
+        description: Existence of instance <type> (OpenStack types)
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          description:
+            type: string
+            description: Description of the metric
+            required: false
+          type:
+            type: string
+            default: Gauge
+            description: Type of the metric value, for an example, Cumulative, Delta, Gauge and etc.
+            required: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          secure:
+            type: boolean
+            default: false
+          port_name:
+            type: string
+            required: false
+          unit:
+            type: string
+            default: instance
+            description: Unit of the metric value
+            required: true
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          name:
+            type: string
+            default: instance:type
+            description: Ceilometer metric type name to monitor. (The name ceilometer is using)
+            required: true
+          category:
+            type: string
+            default: compute
+            description: Category of the metric, for an example, compute, disk, network, storage and etc.
+            required: false
+          url_path:
+            type: string
+            required: false
+      eace9331-04d4-43b4-96b8 1.link:
+        type: tosca.capabilities.network.Linkable
+        occurrences:
+        - 0
+        - UNBOUNDED
+      eace9331-04d4-43b4-96b8 1.memory.usage:
+        type: org.onap.capabilities.metric.Ceilometer
+        description: Volume of RAM used by the instance from the amount of its allocated memory
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          description:
+            type: string
+            description: Description of the metric
+            required: false
+          type:
+            type: string
+            default: Gauge
+            description: Type of the metric value, for an example, Cumulative, Delta, Gauge and etc.
+            required: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          secure:
+            type: boolean
+            default: false
+          port_name:
+            type: string
+            required: false
+          unit:
+            type: string
+            default: MB
+            description: Unit of the metric value
+            required: true
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          name:
+            type: string
+            default: memory.usage
+            description: Ceilometer metric type name to monitor. (The name ceilometer is using)
+            required: true
+          category:
+            type: string
+            default: compute
+            description: Category of the metric, for an example, compute, disk, network, storage and etc.
+            required: false
+          url_path:
+            type: string
+            required: false
+      eace9331-04d4-43b4-96b8 1.endpoint:
+        type: tosca.capabilities.Endpoint.Admin
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          port_name:
+            type: string
+            required: false
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          secure:
+            type: boolean
+            default: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          url_path:
+            type: string
+            required: false
+    requirements:
+      eace9331-04d4-43b4-96b8 1.local_storage:
+        occurrences:
+        - 0
+        - UNBOUNDED
+        capability: tosca.capabilities.Attachment
+        node: tosca.nodes.BlockStorage
+        relationship: tosca.relationships.AttachesTo
+      eace9331-04d4-43b4-96b8 1.dependency:
+        occurrences:
+        - 0
+        - UNBOUNDED
+        capability: tosca.capabilities.Node
+        node: tosca.nodes.Root
+        relationship: tosca.relationships.DependsOn
+      eace9331-04d4-43b4-96b8 1.link:
+        occurrences:
+        - 1
+        - 1
+        capability: tosca.capabilities.network.Linkable
+        relationship: tosca.relationships.network.LinksTo
diff --git a/ONAP-ControlloopPolicy/src/test/resources/v2.0.0/Demo-1.0.0-HeatTemplates/service-D473899264974dca9db9-template.yml b/ONAP-ControlloopPolicy/src/test/resources/v2.0.0/Demo-1.0.0-HeatTemplates/service-D473899264974dca9db9-template.yml
new file mode 100644
index 0000000..2293b3a
--- /dev/null
+++ b/ONAP-ControlloopPolicy/src/test/resources/v2.0.0/Demo-1.0.0-HeatTemplates/service-D473899264974dca9db9-template.yml
@@ -0,0 +1,677 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+metadata:
+  invariantUUID: dc112d6e-7e73-4777-9c6f-1a7fb5fd1b6f
+  UUID: 2eea06c6-e1d3-4c3a-b9c4-478c506eeedf
+  name: d4738992-6497-4dca-9db9
+  description: catalog service description
+  type: Service
+  category: Network L1-3
+  serviceOnapNaming: false
+  serviceHoming: false
+imports:
+- 59a2ee3f-b580-45fe-b5a1:
+    file: resource-59a2ee3fB58045feB5a1-template.yml
+topology_template:
+  node_templates:
+    59a2ee3f-b580-45fe-b5a1 1:
+      type: org.onap.resource.vf.59a2ee3fB58045feB5a1
+      metadata:
+        invariantUUID: 4b8d4018-068b-4c33-b9bb-d980798e52c2
+        UUID: d7d28881-b24d-4512-bfee-1e2eb335591f
+        version: '1.0'
+        name: 59a2ee3f-b580-45fe-b5a1
+        description: vendor software product
+        type: VF
+        category: Generic
+        subcategory: Abstract
+  substitution_mappings:
+    node_type: org.onap.service.D473899264974dca9db9
+    capabilities:
+      59a2ee3f-b580-45fe-b5a1 1.memory.resident:
+        type: org.onap.capabilities.metric.Ceilometer
+        description: Volume of RAM used by the instance on the physical machine
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          description:
+            type: string
+            description: Description of the metric
+            required: false
+          type:
+            type: string
+            default: Gauge
+            description: Type of the metric value, for an example, Cumulative, Delta, Gauge and etc.
+            required: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          secure:
+            type: boolean
+            default: false
+          port_name:
+            type: string
+            required: false
+          unit:
+            type: string
+            default: MB
+            description: Unit of the metric value
+            required: true
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          name:
+            type: string
+            default: memory.resident
+            description: Ceilometer metric type name to monitor. (The name ceilometer is using)
+            required: true
+          category:
+            type: string
+            default: compute
+            description: Category of the metric, for an example, compute, disk, network, storage and etc.
+            required: false
+          url_path:
+            type: string
+            required: false
+      59a2ee3f-b580-45fe-b5a1 1.endpoint:
+        type: tosca.capabilities.Endpoint.Admin
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          port_name:
+            type: string
+            required: false
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          secure:
+            type: boolean
+            default: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          url_path:
+            type: string
+            required: false
+      59a2ee3f-b580-45fe-b5a1 1.attachment:
+        type: tosca.capabilities.Attachment
+        occurrences:
+        - 1
+        - UNBOUNDED
+      59a2ee3f-b580-45fe-b5a1 1.feature:
+        type: tosca.capabilities.Node
+        occurrences:
+        - 1
+        - UNBOUNDED
+      59a2ee3f-b580-45fe-b5a1 1.binding:
+        type: tosca.capabilities.network.Bindable
+        occurrences:
+        - 0
+        - UNBOUNDED
+      59a2ee3f-b580-45fe-b5a1 1.vcpus:
+        type: org.onap.capabilities.metric.Ceilometer
+        description: Average disk latency
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          description:
+            type: string
+            description: Description of the metric
+            required: false
+          type:
+            type: string
+            default: Gauge
+            description: Type of the metric value, for an example, Cumulative, Delta, Gauge and etc.
+            required: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          secure:
+            type: boolean
+            default: false
+          port_name:
+            type: string
+            required: false
+          unit:
+            type: string
+            default: ms
+            description: Unit of the metric value
+            required: true
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          name:
+            type: string
+            default: vcpus
+            description: Ceilometer metric type name to monitor. (The name ceilometer is using)
+            required: true
+          category:
+            type: string
+            default: compute
+            description: Category of the metric, for an example, compute, disk, network, storage and etc.
+            required: false
+          url_path:
+            type: string
+            required: false
+      59a2ee3f-b580-45fe-b5a1 1.host:
+        type: tosca.capabilities.Container
+        occurrences:
+        - 1
+        - UNBOUNDED
+        valid_source_types:
+        - tosca.nodes.SoftwareComponent
+        properties:
+          num_cpus:
+            type: integer
+            required: false
+          disk_size:
+            type: scalar-unit.size
+            required: false
+          cpu_frequency:
+            type: scalar-unit.frequency
+            required: false
+          mem_size:
+            type: scalar-unit.size
+            required: false
+      59a2ee3f-b580-45fe-b5a1 1.memory.usage:
+        type: org.onap.capabilities.metric.Ceilometer
+        description: Volume of RAM used by the instance from the amount of its allocated memory
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          description:
+            type: string
+            description: Description of the metric
+            required: false
+          type:
+            type: string
+            default: Gauge
+            description: Type of the metric value, for an example, Cumulative, Delta, Gauge and etc.
+            required: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          secure:
+            type: boolean
+            default: false
+          port_name:
+            type: string
+            required: false
+          unit:
+            type: string
+            default: MB
+            description: Unit of the metric value
+            required: true
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          name:
+            type: string
+            default: memory.usage
+            description: Ceilometer metric type name to monitor. (The name ceilometer is using)
+            required: true
+          category:
+            type: string
+            default: compute
+            description: Category of the metric, for an example, compute, disk, network, storage and etc.
+            required: false
+          url_path:
+            type: string
+            required: false
+      59a2ee3f-b580-45fe-b5a1 1.instance:
+        type: org.onap.capabilities.metric.Ceilometer
+        description: Existence of instance
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          description:
+            type: string
+            description: Description of the metric
+            required: false
+          type:
+            type: string
+            default: Gauge
+            description: Type of the metric value, for an example, Cumulative, Delta, Gauge and etc.
+            required: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          secure:
+            type: boolean
+            default: false
+          port_name:
+            type: string
+            required: false
+          unit:
+            type: string
+            default: instance
+            description: Unit of the metric value
+            required: true
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          name:
+            type: string
+            default: instance
+            description: Ceilometer metric type name to monitor. (The name ceilometer is using)
+            required: true
+          category:
+            type: string
+            default: compute
+            description: Category of the metric, for an example, compute, disk, network, storage and etc.
+            required: false
+          url_path:
+            type: string
+            required: false
+      59a2ee3f-b580-45fe-b5a1 1.scalable:
+        type: tosca.capabilities.Scalable
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          max_instances:
+            type: integer
+            default: 1
+          min_instances:
+            type: integer
+            default: 1
+          default_instances:
+            type: integer
+      59a2ee3f-b580-45fe-b5a1 1.cpu_util:
+        type: org.onap.capabilities.metric.Ceilometer
+        description: Average CPU utilization
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          description:
+            type: string
+            description: Description of the metric
+            required: false
+          type:
+            type: string
+            default: Gauge
+            description: Type of the metric value, for an example, Cumulative, Delta, Gauge and etc.
+            required: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          secure:
+            type: boolean
+            default: false
+          port_name:
+            type: string
+            required: false
+          unit:
+            type: string
+            default: '%'
+            description: Unit of the metric value
+            required: true
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          name:
+            type: string
+            default: cpu_util
+            description: Ceilometer metric type name to monitor. (The name ceilometer is using)
+            required: true
+          category:
+            type: string
+            default: compute
+            description: Category of the metric, for an example, compute, disk, network, storage and etc.
+            required: false
+          url_path:
+            type: string
+            required: false
+      59a2ee3f-b580-45fe-b5a1 1.instance:type:
+        type: org.onap.capabilities.metric.Ceilometer
+        description: Existence of instance <type> (OpenStack types)
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          description:
+            type: string
+            description: Description of the metric
+            required: false
+          type:
+            type: string
+            default: Gauge
+            description: Type of the metric value, for an example, Cumulative, Delta, Gauge and etc.
+            required: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          secure:
+            type: boolean
+            default: false
+          port_name:
+            type: string
+            required: false
+          unit:
+            type: string
+            default: instance
+            description: Unit of the metric value
+            required: true
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          name:
+            type: string
+            default: instance:type
+            description: Ceilometer metric type name to monitor. (The name ceilometer is using)
+            required: true
+          category:
+            type: string
+            default: compute
+            description: Category of the metric, for an example, compute, disk, network, storage and etc.
+            required: false
+          url_path:
+            type: string
+            required: false
+      59a2ee3f-b580-45fe-b5a1 1.cpu.delta:
+        type: org.onap.capabilities.metric.Ceilometer
+        description: CPU time used since previous datapoint
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          description:
+            type: string
+            description: Description of the metric
+            required: false
+          type:
+            type: string
+            default: Delta
+            description: Type of the metric value, for an example, Cumulative, Delta, Gauge and etc.
+            required: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          secure:
+            type: boolean
+            default: false
+          port_name:
+            type: string
+            required: false
+          unit:
+            type: string
+            default: ns
+            description: Unit of the metric value
+            required: true
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          name:
+            type: string
+            default: cpu.delta
+            description: Ceilometer metric type name to monitor. (The name ceilometer is using)
+            required: true
+          category:
+            type: string
+            default: compute
+            description: Category of the metric, for an example, compute, disk, network, storage and etc.
+            required: false
+          url_path:
+            type: string
+            required: false
+      59a2ee3f-b580-45fe-b5a1 1.memory:
+        type: org.onap.capabilities.metric.Ceilometer
+        description: Volume of RAM allocated to the instance
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          description:
+            type: string
+            description: Description of the metric
+            required: false
+          type:
+            type: string
+            default: Gauge
+            description: Type of the metric value, for an example, Cumulative, Delta, Gauge and etc.
+            required: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          secure:
+            type: boolean
+            default: false
+          port_name:
+            type: string
+            required: false
+          unit:
+            type: string
+            default: MB
+            description: Unit of the metric value
+            required: true
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          name:
+            type: string
+            default: memory
+            description: Ceilometer metric type name to monitor. (The name ceilometer is using)
+            required: true
+          category:
+            type: string
+            default: compute
+            description: Category of the metric, for an example, compute, disk, network, storage and etc.
+            required: false
+          url_path:
+            type: string
+            required: false
+      59a2ee3f-b580-45fe-b5a1 1.link:
+        type: tosca.capabilities.network.Linkable
+        occurrences:
+        - 0
+        - UNBOUNDED
+      59a2ee3f-b580-45fe-b5a1 1.cpu:
+        type: org.onap.capabilities.metric.Ceilometer
+        description: CPU time used
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          initiator:
+            type: string
+            default: source
+          network_name:
+            type: string
+            default: PRIVATE
+            required: false
+          description:
+            type: string
+            description: Description of the metric
+            required: false
+          type:
+            type: string
+            default: Cumulative
+            description: Type of the metric value, for an example, Cumulative, Delta, Gauge and etc.
+            required: true
+          ports:
+            type: map
+            required: false
+            entry_schema:
+              type: PortSpec
+          secure:
+            type: boolean
+            default: false
+          port_name:
+            type: string
+            required: false
+          unit:
+            type: string
+            default: ns
+            description: Unit of the metric value
+            required: true
+          protocol:
+            type: string
+            default: tcp
+          port:
+            type: PortDef
+            required: false
+          name:
+            type: string
+            default: cpu
+            description: Ceilometer metric type name to monitor. (The name ceilometer is using)
+            required: true
+          category:
+            type: string
+            default: compute
+            description: Category of the metric, for an example, compute, disk, network, storage and etc.
+            required: false
+          url_path:
+            type: string
+            required: false
+      59a2ee3f-b580-45fe-b5a1 1.os:
+        type: tosca.capabilities.OperatingSystem
+        occurrences:
+        - 1
+        - UNBOUNDED
+        properties:
+          distribution:
+            type: string
+            required: false
+          type:
+            type: string
+            required: false
+          version:
+            type: version
+            required: false
+          architecture:
+            type: string
+            required: false
+    requirements:
+      59a2ee3f-b580-45fe-b5a1 1.local_storage:
+        occurrences:
+        - 0
+        - UNBOUNDED
+        capability: tosca.capabilities.Attachment
+        node: tosca.nodes.BlockStorage
+        relationship: tosca.relationships.AttachesTo
+      59a2ee3f-b580-45fe-b5a1 1.dependency:
+        occurrences:
+        - 0
+        - UNBOUNDED
+        capability: tosca.capabilities.Node
+        node: tosca.nodes.Root
+        relationship: tosca.relationships.DependsOn
+      59a2ee3f-b580-45fe-b5a1 1.link:
+        occurrences:
+        - 1
+        - 1
+        capability: tosca.capabilities.network.Linkable
+        relationship: tosca.relationships.network.LinksTo
diff --git a/ONAP-ControlloopPolicy/src/test/resources/v2.0.0/pgstreams.json b/ONAP-ControlloopPolicy/src/test/resources/v2.0.0/pgstreams.json
new file mode 100644
index 0000000..4d118af
--- /dev/null
+++ b/ONAP-ControlloopPolicy/src/test/resources/v2.0.0/pgstreams.json
@@ -0,0 +1,26 @@
+{
+    "pg-streams": {
+      "pg-stream": [
+        {
+          "id": "fw_udp1",
+          "is-enabled": "true"
+        },
+        {
+          "id": "fw_udp2",
+          "is-enabled": "true"
+        },
+        {
+          "id": "fw_udp3",
+          "is-enabled": "true"
+        },
+        {
+          "id": "fw_udp4",
+          "is-enabled": "true"
+        },
+        {
+          "id": "fw_udp5",
+          "is-enabled": "true"
+        }
+      ]
+    }
+}
\ No newline at end of file
diff --git a/ONAP-ControlloopPolicy/src/test/resources/v2.0.0/policy_ONAP_demo_vDNS.yaml b/ONAP-ControlloopPolicy/src/test/resources/v2.0.0/policy_ONAP_demo_vDNS.yaml
new file mode 100644
index 0000000..5deb8f7
--- /dev/null
+++ b/ONAP-ControlloopPolicy/src/test/resources/v2.0.0/policy_ONAP_demo_vDNS.yaml
@@ -0,0 +1,47 @@
+controlLoop:
+  version: 2.0.0
+  controlLoopName: ControlLoop-vDNS-6f37f56d-a87d-4b85-b6a9-cc953cf779b3
+  services: 
+    - serviceName: d4738992-6497-4dca-9db9
+      serviceInvariantUUID: dc112d6e-7e73-4777-9c6f-1a7fb5fd1b6f
+      serviceUUID: 2eea06c6-e1d3-4c3a-b9c4-478c506eeedf
+#
+# OPTIONAL to specify the exact resource VF and/or VFC(s)
+#
+#  resources:
+#    - resourceInvariantUUID: 4b8d4018-068b-4c33-b9bb-d980798e52c2
+#      resourceUUID: d7d28881-b24d-4512-bfee-1e2eb335591f
+#      resourceVersion: '1.0'
+#      resourceName: 59a2ee3f-b580-45fe-b5a1
+#      resourceType: VF
+#    
+#  resources: 
+#    - resourceInvariantUUID: ee585c30-127b-492e-b2c1-871dc61d1dde
+#      resourceUUID: d816cb01-b5d0-4bbb-b614-f7c3e230ab19
+#      resourceVersion: '1.0'
+#      resourceName: 59a2ee3fB58045feB5a1.nodes.heat.vdns
+#      resourceType: VFC
+#    - resourceInvariantUUID: f7f1d745-cfb1-4aa9-83fc-31280d0ce513
+#      resourceUUID: 1821f13e-411f-4b29-87a5-ae935897b2e1
+#      resourceVersion: '1.0'
+#      resourceName: 59a2ee3fB58045feB5a1.nodes.heat.vlb
+#      resourceType: VFC
+  trigger_policy: unique-policy-id-1-scale-up
+  timeout: 1200
+
+policies:
+  - id: unique-policy-id-1-scale-up
+    name: Create a new VF Module
+    description:
+    actor: MSO
+    recipe: VF Module Create
+    target:
+      resourceID: 59a2ee3fB58045feB5a1.nodes.heat.vdns
+    retry: 0
+    timeout: 1200
+    success: final_success
+    failure: final_failure
+    failure_timeout: final_failure_timeout
+    failure_retries: final_failure_retries
+    failure_exception: final_failure_exception
+    failure_guard: final_failure_guard
diff --git a/ONAP-ControlloopPolicy/src/test/resources/v2.0.0/policy_ONAP_demo_vFirewall.yaml b/ONAP-ControlloopPolicy/src/test/resources/v2.0.0/policy_ONAP_demo_vFirewall.yaml
new file mode 100644
index 0000000..5159771
--- /dev/null
+++ b/ONAP-ControlloopPolicy/src/test/resources/v2.0.0/policy_ONAP_demo_vFirewall.yaml
@@ -0,0 +1,58 @@
+controlLoop:
+  version: 2.0.0
+  controlLoopName: ControlLoop-vFirewall-d0a1dfc6-94f5-4fd4-a5b5-4630b438850a
+  services: 
+    - serviceInvariantUUID: 5cfe6f4a-41bc-4247-8674-ebd4b98e35cc
+      serviceUUID: 0f40bba5-986e-4b3c-803f-ddd1b7b25f24
+      serviceName: 57e66ea7-0ed6-45c7-970f
+#
+# OPTIONAL
+#
+# IF they want this CL restricted to a particular VFC(s)
+#
+#resources:
+#   -  resourceInvariantUUID: 06fe411e-d006-4ac3-8b0e-fb4f13cd78d3
+#      resourceUUID: 172ce7c5-c2e4-4f8d-b66c-edb49e8e548a
+#      resourceVersion: '1.0'
+#      resourceName: eace9331-04d4-43b4-96b8
+#      resourceType: VF
+   
+#  resources: 
+#    - resourceType: VFC
+#      resourceInvariantUUID: b19f6643-3db0-4d73-b280-94d6f21caa71
+#      resourceUUID: 6dca6eb9-330c-4090-a542-7aca5f446e21
+#      resourceVersion: '1.0'
+#      resourceName: Eace933104d443b496b8.nodes.heat.vsn
+#    - resourceName: vFW
+#      resourceType: VFC
+#      resourceInvariantUUID: 0129e34c-d9fa-442d-bb2c-f925d018000a
+#      resourceUUID: 7fa1f6c7-c6bd-4444-8db2-63334a5aed1b
+#      resourceVersion: '1.0'
+#      resourceName: Eace933104d443b496b8.nodes.heat.vfw
+#    - resourceType: VFC
+#      resourceInvariantUUID: 7654ae14-4e98-45bc-a8c0-2c43e1805bb4
+#      resourceUUID: 5267d6dd-f676-4f98-abec-6387ce6beaf2
+#      resourceVersion: '1.0'
+#      resourceName: Eace933104d443b496b8.nodes.heat.vpg
+  trigger_policy: unique-policy-id-1-modifyConfig
+  timeout: 1200
+
+policies:
+  - id: unique-policy-id-1-modifyConfig
+    name: Change the Load Balancer
+    description:
+    actor: APPC
+    recipe: ModifyConfig
+    target:
+      resourceID: Eace933104d443b496b8.nodes.heat.vpg
+    payload:
+      generic-vnf.vnf-id: {generic-vnf.vnf-id}
+      ref$: pgstreams.json
+    retry: 0
+    timeout: 300
+    success: final_success
+    failure: final_failure
+    failure_timeout: final_failure_timeout
+    failure_retries: final_failure_retries
+    failure_exception: final_failure_exception
+    failure_guard: final_failure_guard