Add support for ScaleOut

Support Scaleout in Clamp UI + rework the Backend to support more
configurable fields of operational policy.

Issue-ID: CLAMP-201
Change-Id: I87dceeecfb4145bf4a0357daefd279729609e21d
Signed-off-by: Determe, Sebastien (sd378r) <sd378r@intl.att.com>
diff --git a/src/main/java/org/onap/clamp/clds/client/req/policy/OperationalPolicyReq.java b/src/main/java/org/onap/clamp/clds/client/req/policy/OperationalPolicyReq.java
index 2ebab88..f062dfc 100644
--- a/src/main/java/org/onap/clamp/clds/client/req/policy/OperationalPolicyReq.java
+++ b/src/main/java/org/onap/clamp/clds/client/req/policy/OperationalPolicyReq.java
@@ -19,7 +19,7 @@
  * ============LICENSE_END============================================
  * Modifications copyright (c) 2018 Nokia
  * ===================================================================
- * 
+ *
  */
 
 package org.onap.clamp.clds.client.req.policy;
@@ -77,7 +77,7 @@
      * @throws UnsupportedEncodingException
      */
     public static Map<AttributeType, Map<String, String>> formatAttributes(ClampProperties refProp,
-            ModelProperties prop, String modelElementId, PolicyChain policyChain)
+        ModelProperties prop, String modelElementId, PolicyChain policyChain)
             throws BuilderException, UnsupportedEncodingException {
         Global global = prop.getGlobal();
         prop.setCurrentModelElementId(modelElementId);
@@ -130,7 +130,7 @@
 
     /**
      * Format Operational OpenLoop Policy yaml.
-     * 
+     *
      * @param refProp
      * @param prop
      * @param modelElementId
@@ -140,7 +140,7 @@
      * @throws UnsupportedEncodingException
      */
     protected static String formatOpenLoopYaml(ClampProperties refProp, ModelProperties prop, String modelElementId,
-            PolicyChain policyChain) throws BuilderException, UnsupportedEncodingException {
+        PolicyChain policyChain) throws BuilderException, UnsupportedEncodingException {
         // get property objects
         Global global = prop.getGlobal();
         prop.setCurrentModelElementId(modelElementId);
@@ -150,7 +150,7 @@
         Resource[] vfResources = convertToResource(global.getResourceVf(), ResourceType.VF);
         // create builder
         ControlLoopPolicyBuilder builder = ControlLoopPolicyBuilder.Factory.buildControlLoop(prop.getControlName(),
-                policyChain.getTimeout(), service, vfResources);
+            policyChain.getTimeout(), service, vfResources);
         // builder.setTriggerPolicy(refProp.getStringValue("op.openloop.policy"));
         // Build the specification
         Results results = builder.buildSpecification();
@@ -170,7 +170,7 @@
      * @throws UnsupportedEncodingException
      */
     protected static String formatYaml(ClampProperties refProp, ModelProperties prop, String modelElementId,
-            PolicyChain policyChain) throws BuilderException, UnsupportedEncodingException {
+        PolicyChain policyChain) throws BuilderException, UnsupportedEncodingException {
         // get property objects
         Global global = prop.getGlobal();
         prop.setCurrentModelElementId(modelElementId);
@@ -181,7 +181,7 @@
         Resource[] vfcResources = convertToResource(global.getResourceVfc(), ResourceType.VFC);
         // create builder
         ControlLoopPolicyBuilder builder = ControlLoopPolicyBuilder.Factory.buildControlLoop(prop.getControlName(),
-                policyChain.getTimeout(), service, vfResources);
+            policyChain.getTimeout(), service, vfResources);
         builder.addResource(vfcResources);
         // process each policy
         Map<String, Policy> policyObjMap = new HashMap<>();
@@ -195,31 +195,21 @@
                 target.setType(TargetType.valueOf(policyItem.getRecipeLevel()));
             }
             target.setResourceID(policyItem.getTargetResourceId());
-            String actor = refProp.getStringValue("op.policy.appc");
-            Map<String, String> payloadMap = null;
-            if ("health-diagnostic".equalsIgnoreCase(policyItem.getRecipe())) {
-                actor = refProp.getStringValue("op.policy.sdno");
-                payloadMap = new HashMap<String, String>();
-                payloadMap.put("ttl", policyItem.getRecipePayload());
-            }
-            // For reboot recipe we have to send type as SOFT/HARD in pay load
-            if (policyItem.getRecipeInfo() != null && !policyItem.getRecipeInfo().isEmpty()) {
-                payloadMap = new HashMap<String, String>();
-                payloadMap.put("type", policyItem.getRecipeInfo());
-            }
+            String actor = policyItem.getActor();
+            Map<String, String> payloadMap = policyItem.getRecipePayload();
             Policy policyObj;
             if (policyItemList.indexOf(policyItem) == 0) {
                 String policyDescription = policyItem.getRecipe()
-                        + " Policy - the trigger (no parent) policy - created by CLDS";
+                    + " Policy - the trigger (no parent) policy - created by CLDS";
                 policyObj = builder.setTriggerPolicy(policyName, policyDescription, actor, target,
-                        policyItem.getRecipe(), payloadMap, policyItem.getMaxRetries(), policyItem.getRetryTimeLimit());
+                    policyItem.getRecipe(), payloadMap, policyItem.getMaxRetries(), policyItem.getRetryTimeLimit());
             } else {
                 Policy parentPolicyObj = policyObjMap.get(policyItem.getParentPolicy());
                 String policyDescription = policyItem.getRecipe() + " Policy - triggered conditionally by "
-                        + parentPolicyObj.getName() + " - created by CLDS";
+                    + parentPolicyObj.getName() + " - created by CLDS";
                 policyObj = builder.setPolicyForPolicyResult(policyName, policyDescription, actor, target,
-                        policyItem.getRecipe(), payloadMap, policyItem.getMaxRetries(), policyItem.getRetryTimeLimit(),
-                        parentPolicyObj.getId(), convertToPolicyResult(policyItem.getParentPolicyConditions()));
+                    policyItem.getRecipe(), payloadMap, policyItem.getMaxRetries(), policyItem.getRetryTimeLimit(),
+                    parentPolicyObj.getId(), convertToPolicyResult(policyItem.getParentPolicyConditions()));
                 logger.info("policyObj.id=" + policyObj.getId() + "; parentPolicyObj.id=" + parentPolicyObj.getId());
             }
             policyObjMap.put(policyItem.getId(), policyObj);
@@ -274,7 +264,7 @@
                 if (parent == null || parent.length() == 0) {
                     if (!outList.isEmpty()) {
                         throw new BadRequestException(
-                                "Operation Policy validation problem: more than one trigger policy");
+                            "Operation Policy validation problem: more than one trigger policy");
                     } else {
                         outList.add(inItem);
                         inListItr.remove();
diff --git a/src/main/java/org/onap/clamp/clds/model/properties/Policy.java b/src/main/java/org/onap/clamp/clds/model/properties/Policy.java
index 2ae0f07..501eb80 100644
--- a/src/main/java/org/onap/clamp/clds/model/properties/Policy.java
+++ b/src/main/java/org/onap/clamp/clds/model/properties/Policy.java
@@ -18,7 +18,7 @@
  * limitations under the License.
  * ============LICENSE_END============================================
  * ===================================================================
- * 
+ *
  */
 
 package org.onap.clamp.clds.model.properties;
@@ -27,6 +27,7 @@
 import com.att.eelf.configuration.EELFManager;
 import com.fasterxml.jackson.databind.JsonNode;
 
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
@@ -62,8 +63,9 @@
      * @param modelProp
      * @param modelBpmn
      * @param modelJson
+     * @throws IOException
      */
-    public Policy(ModelProperties modelProp, ModelBpmn modelBpmn, JsonNode modelJson) {
+    public Policy(ModelProperties modelProp, ModelBpmn modelBpmn, JsonNode modelJson) throws IOException {
         super(TYPE_POLICY, modelProp, modelBpmn, modelJson);
 
         // process policies
diff --git a/src/main/java/org/onap/clamp/clds/model/properties/PolicyChain.java b/src/main/java/org/onap/clamp/clds/model/properties/PolicyChain.java
index 96fc33c..cf24c78 100644
--- a/src/main/java/org/onap/clamp/clds/model/properties/PolicyChain.java
+++ b/src/main/java/org/onap/clamp/clds/model/properties/PolicyChain.java
@@ -18,7 +18,7 @@
  * limitations under the License.
  * ============LICENSE_END============================================
  * ===================================================================
- * 
+ *
  */
 
 package org.onap.clamp.clds.model.properties;
@@ -27,6 +27,7 @@
 import com.att.eelf.configuration.EELFManager;
 import com.fasterxml.jackson.databind.JsonNode;
 
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
@@ -65,23 +66,23 @@
     private List<PolicyItem>          policyItems;
     private String                    policyType;
 
-    public PolicyChain(JsonNode node) {
+    public PolicyChain(JsonNode node) throws IOException {
 
         policyId = AbstractModelElement.getValueByName(node, "pid");
         timeout = AbstractModelElement.getIntValueByName(node, "timeout");
         policyType = AbstractModelElement.getValueByName(node, "policyType");
-    
-        if(node != null && node.size() > 0) {    	   	
-	        JsonNode policyNode = node.get(node.size() - 1).get("policyConfigurations");
-	        if(policyNode != null) {
-		        Iterator<JsonNode> itr = policyNode.elements();
-		        policyItems = new ArrayList<>();
-		        while (itr.hasNext()) {
-		            policyItems.add(new PolicyItem(itr.next()));
-		        }
-	    
-	         } 
-	      }  
+
+        if(node != null && node.size() > 0) {
+            JsonNode policyNode = node.get(node.size() - 1).get("policyConfigurations");
+            if(policyNode != null) {
+                Iterator<JsonNode> itr = policyNode.elements();
+                policyItems = new ArrayList<>();
+                while (itr.hasNext()) {
+                    policyItems.add(new PolicyItem(itr.next()));
+                }
+
+            }
+        }
     }
     /**
      * @return the policyId
@@ -103,7 +104,7 @@
     public List<PolicyItem> getPolicyItems() {
         return policyItems;
     }
-    
+
     /**
      * @return the policyType
      */
diff --git a/src/main/java/org/onap/clamp/clds/model/properties/PolicyItem.java b/src/main/java/org/onap/clamp/clds/model/properties/PolicyItem.java
index 75bf6ae..6e3e865 100644
--- a/src/main/java/org/onap/clamp/clds/model/properties/PolicyItem.java
+++ b/src/main/java/org/onap/clamp/clds/model/properties/PolicyItem.java
@@ -18,16 +18,21 @@
  * limitations under the License.
  * ============LICENSE_END============================================
  * ===================================================================
- * 
+ *
  */
 
 package org.onap.clamp.clds.model.properties;
 
 import com.att.eelf.configuration.EELFLogger;
 import com.att.eelf.configuration.EELFManager;
+import com.fasterxml.jackson.core.type.TypeReference;
 import com.fasterxml.jackson.databind.JsonNode;
 
+import java.io.IOException;
 import java.util.List;
+import java.util.Map;
+
+import org.onap.clamp.clds.util.JacksonUtils;
 
 /**
  * Parse policyConfigurations from Policy json properties.
@@ -61,7 +66,7 @@
     private String targetResourceId;
     private String recipeInfo;
     private String recipeLevel;
-    private String recipePayload;
+    private Map<String, String> recipePayload;
     private String oapRop;
     private String oapLimit;
 
@@ -69,8 +74,9 @@
      * Parse Policy given json node.
      *
      * @param node
+     * @throws IOException
      */
-    public PolicyItem(JsonNode node) {
+    public PolicyItem(JsonNode node) throws  IOException {
         id = AbstractModelElement.getValueByName(node, "_id");
         recipe = AbstractModelElement.getValueByName(node, "recipe");
         maxRetries = AbstractModelElement.getIntValueByName(node, "maxRetries");
@@ -83,9 +89,16 @@
         }
         recipeInfo = AbstractModelElement.getValueByName(node, "recipeInfo");
         recipeLevel = AbstractModelElement.getValueByName(node, "recipeLevel");
-        recipePayload = AbstractModelElement.getValueByName(node, "recipeInput");
+        String payload = AbstractModelElement.getValueByName(node, "recipeInput");
+
+
+        if (payload != null && !payload.isEmpty()) {
+            //recipePayload = JacksonUtils.getObjectMapperInstance().convertValue(payload, Map.class);
+            recipePayload = JacksonUtils.getObjectMapperInstance().readValue(payload, new TypeReference<Map<String, String>>(){});
+        }
         oapRop = AbstractModelElement.getValueByName(node, "oapRop");
         oapLimit = AbstractModelElement.getValueByName(node, "oapLimit");
+        actor = AbstractModelElement.getValueByName(node, "actor");
     }
 
     /**
@@ -202,7 +215,7 @@
         return recipeLevel;
     }
 
-    public String getRecipePayload() {
+    public Map<String, String> getRecipePayload() {
         return recipePayload;
     }
 
@@ -219,9 +232,4 @@
         }
         return oapLimit;
     }
-
-    @Override
-    public Object clone() throws CloneNotSupportedException {
-        return super.clone();
-    }
 }
diff --git a/src/main/resources/META-INF/resources/designer/partials/portfolios/PolicyWindow_properties.html b/src/main/resources/META-INF/resources/designer/partials/portfolios/PolicyWindow_properties.html
index 3a894c2..5109c1b 100644
--- a/src/main/resources/META-INF/resources/designer/partials/portfolios/PolicyWindow_properties.html
+++ b/src/main/resources/META-INF/resources/designer/partials/portfolios/PolicyWindow_properties.html
@@ -178,42 +178,55 @@
 
 			<div class="leftPolicyPanel">
 				<div class="panel panel-default">
-				<i class="glyphicon glyphicon-search modelSearchBox"></i>
-				<input type="text" id="policySearch" onkeyup="searchPolicyList()"
+					<i class="glyphicon glyphicon-search modelSearchBox"></i> <input
+						type="text" id="policySearch" onkeyup="searchPolicyList()"
 						placeholder="Search ...">
 					<div id="policyTableHolder">
 						<table id="policyTable"></table>
 					</div>
 				</div>
 				<div style="float: left">
-				<button type="button" id="createNewPolicy" class="btn btn-sm">New Policy</button></span>
+					<button type="button" id="createNewPolicy" class="btn btn-sm">New
+						Policy</button>
+					</span>
 				</div>
 				<div style="float: right">
-				<button type="button" id="deletePolicy" class="btn btn-sm glyphicon glyphicon-trash" disabled></button></span>
+					<button type="button" id="deletePolicy"
+						class="btn btn-sm glyphicon glyphicon-trash" disabled></button>
+					</span>
 				</div>
-			<div id="repeatIdError" class="idError">Error: This Policy name is already taken.</div>
-			<div id="newIdError" class="idError">Error: Please rename your new Policy.</div>
-			<div id="spaceError" class="idError">Error: Spaces are not allowed in the ID.</div>
+				<div id="repeatIdError" class="idError">Error: This Policy
+					name is already taken.</div>
+				<div id="newIdError" class="idError">Error: Please rename your
+					new Policy.</div>
+				<div id="spaceError" class="idError">Error: Spaces are not
+					allowed in the ID.</div>
 			</div>
 
-		<div class="panel panel-default col-sm-9 policyPanel" style="display:none;">
+			<div class="panel panel-default col-sm-9 policyPanel"
+				style="display: none;">
 				<form id="Timeoutform" class="form-horizontal">
 					<div>
 						<div class="form-group clearfix row">
 							<label class="col-sm-2">Name</label>
 							<div class="col-sm-3" style="padding: 0px;">
-							<input type="text" id="pname" name="pname" maxlength="48" placeholder="Enter Unique Name" class="form-control">
+								<input type="text" id="pname" name="pname" maxlength="48"
+									placeholder="Enter Unique Name" class="form-control">
 							</div>
 
 							<label class="col-sm-1">ID</label>
 							<div class="col-sm-1" style="padding: 0px;">
-							<input onkeydown="return false;" type="text" id="pid" name="pid" class="form-control" readonly>
+								<input onkeydown="return false;" type="text" id="pid" name="pid"
+									class="form-control" readonly>
 							</div>
 
-						<label for="userID" class="col-sm-3" style="padding-left:5px;padding-right:10px;">Overall Time Limit</label>
+							<label for="userID" class="col-sm-3"
+								style="padding-left: 5px; padding-right: 10px;">Overall
+								Time Limit</label>
 							<div class="col-sm-2" style="padding-left: 0px;">
-							<input type="text" maxlength="10" onkeypress="return isNumberKey(event)"
-								class="form-control" id="timeout" name="timeout">
+								<input type="text" maxlength="10"
+									onkeypress="return isNumberKey(event)" class="form-control"
+									id="timeout" name="timeout">
 							</div>
 						</div>
 					</div>
@@ -237,15 +250,16 @@
 						<div class="form-group clearfix">
 							<label class="col-sm-4 control-label" for="recipe">Recipe</label>
 							<div class="col-sm-8">
-							<select class="form-control" name="recipe" id="recipe" enableFilter="true"></select>
+								<select class="form-control" name="recipe" id="recipe"
+									enableFilter="true"></select>
 							</div>
 						</div>
 						<div class="form-group clearfix">
 							<label for="maxRetries" class="col-sm-4 control-label">
 								Max Retries</label>
 							<div class="col-sm-8">
-							<input type="text" maxlength="5" class="form-control" id="maxRetries"
-								onkeypress="return isNumberKey(event)"
+								<input type="text" maxlength="5" class="form-control"
+									id="maxRetries" onkeypress="return isNumberKey(event)"
 									name="maxRetries"> </input>
 							</div>
 						</div>
@@ -253,17 +267,16 @@
 							<label for="retryTimeLimit" class="col-sm-4 control-label">
 								Retry Time Limit</label>
 							<div class="col-sm-8">
-							<input type="text" maxlength="5" class="form-control" id="retryTimeLimit"
-								onkeypress="return isNumberKey(event)"
+								<input type="text" maxlength="5" class="form-control"
+									id="retryTimeLimit" onkeypress="return isNumberKey(event)"
 									name="retryTimeLimit"></input>
 							</div>
 						</div>
 						<div style="display: none;" class="form-group clearfix">
-						<label for="_id" class="col-sm-4 control-label">
-							PolicyID</label>
+							<label for="_id" class="col-sm-4 control-label"> PolicyID</label>
 							<div class="col-sm-8">
-							<input type="text" onkeydown="return false;"  class="form-control" id="_id"
-								name="_id" value=""></input>
+								<input type="text" onkeydown="return false;"
+									class="form-control" id="_id" name="_id" value=""></input>
 							</div>
 						</div>
 						<div class="form-group clearfix">
@@ -271,28 +284,52 @@
 								Parent Policy</label>
 							<div class="col-sm-8">
 								<select class="form-control" id="parentPolicy"
-								name="parentPolicy" enableFilter="true"><option value=""></option></select>
+									name="parentPolicy" enableFilter="true"><option
+										value=""></option></select>
 							</div>
 						</div>
 						<div class="form-group clearfix">
-						<label for="parentPolicyConditions" class="col-sm-4 control-label">
-							Parent Policy Conditions</label>
+							<label for="parentPolicyConditions"
+								class="col-sm-4 control-label"> Parent Policy Conditions</label>
 							<div class="col-sm-8">
 								<select class="form-control" id="parentPolicyConditions"
 									name="parentPolicyConditions" multiple></select>
 							</div>
 						</div>
 						<div class="form-group clearfix">
+
+							<label for="actor" class="col-sm-4 control-label"> Actor</label>
+							<div class="col-sm-8">
+								<select class="form-control" id="actor" name="actor"></select>
+							</div>
+
+							<label for="payload" class="col-sm-4 control-label">
+								Payload</label>
+							<div class="col-sm-8">
+								<textarea class="form-control" id="recipeInput"
+									name=recipeInput></textarea >
+							</div>
+						</div>
+						<div class="form-group clearfix">
+							<label for="targetType" class="col-sm-4 control-label">
+								Target Type</label>
+							<div class="col-sm-8">
+								<select class="form-control" name="recipeLevel" id="recipeLevel">
+								</select>
+							</div>
+
 							<label for="targetResourceId" class="col-sm-4 control-label">
 								Target ResourceId</label>
 							<div class="col-sm-8">
-								<select class="form-control" name="targetResourceId" id="targetResourceId" enableFilter="true" onchange="changeTargetResourceIdOther();" >
+								<select class="form-control" name="targetResourceId"
+									id="targetResourceId" enableFilter="true"
+									onchange="changeTargetResourceIdOther();">
 									<option value=""></option>
 									<option value="Other:">Other:</option>
 								</select>
 							</div>
-							<input type="text" style="display:none" class="form-control" id="targetResourceIdOther"
-								name="targetResourceIdOther" value=""></input>
+							<input type="text" style="display: none" class="form-control"
+								id="targetResourceIdOther" name="targetResourceIdOther" value=""></input>
 						</div>
 					</div>
 				</form>
diff --git a/src/main/resources/clds/templates/globalProperties.json b/src/main/resources/clds/templates/globalProperties.json
index e677abe..880b992 100644
--- a/src/main/resources/clds/templates/globalProperties.json
+++ b/src/main/resources/clds/templates/globalProperties.json
@@ -47,6 +47,11 @@
 	"policy": {
 		"pname": "0",
 		"timeout": 345,
+		"actor": {
+			"APPC":"APPC",
+			"MSO": "SO",
+			"VFC": "VFC"
+		},
 		"vnfRecipe": {
 			"": "",
 			"restart": "Restart",
@@ -54,20 +59,18 @@
 			"migrate": "Migrate",
 			"healthCheck": "Health Check",
 			"modifyConfig": "ModifyConfig",
-			"vfModuleCreate":"VF Module Create"
+			"vfModuleCreate":"VF Module Create",
+			"scaleOut":"Scale Out"
 		},
 		"maxRetries": "3",
-		"retryTimeLimit": 180,
-		"resource": {
-			"vCTS": "vCTS",
-			"v3CDB": "v3CDB",
-			"vUDR": "vUDR",
-			"vCOM": "vCOM",
-			"vRAR": "vRAR",
-			"vLCS": "vLCS",
-			"vUDR-BE": "vUDR-BE",
-			"vDBE": "vDBE"
+		"recipeLevel": {
+			"":"",
+			"VNF":"VNF",
+			"VM":"VM",
+			"VFC":"VFC",
+			"PNF":"PNF"
 		},
+		"retryTimeLimit": 180,
 		"parentPolicyConditions": {
 			"Failure_Retries": "Failure: Max Retries Exceeded",
 			"Failure_Timeout": "Failure: Time Limit Exceeded",