Merge "New Optimization Policy"
diff --git a/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/DictionaryNames.java b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/DictionaryNames.java
index 3735316..38e2c96 100644
--- a/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/DictionaryNames.java
+++ b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/DictionaryNames.java
@@ -32,6 +32,7 @@
 	ActionPolicyDictionary,
 	OnapName,
 	MSPolicyDictionary,
+	OptimizationPolicyDictionary,
 	VNFType,
 	VSCLAction,
 	ClosedLoopService,
diff --git a/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/XACMLPapServlet.java b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/XACMLPapServlet.java
index a30c9c7..1acec1b 100644
--- a/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/XACMLPapServlet.java
+++ b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/XACMLPapServlet.java
@@ -46,7 +46,7 @@
 import java.util.Set;
 import java.util.UUID;
 import java.util.concurrent.CopyOnWriteArrayList;
-import javax.json.JsonException;
+
 import javax.persistence.EntityManagerFactory;
 import javax.persistence.Persistence;
 import javax.persistence.PersistenceException;
@@ -1018,24 +1018,26 @@
 			im.startTransaction();
 			loggingContext.metricEnded();
 			PolicyLogger.metrics("XACMLPapServlet doPut im startTransaction");
-		} catch(AdministrativeStateException e) {
-		    String message = "PUT interface called for PAP " + papResourceName + 
-		            " but it has an Administrative state of " + im.getStateManager().getAdminState() +
-		            "\n Exception Message: " + e.getMessage();
-		    logMessage(e, message, loggingContext, response);
-		    return;
-		} catch(StandbyStatusException e) {
-		    String message = "PUT interface called for PAP " + papResourceName + 
-		            " but it has a Standby Status of " + im.getStateManager().getStandbyStatus() +
-		            "\n Exception Message: " + e.getMessage();
-		    logMessage(e, message, loggingContext, response);
-		    return;
 		} catch (IntegrityMonitorException e) {
-		    String message = "PUT interface called for PAP " + papResourceName +
-		            " but an exception occurred" +
-		            "\n Exception Message: " + e.getMessage();
-		    logMessage(e, message, loggingContext, response);
-		    return;
+			String message = "PUT interface called for PAP " + papResourceName;
+			if (e instanceof AdministrativeStateException) {
+				message += " but it has an Administrative state of "
+					+ im.getStateManager().getAdminState();
+			} else if (e instanceof StandbyStatusException) {
+				message += " but it has a Standby Status of "
+					+ im.getStateManager().getStandbyStatus();
+			} else {
+				message += " but an exception occurred";
+
+			}
+			message += "\n Exception Message: " + e.getMessage();
+
+			LOGGER.info(message, e);
+			PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " " + message);
+			loggingContext.transactionEnded();
+			PolicyLogger.audit("Transaction Failed - See Error.log");
+			setResponseError(response,HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
+			return;
 		}
 
 		loggingContext.metricStarted();
@@ -2840,21 +2842,24 @@
 			PolicyLogger.audit("Transaction Failed - See Error.log");
 			response.setStatus(HttpServletResponse.SC_OK);
 			return;
-		}catch (ForwardProgressException e){
-		    String message = "GET:/pap/test called and PAP " + papResourceName + " is not making forward progress."
-		            + " Exception Message: " + e.getMessage();
-		    logMessage(e, message, loggingContext, response);
-		    return;
-		}catch (AdministrativeStateException e){
-		    String message = "GET:/pap/test called and PAP " + papResourceName + " Administrative State is LOCKED."
-		            + " Exception Message: " + e.getMessage();
-		    logMessage(e, message, loggingContext, response);
-		    return;
-		}catch (StandbyStatusException e){
-		    String message = "GET:/pap/test called and PAP " + papResourceName + " Standby Status is NOT PROVIDING SERVICE."
-		            + " Exception Message: " + e.getMessage();
-		    logMessage(e, message, loggingContext, response);
-		    return;
+		}catch (ForwardProgressException | AdministrativeStateException | StandbyStatusException e){
+			String submsg;
+			if (e instanceof ForwardProgressException) {
+				submsg = " is not making forward progress.";
+			} else if (e instanceof AdministrativeStateException) {
+				submsg = " Administrative State is LOCKED.";
+			} else {
+				submsg = " Standby Status is NOT PROVIDING SERVICE.";
+			}
+
+			String message = "GET:/pap/test called and PAP " + papResourceName + submsg
+					+ " Exception Message: " + e.getMessage();
+			LOGGER.info(message, e);
+			PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " " + message);
+			loggingContext.transactionEnded();
+			PolicyLogger.audit("Transaction Failed - See Error.log");
+			setResponseError(response,HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
+			return;
 		}catch (Exception e) {
 			//A subsystem is not making progress, is locked, standby or is not responding
 			String eMsg = e.getMessage();
@@ -3029,12 +3034,4 @@
 	public static void setMsPolicyName(String msPolicyName) {
 		XACMLPapServlet.msPolicyName = msPolicyName;
 	}
-	
-	private void logMessage(Exception e, String message, ONAPLoggingContext loggingContext, HttpServletResponse response) {
-	    LOGGER.info(message, e);
-	    PolicyLogger.error(MessageCodes.ERROR_SYSTEM_ERROR + " " + message);
-	    loggingContext.transactionEnded();
-	    PolicyLogger.audit("Transaction Failed - See Error.log");
-	    setResponseError(response,HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
-	}
-}
+}
\ No newline at end of file
diff --git a/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/components/CreateNewMicroServiceModel.java b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/components/CreateNewMicroServiceModel.java
index d5233ce..7757c2f 100644
--- a/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/components/CreateNewMicroServiceModel.java
+++ b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/components/CreateNewMicroServiceModel.java
@@ -29,6 +29,7 @@
 import java.util.Arrays;
 import java.util.Enumeration;
 import java.util.HashMap;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.zip.ZipEntry;
@@ -48,6 +49,8 @@
 import org.onap.policy.rest.util.MSModelUtils;
 import org.onap.policy.rest.util.MSModelUtils.MODEL_TYPE;
 
+import com.google.gson.Gson;
+
 public class CreateNewMicroServiceModel {
 	private static final Logger logger = FlexLogger.getLogger(CreateNewMicroServiceModel.class);
 	private MicroServiceModels newModel = null;
@@ -79,8 +82,18 @@
 	        //get all the files from a director
 	        for (File file : fileList){
 	            if (file.isFile()){
-				    tempMap = utils.processEpackage(file.getAbsolutePath(), MODEL_TYPE.XMI);
-				    classMap.putAll(tempMap);
+	            	int i = file.getName().lastIndexOf('.');
+	            	String type = file.getName().substring(i+1);
+	            	
+	            	if(type != null && "yml".equalsIgnoreCase(type)){
+	            		
+	            		processYmlModel(file.toString(), modelName);
+	            		
+	            	}else{
+	            		
+				        tempMap = utils.processEpackage(file.getAbsolutePath(), MODEL_TYPE.XMI);
+				        classMap.putAll(tempMap);
+	            	}
 	            }
 	        }
 	        cleanUpFile = "ExtractDir" + File.separator + randomID + ".zip";
@@ -92,15 +105,67 @@
 			} catch (IOException e) {
 				logger.error("Failed to unzip model file " + randomID, e);
 			}
-	    }else {
-		    tempMap = utils.processEpackage("ExtractDir" + File.separator + randomID+".xmi", MODEL_TYPE.XMI);
-		    classMap.putAll(tempMap);
-		    cleanUpFile = "ExtractDir" + File.separator + randomID+".xmi";
+	    }else {	    	
+	    	if(importFile.contains(".yml")){
+	    		
+				processYmlModel("ExtractDir" + File.separator + randomID+".yml", modelName);
+			    cleanUpFile = "ExtractDir" + File.separator + randomID+".yml";
+	    		
+	    	}else{
+			    tempMap = utils.processEpackage("ExtractDir" + File.separator + randomID+".xmi", MODEL_TYPE.XMI);
+			    classMap.putAll(tempMap);
+			    cleanUpFile = "ExtractDir" + File.separator + randomID+".xmi";
+	    	}
+	    	
 		    File deleteFile = new File(cleanUpFile); 
 			deleteFile.delete();
 	    }
 	}
 	
+	private void processYmlModel(String fileName, String  modelName){
+
+		try {
+			
+			
+			utils.parseTosca(fileName);
+			
+			MSAttributeObject msAttributes= new MSAttributeObject();
+			msAttributes.setClassName(modelName);
+			
+			LinkedHashMap<String, String> returnAttributeList =new LinkedHashMap<>();
+			returnAttributeList.put(modelName, utils.getAttributeString());
+			msAttributes.setAttribute(returnAttributeList);
+			
+			msAttributes.setSubClass(utils.getRetmap());
+			
+			msAttributes.setMatchingSet(utils.getMatchableValues());
+			
+			LinkedHashMap<String, String> returnReferenceList =new LinkedHashMap<>();
+
+			returnReferenceList.put(modelName, utils.getReferenceAttributes());
+			msAttributes.setRefAttribute(returnReferenceList);
+			
+			if(utils.getListConstraints()!=""){
+				LinkedHashMap<String, String> enumList =new LinkedHashMap<>();
+				String[] listArray=utils.getListConstraints().split("#");
+                for(String str:listArray){
+                    String[] strArr= str.split("=");
+                    if(strArr.length>1){
+                        enumList.put(strArr[0], strArr[1]);
+                    }
+                }
+				msAttributes.setEnumType(enumList);
+			}
+			
+			classMap=new LinkedHashMap<>();
+			classMap.put(modelName, msAttributes);
+			
+		} catch (Exception e) {
+			logger.error("Failed to process yml model" + e);
+		}
+	
+	}
+	
 	private List<File> listModelFiles(String directoryName) {
 		File directory = new File(directoryName);
 		List<File> resultList = new ArrayList<>();
@@ -171,7 +236,7 @@
 		}
 	}
 
-	public Map<String, String> addValuesToNewModel() {
+	public Map<String, String> addValuesToNewModel(String type) {
 		
 		Map<String, String> successMap = new HashMap<>();
 		MSAttributeObject mainClass  = null;
@@ -185,29 +250,75 @@
 			return successMap;
 		}
 		mainClass = classMap.get(this.newModel.getModelName());
-		String dependTemp = StringUtils.replaceEach(mainClass.getDependency(), new String[]{"[", "]", " "}, new String[]{"", "", ""});
-		this.newModel.setDependency(dependTemp);
-		if (!this.newModel.getDependency().equals("")){
-			dependency = new ArrayList<String>(Arrays.asList(dependTemp.split(",")));	
-			dependency = utils.getFullDependencyList(dependency, classMap);
-			if (!dependency.isEmpty()){
-				for (String element : dependency){
-				    MSAttributeObject temp;
-					if (classMap.containsKey(element)){
-						temp = classMap.get(element);
-						mainClass.addAllRefAttribute(temp.getRefAttribute());
-						mainClass.addAllAttribute(temp.getAttribute());
+		
+		
+		if(".yml".equalsIgnoreCase(type)){
+			
+			newModel.setDependency("[]");
+			if(mainClass.getSubClass() != null){
+			   String value = new Gson().toJson(mainClass.getSubClass());
+			   newModel.setSub_attributes(value);
+			}
+			
+			if(mainClass.getAttribute() != null){
+				String attributes= mainClass.getAttribute().toString().replace("{", "").replace("}", "");
+				int equalsIndexForAttributes= attributes.indexOf("=");
+				String atttributesAfterFirstEquals= attributes.substring(equalsIndexForAttributes+1);
+				this.newModel.setAttributes(atttributesAfterFirstEquals);
+			}
+			
+			if(mainClass.getRefAttribute() != null){
+				String refAttributes= mainClass.getRefAttribute().toString().replace("{", "").replace("}", "");
+				int equalsIndex= refAttributes.indexOf("=");
+				String refAttributesAfterFirstEquals= refAttributes.substring(equalsIndex+1);
+				this.newModel.setRef_attributes(refAttributesAfterFirstEquals);
+			}
+			
+			if(mainClass.getEnumType() != null){
+			    this.newModel.setEnumValues(mainClass.getEnumType().toString().replace("{", "").replace("}", ""));
+			}
+			
+			if(mainClass.getMatchingSet() != null){
+			    this.newModel.setAnnotation(mainClass.getMatchingSet().toString().replace("{", "").replace("}", ""));
+			}
+			
+		}else{
+		
+			String dependTemp = StringUtils.replaceEach(mainClass.getDependency(), new String[]{"[", "]", " "}, new String[]{"", "", ""});
+			this.newModel.setDependency(dependTemp);
+			if (this.newModel.getDependency() != null && !this.newModel.getDependency().isEmpty()){
+				dependency = new ArrayList<String>(Arrays.asList(dependTemp.split(",")));	
+				dependency = utils.getFullDependencyList(dependency, classMap);
+				if (!dependency.isEmpty()){
+					for (String element : dependency){
+						MSAttributeObject temp = new MSAttributeObject();
+						if (classMap.containsKey(element)){
+							temp = classMap.get(element);
+							mainClass.addAllRefAttribute(temp.getRefAttribute());
+							mainClass.addAllAttribute(temp.getAttribute());
+						}
 					}
-				}
-			}		
+				}		
+			}
+			subAttribute = utils.createSubAttributes(dependency, classMap, this.newModel.getModelName());
+	
+			this.newModel.setSub_attributes(subAttribute);
+			if(mainClass.getAttribute() != null && !mainClass.getAttribute().isEmpty()){
+			    this.newModel.setAttributes(mainClass.getAttribute().toString().replace("{", "").replace("}", ""));
+			}
+			
+			if(mainClass.getRefAttribute() != null && !mainClass.getRefAttribute().isEmpty()){
+			   this.newModel.setRef_attributes(mainClass.getRefAttribute().toString().replace("{", "").replace("}", ""));
+			}
+			
+			if(mainClass.getEnumType() != null && !mainClass.getEnumType().isEmpty()){
+		        this.newModel.setEnumValues(mainClass.getEnumType().toString().replace("{", "").replace("}", ""));
+			}
+			
+			if(mainClass.getMatchingSet() != null && !mainClass.getMatchingSet().isEmpty()){
+	            this.newModel.setAnnotation(mainClass.getMatchingSet().toString().replace("{", "").replace("}", ""));
+			}
 		}
-		subAttribute = utils.createSubAttributes(dependency, classMap, this.newModel.getModelName());
-
-		this.newModel.setSub_attributes(subAttribute);
-		this.newModel.setAttributes(mainClass.getAttribute().toString().replace("{", "").replace("}", ""));
-		this.newModel.setRef_attributes(mainClass.getRefAttribute().toString().replace("{", "").replace("}", ""));
-		this.newModel.setEnumValues(mainClass.getEnumType().toString().replace("{", "").replace("}", ""));
-        this.newModel.setAnnotation(mainClass.getMatchingSet().toString().replace("{", "").replace("}", ""));
 		successMap.put("success", "success");
 		return successMap;
 		
@@ -231,6 +342,7 @@
 			model.setEnumValues(this.newModel.getEnumValues());
 			model.setRef_attributes(this.newModel.getRef_attributes());
 			model.setSub_attributes(this.newModel.getSub_attributes());
+			model.setDataOrderInfo(this.newModel.getDataOrderInfo());
 			UserInfo userInfo = new UserInfo();
 			userInfo.setUserLoginId(imported_by);
 			userInfo.setUserName(imported_by);
diff --git a/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/components/CreateNewOptimizationModel.java b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/components/CreateNewOptimizationModel.java
new file mode 100644
index 0000000..c4de9a0
--- /dev/null
+++ b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/components/CreateNewOptimizationModel.java
@@ -0,0 +1,292 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2018 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.pap.xacml.rest.components;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+import org.apache.commons.io.FileUtils;
+import org.onap.policy.common.logging.eelf.MessageCodes;
+import org.onap.policy.common.logging.eelf.PolicyLogger;
+import org.onap.policy.common.logging.flexlogger.FlexLogger;
+import org.onap.policy.common.logging.flexlogger.Logger;
+import org.onap.policy.pap.xacml.rest.XACMLPapServlet;
+import org.onap.policy.pap.xacml.rest.daoimpl.CommonClassDaoImpl;
+import org.onap.policy.rest.jpa.OptimizationModels;
+import org.onap.policy.rest.jpa.UserInfo;
+import org.onap.policy.rest.util.MSAttributeObject;
+import org.onap.policy.rest.util.MSModelUtils;
+import org.onap.policy.rest.util.MSModelUtils.MODEL_TYPE;
+
+import com.google.gson.Gson;
+
+public class CreateNewOptimizationModel {
+	private static final Logger logger = FlexLogger.getLogger(CreateNewOptimizationModel.class);
+	private OptimizationModels newModel = null;
+	private HashMap<String,MSAttributeObject > classMap = new HashMap<>();
+	
+	private static final String EXTRACTDIR = "ExtractDir";
+	private static final String SUCCESS = "success";
+
+	
+	MSModelUtils utils = new MSModelUtils(XACMLPapServlet.getMsOnapName(), XACMLPapServlet.getMsPolicyName());
+
+	public CreateNewOptimizationModel() {
+		super();
+	}
+
+	public CreateNewOptimizationModel(String importFile, String  modelName, String description, String version, String randomID) {
+	
+		this.newModel = new OptimizationModels();
+		this.newModel.setVersion(version);
+		this.newModel.setModelName(modelName);
+		this.newModel.setDescription(description);
+		UserInfo userInfo = new UserInfo();
+		userInfo.setUserLoginId("API");
+		this.newModel.setUserCreatedBy(userInfo);
+		String cleanUpFile = null;
+	
+	    Map<String, MSAttributeObject> tempMap = new HashMap<>();
+	    //Need to delete the file
+	    if (importFile.contains(".zip")){
+	    	extractFolder(randomID + ".zip");
+	        File directory = new File(EXTRACTDIR + File.separator + randomID);
+	        List<File> fileList = listModelFiles(directory.toString());
+	        //get all the files from a director
+	        for (File file : fileList){
+	            if (file.isFile()){
+            		processYmlModel(file.toString(), modelName);
+	            }
+	        }
+	        cleanUpFile = EXTRACTDIR + File.separator + randomID + ".zip";
+	        try {
+				FileUtils.deleteDirectory(new File(EXTRACTDIR + File.separator + randomID));
+				FileUtils.deleteDirectory(new File(randomID));
+				File deleteFile = new File(cleanUpFile); 
+				FileUtils.forceDelete(deleteFile);
+			} catch (IOException e) {
+				logger.error("Failed to unzip model file " + randomID, e);
+			}
+	    }else {
+	    	if(importFile.contains(".yml")){
+	    		
+				processYmlModel(EXTRACTDIR + File.separator + randomID+".yml", modelName);
+			    cleanUpFile = EXTRACTDIR + File.separator + randomID+".yml";
+	    		
+	    	}else{
+			    tempMap = utils.processEpackage(EXTRACTDIR + File.separator + randomID+".xmi", MODEL_TYPE.XMI);
+			    classMap.putAll(tempMap);
+			    cleanUpFile = EXTRACTDIR + File.separator + randomID+".xmi";
+	    	}
+		    File deleteFile = new File(cleanUpFile); 
+			deleteFile.delete();
+	    }
+	}
+	
+	private void processYmlModel(String fileName, String  modelName){
+
+		try {
+			
+			utils.parseTosca(fileName);
+			
+			MSAttributeObject msAttributes= new MSAttributeObject();
+			msAttributes.setClassName(modelName);
+			
+			LinkedHashMap<String, String> returnAttributeList =new LinkedHashMap<>();
+			returnAttributeList.put(modelName, utils.getAttributeString());
+			msAttributes.setAttribute(returnAttributeList);
+			
+			msAttributes.setSubClass(utils.getRetmap());
+			
+			msAttributes.setMatchingSet(utils.getMatchableValues());
+			
+			LinkedHashMap<String, String> returnReferenceList =new LinkedHashMap<>();
+
+			returnReferenceList.put(modelName, utils.getReferenceAttributes());
+			msAttributes.setRefAttribute(returnReferenceList);
+			
+			if(!"".equals(utils.getListConstraints())){
+				LinkedHashMap<String, String> enumList =new LinkedHashMap<>();
+				String[] listArray=utils.getListConstraints().split("#");
+                for(String str:listArray){
+                    String[] strArr= str.split("=");
+                    if(strArr.length>1){
+                        enumList.put(strArr[0], strArr[1]);
+                    }
+                }
+				msAttributes.setEnumType(enumList);
+			}
+			
+			classMap=new LinkedHashMap<>();
+			classMap.put(modelName, msAttributes);
+			
+		} catch (Exception e) {
+			logger.error("Failed to process yml model" + e);
+		}
+	
+	}
+	
+	private List<File> listModelFiles(String directoryName) {
+		File directory = new File(directoryName);
+		List<File> resultList = new ArrayList<>();
+		File[] fList = directory.listFiles();
+		for (File file : fList) {
+			if (file.isFile()) {
+				resultList.add(file);
+			} else if (file.isDirectory()) {
+				resultList.addAll(listModelFiles(file.getAbsolutePath()));
+			}
+		}
+		return resultList;
+	}
+
+	@SuppressWarnings("rawtypes")
+	private void extractFolder(String zipFile) {
+	    int buffer = 2048;
+	    File file = new File(zipFile);
+
+		try(ZipFile zip = new ZipFile(EXTRACTDIR + File.separator +file);){
+		    String newPath =  zipFile.substring(0, zipFile.length() - 4);
+		    new File(newPath).mkdir();
+		    Enumeration zipFileEntries = zip.entries();
+	
+		    // Process each entry
+		    while (zipFileEntries.hasMoreElements()){
+		        // grab a zip file entry
+		        ZipEntry entry = (ZipEntry) zipFileEntries.nextElement();
+		        String currentEntry = entry.getName();
+		        File destFile = new File(EXTRACTDIR + File.separator + newPath + File.separator + currentEntry);
+		        File destinationParent = destFile.getParentFile();
+	
+		        destinationParent.mkdirs();
+	
+		        if (!entry.isDirectory()){
+		            int currentByte;
+
+		            byte[] data = new byte[buffer];
+					try(FileOutputStream fos = new FileOutputStream(destFile);
+							BufferedInputStream is = new BufferedInputStream(zip.getInputStream(entry));
+								BufferedOutputStream dest = new BufferedOutputStream(fos, buffer)) {
+
+						while ((currentByte = is.read(data, 0, buffer)) != -1) {
+							dest.write(data, 0, currentByte);
+						}
+						dest.flush();
+					}
+		        }
+	
+		        if (currentEntry.endsWith(".zip")){
+		            extractFolder(destFile.getAbsolutePath());
+		        }
+		    }
+	    } catch (IOException e) {
+			logger.error("Failed to unzip model file " + zipFile + e);
+		}
+	}
+
+	public Map<String, String> addValuesToNewModel() {
+		
+		Map<String, String> successMap = new HashMap<>();
+		MSAttributeObject mainClass;
+		
+		if (!classMap.containsKey(this.newModel.getModelName())){
+			logger.error("Model Provided does not contain the service name provided in request. Unable to import new model");
+			PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, "AddValuesToNewModel", "Unable to pull out required values, file missing service name provided in request");
+			successMap.put("error", "MISSING");
+			return successMap;
+		}
+		mainClass = classMap.get(this.newModel.getModelName());
+		newModel.setDependency("[]");
+		if(mainClass.getSubClass() != null){
+		   String value = new Gson().toJson(mainClass.getSubClass());
+		   newModel.setSubattributes(value);
+		}
+		
+		if(mainClass.getAttribute() != null){
+			String attributes= mainClass.getAttribute().toString().replace("{", "").replace("}", "");
+			int equalsIndexForAttributes= attributes.indexOf('=');
+			String atttributesAfterFirstEquals= attributes.substring(equalsIndexForAttributes+1);
+			this.newModel.setAttributes(atttributesAfterFirstEquals);
+		}
+		
+		if(mainClass.getRefAttribute() != null){
+			String refAttributes= mainClass.getRefAttribute().toString().replace("{", "").replace("}", "");
+			int equalsIndex= refAttributes.indexOf('=');
+			String refAttributesAfterFirstEquals= refAttributes.substring(equalsIndex+1);
+			this.newModel.setRefattributes(refAttributesAfterFirstEquals);
+		}
+		
+		if(mainClass.getEnumType() != null){
+		    this.newModel.setEnumValues(mainClass.getEnumType().toString().replace("{", "").replace("}", ""));
+		}
+		
+		if(mainClass.getMatchingSet() != null){
+		    this.newModel.setAnnotation(mainClass.getMatchingSet().toString().replace("{", "").replace("}", ""));
+		}
+		
+		successMap.put(SUCCESS, SUCCESS);
+		return successMap;
+		
+	}
+	
+	public Map<String, String> saveImportService(){
+		String modelName = this.newModel.getModelName();
+		String importedBy = "API";
+		String version = this.newModel.getVersion();
+		Map<String, String> successMap = new HashMap<>();
+		CommonClassDaoImpl dbConnection = new CommonClassDaoImpl();
+		List<Object> result = dbConnection.getDataById(OptimizationModels.class, "modelName:version", modelName+":"+version);
+		if(result.isEmpty()){
+			OptimizationModels model = new OptimizationModels();
+			model.setModelName(modelName);
+			model.setVersion(version);
+			model.setAttributes(this.newModel.getAttributes());
+			model.setAnnotation(this.newModel.getAnnotation());
+			model.setDependency(this.newModel.getDependency());
+			model.setDescription(this.newModel.getDescription());
+			model.setEnumValues(this.newModel.getEnumValues());
+			model.setRefattributes(this.newModel.getRefattributes());
+			model.setSubattributes(this.newModel.getSubattributes());
+			model.setDataOrderInfo(this.newModel.getDataOrderInfo());
+			UserInfo userInfo = new UserInfo();
+			userInfo.setUserLoginId(importedBy);
+			userInfo.setUserName(importedBy);
+			model.setUserCreatedBy(userInfo);
+			dbConnection.save(model);
+			successMap.put(SUCCESS, SUCCESS);
+		}else{
+			successMap.put("DBError", "EXISTS");
+			logger.error("Import new service failed.  Service already exists");
+		}		
+		return successMap;
+	}
+}
diff --git a/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/components/OptimizationConfigPolicy.java b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/components/OptimizationConfigPolicy.java
new file mode 100644
index 0000000..2a03482
--- /dev/null
+++ b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/components/OptimizationConfigPolicy.java
@@ -0,0 +1,530 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2018 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.pap.xacml.rest.components;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.apache.commons.io.FilenameUtils;
+import org.apache.commons.lang.StringUtils;
+import org.onap.policy.common.logging.eelf.MessageCodes;
+import org.onap.policy.common.logging.eelf.PolicyLogger;
+import org.onap.policy.common.logging.flexlogger.FlexLogger;
+import org.onap.policy.common.logging.flexlogger.Logger;
+import org.onap.policy.pap.xacml.rest.daoimpl.CommonClassDaoImpl;
+import org.onap.policy.rest.adapter.PolicyRestAdapter;
+import org.onap.policy.rest.jpa.OptimizationModels;
+
+import com.att.research.xacml.api.pap.PAPException;
+import com.att.research.xacml.std.IdentifierImpl;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.common.base.Splitter;
+
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AdviceExpressionType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AdviceExpressionsType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AllOfType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AnyOfType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeAssignmentExpressionType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeDesignatorType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeValueType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.EffectType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.MatchType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.ObjectFactory;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.RuleType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.TargetType; 
+
+public class OptimizationConfigPolicy extends Policy {
+	
+	private static final Logger LOGGER = FlexLogger.getLogger(OptimizationConfigPolicy.class);
+	
+    private static Map<String, String> mapAttribute = new HashMap<>();
+    private static Map<String, String> mapMatch = new HashMap<>();
+
+	private static synchronized Map<String, String> getMatchMap () {
+		return mapMatch;
+	}
+
+	private static synchronized void setMatchMap(Map<String, String> mm) {
+		mapMatch = mm;
+	}
+
+	public OptimizationConfigPolicy() {
+		super();
+	}
+	
+	public OptimizationConfigPolicy(PolicyRestAdapter policyAdapter){
+		this.policyAdapter = policyAdapter;
+	}
+
+	//save configuration of the policy based on the policyname
+	private void saveConfigurations(String policyName, String jsonBody) {
+		try (PrintWriter out = new PrintWriter(CONFIG_HOME + File.separator + policyName +".json");){
+			if(policyName.endsWith(".xml")){
+				policyName = policyName.replace(".xml", "");
+			}
+			out.println(jsonBody);
+		} catch (Exception e) {
+			LOGGER.error("Exception Occured While writing Configuration data"+e);
+		} 
+	}
+	
+	
+	@Override
+	public Map<String, String> savePolicies() throws PAPException {
+
+		Map<String, String> successMap = new HashMap<>();
+		if(isPolicyExists()){
+			successMap.put("EXISTS", "This Policy already exist on the PAP");
+			return successMap;
+		}
+
+		if(!isPreparedToSave()){
+			//Prep and configure the policy for saving
+			prepareToSave();
+		}
+
+		// Until here we prepared the data and here calling the method to create xml.
+		Path newPolicyPath = null;
+		newPolicyPath = Paths.get(policyAdapter.getNewFileName());
+
+		successMap = createPolicy(newPolicyPath,getCorrectPolicyDataObject());	
+	
+		return successMap;		
+	}
+	
+	//This is the method for preparing the policy for saving.  We have broken it out
+	//separately because the fully configured policy is used for multiple things
+	@Override
+	public boolean prepareToSave() throws PAPException{
+
+		if(isPreparedToSave()){
+			//we have already done this
+			return true;
+		}
+		
+		int version = 0;
+		String policyID = policyAdapter.getPolicyID();
+		version = policyAdapter.getHighestVersion();
+		
+		// Create the Instance for pojo, PolicyType object is used in marshalling.
+		if (policyAdapter.getPolicyType().equals("Config")) {
+			PolicyType policyConfig = new PolicyType();
+
+			policyConfig.setVersion(Integer.toString(version));
+			policyConfig.setPolicyId(policyID);
+			policyConfig.setTarget(new TargetType());
+			policyAdapter.setData(policyConfig);
+		}
+		policyName = policyAdapter.getNewFileName();
+		if (policyAdapter.getData() != null) {
+			// Save the Configurations file with the policy name with extention based on selection.
+			String jsonBody = policyAdapter.getJsonBody();
+			saveConfigurations(policyName, jsonBody);
+			
+			// Make sure the filename ends with an extension
+			if (!policyName.endsWith(".xml")) {
+				policyName = policyName + ".xml";
+			}
+			
+	
+			PolicyType configPolicy = (PolicyType) policyAdapter.getData();
+			
+			configPolicy.setDescription(policyAdapter.getPolicyDescription());
+
+			configPolicy.setRuleCombiningAlgId(policyAdapter.getRuleCombiningAlgId());
+			
+			AllOfType allOfOne = new AllOfType();
+			String fileName = policyAdapter.getNewFileName();
+			String name = fileName.substring(fileName.lastIndexOf('\\') + 1, fileName.length());
+			if ((name == null) || (name.equals(""))) {
+				name = fileName.substring(fileName.lastIndexOf('/') + 1, fileName.length());
+			}
+			
+            //setup values for pulling out matching attributes
+            ObjectMapper mapper = new ObjectMapper();
+            String matching = null;
+            Map<String, String> matchMap = null;
+            try {
+                JsonNode rootNode = mapper.readTree(policyAdapter.getJsonBody());
+                if (policyAdapter.getTtlDate()==null){
+                    policyAdapter.setTtlDate("NA");
+                }
+                if (policyAdapter.getServiceType().contains("-v")){
+                    matching = getValueFromDictionary(policyAdapter.getServiceType());
+                } else {
+                    String jsonVersion  = StringUtils.replaceEach(rootNode.get("version").toString(), new String[]{"\""}, new String[]{""});
+                    matching = getValueFromDictionary(policyAdapter.getServiceType() + "-v" + jsonVersion);
+                }
+                if (matching != null && !matching.isEmpty()){
+                    matchMap = Splitter.on(",").withKeyValueSeparator("=").split(matching);
+                    setMatchMap(matchMap);
+                    if(policyAdapter.getJsonBody() != null){
+                        pullMatchValue(rootNode);           
+                    }
+                }
+            } catch (IOException e1) {
+                throw new PAPException(e1);
+            }
+            
+			// Match for policyName
+			allOfOne.getMatch().add(createMatch("PolicyName", name));
+			
+			AllOfType allOf = new AllOfType();
+		
+			// Adding the matches to AllOfType element Match for Onap
+			allOf.getMatch().add(createMatch("ONAPName", policyAdapter.getOnapName()));
+			if (matchMap!=null && !matchMap.isEmpty()) {
+				for (Entry<String, String> matchValue : matchMap.entrySet()){
+					String value = matchValue.getValue();
+					String key = matchValue.getKey().trim();
+					if (value.contains("matching-true") && mapAttribute.containsKey(key)){
+						allOf.getMatch().add(createDynamicMatch(key, mapAttribute.get(key)));
+					}
+				}
+			}
+			
+			// Match for riskType
+			allOf.getMatch().add(
+					createDynamicMatch("RiskType", policyAdapter.getRiskType()));
+			// Match for riskLevel
+			allOf.getMatch().add(
+					createDynamicMatch("RiskLevel", String.valueOf(policyAdapter.getRiskLevel())));
+			// Match for riskguard
+			allOf.getMatch().add(
+					createDynamicMatch("guard", policyAdapter.getGuard()));
+			// Match for ttlDate
+			allOf.getMatch().add(
+					createDynamicMatch("TTLDate", policyAdapter.getTtlDate()));
+
+			AnyOfType anyOf = new AnyOfType();
+			anyOf.getAllOf().add(allOfOne);
+			anyOf.getAllOf().add(allOf);
+
+			TargetType target = new TargetType();
+			target.getAnyOf().add(anyOf);
+			
+			// Adding the target to the policy element
+			configPolicy.setTarget((TargetType) target);
+
+			RuleType rule = new RuleType();
+			rule.setRuleId(policyAdapter.getRuleID());
+			
+			rule.setEffect(EffectType.PERMIT);
+			
+			// Create Target in Rule
+			AllOfType allOfInRule = new AllOfType();
+
+			// Creating match for ACCESS in rule target
+			MatchType accessMatch = new MatchType();
+			AttributeValueType accessAttributeValue = new AttributeValueType();
+			accessAttributeValue.setDataType(STRING_DATATYPE);
+			accessAttributeValue.getContent().add("ACCESS");
+			accessMatch.setAttributeValue(accessAttributeValue);
+			AttributeDesignatorType accessAttributeDesignator = new AttributeDesignatorType();
+			URI accessURI = null;
+			try {
+				accessURI = new URI(ACTION_ID);
+			} catch (URISyntaxException e) {
+				PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "OptimizationConfigPolicy", "Exception creating ACCESS URI");
+			}
+			accessAttributeDesignator.setCategory(CATEGORY_ACTION);
+			accessAttributeDesignator.setDataType(STRING_DATATYPE);
+			accessAttributeDesignator.setAttributeId(new IdentifierImpl(accessURI).stringValue());
+			accessMatch.setAttributeDesignator(accessAttributeDesignator);
+			accessMatch.setMatchId(FUNCTION_STRING_EQUAL_IGNORE);
+
+			// Creating Config Match in rule Target
+			MatchType configMatch = new MatchType();
+			AttributeValueType configAttributeValue = new AttributeValueType();
+			configAttributeValue.setDataType(STRING_DATATYPE);
+			configAttributeValue.getContent().add("Config");
+			configMatch.setAttributeValue(configAttributeValue);
+			AttributeDesignatorType configAttributeDesignator = new AttributeDesignatorType();
+			URI configURI = null;
+			try {
+				configURI = new URI(RESOURCE_ID);
+			} catch (URISyntaxException e) {
+				PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "OptimizationConfigPolicy", "Exception creating Config URI");
+			}
+			configAttributeDesignator.setCategory(CATEGORY_RESOURCE);
+			configAttributeDesignator.setDataType(STRING_DATATYPE);
+			configAttributeDesignator.setAttributeId(new IdentifierImpl(configURI).stringValue());
+			configMatch.setAttributeDesignator(configAttributeDesignator);
+			configMatch.setMatchId(FUNCTION_STRING_EQUAL_IGNORE);
+
+			allOfInRule.getMatch().add(accessMatch);
+			allOfInRule.getMatch().add(configMatch);
+
+			AnyOfType anyOfInRule = new AnyOfType();
+			anyOfInRule.getAllOf().add(allOfInRule);
+
+			TargetType targetInRule = new TargetType();
+			targetInRule.getAnyOf().add(anyOfInRule);
+
+			rule.setTarget(targetInRule);
+			rule.setAdviceExpressions(getAdviceExpressions(version, policyName));
+
+			configPolicy.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition().add(rule);
+			policyAdapter.setPolicyData(configPolicy);
+
+		} else {
+			PolicyLogger.error("Unsupported data object." + policyAdapter.getData().getClass().getCanonicalName());
+		}
+		setPreparedToSave(true);
+		return true;
+	}
+	
+    private void pullMatchValue(JsonNode rootNode) {
+        Iterator<Map.Entry<String, JsonNode>> fieldsIterator = rootNode.fields();
+        String newValue = null;
+           while (fieldsIterator.hasNext()) {
+               Map.Entry<String, JsonNode> field = fieldsIterator.next();
+               final String key = field.getKey();
+               final JsonNode value = field.getValue();
+               if (value.isContainerNode() && !value.isArray()) {
+                   pullMatchValue(value); // RECURSIVE CALL
+               } else {
+                   newValue = StringUtils.replaceEach(value.toString(), new String[]{"[", "]", "\""}, new String[]{"", "", ""});
+                   mapAttribute.put(key, newValue);
+               }
+           }
+       
+   }
+
+   private String getValueFromDictionary(String service){
+       String ruleTemplate=null;
+       String modelName = service.split("-v")[0];
+       String modelVersion = service.split("-v")[1];
+       
+       CommonClassDaoImpl dbConnection = new CommonClassDaoImpl();
+       List<Object> result = dbConnection.getDataById(OptimizationModels.class, "modelName:version", modelName+":"+modelVersion);
+       if(result != null && !result.isEmpty()){
+    	   OptimizationModels model = (OptimizationModels) result.get(0);
+    	   ruleTemplate = model.getAnnotation();
+       }
+       return ruleTemplate;
+   }
+   
+	// Data required for Advice part is setting here.
+	private AdviceExpressionsType getAdviceExpressions(int version, String fileName) {
+		AdviceExpressionsType advices = new AdviceExpressionsType();
+		AdviceExpressionType advice = new AdviceExpressionType();
+		advice.setAdviceId("OptimizationID");
+		advice.setAppliesTo(EffectType.PERMIT);
+		
+		// For Configuration
+		AttributeAssignmentExpressionType assignment1 = new AttributeAssignmentExpressionType();
+		assignment1.setAttributeId("type");
+		assignment1.setCategory(CATEGORY_RESOURCE);
+		assignment1.setIssuer("");
+
+		AttributeValueType configNameAttributeValue = new AttributeValueType();
+		configNameAttributeValue.setDataType(STRING_DATATYPE);
+		configNameAttributeValue.getContent().add("Configuration");
+		assignment1.setExpression(new ObjectFactory().createAttributeValue(configNameAttributeValue));
+
+		advice.getAttributeAssignmentExpression().add(assignment1);
+		
+		// For Config file Url if configurations are provided.
+		AttributeAssignmentExpressionType assignment2 = new AttributeAssignmentExpressionType();
+		assignment2.setAttributeId("URLID");
+		assignment2.setCategory(CATEGORY_RESOURCE);
+		assignment2.setIssuer("");
+
+		AttributeValueType attributeValue = new AttributeValueType();
+		attributeValue.setDataType(URI_DATATYPE);
+		String configName;
+		if(policyName.endsWith(".xml")){
+			configName = policyName.replace(".xml", "");
+		}else{
+			configName = policyName;
+		}
+		String content = CONFIG_URL +"/Config/" + configName + ".json";
+		attributeValue.getContent().add(content);
+		assignment2.setExpression(new ObjectFactory().createAttributeValue(attributeValue));
+
+		advice.getAttributeAssignmentExpression().add(assignment2);
+		
+		//PolicyName Attribute Assignment
+		AttributeAssignmentExpressionType assignment3 = new AttributeAssignmentExpressionType();
+		assignment3.setAttributeId("PolicyName");
+		assignment3.setCategory(CATEGORY_RESOURCE);
+		assignment3.setIssuer("");
+
+		AttributeValueType attributeValue3 = new AttributeValueType();
+		attributeValue3.setDataType(STRING_DATATYPE);
+		fileName = FilenameUtils.removeExtension(fileName);
+		fileName = fileName + ".xml";
+		String name = fileName.substring(fileName.lastIndexOf('\\') + 1, fileName.length());
+		if ((name == null) || (name.equals(""))) {
+			name = fileName.substring(fileName.lastIndexOf('/') + 1, fileName.length());
+		}
+		attributeValue3.getContent().add(name);
+		assignment3.setExpression(new ObjectFactory().createAttributeValue(attributeValue3));
+		advice.getAttributeAssignmentExpression().add(assignment3);
+
+		//VersionNumber Attribute Assignment
+		AttributeAssignmentExpressionType assignment4 = new AttributeAssignmentExpressionType();
+		assignment4.setAttributeId("VersionNumber");
+		assignment4.setCategory(CATEGORY_RESOURCE);
+		assignment4.setIssuer("");
+
+		AttributeValueType configNameAttributeValue4 = new AttributeValueType();
+		configNameAttributeValue4.setDataType(STRING_DATATYPE);
+		configNameAttributeValue4.getContent().add(Integer.toString(version));
+		assignment4.setExpression(new ObjectFactory().createAttributeValue(configNameAttributeValue4));
+
+		advice.getAttributeAssignmentExpression().add(assignment4);
+
+		//OnapName Attribute Assignment
+		AttributeAssignmentExpressionType assignment5 = new AttributeAssignmentExpressionType();
+		assignment5.setAttributeId("matching:" + ONAPID);
+		assignment5.setCategory(CATEGORY_RESOURCE);
+		assignment5.setIssuer("");
+
+		AttributeValueType configNameAttributeValue5 = new AttributeValueType();
+		configNameAttributeValue5.setDataType(STRING_DATATYPE);
+		configNameAttributeValue5.getContent().add(policyAdapter.getOnapName());
+		assignment5.setExpression(new ObjectFactory().createAttributeValue(configNameAttributeValue5));
+
+		advice.getAttributeAssignmentExpression().add(assignment5);
+		
+		//ServiceType Attribute Assignment
+        AttributeAssignmentExpressionType assignment7 = new AttributeAssignmentExpressionType();
+        assignment7.setAttributeId("matching:service");
+        assignment7.setCategory(CATEGORY_RESOURCE);
+        assignment7.setIssuer("");
+ 
+        AttributeValueType configNameAttributeValue7 = new AttributeValueType();
+        configNameAttributeValue7.setDataType(STRING_DATATYPE);
+        configNameAttributeValue7.getContent().add(policyAdapter.getServiceType());
+        assignment7.setExpression(new ObjectFactory().createAttributeValue(configNameAttributeValue7));
+ 
+        advice.getAttributeAssignmentExpression().add(assignment7);
+
+        // Add matching attribute assignments if exist
+        Map<String, String> matchMap = getMatchMap();
+        if (matchMap!=null && !matchMap.isEmpty()) {
+        	for (Entry<String, String> matchValue : matchMap.entrySet()){
+                String value = matchValue.getValue();
+                String key = matchValue.getKey().trim();
+                if (value.contains("matching-true") && mapAttribute.containsKey(key)){
+                    AttributeAssignmentExpressionType assignment9 = new AttributeAssignmentExpressionType();
+                    assignment9.setAttributeId("matching:" + key);
+                    assignment9.setCategory(CATEGORY_RESOURCE);
+                    assignment9.setIssuer("");
+            
+                    AttributeValueType configNameAttributeValue9 = new AttributeValueType();
+                    configNameAttributeValue9.setDataType(STRING_DATATYPE);
+                    configNameAttributeValue9.getContent().add(mapAttribute.get(key));
+                    assignment9.setExpression(new ObjectFactory().createAttributeValue(configNameAttributeValue9));
+            
+                    advice.getAttributeAssignmentExpression().add(assignment9);
+                }
+            }
+        }
+        
+        // Priority Attribute Assignment
+		AttributeAssignmentExpressionType assignment10 = new AttributeAssignmentExpressionType();
+		assignment10.setAttributeId("Priority");
+		assignment10.setCategory(CATEGORY_RESOURCE);
+		assignment10.setIssuer("");
+
+		AttributeValueType configNameAttributeValue10 = new AttributeValueType();
+		configNameAttributeValue10.setDataType(STRING_DATATYPE);
+		configNameAttributeValue10.getContent().add(policyAdapter.getPriority());
+		assignment10.setExpression(new ObjectFactory().createAttributeValue(configNameAttributeValue10));
+
+		advice.getAttributeAssignmentExpression().add(assignment10);
+		
+		//RiskType Attribute Assignment
+		AttributeAssignmentExpressionType assignment11 = new AttributeAssignmentExpressionType();
+		assignment11.setAttributeId("RiskType");
+		assignment11.setCategory(CATEGORY_RESOURCE);
+		assignment11.setIssuer("");
+
+		AttributeValueType configNameAttributeValue11 = new AttributeValueType();
+		configNameAttributeValue11.setDataType(STRING_DATATYPE);
+		configNameAttributeValue11.getContent().add(policyAdapter.getRiskType());
+		assignment11.setExpression(new ObjectFactory().createAttributeValue(configNameAttributeValue11));
+
+		advice.getAttributeAssignmentExpression().add(assignment11);
+		
+		//RiskLevel Attribute Assignment
+		AttributeAssignmentExpressionType assignment12 = new AttributeAssignmentExpressionType();
+		assignment12.setAttributeId("RiskLevel");
+		assignment12.setCategory(CATEGORY_RESOURCE);
+		assignment12.setIssuer("");
+
+		AttributeValueType configNameAttributeValue12 = new AttributeValueType();
+		configNameAttributeValue12.setDataType(STRING_DATATYPE);
+		configNameAttributeValue12.getContent().add(policyAdapter.getRiskLevel());
+		assignment12.setExpression(new ObjectFactory().createAttributeValue(configNameAttributeValue12));
+
+		advice.getAttributeAssignmentExpression().add(assignment12);	
+		
+		//Guard Attribute Assignment
+		AttributeAssignmentExpressionType assignment13 = new AttributeAssignmentExpressionType();
+		assignment13.setAttributeId("guard");
+		assignment13.setCategory(CATEGORY_RESOURCE);
+		assignment13.setIssuer("");
+
+		AttributeValueType configNameAttributeValue13 = new AttributeValueType();
+		configNameAttributeValue13.setDataType(STRING_DATATYPE);
+		configNameAttributeValue13.getContent().add(policyAdapter.getGuard());
+		assignment13.setExpression(new ObjectFactory().createAttributeValue(configNameAttributeValue13));
+
+		advice.getAttributeAssignmentExpression().add(assignment13);
+		
+		//TTLDate Attribute Assignment
+		AttributeAssignmentExpressionType assignment14 = new AttributeAssignmentExpressionType();
+		assignment14.setAttributeId("TTLDate");
+		assignment14.setCategory(CATEGORY_RESOURCE);
+		assignment14.setIssuer("");
+
+		AttributeValueType configNameAttributeValue14 = new AttributeValueType();
+		configNameAttributeValue14.setDataType(STRING_DATATYPE);
+		configNameAttributeValue14.getContent().add(policyAdapter.getTtlDate());
+		assignment14.setExpression(new ObjectFactory().createAttributeValue(configNameAttributeValue14));
+
+		advice.getAttributeAssignmentExpression().add(assignment14);
+
+		advices.getAdviceExpression().add(advice);
+		return advices;
+	}
+
+	@Override
+	public Object getCorrectPolicyDataObject() {
+		return policyAdapter.getPolicyData();
+	}	
+}
diff --git a/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/components/Policy.java b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/components/Policy.java
index 2196209..3b3e81e 100644
--- a/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/components/Policy.java
+++ b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/components/Policy.java
@@ -204,9 +204,9 @@
 		String policyDir = EMPTY_STRING;
 		String absolutePath = parent.toString();
 		if (absolutePath != null && !absolutePath.equals(EMPTY_STRING)) {
-			policyDir = absolutePath.substring(absolutePath.lastIndexOf("\\") + 1, absolutePath.length());
+			policyDir = absolutePath.substring(absolutePath.lastIndexOf('\\') + 1, absolutePath.length());
 			if (policyDir == null || policyDir.equals(EMPTY_STRING)) {
-				policyDir = absolutePath.substring(absolutePath.lastIndexOf("/") + 1, absolutePath.length());
+				policyDir = absolutePath.substring(absolutePath.lastIndexOf('/') + 1, absolutePath.length());
 			}
 		}
 
@@ -214,10 +214,9 @@
 		if (policyDir != null && !policyDir.equals(EMPTY_STRING)) {
 			fileName = policyType + "_" + String.format(polcyFileName) + "." + version + ".xml";
 		} 
-		if (fileName != null) {
-			newFile = Paths.get(parent.toString(), fileName);
-		}
-		if (Files.notExists(newFile)) {
+			
+		newFile = Paths.get(parent.toString(), fileName);
+		if (newFile.toFile().exists()) {
 			return newFile;
 		}
 		return null;
@@ -231,26 +230,28 @@
 		String policyDir = EMPTY_STRING;
 		String absolutePath = parentPath.toString();
 		if (absolutePath != null && !absolutePath.equals(EMPTY_STRING)) {
-			policyDir = absolutePath.substring(absolutePath.lastIndexOf("\\") + 1, absolutePath.length());
+			policyDir = absolutePath.substring(absolutePath.lastIndexOf('\\') + 1, absolutePath.length());
 			if (policyDir == null || policyDir.equals(EMPTY_STRING)) {
-				policyDir = absolutePath.substring(absolutePath.lastIndexOf("/") + 1, absolutePath.length());
+				policyDir = absolutePath.substring(absolutePath.lastIndexOf('/') + 1, absolutePath.length());
 			}
 		}
 
 		String fileName = "default";
 		if (policyDir != null && !policyDir.equals(EMPTY_STRING)) {
-			if(policyConfigType.equals("ClosedLoop_PM")){
+			if("ClosedLoop_PM".equals(policyConfigType)){
 				fileName = policyType + "_" + "PM" + "_" +java.lang.String.format(policyFileName) + "." +version +".xml";
-			}else if(policyConfigType.equals("ClosedLoop_Fault")){
+			}else if("ClosedLoop_Fault".equals(policyConfigType)){
 				fileName = policyType + "_" + "Fault" + "_" +java.lang.String.format(policyFileName) +  "." + version + ".xml";
-			}else if(policyConfigType.equals("Micro Service")){
+			}else if("Micro Service".equals(policyConfigType)){
 				fileName = policyType + "_" + "MS" + "_" + java.lang.String.format(policyFileName) + "." + version + ".xml";
+			}else if("Optimization".equals(policyConfigType)) {
+				fileName = policyType + "_" + "OOF" + "_" + java.lang.String.format(policyFileName) + "." + version + ".xml";
 			}
 		} 
-		if (fileName != null) {
-			newFile = Paths.get(parentPath.toString(), fileName);
-		}
-		if (Files.notExists(newFile)) {
+
+		newFile = Paths.get(parentPath.toString(), fileName);
+
+		if (newFile.toFile().exists()) {
 			return newFile;
 		}
 		return null;
diff --git a/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/controller/DictionaryImportController.java b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/controller/DictionaryImportController.java
index f3c78ff..9423017 100644
--- a/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/controller/DictionaryImportController.java
+++ b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/controller/DictionaryImportController.java
@@ -79,16 +79,21 @@
 	
 	private static CommonClassDao commonClassDao;
 	private static final String DESCRIPTION= "description";
+	private static final String ERROR= "Error";
+	private static final String DEPENDENCY= "dependency";
 	
 	@Autowired
 	public DictionaryImportController(CommonClassDao commonClassDao){
+		setCommonClassDao(commonClassDao);
+	}
+	
+	public static void setCommonClassDao(CommonClassDao commonClassDao) {
 		DictionaryImportController.commonClassDao = commonClassDao;
 	}
 	
 	public DictionaryImportController(){
-		super();
-	}	
-
+		super();	
+	}
 
 	@RequestMapping(value={"/dictionary/import_dictionary"}, method={RequestMethod.POST})
 	public void importDictionaryData(HttpServletRequest request, HttpServletResponse response) throws IOException{
@@ -100,15 +105,15 @@
 		if(dictionaryName == null || dictionaryName.isEmpty()){
 			LOGGER.error("dictionaryName is null/empty");
 			response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
-			response.getWriter().write("Error");
+			response.getWriter().write(ERROR);
 			return;
 		}
 		
 		// fix Fortify Path Manipulation issue
 		if(!isValidDictionaryName(dictionaryName)){
 			LOGGER.error("dictionaryName is invalid");
-			response.setStatus(HttpServletResponse.SC_OK);
-			response.getWriter().write("Dictionary Import failed. Hence the following dictionary doen't support import function  : "+ dictionaryName);
+			response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
+			response.getWriter().write(ERROR);
 			return;			
 		}
 		File file = new File(dictionaryName);	
@@ -230,7 +235,7 @@
 						if(DESCRIPTION.equalsIgnoreCase(dictSheet.get(0)[j])){
 							attribute.setDescription(rows[j]);
 						}
-						if("dependency".equalsIgnoreCase(dictSheet.get(0)[j])){
+						if(DEPENDENCY.equalsIgnoreCase(dictSheet.get(0)[j])){
 							attribute.setDependency(rows[j]);
 						}
 						if("attributes".equalsIgnoreCase(dictSheet.get(0)[j])){
@@ -245,6 +250,50 @@
 						if("Sub Attributes".equalsIgnoreCase(dictSheet.get(0)[j])){
 							attribute.setSub_attributes(rows[j]);
 						}
+						if("annotations".equalsIgnoreCase(dictSheet.get(0)[j])) {
+							attribute.setAnnotation(rows[j]);
+						}
+					}
+
+					commonClassDao.save(attribute);
+				}
+			}		
+
+			if(dictionaryName.startsWith("OptimizationPolicyDictionary")){
+				for(int i = 1; i< dictSheet.size(); i++){
+					MicroServiceModels attribute = new MicroServiceModels();
+					UserInfo userinfo = new UserInfo();
+					userinfo.setUserLoginId(userId);
+					attribute.setUserCreatedBy(userinfo);
+					String[] rows = dictSheet.get(i);
+					for (int j=0 ; j<rows.length; j++ ){
+						if("modelName".equalsIgnoreCase(dictSheet.get(0)[j]) || "Optimization Service Model".equalsIgnoreCase(dictSheet.get(0)[j])){
+							attribute.setModelName(rows[j]);
+						}
+						if("version".equalsIgnoreCase(dictSheet.get(0)[j]) || "Model Version".equalsIgnoreCase(dictSheet.get(0)[j])){
+							attribute.setVersion(rows[j]);
+						}
+						if(DESCRIPTION.equalsIgnoreCase(dictSheet.get(0)[j])){
+							attribute.setDescription(rows[j]);
+						}
+						if(DEPENDENCY.equalsIgnoreCase(dictSheet.get(0)[j])){
+							attribute.setDependency(rows[j]);
+						}
+						if("attributes".equalsIgnoreCase(dictSheet.get(0)[j])){
+							attribute.setAttributes(rows[j]);
+						}
+						if("enumValues".equalsIgnoreCase(dictSheet.get(0)[j])){
+							attribute.setEnumValues(rows[j]);
+						}
+						if("Ref Attributes".equalsIgnoreCase(dictSheet.get(0)[j])){
+							attribute.setRef_attributes(rows[j]);
+						}
+						if("Sub Attributes".equalsIgnoreCase(dictSheet.get(0)[j])){
+							attribute.setSub_attributes(rows[j]);
+						}
+						if("annotations".equalsIgnoreCase(dictSheet.get(0)[j])) {
+							attribute.setAnnotation(rows[j]);
+						}
 					}
 
 					commonClassDao.save(attribute);
@@ -427,7 +476,7 @@
 						if(DESCRIPTION.equalsIgnoreCase(dictSheet.get(0)[j])){
 							attribute.setDescription(rows[j]);
 						}
-						if("dependency".equalsIgnoreCase(dictSheet.get(0)[j])){
+						if(DEPENDENCY.equalsIgnoreCase(dictSheet.get(0)[j])){
 							attribute.setDependency(rows[j]);
 						}
 					}
@@ -677,7 +726,7 @@
 		}catch(Exception e){
 			LOGGER.error("Exception Occured while importing dictionary"+e);
 			response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
-			response.getWriter().write("Error");
+			response.getWriter().write(ERROR);
 		}finally{
 			if(file != null && file.exists()){
 				boolean deleted = file.delete();
@@ -696,6 +745,7 @@
 				case ActionPolicyDictionary:
 				case OnapName:
 				case MSPolicyDictionary:
+				case OptimizationPolicyDictionary:
 				case VNFType:
 				case VSCLAction:
 				case ClosedLoopService:
diff --git a/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/controller/MicroServiceDictionaryController.java b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/controller/MicroServiceDictionaryController.java
index becf5ad..6acae3f 100644
--- a/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/controller/MicroServiceDictionaryController.java
+++ b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/controller/MicroServiceDictionaryController.java
@@ -24,6 +24,7 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -44,6 +45,7 @@
 import org.onap.policy.rest.jpa.MicroServiceConfigName;
 import org.onap.policy.rest.jpa.MicroServiceLocation;
 import org.onap.policy.rest.jpa.MicroServiceModels;
+import org.onap.policy.rest.jpa.MicroserviceHeaderdeFaults;
 import org.onap.policy.rest.jpa.PrefixList;
 import org.onap.policy.rest.jpa.UserInfo;
 import org.onap.policy.rest.util.MSAttributeObject;
@@ -72,9 +74,11 @@
     private static String getDictionary = "getDictionary";
     private static String errorMsg = "error";
     private static String dictionaryDBQuery = "dictionaryDBQuery";
-    private HashMap<String,MSAttributeObject > classMap;
+    private LinkedHashMap<String,MSAttributeObject > classMap;
     private List<String> modelList = new ArrayList<>();
+    private static String apiflag = "apiflag";
 	private static String dictionaryFields ="dictionaryFields";
+	private static String update = "update";
 	private static String duplicateResponseString = "Duplicate";
 	private static String microServiceModelsDictionaryDatas = "microServiceModelsDictionaryDatas";
 	private static String modelName = "modelName";
@@ -86,6 +90,7 @@
 	private static String microServiceConfigNameDatas = "microServiceConfigNameDictionaryDatas";
 	private static String microServiceLocationDatas = "microServiceLocationDictionaryDatas";
 	private static String microServiceAttributeDatas = "microServiceAttributeDictionaryDatas";
+	private static String microServiceHeaderDefaultDatas = "microServiceHeaderDefaultDatas";
 
     public MicroServiceDictionaryController(){
     	super();
@@ -136,7 +141,7 @@
             
             List<Object> duplicateData =  commonClassDao.checkDuplicateEntry(dCAEuuid.getName(), "name", DCAEuuid.class);
 			boolean duplicateflag = false;
-			if(!duplicateData.isEmpty()){
+			if(duplicateData != null && !duplicateData.isEmpty()){
 				DCAEuuid data = (DCAEuuid) duplicateData.get(0);
 				if(request.getParameter(operation) != null && "update".equals(request.getParameter(operation))){
 					dCAEuuid.setId(data.getId());
@@ -201,7 +206,7 @@
             }
             List<Object> duplicateData =  commonClassDao.checkDuplicateEntry(microServiceConfigName.getName(), "name", MicroServiceConfigName.class);
 			boolean duplicateflag = false;
-			if(!duplicateData.isEmpty()){
+			if(duplicateData != null && !duplicateData.isEmpty()){
 				MicroServiceConfigName data = (MicroServiceConfigName) duplicateData.get(0);
 				if(request.getParameter(operation) != null && "update".equals(request.getParameter(operation))){
 					microServiceConfigName.setId(data.getId());
@@ -267,7 +272,7 @@
             
             List<Object> duplicateData =  commonClassDao.checkDuplicateEntry(microServiceLocation.getName(), "name", MicroServiceLocation.class);
 			boolean duplicateflag = false;
-			if(!duplicateData.isEmpty()){
+			if(duplicateData != null && !duplicateData.isEmpty()){
 				MicroServiceLocation data = (MicroServiceLocation) duplicateData.get(0);
 				if(request.getParameter(operation) != null && "update".equals(request.getParameter(operation))){
 					microServiceLocation.setId(data.getId());
@@ -329,16 +334,13 @@
             String checkValue;
             if (fromAPI) {
                 microServiceAttribute = mapper.readValue(root.get(dictionaryFields).toString(), MicroServiceAttribute.class);
-                MicroServiceAttribute initialAttribute = (MicroServiceAttribute)mapper.readValue(root.get("initialFields").toString(), MicroServiceAttribute.class);
-                checkValue = initialAttribute.getName() + ":" + initialAttribute.getValue() + ":" + initialAttribute.getModelName();
             } else {
                 microServiceAttribute = mapper.readValue(root.get("modelAttributeDictionaryData").toString(), MicroServiceAttribute.class);
-                checkValue = microServiceAttribute.getName() + ":" + microServiceAttribute.getValue() + ":" + microServiceAttribute.getModelName();
             }
-      
+            checkValue = microServiceAttribute.getName() + ":" + microServiceAttribute.getValue() + ":" + microServiceAttribute.getModelName();
             List<Object> duplicateData =  commonClassDao.checkDuplicateEntry(checkValue, "name:value:modelName", MicroServiceAttribute.class);
 			boolean duplicateflag = false;
-			if(!duplicateData.isEmpty()){
+			if(duplicateData != null && !duplicateData.isEmpty()){
 				MicroServiceAttribute data = (MicroServiceAttribute) duplicateData.get(0);
 				if(request.getParameter(operation) != null && "update".equals(request.getParameter(operation))){
 					microServiceAttribute.setId(data.getId());
@@ -472,6 +474,11 @@
 			JsonNode root = mapper.readTree(request.getReader());
 			MicroServiceModels microServiceModels = new MicroServiceModels();
 			String userId = null;
+			
+			String dataOrderInfo = null;
+			if(root.has("dataOrderInfo")){
+				dataOrderInfo = root.get("dataOrderInfo").toString();
+			}
 
 			if(root.has("modelType")){
 				JsonNode dataType = root.get("modelType");
@@ -491,7 +498,7 @@
 						}
 					}
 
-					classMap = new HashMap<>();
+					classMap = new LinkedHashMap<>();
 					JsonNode data = root.get(classMapData);
 					ObjectMapper mapper1 = new ObjectMapper();
 					String data1 = data.toString().substring(1, data.toString().length()-1);
@@ -513,11 +520,11 @@
 					this.newModel.setSub_attributes(value);
 					String attributes= mainClass.getAttribute().toString().replace("{", "").replace("}", "");
 					int equalsIndexForAttributes= attributes.indexOf('=');
-					String atttributesAfterFirstEquals= attributes.substring(equalsIndexForAttributes+1, attributes.length()-1);
+					String atttributesAfterFirstEquals= attributes.substring(equalsIndexForAttributes+1);
 					this.newModel.setAttributes(atttributesAfterFirstEquals);
 					String refAttributes= mainClass.getRefAttribute().toString().replace("{", "").replace("}", "");
-					int equalsIndex= refAttributes.indexOf('=');
-					String refAttributesAfterFirstEquals= refAttributes.substring(equalsIndex+1, refAttributes.length()-1);
+					int equalsIndex= refAttributes.indexOf("=");
+					String refAttributesAfterFirstEquals= refAttributes.substring(equalsIndex+1);
 					this.newModel.setRef_attributes(refAttributesAfterFirstEquals);
 					this.newModel.setEnumValues(mainClass.getEnumType().toString().replace("{", "").replace("}", ""));
 					this.newModel.setAnnotation(mainClass.getMatchingSet().toString().replace("{", "").replace("}", ""));
@@ -541,7 +548,7 @@
 							}
 						}
 						if(root.has(classMapData)){
-							classMap = new HashMap<>();
+							classMap = new LinkedHashMap<>();
 							JsonNode data = root.get(classMapData);
 							ObjectMapper mapper1 = new ObjectMapper();
 							String data1 = data.toString().substring(1, data.toString().length()-1);
@@ -567,11 +574,13 @@
 			microServiceModels.setVersion(this.newModel.getVersion());
 			microServiceModels.setEnumValues(this.newModel.getEnumValues());
 			microServiceModels.setAnnotation(this.newModel.getAnnotation());
-			
+			if(dataOrderInfo != null){
+				 microServiceModels.setDataOrderInfo(dataOrderInfo);
+			}
 			String checkName = microServiceModels.getModelName() + ":" + microServiceModels.getVersion();
 			List<Object> duplicateData =  commonClassDao.checkDuplicateEntry(checkName, "modelName:version", MicroServiceModels.class);
 			boolean duplicateflag = false;
-			if(!duplicateData.isEmpty()){
+			if(duplicateData != null && !duplicateData.isEmpty()){
 				MicroServiceModels data = (MicroServiceModels) duplicateData.get(0);
 				if(request.getParameter(operation) != null && "update".equals(request.getParameter(operation))){
 					microServiceModels.setId(data.getId());
@@ -667,5 +676,74 @@
 		
 		return returnList;
 	}
-
-}
+	
+	@RequestMapping(value={"/get_MicroServiceHeaderDefaultsDataByName"}, method={RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
+	public void getMicroServiceHeaderDefaultsEntityDataByName(HttpServletResponse response){
+		DictionaryUtils utils = getDictionaryUtilsInstance();
+		utils.getDataByEntity(response, microServiceHeaderDefaultDatas, "modelName", MicroserviceHeaderdeFaults.class);
+	}
+	
+    @RequestMapping(value={"/get_MicroServiceHeaderDefaultsData"}, method={RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
+    public void getMicroServiceHeaderDefaultsEntityData(HttpServletResponse response){
+		DictionaryUtils utils = getDictionaryUtilsInstance();
+		utils.getData(response, microServiceHeaderDefaultDatas, MicroserviceHeaderdeFaults.class);
+    }
+    
+    
+    @RequestMapping(value={"/ms_dictionary/save_headerDefaults"}, method={RequestMethod.POST})
+    public ModelAndView saveMicroServiceHeaderDefaultValues(HttpServletRequest request, HttpServletResponse response) throws IOException{
+    	DictionaryUtils utils = getDictionaryUtilsInstance();
+        try {
+        	boolean fromAPI = utils.isRequestFromAPI(request);
+			ObjectMapper mapper = new ObjectMapper();
+			mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+			JsonNode root = mapper.readTree(request.getReader());
+            
+            MicroserviceHeaderdeFaults msHeaderdeFaults;
+            if(fromAPI){
+            	msHeaderdeFaults = mapper.readValue(root.get(dictionaryFields).toString(), MicroserviceHeaderdeFaults.class);
+            }else{
+            	msHeaderdeFaults = mapper.readValue(root.get("modelAttributeDictionaryData").toString(), MicroserviceHeaderdeFaults.class);
+            }
+            
+            List<Object> duplicateData =  commonClassDao.checkDuplicateEntry(msHeaderdeFaults.getModelName(), "modelName", MicroserviceHeaderdeFaults.class);
+			boolean duplicateflag = false;
+			if(duplicateData != null && !duplicateData.isEmpty()){
+				MicroserviceHeaderdeFaults data = (MicroserviceHeaderdeFaults) duplicateData.get(0);
+				if(request.getParameter(operation) != null && "update".equals(request.getParameter(operation))){
+					msHeaderdeFaults.setId(data.getId());
+				}else if((request.getParameter(operation) != null && !"update".equals(request.getParameter(operation))) || 
+						(request.getParameter(operation) == null && (data.getId() != msHeaderdeFaults.getId()))){
+					duplicateflag = true;
+				}
+			}
+            
+			String responseString = null;
+			if(!duplicateflag){
+				if(msHeaderdeFaults.getId() == 0){
+					commonClassDao.save(msHeaderdeFaults);
+				}else{
+					commonClassDao.update(msHeaderdeFaults); 
+				} 
+				responseString = mapper.writeValueAsString(commonClassDao.getData(MicroserviceHeaderdeFaults.class));
+			}else{
+				responseString = duplicateResponseString;
+			}
+			if(fromAPI){
+				return utils.getResultForApi(responseString);
+			}else{
+				utils.setResponseData(response, microServiceHeaderDefaultDatas, responseString);
+			}
+        }
+        catch (Exception e){
+        	utils.setErrorResponseData(response, e);
+        }
+        return null;
+    }
+    
+    @RequestMapping(value={"/ms_dictionary/remove_headerDefaults"}, method={RequestMethod.POST})
+    public void removeMicroServiceHeaderDefaults(HttpServletRequest request, HttpServletResponse response) throws IOException{
+    	DictionaryUtils utils = getDictionaryUtilsInstance();
+		utils.removeData(request, response, microServiceHeaderDefaultDatas, MicroserviceHeaderdeFaults.class);
+    }
+}
\ No newline at end of file
diff --git a/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/controller/OptimizationDictionaryController.java b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/controller/OptimizationDictionaryController.java
new file mode 100644
index 0000000..acb5a2a
--- /dev/null
+++ b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/controller/OptimizationDictionaryController.java
@@ -0,0 +1,318 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2018 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.pap.xacml.rest.controller;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Set;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.lang.StringUtils;
+import org.json.JSONObject;
+import org.onap.policy.pap.xacml.rest.XACMLPapServlet;
+import org.onap.policy.pap.xacml.rest.util.DictionaryUtils;
+import org.onap.policy.rest.dao.CommonClassDao;
+import org.onap.policy.rest.jpa.OptimizationModels;
+import org.onap.policy.rest.jpa.UserInfo;
+import org.onap.policy.rest.util.MSAttributeObject;
+import org.onap.policy.rest.util.MSModelUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.servlet.ModelAndView;
+
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.gson.Gson;
+
+@Controller
+public class OptimizationDictionaryController {
+	private static CommonClassDao commonClassDao;
+	
+    private static String operation = "operation";
+    private LinkedHashMap<String,MSAttributeObject > classMap;
+	private static String dictionaryFields ="dictionaryFields";
+	private static String duplicateResponseString = "Duplicate";
+	private static String optimizationModelsDictionaryDatas = "optimizationModelsDictionaryDatas";
+	private static String modelName = "modelName";
+	private static String optimizationModelsDictionaryData = "optimizationModelsDictionaryData";
+	private static String description = "description";
+	private static String version = "version";
+	private static String classMapData = "classMap";
+	private static final String UPDATE = "update";
+
+
+    public OptimizationDictionaryController(){
+    	super();
+    }	
+	
+    private DictionaryUtils getDictionaryUtilsInstance(){
+		return DictionaryUtils.getDictionaryUtils();
+	}
+    
+	@Autowired
+	public OptimizationDictionaryController(CommonClassDao commonClassDao){
+		setCommonClassDao(commonClassDao);
+	}
+	public static void setCommonClassDao(CommonClassDao commonClassDao) {
+		OptimizationDictionaryController.commonClassDao = commonClassDao;
+	}
+
+	MSModelUtils utils = new MSModelUtils(XACMLPapServlet.getMsOnapName(), XACMLPapServlet.getMsPolicyName());
+	
+	private OptimizationModels newModel;
+	
+	@RequestMapping(value={"/get_OptimizationModelsData"}, method={RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
+	public void getOptimizationModelsDictionaryEntityData(HttpServletResponse response){
+		DictionaryUtils dUtils = getDictionaryUtilsInstance();
+		dUtils.getData(response, optimizationModelsDictionaryDatas, OptimizationModels.class);
+	}
+	
+	@RequestMapping(value={"/get_OptimizationModelsDataByName"}, method={RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
+	public void getOptimizationModelsDictionaryByNameEntityData(HttpServletResponse response){
+		DictionaryUtils dUtils = getDictionaryUtilsInstance();
+		dUtils.getDataByEntity(response, optimizationModelsDictionaryDatas, modelName, OptimizationModels.class);
+	}
+	
+	@RequestMapping(value={"/oof_dictionary/save_model"}, method={RequestMethod.POST})
+	public ModelAndView saveOptimizationModelsDictionary(HttpServletRequest request, HttpServletResponse response) throws IOException{
+		DictionaryUtils dUtils = getDictionaryUtilsInstance();
+		try {
+			this.newModel = new OptimizationModels();
+			boolean fromAPI = dUtils.isRequestFromAPI(request);
+			ObjectMapper mapper = new ObjectMapper();
+			mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+			JsonNode root = mapper.readTree(request.getReader());
+			OptimizationModels optimizationModels = new OptimizationModels();
+			String userId = null;
+			
+			String dataOrderInfo = null;
+			if(root.has("dataOrderInfo")){
+				dataOrderInfo = root.get("dataOrderInfo").toString();
+			}
+
+			if(root.has("modelType")){
+				JsonNode dataType = root.get("modelType");
+				String modelType= dataType.toString();
+				if(modelType.contains("yml")){
+					if (root.has(optimizationModelsDictionaryData)){
+						if (root.get(optimizationModelsDictionaryData).has(description)){
+							optimizationModels.setDescription(root.get(optimizationModelsDictionaryData).get(description).asText().replace("\"", ""));
+						}
+						if (root.get(optimizationModelsDictionaryData).has(modelName)){
+							optimizationModels.setModelName(root.get(optimizationModelsDictionaryData).get(modelName).asText().replace("\"", ""));
+							this.newModel.setModelName(optimizationModels.getModelName());
+						}
+						if (root.get(optimizationModelsDictionaryData).has(version)){
+							optimizationModels.setVersion(root.get(optimizationModelsDictionaryData).get(version).asText().replace("\"", ""));
+							this.newModel.setVersion(optimizationModels.getVersion());
+						}
+					}
+
+					classMap = new LinkedHashMap<>();
+					JsonNode data = root.get(classMapData);
+					ObjectMapper mapper1 = new ObjectMapper();
+					String data1 = data.toString().substring(1, data.toString().length()-1);
+					data1 = data1.replace("\\", "");
+					data1=data1.replace("\"{","{");
+					data1=data1.replace("}\"","}");
+					JSONObject jsonObject = new JSONObject(data1);
+					Set<String> keys = jsonObject.keySet();
+					for(String key : keys){
+						String value = jsonObject.get(key).toString();
+						MSAttributeObject msAttributeObject = mapper1.readValue(value, MSAttributeObject.class);
+						classMap.put(key, msAttributeObject);
+					}
+
+					userId = root.get("userid").textValue();
+					MSAttributeObject mainClass = classMap.get(this.newModel.getModelName());
+					this.newModel.setDependency("[]");
+					String value = new Gson().toJson(mainClass.getSubClass());
+					this.newModel.setSubattributes(value);
+					String attributes= mainClass.getAttribute().toString().replace("{", "").replace("}", "");
+					int equalsIndexForAttributes= attributes.indexOf('=');
+					String atttributesAfterFirstEquals= attributes.substring(equalsIndexForAttributes+1, attributes.length()-1);
+					this.newModel.setAttributes(atttributesAfterFirstEquals);
+					String refAttributes= mainClass.getRefAttribute().toString().replace("{", "").replace("}", "");
+					int equalsIndex= refAttributes.indexOf('=');
+					String refAttributesAfterFirstEquals= refAttributes.substring(equalsIndex+1, refAttributes.length()-1);
+					this.newModel.setRefattributes(refAttributesAfterFirstEquals);
+					this.newModel.setEnumValues(mainClass.getEnumType().toString().replace("{", "").replace("}", ""));
+					this.newModel.setAnnotation(mainClass.getMatchingSet().toString().replace("{", "").replace("}", ""));
+
+				}else{
+					if (fromAPI) {
+						optimizationModels = mapper.readValue(root.get(dictionaryFields).toString(), OptimizationModels.class);
+						userId = "API";
+					} else {
+						if (root.has(optimizationModelsDictionaryData)){
+							if (root.get(optimizationModelsDictionaryData).has(description)){
+								optimizationModels.setDescription(root.get(optimizationModelsDictionaryData).get(description).asText().replace("\"", ""));
+							}
+							if (root.get(optimizationModelsDictionaryData).has(modelName)){
+								optimizationModels.setModelName(root.get(optimizationModelsDictionaryData).get(modelName).asText().replace("\"", ""));
+								this.newModel.setModelName(optimizationModels.getModelName());
+							}
+							if (root.get(optimizationModelsDictionaryData).has(version)){
+								optimizationModels.setVersion(root.get(optimizationModelsDictionaryData).get(version).asText().replace("\"", ""));
+								this.newModel.setVersion(optimizationModels.getVersion());
+							}
+						}
+						if(root.has(classMapData)){
+							classMap = new LinkedHashMap<>();
+							JsonNode data = root.get(classMapData);
+							ObjectMapper mapper1 = new ObjectMapper();
+							String data1 = data.toString().substring(1, data.toString().length()-1);
+							data1 = data1.replace("\\", "");
+							JSONObject jsonObject = new JSONObject(data1);
+							Set<String> keys = jsonObject.keySet();
+							for(String key : keys){
+								String value = jsonObject.get(key).toString();
+								MSAttributeObject msAttributeObject = mapper1.readValue(value, MSAttributeObject.class);
+								classMap.put(key, msAttributeObject);
+							}
+						}
+						userId = root.get("userid").textValue();
+						addValuesToNewModel(classMap);
+					}
+				}		
+			}
+			optimizationModels.setAttributes(this.newModel.getAttributes());
+			optimizationModels.setRefattributes(this.newModel.getRefattributes());
+			optimizationModels.setDependency(this.newModel.getDependency());
+			optimizationModels.setModelName(this.newModel.getModelName());
+			optimizationModels.setSubattributes(this.newModel.getSubattributes());
+			optimizationModels.setVersion(this.newModel.getVersion());
+			optimizationModels.setEnumValues(this.newModel.getEnumValues());
+			optimizationModels.setAnnotation(this.newModel.getAnnotation());
+			
+			if(dataOrderInfo != null){
+				optimizationModels.setDataOrderInfo(dataOrderInfo);
+			}
+			
+			String checkName = optimizationModels.getModelName() + ":" + optimizationModels.getVersion();
+			List<Object> duplicateData =  commonClassDao.checkDuplicateEntry(checkName, "modelName:version", OptimizationModels.class);
+			boolean duplicateflag = false;
+			if(duplicateData!=null && !duplicateData.isEmpty()){
+				OptimizationModels data = (OptimizationModels) duplicateData.get(0);
+				if(request.getParameter(operation) != null && UPDATE.equals(request.getParameter(operation))){
+					optimizationModels.setId(data.getId());
+				}else if((request.getParameter(operation) != null && !UPDATE.equals(request.getParameter(operation))) || 
+						(request.getParameter(operation) == null && (data.getId() != optimizationModels.getId()))){
+					duplicateflag = true;
+				}
+			}
+			UserInfo userInfo = dUtils.getUserInfo(userId);
+			
+			String responseString = null;
+			if(!duplicateflag){
+				optimizationModels.setUserCreatedBy(userInfo);
+				if(optimizationModels.getId() == 0){
+					commonClassDao.save(optimizationModels);
+				}else{
+					commonClassDao.update(optimizationModels); 
+				} 
+				responseString = mapper.writeValueAsString(commonClassDao.getData(OptimizationModels.class));
+			}else{
+				responseString = duplicateResponseString;
+			}
+			if(fromAPI){
+				return dUtils.getResultForApi(responseString);
+			}else{
+				dUtils.setResponseData(response, optimizationModelsDictionaryDatas, responseString);
+			}
+		}catch (Exception e){
+			dUtils.setErrorResponseData(response, e);
+		}
+		return null;
+	}
+
+	@RequestMapping(value={"/oof_dictionary/remove_model"}, method={RequestMethod.POST})
+	public void removeOptimizationModelsDictionary(HttpServletRequest request, HttpServletResponse response) throws IOException {
+		DictionaryUtils dUtils = getDictionaryUtilsInstance();
+		dUtils.removeData(request, response, optimizationModelsDictionaryDatas, OptimizationModels.class);
+	}
+		
+	private void addValuesToNewModel(HashMap<String,MSAttributeObject > classMap) {
+		//Loop  through the classmap and pull out the required info for the new file.
+		String subAttribute = null;
+		
+		MSAttributeObject mainClass = classMap.get(this.newModel.getModelName());
+		
+		if (mainClass !=null){
+			String dependTemp = StringUtils.replaceEach(mainClass.getDependency(), new String[]{"[", "]", " "}, new String[]{"", "", ""});
+			ArrayList<String> dependency = new ArrayList<>(Arrays.asList(dependTemp.split(",")));	
+			dependency = getFullDependencyList(dependency);
+			for (String element : dependency){
+				MSAttributeObject temp = classMap.get(element);
+				if (temp!=null){
+					mainClass.addAllRefAttribute(temp.getRefAttribute());
+					mainClass.addAllAttribute(temp.getAttribute());
+				}
+			}
+			subAttribute = utils.createSubAttributes(dependency, classMap, this.newModel.getModelName());
+		}else{
+			subAttribute = "{}";
+			this.newModel.setDependency("");
+		}
+
+		if (mainClass != null && mainClass.getDependency()==null){
+			mainClass.setDependency("");
+		}
+		if(mainClass != null){
+			this.newModel.setDependency(mainClass.getDependency());
+			this.newModel.setSubattributes(subAttribute);
+			this.newModel.setAttributes(mainClass.getAttribute().toString().replace("{", "").replace("}", ""));
+			this.newModel.setRefattributes(mainClass.getRefAttribute().toString().replace("{", "").replace("}", ""));
+			this.newModel.setEnumValues(mainClass.getEnumType().toString().replace("{", "").replace("}", ""));
+			this.newModel.setAnnotation(mainClass.getMatchingSet().toString().replace("{", "").replace("}", ""));
+		}
+	} 
+	
+	private ArrayList<String> getFullDependencyList(ArrayList<String> dependency) {
+		ArrayList<String> returnList = new ArrayList<>();
+		ArrayList<String> workingList;
+		returnList.addAll(dependency);
+		for (String element : dependency ){
+			if (classMap.containsKey(element)){
+				MSAttributeObject value = classMap.get(element);			
+				String rawValue = StringUtils.replaceEach(value.getDependency(), new String[]{"[", "]"}, new String[]{"", ""});
+				workingList = new ArrayList<>(Arrays.asList(rawValue.split(",")));	
+				for(String depend : workingList){
+					if (!returnList.contains(depend) && !depend.isEmpty()){
+						returnList.add(depend.trim());
+					}
+				}
+			}
+		}
+		
+		return returnList;
+	}
+
+}
diff --git a/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/elk/client/ElkConnector.java b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/elk/client/ElkConnector.java
index 1dea5dd..83d5c3f 100644
--- a/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/elk/client/ElkConnector.java
+++ b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/elk/client/ElkConnector.java
@@ -47,6 +47,7 @@
 		Config_PM,
 		Config_FW,
 		Config_MS,
+		Config_OOF,
 		none,
 	}
 	
@@ -85,6 +86,8 @@
 			return PolicyIndexType.config;
 		} else if (policyName.startsWith("Config_MS")) {
 			return PolicyIndexType.config;
+		} else if (policyName.startsWith("Config_OOF")) {
+			return PolicyIndexType.config;
 		}else if (policyName.startsWith("Action")) {
 			return PolicyIndexType.action;
 		} else if (policyName.startsWith("Decision")) {
diff --git a/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/handler/APIRequestHandler.java b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/handler/APIRequestHandler.java
index a031ac6..db77110 100644
--- a/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/handler/APIRequestHandler.java
+++ b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/handler/APIRequestHandler.java
@@ -60,7 +60,7 @@
 	}
 
 	public void doPut(HttpServletRequest request, HttpServletResponse response, String service) throws IOException {
-		if ("MICROSERVICE".equalsIgnoreCase(service) || "BRMSPARAM".equalsIgnoreCase(service)){
+		if ("MICROSERVICE".equalsIgnoreCase(service) || "BRMSPARAM".equalsIgnoreCase(service) || "OPTIMIZATION".equalsIgnoreCase(service)){
 			ImportService importService = new ImportService();
 			importService.doImportMicroServicePut(request, response);
 			return;
diff --git a/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/handler/DictionaryHandlerImpl.java b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/handler/DictionaryHandlerImpl.java
index f1cc9e6..d0cd985 100644
--- a/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/handler/DictionaryHandlerImpl.java
+++ b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/handler/DictionaryHandlerImpl.java
@@ -117,6 +117,12 @@
 			case "MicroServiceModels":
 				dictionary.getMicroServiceModelsDictionary(response);
 				break;
+			case "MicroServiceDictionary":
+				dictionary.getMicroServiceDictionary(response);
+				break;
+			case "OptimizationModels":
+				dictionary.getOptimizationModelsDictionary(response);
+				break;
 			case "PolicyScopeService":
 				dictionary.getPSServiceDictionary(response);
 				break;
@@ -138,9 +144,6 @@
 			case "SafePolicyWarning":
 				dictionary.getSafePolicyWarningDictionary(response);
 				break;
-			case "MicroServiceDictionary":
-				dictionary.getMicroServiceDictionary(response);
-				break;
 			default:
 				extendedOptions(dictionaryType, request, response, true);
 				return;
@@ -260,6 +263,12 @@
 			case "MicroServiceModels":
 				result = dictionary.saveMicroServiceModelsDictionary(request, response);
 				break;
+			case "MicroServiceDictionary":
+				result = dictionary.saveMicroServiceDictionary(request, response);
+				break;
+			case "OptimizationModels":
+				result = dictionary.saveOptimizationModelsDictionary(request, response);
+				break;
 			case "PolicyScopeService":
 				result = dictionary.savePSServiceDictionary(request, response);
 				break;
@@ -281,9 +290,6 @@
 			case "SafePolicyWarning":
 				result = dictionary.saveSafePolicyWarningDictionary(request, response);
 				break;
-			case "MicroServiceDictionary":
-				result = dictionary.saveMicroServiceDictionary(request, response);
-				break;
 			default:
 				result = extendedOptions(dictionaryType, request, response, false);
 				if(result==null){
diff --git a/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/policycontroller/PolicyCreation.java b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/policycontroller/PolicyCreation.java
index 48f67aa..f7ef1a0 100644
--- a/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/policycontroller/PolicyCreation.java
+++ b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/policycontroller/PolicyCreation.java
@@ -44,6 +44,7 @@
 import org.onap.policy.pap.xacml.rest.components.DecisionPolicy;
 import org.onap.policy.pap.xacml.rest.components.FirewallConfigPolicy;
 import org.onap.policy.pap.xacml.rest.components.MicroServiceConfigPolicy;
+import org.onap.policy.pap.xacml.rest.components.OptimizationConfigPolicy;
 import org.onap.policy.pap.xacml.rest.components.Policy;
 import org.onap.policy.pap.xacml.rest.components.PolicyDBDao;
 import org.onap.policy.pap.xacml.rest.components.PolicyDBDaoTransaction;
@@ -133,6 +134,8 @@
 					filePrefix = "Config_PM_";
 				}else if ("Micro Service".equalsIgnoreCase(policyConfigType)) {
 					filePrefix = "Config_MS_";
+				}else if ("Optimization".equalsIgnoreCase(policyConfigType)) {
+					filePrefix = "Config_OOF_";
 				}else if ("BRMS_Raw".equalsIgnoreCase(policyConfigType)) {
 					filePrefix = "Config_BRMS_Raw_";
 				}else if ("BRMS_Param".equalsIgnoreCase(policyConfigType)) {
@@ -247,14 +250,14 @@
 			policyData.setHighestVersion(version);
 
 			// Calling Component class per policy type
-			if (policyType.equalsIgnoreCase("Config")) {
-				if (policyConfigType.equalsIgnoreCase("Firewall Config")) {
+			if ("Config".equalsIgnoreCase(policyType)) {
+				if ("Firewall Config".equalsIgnoreCase(policyConfigType)) {
 					newPolicy = new FirewallConfigPolicy(policyData);
-				}else if (policyConfigType.equalsIgnoreCase("BRMS_Raw")) { 
+				}else if ("BRMS_Raw".equalsIgnoreCase(policyConfigType)) { 
 					policyData.setOnapName("DROOLS");
 					policyData.setConfigName("BRMS_RAW_RULE");
 					newPolicy = new CreateBrmsRawPolicy(policyData);
-				}else if (policyConfigType.equalsIgnoreCase("BRMS_Param")) {
+				}else if ("BRMS_Param".equalsIgnoreCase(policyConfigType)) {
 					policyData.setOnapName("DROOLS");
 					policyData.setConfigName("BRMS_PARAM_RULE");
 					Map<String, String> drlRuleAndUIParams = new HashMap<>();
@@ -287,11 +290,11 @@
 		                }
 					}		
 					newPolicy = new CreateBrmsParamPolicy(policyData);
-				}else if (policyConfigType.equalsIgnoreCase("Base")) {
+				}else if ("Base".equalsIgnoreCase(policyConfigType)) {
 					newPolicy =  new ConfigPolicy(policyData);
-				}else if (policyConfigType.equalsIgnoreCase("ClosedLoop_Fault")) {
+				}else if ("ClosedLoop_Fault".equalsIgnoreCase(policyConfigType)) {
 					newPolicy = new ClosedLoopPolicy(policyData);
-				}else if (policyConfigType.equalsIgnoreCase("ClosedLoop_PM")) {
+				}else if ("ClosedLoop_PM".equalsIgnoreCase(policyConfigType)) {
 					if(policyData.getApiflag() == null){
 						policyData.setServiceType(policyData.getServiceTypePolicyName().get("serviceTypePolicyName").toString());
 						ObjectMapper jsonMapper = new ObjectMapper();
@@ -301,10 +304,12 @@
 						policyData.setJsonBody(jsonBody);
 					}
 					newPolicy = new CreateClosedLoopPerformanceMetrics(policyData);
-				}else if (policyConfigType.equalsIgnoreCase("Micro Service")) {
+				}else if ("Micro Service".equalsIgnoreCase(policyConfigType)) {
 					newPolicy = new MicroServiceConfigPolicy(policyData);
+				}else if ("Optimization".equalsIgnoreCase(policyConfigType)) {
+					newPolicy = new OptimizationConfigPolicy(policyData);
 				}
-			}else if(policyType.equalsIgnoreCase("Action")) {
+			}else if("Action".equalsIgnoreCase(policyType)) {
 				if(policyData.getApiflag() == null){
 					List<String> dynamicRuleAlgorithmLabels = new LinkedList<>();
 					List<String> dynamicRuleAlgorithmCombo = new LinkedList<>();
@@ -361,7 +366,7 @@
 					}
 				}
 				newPolicy = new ActionPolicy(policyData, commonClassDao);
-			} else if (policyType.equalsIgnoreCase("Decision")) {
+			} else if ("Decision".equalsIgnoreCase(policyType)) {
 				if(policyData.getApiflag() == null){
 					Map<String, String> settingsMap = new HashMap<>();
 					Map<String, String> treatmentMap = new HashMap<>();
diff --git a/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/service/DictionaryService.java b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/service/DictionaryService.java
index 00ae10f..cb03d44 100644
--- a/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/service/DictionaryService.java
+++ b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/service/DictionaryService.java
@@ -32,6 +32,7 @@
 import org.onap.policy.pap.xacml.rest.controller.DictionaryController;
 import org.onap.policy.pap.xacml.rest.controller.FirewallDictionaryController;
 import org.onap.policy.pap.xacml.rest.controller.MicroServiceDictionaryController;
+import org.onap.policy.pap.xacml.rest.controller.OptimizationDictionaryController;
 import org.onap.policy.pap.xacml.rest.controller.PolicyScopeDictionaryController;
 import org.onap.policy.pap.xacml.rest.controller.SafePolicyController;
 import org.springframework.stereotype.Service;
@@ -236,6 +237,13 @@
 		return result.getViewName();
 	}
 	
+	public String saveOptimizationModelsDictionary(HttpServletRequest request, HttpServletResponse response) throws IOException{
+		
+		OptimizationDictionaryController dictionary = new OptimizationDictionaryController();
+			ModelAndView result = dictionary.saveOptimizationModelsDictionary(request, response);
+		return result.getViewName();
+	}
+	
 	public String savePSServiceDictionary(HttpServletRequest request, HttpServletResponse response) throws IOException{
 		
 		PolicyScopeDictionaryController dictionary = new PolicyScopeDictionaryController();
@@ -424,6 +432,11 @@
 			dictionary.getMicroServiceModelsDictionaryEntityData(response);
 	}
 	
+	public void getOptimizationModelsDictionary(HttpServletResponse response){
+		OptimizationDictionaryController dictionary = new OptimizationDictionaryController();
+			dictionary.getOptimizationModelsDictionaryEntityData(response);
+	}
+	
 	public void getPSServiceDictionary(HttpServletResponse response){
 		PolicyScopeDictionaryController dictionary = new PolicyScopeDictionaryController();
 			dictionary.getPSServiceEntityData(response);
diff --git a/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/service/ImportService.java b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/service/ImportService.java
index c804f2b..7382a77 100644
--- a/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/service/ImportService.java
+++ b/ONAP-PAP-REST/src/main/java/org/onap/policy/pap/xacml/rest/service/ImportService.java
@@ -38,6 +38,7 @@
 import org.onap.policy.common.logging.flexlogger.Logger;
 import org.onap.policy.pap.xacml.rest.components.CreateBRMSRuleTemplate;
 import org.onap.policy.pap.xacml.rest.components.CreateNewMicroServiceModel;
+import org.onap.policy.pap.xacml.rest.components.CreateNewOptimizationModel;
 
 public class ImportService {
 	private static final Logger logger = FlexLogger.getLogger(ImportService.class);
@@ -50,6 +51,7 @@
 	private static String successMessage = "success";
 	private static String invalidServiceName = "Invalid ServiceName";
 	private static final String REGEX = "[0-9a-zA-Z._ ]*";
+	private static final String MISSING = "missing";
 	
 	public void doImportMicroServicePut(HttpServletRequest request, HttpServletResponse response) {
 		String importServiceCreation = request.getParameter("importService");
@@ -59,7 +61,7 @@
 		
 		if(serviceName == null || serviceName.isEmpty() || !serviceName.matches(REGEX)){
 			response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
-			response.addHeader(errorMsg, "missing");	
+			response.addHeader(errorMsg, MISSING);	
 			response.addHeader(operation, importHeader);
 			response.addHeader(service, invalidServiceName);
 			return;
@@ -78,7 +80,7 @@
 				logger.error(e);
 				PolicyLogger.error(errorMessage);
 				response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
-				response.addHeader(errorMsg, "missing");	
+				response.addHeader(errorMsg, MISSING);	
 				response.addHeader(operation, importHeader);
 				response.addHeader(service, serviceName);
 			}
@@ -88,12 +90,16 @@
 		else if(("MICROSERVICE").equals(importServiceCreation)){
 			CreateNewMicroServiceModel newMS = null;
 			String randomID = UUID.randomUUID().toString();
+			String type = ".xmi"; 
 			if ( fileName != null) {
 				File extracDir = new File(extractDir);
 				if (!extracDir.exists()){
 					extracDir.mkdirs();
 				}
-				if (fileName.contains(".xmi")){
+				if (fileName.contains(".xmi") || fileName.contains(".yml")){
+					if(fileName.contains(".yml")){
+						type = ".yml";
+					}
 					// get the request content into a String
 					String xmi = null;
 					java.util.Scanner scanner;
@@ -107,9 +113,9 @@
 						PolicyLogger.error(errorMessage);
 						return;
 					}
-					PolicyLogger.info("XML request from API for import new Service"); 
+					PolicyLogger.info("Request from API to import new Service"); 
 					try (Writer writer = new BufferedWriter(new OutputStreamWriter(
-							new FileOutputStream(extractDir + File.separator + randomID+".xmi"), "utf-8"))) {
+							new FileOutputStream(extractDir + File.separator + randomID+type), "utf-8"))) {
 						writer.write(xmi);
 					} catch (IOException e) {
 						logger.error(e);
@@ -138,13 +144,54 @@
 						}
 					}
 				}
+				
 				newMS =  new CreateNewMicroServiceModel(fileName, serviceName, "API", version, randomID);
-				successMap = newMS.addValuesToNewModel();
+				
+				successMap = newMS.addValuesToNewModel(type);
+				
 				if (successMap.containsKey(successMessage)) {
 					successMap.clear();
 					successMap = newMS.saveImportService();
 				}
 			}
+		} else if(("OPTIMIZATION").equals(importServiceCreation)){
+			CreateNewOptimizationModel newOOF = null;
+			String randomID = UUID.randomUUID().toString();
+			if ( fileName != null) {
+				File extracDir = new File(extractDir);
+				if (!extracDir.exists()){
+					extracDir.mkdirs();
+				}
+				
+				String type = ".yml";
+				
+				// get the request content into a String
+				String yml = null;
+				try (java.util.Scanner scanner = new java.util.Scanner(request.getInputStream());){
+					scanner.useDelimiter("\\A");
+					yml =  scanner.hasNext() ? scanner.next() : "";
+				} catch (IOException e1) {
+					logger.error(e1);
+					PolicyLogger.error(errorMessage);
+					return;
+				}
+				PolicyLogger.info("Request from API to import new Optimization Service Model"); 
+				try (Writer writer = new BufferedWriter(new OutputStreamWriter(
+						new FileOutputStream(extractDir + File.separator + randomID+type), "utf-8"))) {
+					writer.write(yml);
+				} catch (IOException e) {
+					logger.error(e);
+					PolicyLogger.error(errorMessage);
+					return;
+				}
+				
+				newOOF =  new CreateNewOptimizationModel(fileName, serviceName, "API Import Service", version, randomID);
+				successMap = newOOF.addValuesToNewModel();
+				if (successMap.containsKey(successMessage)) {
+					successMap.clear();
+					successMap = newOOF.saveImportService();
+				}
+			}
 		}
 		
 		// return a response to the PAP		    
@@ -166,7 +213,7 @@
 			response.addHeader(service, serviceName);
 		}else if (successMap.get(errorMsg).contains("MISSING")){
 			response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
-			response.addHeader(errorMsg, "missing");	
+			response.addHeader(errorMsg, MISSING);	
 			response.addHeader(operation, importHeader);
 			response.addHeader(service, serviceName);
 		}else if (successMap.get(errorMsg).contains("VALIDATION")){
diff --git a/ONAP-PAP-REST/src/test/java/org/onap/policy/pap/xacml/rest/components/MicroServicePolicyTest.java b/ONAP-PAP-REST/src/test/java/org/onap/policy/pap/xacml/rest/components/MicroServicePolicyTest.java
index 39b21f1..a47c2be 100644
--- a/ONAP-PAP-REST/src/test/java/org/onap/policy/pap/xacml/rest/components/MicroServicePolicyTest.java
+++ b/ONAP-PAP-REST/src/test/java/org/onap/policy/pap/xacml/rest/components/MicroServicePolicyTest.java
@@ -105,7 +105,7 @@
 		String testFileName = "testFile.zip";
 		String testVal = "testVal";
 		CreateNewMicroServiceModel model = new CreateNewMicroServiceModel(testFileName, testVal, testVal, testVal, testVal);
-		model.addValuesToNewModel();
+		model.addValuesToNewModel(".xmi");
 		model.saveImportService();
 	}
 }
diff --git a/ONAP-PAP-REST/src/test/java/org/onap/policy/pap/xacml/rest/components/OptimizationConfigPolicyTest.java b/ONAP-PAP-REST/src/test/java/org/onap/policy/pap/xacml/rest/components/OptimizationConfigPolicyTest.java
new file mode 100644
index 0000000..7b9be68
--- /dev/null
+++ b/ONAP-PAP-REST/src/test/java/org/onap/policy/pap/xacml/rest/components/OptimizationConfigPolicyTest.java
@@ -0,0 +1,105 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2018 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.pap.xacml.rest.components;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.fail;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.when;
+import static org.mockito.Matchers.any;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+import org.onap.policy.pap.xacml.rest.daoimpl.CommonClassDaoImpl;
+import org.onap.policy.rest.adapter.PolicyRestAdapter;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+import java.io.File;
+import java.util.Collections;
+
+@RunWith(PowerMockRunner.class)
+public class OptimizationConfigPolicyTest {
+	@Rule
+    public ExpectedException thrown = ExpectedException.none();
+
+	@Test
+	public void testConstructor1() {
+		thrown.expect(NullPointerException.class);
+		OptimizationConfigPolicy policy = new OptimizationConfigPolicy();
+		policy.getCorrectPolicyDataObject();
+		fail("Expected an exception");
+	}
+	
+	@Test
+	public void testConstructor2() {
+		PolicyRestAdapter policyAdapter = new PolicyRestAdapter();
+		OptimizationConfigPolicy policy = new OptimizationConfigPolicy(policyAdapter);
+		assertNull(policy.getCorrectPolicyDataObject());
+	}
+	
+	@PrepareForTest({OptimizationConfigPolicy.class})
+	@Test
+	public void testPrepareToSave() throws Exception {
+		// Need to mock internal dictionary retrieval
+		CommonClassDaoImpl impl = Mockito.mock(CommonClassDaoImpl.class);
+		PowerMockito.whenNew(CommonClassDaoImpl.class).withNoArguments().thenReturn(impl);
+		when(impl.getDataById(any(), anyString(), anyString())).thenReturn(null);
+		
+		PolicyRestAdapter policyAdapter = new PolicyRestAdapter();
+		OptimizationConfigPolicy policy = new OptimizationConfigPolicy(policyAdapter);
+		policyAdapter.setHighestVersion(1);
+		policyAdapter.setPolicyType("Config");
+		policyAdapter.setNewFileName("foo.xml");
+		policyAdapter.setJsonBody("{ \"version\": \"1.0\"}");
+		policyAdapter.setServiceType("foo");
+		policy.prepareToSave();
+		assertEquals(true, policy.isPreparedToSave());
+	}
+	
+	@PrepareForTest({CreateNewOptimizationModel.class})
+	@Test
+	public void testCreateModel() throws Exception {
+		// Mock file retrieval
+		File testFile = new File("testFile");
+		File[] testList = new File[1];
+		testList[0] = testFile;
+		File impl = Mockito.mock(File.class);
+		PowerMockito.whenNew(File.class).withAnyArguments().thenReturn(impl);
+		when(impl.listFiles()).thenReturn(testList);
+		when(impl.isFile()).thenReturn(true);
+
+		// Mock internal dictionary retrieval
+		CommonClassDaoImpl daoImpl = Mockito.mock(CommonClassDaoImpl.class);
+		PowerMockito.whenNew(CommonClassDaoImpl.class).withNoArguments().thenReturn(daoImpl);
+		when(daoImpl.getDataById(any(), anyString(), anyString())).thenReturn(Collections.emptyList());
+
+		// Test create methods
+		String testFileName = "testFile.zip";
+		String testVal = "testVal";
+		CreateNewOptimizationModel model = new CreateNewOptimizationModel(testFileName, testVal, testVal, testVal, testVal);
+		model.addValuesToNewModel();
+		model.saveImportService();
+	}
+}
diff --git a/ONAP-PAP-REST/src/test/java/org/onap/policy/pap/xacml/rest/controller/DictionaryImportControllerTest.java b/ONAP-PAP-REST/src/test/java/org/onap/policy/pap/xacml/rest/controller/DictionaryImportControllerTest.java
index 7c1c507..6a28c27 100644
--- a/ONAP-PAP-REST/src/test/java/org/onap/policy/pap/xacml/rest/controller/DictionaryImportControllerTest.java
+++ b/ONAP-PAP-REST/src/test/java/org/onap/policy/pap/xacml/rest/controller/DictionaryImportControllerTest.java
@@ -42,15 +42,15 @@
 import org.onap.policy.rest.dao.CommonClassDao;
 import org.springframework.mock.web.MockHttpServletResponse;
 
-public class DictionaryImportControllerTest  extends Mockito{
+public class DictionaryImportControllerTest extends Mockito{
 	
 	private static Logger logger = FlexLogger.getLogger(DictionaryImportController.class);
-
+	
 	private static CommonClassDao commonClassDao;
 	private HttpServletRequest request = null;
 	private HttpServletResponse response = null;
 	private DictionaryImportController controller = null;
-	
+
 	@Before
 	public void setUp() throws Exception {
 		logger.info("setUp: Entering");
@@ -59,7 +59,7 @@
 		controller = new DictionaryImportController(); 
 		new DictionaryImportController(commonClassDao);
 		request = Mockito.mock(HttpServletRequest.class);
-		response =  new MockHttpServletResponse();
+		response =  new MockHttpServletResponse();	
 	}
 	
 	@Test
@@ -70,7 +70,7 @@
 		//test valid name
 		assertTrue(cotroller.isValidDictionaryName("ActionList"));
 	}
-	
+
 	@Test
 	public void testImportDictionaryData() throws ServletException, IOException{
 		List<String> fileNames = new ArrayList<>();
@@ -78,6 +78,7 @@
 		fileNames.add("ActionPolicyDictionary.csv");
 		fileNames.add("OnapName.csv");
 		fileNames.add("MSPolicyDictionary.csv");
+		fileNames.add("OptimizationPolicyDictionary.csv");
 		fileNames.add("ClosedLoopService.csv");
 		fileNames.add("ClosedLoopSite.csv");
 		fileNames.add("VarbindDictionary.csv");
@@ -113,7 +114,7 @@
 		}
 		when(request.getParameter("dictionaryName")).thenReturn("WrongName");
 		controller.importDictionaryData(request, response);
-		assertTrue(HttpServletResponse.SC_OK == response.getStatus());
+		assertTrue(HttpServletResponse.SC_BAD_REQUEST == response.getStatus());
 		
 		when(request.getParameter("dictionaryName")).thenReturn("");
 		controller.importDictionaryData(request, response);
diff --git a/ONAP-PAP-REST/src/test/java/org/onap/policy/pap/xacml/rest/controller/MicroServiceDictionaryControllerTest.java b/ONAP-PAP-REST/src/test/java/org/onap/policy/pap/xacml/rest/controller/MicroServiceDictionaryControllerTest.java
index 36335ae..ae71692 100644
--- a/ONAP-PAP-REST/src/test/java/org/onap/policy/pap/xacml/rest/controller/MicroServiceDictionaryControllerTest.java
+++ b/ONAP-PAP-REST/src/test/java/org/onap/policy/pap/xacml/rest/controller/MicroServiceDictionaryControllerTest.java
@@ -114,6 +114,98 @@
         logger.info("setUp: exit");
 	}
 
+	
+	@Test
+	public void testSaveMicroServiceHeaderDefaultValues() {
+		logger.info("testSaveMicroServiceHeaderDefaultValues: Entering");
+
+		MockHttpServletResponse response =  new MockHttpServletResponse();
+	    request = mock(HttpServletRequest.class);   
+	
+		try {
+		    // mock the getReader() call
+			jsonString = "{\"modelAttributeDictionaryData\": {\"onapName\": \"test\",	\"guard\": false,\"priority\": \"3\","
+					+ " \"riskType\": \"test\", \"riskLevel\": \"7\", \"modelName\": \"testname\"}}";
+			BufferedReader br = new BufferedReader(new StringReader(jsonString));
+			when(request.getReader()).thenReturn(br); 		    
+			controller.saveMicroServiceHeaderDefaultValues(request, response);
+			logger.info("response.getContentAsString(): " + response.getContentAsString());
+			assertTrue( response.getContentAsString() != null && response.getContentAsString().contains("microServiceHeaderDefaultDatas"));
+
+		} catch (Exception e) {
+			fail("Exception: " + e);
+		}
+		
+		logger.info("testSaveMicroServiceHeaderDefaultValues: exit");
+	}
+	
+	
+	@Test
+	public void testGetMicroServiceHeaderDefaultsEntityDataByName() {
+		logger.info("testGetMicroServiceHeaderDefaultsEntityDataByName: Entering");
+
+		MockHttpServletResponse response =  new MockHttpServletResponse();
+		
+		controller.getMicroServiceHeaderDefaultsEntityDataByName(response);
+		
+		try {
+			assertTrue( response.getContentAsString() != null && response.getContentAsString().contains("microServiceHeaderDefaultDatas"));
+			logger.info("response.getContentAsString(): " + response.getContentAsString());
+		} catch (UnsupportedEncodingException e) {
+			fail("Exception: " + e);
+		}
+		
+		logger.info("testGetMicroServiceHeaderDefaultsEntityDataByName: exit");
+	}
+
+	@Test
+	public void testGetMicroServiceHeaderDefaultsEntityData() {
+		logger.info("testGetMicroServiceHeaderDefaultsEntityData: Entering");
+
+		MockHttpServletResponse response =  new MockHttpServletResponse();
+		
+		controller.getMicroServiceHeaderDefaultsEntityData(response);
+		
+		try {
+			assertTrue( response.getContentAsString() != null && response.getContentAsString().contains("microServiceHeaderDefaultDatas"));
+			logger.info("response.getContentAsString(): " + response.getContentAsString());
+		} catch (UnsupportedEncodingException e) {
+			fail("Exception: " + e);
+		}
+		
+		logger.info("testGetMicroServiceHeaderDefaultsEntityData: exit");
+	}
+	
+	@Test
+	public void testRemoveMicroServiceHeaderDefaults() {
+		logger.info("testRemoveMicroServiceHeaderDefaults: Entering");
+
+		MockHttpServletResponse response =  new MockHttpServletResponse();
+	    request = mock(HttpServletRequest.class);   
+	
+		try {
+		    // mock the getReader() call
+			jsonString = "{\"data\": {\"modelName\": \"test\",	\"inprocess\": false,\"model\": {\"name\": \"testingdata\", "
+					+ " \"subScopename\": \"\",\"path\": [],\"type\": \"dir\",\"size\": 0,\"date\": \"2017-04-12T21:26:57.000Z\", "
+					+ " \"version\": \"\",\"createdBy\": \"someone\",	\"modifiedBy\": \"someone\",	\"content\": \"\",\"recursive\": false},"
+					+ " \"tempModel\": {\"name\": \"testingdata\",\"subScopename\": \"\"	},"
+					+ " \"policy\": {\"policyType\": \"Config\",\"configPolicyType\": \"Micro Service\",\"policyName\": \"may1501\", "
+					+ "	\"policyDescription\": \"testing input\", \"onapName\": \"RaviTest\",\"guard\": \"False\",\"riskType\": \"Risk12345\",\"riskLevel\": \"2\","
+					+ "	\"priority\": \"6\",\"serviceType\": \"DkatPolicyBody\",\"version\": \"1707.41.02\",\"ruleGridData\": [	[\"fileId\"]],\"ttlDate\": null}}, "
+					+ "	\"policyJSON\": {\"pmTableName\": \"test\",	\"dmdTopic\": \"1\",\"fileId\": \"56\"} }";
+			BufferedReader br = new BufferedReader(new StringReader(jsonString));
+			when(request.getReader()).thenReturn(br); 		    
+			controller.removeMicroServiceHeaderDefaults(request, response);
+			logger.info("response.getContentAsString(): " + response.getContentAsString());
+			assertTrue( response.getContentAsString() != null && response.getContentAsString().contains("microServiceHeaderDefaultDatas"));
+
+		} catch (Exception e) {
+			fail("Exception: " + e);
+		}
+		
+		logger.info("testRemoveMicroServiceHeaderDefaults: exit");
+	}
+
 
 	@Test
 	public void testGetDCAEUUIDDictionaryByNameEntityData() {
diff --git a/ONAP-PAP-REST/src/test/java/org/onap/policy/pap/xacml/rest/controller/OptimizationDictionaryControllerTest.java b/ONAP-PAP-REST/src/test/java/org/onap/policy/pap/xacml/rest/controller/OptimizationDictionaryControllerTest.java
new file mode 100644
index 0000000..edc08f3
--- /dev/null
+++ b/ONAP-PAP-REST/src/test/java/org/onap/policy/pap/xacml/rest/controller/OptimizationDictionaryControllerTest.java
@@ -0,0 +1,173 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2018 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.pap.xacml.rest.controller;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.io.BufferedReader;
+import java.io.StringReader;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.onap.policy.common.logging.flexlogger.FlexLogger;
+import org.onap.policy.common.logging.flexlogger.Logger;
+import org.onap.policy.pap.xacml.rest.util.DictionaryUtils;
+import org.onap.policy.rest.dao.CommonClassDao;
+import org.onap.policy.rest.jpa.DCAEuuid;
+import org.onap.policy.rest.jpa.MicroServiceLocation;
+import org.onap.policy.rest.jpa.MicroServiceModels;
+import org.onap.policy.rest.jpa.OptimizationModels;
+import org.onap.policy.rest.jpa.UserInfo;
+import org.springframework.mock.web.MockHttpServletResponse;
+
+
+public class OptimizationDictionaryControllerTest {
+	
+	private static Logger logger = FlexLogger.getLogger(OptimizationDictionaryControllerTest.class);
+	private static CommonClassDao commonClassDao;
+	private String jsonString = null;
+	private HttpServletRequest request = null;
+	private OptimizationDictionaryController controller = null;
+	 BufferedReader br = null;
+
+	@Before
+	public void setUp() throws Exception {
+		logger.info("setUp: Entering");
+        commonClassDao = Mockito.mock(CommonClassDao.class);
+        UserInfo userInfo = new UserInfo();
+        userInfo.setUserLoginId("testUserId");
+        userInfo.setUserName("John");
+        when(commonClassDao.getEntityItem(UserInfo.class, "userLoginId", "testing")).thenReturn(userInfo);
+        
+        OptimizationModels optimziationModels = new OptimizationModels();
+        
+        doNothing().when(commonClassDao).delete(optimziationModels);
+		
+        OptimizationDictionaryController.setCommonClassDao(commonClassDao);	
+		
+		controller = new OptimizationDictionaryController();
+       
+        HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
+        
+		jsonString = "{\"optimizationModelsDictionaryData\": {\"modelName\": \"test\",	\"inprocess\": false,\"model\": {\"name\": \"testingdata\", "
+				+ " \"subScopename\": \"\",\"path\": [],\"type\": \"dir\",\"size\": 0,\"date\": \"2017-04-12T21:26:57.000Z\", "
+				+ " \"version\": \"\",\"createdBy\": \"someone\",	\"modifiedBy\": \"someone\",	\"content\": \"\",\"recursive\": false},"
+				+ " \"tempModel\": {\"name\": \"testingdata\",\"subScopename\": \"\"	},"
+				+ " \"policy\": {\"policyType\": \"Config\",\"configPolicyType\": \"Micro Service\",\"policyName\": \"may1501\", "
+				+ "	\"policyDescription\": \"testing input\", \"onapName\": \"RaviTest\",\"guard\": \"False\",\"riskType\": \"Risk12345\",\"riskLevel\": \"2\","
+				+ "	\"priority\": \"6\",\"serviceType\": \"DkatPolicyBody\",\"version\": \"1707.41.02\",\"ruleGridData\": [	[\"fileId\"]],\"ttlDate\": null}}, "
+				+ "	\"policyJSON\": {\"pmTableName\": \"test\",	\"dmdTopic\": \"1\",\"fileId\": \"56\"} }";
+    
+        br = new BufferedReader(new StringReader(jsonString));
+        //--- mock the getReader() call
+        when(request.getReader()).thenReturn(br);   
+        new DictionaryUtils(commonClassDao);
+        DictionaryUtils.setDictionaryUtils(new DictionaryUtils());
+        mock(DictionaryUtils.class);        
+        logger.info("setUp: exit");
+	}
+
+	@Test
+	public void testGetOptimizationModelsDictionaryEntityData() {
+		logger.info("testGetOptimizationModelsDictionaryEntityData: Entering");
+
+		MockHttpServletResponse response =  new MockHttpServletResponse();
+		String modelJson = "{\"optimizationModelsDictionaryData\":[\"modelName\"]}";
+	        
+	    BufferedReader br = new BufferedReader(new StringReader(modelJson));
+	    request = mock(HttpServletRequest.class);   
+	
+		try {
+		    // mock the getReader() call
+			when(request.getReader()).thenReturn(br); 		    
+			controller.getOptimizationModelsDictionaryEntityData(response);
+			logger.info("response.getContentAsString(): " + response.getContentAsString());
+			assertTrue( response.getContentAsString() != null && response.getContentAsString().contains("optimizationModelsDictionaryDatas"));
+
+		} catch (Exception e) {
+			fail("Exception: " + e);
+		}
+		
+		logger.info("testGetOptimizationModelsDictionaryEntityData: exit");
+	}
+
+	@Test
+	public void testSaveOptimizationModelsDictionary() {
+		logger.info("testSaveOptimizationModelsDictionary: Entering");
+
+		MockHttpServletResponse response =  new MockHttpServletResponse();
+	    request = mock(HttpServletRequest.class);   
+	
+		try {
+		    // mock the getReader() call
+			when(request.getReader()).thenReturn(br); 		    
+			controller.saveOptimizationModelsDictionary(request, response);
+			logger.info("response.getContentAsString(): " + response.getContentAsString());
+			assertTrue( response.getContentAsString() != null && response.getContentAsString().contains("optimizationModelsDictionaryDatas"));
+
+		} catch (Exception e) {
+			fail("Exception: " + e);
+		}
+		
+		logger.info("testSaveOptimizationModelsDictionary: exit");
+	}
+
+	@Test
+	public void testRemoveOptimizationModelsDictionary() {
+		logger.info("testRemoveOptimizationModelsDictionary: Entering");
+
+		MockHttpServletResponse response =  new MockHttpServletResponse();
+	    request = mock(HttpServletRequest.class);   
+	
+		try {
+		    // mock the getReader() call
+			jsonString = "{\"data\": {\"modelName\": \"test\",	\"inprocess\": false,\"model\": {\"name\": \"testingdata\", "
+					+ " \"subScopename\": \"\",\"path\": [],\"type\": \"dir\",\"size\": 0,\"date\": \"2017-04-12T21:26:57.000Z\", "
+					+ " \"version\": \"\",\"createdBy\": \"someone\",	\"modifiedBy\": \"someone\",	\"content\": \"\",\"recursive\": false},"
+					+ " \"tempModel\": {\"name\": \"testingdata\",\"subScopename\": \"\"	},"
+					+ " \"policy\": {\"policyType\": \"Config\",\"configPolicyType\": \"Micro Service\",\"policyName\": \"may1501\", "
+					+ "	\"policyDescription\": \"testing input\", \"onapName\": \"RaviTest\",\"guard\": \"False\",\"riskType\": \"Risk12345\",\"riskLevel\": \"2\","
+					+ "	\"priority\": \"6\",\"serviceType\": \"DkatPolicyBody\",\"version\": \"1707.41.02\",\"ruleGridData\": [	[\"fileId\"]],\"ttlDate\": null}}, "
+					+ "	\"policyJSON\": {\"pmTableName\": \"test\",	\"dmdTopic\": \"1\",\"fileId\": \"56\"} }";
+			
+			BufferedReader br = new BufferedReader(new StringReader(jsonString));
+			when(request.getReader()).thenReturn(br); 		    
+			controller.removeOptimizationModelsDictionary(request, response);
+			logger.info("response.getContentAsString(): " + response.getContentAsString());
+			assertTrue( response.getContentAsString() != null && response.getContentAsString().contains("optimizationModelsDictionaryDatas"));
+
+		} catch (Exception e) {
+			fail("Exception: " + e);
+		}
+		
+		logger.info("testRemoveOptimizationModelsDictionary: exit");
+	}
+
+}
diff --git a/ONAP-PAP-REST/src/test/resources/dictionaryImport/OptimizationPolicyDictionary.csv b/ONAP-PAP-REST/src/test/resources/dictionaryImport/OptimizationPolicyDictionary.csv
new file mode 100644
index 0000000..722f315
--- /dev/null
+++ b/ONAP-PAP-REST/src/test/resources/dictionaryImport/OptimizationPolicyDictionary.csv
@@ -0,0 +1,2 @@
+Id,Optimization Model,Description,Model Version,Imported By,dependency,attributes,enumValues,Ref Attributes,Sub Attributes
+16857,PolicyBody,PolicyBody,0.1.0-SNAPSHOT,demo,test,test,test,test,test
diff --git a/ONAP-PDP-REST/config/policyLogger.properties b/ONAP-PDP-REST/config/policyLogger.properties
deleted file mode 100644
index a04f4ee..0000000
--- a/ONAP-PDP-REST/config/policyLogger.properties
+++ /dev/null
@@ -1,44 +0,0 @@
-###
-# ============LICENSE_START=======================================================
-# ONAP-PDP-REST
-# ================================================================================
-# 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=========================================================
-###
-
-################################### Set concurrentHashMap and timer info  #######################
-#Timer initial delay and the delay between in milliseconds before task is to be execute.
-timer.delay.time=1000
-#Timer scheduleAtFixedRate period - time in milliseconds between successive task executions.
-check.interval= 30000
-#Longest time an event info can be stored in the concurrentHashMap for logging - in seconds. 
-event.expired.time=86400
-#Size of the concurrentHashMap which stores the event starting time, etc - when its size reaches this limit, the Timer gets executed 
-#to remove all expired records from this concurrentHashMap.
-concurrentHashMap.limit=5000
-#Size of the concurrentHashMap - when its size drops to this point, stop the Timer
-stop.check.point=2500
-################################### Set logging format #############################################
-# set EELF for EELF logging format, set LOG4J for using log4j, set SYSTEMOUT for using system.out.println
-logger.type=EELF
-#################################### Set level for EELF or SYSTEMOUT logging ##################################
-# Set level for debug file. Set DEBUG to enable .info, .warn and .debug; set INFO for enable .info and .warn; set OFF to disable all 
-debugLogger.level=INFO
-# Set level for metrics file. Set OFF to disable; set ON to enable
-metricsLogger.level=ON
-# Set level for error file. Set OFF to disable; set ON to enable
-error.level=ON
-# Set level for audit file. Set OFF to disable; set ON to enable
-audit.level=ON
diff --git a/ONAP-PDP-REST/config/xacml.pip.properties b/ONAP-PDP-REST/config/xacml.pip.properties
index 2286b5d..0ded409 100644
--- a/ONAP-PDP-REST/config/xacml.pip.properties
+++ b/ONAP-PDP-REST/config/xacml.pip.properties
@@ -1,3 +1,9 @@
 #
-#Wed May 31 15:42:12 EDT 2017
-
+#Mon Mar 19 19:20:17 UTC 2018
+historydb.name=operationHistoryDB
+AAF.description=AAFEngine to communicate with AAF to take decisions
+historydb.issuer=org\:onap\:xacml\:guard\:historydb
+AAF.classname=org.onap.policy.xacml.std.pip.engines.aaf.AAFEngine
+AAF.name=AAFEngine
+historydb.classname=org.onap.policy.xacml.std.pip.engines.OperationHistoryEngine
+xacml.pip.engines=historydb,AAF
diff --git a/ONAP-PDP-REST/config/xacml.policy.properties b/ONAP-PDP-REST/config/xacml.policy.properties
index 5c884ed..1090a5e 100644
--- a/ONAP-PDP-REST/config/xacml.policy.properties
+++ b/ONAP-PDP-REST/config/xacml.policy.properties
@@ -1,4 +1,7 @@
 #
-#Wed May 31 15:42:12 EDT 2017
+#Mon Mar 19 19:20:17 UTC 2018
 xacml.referencedPolicies=
-xacml.rootPolicies=
+Mike.Config_OOF_testMatchingConfigs.1.xml.url=http\://localhost\:8070/pap/?id\=Mike.Config_OOF_testMatchingConfigs.1.xml
+xacml.rootPolicies=Mike.Config_OOF_testMatchingConfigs.1.xml
+Mike.Config_OOF_testMatchingConfigs.1.xml.name=Mike.Config_OOF_testMatchingConfigs
+Mike.Config_OOF_testMatchingConfigs.1.xml.file=/media/sf_SourceTree/gerrit-pe/engine/ONAP-PDP-REST/config/Mike.Config_OOF_testMatchingConfigs.1.xml
diff --git a/ONAP-PDP-REST/config_testing/xacml.policy.properties b/ONAP-PDP-REST/config_testing/xacml.policy.properties
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/ONAP-PDP-REST/config_testing/xacml.policy.properties
diff --git a/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/services/CreateUpdatePolicyServiceImpl.java b/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/services/CreateUpdatePolicyServiceImpl.java
index 62b8503..f2cc16b 100644
--- a/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/services/CreateUpdatePolicyServiceImpl.java
+++ b/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/services/CreateUpdatePolicyServiceImpl.java
@@ -176,6 +176,12 @@
                 // Get Result. 
                 response = microServicesPolicyService.getResult(updateFlag);
                 break;
+            case Optimization:
+            	OptimizationPolicyService optimizationPolicyService = new OptimizationPolicyService(policyName, policyScope, policyParameters, date);
+
+            	// Get Result
+            	response = optimizationPolicyService.getResult(updateFlag);
+            	break;
             default:
                 message = XACMLErrorConstants.ERROR_DATA_ISSUE+ " Invalid Config Type Present";
                 LOGGER.error(message);
diff --git a/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/services/DeletePolicyService.java b/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/services/DeletePolicyService.java
index 144d3a4..c9ecee8 100644
--- a/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/services/DeletePolicyService.java
+++ b/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/services/DeletePolicyService.java
@@ -236,6 +236,9 @@
         } else if ("MicroService".equalsIgnoreCase(policyType)) {
             clientScope = "ConfigMS";
             filePrefix = "Config_MS_";
+        } else if ("Optimization".equalsIgnoreCase(policyType)) {
+        	clientScope = "ConfigOptimization";
+        	filePrefix = "Config_OOF_";
         }else if ("BRMS_RAW".equalsIgnoreCase(policyType)) {
             clientScope = "ConfigBrmsRaw";
             filePrefix = "Config_BRMS_Raw_";
diff --git a/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/services/GetConfigService.java b/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/services/GetConfigService.java
index 6e6badf..1744aa8 100644
--- a/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/services/GetConfigService.java
+++ b/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/services/GetConfigService.java
@@ -173,6 +173,8 @@
                 return PolicyConfigType.ClosedLoop_PM;
             } else if(name.startsWith("Config_MS_")) {
                 return PolicyConfigType.MicroService;
+            } else if(name.startsWith("Config_OOF_")) {
+            	return PolicyConfigType.Optimization;
             } else if(name.startsWith("Config_")) {
                 return PolicyConfigType.Base;
             }
diff --git a/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/services/GetDictionaryService.java b/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/services/GetDictionaryService.java
index 9b86204..152e84c 100644
--- a/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/services/GetDictionaryService.java
+++ b/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/services/GetDictionaryService.java
@@ -222,6 +222,9 @@
         case "MicroServiceModels":
             jsonString = jsonString.replace("microServiceModelsDictionaryDatas", "DictionaryDatas");
             break;
+        case "OptimizationModels":
+        	jsonString = jsonString.replace("optmizationModelsDictionaryDatas", "DictionaryDatas");
+        	break;
         case "PolicyScopeService":
             jsonString = jsonString.replace("psServiceDictionaryDatas", "DictionaryDatas");
             break;
diff --git a/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/services/OptimizationPolicyService.java b/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/services/OptimizationPolicyService.java
new file mode 100644
index 0000000..61038d9
--- /dev/null
+++ b/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/services/OptimizationPolicyService.java
@@ -0,0 +1,110 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP-PDP-REST
+ * ================================================================================
+ * Copyright (C) 2018 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.pdp.rest.api.services;
+
+import javax.json.JsonException;
+import javax.json.JsonObject;
+import org.onap.policy.api.PolicyException;
+import org.onap.policy.api.PolicyParameters;
+import org.onap.policy.common.logging.flexlogger.FlexLogger;
+import org.onap.policy.common.logging.flexlogger.Logger;
+import org.onap.policy.pdp.rest.api.utils.PolicyApiUtils;
+import org.onap.policy.xacml.api.XACMLErrorConstants;
+import org.onap.policy.xacml.std.pap.StdPAPPolicy;
+
+/**
+ * Optimization Policy implementation. 
+ * 
+ * @version 0.1
+ */
+public class OptimizationPolicyService{
+	private static final Logger LOGGER = FlexLogger.getLogger(OptimizationPolicyService.class.getName());
+	
+	private PAPServices papServices = null;
+	private PolicyParameters policyParameters = null;
+	private String message = null;
+	private String policyName = null;
+	private String policyScope = null;
+	private String date = null;
+
+	public OptimizationPolicyService(String policyName, String policyScope, PolicyParameters policyParameters, String date) {
+		this.policyParameters = policyParameters;
+		this.policyName = policyName;
+		this.policyScope = policyScope;
+		this.date = date;
+		papServices = new PAPServices();
+	}
+
+	public String getMessage() {
+		return message;
+	}
+	
+	public String getResult(boolean updateFlag) throws PolicyException{
+	    String response = null;
+        String operation = null;
+        
+        if (updateFlag){
+            operation = "update";
+        } else {
+            operation = "create";
+        }
+        
+        // get values and attributes from the JsonObject
+        String servicModel = null;
+        String policyDescription=null;
+        String priority=null;
+        String version=null;
+        
+		String onapName = policyParameters.getOnapName();
+		JsonObject optimizationAttributes = null;
+		try{
+			optimizationAttributes = PolicyApiUtils.stringToJsonObject(policyParameters.getConfigBody());
+		} catch(JsonException| IllegalStateException e){
+			message = XACMLErrorConstants.ERROR_DATA_ISSUE+ " improper JSON object : " + policyParameters.getConfigBody();
+			LOGGER.error("Error while parsing JSON body for MicroService Policy creation. ", e);
+			return null;
+		}
+		
+        if (optimizationAttributes.get("service")!=null){
+        	servicModel = optimizationAttributes.get("service").toString().replace("\"", "");
+        }
+        if(optimizationAttributes.containsKey("description")){
+        	policyDescription = optimizationAttributes.get("description").toString().replace("\"", "");
+        }
+        if(optimizationAttributes.containsKey("priority")){
+        	priority = optimizationAttributes.get("priority").toString().replace("\"", "");
+        }
+        if(optimizationAttributes.containsKey("version")){
+        	version = optimizationAttributes.get("version").toString().replace("\"", "");
+        }
+        
+        // Create Policy Object 
+        StdPAPPolicy newPAPPolicy = new StdPAPPolicy("Optimization", policyName, policyDescription, onapName, 
+                null, servicModel, null, null, optimizationAttributes.toString(), priority, 
+                version, updateFlag, policyScope, 0, policyParameters.getRiskLevel(),
+                policyParameters.getRiskType(), String.valueOf(policyParameters.getGuard()), date); 
+        
+        // Send JSON Object to PAP 
+        response = (String) papServices.callPAP(newPAPPolicy, new String[] {"operation="+operation, "apiflag=api", "policyType=Config"}, 
+        		policyParameters.getRequestID(), "ConfigOptimization");
+        LOGGER.info("Response: " + response);
+        return response;
+	}
+}
diff --git a/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/services/PolicyEngineImportService.java b/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/services/PolicyEngineImportService.java
index d0649d7..f7c1cc5 100644
--- a/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/services/PolicyEngineImportService.java
+++ b/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/services/PolicyEngineImportService.java
@@ -110,7 +110,8 @@
         String fileName = file.getOriginalFilename();
         switch (importParameters.getServiceType()){
 		case MICROSERVICE:
-			if (fileName.endsWith(".xmi") ||  fileName.endsWith(".zip")){
+		case OPTIMIZATION:
+			if (fileName.endsWith(".yml") || fileName.endsWith(".xmi") ||  fileName.endsWith(".zip")){
 	            try {
 	                targetStream = new BufferedInputStream(file.getInputStream());
 	            } catch (IOException e) {
@@ -164,7 +165,8 @@
             message = XACMLErrorConstants.ERROR_DATA_ISSUE + "Missing service Type value.";
             return false;
         }
-        if(importParameters.getServiceType().equals(IMPORT_TYPE.MICROSERVICE) && (importParameters.getVersion()==null || importParameters.getVersion().trim().isEmpty())){
+        if((IMPORT_TYPE.MICROSERVICE.equals(importParameters.getServiceType()) || IMPORT_TYPE.OPTIMIZATION.equals(importParameters.getServiceType()))
+        		&& (importParameters.getVersion()==null || importParameters.getVersion().trim().isEmpty())){
             message = XACMLErrorConstants.ERROR_DATA_ISSUE + "Missing version value.";
             return false;
         }
diff --git a/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/services/PushPolicyService.java b/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/services/PushPolicyService.java
index a3d18b3..7ab17e0 100644
--- a/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/services/PushPolicyService.java
+++ b/ONAP-PDP-REST/src/main/java/org/onap/policy/pdp/rest/api/services/PushPolicyService.java
@@ -176,6 +176,9 @@
         } else if ("MicroService".equalsIgnoreCase(policyType)) {
             clientScope = "ConfigMS";
             filePrefix = "Config_MS_";
+        } else if ("Optimization".equalsIgnoreCase(policyType)) {
+        	clientScope = "ConfigOptimization";
+        	filePrefix = "Config_OOF_";
         } else if ("BRMS_RAW".equalsIgnoreCase(policyType)) {
             clientScope = "ConfigBrmsRaw";
             filePrefix = "Config_BRMS_Raw_";
diff --git a/ONAP-PDP-REST/src/test/java/org/onap/policy/pdp/rest/api/services/BRMSRawPolicyServiceTest.java b/ONAP-PDP-REST/src/test/java/org/onap/policy/pdp/rest/api/services/BRMSRawPolicyServiceTest.java
index 8d53127..5f20dfb 100644
--- a/ONAP-PDP-REST/src/test/java/org/onap/policy/pdp/rest/api/services/BRMSRawPolicyServiceTest.java
+++ b/ONAP-PDP-REST/src/test/java/org/onap/policy/pdp/rest/api/services/BRMSRawPolicyServiceTest.java
@@ -20,24 +20,39 @@
 package org.onap.policy.pdp.rest.api.services;
 
 import static org.junit.Assert.assertEquals;
+
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Properties;
+
 import org.junit.Test;
-import org.onap.policy.api.PolicyException;
 import org.onap.policy.api.PolicyParameters;
 
 public class BRMSRawPolicyServiceTest {
 	@Test
-	public void testRaw() throws PolicyException  {
+	public void testRaw() throws FileNotFoundException, IOException  {
+		Properties prop = new Properties();
+		prop.load(new FileInputStream("src/test/resources/pass.xacml.pdp.properties"));
+		String succeeded = prop.getProperty("xacml.rest.pap.url");
+		List<String> paps = Arrays.asList(succeeded.split(","));
+		PAPServices.setPaps(paps);
+		PAPServices.setJunit(true);
+		prop.clear();
+		
 		String systemKey = "xacml.properties";
 		String testVal = "testVal";
 		PolicyParameters testParams = new PolicyParameters();
-		
+				
 		// Set the system property temporarily
 		String oldProperty = System.getProperty(systemKey);
 		System.setProperty(systemKey, "xacml.pdp.properties");
 		
 		BRMSRawPolicyService service = new BRMSRawPolicyService(testVal, testVal, testParams, testVal);
-		assertEquals(service.getValidation(), false);
-		assertEquals(service.getMessage(), "PE300 - Data Issue:  No Rule Body given");
+		assertEquals(false, service.getValidation());
+		assertEquals("PE300 - Data Issue:  No Rule Body given", service.getMessage());
 		
 		// Restore the original system property
 		if (oldProperty != null) {
diff --git a/ONAP-PDP-REST/src/test/java/org/onap/policy/pdp/rest/api/services/ConfigPolicyServiceTest.java b/ONAP-PDP-REST/src/test/java/org/onap/policy/pdp/rest/api/services/ConfigPolicyServiceTest.java
index 389d9bf..16f5a47 100644
--- a/ONAP-PDP-REST/src/test/java/org/onap/policy/pdp/rest/api/services/ConfigPolicyServiceTest.java
+++ b/ONAP-PDP-REST/src/test/java/org/onap/policy/pdp/rest/api/services/ConfigPolicyServiceTest.java
@@ -20,13 +20,27 @@
 package org.onap.policy.pdp.rest.api.services;
 
 import static org.junit.Assert.assertEquals;
+
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Properties;
+
 import org.junit.Test;
-import org.onap.policy.api.PolicyException;
 import org.onap.policy.api.PolicyParameters;
 
 public class ConfigPolicyServiceTest {
 	@Test
-	public void testRaw() throws PolicyException  {
+	public void testRaw() throws FileNotFoundException, IOException  {
+		Properties prop = new Properties();
+		prop.load(new FileInputStream("src/test/resources/pass.xacml.pdp.properties"));
+		String succeeded = prop.getProperty("xacml.rest.pap.url");
+		List<String> paps = Arrays.asList(succeeded.split(","));
+		PAPServices.setPaps(paps);
+		PAPServices.setJunit(true);
+		
 		String systemKey = "xacml.properties";
 		String testVal = "testVal";
 		PolicyParameters testParams = new PolicyParameters();
diff --git a/ONAP-PDP-REST/src/test/java/org/onap/policy/pdp/rest/api/services/OptimizationPolicyServiceTest.java b/ONAP-PDP-REST/src/test/java/org/onap/policy/pdp/rest/api/services/OptimizationPolicyServiceTest.java
new file mode 100644
index 0000000..79ca2e6
--- /dev/null
+++ b/ONAP-PDP-REST/src/test/java/org/onap/policy/pdp/rest/api/services/OptimizationPolicyServiceTest.java
@@ -0,0 +1,91 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP-PAP-REST
+ * ================================================================================
+ * Copyright (C) 2018 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.pdp.rest.api.services;
+
+import static org.junit.Assert.*;
+
+import java.io.FileInputStream;
+import java.text.SimpleDateFormat;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+import java.util.Properties;
+import java.util.UUID;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.policy.api.PolicyConfigType;
+import org.onap.policy.api.PolicyException;
+import org.onap.policy.api.PolicyParameters;
+
+public class OptimizationPolicyServiceTest {
+
+	OptimizationPolicyService service = null;
+
+	@Before
+	public void setUp() throws Exception {
+		Properties prop = new Properties();
+		prop.load(new FileInputStream("src/test/resources/pass.xacml.pdp.properties"));
+		String succeeded = prop.getProperty("xacml.rest.pap.url");
+		List<String> paps = Arrays.asList(succeeded.split(","));
+		PAPServices.setPaps(paps);
+		PAPServices.setJunit(true);
+		prop.clear();
+		
+		PolicyParameters policyParameters = new PolicyParameters();
+        policyParameters.setPolicyConfigType(PolicyConfigType.Optimization);
+        policyParameters.setPolicyName("Test.testOOFPolicy");
+		policyParameters.setOnapName("OOF");
+        policyParameters.setRequestID(UUID.randomUUID());
+      	SimpleDateFormat dateformat3 = new SimpleDateFormat("dd/MM/yyyy");
+		Date date = dateformat3.parse("15/10/2016");
+		policyParameters.setTtlDate(date);
+		policyParameters.setGuard(true);
+		policyParameters.setRiskLevel("5");
+		policyParameters.setRiskType("TEST");
+		policyParameters.setConfigBody("{\"optimization\":\"test\"}");
+		String policyName = "testOOFPolicy";
+		String policyScope = "Test";
+		service = new OptimizationPolicyService(policyName, policyScope, policyParameters, date.toString());
+	}
+
+	@After
+	public void tearDown() throws Exception {
+	}
+
+	@Test
+	public final void testOptimizationPolicyService() {
+		assertNotNull(service);
+	}
+
+	@Test
+	public final void testGetMessage() {
+		String message = service.getMessage();
+		assertNull(message);
+	}
+
+	@Test
+	public final void testGetResult() throws PolicyException {
+		String result = service.getResult(false);
+		assertEquals("success",result);
+	}
+
+}
diff --git a/ONAP-REST/pom.xml b/ONAP-REST/pom.xml
index 71bf6d8..5111d51 100644
--- a/ONAP-REST/pom.xml
+++ b/ONAP-REST/pom.xml
@@ -38,6 +38,12 @@
 	<packaging>jar</packaging>
 
 	<dependencies>
+	    <!-- https://mvnrepository.com/artifact/org.yaml/snakeyaml -->
+		<dependency>
+		    <groupId>org.yaml</groupId>
+		    <artifactId>snakeyaml</artifactId>
+		    <version>1.16</version>
+		</dependency>
 		<dependency>
 			<groupId>com.h2database</groupId>
 			<artifactId>h2</artifactId>
diff --git a/ONAP-REST/src/main/java/org/onap/policy/rest/XACMLRestProperties.java b/ONAP-REST/src/main/java/org/onap/policy/rest/XACMLRestProperties.java
index e52a411..325dda5 100644
--- a/ONAP-REST/src/main/java/org/onap/policy/rest/XACMLRestProperties.java
+++ b/ONAP-REST/src/main/java/org/onap/policy/rest/XACMLRestProperties.java
@@ -347,6 +347,10 @@
 	 */
 	public static final String TemplateVersion_MS= "xacml.rest.microServices";
 	/*
+	 * Optimization Policy Template Version
+	 */
+	public static final String TemplateVersion_OOF= "xacml.rest.optimization";
+	/*
 	 * Firewall Policy Template Version
 	 */
 	public static final String TemplateVersion_FW= "xacml.rest.firewallPolicy";
diff --git a/ONAP-REST/src/main/java/org/onap/policy/rest/jpa/MicroServiceModels.java b/ONAP-REST/src/main/java/org/onap/policy/rest/jpa/MicroServiceModels.java
index f323251..4029ad5 100644
--- a/ONAP-REST/src/main/java/org/onap/policy/rest/jpa/MicroServiceModels.java
+++ b/ONAP-REST/src/main/java/org/onap/policy/rest/jpa/MicroServiceModels.java
@@ -68,6 +68,9 @@
 	@Column (name="sub_attributes", nullable=false, length=2000)
 	private String sub_attributes;
 	
+	@Column (name="dataOrderInfo", nullable=true, length=2000)
+	private String dataOrderInfo;
+
 	@Column (name="version", nullable=false, length=2000)
 	private String version;
 	
@@ -84,6 +87,14 @@
 	public void setSub_attributes(String sub_attributes) {
 		this.sub_attributes = sub_attributes;
 	}
+	
+	public String getDataOrderInfo() {
+		return dataOrderInfo;
+	}
+
+	public void setDataOrderInfo(String dataOrderInfo) {
+		this.dataOrderInfo = dataOrderInfo;
+	}
 
 	public String getVersion() {
 		return version;
@@ -168,4 +179,4 @@
 	public void setAnnotation(String annotation) {
 		this.annotation = annotation;
 	}
-}
+}
\ No newline at end of file
diff --git a/ONAP-REST/src/main/java/org/onap/policy/rest/jpa/MicroserviceHeaderdeFaults.java b/ONAP-REST/src/main/java/org/onap/policy/rest/jpa/MicroserviceHeaderdeFaults.java
new file mode 100644
index 0000000..b876484
--- /dev/null
+++ b/ONAP-REST/src/main/java/org/onap/policy/rest/jpa/MicroserviceHeaderdeFaults.java
@@ -0,0 +1,123 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP-REST
+ * ================================================================================
+ * Copyright (C) 2018 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.rest.jpa;
+
+import java.io.Serializable;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.NamedQuery;
+import javax.persistence.OrderBy;
+import javax.persistence.PrePersist;
+import javax.persistence.PreUpdate;
+import javax.persistence.Table;
+
+@Entity
+@Table(name="MicroserviceHeaderdeFaults")
+@NamedQuery(name="MicroserviceHeaderdeFaults.findAll", query="SELECT e FROM MicroserviceHeaderdeFaults e ")
+public class MicroserviceHeaderdeFaults implements Serializable {
+	private static final long serialVersionUID = 1L;
+
+	private static String domain;
+
+	@Id
+	@GeneratedValue(strategy = GenerationType.AUTO)
+	@Column(name="id")
+	private int id;
+	
+	@Column(name="onapName")
+	private String onapName;
+	
+	@Column(name="guard")
+	private String guard ;
+	
+	@Column(name="priority")
+	private String priority;
+	
+	@Column(name="riskType")
+	private String riskType ;
+	
+	@Column(name="riskLevel")
+
+	private String riskLevel;
+	
+	@Column(name="modelName", nullable=false)
+	@OrderBy("asc")
+	private String modelName;
+
+	@PrePersist
+	public void	prePersist() {
+		
+	}
+	@PreUpdate
+	public void preUpdate() {
+	}
+
+	
+	public int getId() {
+		return this.id;
+	}
+
+	public void setId(int id) {
+		this.id = id;
+	}
+
+	public String getModelName() {
+		return modelName;
+	}
+	public void setModelName(String modelName) {
+		this.modelName = modelName;
+	}
+	public String getOnapName() {
+		return onapName;
+	}
+	public void setOnapName(String onapName) {
+		this.onapName = onapName;
+	}
+	public String getGuard() {
+		return guard;
+	}
+	public void setGuard(String guard) {
+		this.guard = guard;
+	}
+	public String getPriority() {
+		return priority;
+	}
+	public void setPriority(String priority) {
+		this.priority = priority;
+	}
+	public String getRiskType() {
+		return riskType;
+	}
+	public void setRiskType(String riskType) {
+		this.riskType = riskType;
+	}
+	public String getRiskLevel() {
+		return riskLevel;
+	}
+	public void setRiskLevel(String riskLevel) {
+		this.riskLevel = riskLevel;
+	}
+	
+}
\ No newline at end of file
diff --git a/ONAP-REST/src/main/java/org/onap/policy/rest/jpa/OptimizationModels.java b/ONAP-REST/src/main/java/org/onap/policy/rest/jpa/OptimizationModels.java
new file mode 100644
index 0000000..1accc99
--- /dev/null
+++ b/ONAP-REST/src/main/java/org/onap/policy/rest/jpa/OptimizationModels.java
@@ -0,0 +1,182 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP-REST
+ * ================================================================================
+ * Copyright (C) 2018 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.rest.jpa;
+
+import java.io.Serializable;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.NamedQuery;
+import javax.persistence.OrderBy;
+import javax.persistence.Table;
+/*
+ * JPA for the OOF Models. 
+ * 
+ * @version: 0.1
+ */
+
+
+@Entity
+@Table(name="OptimizationModels")
+@NamedQuery(name="OptimizationModels.findAll", query="SELECT b FROM OptimizationModels b ")
+public class OptimizationModels implements Serializable{
+	private static final long serialVersionUID = 1L;
+	
+	@Id
+	@GeneratedValue(strategy = GenerationType.AUTO)
+	@Column(name="id")
+	private int id;
+	
+	@Column(name="modelName", nullable=false, unique=true)
+	@OrderBy("asc")
+	private String modelName;
+	
+	@Column(name="description", nullable=true, length=2048)
+	private String description;
+	
+	@Column(name="dependency", nullable=true, length=2048)
+	private String dependency;
+
+	@Column(name="attributes", nullable=false, length=255)
+	private String attributes;
+	
+	@Column(name="ref_attributes", nullable=false, length=255)
+	private String refattributes;
+
+	@Column (name="sub_attributes", nullable=false, length=2000)
+	private String subattributes;
+	
+	@Column (name="dataOrderInfo", nullable=true, length=2000)
+	private String dataOrderInfo;
+	
+	@Column (name="version", nullable=false, length=2000)
+	private String version;
+	
+	@Column (name="enumValues", nullable=false, length=2000)
+	private String enumValues;
+	
+	@Column (name="annotation", nullable=false, length=2000)
+	private String annotation;
+	
+	public String getSubattributes() {
+		return subattributes;
+	}
+
+	public void setSubattributes(String subattributes) {
+		this.subattributes = subattributes;
+	}
+	
+	public String getDataOrderInfo() {
+		return dataOrderInfo;
+	}
+
+	public void setDataOrderInfo(String dataOrderInfo) {
+		this.dataOrderInfo = dataOrderInfo;
+	}
+
+	public String getVersion() {
+		return version;
+	}
+
+	public void setVersion(String version) {
+		this.version = version;
+	}
+
+	@ManyToOne
+	@JoinColumn(name="imported_by")
+	private UserInfo userCreatedBy;
+	
+	public UserInfo getUserCreatedBy() {
+		return userCreatedBy;
+	}
+
+	public void setUserCreatedBy(UserInfo userCreatedBy) {
+		this.userCreatedBy = userCreatedBy;
+	}
+	
+	public String getAttributes() {
+		return attributes;
+	}
+
+	public void setAttributes(String attributes) {
+		this.attributes = attributes;
+	}
+
+	public String getRefattributes() {
+		return refattributes;
+	}
+
+	public void setRefattributes(String refattributes) {
+		this.refattributes = refattributes;
+	}
+
+	public int getId() {
+		return this.id;
+	}
+	
+	public void setId(int id) {
+		this.id = id;
+	}
+	
+	public String getDescription() {
+		return this.description;
+	}
+
+	public void setDescription(String description) {
+		this.description = description;
+	}
+	
+	public String getDependency() {
+		return dependency;
+	}
+
+	public void setDependency(String dependency) {
+		this.dependency = dependency;
+	}
+	
+	public String getModelName(){
+		return this.modelName;
+	}
+	
+	public void setModelName(String modelName){
+		this.modelName = modelName;
+	}
+	
+	public String getEnumValues() {
+		return enumValues;
+	}
+
+	public void setEnumValues(String enumValues) {
+		this.enumValues = enumValues;
+	}
+	
+	public String getAnnotation() {
+		return annotation;
+	}
+
+	public void setAnnotation(String annotation) {
+		this.annotation = annotation;
+	}
+}
diff --git a/ONAP-REST/src/main/java/org/onap/policy/rest/util/MSModelUtils.java b/ONAP-REST/src/main/java/org/onap/policy/rest/util/MSModelUtils.java
index 18fd80c..f8b8b52 100644
--- a/ONAP-REST/src/main/java/org/onap/policy/rest/util/MSModelUtils.java
+++ b/ONAP-REST/src/main/java/org/onap/policy/rest/util/MSModelUtils.java
@@ -20,13 +20,21 @@
 
 package org.onap.policy.rest.util;
 
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
 import java.io.IOException;
+import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.Map.Entry;
 
 import org.apache.commons.lang.StringUtils;
@@ -54,6 +62,7 @@
 import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl;
 import org.json.JSONObject;
 import org.onap.policy.rest.XACMLRestProperties;
+import org.yaml.snakeyaml.Yaml;
 
 import com.att.research.xacml.util.XACMLProperties;
 import com.google.gson.Gson;
@@ -71,6 +80,38 @@
 	private String onap = "";
 	private String policy = "";
 	private String eProxyURI = "eProxyURI:";
+	private List<String> orderedElements = new ArrayList<>();
+	private String dataOrderInfo = null;
+	private Set<String> uniqueDataKeys= new HashSet<>();
+	private Set<String> uniqueKeys= new HashSet<>();
+	private String listConstraints = null;
+	private String referenceAttributes;
+	private LinkedHashMap<String, Object> retmap = new LinkedHashMap<>();
+	private Map<String, String>  matchableValues;
+	public static final String PROPERTIES=".properties.";
+	public static final String DATATYPE  = "data_types.policy.data.";
+	public static final String TYPE=".type";
+	public static final String REQUIRED=".required";
+	public static final String MATCHABLE=".matchable";
+	public static final String STRING="string";
+	public static final String INTEGER="integer";
+	public static final String LIST="list";
+	public static final String DEFAULT=".default";
+	public static final String MANYFALSE=":MANY-false";
+	public static final String MANYTRUE=":MANY-true";
+	public static final String DEFAULTVALUE=":defaultValue-";
+	public static final String REQUIREDVALUE=":required-";
+	public static final String MATCHABLEKEY="matchable";
+	public static final String REQUIREDFALSE=":required-false";
+	public static final String REQUIREDTRUE=":required-true";
+	public static final String MATCHINGTRUE="matching-true";
+
+	private StringBuilder dataListBuffer=new StringBuilder();
+	private List<String> dataConstraints= new ArrayList <>();
+	private String attributeString = null;
+	
+	public MSModelUtils(){
+	}
 	
 	public MSModelUtils(String onap, String policy){
 		this.onap = onap;
@@ -110,7 +151,7 @@
 				if (obj instanceof EEnum) {
 					enumMap.putAll(getEEnum(obj));
 				}else if (obj instanceof EClass) {
-					String temp = getDependencyList(eClassifier, className).toString();
+					String temp = getDependencyList(eClassifier).toString();
 					returnValue = StringUtils.replaceEach(temp, new String[]{"[", "]"}, new String[]{"", ""});
 					getAttributes(className, returnValue, root);
 				}        		   		
@@ -135,11 +176,11 @@
 				Map<String, String> listRef = classMap.get(key).getRefAttribute();
 				for (  Entry<String, String> eSet : listAttributes.entrySet()){
 					String key2 = eSet.getKey();
-					tempAttribute.put(key2, "matching-true");
+					tempAttribute.put(key2, MATCHINGTRUE);
 				}
 				for (  Entry<String, String> eSet : listRef.entrySet()){
 					String key3 = eSet.getKey();
-					tempAttribute.put(key3, "matching-true");
+					tempAttribute.put(key3, MATCHINGTRUE);
 				}
 
 			}
@@ -232,7 +273,7 @@
 		HashMap<String, String> annotationSet = new HashMap<>();
 		String  matching;
 		String range;
-		String dictionary;
+		String annotationDict;
 
 		//    Pulling out dependency from file
 		while (treeItr.hasNext()) {	    
@@ -254,14 +295,13 @@
 						if (range!=null){
 							annotationSet.put(eStrucClassifier.getName(), range);
 						}
-						dictionary = annotationValue(eStrucClassifier, ANNOTATION_TYPE.DICTIONARY, policy);
-						if (dictionary!=null){
-							annotationSet.put(eStrucClassifier.getName(), dictionary);
+						annotationDict = annotationValue(eStrucClassifier, ANNOTATION_TYPE.DICTIONARY, policy);
+						if (annotationDict!=null){
+							annotationSet.put(eStrucClassifier.getName(), annotationDict);
 						}
 					}
 				}
-			} else if (requiredMatchAttribute){
-				if (obj instanceof EStructuralFeature) {
+			} else if (requiredMatchAttribute && (obj instanceof EStructuralFeature)) {
 					EStructuralFeature eStrucClassifier = (EStructuralFeature) obj;
 					if (!eStrucClassifier.getEAnnotations().isEmpty()) {
 						matching  = annotationValue(eStrucClassifier, ANNOTATION_TYPE.MATCHING, policy);
@@ -275,7 +315,6 @@
 							}
 						}
 					}
-				}
 			}
 		}
 		return annotationSet;
@@ -305,22 +344,20 @@
 				rollingCount = rollingCount+processClass;
 			}
 
-			if (requiredAttribute)   {
-				if (obj instanceof EStructuralFeature) {
-					EStructuralFeature eStrucClassifier = (EStructuralFeature) obj;
-					if (!eStrucClassifier.getEAnnotations().isEmpty()) {
-						annotation = annotationTest(eStrucClassifier, configuration, onap);
-						if (annotation &&  obj instanceof EReference) {
-							EClass refType = ((EReference) obj).getEReferenceType();
-							if(!refType.toString().contains(eProxyURI)){
-								String required = ":required-false";
-								if(eStrucClassifier.getLowerBound() == 1){
-									required = ":required-true";
-								}
-								subAttribute.put(eStrucClassifier.getName(), refType.getName() + required);						
+			if (requiredAttribute && (obj instanceof EStructuralFeature)) {
+				EStructuralFeature eStrucClassifier = (EStructuralFeature) obj;
+				if (!eStrucClassifier.getEAnnotations().isEmpty()) {
+					annotation = annotationTest(eStrucClassifier, configuration, onap);
+					if (annotation &&  obj instanceof EReference) {
+						EClass refType = ((EReference) obj).getEReferenceType();
+						if(!refType.toString().contains(eProxyURI)){
+							String required = REQUIREDFALSE;
+							if(eStrucClassifier.getLowerBound() == 1){
+								required = REQUIREDTRUE;
 							}
-						}	
-					}
+							subAttribute.put(eStrucClassifier.getName(), refType.getName() + required);						
+						}
+					}	
 				}
 			}
 		}
@@ -329,7 +366,7 @@
 
 	public String checkDefultValue(String defultValue) {
 		if (defultValue!=null){
-			return ":defaultValue-"+ defultValue;
+			return DEFAULTVALUE+ defultValue;
 		}
 		return ":defaultValue-NA";
 
@@ -341,11 +378,11 @@
 
 		if (pattern!=null){
 			if (upper == Integer.parseInt(pattern.split(",")[1]) && lower==Integer.parseInt(pattern.split(",")[0])){
-				return ":required-true";
+				return REQUIREDTRUE;
 			}
 		}
 
-		return ":required-false";
+		return REQUIREDFALSE;
 	}
 
 	public JSONObject buildJavaObject(Map<String, String> map){
@@ -376,8 +413,7 @@
 				rollingCount = rollingCount+processClass;
 			}
 
-			if (requiredAttribute)   {
-				if (obj instanceof EStructuralFeature) {
+			if (requiredAttribute && (obj instanceof EStructuralFeature)) {
 					EStructuralFeature eStrucClassifier = (EStructuralFeature) obj;
 					if (!eStrucClassifier.getEAnnotations().isEmpty()) {
 						annotation = annotationTest(eStrucClassifier, configuration, onap);
@@ -389,9 +425,9 @@
 								refAttribute.put(eStrucClassifier.getName(), refValue);							
 							} else {
 								String array = arrayCheck(((EStructuralFeature) obj).getUpperBound());
-								String required = ":required-false";
+								String required = REQUIREDFALSE;
 								if(((EStructuralFeature) obj).getLowerBound() == 1){
-									required = ":required-true";
+									required = REQUIREDTRUE;
 								}
 								refAttribute.put(eStrucClassifier.getName(), refType.getName() + array + required);
 							}
@@ -399,15 +435,14 @@
 							EClassifier refType = ((EAttributeImpl) obj).getEType();
 							if (refType instanceof EEnumImpl){
 								String array = arrayCheck(((EStructuralFeature) obj).getUpperBound());
-								String required = ":required-false";
+								String required = REQUIREDFALSE;
 								if(((EStructuralFeature) obj).getLowerBound() == 1){
-									required = ":required-true";
+									required = REQUIREDTRUE;
 								}
 								refAttribute.put(eStrucClassifier.getName(), refType.getName() + array + required);							
 							}
 						}	
 					}
-				}
 			}
 		}
 		
@@ -427,9 +462,12 @@
 			eAnnotation = eStrucClassifier.getEAnnotations().get(i);
 			onapType = eAnnotation.getDetails().get(0).getValue();
 			onapValue = eAnnotation.getDetails().get(0).getKey();
+			
 			if (annotationType.contains(type) && onapType.contains(annotation)){
 				return true;
-			} else if (annotationType.contains(type) && onapValue.contains(annotation)){
+			}
+			
+			if (annotationType.contains(type) && onapValue.contains(annotation)){
 				return true;
 			}
 		}
@@ -464,8 +502,7 @@
 	}
 	public boolean isRequiredAttribute(EObject obj, String className){
 		EClassifier eClassifier = (EClassifier) obj;
-		String workingClass = eClassifier.getName();
-		workingClass.trim();
+		String workingClass = eClassifier.getName().trim();
 		if (workingClass.equalsIgnoreCase(className)){
 			return  true;
 		}
@@ -530,8 +567,7 @@
 
 			}
 
-			if (requiredAttribute){
-				if (obj instanceof EStructuralFeature) {
+			if (requiredAttribute && (obj instanceof EStructuralFeature)) {
 					EStructuralFeature eStrucClassifier = (EStructuralFeature) obj;
 					if (!eStrucClassifier.getEAnnotations().isEmpty()) {
 						annotation = annotationTest(eStrucClassifier, configuration, onap);
@@ -552,7 +588,6 @@
 							refAttribute.put(name, attributeValue);	
 						}
 					}
-				}
 			}
 		}
 		return refAttribute;
@@ -562,13 +597,13 @@
 	public String arrayCheck(int upperBound) {
 
 		if (upperBound == -1){
-			return ":MANY-true";
+			return MANYTRUE;
 		}
 
-		return ":MANY-false";
+		return MANYFALSE;
 	}
 
-	public List<String> getDependencyList(EClassifier eClassifier, String className){
+	public List<String> getDependencyList(EClassifier eClassifier){
 		List<String> returnValue = new ArrayList<>();;
 		EList<EClass> somelist = ((EClass) eClassifier).getEAllSuperTypes();
 		if (somelist.isEmpty()){
@@ -617,10 +652,9 @@
 		Map<String, String> returnClass = getRefclass(classMap, className);
 		returnObject.put(className, returnClass);
 		for (Entry<String, String> reAttribute :returnClass.entrySet()){
-			if (reAttribute.getValue().split(":")[1].contains("MANY")){
-				if (classMap.get(reAttribute.getValue().split(":")[0]) != null){
+			if (reAttribute.getValue().split(":")[1].contains("MANY") && 
+					classMap.get(reAttribute.getValue().split(":")[0]) != null){
 					returnObject.putAll(recursiveReference(classMap, reAttribute.getValue().split(":")[0]));
-				}
 			}
 
 		}
@@ -629,18 +663,16 @@
 
 	}
 
-	public String createJson(Map<String, Object> subClassAttributes, Map<String, MSAttributeObject> classMap, String className) {
+	public String createJson(Map<String, MSAttributeObject> classMap, String className) {
 		boolean enumType;
 		Map<String, Map<String, String>> myObject = new HashMap<>();
 		for ( Entry<String, String> map : classMap.get(className).getRefAttribute().entrySet()){
 			String value = map.getValue().split(":")[0];
 			if (value!=null){
 				enumType = classMap.get(className).getEnumType().containsKey(value);
-				if (!enumType){
-					if (map.getValue().split(":")[1].contains("MANY")){
+				if (!enumType && map.getValue().split(":")[1].contains("MANY")){
 						Map<String, Map<String, String>> testRecursive = recursiveReference(classMap, map.getValue().split(":")[0] );
 						myObject.putAll(testRecursive);
-					}
 				}
 			}
 		}
@@ -680,7 +712,7 @@
 			}
 		}
 
-		return createJson(workingMap, classMap, modelName);
+		return createJson(classMap, modelName);
 	}
 
 	public List<String> getFullDependencyList(List<String> dependency, Map<String,MSAttributeObject > classMap) {
@@ -702,4 +734,529 @@
 
 		return returnList;
 	}
-}
+	
+    /*
+     * For TOSCA Model
+     */
+	public void parseTosca (String fileName){
+		LinkedHashMap<String,String> map= new LinkedHashMap<>();
+    
+    	try {
+			map=load(fileName);
+			
+			parseDataAndPolicyNodes(map);
+			
+			LinkedHashMap<String,String> dataMapForJson=parseDataNodes(map);
+			
+			constructJsonForDataFields(dataMapForJson);	
+			
+			LinkedHashMap<String,LinkedHashMap<String,String>> mapKey= parsePolicyNodes(map);
+			
+			createAttributes(mapKey);
+		
+    	} catch (IOException e) {
+    		logger.error(e);
+    	}
+	
+	} 
+	
+	@SuppressWarnings("unchecked")
+	public LinkedHashMap<String, String> load(String fileName) throws IOException { 
+		File newConfiguration = new File(fileName);
+		StringBuilder orderInfo = new StringBuilder("[");
+		Yaml yaml = new Yaml();
+		LinkedHashMap<Object, Object> yamlMap = null;
+		try(InputStream is = new FileInputStream(newConfiguration)){
+			yamlMap = (LinkedHashMap<Object, Object>) yaml.load(is); 
+		} catch (FileNotFoundException e) {
+			logger.error(e);
+		}
+
+		StringBuilder sb = new StringBuilder(); 
+		LinkedHashMap<String, String> settings = new LinkedHashMap<>(); 
+		if (yamlMap == null) { 
+			return settings; 
+		} 
+		
+		findNode(yamlMap);
+		
+		orderedElements.stream().forEach((string) -> {
+			orderInfo.append(string);
+			orderInfo.append(",");
+			logger.info("Content: " + string);
+		});
+		
+		orderInfo.append("]");
+		
+		dataOrderInfo = orderInfo.toString();
+		dataOrderInfo = dataOrderInfo.replace(",]", "]");
+		
+		logger.info("dataOrderInfo :" + dataOrderInfo);
+		
+		List<String> path = new ArrayList <>(); 
+		serializeMap(settings, sb, path, yamlMap); 
+		return settings; 
+	} 
+	
+	@SuppressWarnings({ "unchecked", "rawtypes" })
+	private void serializeMap(LinkedHashMap<String, String> settings, StringBuilder sb, List<String> path, Map<Object, Object> yamlMap) { 
+		for (Map.Entry<Object, Object> entry : yamlMap.entrySet()) { 
+				        
+			if (entry.getValue() instanceof Map) { 
+				path.add((String) entry.getKey()); 
+				serializeMap(settings, sb, path, (Map<Object, Object>) entry.getValue()); 
+				path.remove(path.size() - 1); 
+			} else if (entry.getValue() instanceof List) { 
+				path.add((String) entry.getKey()); 
+				serializeList(settings, sb, path, (List) entry.getValue()); 
+				path.remove(path.size() - 1); 
+			} else { 
+				serializeValue(settings, sb, path, (String) entry.getKey(), entry.getValue()); 
+			} 
+		} 
+	}
+	
+	@SuppressWarnings("unchecked")
+	private void serializeList(LinkedHashMap<String, String> settings, StringBuilder sb, List<String> path, List<String> yamlList) { 
+		int counter = 0; 
+		for (Object listEle : yamlList) { 
+			if (listEle instanceof Map) { 
+				path.add(Integer.toString(counter)); 
+				serializeMap(settings, sb, path, (Map<Object, Object>) listEle); 
+				path.remove(path.size() - 1); 
+			} else if (listEle instanceof List) { 
+				path.add(Integer.toString(counter)); 
+				serializeList(settings, sb, path, (List<String>) listEle); 
+				path.remove(path.size() - 1); 
+			} else { 
+				serializeValue(settings, sb, path, Integer.toString(counter), listEle); 
+			} 
+			counter++; 
+		} 
+	} 
+
+	private void serializeValue(LinkedHashMap<String, String> settings, StringBuilder sb, List<String> path, String name, Object value) { 		
+	    if (value == null) { 
+			return; 
+		} 
+		sb.setLength(0); 
+		for (String pathEle : path) { 
+			sb.append(pathEle).append('.'); 
+		} 
+		sb.append(name); 
+		settings.put(sb.toString(), value.toString()); 
+	} 
+	
+	
+	void parseDataAndPolicyNodes(LinkedHashMap<String,String> map){
+		for(String key:map.keySet()){
+			if(key.contains("policy.nodes.Root"))
+			{
+				continue;
+			}
+			else if(key.contains("policy.nodes")){
+				String wordToFind = "policy.nodes.";
+				int indexForPolicyNode=key.indexOf(wordToFind);
+				String subNodeString= key.substring(indexForPolicyNode+13, key.length());
+
+				stringBetweenDots(subNodeString);
+			}
+			else if(key.contains("policy.data")){
+				String wordToFind="policy.data.";
+				int indexForPolicyNode=key.indexOf(wordToFind);
+				String subNodeString= key.substring(indexForPolicyNode+12, key.length());
+
+				stringBetweenDotsForDataFields(subNodeString);
+			}
+		}
+	}
+	
+	// Second index of dot should be returned. 
+	public int stringBetweenDots(String str){
+		String stringToSearch=str;
+		String[]ss=stringToSearch.split("\\.");
+		if(ss!=null){
+			int len= ss.length;
+			if(len>2){
+				uniqueKeys.add(ss[2]);
+			}
+		}
+		
+		return uniqueKeys.size();
+	}
+	
+	
+	public void stringBetweenDotsForDataFields(String str){
+		String stringToSearch=str;
+		String[]ss=stringToSearch.split("\\.");
+		if(ss!=null){
+			int len= ss.length;
+
+			if(len>2){
+				uniqueDataKeys.add(ss[0]+"%"+ss[2]);
+			}
+		}
+	}
+	
+	void constructJsonForDataFields(LinkedHashMap<String,String> dataMapForJson){
+		LinkedHashMap<String,LinkedHashMap<String,String>> dataMapKey= new LinkedHashMap <>();
+		LinkedHashMap<String, String> hmSub;
+		for(Map.Entry<String, String> entry: dataMapForJson.entrySet()){
+			String uniqueDataKey= entry.getKey();
+			String[] uniqueDataKeySplit=uniqueDataKey.split("%");
+			String value= dataMapForJson.get(uniqueDataKey);
+			if(dataMapKey.containsKey(uniqueDataKeySplit[0])){
+				hmSub = dataMapKey.get(uniqueDataKeySplit[0]);
+				hmSub.put(uniqueDataKeySplit[1], value);
+			}
+			else{
+				hmSub=new LinkedHashMap <>();
+				hmSub.put(uniqueDataKeySplit[1], value);
+			}
+				
+			dataMapKey.put(uniqueDataKeySplit[0], hmSub);
+		}
+				
+		JSONObject mainObject= new JSONObject();
+		JSONObject json;
+		for(Map.Entry<String,LinkedHashMap<String,String>> entry: dataMapKey.entrySet()){
+			String s=entry.getKey();
+			json= new JSONObject();
+			HashMap<String,String> jsonHm=dataMapKey.get(s);
+			for(Map.Entry<String,String> entryMap:jsonHm.entrySet()){
+				String key=entryMap.getKey();
+				json.put(key, jsonHm.get(key));
+			}
+			mainObject.put(s,json);
+		}	
+		Iterator<String> keysItr = mainObject.keys();
+		while(keysItr.hasNext()) {
+			String key = keysItr.next();
+			String value = mainObject.get(key).toString();
+			retmap.put(key, value);
+		}
+		
+		logger.info("#############################################################################");
+		logger.info(mainObject);
+		logger.info("###############################################################################");	
+	}
+	
+	LinkedHashMap<String,String> parseDataNodes(LinkedHashMap<String,String> map){
+		LinkedHashMap<String,String> dataMapForJson=new LinkedHashMap <>(); 
+		matchableValues = new HashMap <>(); 
+		for(String uniqueDataKey: uniqueDataKeys){
+			if(uniqueDataKey.contains("%")){
+				String[] uniqueDataKeySplit= uniqueDataKey.split("%");
+				String findType=DATATYPE+uniqueDataKeySplit[0]+PROPERTIES+uniqueDataKeySplit[1]+TYPE;
+				String typeValue=map.get(findType);
+				logger.info(typeValue);
+				
+				String findRequired=DATATYPE+uniqueDataKeySplit[0]+PROPERTIES+uniqueDataKeySplit[1]+REQUIRED;
+				String requiredValue= map.get(findRequired);
+				
+				String matchable =DATATYPE+uniqueDataKeySplit[0]+PROPERTIES+uniqueDataKeySplit[1]+MATCHABLE;
+
+				String matchableValue= map.get(matchable);
+
+				if(matchableValue != null && matchableValue.equalsIgnoreCase("true")){
+					if(uniqueDataKey.contains("%")){
+						String[] keys= uniqueDataKey.split("%");
+						String key=keys[keys.length -1];
+						matchableValues.put(key, MATCHINGTRUE);
+					}else{
+						matchableValues.put(uniqueDataKey, MATCHINGTRUE);
+					}
+				}
+					
+				if(requiredValue == null || requiredValue.isEmpty()){
+					requiredValue = "false";
+				}
+				if(typeValue != null && (typeValue.equalsIgnoreCase(STRING)||
+						typeValue.equalsIgnoreCase(INTEGER))){
+					
+					String findDefault=DATATYPE+uniqueDataKeySplit[0]+PROPERTIES+uniqueDataKeySplit[1]+DEFAULT;
+					String defaultValue= map.get(findDefault);
+					logger.info("defaultValue is:"+ defaultValue);
+					logger.info("requiredValue is:"+ requiredValue);
+					
+					StringBuilder attributeIndividualStringBuilder= new StringBuilder();
+					attributeIndividualStringBuilder.append(typeValue+DEFAULTVALUE);
+					attributeIndividualStringBuilder.append(defaultValue+REQUIREDVALUE);
+					attributeIndividualStringBuilder.append(requiredValue+MANYFALSE);
+					dataMapForJson.put(uniqueDataKey, attributeIndividualStringBuilder.toString());		
+				}
+				else if(typeValue != null && typeValue.equalsIgnoreCase(LIST)){
+					logger.info("requiredValue is:"+ requiredValue);
+					String findList= DATATYPE+uniqueDataKeySplit[0]+PROPERTIES+uniqueDataKeySplit[1]+".entry_schema.type";
+					String listValue=map.get(findList);
+					if(listValue!=null){
+						logger.info("Type of list is:"+ listValue);
+						//Its userdefined
+						if(listValue.contains(".")){
+							String trimValue=listValue.substring(listValue.lastIndexOf('.')+1);
+							StringBuilder referenceIndividualStringBuilder= new StringBuilder();
+							referenceIndividualStringBuilder.append(trimValue+REQUIREDVALUE);
+							referenceIndividualStringBuilder.append(requiredValue+MANYTRUE);
+							dataMapForJson.put(uniqueDataKey, referenceIndividualStringBuilder.toString());
+						}//Its string
+						else{
+							StringBuilder stringListItems= new StringBuilder();
+							stringListItems.append(uniqueDataKeySplit[1].toUpperCase()+REQUIREDVALUE+requiredValue +MANYFALSE);
+							dataMapForJson.put(uniqueDataKey, stringListItems.toString());
+							dataListBuffer.append(uniqueDataKeySplit[1].toUpperCase()+"=[");
+							for(int i=0;i<10;i++){
+								String findConstraints= DATATYPE+uniqueDataKeySplit[0]+PROPERTIES+uniqueDataKeySplit[1]+".entry_schema.constraints.0.valid_values."+i;
+								logger.info("findConstraints => " + findConstraints);
+								String constraintsValue=map.get(findConstraints);
+								logger.info("constraintsValue => " + constraintsValue);
+								if(constraintsValue==null){
+									break;
+								}
+								else{
+									logger.info("constraintsValue => " + constraintsValue);
+									if(constraintsValue.contains("=")){
+										constraintsValue = constraintsValue.replace("=", "equal-sign");
+									}
+									dataConstraints.add(constraintsValue);									
+									dataListBuffer.append(constraintsValue+",");
+								}
+							}
+							dataListBuffer.append("]#");
+							logger.info(dataListBuffer);
+						}
+					}
+				}
+				else{
+					String findUserDefined=DATATYPE+uniqueDataKeySplit[0]+"."+"properties"+"."+uniqueDataKeySplit[1]+TYPE;
+					String userDefinedValue=map.get(findUserDefined);
+					String trimValue=userDefinedValue.substring(userDefinedValue.lastIndexOf('.')+1);
+					StringBuilder referenceIndividualStringBuilder= new StringBuilder();
+					referenceIndividualStringBuilder.append(trimValue+REQUIREDVALUE);
+					referenceIndividualStringBuilder.append(requiredValue+MANYFALSE);
+					dataMapForJson.put(uniqueDataKey, referenceIndividualStringBuilder.toString());
+					
+				}
+			}
+		}
+		
+		return dataMapForJson;
+	}
+	
+	
+	LinkedHashMap<String, LinkedHashMap<String, String>> parsePolicyNodes(Map<String,String> map){
+		LinkedHashMap<String,LinkedHashMap<String,String>> mapKey= new LinkedHashMap <>();
+		for(String uniqueKey: uniqueKeys){
+			LinkedHashMap<String,String> hm;
+
+			for(Map.Entry<String,String> entry:map.entrySet()){
+				String key=entry.getKey();
+				if(key.contains(uniqueKey) && key.contains("policy.nodes")){
+					if(mapKey.containsKey(uniqueKey)){
+						hm = mapKey.get(uniqueKey);
+						String keyStr= key.substring(key.lastIndexOf('.')+1);
+						String valueStr= map.get(key);
+						if(("type").equals(keyStr)){
+							if(!key.contains("entry_schema"))
+							{
+								hm.put(keyStr,valueStr);
+							}
+						}else{
+							hm.put(keyStr,valueStr);
+						}
+
+					} else {
+						hm = new LinkedHashMap <>();
+						String keyStr= key.substring(key.lastIndexOf('.')+1);
+						String valueStr= map.get(key);
+						if(("type").equals(keyStr)){
+							if(!key.contains("entry_schema"))
+							{
+								hm.put(keyStr,valueStr);
+							}
+						}else{
+							hm.put(keyStr,valueStr);
+						}
+						mapKey.put(uniqueKey, hm);
+					}
+				}
+			}
+		}
+		return mapKey;
+	}
+
+	void createAttributes(LinkedHashMap<String,LinkedHashMap<String,String>> mapKey){
+		StringBuilder attributeStringBuilder= new StringBuilder();
+		StringBuilder referenceStringBuilder= new StringBuilder();
+		StringBuilder listBuffer= new StringBuilder();
+		List<String> constraints= new ArrayList<>();
+		for(Map.Entry<String,LinkedHashMap<String,String>> entry: mapKey.entrySet()){
+			String keySetString= entry.getKey();
+			LinkedHashMap<String,String> keyValues=mapKey.get(keySetString);
+			if(STRING.equalsIgnoreCase(keyValues.get("type"))|| 
+					INTEGER.equalsIgnoreCase(keyValues.get("type"))){
+				StringBuilder attributeIndividualStringBuilder= new StringBuilder();
+				attributeIndividualStringBuilder.append(keySetString+"=");
+				attributeIndividualStringBuilder.append(keyValues.get("type")+DEFAULTVALUE);
+				attributeIndividualStringBuilder.append(keyValues.get("default")+REQUIREDVALUE);
+				attributeIndividualStringBuilder.append(keyValues.get("required")+MANYFALSE);
+				attributeStringBuilder.append(attributeIndividualStringBuilder+",");	
+                if("true".equalsIgnoreCase(keyValues.get(MATCHABLEKEY))){
+				    matchableValues.put(keySetString, MATCHINGTRUE);
+                }
+			}
+			else if(LIST.equalsIgnoreCase(keyValues.get("type"))){
+				
+                if(("true").equalsIgnoreCase(keyValues.get(MATCHABLEKEY))){
+				    matchableValues.put(keySetString, MATCHINGTRUE);
+                }
+				//List Datatype
+				Set<String> keys= keyValues.keySet();
+				Iterator<String> itr=keys.iterator();
+				boolean isDefinedType = false;
+				while(itr.hasNext()){
+					String key= itr.next();
+					if((!("type").equals(key) ||("required").equals(key)))
+					{
+						String value= keyValues.get(key);
+						//The "." in the value determines if its a string or a user defined type.  
+						if (!value.contains(".")){
+							//This is string
+							if(StringUtils.isNumeric(key) ){  //only integer key for the value of Constrains 
+							    constraints.add(keyValues.get(key));
+							}
+						}else{
+							//This is user defined type
+							String trimValue=value.substring(value.lastIndexOf('.')+1);
+							StringBuilder referenceIndividualStringBuilder= new StringBuilder();
+							referenceIndividualStringBuilder.append(keySetString+"="+trimValue+MANYTRUE);
+							referenceStringBuilder.append(referenceIndividualStringBuilder+",");
+							isDefinedType = true;
+						}
+					}				
+
+				}
+
+				if(!isDefinedType && LIST.equalsIgnoreCase(keyValues.get("type"))){ //type is not user defined and is a list but no constraints defined.
+					if(constraints == null || constraints.isEmpty()){
+						referenceStringBuilder.append(keySetString+"=MANY-true"+",");
+					}
+				}
+			}else{
+				//User defined Datatype.
+                if("true".equalsIgnoreCase(keyValues.get(MATCHABLEKEY))){
+				    matchableValues.put(keySetString, MATCHINGTRUE);
+                }
+				String value=keyValues.get("type");
+				if(value != null && !value.isEmpty()){
+					String trimValue=value.substring(value.lastIndexOf('.')+1);
+					StringBuilder referenceIndividualStringBuilder= new StringBuilder();
+					referenceIndividualStringBuilder.append(keySetString+"="+trimValue+MANYFALSE);
+					referenceStringBuilder.append(referenceIndividualStringBuilder+",");
+				}else{
+					logger.info("keyValues.get(type) is null/empty");
+				}
+
+			}
+			if(constraints!=null && !constraints.isEmpty()){
+				//List handling. 
+				listBuffer.append(keySetString.toUpperCase()+"=[");
+				for(String str:constraints){
+					listBuffer.append(str+",");
+				}
+				listBuffer.append("]#");
+				logger.info(listBuffer);
+
+
+				StringBuilder referenceIndividualStringBuilder= new StringBuilder();
+				referenceIndividualStringBuilder.append(keySetString+"="+keySetString.toUpperCase()+MANYFALSE);
+				referenceStringBuilder.append(referenceIndividualStringBuilder+",");
+				constraints.clear();
+			}
+		}
+		
+		dataListBuffer.append(listBuffer);
+		
+
+		logger.info("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$");
+		logger.info("Whole attribute String is:"+attributeStringBuilder);	
+		logger.info("Whole reference String is:"+referenceStringBuilder);
+		logger.info("List String is:"+listBuffer);
+		logger.info("Data list buffer is:"+dataListBuffer);
+		logger.info("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$");
+		
+		this.listConstraints=dataListBuffer.toString();
+		this.referenceAttributes=referenceStringBuilder.toString();
+		this.attributeString=attributeStringBuilder.toString();
+	}
+	
+	@SuppressWarnings("unchecked")
+	public void findNode(LinkedHashMap<Object, Object> map) {
+		
+		map.forEach((key,value) -> {
+			// if the value is properties and its type is map object, then save all the keys
+			if(key.equals("properties") && value instanceof Map){
+				saveNodes((LinkedHashMap<?, ?>)value);
+			}
+			
+			if(!key.equals("policy.nodes.Root") && value instanceof Map){
+				//value is a Map object, then make a recursive call
+			    findNode((LinkedHashMap<Object, Object>) value);   
+			}
+		});
+
+	}
+	
+	public void saveNodes(LinkedHashMap<?, ?> map) {
+		
+		map.forEach((key,value) -> {
+			
+		    orderedElements.add((String)key);
+	    
+		});
+
+	}
+	
+	public String getAttributeString() {
+		return attributeString;
+	}
+	public void setAttributeString(String attributeString) {
+		this.attributeString = attributeString;
+	}
+	
+	public LinkedHashMap<String, Object> getRetmap() {
+		return retmap;
+	}
+
+	public void setRetmap(LinkedHashMap<String, Object> retmap) {
+		this.retmap = retmap;
+	}
+	public Map<String, String> getMatchableValues() {
+		return matchableValues;
+	}
+
+	public void setMatchableValues(Map<String, String> matchableValues) {
+		this.matchableValues = matchableValues;
+	}
+	public String getReferenceAttributes() {
+		return referenceAttributes;
+	}
+
+	public void setReferenceAttributes(String referenceAttributes) {
+		this.referenceAttributes = referenceAttributes;
+	}
+	public String getListConstraints() {
+		return listConstraints;
+	}
+
+	public void setListConstraints(String listConstraints) {
+		this.listConstraints = listConstraints;
+	}
+	public String getDataOrderInfo() {
+		return dataOrderInfo;
+	}
+
+	public void setDataOrderInfo(String dataOrderInfo) {
+		this.dataOrderInfo = dataOrderInfo;
+	}
+
+}
\ No newline at end of file
diff --git a/ONAP-REST/src/main/java/org/onap/policy/rest/util/PolicyValidation.java b/ONAP-REST/src/main/java/org/onap/policy/rest/util/PolicyValidation.java
index 47291cf..2e685d4 100644
--- a/ONAP-REST/src/main/java/org/onap/policy/rest/util/PolicyValidation.java
+++ b/ONAP-REST/src/main/java/org/onap/policy/rest/util/PolicyValidation.java
@@ -44,6 +44,7 @@
 import org.onap.policy.rest.adapter.PolicyRestAdapter;
 import org.onap.policy.rest.dao.CommonClassDao;
 import org.onap.policy.rest.jpa.MicroServiceModels;
+import org.onap.policy.rest.jpa.OptimizationModels;
 import org.onap.policy.rest.jpa.SafePolicyWarning;
 import org.onap.policy.utils.PolicyUtils;
 import org.onap.policy.xacml.api.XACMLErrorConstants;
@@ -65,12 +66,19 @@
 	public static final String DECISION_POLICY = "Decision";
 	public static final String CLOSEDLOOP_POLICY = "ClosedLoop_Fault";
 	public static final String CLOSEDLOOP_PM = "ClosedLoop_PM";
-	public static final String ENFORCER_CONFIG_POLICY= "Enforcer Config";
-	public static final String MICROSERVICES="Micro Service";
-	public static final String FIREWALL="Firewall Config";
+	public static final String ENFORCER_CONFIG_POLICY = "Enforcer Config";
+	public static final String MICROSERVICES = "Micro Service";
+	public static final String FIREWALL = "Firewall Config";
+	public static final String OPTIMIZATION="Optimization";
+	public static final String BRMSPARAM = "BRMS_Param";
+	public static final String BRMSRAW = "BRMS_Raw";
 	public static final String HTML_ITALICS_LNBREAK = "</i><br>";
 	public static final String SUCCESS = "success";
 	public static final String EMPTY_COMPONENT_ATTR = "Component Attributes: One or more Fields in Component Attributes is Empty.";
+	public static final String ISREQUIRED = " is required";
+	public static final String SPACESINVALIDCHARS = " : value has spaces or invalid characters</i><br>";
+	public static final String RULEALGORITHMS = "<b>Rule Algorithms</b>:<i>";
+	public static final String VALUE = "value";
 	
 	private static Map<String, String> mapAttribute = new HashMap<>();
 	private static Map<String, String> jsonRequestMap = new HashMap<>();
@@ -122,8 +130,8 @@
                         String key = null;
                         if(((LinkedHashMap<?, ?>) attribute).get("key") != null){
                             key = ((LinkedHashMap<?, ?>) attribute).get("key").toString();
-                            if(!PolicyUtils.policySpecialCharValidator(key).contains("success")){
-                                responseString.append("<b>Attributes or Component Attributes</b>:<i>" +  value + " : value has spaces or invalid characters</i><br>");
+                            if(!PolicyUtils.policySpecialCharValidator(key).contains(SUCCESS)){
+                                responseString.append("<b>Attributes or Component Attributes</b>:<i>" +  value + SPACESINVALIDCHARS);
                                 valid = false;
                             }
                         }else{
@@ -131,7 +139,7 @@
                                 if("Base".equals(policyData.getConfigPolicyType())){
                                     responseString.append("<b>Attributes</b>:<i> has one missing Attribute key</i><br>");
                                 }
-                                if("BRMS_Param".equals(policyData.getConfigPolicyType()) || "BRMS_Raw".equals(policyData.getConfigPolicyType())){
+                                if(BRMSPARAM.equals(policyData.getConfigPolicyType()) || BRMSRAW.equals(policyData.getConfigPolicyType())){
                                     responseString.append("<b>Rule Attributes</b>:<i> has one missing Attribute key</i><br>");
                                 }
                             }else{
@@ -139,18 +147,18 @@
                             }
                             valid = false;
                         }
-                        if(((LinkedHashMap<?, ?>) attribute).get("value") != null){
-                            value = ((LinkedHashMap<?, ?>) attribute).get("value").toString();
-                            if(!PolicyUtils.policySpecialCharValidator(value).contains("success")){
+                        if(((LinkedHashMap<?, ?>) attribute).get(VALUE) != null){
+                            value = ((LinkedHashMap<?, ?>) attribute).get(VALUE).toString();
+                            if(!PolicyUtils.policySpecialCharValidator(value).contains(SUCCESS)){
                                 if(CONFIG_POLICY.equals(policyData.getPolicyType())){
                                     if("Base".equals(policyData.getConfigPolicyType())){
-                                        responseString.append("<b>Attributes</b>:<i>" +  value + " : value has spaces or invalid characters</i><br>");
+                                        responseString.append("<b>Attributes</b>:<i>" +  value + SPACESINVALIDCHARS);
                                     }
-                                    if("BRMS_Param".equals(policyData.getConfigPolicyType()) || "BRMS_Raw".equals(policyData.getConfigPolicyType())){
-                                        responseString.append("<b>Rule Attributes</b>:<i>" +  value + " : value has spaces or invalid characters</i><br>");
+                                    if(BRMSPARAM.equals(policyData.getConfigPolicyType()) || BRMSRAW.equals(policyData.getConfigPolicyType())){
+                                        responseString.append("<b>Rule Attributes</b>:<i>" +  value + SPACESINVALIDCHARS);
                                     }
                                 }else{
-                                    responseString.append("<b>Component Attributes</b>:<i>" +  value + " : value has spaces or invalid characters</i><br>");
+                                    responseString.append("<b>Component Attributes</b>:<i>" +  value + SPACESINVALIDCHARS);
                                 }
                                 valid = false;
                             }
@@ -159,7 +167,7 @@
                                 if("Base".equals(policyData.getConfigPolicyType())){
                                     responseString.append("<b>Attributes</b>:<i> has one missing Attribute value</i><br>");
                                 }
-                                if("BRMS_Param".equals(policyData.getConfigPolicyType()) || "BRMS_Raw".equals(policyData.getConfigPolicyType())){
+                                if(BRMSPARAM.equals(policyData.getConfigPolicyType()) || BRMSRAW.equals(policyData.getConfigPolicyType())){
                                     responseString.append("<b>Rule Attributes</b>:<i> has one missing Attribute value</i><br>");
                                 }
                             }else{
@@ -180,10 +188,10 @@
                             responseString.append("<b>Settings Attributes</b>:<i> has one missing Attribute key</i><br>");
                             valid = false;
                         }
-                        if(((LinkedHashMap<?, ?>) attribute).get("value") != null){
-                            value = ((LinkedHashMap<?, ?>) attribute).get("value").toString();
-                            if(!PolicyUtils.policySpecialCharValidator(value).contains("success")){
-                                responseString.append("<b>Settings Attributes</b>:<i>" +  value + " : value has spaces or invalid characters</i><br>");
+                        if(((LinkedHashMap<?, ?>) attribute).get(VALUE) != null){
+                            value = ((LinkedHashMap<?, ?>) attribute).get(VALUE).toString();
+                            if(!PolicyUtils.policySpecialCharValidator(value).contains(SUCCESS)){
+                                responseString.append("<b>Settings Attributes</b>:<i>" +  value + SPACESINVALIDCHARS);
                                 valid = false;
                             }
                         }else{
@@ -199,21 +207,21 @@
                     if(attribute instanceof LinkedHashMap<?, ?>){
                         String label = ((LinkedHashMap<?, ?>) attribute).get("id").toString();
                         if(((LinkedHashMap<?, ?>) attribute).get("dynamicRuleAlgorithmField1") == null){
-                            responseString.append("<b>Rule Algorithms</b>:<i>" +  label + " : Field 1 value is not selected</i><br>");
+                            responseString.append(RULEALGORITHMS +  label + " : Field 1 value is not selected</i><br>");
                             valid = false;
                         }
                         if(((LinkedHashMap<?, ?>) attribute).get("dynamicRuleAlgorithmCombo") == null){
-                            responseString.append("<b>Rule Algorithms</b>:<i>" +  label + " : Field 2 value is not selected</i><br>");
+                            responseString.append(RULEALGORITHMS +  label + " : Field 2 value is not selected</i><br>");
                             valid = false;
                         }
                         if(((LinkedHashMap<?, ?>) attribute).get("dynamicRuleAlgorithmField2") != null){
                             String value = ((LinkedHashMap<?, ?>) attribute).get("dynamicRuleAlgorithmField2").toString();
-                            if(!PolicyUtils.policySpecialCharValidator(value).contains("success")){
-                                responseString.append("<b>Rule Algorithms</b>:<i>" +  label + " : Field 3 value has special characters</i><br>");
+                            if(!PolicyUtils.policySpecialCharValidator(value).contains(SUCCESS)){
+                                responseString.append(RULEALGORITHMS +  label + " : Field 3 value has special characters</i><br>");
                                 valid = false;
                             }
                         }else{
-                            responseString.append("<b>Rule Algorithms</b>:<i>" +  label + " : Field 3 value is empty</i><br>");
+                            responseString.append(RULEALGORITHMS +  label + " : Field 3 value is empty</i><br>");
                             valid = false;
                         }
                     }
@@ -223,7 +231,7 @@
 			if(CONFIG_POLICY.equalsIgnoreCase(policyData.getPolicyType())){
 				if ("Base".equals(policyData.getConfigPolicyType()) || CLOSEDLOOP_POLICY.equals(policyData.getConfigPolicyType())
 						||  CLOSEDLOOP_PM.equals(policyData.getConfigPolicyType()) || ENFORCER_CONFIG_POLICY.equals(policyData.getConfigPolicyType()) 
-						|| MICROSERVICES.equals(policyData.getConfigPolicyType())) {
+						|| MICROSERVICES.equals(policyData.getConfigPolicyType()) || OPTIMIZATION.equals(policyData.getConfigPolicyType())) {
 					
 					if(!Strings.isNullOrEmpty(policyData.getOnapName())) {
 						String onapNameValidate = PolicyUtils.policySpecialCharValidator(policyData.getOnapName());
@@ -269,7 +277,8 @@
 					responseString.append("<b>Guard</b>: Guard Value Should not be Empty" + HTML_ITALICS_LNBREAK);
 					valid = false;
 				}
-
+				
+				// Validate Config Base Policy Data
 				if("Base".equalsIgnoreCase(policyData.getConfigPolicyType())){
 					if(!Strings.isNullOrEmpty(policyData.getConfigName())) {
 						String configNameValidate = PolicyUtils.policySpecialCharValidator(policyData.getConfigName());
@@ -320,7 +329,8 @@
 						valid = false;
 					}
 				}
-
+				
+				// Validate Config Firewall Policy Data
 				if(FIREWALL.equalsIgnoreCase(policyData.getConfigPolicyType())){
 					if(policyData.getConfigName() != null && !policyData.getConfigName().isEmpty()){
 						String configNameValidate = PolicyUtils.policySpecialCharValidator(policyData.getConfigName());
@@ -337,11 +347,15 @@
 						valid = false;
 					}
 				}
-				if("BRMS_Param".equalsIgnoreCase(policyData.getConfigPolicyType()) && Strings.isNullOrEmpty(policyData.getRuleName())){
+				
+				// Validate BRMS_Param Policy Data
+				if(BRMSPARAM.equalsIgnoreCase(policyData.getConfigPolicyType()) && Strings.isNullOrEmpty(policyData.getRuleName())){
 					responseString.append("<b>BRMS Template</b>:<i>BRMS Template is required" + HTML_ITALICS_LNBREAK);
 					valid = false;
 				}
-				if("BRMS_Raw".equalsIgnoreCase(policyData.getConfigPolicyType())){
+				
+				// Validate BRMS_Raw Policy Data
+				if(BRMSRAW.equalsIgnoreCase(policyData.getConfigPolicyType())){
 					if(policyData.getConfigBodyData() != null && !policyData.getConfigBodyData().isEmpty()){
 						String message = PolicyUtils.brmsRawValidate(policyData.getConfigBodyData());
 						
@@ -355,6 +369,8 @@
 						valid = false;
 					}
 				}
+				
+				// Validate ClosedLoop_PM Policy Data
 				if(CLOSEDLOOP_PM.equalsIgnoreCase(policyData.getConfigPolicyType())){
 					try{
 						if(Strings.isNullOrEmpty(policyData.getServiceTypePolicyName().get("serviceTypePolicyName").toString())){
@@ -407,6 +423,8 @@
 						valid = false;
 					}
 				}
+				
+				// Validate ClosedLoop_Fault Policy Data
 				if(CLOSEDLOOP_POLICY.equalsIgnoreCase(policyData.getConfigPolicyType())){
 					if(policyData.getJsonBody() != null){
 
@@ -511,8 +529,10 @@
 						valid = false; 
 					}
 				}
-
+				
+				// Validate MicroServices Policy Data
 				if (MICROSERVICES.equals(policyData.getConfigPolicyType())){
+					
 					if(!Strings.isNullOrEmpty(policyData.getServiceType())){
 						
 						modelRequiredFieldsList.clear();
@@ -529,7 +549,7 @@
 						}
 						
 						if(!Strings.isNullOrEmpty(version)) {
-							MicroServiceModels returnModel = getAttributeObject(service, version);
+							MicroServiceModels returnModel = getMSModelData(service, version);
 							
 							if(returnModel != null) {
 								
@@ -639,11 +659,11 @@
 												if(Strings.isNullOrEmpty(jsonRequestMap.get(requiredField)) || 
 														"\"\"".equals(value) || 
 														"".equals(jsonRequestMap.get(requiredField))){
-													responseString.append("<b>Micro Service Model</b>:<i> " + requiredField + " is required" + HTML_ITALICS_LNBREAK);
+													responseString.append("<b>Micro Service Model</b>:<i> " + requiredField + ISREQUIRED + HTML_ITALICS_LNBREAK);
 													valid = false; 
 												}
 											} else {
-												responseString.append("<b>Micro Service Model</b>:<i> " + requiredField + " is required" + HTML_ITALICS_LNBREAK);
+												responseString.append("<b>Micro Service Model</b>:<i> " + requiredField + ISREQUIRED + HTML_ITALICS_LNBREAK);
 												valid = false; 
 											}
 										}
@@ -667,6 +687,144 @@
 						responseString.append("<b>Priority</b>:<i> Priority is required" + HTML_ITALICS_LNBREAK);
 						valid = false;
 					}
+				}
+				
+				// Validate Optimization Policy Data
+				if (OPTIMIZATION.equals(policyData.getConfigPolicyType())){
+					
+					if(!Strings.isNullOrEmpty(policyData.getServiceType())){
+						
+						modelRequiredFieldsList.clear();
+						pullJsonKeyPairs((JsonNode) policyData.getPolicyJSON());
+
+						String service;
+						String version;
+						if (policyData.getServiceType().contains("-v")){
+							service = policyData.getServiceType().split("-v")[0];
+							version = policyData.getServiceType().split("-v")[1];
+						}else {
+							service = policyData.getServiceType();
+							version = policyData.getVersion();
+						}
+						
+						if(!Strings.isNullOrEmpty(version)) {
+							OptimizationModels returnModel = getOptimizationModelData(service, version);
+							
+							if(returnModel != null) {
+								
+								String annotation = returnModel.getAnnotation();
+								String refAttributes = returnModel.getRefattributes();
+								String subAttributes = returnModel.getSubattributes();
+								String modelAttributes = returnModel.getAttributes();
+								
+								if (!Strings.isNullOrEmpty(annotation)){ 
+									Map<String, String> rangeMap = Splitter.on(",").withKeyValueSeparator("=").split(annotation);
+									for (Entry<String, String> rMap : rangeMap.entrySet()){
+										if (rMap.getValue().contains("range::")){
+											String value = mapAttribute.get(rMap.getKey().trim());
+											String[] tempString = rMap.getValue().split("::")[1].split("-");
+											int startNum = Integer.parseInt(tempString[0]);
+											int endNum = Integer.parseInt(tempString[1]);
+											String returnString = "InvalidreturnModel Range:" + rMap.getKey() + " must be between " 
+													+ startNum + " - "  + endNum + ",";
+											
+											if(value != null) {
+												if (PolicyUtils.isInteger(value.replace("\"", ""))){
+													int result = Integer.parseInt(value.replace("\"", ""));
+													if (result < startNum || result > endNum){
+														responseString.append(returnString);									
+														valid = false;
+													}
+												}else {
+													responseString.append(returnString);
+													valid = false;
+												}
+											} else {
+												responseString.append("<b>"+rMap.getKey()+"</b>:<i>" + rMap.getKey() 
+												+ " is required for the Optimization model " + service + HTML_ITALICS_LNBREAK);
+												valid = false;
+											}
+
+										}
+									}
+								}
+								
+								// If request comes from the API we need to validate required fields in the Micro Service Model 
+								// GUI request are already validated from the SDK-APP
+								if("API".equals(policyData.getApiflag())){
+									// get list of required fields from the sub_Attributes of the Model
+									if(!Strings.isNullOrEmpty(subAttributes)) {
+										JsonObject subAttributesJson = stringToJsonObject(subAttributes);
+										findRequiredFields(subAttributesJson);
+									}
+									
+									// get list of required fields from the attributes of the Model
+									if (!Strings.isNullOrEmpty(modelAttributes)) {
+										Map<String, String> modelAttributesMap = null;
+										if (",".equals(modelAttributes.substring(modelAttributes.length()-1))) {
+											String attributeString = modelAttributes.substring(0, modelAttributes.length()-1);
+											modelAttributesMap = Splitter.on(",").withKeyValueSeparator("=").split(attributeString);
+										} else {
+											modelAttributesMap = Splitter.on(",").withKeyValueSeparator("=").split(modelAttributes);
+										}
+										String json = new ObjectMapper().writeValueAsString(modelAttributesMap);
+										findRequiredFields(stringToJsonObject(json));
+									}
+									
+									// get list of required fields from the ref_Attributes of the Model
+									if (!Strings.isNullOrEmpty(refAttributes)) {
+										Map<String, String> refAttributesMap = null;
+										if (",".equals(refAttributes.substring(refAttributes.length()-1))) {
+											String attributesString = refAttributes.substring(0, refAttributes.length()-1);
+											refAttributesMap = Splitter.on(",").withKeyValueSeparator("=").split(attributesString);
+										} else {
+											refAttributesMap = Splitter.on(",").withKeyValueSeparator("=").split(modelAttributes);
+										}
+										String json = new ObjectMapper().writeValueAsString(refAttributesMap);
+										findRequiredFields(stringToJsonObject(json));
+									}
+									
+									if (modelRequiredFieldsList!=null || !modelRequiredFieldsList.isEmpty()) {
+										// create jsonRequestMap with all json keys and values from request
+										JsonNode rootNode = (JsonNode) policyData.getPolicyJSON();
+										jsonRequestMap.clear();
+										pullModelJsonKeyPairs(rootNode);
+										
+										// validate if the requiredFields are in the request
+										for(String requiredField : modelRequiredFieldsList) {
+											if (jsonRequestMap.containsKey(requiredField)) {
+												String value = jsonRequestMap.get(requiredField);
+												if(Strings.isNullOrEmpty(jsonRequestMap.get(requiredField)) || 
+														"\"\"".equals(value) || 
+														"".equals(jsonRequestMap.get(requiredField))){
+													responseString.append("<b>Optimization Service Model</b>:<i> " + requiredField + ISREQUIRED + HTML_ITALICS_LNBREAK);
+													valid = false; 
+												}
+											} else {
+												responseString.append("<b>Optimization Service Model</b>:<i> " + requiredField + ISREQUIRED + HTML_ITALICS_LNBREAK);
+												valid = false; 
+											}
+										}
+									}
+								}								
+							} else {
+								responseString.append("<b>Optimization Service Model</b>:<i> Invalid Model. The model name, " + service + 
+										" of version, " + version + " was not found in the dictionary" + HTML_ITALICS_LNBREAK);
+								valid = false;
+							}
+						} else {
+							responseString.append("<b>Optimization Service Version</b>:<i> Optimization Service Version is required" + HTML_ITALICS_LNBREAK);
+							valid = false;
+						}
+					} else {
+						responseString.append("<b>Optimization Service</b>:<i> Optimization Service Model is required" + HTML_ITALICS_LNBREAK);
+						valid = false;
+					}
+
+					if(Strings.isNullOrEmpty(policyData.getPriority())){
+						responseString.append("<b>Priority</b>:<i> Priority is required" + HTML_ITALICS_LNBREAK);
+						valid = false;
+					}
 				}	
 			}
 			if (DECISION_POLICY.equalsIgnoreCase(policyData.getPolicyType())){
@@ -864,7 +1022,7 @@
 		return res;
 	}
 
-	private MicroServiceModels getAttributeObject(String name, String version) {	
+	private MicroServiceModels getMSModelData(String name, String version) {	
 		MicroServiceModels workingModel = null;
 		try{
 			List<Object> microServiceModelsData = commonClassDao.getDataById(MicroServiceModels.class, "modelName:version", name+":"+version);
@@ -880,6 +1038,23 @@
 
 		return workingModel;
 	}
+	
+	private OptimizationModels getOptimizationModelData(String name, String version) {	
+		OptimizationModels workingModel = null;
+		try{
+			List<Object> optimizationModelsData = commonClassDao.getDataById(OptimizationModels.class, "modelName:version", name+":"+version);
+			if(optimizationModelsData != null){
+				workingModel = (OptimizationModels) optimizationModelsData.get(0);
+			}
+		}catch(Exception e){
+			String message = XACMLErrorConstants.ERROR_DATA_ISSUE + "Invalid Template.  The template name, " 
+                    + name + " was not found in the dictionary: ";
+			LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + message + e);
+			return null;
+		}
+
+		return workingModel;
+	}
 
 	private void pullJsonKeyPairs(JsonNode rootNode) {
 		Iterator<Map.Entry<String, JsonNode>> fieldsIterator = rootNode.fields();
diff --git a/ONAP-REST/src/main/java/org/onap/policy/rest/util/PolicyValidationRequestWrapper.java b/ONAP-REST/src/main/java/org/onap/policy/rest/util/PolicyValidationRequestWrapper.java
index 76584e7..c80e5bb 100644
--- a/ONAP-REST/src/main/java/org/onap/policy/rest/util/PolicyValidationRequestWrapper.java
+++ b/ONAP-REST/src/main/java/org/onap/policy/rest/util/PolicyValidationRequestWrapper.java
@@ -54,8 +54,18 @@
 	public static final String CONFIG_NAME="configName";
 	public static final String INVALIDJSON = " improper JSON format: ";
 	public static final String ONAPNAME = "onapname";
-	public static final String SERVICETYPE_POLICY_NAME = "serviceTypePolicyName";
+	public static final String CONTENT = "content";
+	public static final String GUARD = "guard";
+	public static final String LOCATION = "location";
+	public static final String POLICYSCOPE = "policyScope";
+	public static final String PRIORITY = "priority";
+	public static final String RISKLEVEL = "riskLevel";
+	public static final String RISKTYPE = "riskType";
+	public static final String SERVICE = "service";
+	public static final String VERSION = "version";
 
+	public static final String SERVICETYPE_POLICY_NAME = "serviceTypePolicyName";
+	
 	public PolicyRestAdapter populateRequestParameters(HttpServletRequest request) {
 		
 		PolicyRestAdapter policyData = null;
@@ -281,8 +291,8 @@
 				
 		        // get values and attributes from the JsonObject
 				if(json != null){
-					if (json.containsKey("content")){
-						String content = json.get("content").toString();
+					if (json.containsKey(CONTENT)){
+						String content = json.get(CONTENT).toString();
 						ObjectMapper mapper = new ObjectMapper();
 						JsonNode policyJSON = null;
 						try {
@@ -294,44 +304,44 @@
 				        }
 						policyData.setPolicyJSON(policyJSON);
 					}
-			        if (json.containsKey("service")){
-			        	String serviceType = json.get("service").toString().replace("\"", "");
+			        if (json.containsKey(SERVICE)){
+			        	String serviceType = json.get(SERVICE).toString().replace("\"", "");
 			        	policyData.setServiceType(serviceType);
 			        }
 			        if (json.containsKey("uuid")){
 			            String uuid = json.get("uuid").toString().replace("\"", "");
 			            policyData.setUuid(uuid);
 			        }
-			        if (json.containsKey("location")){
-			            String msLocation = json.get("location").toString().replace("\"", "");
+			        if (json.containsKey(LOCATION)){
+			            String msLocation = json.get(LOCATION).toString().replace("\"", "");
 			            policyData.setLocation(msLocation);
 			        }
 			        if (json.containsKey(CONFIG_NAME)){
 			            String configName = json.get(CONFIG_NAME).toString().replace("\"", "");
 			            policyData.setConfigName(configName);
 			        }
-			        if(json.containsKey("priority")){
-			        	String priority = json.get("priority").toString().replace("\"", "");
+			        if(json.containsKey(PRIORITY)){
+			        	String priority = json.get(PRIORITY).toString().replace("\"", "");
 			        	policyData.setPriority(priority);
 			        }
-			        if(json.containsKey("version")){
-			        	String version = json.get("version").toString().replace("\"", "");
+			        if(json.containsKey(VERSION)){
+			        	String version = json.get(VERSION).toString().replace("\"", "");
 			        	policyData.setVersion(version);
 			        }
-			        if(json.containsKey("policyScope")){
-			        	String policyScope = json.get("policyScope").toString().replace("\"", "");
+			        if(json.containsKey(POLICYSCOPE)){
+			        	String policyScope = json.get(POLICYSCOPE).toString().replace("\"", "");
 			        	policyData.setPolicyScope(policyScope);
 			        }
-			        if(json.containsKey("riskType")){
-			        	String riskType = json.get("riskType").toString().replace("\"", "");
+			        if(json.containsKey(RISKTYPE)){
+			        	String riskType = json.get(RISKTYPE).toString().replace("\"", "");
 			        	policyData.setRiskType(riskType);
 			        }
-			        if(json.containsKey("riskLevel")){
-			        	String riskLevel = json.get("riskLevel").toString().replace("\"", "");
+			        if(json.containsKey(RISKLEVEL)){
+			        	String riskLevel = json.get(RISKLEVEL).toString().replace("\"", "");
 			        	policyData.setRiskLevel(riskLevel);
 			        }
-			        if(json.containsKey("guard")){
-			        	String guard = json.get("guard").toString().replace("\"", "");
+			        if(json.containsKey(GUARD)){
+			        	String guard = json.get(GUARD).toString().replace("\"", "");
 			        	policyData.setGuard(guard);
 			        }
 				} else {
@@ -340,6 +350,67 @@
 		            return null;				
 				}
 				
+			}else if("Optimization".equals(parameters.getPolicyConfigType().toString())){
+				
+				policyData.setConfigPolicyType("Optimization");
+				
+		        // get values and attributes from the JsonObject
+				if(json != null){
+					if (json.containsKey(CONTENT)){
+						String content = json.get(CONTENT).toString();
+						ObjectMapper mapper = new ObjectMapper();
+						JsonNode policyJSON = null;
+						try {
+							policyJSON = mapper.readTree(content);
+						} catch (IOException e) {
+				            String message = XACMLErrorConstants.ERROR_DATA_ISSUE+ INVALIDJSON + parameters.getConfigBody();
+				            LOGGER.error(message, e);
+				            return null;					
+				        }
+						policyData.setPolicyJSON(policyJSON);
+					}
+			        if (json.containsKey(SERVICE)){
+			        	String serviceType = json.get(SERVICE).toString().replace("\"", "");
+			        	policyData.setServiceType(serviceType);
+			        }
+			        if (json.containsKey("uuid")){
+			            String uuid = json.get("uuid").toString().replace("\"", "");
+			            policyData.setUuid(uuid);
+			        }
+			        if (json.containsKey(LOCATION)){
+			            String msLocation = json.get(LOCATION).toString().replace("\"", "");
+			            policyData.setLocation(msLocation);
+			        }
+			        if (json.containsKey(CONFIG_NAME)){
+			            String configName = json.get(CONFIG_NAME).toString().replace("\"", "");
+			            policyData.setConfigName(configName);
+			        }
+			        if(json.containsKey(PRIORITY)){
+			        	String priority = json.get(PRIORITY).toString().replace("\"", "");
+			        	policyData.setPriority(priority);
+			        }
+			        if(json.containsKey(VERSION)){
+			        	String version = json.get(VERSION).toString().replace("\"", "");
+			        	policyData.setVersion(version);
+			        }
+			        if(json.containsKey(POLICYSCOPE)){
+			        	String policyScope = json.get(POLICYSCOPE).toString().replace("\"", "");
+			        	policyData.setPolicyScope(policyScope);
+			        }
+			        if(json.containsKey(RISKTYPE)){
+			        	String riskType = json.get(RISKTYPE).toString().replace("\"", "");
+			        	policyData.setRiskType(riskType);
+			        }
+			        if(json.containsKey(RISKLEVEL)){
+			        	String riskLevel = json.get(RISKLEVEL).toString().replace("\"", "");
+			        	policyData.setRiskLevel(riskLevel);
+			        }
+			        if(json.containsKey(GUARD)){
+			        	String guard = json.get(GUARD).toString().replace("\"", "");
+			        	policyData.setGuard(guard);
+			        }
+				}
+				
 			} else if("Fault".equals(parameters.getPolicyConfigType().toString())){
 				
 				policyData.setConfigPolicyType("ClosedLoop_Fault");
diff --git a/ONAP-REST/src/test/java/org/onap/policy/rest/jpa/OptimizationModelsJPATest.java b/ONAP-REST/src/test/java/org/onap/policy/rest/jpa/OptimizationModelsJPATest.java
new file mode 100644
index 0000000..cd7360c
--- /dev/null
+++ b/ONAP-REST/src/test/java/org/onap/policy/rest/jpa/OptimizationModelsJPATest.java
@@ -0,0 +1,71 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP-REST
+ * ================================================================================
+ * Copyright (C) 2018 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.rest.jpa;
+
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.policy.common.logging.flexlogger.FlexLogger;
+import org.onap.policy.common.logging.flexlogger.Logger;
+
+public class OptimizationModelsJPATest {
+
+	private static Logger logger = FlexLogger.getLogger(OptimizationModelsJPATest.class);
+	private UserInfo userInfo;
+	
+	@Before
+	public void setUp() throws Exception {
+		logger.info("setUp: Entering");
+		userInfo = new UserInfo();
+		userInfo.setUserLoginId("Test");
+		userInfo.setUserName("Test");
+		logger.info("setUp: exit");
+	}
+	
+	@Test
+	public void testMSModels(){
+		OptimizationModels data = new OptimizationModels();
+		data.setId(1);
+		assertTrue(1 == data.getId());
+		data.setModelName("Test");
+		assertTrue("Test".equals(data.getModelName()));
+		data.setDescription("Test");
+		assertTrue("Test".equals(data.getDescription()));
+		data.setDependency("Test");
+		assertTrue("Test".equals(data.getDependency()));
+		data.setEnumValues("Test");
+		assertTrue("Test".equals(data.getEnumValues()));
+		data.setAnnotation("Test");
+		assertTrue("Test".equals(data.getAnnotation()));
+		data.setAttributes("Test");
+		assertTrue("Test".equals(data.getAttributes()));
+		data.setRefattributes("Test");
+		assertTrue("Test".equals(data.getRefattributes()));
+		data.setUserCreatedBy(userInfo);
+		assertTrue(data.getUserCreatedBy()!=null);
+		data.setSubattributes("Test");
+		assertTrue("Test".equals(data.getSubattributes()));
+		data.setVersion("Test");
+		assertTrue("Test".equals(data.getVersion()));
+	}
+	
+	
+}
diff --git a/ONAP-SDK-APP/xacml.admin.properties b/ONAP-SDK-APP/xacml.admin.properties
index 5628d8d..6d6570f 100644
--- a/ONAP-SDK-APP/xacml.admin.properties
+++ b/ONAP-SDK-APP/xacml.admin.properties
@@ -152,6 +152,7 @@
 xacml.rest.microServices=OpenSource.version.1
 xacml.rest.gocPolicy=OpenSource.version.1
 xacml.rest.firewallPolicy=OpenSource.version.1
+xacml.rest.optimization=OpenSource.version.1
 
 #***Properties for IntegrityMonitor integration defined in XACMLRestProperties.java***
 
diff --git a/ONAP-XACML/src/main/java/org/onap/policy/xacml/util/XACMLPolicyWriter.java b/ONAP-XACML/src/main/java/org/onap/policy/xacml/util/XACMLPolicyWriter.java
index cb3d448..168bc54 100644
--- a/ONAP-XACML/src/main/java/org/onap/policy/xacml/util/XACMLPolicyWriter.java
+++ b/ONAP-XACML/src/main/java/org/onap/policy/xacml/util/XACMLPolicyWriter.java
@@ -227,7 +227,7 @@
 										AdviceExpressionType adviceExpressionType = (AdviceExpressionType) iterator
 												.next();
 										if (adviceExpressionType.getAdviceId() != null && !"".equals(adviceExpressionType.getAdviceId()) && ("configID".equals(adviceExpressionType.getAdviceId())
-												|| "faultID".equals(adviceExpressionType.getAdviceId()) || "PMID".equals(adviceExpressionType.getAdviceId())||"firewallConfigID".equals(adviceExpressionType.getAdviceId()) 
+												|| "faultID".equals(adviceExpressionType.getAdviceId()) || "PMID".equals(adviceExpressionType.getAdviceId())||"firewallConfigID".equals(adviceExpressionType.getAdviceId()) || "OptimizationID".equals(adviceExpressionType.getAdviceId())
 												|| "MSID".equals(adviceExpressionType.getAdviceId())) || "GocID".equals(adviceExpressionType.getAdviceId())||"GocHPID".equals(adviceExpressionType.getAdviceId())||"BRMSRAWID".equals(adviceExpressionType.getAdviceId())
 												|| "BRMSPARAMID".equals(adviceExpressionType.getAdviceId())|| "HPSuppID".equals(adviceExpressionType.getAdviceId()) || "HPFlapID".equals(adviceExpressionType.getAdviceId()) || "HPOverID".equals(adviceExpressionType.getAdviceId()))
 										{
diff --git a/POLICY-SDK-APP/src/main/java/org/onap/policy/admin/PolicyAdapter.java b/POLICY-SDK-APP/src/main/java/org/onap/policy/admin/PolicyAdapter.java
index 42010f1..c1d1e9c 100644
--- a/POLICY-SDK-APP/src/main/java/org/onap/policy/admin/PolicyAdapter.java
+++ b/POLICY-SDK-APP/src/main/java/org/onap/policy/admin/PolicyAdapter.java
@@ -29,6 +29,7 @@
 import org.onap.policy.controller.CreateClosedLoopPMController;
 import org.onap.policy.controller.CreateDcaeMicroServiceController;
 import org.onap.policy.controller.CreateFirewallController;
+import org.onap.policy.controller.CreateOptimizationController;
 import org.onap.policy.controller.CreatePolicyController;
 import org.onap.policy.controller.DecisionPolicyController;
 import org.onap.policy.rest.adapter.PolicyRestAdapter;
@@ -58,6 +59,8 @@
 			configPolicyName = "BRMS_Param";
 		}else if(policyAdapter.getPolicyName().startsWith("Config_MS")){
 			configPolicyName = "Micro Service";
+		}else if(policyAdapter.getPolicyName().startsWith("Config_OOF")){
+			configPolicyName = "Optimization";
 		}else if(policyAdapter.getPolicyName().startsWith("Action") || policyAdapter.getPolicyName().startsWith("Decision") ){
 			// No configPolicyName is applicable
 		}else{
@@ -95,6 +98,9 @@
 			else if("Micro Service".equalsIgnoreCase(policyAdapter.getConfigPolicyType())){
 				new CreateDcaeMicroServiceController().prePopulateDCAEMSPolicyData(policyAdapter, entity);
 			}
+			else if("Optimization".equalsIgnoreCase(policyAdapter.getConfigPolicyType())){
+				new CreateOptimizationController().prePopulatePolicyData(policyAdapter, entity);
+			}
 			else if("Firewall Config".equalsIgnoreCase(policyAdapter.getConfigPolicyType())){
 				new CreateFirewallController().prePopulateFWPolicyData(policyAdapter, entity);
 			}
diff --git a/POLICY-SDK-APP/src/main/java/org/onap/policy/admin/PolicyRestController.java b/POLICY-SDK-APP/src/main/java/org/onap/policy/admin/PolicyRestController.java
index 801d4ec..8df9d1b 100644
--- a/POLICY-SDK-APP/src/main/java/org/onap/policy/admin/PolicyRestController.java
+++ b/POLICY-SDK-APP/src/main/java/org/onap/policy/admin/PolicyRestController.java
@@ -45,6 +45,7 @@
 import org.onap.policy.controller.CreateClosedLoopFaultController;
 import org.onap.policy.controller.CreateDcaeMicroServiceController;
 import org.onap.policy.controller.CreateFirewallController;
+import org.onap.policy.controller.CreateOptimizationController;
 import org.onap.policy.controller.PolicyController;
 import org.onap.policy.rest.XACMLRestProperties;
 import org.onap.policy.rest.adapter.PolicyRestAdapter;
@@ -79,7 +80,7 @@
 
 	private static final Logger policyLogger = FlexLogger.getLogger(PolicyRestController.class);
 	
-	private static final String modal = "model";
+	private static final String model = "model";
 	private static final String importDictionary = "import_dictionary";
 	
 	private static CommonClassDao commonClassDao;
@@ -117,21 +118,21 @@
 			
 			PolicyRestAdapter policyData = mapper.readValue(root.get(PolicyController.getPolicydata()).get("policy").toString(), PolicyRestAdapter.class);
 
-			if("file".equals(root.get(PolicyController.getPolicydata()).get(modal).get("type").toString().replace("\"", ""))){
+			if("file".equals(root.get(PolicyController.getPolicydata()).get(model).get("type").toString().replace("\"", ""))){
 				policyData.setEditPolicy(true);
 			}
-			if(root.get(PolicyController.getPolicydata()).get(modal).get("path").size() != 0){
+			if(root.get(PolicyController.getPolicydata()).get(model).get("path").size() != 0){
 				String dirName = "";
-				for(int i = 0; i < root.get(PolicyController.getPolicydata()).get(modal).get("path").size(); i++){
-					dirName = dirName.replace("\"", "") + root.get(PolicyController.getPolicydata()).get(modal).get("path").get(i).toString().replace("\"", "") + File.separator;
+				for(int i = 0; i < root.get(PolicyController.getPolicydata()).get(model).get("path").size(); i++){
+					dirName = dirName.replace("\"", "") + root.get(PolicyController.getPolicydata()).get(model).get("path").get(i).toString().replace("\"", "") + File.separator;
 				}
 				if(policyData.isEditPolicy()){
 					policyData.setDomainDir(dirName.substring(0, dirName.lastIndexOf(File.separator)));
 				}else{
-					policyData.setDomainDir(dirName + root.get(PolicyController.getPolicydata()).get(modal).get("name").toString().replace("\"", ""));
+					policyData.setDomainDir(dirName + root.get(PolicyController.getPolicydata()).get(model).get("name").toString().replace("\"", ""));
 				}
 			}else{
-				String domain = root.get(PolicyController.getPolicydata()).get(modal).get("name").toString();
+				String domain = root.get(PolicyController.getPolicydata()).get(model).get("name").toString();
 				if(domain.contains("/")){
 					domain = domain.substring(0, domain.lastIndexOf('/')).replace("/", File.separator);
 				}
@@ -146,6 +147,8 @@
 					policyData = new CreateFirewallController().setDataToPolicyRestAdapter(policyData);
 				}else if("Micro Service".equalsIgnoreCase(policyData.getConfigPolicyType())){
 					policyData = new CreateDcaeMicroServiceController().setDataToPolicyRestAdapter(policyData, root);
+				}else if("Optimization".equalsIgnoreCase(policyData.getConfigPolicyType())){
+					policyData = new CreateOptimizationController().setDataToPolicyRestAdapter(policyData, root);
 				}
 			}
 
diff --git a/POLICY-SDK-APP/src/main/java/org/onap/policy/controller/CreateDcaeMicroServiceController.java b/POLICY-SDK-APP/src/main/java/org/onap/policy/controller/CreateDcaeMicroServiceController.java
index 422c18a..0f315a3 100644
--- a/POLICY-SDK-APP/src/main/java/org/onap/policy/controller/CreateDcaeMicroServiceController.java
+++ b/POLICY-SDK-APP/src/main/java/org/onap/policy/controller/CreateDcaeMicroServiceController.java
@@ -2,7 +2,7 @@
  * ============LICENSE_START=======================================================
  * ONAP Policy Engine
  * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2017-2018 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.
@@ -24,11 +24,8 @@
 import java.io.BufferedInputStream;
 import java.io.BufferedOutputStream;
 import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
-import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.PrintWriter;
 import java.io.StringReader;
@@ -36,7 +33,6 @@
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -78,6 +74,7 @@
 import org.onap.policy.rest.dao.CommonClassDao;
 import org.onap.policy.rest.jpa.GroupPolicyScopeList;
 import org.onap.policy.rest.jpa.MicroServiceModels;
+import org.onap.policy.rest.jpa.MicroserviceHeaderdeFaults;
 import org.onap.policy.rest.jpa.PolicyEntity;
 import org.onap.policy.rest.util.MSAttributeObject;
 import org.onap.policy.rest.util.MSModelUtils;
@@ -89,8 +86,6 @@
 import org.springframework.stereotype.Controller;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.servlet.ModelAndView;
-import org.yaml.snakeyaml.Yaml;
-
 import com.att.research.xacml.util.XACMLProperties;
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.DeserializationFeature;
@@ -113,7 +108,7 @@
 @RequestMapping("/")
 public class CreateDcaeMicroServiceController extends RestrictedBaseController {
 	private static final Logger LOGGER = FlexLogger.getLogger(CreateDcaeMicroServiceController.class);
-	private Map<String, String>  matchableValues;
+
 	private static CommonClassDao commonClassDao;
 	
 	public static CommonClassDao getCommonClassDao() {
@@ -129,19 +124,11 @@
 	private String directory;
 	private List<String> modelList = new ArrayList<>();
 	private List<String> dirDependencyList = new ArrayList<>();
-	private HashMap<String,MSAttributeObject > classMap = new HashMap<>();
-	//Tosca Model related Datastructure. 
+	private LinkedHashMap<String,MSAttributeObject > classMap = new LinkedHashMap<>();
 	String referenceAttributes;
 	String attributeString;
-	String listConstraints;
-	String subAttributeString;
-	HashMap<String, Object> retmap = new HashMap<>();
-	Set<String> uniqueKeys= new HashSet<>();
-	Set<String> uniqueDataKeys= new HashSet<>();
-	StringBuilder dataListBuffer=new StringBuilder();
-	List<String> dataConstraints= new ArrayList <>();
 	Set<String> allManyTrueKeys= new HashSet <>();
-	
+
 	public static final String DATATYPE  = "data_types.policy.data.";
 	public static final String PROPERTIES=".properties.";
 	public static final String TYPE=".type";
@@ -150,8 +137,9 @@
 	public static final String LIST="list";
 	public static final String DEFAULT=".default";
 	public static final String REQUIRED=".required";
-	public static final String MANYFALSE=":MANY-false";
 	public static final String MATCHABLE=".matchable";
+	public static final String MANYFALSE=":MANY-false";
+	
 	
 	@Autowired
 	private CreateDcaeMicroServiceController(CommonClassDao commonClassDao){
@@ -260,7 +248,7 @@
 		return policyAdapter;
 	}
 	
-	private String removeNullAttributes(String cleanJson) {
+	public String removeNullAttributes(String cleanJson) {
 		ObjectMapper mapper = new ObjectMapper();
 
 		try {
@@ -385,446 +373,7 @@
 	    return builder.build();
 	}
 	
-	// Second index of dot should be returned. 
-	public int stringBetweenDots(String str){
-		String stringToSearch=str;
-		String[]ss=stringToSearch.split("\\.");
-		if(ss!=null){
-			int len= ss.length;
-			if(len>2){
-				uniqueKeys.add(ss[2]);
-			}
-		}
-		
-		return uniqueKeys.size();
-	}
-	
-	public void stringBetweenDotsForDataFields(String str){
-		String stringToSearch=str;
-		String[]ss=stringToSearch.split("\\.");
-		if(ss!=null){
-			int len= ss.length;
-
-			if(len>2){
-				uniqueDataKeys.add(ss[0]+"%"+ss[2]);
-			}
-		}
-	}
-	
- 
-	@SuppressWarnings("unchecked")
-	public Map<String, String> load(String fileName) throws IOException { 
-		File newConfiguration = new File(fileName);
-		Yaml yaml = new Yaml();
-		Map<Object, Object> yamlMap = null;
-		try(InputStream is = new FileInputStream(newConfiguration)){
-			yamlMap = (Map<Object, Object>) yaml.load(is); 
-		} catch (FileNotFoundException e) {
-			LOGGER.error(e);
-		}
-
-		StringBuilder sb = new StringBuilder(); 
-		Map<String, String> settings = new HashMap<>(); 
-		if (yamlMap == null) { 
-			return settings; 
-		} 
-		List<String> path = new ArrayList <>(); 
-		serializeMap(settings, sb, path, yamlMap); 
-		return settings; 
-	} 
-
-	public Map<String, String> load(byte[] source) { 
-		Yaml yaml = new Yaml(); 
-		@SuppressWarnings("unchecked")
-		Map<Object, Object> yamlMap = (Map<Object, Object>) yaml.load(Arrays.toString(source)); 
-		StringBuilder sb = new StringBuilder(); 
-		Map<String, String> settings = new HashMap <>(); 
-		if (yamlMap == null) { 
-			return settings; 
-		} 
-		List<String> path = new ArrayList <>(); 
-		serializeMap(settings, sb, path, yamlMap); 
-		return settings; 
-	} 
-
-	@SuppressWarnings({ "unchecked", "rawtypes" })
-	private void serializeMap(Map<String, String> settings, StringBuilder sb, List<String> path, Map<Object, Object> yamlMap) { 
-		for (Map.Entry<Object, Object> entry : yamlMap.entrySet()) { 
-			if (entry.getValue() instanceof Map) { 
-				path.add((String) entry.getKey()); 
-				serializeMap(settings, sb, path, (Map<Object, Object>) entry.getValue()); 
-				path.remove(path.size() - 1); 
-			} else if (entry.getValue() instanceof List) { 
-				path.add((String) entry.getKey()); 
-				serializeList(settings, sb, path, (List) entry.getValue()); 
-				path.remove(path.size() - 1); 
-			} else { 
-				serializeValue(settings, sb, path, (String) entry.getKey(), entry.getValue()); 
-			} 
-		} 
-	} 
-
-	@SuppressWarnings("unchecked")
-	private void serializeList(Map<String, String> settings, StringBuilder sb, List<String> path, List<String> yamlList) { 
-		int counter = 0; 
-		for (Object listEle : yamlList) { 
-			if (listEle instanceof Map) { 
-				path.add(Integer.toString(counter)); 
-				serializeMap(settings, sb, path, (Map<Object, Object>) listEle); 
-				path.remove(path.size() - 1); 
-			} else if (listEle instanceof List) { 
-				path.add(Integer.toString(counter)); 
-				serializeList(settings, sb, path, (List<String>) listEle); 
-				path.remove(path.size() - 1); 
-			} else { 
-				serializeValue(settings, sb, path, Integer.toString(counter), listEle); 
-			} 
-			counter++; 
-		} 
-	} 
-
-	private void serializeValue(Map<String, String> settings, StringBuilder sb, List<String> path, String name, Object value) { 
-		if (value == null) { 
-			return; 
-		} 
-		sb.setLength(0); 
-		for (String pathEle : path) { 
-			sb.append(pathEle).append('.'); 
-		} 
-		sb.append(name); 
-		settings.put(sb.toString(), value.toString()); 
-	} 
-    
-	void parseDataAndPolicyNodes(Map<String,String> map){
-		for(String key:map.keySet()){
-			if(key.contains("policy.nodes.Root"))
-			{
-				continue;
-			}
-			else if(key.contains("policy.nodes")){
-				String wordToFind = "policy.nodes.";
-				int indexForPolicyNode=key.indexOf(wordToFind);
-				String subNodeString= key.substring(indexForPolicyNode+13, key.length());
-
-				stringBetweenDots(subNodeString);
-			}
-			else if(key.contains("policy.data")){
-				String wordToFind="policy.data.";
-				int indexForPolicyNode=key.indexOf(wordToFind);
-				String subNodeString= key.substring(indexForPolicyNode+12, key.length());
-
-				stringBetweenDotsForDataFields(subNodeString);
-			}
-		}
-	}
-	
-	HashMap<String,String> parseDataNodes(Map<String,String> map){
-		HashMap<String,String> dataMapForJson=new HashMap <>(); 
-		matchableValues = new HashMap <>(); 
-		for(String uniqueDataKey: uniqueDataKeys){
-			if(uniqueDataKey.contains("%")){
-				String[] uniqueDataKeySplit= uniqueDataKey.split("%");
-				String findType=DATATYPE+uniqueDataKeySplit[0]+PROPERTIES+uniqueDataKeySplit[1]+TYPE;
-				String typeValue=map.get(findType);
-				LOGGER.info(typeValue);
-				if(typeValue != null && typeValue.equalsIgnoreCase(STRING)||
-						typeValue.equalsIgnoreCase(INTEGER)
-				  )
-				{
-					String findDefault=DATATYPE+uniqueDataKeySplit[0]+PROPERTIES+uniqueDataKeySplit[1]+DEFAULT;
-					String defaultValue= map.get(findDefault);
-					LOGGER.info("defaultValue is:"+ defaultValue);
-					
-					String findRequired=DATATYPE+uniqueDataKeySplit[0]+PROPERTIES+uniqueDataKeySplit[1]+REQUIRED;
-					String requiredValue= map.get(findRequired);
-					LOGGER.info("requiredValue is:"+ requiredValue);
-					
-					String matchable =DATATYPE+uniqueDataKeySplit[0]+PROPERTIES+uniqueDataKeySplit[1]+MATCHABLE;
-
-					String matchableValue= map.get(matchable);
-
-					if("true".equalsIgnoreCase(matchableValue)){						
-						String key=uniqueDataKeySplit[uniqueDataKeySplit.length -1];
-						matchableValues.put(key, "matching-true");						
-					}
-					
-					StringBuilder attributeIndividualStringBuilder= new StringBuilder();
-					attributeIndividualStringBuilder.append(typeValue+":defaultValue-");
-					attributeIndividualStringBuilder.append(defaultValue+":required-");
-					attributeIndividualStringBuilder.append(requiredValue+MANYFALSE);
-					dataMapForJson.put(uniqueDataKey, attributeIndividualStringBuilder.toString());		
-				}
-				else if(typeValue != null && typeValue.equalsIgnoreCase(LIST)){
-					
-
-					String findList= DATATYPE+uniqueDataKeySplit[0]+PROPERTIES+uniqueDataKeySplit[1]+".entry_schema.type";
-					String listValue=map.get(findList);
-					if(listValue!=null){
-						LOGGER.info("Type of list is:"+ listValue);
-						//Its userdefined
-						if(listValue.contains(".")){
-							String trimValue=listValue.substring(listValue.lastIndexOf('.')+1);
-							StringBuilder referenceIndividualStringBuilder= new StringBuilder();
-							referenceIndividualStringBuilder.append(trimValue+":MANY-true");
-							dataMapForJson.put(uniqueDataKey, referenceIndividualStringBuilder.toString());
-						}//Its string
-						else{
-							StringBuilder stringListItems= new StringBuilder();
-							stringListItems.append(uniqueDataKeySplit[1].toUpperCase()+":MANY-false");
-							dataMapForJson.put(uniqueDataKey, stringListItems.toString());
-							dataListBuffer.append(uniqueDataKeySplit[1].toUpperCase()+"=[");
-							for(int i=0;i<10;i++){
-								String findConstraints= DATATYPE+uniqueDataKeySplit[0]+PROPERTIES+uniqueDataKeySplit[1]+".entry_schema.constraints.0.valid_values."+i;
-								String constraintsValue=map.get(findConstraints);
-								LOGGER.info(constraintsValue);
-								if(constraintsValue==null){
-									break;
-								}
-								else{
-									if(constraintsValue.contains("=")){
-										constraintsValue = constraintsValue.replace("=", "equal-sign");
-									}
-									dataConstraints.add(constraintsValue);
-									dataListBuffer.append(constraintsValue+",");
-								}
-							}
-							dataListBuffer.append("]#");
-							
-							LOGGER.info(dataListBuffer);
-						}
-					}
-				}
-				else{
-					String findUserDefined="data_types.policy.data."+uniqueDataKeySplit[0]+"."+"properties"+"."+uniqueDataKeySplit[1]+".type";
-					String userDefinedValue=map.get(findUserDefined);
-					String trimValue=userDefinedValue.substring(userDefinedValue.lastIndexOf('.')+1);
-					StringBuilder referenceIndividualStringBuilder= new StringBuilder();
-					referenceIndividualStringBuilder.append(trimValue+":MANY-false");
-					dataMapForJson.put(uniqueDataKey, referenceIndividualStringBuilder.toString());
-					
-				}
-			}else{
-				matchableValues.put(uniqueDataKey, "matching-true");
-			}
-		}
-		return dataMapForJson;
-	}
-	
-	void constructJsonForDataFields(HashMap<String,String> dataMapForJson){
-		HashMap<String,HashMap<String,String>> dataMapKey= new HashMap <>();
-		HashMap<String,String> hmSub;
-		for(Map.Entry<String, String> entry: dataMapForJson.entrySet()){
-			String uniqueDataKey= entry.getKey();
-			String[] uniqueDataKeySplit=uniqueDataKey.split("%");
-			String value= dataMapForJson.get(uniqueDataKey);
-			if(dataMapKey.containsKey(uniqueDataKeySplit[0])){
-				hmSub = dataMapKey.get(uniqueDataKeySplit[0]);
-				hmSub.put(uniqueDataKeySplit[1], value);
-			}
-			else{
-				hmSub=new HashMap <>();
-				hmSub.put(uniqueDataKeySplit[1], value);
-			}
-				
-			dataMapKey.put(uniqueDataKeySplit[0], hmSub);
-		}
-				
-		JSONObject mainObject= new JSONObject();
-		JSONObject json;
-		for(Map.Entry<String,HashMap<String,String>> entry: dataMapKey.entrySet()){
-			String s=entry.getKey();
-			json= new JSONObject();
-			HashMap<String,String> jsonHm=dataMapKey.get(s);
-			for(Map.Entry<String,String> entryMap:jsonHm.entrySet()){
-				String key=entryMap.getKey();
-				json.put(key, jsonHm.get(key));
-			}
-			mainObject.put(s,json);
-		}	
-		Iterator<String> keysItr = mainObject.keys();
-		while(keysItr.hasNext()) {
-			String key = keysItr.next();
-			String value = mainObject.get(key).toString();
-			retmap.put(key, value);
-		}
-		
-		LOGGER.info("#############################################################################");
-		LOGGER.info(mainObject);
-		LOGGER.info("###############################################################################");	
-	}
-	
-	
-	HashMap<String,HashMap<String,String>> parsePolicyNodes(Map<String,String> map){
-		HashMap<String,HashMap<String,String>> mapKey= new HashMap <>();
-		for(String uniqueKey: uniqueKeys){
-			HashMap<String,String> hm;
-
-			for(Map.Entry<String,String> entry:map.entrySet()){
-				String key=entry.getKey();
-				if(key.contains(uniqueKey) && key.contains("policy.nodes")){
-					if(mapKey.containsKey(uniqueKey)){
-						hm = mapKey.get(uniqueKey);
-						String keyStr= key.substring(key.lastIndexOf('.')+1);
-						String valueStr= map.get(key);
-						if(("type").equals(keyStr)){
-							if(!key.contains("entry_schema"))
-							{
-								hm.put(keyStr,valueStr);
-							}
-						}else{
-							hm.put(keyStr,valueStr);
-						}
-
-					} else {
-						hm = new HashMap <>();
-						String keyStr= key.substring(key.lastIndexOf('.')+1);
-						String valueStr= map.get(key);
-						if(("type").equals(keyStr)){
-							if(!key.contains("entry_schema"))
-							{
-								hm.put(keyStr,valueStr);
-							}
-						}else{
-							hm.put(keyStr,valueStr);
-						}
-						mapKey.put(uniqueKey, hm);
-					}
-				}
-			}
-		}
-		return mapKey;
-	}
-
-	void createAttributes(HashMap<String,HashMap<String,String>> mapKey){
-		StringBuilder attributeStringBuilder= new StringBuilder();
-		StringBuilder referenceStringBuilder= new StringBuilder();
-		StringBuilder listBuffer= new StringBuilder();
-		List<String> constraints= new ArrayList<>();
-		for(Map.Entry<String,HashMap<String,String>> entry: mapKey.entrySet()){
-			String keySetString= entry.getKey();
-			HashMap<String,String> keyValues=mapKey.get(keySetString);
-			if(keyValues.get("type") != null && keyValues.get("type").equalsIgnoreCase(STRING)||
-					keyValues.get("type") != null && keyValues.get("type").equalsIgnoreCase(INTEGER)
-					){
-				StringBuilder attributeIndividualStringBuilder= new StringBuilder();
-				attributeIndividualStringBuilder.append(keySetString+"=");
-				attributeIndividualStringBuilder.append(keyValues.get("type")+":defaultValue-");
-				attributeIndividualStringBuilder.append(keyValues.get("default")+":required-");
-				attributeIndividualStringBuilder.append(keyValues.get("required")+":MANY-false");
-				attributeStringBuilder.append(attributeIndividualStringBuilder+",");	
-                if("true".equalsIgnoreCase(keyValues.get("matchable"))){
-				    matchableValues.put(keySetString, "matching-true");
-                }
-			}
-			else if(keyValues.get("type") != null && keyValues.get("type").equalsIgnoreCase(LIST)){
-				
-                if("true".equalsIgnoreCase(keyValues.get("matchable"))){
-				    matchableValues.put(keySetString, "matching-true");
-                }
-				//List Datatype
-				Set<String> keys= keyValues.keySet();
-				Iterator<String> itr=keys.iterator();
-				boolean isDefinedType = false;
-				while(itr.hasNext()){
-					String key= itr.next();
-					if(!("type").equals(key) ||("required").equals(key))
-					{
-						String value= keyValues.get(key);
-						//The "." in the value determines if its a string or a user defined type.  
-						if (!value.contains(".")){
-							//This is string
-							if(StringUtils.isNumeric(key) ){  //only integer key for the value of Constrains 
-							    constraints.add(keyValues.get(key));
-							}
-						}else{
-							//This is user defined type
-							String trimValue=value.substring(value.lastIndexOf('.')+1);
-							StringBuilder referenceIndividualStringBuilder= new StringBuilder();
-							referenceIndividualStringBuilder.append(keySetString+"="+trimValue+":MANY-true");
-							referenceStringBuilder.append(referenceIndividualStringBuilder+",");
-							isDefinedType = true;
-						}
-					}				
-
-				}
-
-				if(!isDefinedType && keyValues.get("type").equalsIgnoreCase(LIST) &&
-					(constraints == null || constraints.isEmpty()) ) {   //type is list but no constraints defined.
-						referenceStringBuilder.append(keySetString+"=MANY-true"+",");
-				}
-			}else{
-				//User defined Datatype. 
-                if("true".equalsIgnoreCase(keyValues.get("matchable"))){
-				    matchableValues.put(keySetString, "matching-true");
-                }
-				String value=keyValues.get("type");
-				if(value != null && !value.isEmpty()){
-					String trimValue=value.substring(value.lastIndexOf('.')+1);
-					StringBuilder referenceIndividualStringBuilder= new StringBuilder();
-					referenceIndividualStringBuilder.append(keySetString+"="+trimValue+":MANY-false");
-					referenceStringBuilder.append(referenceIndividualStringBuilder+",");
-				}else{
-					LOGGER.info("keyValues.get(type) is null/empty");
-				}
-
-			}
-			if(constraints!=null && ! constraints.isEmpty()){
-				//List handling. 
-				listBuffer.append(keySetString.toUpperCase()+"=[");
-				for(String str:constraints){
-					listBuffer.append(str+",");
-				}
-				listBuffer.append("]#");
-				LOGGER.info(listBuffer);
-
-
-				StringBuilder referenceIndividualStringBuilder= new StringBuilder();
-				referenceIndividualStringBuilder.append(keySetString+"="+keySetString.toUpperCase()+":MANY-false");
-				referenceStringBuilder.append(referenceIndividualStringBuilder+",");
-				constraints.clear();
-			}
-		}
-		
-		dataListBuffer.append(listBuffer);
-		
-
-		LOGGER.info("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$");
-		LOGGER.info("Whole attribute String is:"+attributeStringBuilder);	
-		LOGGER.info("Whole reference String is:"+referenceStringBuilder);
-		LOGGER.info("List String is:"+listBuffer);
-		LOGGER.info("Data list buffer is:"+dataListBuffer);
-		LOGGER.info("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$");
-		
-		this.listConstraints=dataListBuffer.toString();
-		this.referenceAttributes=referenceStringBuilder.toString();
-		this.attributeString=attributeStringBuilder.toString();
-	}
-	
-	
-    
-	public void parseTosca (String fileName){
-		Map<String,String> map= new HashMap<>();
-    
-    	try {
-			map=load(fileName);
-			
-			parseDataAndPolicyNodes(map);
-			
-			HashMap<String,String> dataMapForJson=parseDataNodes(map);
-			
-			constructJsonForDataFields(dataMapForJson);	
-			
-			HashMap<String,HashMap<String,String>> mapKey= parsePolicyNodes(map);
-			
-			createAttributes(mapKey);
-		
-    	} catch (IOException e) {
-    		LOGGER.error(e);
-    	}
-	
-	} 
-
-	private String cleanUPJson(String json) {
+	public String cleanUPJson(String json) {
 		String cleanJson = StringUtils.replaceEach(json, new String[]{"\\\\", "\\\\\\", "\\\\\\\\"}, new String[]{"\\", "\\", "\\"});
 		cleanJson = StringUtils.replaceEach(cleanJson, new String[]{"\\\\\\"}, new String[]{"\\"});
 		cleanJson = StringUtils.replaceEach(cleanJson, new String[]{"\\\\", "[[", "]]"}, new String[]{"\\", "[", "]"});
@@ -842,7 +391,7 @@
 		return cleanJson;
 	}
 	
-	private JSONObject decodeContent(JsonNode jsonNode){
+	public JSONObject decodeContent(JsonNode jsonNode){
 		Iterator<JsonNode> jsonElements = jsonNode.elements();
 		Iterator<String> jsonKeys = jsonNode.fieldNames();
 		Map<String,String> element = new TreeMap<>();
@@ -1004,6 +553,22 @@
 		}
 		MicroServiceModels returnModel = getAttributeObject(servicename, version);
 		
+		MicroserviceHeaderdeFaults returnHeaderDefauls = getHeaderDefaultsObject(value);
+		JSONObject jsonHdDefaultObj = null;
+		if(returnHeaderDefauls != null){
+			jsonHdDefaultObj = new JSONObject();
+			jsonHdDefaultObj.put("onapName", returnHeaderDefauls.getOnapName());
+			jsonHdDefaultObj.put("guard", returnHeaderDefauls.getGuard());
+			jsonHdDefaultObj.put("riskLevel", returnHeaderDefauls.getRiskLevel());
+			jsonHdDefaultObj.put("riskType", returnHeaderDefauls.getRiskType());
+			jsonHdDefaultObj.put("priority", returnHeaderDefauls.getPriority());
+		}
+		String headDefautlsData = "";
+		if(jsonHdDefaultObj != null){			
+			headDefautlsData = jsonHdDefaultObj.toString();
+		}else{
+			headDefautlsData = "null";
+		}
 		
 		//Get all keys with "MANY-true" defined in their value from subAttribute 
 		Set<String> allkeys = null;
@@ -1015,9 +580,12 @@
 			LOGGER.info("allkeys : " + allkeys);
 		}
 		
-		String nameOfTrueKey = "";
+		//Get element order info 
+		String dataOrderInfo = returnModel.getDataOrderInfo();
+		
+		String allManyTrueKeys = "";
 		if(allkeys != null){
-			nameOfTrueKey = allkeys.toString();
+			allManyTrueKeys = allkeys.toString();
 		}
 		
 		String jsonModel = createMicroSeriveJson(returnModel, allkeys);
@@ -1060,11 +628,13 @@
 		List<Object>  list = new ArrayList<>();
 		PrintWriter out = response.getWriter();
 		String responseString = mapper.writeValueAsString(returnModel);
-		JSONObject j;
-		if("".equals(nameOfTrueKey)){
-			j = new JSONObject("{dcaeModelData: " + responseString + ",jsonValue: " + jsonModel + "}");	
+
+		JSONObject j = null;
+		
+		if("".equals(allManyTrueKeys)){
+			j = new JSONObject("{dcaeModelData: " + responseString + ",jsonValue: " + jsonModel + ",dataOrderInfo:" + dataOrderInfo + ",headDefautlsData:" + headDefautlsData +"}");	
 		}else{
-			j = new JSONObject("{dcaeModelData: " + responseString + ",jsonValue: " + jsonModel + ",allManyTrueKeys: " + nameOfTrueKey+ "}");	
+			j = new JSONObject("{dcaeModelData: " + responseString + ",jsonValue: " + jsonModel + ",allManyTrueKeys: " + allManyTrueKeys+",dataOrderInfo:" + dataOrderInfo + ",headDefautlsData:" + headDefautlsData+ "}");	
 		}
 		list.add(j);
 		out.write(list.toString());
@@ -1102,10 +672,11 @@
 		}else{
 			subAttributes = "";
 		}
+		
 		Map gsonObject = (Map) gson.fromJson(subAttributes, Object.class);
 		
 		JSONObject object = new JSONObject();
-		JSONArray array;
+		JSONArray array = new JSONArray();
 		
 		for (Entry<String, String> keySet : attributeMap.entrySet()){
 			array = new JSONArray();
@@ -1137,8 +708,6 @@
 				}
 			}
 		}
-		
-		
 
 		return object.toString();
 	}
@@ -1210,7 +779,7 @@
 		
 		if(referAttributes != null){
 			String[] referAarray = referAttributes.split(",");
-			String []element;
+			String []element= null;
 			for(int i=0; i<referAarray.length; i++){
 				element = referAarray[i].split("=");	  
 				if(element.length > 1 && element[1].contains("MANY-true")){
@@ -1240,6 +809,7 @@
 
 	    return keys;
 	}
+	
     // this method returns a set of keys with "MANY-true" defined in their value.
 	private Set<String> getAllKeys(JSONObject json, Set<String> keys) {
 	    for (String key : json.keySet()) {
@@ -1314,6 +884,10 @@
 		}
 		return workingModel;
 	}
+	
+	private MicroserviceHeaderdeFaults getHeaderDefaultsObject(String modelName) {	
+		return (MicroserviceHeaderdeFaults) commonClassDao.getEntityItem(MicroserviceHeaderdeFaults.class, "modelName", modelName);
+	}	
 
 	@RequestMapping(value={"/get_DCAEPriorityValues"}, method={org.springframework.web.bind.annotation.RequestMethod.GET} , produces=MediaType.APPLICATION_JSON_VALUE)
 	public void getDCAEPriorityValuesData(HttpServletRequest request, HttpServletResponse response){
@@ -1457,8 +1031,8 @@
 
 	}
 
-	@SuppressWarnings({ "rawtypes", "unchecked" })
-	private void readRecursivlyJSONContent(LinkedHashMap<String, ?> map, LinkedHashMap<String, Object> data){
+	@SuppressWarnings({ "rawtypes", "unchecked" }) 
+	public void readRecursivlyJSONContent(LinkedHashMap<String, ?> map, LinkedHashMap<String, Object> data){
 		for (Iterator iterator = map.keySet().iterator(); iterator.hasNext();) {
 			Object key =  iterator.next();
 			Object value = map.get(key);
@@ -1494,7 +1068,7 @@
 		}
 	}
 
-	private String getPolicyScope(String value) {
+	public String getPolicyScope(String value) {
 		List<Object> groupList= commonClassDao.getDataById(GroupPolicyScopeList.class, "groupList", value);
 		if(groupList != null && !groupList.isEmpty()){
 			GroupPolicyScopeList pScope = (GroupPolicyScopeList) groupList.get(0);
@@ -1545,12 +1119,7 @@
 	public void SetMSModelData(HttpServletRequest request, HttpServletResponse response) throws IOException, FileUploadException{
 		modelList = new ArrayList<>();
 		dirDependencyList = new ArrayList<>();
-		classMap = new HashMap<>();
-		retmap = new HashMap<>();
-		uniqueKeys= new HashSet<>();
-		uniqueDataKeys= new HashSet<>();
-		dataListBuffer=new StringBuilder();
-		dataConstraints= new ArrayList <>();
+		classMap = new LinkedHashMap<>();
 		List<FileItem> items = new ServletFileUpload(new DiskFileItemFactory()).parseRequest(request);
 		boolean zip = false;
 		boolean yml= false;
@@ -1593,7 +1162,7 @@
 			response.setCharacterEncoding("UTF-8");
 			response.setContentType("application / json");
 			request.setCharacterEncoding("UTF-8");
-			
+
 			JSONObject j = new JSONObject();
 			j.put("errorMsg", errorMsg);
 			out.write(j.toString());
@@ -1601,21 +1170,24 @@
 		}
 		
 		List<File> fileList = new ArrayList<>();
+		MSModelUtils msMLUtils =  new MSModelUtils();
 		this.directory = "model";
 		if (zip){
 			extractFolder(this.newFile);
 			fileList = listModelFiles(this.directory);
-		}else if (yml){
-			parseTosca(this.newFile);
+		}else if (yml==true){
+			
+			msMLUtils.parseTosca(this.newFile);
+			
 		}else {
 			File file = new File(this.newFile);
 			fileList.add(file);
 		}
-		String modelType;
-		if(! yml){
+		String modelType= "";
+		if(!yml){
 			modelType="xmi";
 			//Process Main Model file first
-			classMap = new HashMap<>();
+			classMap = new LinkedHashMap<>();
 			for (File file : fileList) {
 				if(!file.isDirectory() && file.getName().endsWith(".xmi")){
 	            	retreiveDependency(file.toString(), true);
@@ -1633,19 +1205,22 @@
 			MSAttributeObject msAttributes= new MSAttributeObject();
 			msAttributes.setClassName(className);
 			
-			HashMap<String, String> returnAttributeList =new HashMap<>();
-			returnAttributeList.put(className, this.attributeString);
+			LinkedHashMap<String, String> returnAttributeList =new LinkedHashMap<>();
+			returnAttributeList.put(className, msMLUtils.getAttributeString());
 			msAttributes.setAttribute(returnAttributeList);
 			
-			msAttributes.setSubClass(this.retmap);
-			msAttributes.setMatchingSet(matchableValues);
-			HashMap<String, String> returnReferenceList =new HashMap<>();
-			returnReferenceList.put(className, this.referenceAttributes);
+			msAttributes.setSubClass(msMLUtils.getRetmap());
+			
+			msAttributes.setMatchingSet(msMLUtils.getMatchableValues());
+			
+			LinkedHashMap<String, String> returnReferenceList =new LinkedHashMap<>();
+
+			returnReferenceList.put(className, msMLUtils.getReferenceAttributes());
 			msAttributes.setRefAttribute(returnReferenceList);
 			
-			if(this.listConstraints!=""){
-				HashMap<String, String> enumList =new HashMap<>();
-				String[] listArray=this.listConstraints.split("#");
+			if(msMLUtils.getListConstraints()!=""){
+				LinkedHashMap<String, String> enumList =new LinkedHashMap<>();
+				String[] listArray=msMLUtils.getListConstraints().split("#");
                 for(String str:listArray){
                     String[] strArr= str.split("=");
                     if(strArr.length>1){
@@ -1655,7 +1230,7 @@
 				msAttributes.setEnumType(enumList);
 			}
 			
-			classMap=new HashMap<>();
+			classMap=new LinkedHashMap<>();
 			classMap.put(className, msAttributes);
 			
 		}
@@ -1671,6 +1246,8 @@
 		j.put("classListDatas", modelList);
 		j.put("modelDatas", mapper.writeValueAsString(classMap));
 		j.put("modelType", modelType);
+		j.put("dataOrderInfo", msMLUtils.getDataOrderInfo());
+		
 		out.write(j.toString());
 	}
 	
@@ -1756,7 +1333,7 @@
 		return resultList;
 	}
 	
-    private void cleanUp(String path) {
+    public void cleanUp(String path) {
         if (path!=null){
             try {
                 FileUtils.forceDelete(new File(path));
@@ -1766,7 +1343,7 @@
         }
     }
  
-    private void checkZipDirectory(String zipDirectory) {
+    public void checkZipDirectory(String zipDirectory) {
         Path path = Paths.get(zipDirectory);
  
         if (Files.exists(path)) {
diff --git a/POLICY-SDK-APP/src/main/java/org/onap/policy/controller/CreateOptimizationController.java b/POLICY-SDK-APP/src/main/java/org/onap/policy/controller/CreateOptimizationController.java
new file mode 100644
index 0000000..4ae1344
--- /dev/null
+++ b/POLICY-SDK-APP/src/main/java/org/onap/policy/controller/CreateOptimizationController.java
@@ -0,0 +1,954 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP Policy Engine
+ * ================================================================================
+ * Copyright (C) 2018 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.controller;
+
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.UUID;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.compress.utils.IOUtils;
+import org.apache.commons.fileupload.FileItem;
+import org.apache.commons.fileupload.FileUploadException;
+import org.apache.commons.fileupload.disk.DiskFileItemFactory;
+import org.apache.commons.fileupload.servlet.ServletFileUpload;
+import org.apache.commons.lang.StringUtils;
+import org.json.JSONArray;
+import org.json.JSONObject;
+import org.onap.policy.common.logging.flexlogger.FlexLogger;
+import org.onap.policy.common.logging.flexlogger.Logger;
+import org.onap.policy.rest.XACMLRestProperties;
+import org.onap.policy.rest.adapter.PolicyRestAdapter;
+import org.onap.policy.rest.dao.CommonClassDao;
+import org.onap.policy.rest.jpa.OptimizationModels;
+import org.onap.policy.rest.jpa.PolicyEntity;
+import org.onap.policy.rest.jpa.MicroserviceHeaderdeFaults;
+import org.onap.policy.rest.util.MSAttributeObject;
+import org.onap.policy.rest.util.MSModelUtils;
+import org.onap.policy.rest.util.MSModelUtils.MODEL_TYPE;
+import org.onap.portalsdk.core.controller.RestrictedBaseController;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.servlet.ModelAndView;
+
+import com.att.research.xacml.util.XACMLProperties;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.ObjectWriter;
+import com.google.gson.Gson;
+
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AllOfType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AnyOfType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeDesignatorType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeValueType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.MatchType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.TargetType;
+
+@Controller
+@RequestMapping("/")
+public class CreateOptimizationController extends RestrictedBaseController {
+	private static final Logger LOGGER = FlexLogger.getLogger(CreateOptimizationController.class);
+	private static CommonClassDao commonClassDao;
+	
+	public static CommonClassDao getCommonClassDao() {
+		return commonClassDao;
+	}
+
+	public static void setCommonClassDao(CommonClassDao commonClassDao) {
+		CreateOptimizationController.commonClassDao = commonClassDao;
+	}
+
+	private OptimizationModels newModel;
+	private String newFile;
+	private String directory;
+	private List<String> modelList = new ArrayList<>();
+	private List<String> dirDependencyList = new ArrayList<>();
+	private LinkedHashMap<String,MSAttributeObject > classMap = new LinkedHashMap<>();
+	String referenceAttributes;
+	String attributeString;
+	Set<String> allManyTrueKeys= new HashSet <>();
+	
+	public static final String DATATYPE  = "data_types.policy.data.";
+	public static final String PROPERTIES=".properties.";
+	public static final String TYPE=".type";
+	public static final String STRING="string";
+	public static final String INTEGER="integer";
+	public static final String LIST="list";
+	public static final String DEFAULT=".default";
+	public static final String REQUIRED=".required";
+	public static final String MATCHABLE=".matchable";
+	public static final String MANYFALSE=":MANY-false";
+	public static final String MODEL = "model";
+	public static final String MANY = "MANY-";
+	public static final String UTF8 = "UTF-8";
+	public static final String MODELNAME = "modelName";
+	public static final String APPLICATIONJSON = "application / json";
+	
+	
+	@Autowired
+	private CreateOptimizationController(CommonClassDao commonClassDao){
+		CreateOptimizationController.commonClassDao = commonClassDao;
+	}
+
+	public CreateOptimizationController(){
+		// Empty Constructor
+	}
+
+	protected PolicyRestAdapter policyAdapter = null;
+	private Map<String, String> attributesListRefMap =  new HashMap<>();
+	private Map<String, LinkedList<String>> arrayTextList =  new HashMap<>();
+	CreateDcaeMicroServiceController msController = new CreateDcaeMicroServiceController();
+
+	public PolicyRestAdapter setDataToPolicyRestAdapter(PolicyRestAdapter policyData, JsonNode root) {
+		String jsonContent = null;
+		try{
+			LOGGER.info("policyJSON :" + (root.get("policyJSON")).toString());
+			
+			String tempJson = root.get("policyJSON").toString();
+			
+			//---replace empty value with the value below before calling decodeContent method.
+			String dummyValue = "*empty-value*" + UUID.randomUUID().toString();
+			LOGGER.info("dummyValue:" + dummyValue);
+			tempJson = StringUtils.replaceEach(tempJson, new String[]{"\"\""}, new String[]{"\""+dummyValue+"\""});
+			ObjectMapper mapper = new ObjectMapper();
+			JsonNode tempJsonNode = mapper.readTree(tempJson);
+			jsonContent = msController.decodeContent(tempJsonNode).toString();
+			constructJson(policyData, jsonContent, dummyValue);
+		}catch(Exception e){
+			LOGGER.error("Error while decoding microservice content", e);
+		}
+		
+		return policyData;
+	}
+	
+	private PolicyRestAdapter constructJson(PolicyRestAdapter policyAdapter, String jsonContent, String dummyValue) {
+		ObjectWriter om = new ObjectMapper().writer();
+		String json="";
+		OptimizationObject optimizationObject = setOptimizationObjectValues(policyAdapter);
+		
+		optimizationObject.setContent(jsonContent);
+
+		try {
+			json = om.writeValueAsString(optimizationObject);
+		} catch (JsonProcessingException e) {
+			LOGGER.error("Error writing out the object", e);
+		}
+		LOGGER.info("input json: " + json);
+		LOGGER.info("input jsonContent: " + jsonContent);
+		String cleanJson = msController.cleanUPJson(json);
+		
+        //--- reset empty value back after called cleanUPJson method and before calling removeNullAttributes
+		String tempJson = StringUtils.replaceEach(cleanJson, new String[]{"\""+dummyValue+"\""},  new String[]{"\"\""});
+		LOGGER.info("tempJson: " + tempJson);
+		cleanJson = msController.removeNullAttributes(tempJson);
+		policyAdapter.setJsonBody(cleanJson);
+		return policyAdapter;
+	}
+
+	@RequestMapping(value={"/policyController/getOptimizationTemplateData.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	public ModelAndView getOptimizationTemplateData(HttpServletRequest request, HttpServletResponse response) throws IOException{
+		ObjectMapper mapper = new ObjectMapper();
+		mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+		JsonNode root = mapper.readTree(request.getReader());
+
+		String value = root.get("policyData").toString().replaceAll("^\"|\"$", "");
+		String  servicename = value.toString().split("-v")[0];
+		String version = null;
+		if (value.toString().contains("-v")){
+			version = value.toString().split("-v")[1];
+		}
+		
+		OptimizationModels returnModel = getAttributeObject(servicename, version);
+		
+		MicroserviceHeaderdeFaults returnHeaderDefauls = getHeaderDefaultsObject(value);
+		JSONObject jsonHdDefaultObj = null;
+		if(returnHeaderDefauls != null){
+			jsonHdDefaultObj = new JSONObject();
+			jsonHdDefaultObj.put("onapName", returnHeaderDefauls.getOnapName());
+			jsonHdDefaultObj.put("guard", returnHeaderDefauls.getGuard());
+			jsonHdDefaultObj.put("riskLevel", returnHeaderDefauls.getRiskLevel());
+			jsonHdDefaultObj.put("riskType", returnHeaderDefauls.getRiskType());
+			jsonHdDefaultObj.put("priority", returnHeaderDefauls.getPriority());
+		}
+		
+		String headDefautlsData = "";
+		if(jsonHdDefaultObj != null){			
+			headDefautlsData = jsonHdDefaultObj.toString();
+			LOGGER.info("returnHeaderDefauls headDefautlsData: " + headDefautlsData);
+		}else{
+			headDefautlsData = "null";
+		}
+		
+		//Get all keys with "MANY-true" defined in their value from subAttribute 
+		Set<String> allkeys = null;
+		if(returnModel.getSubattributes() != null && !returnModel.getSubattributes().isEmpty()){
+			JSONObject json = new JSONObject(returnModel.getSubattributes());	
+			getAllKeys(json); 
+			allkeys = allManyTrueKeys;
+			allManyTrueKeys = new  HashSet <>();
+			LOGGER.info("allkeys : " + allkeys);
+		}
+		
+		//Get element order info 
+		String dataOrderInfo = returnModel.getDataOrderInfo();
+		String nameOfTrueKeys = "";
+		if(allkeys != null){
+			nameOfTrueKeys = allkeys.toString();
+		}
+		
+		String jsonModel = createOptimizationJson(returnModel);
+		
+		JSONObject jsonObject = new JSONObject(jsonModel);
+		
+		JSONObject finalJsonObject = null;
+		if(allkeys != null){
+			Iterator<String> iter = allkeys.iterator();
+			while(iter.hasNext()){
+				//Convert to array values for MANY-true keys
+				finalJsonObject = CreateDcaeMicroServiceController.convertToArrayElement(jsonObject, iter.next());
+			}
+		}
+
+		if(finalJsonObject != null){
+		    LOGGER.info(finalJsonObject.toString());
+		    jsonModel  = finalJsonObject.toString();
+		}
+		
+		//get all properties with "MANY-true" defined in Ref_attributes
+		Set<String> manyTrueProperties = CreateDcaeMicroServiceController.getManyTrueProperties(returnModel.getRefattributes());
+		JSONObject jsonObj = new JSONObject(jsonModel);
+		for (String s : manyTrueProperties) {
+			LOGGER.info(s);
+			//convert to array element for MANY-true properties
+			finalJsonObject = CreateDcaeMicroServiceController.convertToArrayElement(jsonObj, s.trim());
+		}
+		
+		if(finalJsonObject != null){
+		    LOGGER.info(finalJsonObject.toString());
+		    jsonModel = finalJsonObject.toString();
+		}
+		
+		response.setCharacterEncoding(UTF8);
+		response.setContentType(APPLICATIONJSON);
+		request.setCharacterEncoding(UTF8);
+		List<Object>  list = new ArrayList<>();
+		PrintWriter out = response.getWriter();
+		String responseString = mapper.writeValueAsString(returnModel);
+		JSONObject j = null;
+		if("".equals(nameOfTrueKeys)){
+			j = new JSONObject("{optimizationModelData: " + responseString + ",jsonValue: " + jsonModel + ",dataOrderInfo:" + dataOrderInfo + ",headDefautlsData:" + headDefautlsData +"}");	
+		}else{
+			j = new JSONObject("{optimizationModelData: " + responseString + ",jsonValue: " + jsonModel + ",allManyTrueKeys: " + allManyTrueKeys+",dataOrderInfo:" + dataOrderInfo + ",headDefautlsData:" + headDefautlsData+ "}");	
+		}
+		list.add(j);
+		out.write(list.toString());
+		return null;
+	}
+	
+	@SuppressWarnings({ "rawtypes", "unchecked" })
+	private String createOptimizationJson(OptimizationModels returnModel) {
+		Map<String, String> attributeMap = new HashMap<>();
+		Map<String, String> refAttributeMap = new HashMap<>();
+		
+		String attribute = returnModel.getAttributes();
+		if(attribute != null){
+			attribute = attribute.trim();
+		}
+		String refAttribute = returnModel.getRefattributes();
+		if(refAttribute != null){
+			refAttribute = refAttribute.trim();
+		}
+		
+		String enumAttribute = returnModel.getEnumValues();
+		if(enumAttribute != null){
+			enumAttribute = enumAttribute.trim();
+		}
+		
+		if (!StringUtils.isEmpty(attribute)){
+			attributeMap = CreateDcaeMicroServiceController.convert(attribute, ",");
+		}
+		
+		if (!StringUtils.isEmpty(refAttribute)){
+			refAttributeMap = CreateDcaeMicroServiceController.convert(refAttribute, ",");
+		}
+
+		Gson gson = new Gson();
+		
+		String subAttributes = returnModel.getSubattributes();
+		if(subAttributes != null){
+			subAttributes = subAttributes.trim();
+		}else{
+			subAttributes = "";
+		}
+		
+		Map gsonObject = (Map) gson.fromJson(subAttributes, Object.class);
+		
+		JSONObject object = new JSONObject();
+		JSONArray array;
+		
+		for (Entry<String, String> keySet : attributeMap.entrySet()){
+			array = new JSONArray();
+			String value = keySet.getValue();
+			if ("true".equalsIgnoreCase(keySet.getValue().split(MANY)[1])){
+				array.put(value);
+				object.put(keySet.getKey().trim(), array);
+			}else {
+				object.put(keySet.getKey().trim(), value.trim());
+			}
+		}
+		
+		for (Entry<String, String> keySet : refAttributeMap.entrySet()){
+			array = new JSONArray();
+			String value = keySet.getValue().split(":")[0];
+			if (gsonObject.containsKey(value)){
+				if ("true".equalsIgnoreCase(keySet.getValue().split(MANY)[1])){
+					array.put(recursiveReference(value, gsonObject, enumAttribute));
+					object.put(keySet.getKey().trim(), array);
+				}else {
+					object.put(keySet.getKey().trim(), recursiveReference(value, gsonObject, enumAttribute));
+				}
+			}else {
+				if ("true".equalsIgnoreCase(keySet.getValue().split(MANY)[1])){
+					array.put(value.trim());
+					object.put(keySet.getKey().trim(), array);
+				}else {
+					object.put(keySet.getKey().trim(), value.trim()); 
+				}
+			}
+		}
+		
+		return object.toString();
+	}
+
+	@SuppressWarnings("unchecked")
+	private JSONObject recursiveReference(String name, Map<String,String> subAttributeMap, String enumAttribute) {
+		JSONObject object = new JSONObject();
+		Map<String, String> map;
+		Object returnClass = subAttributeMap.get(name);
+		map = (Map<String, String>) returnClass; 
+		JSONArray array;
+		
+		for( Entry<String, String> m:map.entrySet()){  
+			String[] splitValue = m.getValue().split(":");
+			array = new JSONArray();
+			if (subAttributeMap.containsKey(splitValue[0])){
+				if ("true".equalsIgnoreCase(m.getValue().split(MANY)[1])){
+					array.put(recursiveReference(splitValue[0], subAttributeMap, enumAttribute));
+					object.put(m.getKey().trim(), array);
+				}else {
+					object.put(m.getKey().trim(), recursiveReference(splitValue[0], subAttributeMap, enumAttribute));
+				}
+			} else{
+				if ("true".equalsIgnoreCase(m.getValue().split(MANY)[1])){
+					array.put(splitValue[0].trim());
+					object.put(m.getKey().trim(), array);
+				}else {
+					object.put(m.getKey().trim(), splitValue[0].trim());
+				}
+			}
+		  }  
+		
+		return object;
+	}
+	
+	//call this method to start the recursive
+	private Set<String> getAllKeys(JSONObject json) {
+	    return getAllKeys(json, new HashSet<>());
+	}
+
+	private Set<String> getAllKeys(JSONArray arr) {
+	    return getAllKeys(arr, new HashSet<>());
+	}
+
+	private Set<String> getAllKeys(JSONArray arr, Set<String> keys) {
+	    for (int i = 0; i < arr.length(); i++) {
+	        Object obj = arr.get(i);
+	        if (obj instanceof JSONObject) keys.addAll(getAllKeys(arr.getJSONObject(i)));
+	        if (obj instanceof JSONArray) keys.addAll(getAllKeys(arr.getJSONArray(i)));
+	    }
+
+	    return keys;
+	}
+	
+    // this method returns a set of keys with "MANY-true" defined in their value.
+	private Set<String> getAllKeys(JSONObject json, Set<String> keys) {
+	    for (String key : json.keySet()) {
+	        Object obj = json.get(key);
+	        if(obj instanceof String && ((String) obj).contains("MANY-true")){
+	        	LOGGER.info("key : " + key);
+	        	LOGGER.info("obj : " + obj);
+	        	allManyTrueKeys.add(key);
+	        }
+	        if (obj instanceof JSONObject) keys.addAll(getAllKeys(json.getJSONObject(key)));
+	        if (obj instanceof JSONArray) keys.addAll(getAllKeys(json.getJSONArray(key)));
+	    }
+
+	    return keys;
+	}
+	
+	@RequestMapping(value={"/policyController/getModelServiceVersionData.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	public ModelAndView getModelServiceVersionData(HttpServletRequest request, HttpServletResponse response) throws IOException{
+		ObjectMapper mapper = new ObjectMapper();
+		mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+		JsonNode root = mapper.readTree(request.getReader());
+
+		String value = root.get("policyData").toString().replaceAll("^\"|\"$", "");
+		String  servicename = value.split("-v")[0];
+		Set<String> returnList = getVersionList(servicename);
+		
+		response.setCharacterEncoding(UTF8);
+		response.setContentType(APPLICATIONJSON);
+		request.setCharacterEncoding(UTF8);
+        List<Object>  list = new ArrayList<>();
+		PrintWriter out = response.getWriter();
+		String responseString = mapper.writeValueAsString(returnList);
+		JSONObject j = new JSONObject("{optimizationModelVersionData: " + responseString +"}");
+		list.add(j);
+		out.write(list.toString());
+		return null;
+	}
+
+	private Set<String> getVersionList(String name) {	
+		OptimizationModels workingModel;
+		Set<String> list = new HashSet<>();
+		List<Object> optimizationModelsData = commonClassDao.getDataById(OptimizationModels.class, MODELNAME, name);
+		for (int i = 0; i < optimizationModelsData.size(); i++) {
+			workingModel = (OptimizationModels) optimizationModelsData.get(i);
+			if (workingModel.getVersion()!=null){
+				list.add(workingModel.getVersion());
+			}else{
+				list.add("Default");
+			}
+		}
+		return list;
+	}
+	
+	private OptimizationModels getAttributeObject(String name, String version) {	
+		OptimizationModels workingModel = new OptimizationModels();
+		List<Object> optimizationModelsData = commonClassDao.getDataById(OptimizationModels.class, MODELNAME, name);
+		for (int i = 0; i < optimizationModelsData.size(); i++) {
+			workingModel = (OptimizationModels) optimizationModelsData.get(i);
+			if(version != null){
+				if (workingModel.getVersion()!=null){
+					if (workingModel.getVersion().equals(version)){
+						return workingModel;
+					}
+				}else{
+					return workingModel;
+				}
+			}else{
+				return workingModel;
+			}
+			
+		}
+		return workingModel;
+	}
+	
+	private MicroserviceHeaderdeFaults getHeaderDefaultsObject(String modelName) {	
+		return (MicroserviceHeaderdeFaults) commonClassDao.getEntityItem(MicroserviceHeaderdeFaults.class, MODELNAME, modelName);
+	}
+
+	public void prePopulatePolicyData(PolicyRestAdapter policyAdapter, PolicyEntity entity) {
+		if (policyAdapter.getPolicyData() instanceof PolicyType) {
+			Object policyData = policyAdapter.getPolicyData();
+			PolicyType policy = (PolicyType) policyData;
+			policyAdapter.setOldPolicyFileName(policyAdapter.getPolicyName());
+			String policyNameValue = policyAdapter.getPolicyName().substring(policyAdapter.getPolicyName().indexOf("OOF_") +4);
+			policyAdapter.setPolicyName(policyNameValue);
+			String description = "";
+			try{
+				description = policy.getDescription().substring(0, policy.getDescription().indexOf("@CreatedBy:"));
+			}catch(Exception e){
+			    LOGGER.error("Error while collecting the description tag in " + policyNameValue ,e);
+				description = policy.getDescription();
+			}
+			policyAdapter.setPolicyDescription(description);
+			// Get the target data under policy.
+			TargetType target = policy.getTarget();			
+			if (target != null) {
+				// Under target we have AnyOFType
+				List<AnyOfType> anyOfList = target.getAnyOf();
+				if (anyOfList != null) {
+					Iterator<AnyOfType> iterAnyOf = anyOfList.iterator();
+					while (iterAnyOf.hasNext()) {
+						AnyOfType anyOf = iterAnyOf.next();
+						// Under AnyOFType we have AllOFType
+						List<AllOfType> allOfList = anyOf.getAllOf();
+						if (allOfList != null) {
+							Iterator<AllOfType> iterAllOf = allOfList.iterator();
+							while (iterAllOf.hasNext()) {
+								AllOfType allOf = iterAllOf.next();
+								// Under AllOFType we have Match
+								List<MatchType> matchList = allOf.getMatch();
+								if (matchList != null) {
+									Iterator<MatchType> iterMatch = matchList.iterator();
+									while (matchList.size()>1 && iterMatch.hasNext()) {
+										MatchType match = iterMatch.next();
+										//
+										// Under the match we have attribute value and
+										// attributeDesignator. So,finally down to the actual attribute.
+										//
+										AttributeValueType attributeValue = match.getAttributeValue();
+										String value = (String) attributeValue.getContent().get(0);
+										AttributeDesignatorType designator = match.getAttributeDesignator();
+										String attributeId = designator.getAttributeId();
+										// First match in the target is OnapName, so set that value.
+										if ("ONAPName".equals(attributeId)) {
+											policyAdapter.setOnapName(value);
+										}
+										if ("RiskType".equals(attributeId)){
+											policyAdapter.setRiskType(value);
+										}
+										if ("RiskLevel".equals(attributeId)){
+											policyAdapter.setRiskLevel(value);
+										}
+										if ("guard".equals(attributeId)){
+											policyAdapter.setGuard(value);
+										}
+										if ("TTLDate".equals(attributeId) && !value.contains("NA")){
+											PolicyController controller = new PolicyController();
+											String newDate = controller.convertDate(value);
+											policyAdapter.setTtlDate(newDate);
+										}
+									}
+									readFile(policyAdapter, entity);
+								}
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+
+	@SuppressWarnings("unchecked")
+	private void readFile(PolicyRestAdapter policyAdapter, PolicyEntity entity) {
+		String policyScopeName = null;
+		ObjectMapper mapper = new ObjectMapper();
+		try {
+			OptimizationObject optimizationBody = mapper.readValue(entity.getConfigurationData().getConfigBody(), OptimizationObject.class);
+			policyScopeName = msController.getPolicyScope(optimizationBody.getPolicyScope());
+			policyAdapter.setPolicyScope(policyScopeName);
+
+			policyAdapter.setPriority(optimizationBody.getPriority());
+
+			if (optimizationBody.getVersion()!= null){
+				policyAdapter.setServiceType(optimizationBody.getService());
+				policyAdapter.setVersion(optimizationBody.getVersion());
+			}else{
+				policyAdapter.setServiceType(optimizationBody.getService());
+			}
+			if(optimizationBody.getContent() != null){
+				LinkedHashMap<String, Object>  data = new LinkedHashMap<>();
+				LinkedHashMap<String, ?> map = (LinkedHashMap<String, ?>) optimizationBody.getContent();
+				msController.readRecursivlyJSONContent(map, data);
+				policyAdapter.setRuleData(data);
+			}
+
+		} catch (Exception e) {
+			LOGGER.error(e);
+		}
+
+	}
+	
+	@RequestMapping(value={"/oof_dictionary/set_ModelData"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
+	public void SetModelData(HttpServletRequest request, HttpServletResponse response) throws IOException, FileUploadException{
+		modelList = new ArrayList<>();
+		dirDependencyList = new ArrayList<>();
+		classMap = new LinkedHashMap<>();
+		List<FileItem> items = new ServletFileUpload(new DiskFileItemFactory()).parseRequest(request);
+				
+		boolean zip = false;
+		boolean yml= false;
+		String errorMsg = "";
+		for (FileItem item : items) {
+			if(item.getName().endsWith(".zip") || item.getName().endsWith(".xmi")||item.getName().endsWith(".yml")){
+				this.newModel = new OptimizationModels();
+				try{
+					File file = new File(item.getName());
+					OutputStream outputStream = new FileOutputStream(file);
+					IOUtils.copy(item.getInputStream(), outputStream);
+					outputStream.close();
+					this.newFile = file.toString();
+					this.newModel.setModelName(this.newFile.split("-v")[0]);
+				
+					if (this.newFile.contains("-v")){
+						if (item.getName().endsWith(".zip")){
+							this.newModel.setVersion(this.newFile.split("-v")[1].replace(".zip", ""));
+							zip = true;
+						}else if(item.getName().endsWith(".yml")){
+							this.newModel.setVersion(this.newFile.split("-v")[1].replace(".yml", ""));
+							yml = true;
+						}
+						else {
+							this.newModel.setVersion(this.newFile.split("-v")[1].replace(".xmi", ""));
+						}
+					}				
+				}catch(Exception e){
+					LOGGER.error("Upload error : ", e);
+					errorMsg = "Upload error:" + e.getMessage();
+				}
+			}
+			
+		}
+		
+		if(!errorMsg.isEmpty()){
+			
+			PrintWriter out = response.getWriter();
+			
+			response.setCharacterEncoding(UTF8);
+			response.setContentType(APPLICATIONJSON);
+			request.setCharacterEncoding(UTF8);
+			
+			JSONObject j = new JSONObject();
+			j.put("errorMsg", errorMsg);
+			out.write(j.toString());
+			return;
+		}
+		
+		List<File> fileList = new ArrayList<>();
+		MSModelUtils modelUtil = new MSModelUtils();
+		this.directory = MODEL;
+		if (zip){
+			extractFolder(this.newFile);
+			fileList = listModelFiles(this.directory);
+		}else if (yml){
+			modelUtil.parseTosca(this.newFile);
+		}else {
+			File file = new File(this.newFile);
+			fileList.add(file);
+		}
+		String modelType;
+		if(! yml){
+			modelType="xmi";
+			//Process Main Model file first
+			classMap = new LinkedHashMap<>();
+			for (File file : fileList) {
+				if(!file.isDirectory() && file.getName().endsWith(".xmi")){
+	            	retrieveDependency(file.toString());
+	            }	
+			}
+			
+			modelList = createList();
+			
+			msController.cleanUp(this.newFile);
+			msController.cleanUp(directory);
+		}else{
+			modelType="yml";
+			modelList.add(this.newModel.getModelName());
+			String className=this.newModel.getModelName();
+			MSAttributeObject optimizationAttributes= new MSAttributeObject();
+			optimizationAttributes.setClassName(className);
+
+			LinkedHashMap<String, String> returnAttributeList =new LinkedHashMap<>();
+			returnAttributeList.put(className, modelUtil.getAttributeString());
+			optimizationAttributes.setAttribute(returnAttributeList);
+			
+			optimizationAttributes.setSubClass(modelUtil.getRetmap());
+			
+			optimizationAttributes.setMatchingSet(modelUtil.getMatchableValues());
+
+			LinkedHashMap<String, String> returnReferenceList =new LinkedHashMap<>();
+			returnReferenceList.put(className, modelUtil.getReferenceAttributes());
+			optimizationAttributes.setRefAttribute(returnReferenceList);
+			
+			if(!"".equals(modelUtil.getListConstraints())){
+				LinkedHashMap<String, String> enumList =new LinkedHashMap<>();
+				String[] listArray=modelUtil.getListConstraints().split("#");
+                for(String str:listArray){
+                    String[] strArr= str.split("=");
+                    if(strArr.length>1){
+                        enumList.put(strArr[0], strArr[1]);
+                    }
+                }
+                optimizationAttributes.setEnumType(enumList);
+			}
+			
+			classMap=new LinkedHashMap<>();
+			classMap.put(className, optimizationAttributes);
+			
+		}
+		
+		PrintWriter out = response.getWriter();
+		
+		response.setCharacterEncoding(UTF8);
+		response.setContentType(APPLICATIONJSON);
+		request.setCharacterEncoding(UTF8);
+		
+		ObjectMapper mapper = new ObjectMapper();
+		JSONObject j = new JSONObject();
+		j.put("classListDatas", modelList);
+		j.put("modelDatas", mapper.writeValueAsString(classMap));
+		j.put("modelType", modelType);
+		j.put("dataOrderInfo", modelUtil.getDataOrderInfo());
+		
+		out.write(j.toString());
+	}
+	
+	/*
+	 * Unzip file and store in the model directory for processing
+	 */
+	@SuppressWarnings("rawtypes")
+	private void extractFolder(String zipFile )  {
+	    int BUFFER = 2048;
+	    File file = new File(zipFile);
+
+		try (ZipFile zip = new ZipFile(file)) {
+		    String newPath =  MODEL + File.separator + zipFile.substring(0, zipFile.length() - 4);
+		    this.directory = MODEL + File.separator + zipFile.substring(0, zipFile.length() - 4);
+		    msController.checkZipDirectory(this.directory);
+		    new File(newPath).mkdir();
+		    Enumeration zipFileEntries = zip.entries();
+	
+		    // Process each entry
+		    while (zipFileEntries.hasMoreElements()){
+		        // grab a zip file entry
+		        ZipEntry entry = (ZipEntry) zipFileEntries.nextElement();
+		        String currentEntry = entry.getName();
+		        File destFile = new File(MODEL + File.separator + currentEntry);
+		        File destinationParent = destFile.getParentFile();
+		        
+		        destinationParent.mkdirs();
+	
+		        if (!entry.isDirectory()){
+		            BufferedInputStream is = new BufferedInputStream(zip.getInputStream(entry));
+		            int currentByte;
+		            byte[] data = new byte[BUFFER];
+		            try (FileOutputStream fos = new FileOutputStream(destFile);
+		            		BufferedOutputStream dest = new BufferedOutputStream(fos, BUFFER)) {
+			            while ((currentByte = is.read(data, 0, BUFFER)) != -1) {
+			                dest.write(data, 0, currentByte);
+			            }
+			            dest.flush();
+		            } catch (IOException e) {
+		            	LOGGER.error("Failed to write zip contents to {}" + destFile + e);
+		            	//
+		            	// PLD should I throw e?
+		            	//
+		            	throw e;
+		            }
+		        }
+	
+		        if (currentEntry.endsWith(".zip")){
+		            extractFolder(destFile.getAbsolutePath());
+		        }
+		    }
+	    } catch (IOException e) {
+	    	LOGGER.error("Failed to unzip model file " + zipFile, e);
+		}
+	}
+	
+	private void retrieveDependency(String workingFile) {
+		
+		MSModelUtils utils = new MSModelUtils(PolicyController.getMsOnapName(), PolicyController.getMsPolicyName());
+	    Map<String, MSAttributeObject> tempMap;
+	    
+	    tempMap = utils.processEpackage(workingFile, MODEL_TYPE.XMI);
+	    
+	    classMap.putAll(tempMap);
+	    LOGGER.info(tempMap);
+	    
+	    return;   	
+	    
+	}
+		
+	private List<File> listModelFiles(String directoryName) {
+		File fileDirectory = new File(directoryName);
+		List<File> resultList = new ArrayList<>();
+		File[] fList = fileDirectory.listFiles();
+		for (File file : fList) {
+			if (file.isFile()) {
+				resultList.add(file);
+			} else if (file.isDirectory()) {
+				dirDependencyList.add(file.getName());
+				resultList.addAll(listModelFiles(file.getAbsolutePath()));
+			}
+		}
+		return resultList;
+	}
+	
+    private List<String> createList() {
+        List<String> list = new  ArrayList<>();
+        for (Entry<String, MSAttributeObject> cMap : classMap.entrySet()){
+            if (cMap.getValue().isPolicyTempalate()){
+                list.add(cMap.getKey());
+            }
+            
+        }
+        
+        if (list.isEmpty()){
+            if (classMap.containsKey(this.newModel.getModelName())){
+                list.add(this.newModel.getModelName());
+            }else {
+                list.add("EMPTY");
+            }
+        }
+        return list;
+    }
+
+	public Map<String, String> getAttributesListRefMap() {
+		return attributesListRefMap;
+	}
+
+	public Map<String, LinkedList<String>> getArrayTextList() {
+		return arrayTextList;
+	}
+
+	private OptimizationObject setOptimizationObjectValues(PolicyRestAdapter policyAdapter) {
+		OptimizationObject optimizationObject = new OptimizationObject();
+		optimizationObject.setTemplateVersion(XACMLProperties.getProperty(XACMLRestProperties.TemplateVersion_OOF));
+
+		if(policyAdapter.getServiceType() !=null){
+			optimizationObject.setService(policyAdapter.getServiceType());
+			optimizationObject.setVersion(policyAdapter.getVersion());
+		}
+		if(policyAdapter.getPolicyName()!=null){
+			optimizationObject.setPolicyName(policyAdapter.getPolicyName());
+		}
+		if(policyAdapter.getPolicyDescription()!=null){
+			optimizationObject.setDescription(policyAdapter.getPolicyDescription());
+		}
+		if (policyAdapter.getPriority()!=null){
+			optimizationObject.setPriority(policyAdapter.getPriority());
+		}else {
+			optimizationObject.setPriority("9999");
+		}
+		if (policyAdapter.getRiskLevel()!=null){
+			optimizationObject.setRiskLevel(policyAdapter.getRiskLevel());
+		}
+		if (policyAdapter.getRiskType()!=null){
+			optimizationObject.setRiskType(policyAdapter.getRiskType());
+		}
+		if (policyAdapter.getGuard()!=null){
+			optimizationObject.setGuard(policyAdapter.getGuard());
+		}		
+		return optimizationObject;
+	}
+}
+
+class OptimizationObject {
+
+	private String service;
+	private String policyName;
+	private String description;
+	private String templateVersion;
+	private String version;
+	private String priority;
+	private String policyScope;
+	private String riskType;
+	private String riskLevel; 
+	private String guard = null;
+
+	public String getGuard() {
+		return guard;
+	}
+	public void setGuard(String guard) {
+		this.guard = guard;
+	}
+	public String getRiskType() {
+		return riskType;
+	}
+	public void setRiskType(String riskType) {
+		this.riskType = riskType;
+	}
+	public String getRiskLevel() {
+		return riskLevel;
+	}
+	public void setRiskLevel(String riskLevel) {
+		this.riskLevel = riskLevel;
+	}
+	public String getPriority() {
+		return priority;
+	}
+	public void setPriority(String priority) {
+		this.priority = priority;
+	}
+	public String getPolicyScope() {
+		return policyScope;
+	}
+	public void setPolicyScope(String policyScope) {
+		this.policyScope = policyScope;
+	}
+	public String getVersion() {
+		return version;
+	}
+	public void setVersion(String version) {
+		this.version = version;
+	}
+	private Object content;
+
+	public String getPolicyName() {
+		return policyName;
+	}
+	public void setPolicyName(String policyName) {
+		this.policyName = policyName;
+	}
+	public String getDescription() {
+		return description;
+	}
+	public void setDescription(String description) {
+		this.description = description;
+	}
+	public Object getContent() {
+		return content;
+	}
+	public void setContent(Object content) {
+		this.content = content;
+	}
+	public String getService() {
+		return service;
+	}
+	public void setService(String service) {
+		this.service = service;
+	}
+	public String getTemplateVersion() {
+		return templateVersion;
+	}
+	public void setTemplateVersion(String templateVersion) {
+		this.templateVersion = templateVersion;
+	}
+
+}
\ No newline at end of file
diff --git a/POLICY-SDK-APP/src/main/webapp/app/policyApp/Windows/Dictionary/MSHeaderDefaultValuesDictionary.html b/POLICY-SDK-APP/src/main/webapp/app/policyApp/Windows/Dictionary/MSHeaderDefaultValuesDictionary.html
new file mode 100644
index 0000000..6b841e7
--- /dev/null
+++ b/POLICY-SDK-APP/src/main/webapp/app/policyApp/Windows/Dictionary/MSHeaderDefaultValuesDictionary.html
@@ -0,0 +1,90 @@
+<!--/*-
+ * ============LICENSE_START=======================================================
+ * ONAP Policy Engine
+ * ================================================================================
+ * Copyright (C) 2018 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=========================================================
+ */-->
+<script type="text/ng-template" id="add_HeaderDefaultValues_popup.html">
+<div class="modal" tabindex="-1">
+		 <div class="modal-dialog modal-lg">
+			<div class="modal-content">
+        <div class="modal-header">
+            <h2 class="font-showcase-font-name" style="color : #157bb2">{{label}}</h2>
+        </div>
+		<form name="formdata" ng-submit="saveHeaderDefaults(editHeaderDefaults);" novalidate>
+        <div class="modal-body" id="HeaderDefaultValues">
+			<div class="form-group row">
+  			  <div class="form-group col-sm-6" ng-class="{ 'has-error' : formdata.modelName.$invalid && !formdata.modelName.$pristine }">
+            	 <label>Micro Service:<sup><b>*</b></sup></label><br>
+            	 <select class="form-control" name= "modelName"  required  ng-model="editHeaderDefaults.modelName"  ng-options="option for option in microServiceModelsDictionaryDatas track by option" ></select>
+				 <p ng-show="formdata.modelName.$invalid && !formdata.modelName.$pristine" class="help-block">Micro Service is required.</p>
+     		   </div>
+  			   <div class="form-group col-sm-6" ng-class="{ 'has-error' : formdata.modelName.$invalid && !formdata.modelName.$pristine }">
+            	  <label>Onap Name:<sup><b>*</b></sup></label><br>
+            	  <select class="form-control" name= "modelName"  required  ng-model="editHeaderDefaults.onapName"  ng-options="option for option in onapNameDictionaryDatas track by option" ></select>
+				  <p ng-show="formdata.modelName.$invalid && !formdata.modelName.$pristine" class="help-block">Micro Service is required.</p>
+     		    </div>
+			</div>
+
+			<div class="form-group row">
+  			  <div class="form-group col-sm-6" ng-class="{ 'has-error' : formdata.modelName.$invalid && !formdata.modelName.$pristine }">
+            	  <label>Guard:<sup><b>*</b></sup></label><br>
+            	  <select
+						class="form-control" ng-disabled="temp.policy.readOnly"
+						ng-model="editHeaderDefaults.guard" >
+						<option>True</option>
+						<option>False</option>
+                  </select>
+				  <p ng-show="formdata.modelName.$invalid && !formdata.modelName.$pristine" class="help-block">Guard is required.</p>
+     		   </div>
+  			   <div class="form-group col-sm-6" ng-class="{ 'has-error' : formdata.modelName.$invalid && !formdata.modelName.$pristine }">
+            	  <label>Priority:<sup><b>*</b></sup></label><br>
+                   <select
+						class="form-control" ng-disabled="temp.policy.readOnly"
+						ng-model="editHeaderDefaults.priority"
+						ng-options="option for option in priorityDatas track by option">
+					</select>				  
+                    <p ng-show="formdata.modelName.$invalid && !formdata.modelName.$pristine" class="help-block">Priority is required.</p>
+     		    </div>
+			</div>
+			<div class="form-group row">
+  			     <div class="form-group col-sm-6" ng-class="{ 'has-error' : formdata.modelName.$invalid && !formdata.modelName.$pristine }">
+            	 <label>Risk Type:<sup><b>*</b></sup></label><br>
+            	 <select  name= "riskType"  required class="form-control"  ng-model="editHeaderDefaults.riskType"  ng-options="option for option in riskTypeDictionaryDatas track by option"></select>
+      			 <p ng-show="formdata.riskType.$invalid && !formdata.riskType.$pristine" class="help-block">Policy riskType is required.</p>
+     		     </div>
+  			     <div class="form-group col-sm-6" ng-class="{ 'has-error' : formdata.modelName.$invalid && !formdata.modelName.$pristine }">
+            	    <label>Risk Level:<sup><b>*</b></sup></label><br>
+            	    <select class="form-control" ng-disabled="temp.policy.readOnly"
+						ng-model="editHeaderDefaults.riskLevel">
+                        <option>1</option>
+						<option>2</option>
+						<option>3</option>
+						<option>4</option>
+						<option>5</option></select>
+				    <p ng-show="formdata.modelName.$invalid && !formdata.modelName.$pristine" class="help-block">Risk Level is required.</p>
+     		     </div>
+			</div>
+        </div>
+        <div class="modal-footer">
+            <button class="btn btn-success" type="submit" ng-disabled="formdata.$invalid">Save</button>
+            <button class="btn btn-default"  type="button" ng-click="close()">Close</button>
+		</div>
+		</form>
+    </div>
+			</div>
+</div>
+</script>
\ No newline at end of file
diff --git a/POLICY-SDK-APP/src/main/webapp/app/policyApp/Windows/Dictionary/OptimizationModelsDictionary.html b/POLICY-SDK-APP/src/main/webapp/app/policyApp/Windows/Dictionary/OptimizationModelsDictionary.html
new file mode 100644
index 0000000..bd9c51b
--- /dev/null
+++ b/POLICY-SDK-APP/src/main/webapp/app/policyApp/Windows/Dictionary/OptimizationModelsDictionary.html
@@ -0,0 +1,61 @@
+<!--/*-
+ * ============LICENSE_START=======================================================
+ * ONAP Policy Engine
+ * ================================================================================
+ * Copyright (C) 2018 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=========================================================
+ */-->
+<script type="text/ng-template" id="add_optimizationModel_popup.html">
+<div class="modal" tabindex="-1">
+		 <div class="modal-dialog modal-lg">
+			<div class="modal-content">
+        <div class="modal-header">
+            <h2 class="font-showcase-font-name" style="color : #157bb2">{{label}}</h2>
+        </div>
+		<form name="formdata" ng-submit="saveOptimizationModel(editOptimizationModelName);" novalidate>
+        <div class="modal-body">
+			<div class="form-group row">
+            <div class="form-group col-sm-12">
+                <label>Description:</label><br>
+                <input type="text" ng-model="editOptimizationModelName.description" class="form-control"/>
+            </div>
+			</div>
+			<div class="form-group row">
+ 			<div  class="form-group col-sm-6" ng-class="{ 'has-error' : formdata.file.$invalid && !formdata.file.$pristine }">
+				<input type="file" name="file" onchange="angular.element(this).scope().uploadFile(this.files)" name= "file"  required/>
+				<p ng-show="formdata.file.$invalid && !formdata.file.$pristine" class="help-block">Uploading Model is required.</p>
+            </div>
+			</div>
+			<div class="form-group row">
+  			<div class="form-group col-sm-6" ng-class="{ 'has-error' : formdata.modelName.$invalid && !formdata.modelName.$pristine }">
+            	<label>Optimization Model Name:<sup><b>*</b></sup></label><br>
+            	<select class="form-control" name= "editOptimizationModelName.modelName"  required   ng-model="editOptimizationModelName.modelName"  ng-options="option for option in classListDatas track by option" ></select>
+				<p ng-show="formdata.classList.$invalid && !formdata.classList.$pristine" class="help-block">Optimization Model is required.</p>
+     		 </div>
+			 <div class="form-group col-sm-6">
+            	<label>Version:<sup><b>*</b></sup></label><br>
+            	<input type="text" required ng-model="editOptimizationModelName.version" class="form-control"/>
+         	</div>
+			</div>
+        </div>
+        <div class="modal-footer">
+            <button class="btn btn-success" type="submit" ng-disabled="formdata.$invalid">Save</button>
+            <button class="btn btn-default"  type="button" ng-click="close()">Close</button>
+		</div>
+		</form>
+			</div>
+</div>
+    </div>
+</script>
diff --git a/POLICY-SDK-APP/src/main/webapp/app/policyApp/controller/DictionaryController.js b/POLICY-SDK-APP/src/main/webapp/app/policyApp/controller/DictionaryController.js
index cc3dd14..d125238 100644
--- a/POLICY-SDK-APP/src/main/webapp/app/policyApp/controller/DictionaryController.js
+++ b/POLICY-SDK-APP/src/main/webapp/app/policyApp/controller/DictionaryController.js
@@ -2,7 +2,7 @@
  * ============LICENSE_START=======================================================
  * ONAP Policy Engine
  * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2017-2018 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.
@@ -19,7 +19,7 @@
  */
 
 var mainDictionarys = ["Action Policy", "BRMS Policy", "Common Dictionary", "ClosedLoop Policy","Decision Policy", "Descriptive Policy",
-	 "Firewall Policy", "MicroService Policy", "Policy Scope", "Safe Policy Dictionary"];
+	 "Firewall Policy", "MicroService Policy", "Optimization Policy", "Policy Scope", "Safe Policy Dictionary"];
 var subDictionarys = [["Action Dictionary"],
 	["BRMS Controller" , "BRMS Dependency", "BRMS Param Template"],
 	["Attribute Dictionary","OnapName Dictionary"],
@@ -27,7 +27,8 @@
 	["Settings Dictionary","Rainy Day Allowed Treatments"],
 	["Descriptive Scope"],
 	["Action List", "Address Group", "Parent Dictionary List", "Port List", "Prefix List", "Protocol List", "Security Zone", "Service Group", "Service List", "Tag List", "Tag Picker List", "Term List", "Zone"],
-	["DCAE UUID","MicroService ConfigName","MicroService Location", "MicroService Models", "MicroService Dictionary"],
+	["DCAE UUID","Header Default Values","MicroService ConfigName","MicroService Location", "MicroService Models", "MicroService Dictionary"],
+	["ONAP Optimization Models"],
 	["Closed Loop", "Group Policy Scope", "Resource", "Service", "Type"],
 	["Risk Type", "Safe Policy Warning"]];
 app.controller('dictionaryTabController', function ($scope, PolicyAppService, modalService, $modal){
diff --git a/POLICY-SDK-APP/src/main/webapp/app/policyApp/controller/dictionaryController/MSHeaderDefaultValuesDictController.js b/POLICY-SDK-APP/src/main/webapp/app/policyApp/controller/dictionaryController/MSHeaderDefaultValuesDictController.js
new file mode 100644
index 0000000..883ac25
--- /dev/null
+++ b/POLICY-SDK-APP/src/main/webapp/app/policyApp/controller/dictionaryController/MSHeaderDefaultValuesDictController.js
@@ -0,0 +1,133 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP Policy Engine
+ * ================================================================================
+ * Copyright (C) 2018 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=========================================================
+ */
+app.controller('editMSHeaderDefaultValuesController' ,  function ($scope, $modalInstance, message, PolicyAppService, UserInfoServiceDS2, Notification){
+	   if(message.modelAttributeDictionaryData==null)
+	        $scope.label='Set Header Default Values'
+	    else{
+	        $scope.label='Edit Header Default Values'
+	        $scope.disableCd=true;
+	    }
+
+	    PolicyAppService.getData('getDictionary/get_MicroServiceHeaderDefaultsData').then(function (data) {
+	    	var j = data;
+	    	$scope.data = JSON.parse(j.data);
+	    	console.log($scope.data);
+	    	$scope.microServiceHeaderDefaultDatas = JSON.parse($scope.data.microServiceHeaderDefaultDatas);
+	    	console.log("microServiceHeaderDefaultDatas:" + $scope.microServiceHeaderDefaultDatas);
+	    }, function (error) {
+	    	console.log("failed");
+	    });
+
+	    PolicyAppService.getData('getDictionary/get_MicroServiceModelsDataServiceVersion').then(function (data) {
+	    	var j = data;
+	    	$scope.data = JSON.parse(j.data);
+	    	console.log($scope.data);
+	    	$scope.microServiceModelsDictionaryDatas = JSON.parse($scope.data.microServiceModelsDictionaryDatas);
+	    	console.log($scope.microServiceModelsDictionaryDatas);
+	    }, function (error) {
+	    	console.log("failed");
+	    });
+	    
+		PolicyAppService.getData('getDictionary/get_RiskTypeDataByName').then(function (data) {
+			var j = data;
+			$scope.data = JSON.parse(j.data);
+			console.log("riskTypeDictionaryDatas = " + $scope.data);
+			$scope.riskTypeDictionaryDatas = JSON.parse($scope.data.riskTypeDictionaryDatas);
+			console.log($scope.riskTypeDictionaryDatas);
+		}, function (error) {
+			console.log("failed");
+		});
+
+		PolicyAppService.getData('getDictionary/get_RiskTypeDataByName').then(function (data) {
+			var j = data;
+			$scope.data = JSON.parse(j.data);
+			console.log("riskTypeDictionaryDatas: " + $scope.data);
+			$scope.riskTypeDictionaryDatas = JSON.parse($scope.data.riskTypeDictionaryDatas);
+			console.log($scope.riskTypeDictionaryDatas);
+		}, function (error) {
+			console.log("failed");
+		});
+		
+		PolicyAppService.getData('getDictionary/get_OnapNameDataByName').then(function (data) {
+			var j = data;
+			$scope.data = JSON.parse(j.data);
+			console.log($scope.data);
+			$scope.onapNameDictionaryDatas = JSON.parse($scope.data.onapNameDictionaryDatas);
+			console.log($scope.onapNameDictionaryDatas);
+		}, function (error) {
+			console.log("failed");
+		});
+
+		PolicyAppService.getData('get_DCAEPriorityValues').then(function (data) {
+			var j = data;
+			$scope.data = JSON.parse(j.data);
+			console.log($scope.data);
+			$scope.priorityDatas = JSON.parse($scope.data.priorityDatas);
+			console.log($scope.priorityDatas);
+		}, function (error) {
+			console.log("failed");
+		});
+				
+		/*getting user info from session*/
+		var userid = null;
+		UserInfoServiceDS2.getFunctionalMenuStaticDetailSession()
+		  	.then(function (response) {	  		
+		  		userid = response.userid;	  	
+		 });
+		
+	    $scope.editHeaderDefaults = message.modelAttributeDictionaryData;
+	    $scope.editModelAttribute1 = {microservice: []};
+	    if($scope.edit){
+	    	if(message.modelAttributeDictionaryData.groupList != null){
+	    		var splitValue = message.modelAttributeDictionaryData.groupList.split(",");
+	    		console.log(splitValue);
+	    	}	
+	    }
+	    $scope.saveHeaderDefaults = function(editHeaderDefaultsData) {
+	    	console.log("editHeaderDefaultsData :" + editHeaderDefaultsData);
+	        var uuu = "saveDictionary/ms_dictionary/save_headerDefaults";
+	    	var postData={modelAttributeDictionaryData: editHeaderDefaultsData, userid: userid};
+	    	$.ajax({
+	    			type : 'POST',
+	    			url : uuu,
+	    			dataType: 'json',
+	    			contentType: 'application/json',
+	    			data: JSON.stringify(postData),
+	    			success : function(data){
+	    				$scope.$apply(function(){
+	    					$scope.microServiceAttributeDictionaryDatas=data.microServiceHeaderDefaultDatas;});
+	    				if($scope.microServiceAttributeDictionaryDatas == "Duplicate"){
+	    					Notification.error("Model Attribute Dictionary exists with Same Attribute Name.")
+	    				}else{      
+	    					console.log($scope.microServiceAttributeDictionaryDatas);
+	    					$modalInstance.close({microServiceAttributeDictionaryDatas:$scope.microServiceAttributeDictionaryDatas});
+	    				}
+	    			},
+	    			error : function(data){
+	    				alert("Error while saving.");
+	    			}
+	    	});
+	    	
+	    };
+
+	    $scope.close = function() {
+	        $modalInstance.close();
+	    };
+	});
\ No newline at end of file
diff --git a/POLICY-SDK-APP/src/main/webapp/app/policyApp/controller/dictionaryController/MSModelsDictController.js b/POLICY-SDK-APP/src/main/webapp/app/policyApp/controller/dictionaryController/MSModelsDictController.js
index 105225a..3165b1b 100644
--- a/POLICY-SDK-APP/src/main/webapp/app/policyApp/controller/dictionaryController/MSModelsDictController.js
+++ b/POLICY-SDK-APP/src/main/webapp/app/policyApp/controller/dictionaryController/MSModelsDictController.js
@@ -57,6 +57,7 @@
                 	$scope.classListDatas=data.classListDatas;
                 	$scope.modalDatas = data.modelDatas;
                 	$scope.modelType= data.modelType;
+                	$scope.dataOrderInfo= data.dataOrderInfo;
                 	console.log($scope.classListDatas);
                 }
             }).error( );
@@ -70,7 +71,7 @@
     $scope.saveMSModel = function(microServiceModelsDictionaryData) {
     	if(valid){
     		 var uuu = "saveDictionary/ms_dictionary/save_model";
-    	        var postData={microServiceModelsDictionaryData: microServiceModelsDictionaryData, userid: userid, classMap: $scope.modalDatas,modelType:$scope.modelType};
+    	        var postData={microServiceModelsDictionaryData: microServiceModelsDictionaryData, userid: userid, classMap: $scope.modalDatas,modelType:$scope.modelType, dataOrderInfo:$scope.dataOrderInfo};
     	        $.ajax({
     	            type : 'POST',
     	            url : uuu,
diff --git a/POLICY-SDK-APP/src/main/webapp/app/policyApp/controller/dictionaryController/OptimizationModelsDictController.js b/POLICY-SDK-APP/src/main/webapp/app/policyApp/controller/dictionaryController/OptimizationModelsDictController.js
new file mode 100644
index 0000000..3279a60
--- /dev/null
+++ b/POLICY-SDK-APP/src/main/webapp/app/policyApp/controller/dictionaryController/OptimizationModelsDictController.js
@@ -0,0 +1,104 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP Policy Engine
+ * ================================================================================
+ * Copyright (C) 2018 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=========================================================
+ */
+app.controller('editOptimizationModelController' ,  function ($scope, $modalInstance, message, $http, UserInfoServiceDS2, Notification){
+    if(message.optimizationModelsDictionaryData==null)
+        $scope.label='Add Optimization Model'
+    else{
+        $scope.label='Edit Optimization Model'
+        $scope.disableCd=true;
+    }
+	
+	/*getting user info from session*/
+	var userid = null;
+	UserInfoServiceDS2.getFunctionalMenuStaticDetailSession()
+	  	.then(function (response) {	  		
+	  		userid = response.userid;	  	
+	 });
+	
+	var valid = true;
+    $scope.editOptimizationModelName = message.optimizationModelsDictionaryData;
+
+    $scope.uploadFile = function(files) {
+    	var extn = files[0].name.substr(files[0].name.lastIndexOf('.')+1);
+    	if(extn == 'zip' || extn == 'xmi'||  extn == 'yml'){
+    		valid = true;
+    		var fd = new FormData();
+    		fd.append("file", files[0]);
+    		$http.post("oof_dictionary/set_ModelData", fd, {
+    			withCredentials: false,
+    			headers: {'Content-Type': undefined },
+    			transformRequest: angular.identity
+    		}).success(function(data){
+    			if(data.errorMsg != undefined){
+    				Notification.error(data.errorMsg);
+    				valid = false;
+    				return;
+    			}     			
+                if(data.classListDatas  == "EMPTY"){
+                	Notification.error("No Optimization Models Available.")
+                }else{      
+                	$scope.classListDatas=data.classListDatas;
+                	$scope.modalDatas = data.modelDatas;
+                	$scope.modelType= data.modelType;
+                	$scope.dataOrderInfo= data.dataOrderInfo;
+                	console.log($scope.classListDatas);
+                }
+            }).error( );
+    	}else{
+    		Notification.error("Optimization Model Upload file should ends with .zip or .xmi extension");
+    		valid = false;
+    	}
+
+    };
+    
+    $scope.saveOptimizationModel = function(optimizationModelsDictionaryData) {
+    	if(valid){
+    		 var uuu = "saveDictionary/oof_dictionary/save_model";
+    	        var postData={optimizationModelsDictionaryData: optimizationModelsDictionaryData, userid: userid, classMap: $scope.modalDatas,modelType:$scope.modelType, dataOrderInfo:$scope.dataOrderInfo};
+    	        $.ajax({
+    	            type : 'POST',
+    	            url : uuu,
+    	            dataType: 'json',
+    	            contentType: 'application/json',
+    	            data: JSON.stringify(postData),
+    	            success : function(data){
+    	                $scope.$apply(function(){
+    	                    $scope.optimizationModelsDictionaryDatas=data.optimizationModelsDictionaryDatas;});
+    	                if($scope.optimizationModelsDictionaryDatas == "Duplicate"){
+    	                	Notification.error("Optimization Model Dictionary exists with Same Model Name.")
+    	                }else{      
+    	                	console.log($scope.optimizationModelsDictionaryDatas);
+    	                    $modalInstance.close({optimizationModelsDictionaryDatas:$scope.optimizationModelsDictionaryDatas});
+    	                }
+    	            },
+    	            error : function(data){
+    	                Notification.error("Error while saving.");
+    	            }
+    	        });
+    	}else{
+    		Notification.error("Please check Optimization Model Upload file format.");
+    	}
+       
+    };
+
+    $scope.close = function() {
+        $modalInstance.close();
+    };
+});
\ No newline at end of file
diff --git a/POLICY-SDK-APP/src/main/webapp/app/policyApp/controller/dictionaryGridController/MSHeaderDefaultValuesDictGridController.js b/POLICY-SDK-APP/src/main/webapp/app/policyApp/controller/dictionaryGridController/MSHeaderDefaultValuesDictGridController.js
new file mode 100644
index 0000000..5a86c14
--- /dev/null
+++ b/POLICY-SDK-APP/src/main/webapp/app/policyApp/controller/dictionaryGridController/MSHeaderDefaultValuesDictGridController.js
@@ -0,0 +1,168 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP Policy Engine
+ * ================================================================================
+ * Copyright (C) 2018 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=========================================================
+ */
+app.controller('msHeaderDefaultValuesDictGridController', function ($scope, PolicyAppService, modalService, $modal){
+    $( "#dialog" ).hide();
+    
+    PolicyAppService.getData('getDictionary/get_MicroServiceHeaderDefaultsData').then(function (data) {
+    	var j = data;
+    	$scope.data = JSON.parse(j.data);
+    	console.log($scope.data);
+    	$scope.microServiceHeaderDefaultDatas = JSON.parse($scope.data.microServiceHeaderDefaultDatas);
+    	console.log("microServiceHeaderDefaultDatas: " + $scope.microServiceHeaderDefaultDatas);
+    }, function (error) {
+    	console.log("failed");
+    });
+
+    PolicyAppService.getData('getDictionary/get_MicroServiceModelsDataByName').then(function (data) {
+    	var j = data;
+    	$scope.data = JSON.parse(j.data);
+    	console.log($scope.data);
+    	$scope.microServiceModelsDictionaryDatas = JSON.parse($scope.data.microServiceModelsDictionaryDatas);
+    	console.log($scope.microServiceModelsDictionaryDatas);
+    }, function (error) {
+    	console.log("failed");
+    });
+    
+	PolicyAppService.getData('getDictionary/get_RiskTypeDataByName').then(function (data) {
+		var j = data;
+		$scope.data = JSON.parse(j.data);
+		console.log("riskTypeDictionaryDatas: " + $scope.data);
+		$scope.riskTypeDictionaryDatas = JSON.parse($scope.data.riskTypeDictionaryDatas);
+		console.log($scope.riskTypeDictionaryDatas);
+	}, function (error) {
+		console.log("failed");
+	});
+	
+	PolicyAppService.getData('getDictionary/get_OnapNameDataByName').then(function (data) {
+		var j = data;
+		$scope.data = JSON.parse(j.data);
+		console.log($scope.data);
+		$scope.onapNameDictionaryDatas = JSON.parse($scope.data.onapNameDictionaryDatas);
+		console.log($scope.onapNameDictionaryDatas);
+	}, function (error) {
+		console.log("failed");
+	});
+
+	PolicyAppService.getData('get_DCAEPriorityValues').then(function (data) {
+		var j = data;
+		$scope.data = JSON.parse(j.data);
+		console.log($scope.data);
+		$scope.priorityDatas = JSON.parse($scope.data.priorityDatas);
+		console.log($scope.priorityDatas);
+	}, function (error) {
+		console.log("failed");
+	});
+	
+    PolicyAppService.getData('get_LockDownData').then(function(data){
+    	var j = data;
+    	$scope.data = JSON.parse(j.data);
+    	$scope.lockdowndata = JSON.parse($scope.data.lockdowndata);
+    	if($scope.lockdowndata[0].lockdown == true){
+    		$scope.msHeaderDefaultValuesDictionaryGrid.columnDefs[0].visible = false;
+    		$scope.gridApi.grid.refresh();
+    	}else{
+    		$scope.msHeaderDefaultValuesDictionaryGrid.columnDefs[0].visible = true;
+    		$scope.gridApi.grid.refresh();
+    	}
+    },function(error){
+    	console.log("failed");
+    });
+	
+    $scope.msHeaderDefaultValuesDictionaryGrid = {
+        data : 'microServiceHeaderDefaultDatas',
+        enableFiltering: true,
+        columnDefs: [{
+            field: 'id', enableFiltering: false, headerCellTemplate: '' +
+            '<button id=\'New\' ng-click="grid.appScope.createNewModelAttributeWindow()" class="btn btn-success">' + 'Create</button>',
+            cellTemplate:
+            '<button  type="button"  class="btn btn-primary"  ng-click="grid.appScope.editModelHeaderDefaultsWindow(row.entity)"><i class="fa fa-pencil-square-o"></i></button> ' +
+            '<button  type="button"  class="btn btn-danger"  ng-click="grid.appScope.deleteModelAttribute(row.entity)" ><i class="fa fa-trash-o"></i></button> ',  width: '8%'
+        },{ field: 'modelName', displayName :'MicroService', sort: { direction: 'asc', priority: 0 }},
+            { field: 'guard', displayName :'Guard'}, { field: 'priority', displayName :'Priority'},{ field: 'riskType', displayName :'Risk Type'},{ field: 'riskLevel', displayName :'Risk Level'},{field: 'onapName' , displayName :'Onap Name' }
+        ]
+    };
+
+    $scope.editModelAttribute = null;
+    $scope.createNewModelAttributeWindow = function(){
+        $scope.editModelAttribute = null;
+        var modalInstance = $modal.open({
+        	backdrop: 'static', keyboard: false,
+            templateUrl : 'add_HeaderDefaultValues_popup.html',
+            controller: 'editMSHeaderDefaultValuesController',
+            resolve: {
+                message: function () {
+                    var message = {
+                    		microServiceAttributeDictionaryDatas: $scope.editModelAttribute
+                    };
+                    return message;
+                }
+            }
+        });
+        modalInstance.result.then(function(response){
+            console.log('response', response);
+            $scope.microServiceHeaderDefaultDatas=response.microServiceHeaderDefaultDatas;
+        });
+    };
+
+    $scope.editModelHeaderDefaultsWindow = function(modelAttributeDictionaryData) {
+        $scope.editHeaderDefaults = modelAttributeDictionaryData;
+        var modalInstance = $modal.open({
+        	backdrop: 'static', keyboard: false,
+            templateUrl : 'add_HeaderDefaultValues_popup.html',
+            controller: 'editMSHeaderDefaultValuesController',
+            resolve: {
+                message: function () {
+                    var message = {
+                    		modelAttributeDictionaryData: $scope.editHeaderDefaults
+                    };
+                    return message;
+                }
+            }
+        });
+        modalInstance.result.then(function(response){
+            console.log('response', response);
+            $scope.modelAttributeDictionaryDataa = response.modelAttributeDictionaryDatas;
+        });
+    };
+
+    $scope.deleteModelAttribute = function(data) {
+        modalService.popupConfirmWin("Confirm","You are about to delete the Header Default Values :  "+data.name+". Do you want to continue?",
+            function(){
+                var uuu =  "deleteDictionary/ms_dictionary/remove_headerDefaults";
+                var postData={data: data};
+                $.ajax({
+                    type : 'POST',
+                    url : uuu,
+                    dataType: 'json',
+                    contentType: 'application/json',
+                    data: JSON.stringify(postData),
+                    success : function(data){
+                        $scope.$apply(function(){$scope.microServiceHeaderDefaultDatas=data.microServiceHeaderDefaultDatas;});
+                    },
+                    error : function(data){
+                        console.log(data);
+                        modalService.showFailure("Fail","Error while deleting: "+ data.responseText);
+                    }
+                });
+
+            })
+    };
+
+});
\ No newline at end of file
diff --git a/POLICY-SDK-APP/src/main/webapp/app/policyApp/controller/dictionaryGridController/OptimizationModelDictGridController.js b/POLICY-SDK-APP/src/main/webapp/app/policyApp/controller/dictionaryGridController/OptimizationModelDictGridController.js
new file mode 100644
index 0000000..625467a
--- /dev/null
+++ b/POLICY-SDK-APP/src/main/webapp/app/policyApp/controller/dictionaryGridController/OptimizationModelDictGridController.js
@@ -0,0 +1,166 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP Policy Engine
+ * ================================================================================
+ * Copyright (C) 2018 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=========================================================
+ */
+app.controller('optimizationModelsDictGridController', function ($scope, PolicyAppService, modalService, $modal){
+    $( "#dialog" ).hide();
+    
+    PolicyAppService.getData('getDictionary/get_OptimizationModelsData').then(function (data) {
+    	var j = data;
+    	$scope.data = JSON.parse(j.data);
+    	console.log($scope.data);
+    	$scope.optimizationModelsDictionaryDatas = JSON.parse($scope.data.optimizationModelsDictionaryDatas);
+    	console.log($scope.optimizationModelsDictionaryDatas);
+    }, function (error) {
+    	console.log("failed");
+    });
+
+    PolicyAppService.getData('get_LockDownData').then(function(data){
+    	var j = data;
+    	$scope.data = JSON.parse(j.data);
+    	$scope.lockdowndata = JSON.parse($scope.data.lockdowndata);
+    	if($scope.lockdowndata[0].lockdown == true){
+    		$scope.optimizationModelsDictionaryGrid.columnDefs[0].visible = false;
+    		$scope.gridApi.grid.refresh();
+    	}else{
+    		$scope.optimizationModelsDictionaryGrid.columnDefs[0].visible = true;
+    		$scope.gridApi.grid.refresh();
+    	}
+    },function(error){
+    	console.log("failed");
+    });
+	
+    $scope.optimizationModelsDictionaryGrid = {
+            data : 'optimizationModelsDictionaryDatas',
+            enableFiltering: true,
+    		exporterCsvFilename: 'OptimizationPolicyDictionary.csv',
+    		enableGridMenu: true,
+    		enableSelectAll: true,
+            columnDefs: [{
+                field: 'id', 
+                enableFiltering: false, headerCellTemplate: '' +
+                '<button id=\'New\' ng-click="grid.appScope.createNewOptimizationModelsWindow()" class="btn btn-success">' + 'Create</button>',
+                cellTemplate:
+                    '<button  type="button"  class="btn btn-danger"  ng-click="grid.appScope.deleteOptimizationModels(row.entity)" ><i class="fa fa-trash-o"></i></button> ',  width: '8%'
+            },{ field: 'modelName', displayName : 'ONAP Optimization Model', sort: { direction: 'asc', priority: 0 }},
+                { field: 'description' },
+                { field: 'version', displayName : 'Model Version' },
+                {field: 'userCreatedBy.userName', displayName : 'Imported By' },
+                {field: 'dependency', visible: false}, 
+                {field: 'attributes', visible: false},
+                {field: 'enumValues', visible: false},
+                {field: 'ref_attributes',visible: false},
+                {field: 'sub_attributes', visible: false}
+            ],
+    		exporterMenuPdf: false,
+    		exporterPdfDefaultStyle: {fontSize: 9},
+    		exporterPdfTableStyle: {margin: [30, 30, 30, 30]},
+    		exporterPdfTableHeaderStyle: {fontSize: 10, bold: true, italics: true, color: 'red'},
+    		exporterPdfHeader: { text: "My Header", style: 'headerStyle' },
+    		exporterPdfFooter: function ( currentPage, pageCount ) {
+    			return { text: currentPage.toString() + ' of ' + pageCount.toString(), style: 'footerStyle' };
+    		},
+    		exporterPdfCustomFormatter: function ( docDefinition ) {
+    			docDefinition.styles.headerStyle = { fontSize: 22, bold: true };
+    			docDefinition.styles.footerStyle = { fontSize: 10, bold: true };
+    			return docDefinition;
+    		},
+    		exporterFieldCallback: function(grid, row, col, input) {
+    	       	 if( col.name == 'createdDate' || col.name == 'modifiedDate') {
+    	       		 var date = new Date(input);
+    	       		 return date.toString("yyyy-MM-dd HH:MM:ss a");
+    	       	 } else {
+    	       		 return input;
+    	       	 }
+    	        },
+    		exporterPdfOrientation: 'portrait',
+    		exporterPdfPageSize: 'LETTER',
+    		exporterPdfMaxGridWidth: 500,
+    		exporterCsvLinkElement: angular.element(document.querySelectorAll(".custom-csv-link-location")),
+    		onRegisterApi: function(gridApi){
+    			$scope.gridApi = gridApi;
+    		}
+    };
+    
+    $scope.editOptimizationModelName = null;
+    $scope.createNewOptimizationModelsWindow = function(){
+        $scope.editOptimizationModelName = null;
+        var modalInstance = $modal.open({
+        	backdrop: 'static', keyboard: false,
+            templateUrl : 'add_optimizationModel_popup.html',
+            controller: 'editOptimizationModelController',
+            resolve: {
+                message: function () {
+                    var message = {
+                        optimizationModelsDictionaryDatas: $scope.editOptimizationModelName
+                    };
+                    return message;
+                }
+            }
+        });
+        modalInstance.result.then(function(response){
+            console.log('response', response);
+            $scope.optimizationModelsDictionaryDatas=response.optimizationModelsDictionaryDatas;
+        });
+    };
+
+    $scope.editOptimizationModelsWindow = function(optimizationModelsDictionaryData) {
+        $scope.editOptimizationModelName = optimizationModelsDictionaryData;
+        var modalInstance = $modal.open({
+        	backdrop: 'static', keyboard: false,
+            templateUrl : 'add_optimizationModel_popup.html',
+            controller: 'editOptimizationModelController',
+            resolve: {
+                message: function () {
+                    var message = {
+                        optimizationModelsDictionaryData: $scope.editOptimizationModelName
+                    };
+                    return message;
+                }
+            }
+        });
+        modalInstance.result.then(function(response){
+            console.log('response', response);
+            $scope.optimizationModelsDictionaryDatas = response.optimizationModelsDictionaryDatas;
+        });
+    };
+
+    $scope.deleteOptimizationModels = function(data) {
+        modalService.popupConfirmWin("Confirm","You are about to delete the Optimization Model : "+data.modelName+". Do you want to continue?",
+            function(){
+                var uuu = "deleteDictionary/oof_dictionary/remove_model";
+                var postData={data: data};
+                $.ajax({
+                    type : 'POST',
+                    url : uuu,
+                    dataType: 'json',
+                    contentType: 'application/json',
+                    data: JSON.stringify(postData),
+                    success : function(data){
+                        $scope.$apply(function(){$scope.optimizationModelsDictionaryDatas=data.optimizationModelsDictionaryDatas;});
+                    },
+                    error : function(data){
+                        console.log(data);
+                        modalService.showFailure("Fail","Error while deleting: "+ data.responseText);
+                    }
+                });
+
+            })
+    };
+
+});
\ No newline at end of file
diff --git a/POLICY-SDK-APP/src/main/webapp/app/policyApp/main/policyEditor.html b/POLICY-SDK-APP/src/main/webapp/app/policyApp/main/policyEditor.html
index f5a5e86..9be8d01 100644
--- a/POLICY-SDK-APP/src/main/webapp/app/policyApp/main/policyEditor.html
+++ b/POLICY-SDK-APP/src/main/webapp/app/policyApp/main/policyEditor.html
@@ -2,7 +2,7 @@
  * ============LICENSE_START=======================================================
  * ONAP Policy Engine
  * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2017-2018 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.
@@ -119,6 +119,7 @@
 	<script src= "app/policyApp/policy-models/Editor/PolicyTemplateController/DecisionPolicyController.js"></script>
 	<script src= "app/policyApp/policy-models/Editor/PolicyTemplateController/FirewallPolicyController.js"></script>
 	<script src= "app/policyApp/policy-models/Editor/PolicyTemplateController/DCAEMicroServicePolicyController.js"></script>
+	<script src= "app/policyApp/policy-models/Editor/PolicyTemplateController/OptimizationPolicyController.js"></script>
 	<script src= "app/policyApp/policy-models/Editor/PolicyTemplateController/BRMSRawPolicyController.js"></script>
 	<script src= "app/policyApp/policy-models/Editor/PolicyTemplateController/BRMSParamPolicyController.js"></script>
 	
@@ -153,11 +154,13 @@
 	<script src= "app/policyApp/controller/dictionaryGridController/FWTagPickerListDictGridController.js"></script>
 	<script src= "app/policyApp/controller/dictionaryGridController/FWZoneDictGridController.js"></script>
 	<script src= "app/policyApp/controller/dictionaryGridController/MSConfigNameDictGridController.js"></script>
+	<script src= "app/policyApp/controller/dictionaryGridController/MSHeaderDefaultValuesDictGridController.js"></script>
 	<script src= "app/policyApp/controller/dictionaryGridController/MSDcaeUUIDDictGridController.js"></script>
 	<script src= "app/policyApp/controller/dictionaryGridController/MSLocationDictGridController.js"></script>
 	<script src= "app/policyApp/controller/dictionaryGridController/MSModelDictGridController.js"></script>
 	<script src= "app/policyApp/controller/dictionaryGridController/ModelAttributeDictGridController.js"></script>
-		
+	<script src= "app/policyApp/controller/dictionaryGridController/OptimizationModelDictGridController.js"></script>
+	
 	<script src= "app/policyApp/controller/dictionaryGridController/PSClosedLoopDictGridController.js"></script>
 	<script src= "app/policyApp/controller/dictionaryGridController/PSGroupPolicyScopeDictGridController.js"></script>
 	<script src= "app/policyApp/controller/dictionaryGridController/PSResourceDictGridController.js"></script>
@@ -195,11 +198,13 @@
 	<script src= "app/policyApp/controller/dictionaryController/FWTagListDictController.js"></script>
 	<script src= "app/policyApp/controller/dictionaryController/FWTagPickerListDictController.js"></script>
 	<script src= "app/policyApp/controller/dictionaryController/FWZoneDictController.js"></script>
+	<script src= "app/policyApp/controller/dictionaryController/MSHeaderDefaultValuesDictController.js"></script>	
 	<script src= "app/policyApp/controller/dictionaryController/MSConfigNameDictController.js"></script>
 	<script src= "app/policyApp/controller/dictionaryController/MSDcaeUUIDDictController.js"></script>
 	<script src= "app/policyApp/controller/dictionaryController/MSLocationDictController.js"></script>
 	<script src= "app/policyApp/controller/dictionaryController/MSModelsDictController.js"></script>
 	<script src= "app/policyApp/controller/dictionaryController/ModelAttributeDictController.js"></script>
+	<script src= "app/policyApp/controller/dictionaryController/OptimizationModelsDictController.js"></script>
 		
 	<script src= "app/policyApp/controller/dictionaryController/PSClosedLoopDictController.js"></script>
 	<script src= "app/policyApp/controller/dictionaryController/PSGroupPolicyScopeDictController.js"></script>
@@ -258,11 +263,12 @@
 	    <div ng-include src="'app/policyApp/Windows/Dictionary/FWTermListDictionary.html'"></div>
 	    <div ng-include src="'app/policyApp/Windows/Dictionary/FWZoneDictionary.html'"></div>
 	    <div ng-include src="'app/policyApp/Windows/Dictionary/MSConfigNameDictionary.html'"></div>
+	    <div ng-include src="'app/policyApp/Windows/Dictionary/MSHeaderDefaultValuesDictionary.html'"></div>	    
 	    <div ng-include src="'app/policyApp/Windows/Dictionary/MSDCAEUUIDDictionary.html'"></div>
 	    <div ng-include src="'app/policyApp/Windows/Dictionary/MSLocationDictionary.html'"></div>
 	    <div ng-include src="'app/policyApp/Windows/Dictionary/MSModelsDictionary.html'"></div>
 	    <div ng-include src="'app/policyApp/Windows/Dictionary/ModelAttributeDictionary.html'"></div>
-	    
+	    <div ng-include src="'app/policyApp/Windows/Dictionary/OptimizationModelsDictionary.html'"></div>
 	    <div ng-include src="'app/policyApp/Windows/Dictionary/PSClosedLoopDictionary.html'"></div>
 	    <div ng-include src="'app/policyApp/Windows/Dictionary/PSGroupPolicyScopeDictionary.html'"></div>
 	    <div ng-include src="'app/policyApp/Windows/Dictionary/PSResourceDictionary.html'"></div>
diff --git a/POLICY-SDK-APP/src/main/webapp/app/policyApp/policy-models/Dictionary/MSHeaderDefaultValuesDictionary.html b/POLICY-SDK-APP/src/main/webapp/app/policyApp/policy-models/Dictionary/MSHeaderDefaultValuesDictionary.html
new file mode 100644
index 0000000..c848de5
--- /dev/null
+++ b/POLICY-SDK-APP/src/main/webapp/app/policyApp/policy-models/Dictionary/MSHeaderDefaultValuesDictionary.html
@@ -0,0 +1,22 @@
+<!--/*-
+ * ============LICENSE_START=======================================================
+ * ONAP Policy Engine
+ * ================================================================================
+ * Copyright (C) 2018 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=========================================================
+ */-->
+<div ng-app ng-controller = "msHeaderDefaultValuesDictGridController">
+    <div  ui-grid = "msHeaderDefaultValuesDictionaryGrid" ui-grid-pagination ui-grid-selection ui-grid-exporter class= "grid"></div>
+</div>
\ No newline at end of file
diff --git a/POLICY-SDK-APP/src/main/webapp/app/policyApp/policy-models/Dictionary/OptimizationModelDictionary.html b/POLICY-SDK-APP/src/main/webapp/app/policyApp/policy-models/Dictionary/OptimizationModelDictionary.html
new file mode 100644
index 0000000..fc44bad
--- /dev/null
+++ b/POLICY-SDK-APP/src/main/webapp/app/policyApp/policy-models/Dictionary/OptimizationModelDictionary.html
@@ -0,0 +1,22 @@
+<!--/*-
+ * ============LICENSE_START=======================================================
+ * ONAP Policy Engine
+ * ================================================================================
+ * Copyright (C) 2018 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=========================================================
+ */-->
+<div ng-controller = "optimizationModelsDictGridController">
+    <div  ui-grid = "optimizationModelsDictionaryGrid" ui-grid-pagination ui-grid-selection ui-grid-exporter class= "grid"></div>
+</div>
\ No newline at end of file
diff --git a/POLICY-SDK-APP/src/main/webapp/app/policyApp/policy-models/Editor/PolicyTemplateController/DCAEMicroServicePolicyController.js b/POLICY-SDK-APP/src/main/webapp/app/policyApp/policy-models/Editor/PolicyTemplateController/DCAEMicroServicePolicyController.js
index cfc9bec..cb5c9ca 100644
--- a/POLICY-SDK-APP/src/main/webapp/app/policyApp/policy-models/Editor/PolicyTemplateController/DCAEMicroServicePolicyController.js
+++ b/POLICY-SDK-APP/src/main/webapp/app/policyApp/policy-models/Editor/PolicyTemplateController/DCAEMicroServicePolicyController.js
@@ -167,7 +167,7 @@
 	 $scope.attributeDatas = [{"attributes" : $scope.choices}];
 	 $scope.isInitEditTemplate = true;  //just initially create the edit template, didn't click add button yet.
 	 $scope.addNewChoice = function(value) {
-		 console.log(value);
+		 console.log("input value : " + value);
 		 if(value != undefined){
 			if (value.startsWith('div.')){
 				value = value.replace('div.','');
@@ -184,20 +184,24 @@
 						if($scope.temp.policy.ruleData[clone.id]){
 						    clone.value = $scope.temp.policy.ruleData[clone.id];
 						}
-						clone.className += ' child_single'; //here cloned is single element
+						if(!clone.className.includes("child_single")){
+						   clone.className += ' child_single'; //here cloned is single element
+						}
 						document.getElementById("div."+value).appendChild(clone);
 						plainAttributeKeys.push(''+value+'@'+addElement);
 					}
 				}else{ //not view or edit
-					clone.className += ' child_single'; //here cloned is single element
+					if(!clone.className.includes("child_single")){
+					    clone.className += ' child_single'; //here cloned is single element
+					}
 					document.getElementById("div."+value).appendChild(clone);
 					plainAttributeKeys.push(''+value+'@'+addElement);
 				}
 			}else{
 				div = document.getElementById("div."+value+"@0");
-				
-				div.className += ' children_group'; //here is div with a group of children.
-				
+				if(div){
+			    	div.className += ' children_group'; //here is div with a group of children.
+				}
 				var childElement = parentElement.firstElementChild;
 				var countParent = parentElement.childElementCount;
 				var childElementString = childElement.innerHTML;
@@ -279,6 +283,21 @@
 		 }
 	 };
 	 
+	 function findVal(object, key) {
+		    var value;
+		    Object.keys(object).some(function(k) {
+		        if (k === key) {
+		            value = object[k];
+		            return true;
+		        }
+		        if (object[k] && typeof object[k] === 'object') {
+		            value = findVal(object[k], key);
+		            return value !== undefined;
+		        }
+		    });
+		    return value;
+	}
+	 
 	 $scope.pullVersion = function(serviceName) {
 		 console.log(serviceName);
 		 if(serviceName != undefined){
@@ -320,6 +339,11 @@
         	myNode.innerHTML = '';
             var uuu = "policyController/getDCAEMSTemplateData.htm";
             var postData={policyData: service};
+            
+            console.log("service: " +service);
+
+            var dataOrderInfo = "";
+
             $.ajax({
                 type : 'POST',
                 url : uuu,
@@ -328,10 +352,15 @@
                 data: JSON.stringify(postData),
                 success : function(data){
                     $scope.$apply(function(){
-                    	$scope.addNewChoice();
+                    //	$scope.addNewChoice();  
                     	var plainAttributeKeys = [];
                     	$scope.dcaeModelData = data[0].dcaeModelData;
                     	$scope.dcaeJsonDate = data[0].jsonValue;
+                        $scope.dataOrderInfo = null;
+                    	$scope.dataOrderInfo = data[0].dataOrderInfo;
+                    	console.log("data[0].dataOrderInfo: " + data[0].dataOrderInfo);
+                    	console.log("$scope.dataOrderInfo: " + $scope.dataOrderInfo);	
+                    	
                     	if(data[0].allManyTrueKeys){
 	                    	console.log("$scope.allManyTrueKeys: " + $scope.allManyTrueKeys);
                     	}
@@ -341,6 +370,22 @@
                     	var subAttributes = 	$scope.dcaeModelData.sub_attributes;                    	
                     	console.log("subAttributes: " + subAttributes);	
                     	console.log("refAttributes: " + refAttributes);	
+                    	var headDefautlsData  = data[0].headDefautlsData;
+                    	if(headDefautlsData != null){
+	               			 $scope.temp.policy.onapName = headDefautlsData.onapName;
+	               			 $scope.temp.policy.guard = headDefautlsData.guard;
+	               			 $scope.temp.policy.riskType = headDefautlsData.riskType;
+	               			 $scope.temp.policy.riskLevel = headDefautlsData.riskLevel;
+	               			 $scope.temp.policy.priority = headDefautlsData.priority;
+	               			 
+                    	}else if(!$scope.temp.policy.editPolicy && !$scope.temp.policy.readOnly){
+	               			 $scope.temp.policy.onapName = "";
+	               			 $scope.temp.policy.guard = "";
+	               			 $scope.temp.policy.riskType = "";
+	               			 $scope.temp.policy.riskLevel = "";
+	               			 $scope.temp.policy.priority = "";
+                    	}
+                    	  
                        	var enumAttributes = $scope.dcaeModelData.enumValues;
                        	var annotation = $scope.dcaeModelData.annotation;
                        	var dictionary = $scope.microServiceAttributeDictionaryDatas;
@@ -380,6 +425,10 @@
 
                 		$scope.temp.policy.ruleGridData = [];
                 		
+                		if($scope.temp.policy.editPolicy || $scope.temp.policy.readOnly){
+                			dataOrderInfo = $scope.dataOrderInfo;
+                		}
+                		
                 		$scope.jsonLayout($scope.dcaeJsonDate);
                 		
                     });
@@ -401,59 +450,97 @@
 	                    		
 	                    		var extraElements = data;
 	                    		
-	            		    	if(plainAttributeKeys != null){
-	            		    		for(b = 0; b < plainAttributeKeys.length; b++){ // Remove already populated elements from data array
-	            		    			var newValue = plainAttributeKeys[b].split("*");
-	            		    			for(a = 0; a < data.length; a++){
-		            		    			if(data[a] === newValue[0] || data[a] === (newValue[0]+"@0")){
-		            		    				extraElements.splice(a, 1);
+		            		    if(plainAttributeKeys != null){
+		            		    		for(b = 0; b < plainAttributeKeys.length; b++){ // Remove already populated elements from data array
+		            		    			var newValue = plainAttributeKeys[b].split("*");
+		            		    			for(a = 0; a < data.length; a++){
+			            		    			if(data[a] === newValue[0] || data[a] === (newValue[0]+"@0")){
+			            		    				extraElements.splice(a, 1);
+			            		    			}
 		            		    			}
-	            		    			}
-	            		    	}
-	                    		
-	            		    	//--- Populate these extra elements created by clicked add button 
-		                    	for(a = 0; a < extraElements.length; a++){            			
-		                    		if(extraElements[a].includes("@")){
-				                    	var index = extraElements[a].lastIndexOf("@");
-				                    	if(index > 0){
-				                    	    // Get the number after @
-				                    	    var n = getNumOfDigits(extraElements[a], index+1);
-				                    				
-					                        var key = extraElements[a].substring(0, index+n+1); //include @x in key also by n+2 since x can be 1,12, etc
-					                    	console.log("key: " + key);
-					                    	checkData.push(key);
-				                    	}
-		                    		}
-		                    	}
-	                    		var unique = checkData.filter(onlyUnique);
-	                    		for(i =0; i < unique.length; i++){
-	                    			//remove @x and let addNewChoice add @1 or @2...
-	                    			//var newKey = unique[i].substring(0, unique[i].length-2);
-	                    			var index = unique[i].lastIndexOf("@");
-	                    			var newKey = unique[i].substring(0, index);
-	                    			console.log("newKey: " + newKey);	
-	                    			$scope.addNewChoice(newKey);
-	                    		}
+		            		    	}
+		                    		
+		            		    	//--- Populate these extra elements created by clicked add button 
+			                    	for(a = 0; a < extraElements.length; a++){            			
+			                    		if(extraElements[a].includes("@")){
+					                    	var index = extraElements[a].lastIndexOf("@");
+					                    	if(index > 0){
+					                    	    // Get the number after @
+					                    	    var n = getNumOfDigits(extraElements[a], index+1);
+					                    				
+						                        var key = extraElements[a].substring(0, index+n+1); //include @x in key also by n+2 since x can be 1,12, etc
+						                    	console.log("key: " + key);
+						                    	checkData.push(key);
+					                    	}
+			                    		}
+			                    	}
+		                    		var unique = checkData.filter(onlyUnique);
+		                    		//if no layout order info, keep the process as before
+		                    		if(!dataOrderInfo){
+			                    		for(i =0; i < unique.length; i++){
+			                    			//remove @x and let addNewChoice add @1 or @2...
+			                    			//var newKey = unique[i].substring(0, unique[i].length-2);
+			                    			var index = unique[i].lastIndexOf("@");
+			                    			var newKey = unique[i].substring(0, index);
+			                    			console.log("newKey: " + newKey);	
+			                    			$scope.addNewChoice(newKey);
+			                    		}
+		            		    	}else{
+
+				              	    		for (i = 0; i < $scope.labelManyKeys.length; i++) {
+				              	    			//console.log("dataOrderInfo["+i+"]"+  dataOrderInfo[i]);
+				              	    		    var label = $scope.labelManyKeys[i];
+				              	    				// first add parent/label level
+				             	 	    			for (k = 0; k < unique.length; k++){
+						                    			var index = unique[k].lastIndexOf("@");
+						                    			var newKey = unique[k].substring(0, index);
+		 		             	 	    			    if(label == newKey){
+	                                                        //Check this label has bee created or not
+		 		             	 	    			    	if(!document.getElementById(unique[k])){
+		 		             	 	    			    		$scope.addNewChoice(newKey);
+		 		             	 	    			    	}
+		 		             	 	    			    	unique[k] = "*processed*";
+				             	 	    					break;
+		 		             	 	    			    }
+				             	 	    			}				             	 	    			
+				              	    		}
+				              	    		
+				              	    		//---reset to default
+				              	    		dataOrderInfo = [];
+				              	    		$scope.labelManyKeys = [];
+				              	    		
+		             	 	    			//---process none labels
+					              	    	for (j = 0; j < unique.length; j++){
+					              	    		if(unique[j] != "*processed*"){
+					              	    			// if not created yet
+					              	    			if(!document.getElementById(unique[j])){
+						                    			var index = unique[j].lastIndexOf("@");
+						                    			var newKey = unique[j].substring(0, index);
+			 		             	 	    		    $scope.addNewChoice(newKey);
+					              	    			}
+					              	    		}
+					              	    	}
+			              	    		}
+		            		    }
 	                    	}
-	                    }
-                        //After initially create the edit template, reset it to false.
-	                    $scope.isInitEditTemplate = false;
+	                    	
 	                    if($scope.temp.policy.editPolicy){
-	                    	//reset it to false since the template has been created
-	                    	$scope.temp.policy.editPolicy = false;
 	                    	//clean all the events of addNewChoice
 	                    	$scope.$on('$destroy', addNewChoice);
 	                    }
-	                    
                     }
                     var ele = angular.element(document.getElementById("DynamicTemplate"));
             		$compile(ele.contents())($scope);
                     $scope.$apply();
+                    
                 },
                 error : function(data){
                     alert("Error While Retriving the Template Layout Pattren.");
                 }
             });
+            
+            
+
         }
     };
     
@@ -538,9 +625,16 @@
 	        return Object.prototype.toString.call(arrayTest) === '[object Array]';
 	    }
 	    var lableList = [];
-		function deconstructJSON(dataTest, level , name) {
-			var array = false;
-			var label = level;
+	    
+	    $scope.layOutElementList = [];
+	    $scope.layOutOnlyLableList = [];
+	    
+	    var elementOrderNum = 0;
+	    
+		function deconstructJSON(layOutData, level , name) {
+
+			 var array = false;
+			 var label = level;
 			 var stringValue = "java.lang.String";
 			 var string = "string";
 			 var intValue = "int";
@@ -548,18 +642,33 @@
 			 var double = "double";
 			 var boolean = "boolean";
 			 var baseLevel = level;
+			 var list = "list";
+			 var String = "String";
+			 
+			 var attributekey = "";
 			 
 			if (name.length > 1){
 				label = label + name + '.';
 			}
 			
-		    for (key in dataTest) {
-		    	array = isArray(dataTest[key]);
-		    	console.log(key , dataTest[key]);
+		    for (key in layOutData) {
+		    	array = isArray(layOutData[key]);
+		    	console.log("key: " + key , "value: " + layOutData[key]);
 	    	
-		    	if (!!dataTest[key] && typeof(dataTest[key])=="object") {
+		    	if (!!layOutData[key] && typeof(layOutData[key])=="object") {
+		    		
 		    		if (array==false && key!=="0"){
-		    			$scope.labelLayout(label, key, array ); 			
+		    			
+		    			if($scope.dataOrderInfo){
+		    			    var labelObject = {"label" : key, "level" : label, "array" : array};
+		    			    //save it to the list
+		    			    $scope.layOutOnlyLableList.push(labelObject);
+		    			    
+		    			}else {
+		    				//call label layout
+		    				$scope.labelLayout(label, key, array );
+		    			}
+		    			
 		    		}
 		    		
 		    		if (array == true && key!=0){
@@ -571,20 +680,31 @@
 		    		}
 		    		if ( key==="0"){
 		    			var newKey = lableList.pop();
-		    			$scope.labelLayout(baseLevel, newKey, array );
+		    			
+		    			if($scope.dataOrderInfo){
+		    				
+			    			var labelObject = {"label" : newKey, "level" : baseLevel, "array" : array};
+			    			//save it to the list
+			    			$scope.layOutOnlyLableList.push(labelObject);
+			    			
+		    			}else {
+		    				//call label layout 
+		    			    $scope.labelLayout(baseLevel, newKey, array );
+		    			}
+		    			
 		    			if (array){
 		    				label = baseLevel + newKey + '@0.';
 		    			} else {
 		    				label = baseLevel + newKey + '.';
 		    			}
 		    		}
-		        	deconstructJSON(dataTest[key] , label, key);
+		        	deconstructJSON(layOutData[key] , label, key);
 		        } else {
 		        	var attirbuteLabel = label;
 		        	var defaultValue='';
 		        	var isRequired = false;
-		        	if (dataTest[key].includes('defaultValue-')){
-		        		defaultValue = dataTest[key].split('defaultValue-')[1];
+		        	if (layOutData[key].includes('defaultValue-')){
+		        		defaultValue = layOutData[key].split('defaultValue-')[1];
 		        	}
 
 		        	if (key==="0"){
@@ -595,7 +715,7 @@
 		        		attributekey = key.split();
 		        	}
 		        	
-		        	if (dataTest[key].includes('required-true')){
+		        	if (layOutData[key].includes('required-true')){
 		        		isRequired = true;
 		        	}
 		    		
@@ -620,45 +740,176 @@
 		    			}		    			
 		    		}
 		    		
-		        	switch (dataTest[key].split(splitcolon)[0]){
+		    		var elementObject = {};
+		        	switch (layOutData[key].split(splitcolon)[0]){
+		        	
 		        		case stringValue:
-			        		$scope.attributeBox(attributekey, array, attirbuteLabel, defaultValue, isRequired, "text");
-		        			break;
 		        		case string:
-			        		$scope.attributeBox(attributekey, array, attirbuteLabel, defaultValue, isRequired, "text");
+		        			if($scope.dataOrderInfo){		        				
+				        		elementOrderNum++;
+				        		elementObject = {"id": elementOrderNum,"attributekey" : attributekey, "array": array, "attirbuteLabel" : attirbuteLabel, "defaultValue": defaultValue, "isRequired": isRequired, "type":"text"};
+				        		$scope.layOutElementList.push(elementObject);
+		        			}else{
+		        				$scope.attributeBox(attributekey, array, attirbuteLabel, defaultValue, isRequired, "text");
+		        			}
 		        			break;		        			
 		        		case intValue: 
-		        			$scope.attributeBox(attributekey, array, attirbuteLabel, defaultValue, isRequired, "number");
-		        			break;
 		        		case integerValue: 
-		        			$scope.attributeBox(attributekey, array, attirbuteLabel, defaultValue, isRequired, "number");
+		        			if($scope.dataOrderInfo){
+			        			elementOrderNum++;
+				        		elementObject = {"id": elementOrderNum,"attributekey" : attributekey, "array": array, "attirbuteLabel" : attirbuteLabel, "defaultValue": defaultValue,"isRequired": isRequired, "type":"number"};
+				        		$scope.layOutElementList.push(elementObject);
+		        			}else{
+		        				$scope.attributeBox(attributekey, array, attirbuteLabel, defaultValue, isRequired, "number");
+		        			}
 		        			break;		        			
 		        		case double:
-		        			$scope.attributeBox(attributekey, array, attirbuteLabel, defaultValue, isRequired, "double");
+		        			if($scope.dataOrderInfo){
+			        			elementOrderNum++;
+				        		elementObject = {"id": elementOrderNum,"attributekey" : attributekey, "array": array, "attirbuteLabel" : attirbuteLabel, "defaultValue": defaultValue,"isRequired": isRequired, "type":"double"};
+				        		$scope.layOutElementList.push(elementObject);		        				
+		        			}else{
+		        				$scope.attributeBox(attributekey, array, attirbuteLabel, defaultValue, isRequired, "double");
+		        			}
 		        			break;
 		        		case boolean:
-		        			$scope.dropBoxLayout(attirbuteLabel, attributekey, array, dataTest[key], getBooleanList());
+		        			if($scope.dataOrderInfo){
+			        			elementOrderNum++;
+				        		elementObject = {"id": elementOrderNum,"attributekey" : attributekey, "array": array, "attirbuteLabel" : attirbuteLabel, "defaultValue": layOutData[key], "list": getBooleanList, "isRequired": isRequired, "type":"dropBox"};
+				        		$scope.layOutElementList.push(elementObject);
+		        			}else{
+		        				$scope.dropBoxLayout(attirbuteLabel, attributekey, array, layOutData[key], getBooleanList());
+		        			}
 		        			break;
 		        		default:
-		        			if (dataTest[key].includes('dictionary-')){
-		        				var list = getDictionary(dataTest[key].split('dictionary-')[1]);
+		        			if (layOutData[key].includes('dictionary-')){
+		        				var list = getDictionary(layOutData[key].split('dictionary-')[1]);
 		        			}else{
 		        				//--- get dropdown values from enumValues
-		        				var list = getList(dataTest[key]);
+		        				var list = getList(layOutData[key]);
 		        			}
 		        			if (list.length===0){ //not dropdown element
-		        				$scope.attributeBox(attributekey, array, attirbuteLabel, defaultValue, isRequired, "text");
+		        				if($scope.dataOrderInfo){
+		        					elementOrderNum++;
+					        		elementObject = {"id": elementOrderNum,"attributekey" : attributekey, "array": array, "attirbuteLabel" : attirbuteLabel, "defaultValue": defaultValue,"isRequired": isRequired, "type":"text"};
+					        		$scope.layOutElementList.push(elementObject);
+		        					
+		        				}else{
+		        					$scope.attributeBox(attributekey, array, attirbuteLabel, defaultValue, isRequired, "text");
+		        				}		        				
 		        			}else{
-		        				$scope.dropBoxLayout(attirbuteLabel, attributekey, array, dataTest[key], list, isRequired);
+		        				if($scope.dataOrderInfo){
+			        				elementOrderNum++;
+					        		elementObject = {"id": elementOrderNum, "attributekey" : attributekey, "array": array, "attirbuteLabel" : attirbuteLabel, "defaultValue": layOutData[key],"isRequired": isRequired, "list":list, "type":"dropBox"};
+					        		$scope.layOutElementList.push(elementObject);		        					
+		        				}else{
+		        					$scope.dropBoxLayout(attirbuteLabel, attributekey, array, layOutData[key], list, isRequired);
+		        				}
 		        			}
 		        			break;
 		        	}
 		        }
 		    }
 		}  
+		
+		
+	    $scope.validContionalRequired = function(parentId) {
+	        console.log("ng-blur event: parentId : " + parentId);
+	        var c = document.getElementById(parentId).children;
+	        var i;
+	        var hasValue = false;
+	        for (i = 0; i < c.length; i++) {
+	        	if(c[i].getAttribute("data-conditional")){
+	        	    console.log(c[i].getAttribute("data-conditional"));
+	        	    console.log(c[i].value);
+	        	    if(c[i].value != null && c[i].value.trim() != ""){
+	        	    	hasValue = true;
+	        	    }
+	        	}
+	        }
 
-	    $scope.jsonLayout = function(dataTest){
-	    	deconstructJSON(dataTest , "", "");
+		    for (i = 0; i < c.length; i++) {
+		        if(c[i].getAttribute("data-conditional")){
+		        	if(hasValue){
+		        	    c[i].setAttribute("required", true);
+		        	}else{
+		        		c[i].removeAttribute("required");
+		        	}
+		        }
+		    }        	
+	     }
+				
+	    $scope.jsonLayout = function(layOutData){
+	    	
+ 	    	   deconstructJSON(layOutData , "", "");
+ 	    	   
+ 	    	   var orderValue = $scope.dataOrderInfo;
+ 	    	   var layOutElementList = $scope.layOutElementList;
+ 	    	   var labelList = $scope.layOutOnlyLableList;
+ 	    	    
+ 	    	   //reset to default
+ 	    	   elementOrderNum = 0;
+ 	    	   $scope.layOutElementList = [];
+ 	    	   $scope.layOutOnlyLableList = [];
+ 	    	   
+ 	    	   // Only layout in order if order info provided
+ 	    	   if(orderValue){
+ 	    		   
+ 	    		   if(orderValue.includes("[")){
+ 	    			  orderValue = orderValue.replace("[", "") ;
+ 	    			  orderValue = orderValue.replace("]", "") ;
+ 	    		   }
+ 	    		   
+ 	    		   orderValue = orderValue.split(',') ;
+ 	    		   
+ 	    		   for (i = 0; i < orderValue.length; i++) {
+ 	    			   console.log("orderValue["+i+"]"+  orderValue[i]);
+ 	    			   var key = orderValue[i].trim();
+ 	    			 
+ 	    			    //--- Create labels first {"label" : newKey, "level" : baseLevel, "array" : array};
+ 	    			   if(labelList){
+	 	    			   for (k = 0; k < labelList.length; k++){
+	 	    				   
+	 	    				  var label = labelList[k].label.toString().trim();
+	 	    				  var level = labelList[k].level.toString().trim();
+	 	    				  var array = labelList[k].array;
+	 	    				  
+	 	    				  if(key == label){	 	    					  
+	 	    					 $scope.labelLayout(level, label, array);
+		 	 	  	    		 //in case to have duplicate label names
+	 	    					 labelList[k].label = "*processed*";
+	 	    					 break;
+	 	    				  }
+	 	    			   }
+ 	    			   }
+ 	    			   //--- then layout each element based on its order defined in YAML file
+	 	  	    	   for (j = 0; j < layOutElementList.length; j++) { 
+	 	  	    		   
+	 	  	    		   var attributekey = layOutElementList[j].attributekey.toString().trim();	 	  	    		   
+	 	  	    		
+	 	  	    		   if(key == attributekey){ 	
+
+		 	  	    		   var attirbuteLabel = layOutElementList[j].attirbuteLabel.toString().trim();
+		 	  	    		   var defaultValue = layOutElementList[j].defaultValue.toString().trim();
+		 	  	    		   var isRequired = layOutElementList[j].isRequired;
+	 	 	  	    		   
+	 	 	  	    		   console.log("layOutElementList[" +j+ "]: id:" + layOutElementList[j].id + ", attributekey:"+ layOutElementList[j].attributekey + ", attirbuteLabel:" + layOutElementList[j].attirbuteLabel);
+	 		        		  
+	 	 	  	    		   if (layOutElementList[j].type == "dropBox"){ 
+	 		        				$scope.dropBoxLayout(attirbuteLabel, attributekey, layOutElementList[j].array, defaultValue, layOutElementList[j].list, isRequired);
+	                                
+			        		   }else{
+			        			    $scope.attributeBox(attributekey, layOutElementList[j].array, attirbuteLabel, defaultValue, isRequired, layOutElementList[j].type);	
+	
+			        		   }
+	 	 	  	    		   
+	 	 	  	    		   //in case to have duplicate attribute names
+	 	 	  	    		   layOutElementList[j].attributekey = "*processed*";
+	 		        		   break;
+	 	  	    		   }
+	 	  	    	   }
+ 	    		   }
+ 	    	   }
 	    }
 	    
 	    
@@ -674,7 +925,7 @@
 			isRequired = true;  //set required as true for matching element
 		}else {
 			if(isRequired){
-				requiredLabName = attibuteKey + " *";
+				requiredLabName = attibuteKey + " * ";
 				labeltext = document.createTextNode(requiredLabName);
 			}else{
 			    labeltext = document.createTextNode(attibuteKey);	
@@ -706,6 +957,7 @@
 		textField.setAttribute("style" , "width:300px;");
 		textField.setAttribute("ng-disabled" , "temp.policy.readOnly");
 		var checkKey;
+		var id = "";
 		if(attributeManyKey){
 			checkKey = labelValue + attibuteKey+'@0';
 			textField.setAttribute("id" , ''+labelValue + attibuteKey+'@0'+''); 
@@ -727,8 +979,8 @@
 			document.getElementById(divID).appendChild(addButton); 
 			document.getElementById(divID).appendChild(removeButton); 
 			document.getElementById(divID).appendChild(label); 
-			var id = "div."+labelValue+attibuteKey;
-			var divTag = document.createElement("div");
+			id = "div."+labelValue+attibuteKey;
+			//var divTag = document.createElement("div");
 			divTag.setAttribute("id", id); 
 			document.getElementById(divID).appendChild(divTag);
 			textField.className += ' first_child';	
@@ -741,15 +993,33 @@
 		}else{
 			checkKey = labelValue + attibuteKey;
 			textField.setAttribute("id" , ''+labelValue +attibuteKey+'');
-			if(requiredLabName.includes("*")){
-				textField.setAttribute("required", "true");
+			if(document.getElementById(divID).hasAttribute('required') || !document.getElementById(divID).hasAttribute('data-conditional')){
+				if(requiredLabName.includes("*") || isRequired){
+					textField.setAttribute("required", "true");
+				}
+			}else if (document.getElementById(divID).hasAttribute('data-conditional')){
+				if(requiredLabName.includes("*")){					
+					var requiredNode = document.createElement('span');
+					requiredNode.setAttribute("class", "mstooltip");
+					requiredNode.textContent = "?";
+					label.appendChild(requiredNode);
+					
+					var requiredNodeToolTip = document.createElement('span');
+					requiredNodeToolTip.setAttribute("class", "tooltiptext");
+					requiredNodeToolTip.textContent = "Conditional Required";
+					requiredNode.appendChild(requiredNodeToolTip);
+					
+					textField.setAttribute("data-conditional", divID);
+					textField.setAttribute("ng-blur", "validContionalRequired('"+divID+"')");
+				}
 			}
+            
 			document.getElementById(divID).appendChild(label);  
 			document.getElementById(divID).appendChild(textField);  
 			document.getElementById(divID).appendChild(br); 
 
 		}
-		
+
 		if(divID.includes("@0") && divID.includes("div.")){
 			var firstChild_Id = divID.split("@0")[0];
 			var firstChild_element = document.getElementById(firstChild_Id);
@@ -767,7 +1037,7 @@
 					defaultValue = "";
 				}				
 			}
-			if(defaultValue != "undefined" && defaultValue != undefined){
+			if(defaultValue != "undefined" && defaultValue != undefined && defaultValue != "null"){
 		    	document.getElementById(checkKey).value = defaultValue;
 			}
 		}
@@ -788,6 +1058,7 @@
 		plainAttributeKeys.push(labelValue + attibuteKey+'*'+attributeManyKey);	
     };
   
+    $scope.labelManyKeys = [];
     $scope.labelLayout = function(labelValue, lableName, labelManyKey ){
 		var label = document.createElement("Label")
 		var divID = labelValue;
@@ -803,11 +1074,25 @@
 			var divID = 'div.'+ labelValue.substring(0, labelValue.length-1);
 		}
 		
-		var labeltext = document.createTextNode(lableName);
+		var subAttributes = $scope.dcaeModelData.sub_attributes;
+	    var jsonObject = JSON.parse(subAttributes);	
+	    var lablInfo = findVal(jsonObject, lableName);
+		console.log("findValue : " + lableName +": "+ lablInfo);
+		var star = "";
+		var required = null;
+		if(lablInfo){
+			if(lablInfo.includes("required-true")){
+				star = " *";
+				required = true;
+			}else if (lablInfo.includes("required-false")){
+				required = false
+			}
+		}
+		
+		var labeltext = document.createTextNode(lableName + star);
 	
 		label.appendChild(labeltext);
-		
-		var subAttributes = $scope.dcaeModelData.sub_attributes;
+
 
 		if(labelManyKey){
 			var addButton = document.createElement("BUTTON");
@@ -835,117 +1120,147 @@
 			
 			divTag.className += ' children_group'; //here is div with a group of children.
 			
+			if(required){
+			   divTag.setAttribute("required", required);  
+			}else if(required == false){
+			   divTag.setAttribute("data-conditional", "yes");  
+			}
+			
 			document.getElementById(id).appendChild(divTag);
+			
+			$scope.labelManyKeys.push(lableName);
+			
 		}else{
 			var divTag = document.createElement("div");
 			divTag.setAttribute("id", "div."+labelValue+lableName);
 			divTag.className += ' children_group'; //here is div with a group of children.
+			if(required){
+			    divTag.setAttribute("required", required);  
+			}else if(required == false){
+				divTag.setAttribute("data-conditional", "yes");  
+			}  
 			document.getElementById(divID).appendChild(label);  
 			document.getElementById(divID).appendChild(divTag);			
 		}
     };
 
     $scope.dropBoxLayout = function(labelLevel, attributeName, many , refValue, listemunerateValues, isRequired){
-		var br = document.createElement("BR");
-
-		if (labelLevel.length  < 1){
-			var divID = "DynamicTemplate";
-		} else if (labelLevel.endsWith('.')){
-			var divID = 'div.'+ labelLevel.substring(0, labelLevel.length-1);
-		}	
-
-
-	var label = document.createElement("Label")
-	
-	var refAttributes = $scope.dcaeModelData.ref_attributes;
-	if(isRequired != true && refAttributes){ //check refAttributes also		
-	   		var refAttributesList = refAttributes.split(splitComma);
-	   		for (k = 0; k < refAttributesList.length; k++){
-	       		var refAttribute = refAttributesList[k].split(splitEqual);	       		
-	       		if (attributeName == refAttribute[0].trim() && refAttribute[1].includes("required-true")){
-	       			isRequired = true;
-	       		}
-	   		}
-	}
-	
-	if (matching.includes(attributeName)){
-		var labeltext = document.createTextNode(attributeName + "*!");
-		label.appendChild(labeltext);
-		isRequired = true;  //set required as true for matching element
-	}else {
-		var labeltext = document.createTextNode(attributeName);		
-		if(isRequired){
-			requiredLabName = attributeName+ " *";
-			labeltext = document.createTextNode(requiredLabName);
-		}else{
-		    labeltext = document.createTextNode(attributeName);	
-		}
-	
-	    label.appendChild(labeltext);		
-	}
-	label.appendChild(labeltext);
-
-	var listField = document.createElement("SELECT");
-	listField.setAttribute("class" , "form-control");
-	listField.setAttribute("style" , "width:300px;");
-	listField.setAttribute("ng-disabled" , "temp.policy.readOnly");
-	
-	if(isRequired){
-	   listField.setAttribute("required", true);
-	}
-	if( many != true || isRequired != true){ // add an empty option for not required or not multiple select element
-		var optionFirst = document.createElement('option');
-		optionFirst.setAttribute('value', "");
-		listField.appendChild(optionFirst);	
-	}
-	
-	for (i=0; i < listemunerateValues.length; i += 1) {
+			var br = document.createElement("BR");
 		
-		if(listemunerateValues[i].includes("equal-sign")){
-			listemunerateValues[i] = listemunerateValues[i].replace('equal-sign','=');
-		}		
+			if (labelLevel.length  < 1){
+					var divID = "DynamicTemplate";
+			} else if (labelLevel.endsWith('.')){
+					var divID = 'div.'+ labelLevel.substring(0, labelLevel.length-1);
+			}	
 		
-	    option = document.createElement('option');
-	    option.setAttribute('value', listemunerateValues[i]);
-	    option.appendChild(document.createTextNode(listemunerateValues[i]));
-	    option.setAttribute('value', listemunerateValues[i]);
-	    listField.appendChild(option);
-	}
-	listField.setAttribute("id" , ''+ labelLevel + attributeName + '');
-	
-	enumKeyList.push(attributeName);
-	
-	document.getElementById(divID).appendChild(label);  
-	document.getElementById(divID).appendChild(br);	
+		
+			var label = document.createElement("Label")
 			
-	if(many == true){
-		document.getElementById(divID).appendChild(listField).multiple = true;
-		plainAttributeKeys.push(labelLevel + attributeName+'*'+true);
-	}else {
-		document.getElementById(divID).appendChild(listField).multiple = false;
-		plainAttributeKeys.push(labelLevel + attributeName+'*'+false);
-	}
-
-	if($scope.temp.policy.ruleData != null){
-		if (many == true){
-			document.getElementById(labelLevel +attributeName).options[0].selected = false;
-			for (i=0; i < listemunerateValues.length; i += 1) {
-				var testValue = $scope.temp.policy.ruleData[labelLevel +attributeName+'@' + i];
-				if (testValue === undefined){
-					testValue = $scope.temp.policy.ruleData[labelLevel +attributeName];
-					}
-				var location = listemunerateValues.indexOf(testValue);
-				if (location!=-1){
-					document.getElementById(labelLevel +attributeName).options[location].selected = true;
-					}
-				}			
-			}else {
-				    if($scope.temp.policy.ruleData[labelLevel + attributeName] != undefined && $scope.temp.policy.ruleData[labelLevel + attributeName] != "undefined"){
-	                    document.getElementById(labelLevel + attributeName).value = $scope.temp.policy.ruleData[labelLevel + attributeName];	
-				    }
+			var refAttributes = $scope.dcaeModelData.ref_attributes;
+			if(isRequired != true && refAttributes){ //check refAttributes also		
+			   		var refAttributesList = refAttributes.split(splitComma);
+			   		for (k = 0; k < refAttributesList.length; k++){
+			       		var refAttribute = refAttributesList[k].split(splitEqual);	       		
+			       		if (attributeName == refAttribute[0].trim() && refAttribute[1].includes("required-true")){
+			       			isRequired = true;
+			       		}
+			   		}
 			}
-		}
-    };
+			
+			if (matching.includes(attributeName)){
+				var labeltext = document.createTextNode(attributeName + "*!");
+				label.appendChild(labeltext);
+				isRequired = true;  //set required as true for matching element
+			}else {
+				var labeltext = document.createTextNode(attributeName);		
+				if(isRequired){
+				    var requiredLabName = attributeName+ " * ";
+					labeltext = document.createTextNode(requiredLabName);
+				}else{
+				    labeltext = document.createTextNode(attributeName);	
+				}
+			
+			    label.appendChild(labeltext);		
+			}
+			label.appendChild(labeltext);
+			// if this field is required, but its parent is not required
+			if(isRequired && document.getElementById(divID).hasAttribute('data-conditional')){
+			   	var requiredNode = document.createElement('span');
+				requiredNode.setAttribute("class", "mstooltip");
+				requiredNode.textContent = "?";
+				label.appendChild(requiredNode);
+					
+				var requiredNodeToolTip = document.createElement('span');
+				requiredNodeToolTip.setAttribute("class", "tooltiptext");
+				requiredNodeToolTip.textContent = "Conditional Required";
+				requiredNode.appendChild(requiredNodeToolTip);
+
+			}
+		
+			var listField = document.createElement("SELECT");
+			listField.setAttribute("class" , "form-control");
+			listField.setAttribute("style" , "width:300px;");
+			listField.setAttribute("ng-disabled" , "temp.policy.readOnly");
+			
+			if(isRequired){
+			    if(document.getElementById(divID).hasAttribute('data-conditional')){
+			    	listField.setAttribute("data-conditional", divID);
+			    	listField.setAttribute("ng-blur", "validContionalRequired('"+divID+"')");
+			    }else{
+					listField.setAttribute("required", true);
+			    }
+			}
+			if( many != true || isRequired != true){ // add an empty option for not required or not multiple select element
+				var optionFirst = document.createElement('option');
+				optionFirst.setAttribute('value', "");
+				listField.appendChild(optionFirst);	
+			}
+			
+			for (i=0; i < listemunerateValues.length; i += 1) {
+				if(listemunerateValues[i].includes("equal-sign")){
+					listemunerateValues[i] = listemunerateValues[i].replace('equal-sign','=');
+				}
+			    option = document.createElement('option');
+			    option.setAttribute('value', listemunerateValues[i]);
+			    option.appendChild(document.createTextNode(listemunerateValues[i]));
+			    option.setAttribute('value', listemunerateValues[i]);
+			    listField.appendChild(option);
+			}
+			listField.setAttribute("id" , ''+ labelLevel + attributeName + '');
+			
+			enumKeyList.push(attributeName);
+			
+			document.getElementById(divID).appendChild(label);  
+			document.getElementById(divID).appendChild(br);	
+					
+			if(many == true){
+				document.getElementById(divID).appendChild(listField).multiple = true;
+				plainAttributeKeys.push(labelLevel + attributeName+'*'+true);
+			}else {
+				document.getElementById(divID).appendChild(listField).multiple = false;
+				plainAttributeKeys.push(labelLevel + attributeName+'*'+false);
+			}
+		
+			if($scope.temp.policy.ruleData != null){
+				if (many == true){
+					document.getElementById(labelLevel +attributeName).options[0].selected = false;
+					for (i=0; i < listemunerateValues.length; i += 1) {
+						var testValue = $scope.temp.policy.ruleData[labelLevel +attributeName+'@' + i];
+						if (testValue === undefined){
+							testValue = $scope.temp.policy.ruleData[labelLevel +attributeName];
+							}
+						var location = listemunerateValues.indexOf(testValue);
+						if (location!=-1){
+							document.getElementById(labelLevel +attributeName).options[location].selected = true;
+							}
+						}			
+					}else {
+						    if($scope.temp.policy.ruleData[labelLevel + attributeName] != undefined && $scope.temp.policy.ruleData[labelLevel + attributeName] != "undefined"){
+			                    document.getElementById(labelLevel + attributeName).value = $scope.temp.policy.ruleData[labelLevel + attributeName];	
+						    }
+					}
+				}
+		    };
     
     function onlyUnique(value, index, self) { 
         return self.indexOf(value) === index;
diff --git a/POLICY-SDK-APP/src/main/webapp/app/policyApp/policy-models/Editor/PolicyTemplateController/OptimizationPolicyController.js b/POLICY-SDK-APP/src/main/webapp/app/policyApp/policy-models/Editor/PolicyTemplateController/OptimizationPolicyController.js
new file mode 100644
index 0000000..e499c9f
--- /dev/null
+++ b/POLICY-SDK-APP/src/main/webapp/app/policyApp/policy-models/Editor/PolicyTemplateController/OptimizationPolicyController.js
@@ -0,0 +1,1389 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP Policy Engine
+ * ================================================================================
+ * Copyright (C) 2018 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=========================================================
+ */
+angular.module('abs').controller('optimizationController', ['$scope', '$window', '$compile', 'PolicyAppService', 'policyNavigator', 'modalService', '$modal', 'Notification', function ($scope, $window, $compile, PolicyAppService, PolicyNavigator, modalService, $modal, Notification) {
+    $("#dialog").hide();
+    
+    $scope.policyNavigator;
+    $scope.isCheck = false;
+    $scope.savebutton = true;
+    $scope.refreshCheck = false;
+    
+    if(!$scope.temp.policy.editPolicy  && !$scope.temp.policy.readOnly){
+    	$scope.temp.policy = {
+    			policyType : "Config",
+    			configPolicyType : "Optimization"
+    	}
+    };
+    
+    $scope.refresh = function(){
+    	if($scope.refreshCheck){
+    		$scope.policyNavigator.refresh();
+    	}
+    	$scope.modal('createNewPolicy', true);
+    	$scope.temp.policy = "";
+    };
+    
+    $scope.modal = function(id, hide) {
+        return $('#' + id).modal(hide ? 'hide' : 'show');
+    };
+    
+    $('#ttlDate').datepicker({
+    	dateFormat: 'dd/mm/yy',
+    	changeMonth: true,
+    	changeYear: true,
+    	onSelect: function(date) {
+    		angular.element($('#ttlDate')).triggerHandler('input');
+    	}
+    });
+    
+	if ($scope.temp.policy.editPolicy != undefined|| $scope.temp.policy.readOnly  != undefined){
+		if ($scope.temp.policy.configName == undefined){
+			$scope.isCheck = false;
+		}else{
+			$scope.isCheck = true;
+		}
+	}else {
+		$scope.isCheck = false;
+	}
+		
+	PolicyAppService.getData('getDictionary/get_OnapNameDataByName').then(function (data) {
+		var j = data;
+		$scope.data = JSON.parse(j.data);
+		console.log($scope.data);
+		$scope.onapNameDictionaryDatas = JSON.parse($scope.data.onapNameDictionaryDatas);
+		console.log($scope.onapNameDictionaryDatas);
+	}, function (error) {
+		console.log("failed");
+	});
+
+	PolicyAppService.getData('get_PriorityValues').then(function (data) {
+		var j = data;
+		$scope.data = JSON.parse(j.data);
+		console.log($scope.data);
+		$scope.priorityDatas = JSON.parse($scope.data.priorityDatas);
+		console.log($scope.priorityDatas);
+	}, function (error) {
+		console.log("failed");
+	});
+
+	PolicyAppService.getData('getDictionary/get_OptimizationModelsDataByName').then(function (data) {
+		var j = data;
+		$scope.data = JSON.parse(j.data);
+		console.log($scope.data);
+		var inputModelList = JSON.parse($scope.data.optimizationModelsDictionaryDatas);
+		var unique = {};
+		var uniqueList = [];
+		for(var i = 0; i < inputModelList.length; i++){
+			if(typeof unique[inputModelList[i]] == "undefined"){
+				unique[inputModelList[i]] = "";
+				uniqueList.push(inputModelList[i]);
+			}
+		}
+		$scope.optimizationModelsDictionaryDatas = uniqueList;
+		console.log($scope.optimizationModelsDictionaryDatas);
+	}, function (error) {
+		console.log("failed");
+	});
+
+	PolicyAppService.getData('getDictionary/get_RiskTypeDataByName').then(function (data) {
+		var j = data;
+		$scope.data = JSON.parse(j.data);
+		console.log($scope.data);
+		$scope.riskTypeDictionaryDatas = JSON.parse($scope.data.riskTypeDictionaryDatas);
+		console.log($scope.riskTypeDictionaryDatas);
+	}, function (error) {
+		console.log("failed");
+	});
+
+	 $scope.choices = [];
+	 $scope.attributeDatas = [{"attributes" : $scope.choices}];
+	 $scope.isInitEditTemplate = true;  //just initially create the edit template, didn't click add button yet.
+	 $scope.addNewChoice = function(value) {
+		 console.log("input value : " + value);
+		 if(value != undefined){
+			if (value.startsWith('div.')){
+				value = value.replace('div.','');
+			}
+			var parentElement = document.getElementById("div."+value);
+			var div = document.getElementById(value+"@0");
+			if(div != null){
+				var clone = div.cloneNode(true); 
+				var addElement = parentElement.childElementCount;
+				clone.id = ''+value+'@'+addElement;
+				clone.value = '';
+				if($scope.temp.policy.editPolicy || $scope.temp.policy.readOnly){ //if it's view or edit
+					if($scope.temp.policy.ruleData[clone.id] || ($scope.temp.policy.editPolicy && !$scope.isInitEditTemplate)){  // Only append child if its value found in ruleData or edit mode
+						if($scope.temp.policy.ruleData[clone.id]){
+						    clone.value = $scope.temp.policy.ruleData[clone.id];
+						}
+						if(!clone.className.includes("child_single")){   
+							clone.className += ' child_single'; //single element clone
+						}
+						document.getElementById("div."+value).appendChild(clone);
+						plainAttributeKeys.push(''+value+'@'+addElement);
+					}
+				}else{ //not view or edit
+					if(!clone.className.includes("child_single")){   
+						clone.className += ' child_single'; //single element clone
+					}
+					document.getElementById("div."+value).appendChild(clone);
+					plainAttributeKeys.push(''+value+'@'+addElement);
+				}
+			}else{
+				div = document.getElementById("div."+value+"@0");
+				
+				if(div){
+			    	div.className += ' children_group'; //div with a group of children.
+				}				
+				var childElement = parentElement.firstElementChild;
+				var countParent = parentElement.childElementCount;
+				var childElementString = childElement.innerHTML;
+				var find = value+"@0";
+				var re = new RegExp(find, 'g');
+				childElementString = childElementString.replace(re,value+'@' + countParent);
+				var clone = childElement.cloneNode(true);
+				for (var ii = 0; ii < parentElement.childNodes.length; ii++){
+		            var childId = parentElement.childNodes[ii].id;
+		            if(ii = parentElement.childNodes.length){
+		            	var childnewId = childId.slice(0, -1);
+		            	var count = childId.slice(-1);
+		            }
+		        }
+				var countvalue = parseInt(count) + 1;
+				clone.id = childnewId+countvalue;
+				clone.value = '';
+				clone.innerHTML=childElementString;
+				document.getElementById("div."+value).appendChild(clone);
+				var selects = clone.getElementsByTagName("select");
+				var inputs = clone.getElementsByTagName("input");
+				var removeValues = [];
+				for(var i=0; i<inputs.length; i++){
+					if ($scope.temp.policy.ruleData!=undefined){
+						var checkValue = $scope.temp.policy.ruleData[inputs[i].id];
+						if (checkValue!=undefined && checkValue != "undefined"){
+							if($scope.temp.policy.ruleData != null){
+								var checkValue = $scope.temp.policy.ruleData[inputs[i].id];
+								document.getElementById(inputs[i].id).value = $scope.temp.policy.ruleData[inputs[i].id];
+								plainAttributeKeys.push(inputs[i].id);
+							}
+						} else {
+							plainAttributeKeys.push(inputs[i].id);
+						}
+					}else {
+						plainAttributeKeys.push(inputs[i].id);
+					}
+				}
+				
+				for(var i=0; i<selects.length; i++){
+					if ($scope.temp.policy.ruleData!=undefined){
+						var checkValue = $scope.temp.policy.ruleData[selects[i].id];
+						if (checkValue!=undefined && checkValue!="undefined"){
+							if($scope.temp.policy.ruleData != null){
+								var checkValue = $scope.temp.policy.ruleData[selects[i].id];
+								document.getElementById(selects[i].id).value = $scope.temp.policy.ruleData[selects[i].id];
+								plainAttributeKeys.push(selects[i].id);
+							}
+						} else {
+							plainAttributeKeys.push(selects[i].id);
+						}
+					}else {
+						plainAttributeKeys.push(selects[i].id);
+					}
+				}
+				
+				for (var k=0; k<removeValues.length; k++){
+					var elem = document.getElementById(removeValues[k]);
+					elem.parentNode.removeChild(elem);
+				}
+				var ele = angular.element(document.getElementById("div."+value));
+	    		$compile(ele.contents())($scope);
+	            $scope.$apply();
+			}
+		 }
+	 };
+	 
+	 function findVal(object, key) {
+		    var value;
+		    Object.keys(object).some(function(k) {
+		        if (k === key) {
+		            value = object[k];
+		            return true;
+		        }
+		        if (object[k] && typeof object[k] === 'object') {
+		            value = findVal(object[k], key);
+		            return value !== undefined;
+		        }
+		    });
+		    return value;
+	}
+	 
+	 $scope.removeChoice = function(value) {
+		 console.log(value);
+		 if(value != undefined){
+			 var c = document.getElementById("div."+value).childElementCount;
+			 
+			 if(c == 1){
+				 Notification.error("The original one is not removable.");
+				 return;
+			 }	
+			 document.getElementById("div."+value).removeChild(document.getElementById("div."+value).lastChild);	 
+		 }
+	 };
+	 
+	 $scope.pullVersion = function(serviceName) {
+		 console.log(serviceName);
+		 if(serviceName != undefined){
+			 var uuu = "policyController/getModelServiceVersionData.htm";
+			 var postData={policyData: serviceName};
+			 $.ajax({
+				 type : 'POST',
+				 url : uuu,
+				 dataType: 'json',
+				 contentType: 'application/json',
+				 data: JSON.stringify(postData),
+				 success : function(data){
+					 $scope.$apply(function(){
+						 $scope.optimizationModelsDictionaryVersionDatas = data[0].optimizationModelVersionData;
+					 });
+				 },
+				 error : function(data){
+					 alert("Error While Retrieving the Template Layout Pattern.");
+				 }
+			 });		 
+		 }
+	 };
+    
+    var splitDash = '-';
+	var splitEqual = '=';
+	var splitComma = ',';
+	var splitcolon = ':';
+	var splitsemicolon = ";";
+	var splitEnum = "],";
+	var plainAttributeKeys = [];
+	var matching = [];
+	var enumKeyList = [];
+	var dictionaryList = [];
+	var dictionaryNameList = [];
+    $scope.addDataToFields = function(serviceName, version){
+        if(serviceName != null && version !=null){
+        	var service=serviceName+"-v"+version;
+        	var myNode = document.getElementById("DynamicTemplate");
+        	myNode.innerHTML = '';
+            var uuu = "policyController/getOptimizationTemplateData.htm";
+            var postData={policyData: service};
+            var dataOrderInfo = "";
+            
+            $.ajax({
+                type : 'POST',
+                url : uuu,
+                dataType: 'json',
+                contentType: 'application/json',
+                data: JSON.stringify(postData),
+                success : function(data){
+                    $scope.$apply(function(){
+                    	var plainAttributeKeys = [];
+                    	$scope.optimizationModelData = data[0].optimizationModelData;
+                    	$scope.optimizationJsonDate = data[0].jsonValue;
+                        $scope.dataOrderInfo = null;
+                    	$scope.dataOrderInfo = data[0].dataOrderInfo;
+                    	console.log("data[0].dataOrderInfo: " + data[0].dataOrderInfo);
+                    	console.log("$scope.dataOrderInfo: " + $scope.dataOrderInfo);	
+                    	if(data[0].allManyTrueKeys){
+	                    	console.log("$scope.allManyTrueKeys: " + $scope.allManyTrueKeys);
+                    	}
+                    	console.log("$scope.optimizationJsonDate: " + $scope.optimizationJsonDate);	
+                    	var attributes = $scope.optimizationModelData.attributes;
+                    	var refAttributes = $scope.optimizationModelData.ref_attributes;
+                    	var subAttributes = 	$scope.optimizationModelData.sub_attributes;   
+                    	console.log("attributes: " +attributes);                    	
+                    	console.log("subAttributes: " + subAttributes);	
+                    	console.log("refAttributes: " + refAttributes);	
+                    	
+                    	var headDefautlsData  = data[0].headDefautlsData;
+                    	if(headDefautlsData != null){
+	               			 $scope.temp.policy.onapName = headDefautlsData.onapName;
+	               			 $scope.temp.policy.guard = headDefautlsData.guard;
+	               			 $scope.temp.policy.riskType = headDefautlsData.riskType;
+	               			 $scope.temp.policy.riskLevel = headDefautlsData.riskLevel;
+	               			 $scope.temp.policy.priority = headDefautlsData.priority;
+	               			 
+                    	}else if(!$scope.temp.policy.editPolicy && !$scope.temp.policy.readOnly){
+	               			 $scope.temp.policy.onapName = "";
+	               			 $scope.temp.policy.guard = "";
+	               			 $scope.temp.policy.riskType = "";
+	               			 $scope.temp.policy.riskLevel = "";
+	               			 $scope.temp.policy.priority = "";
+                    	}
+                    	
+                       	var enumAttributes = $scope.optimizationModelData.enumValues;
+                       	var annotation = $scope.optimizationModelData.annotation;
+                       	var dictionary = $scope.microServiceAttributeDictionaryDatas;
+
+                       	if (annotation == null || annotation.length<1){
+                       		$scope.isCheck = true;
+                       	}else {
+                       		$scope.isCheck = false;
+                       		var annoationList = annotation.split(splitComma);
+                       		for (k = 0; k < annoationList.length; k++){
+                           		var splitAnnotation = annoationList[k].split(splitEqual);
+                           		if (splitAnnotation[1].includes("matching-true")){
+                           			matching.push(splitAnnotation[0].trim());
+                           		}
+                       		}
+
+                       	}
+
+                       	if (dictionary!= null && dictionary.length>1){
+                       		for (m=0; m < dictionary.length; m += 1){
+                       			var keyCompare = dictionary[m].name;
+                       			var valueCompare = dictionary[m].value;
+                       			var valueModel = dictionary[m].modelName;
+                       			var conpairService = serviceName;
+                       			if (valueModel.includes('-v')){
+                       				conpairService = service;
+                       			}
+                       			if(valueModel.localeCompare(conpairService) == 0){
+                       				console.log(valueCompare);	
+                       				dictionaryList.push(dictionary[m]);
+                       				if (!dictionaryNameList.includes(dictionary[m].name)){
+                       					dictionaryNameList.push(dictionary[m].name)
+                       				}
+                       			}
+                       		}
+                       	}
+
+                		$scope.temp.policy.ruleGridData = [];
+                		
+                		if($scope.temp.policy.editPolicy || $scope.temp.policy.readOnly){
+                			dataOrderInfo = $scope.dataOrderInfo;
+                		}
+                		
+                		$scope.jsonLayout($scope.optimizationJsonDate);
+                		
+                    });
+                    
+                    if($scope.temp.policy.editPolicy || $scope.temp.policy.readOnly){  // If it's veiw or edit
+                    	
+                    	if($scope.temp.policy.editPolicy){
+                        	$scope.isInitEditTemplate = true;
+                    	}
+                    	
+                    	var checkData = [];
+                    	var data = [];
+                    	    // If ruleData contains extra elements created by clicked add button 
+	                    	if($scope.temp.policy.ruleData != null){
+	                    		var propNames = Object.getOwnPropertyNames($scope.temp.policy.ruleData);
+	                    		propNames.forEach(function(name) {
+	                    			data.push(name);
+	                    		});
+	                    		
+	                    		var extraElements = data;
+	                    		
+	                    		if(plainAttributeKeys != null){
+	            		    		for(b = 0; b < plainAttributeKeys.length; b++){ // Remove already populated elements from data array
+	            		    			var newValue = plainAttributeKeys[b].split("*");
+	            		    			for(a = 0; a < data.length; a++){
+		            		    			if(data[a] === newValue[0] || data[a] === (newValue[0]+"@0")){
+		            		    				extraElements.splice(a, 1);
+		            		    			}
+	            		    			}
+	            		    	
+	            		    		}
+	                    		
+		            		    	//--- Populate these extra elements created by clicked add button 
+			                    	for(a = 0; a < extraElements.length; a++){            			
+			                    		if(extraElements[a].includes("@")){
+					                    	var index = extraElements[a].lastIndexOf("@");
+					                    	if(index > 0){
+					                    	    // Get the number after @
+					                    	    var n = getNumOfDigits(extraElements[a], index+1);
+					                    				
+						                        var key = extraElements[a].substring(0, index+n+1); //include @x in key also by n+2 since x can be 1,12, etc
+						                    	console.log("key: " + key);
+						                    	checkData.push(key);
+					                    	}
+			                    		}
+			                    	}
+		                    		var unique = checkData.filter(onlyUnique);
+		                    		//if no layout order info, keep the process as before
+		                    		if(!dataOrderInfo){
+			                    		for(i =0; i < unique.length; i++){
+			                    			//remove @x and let addNewChoice add @1 or @2...
+			                    			//var newKey = unique[i].substring(0, unique[i].length-2);
+			                    			var index = unique[i].lastIndexOf("@");
+			                    			var newKey = unique[i].substring(0, index);
+			                    			console.log("newKey: " + newKey);	
+			                    			$scope.addNewChoice(newKey);
+			                    		}
+		            		    	}else{
+
+			              	    		for (i = 0; i < $scope.labelManyKeys.length; i++) {
+			              	    			console.log("dataOrderInfo["+i+"]"+  dataOrderInfo[i]);
+			              	    		    var label = $scope.labelManyKeys[i];
+			              	    				// first add parent/label level
+			             	 	    			for (k = 0; k < unique.length; k++){
+					                    			var newindex = unique[k].lastIndexOf("@");
+					                    			var newKey = unique[k].substring(0, index);
+	 		             	 	    			    if(label == newKey){
+                                                        //Check this label has bee created or not
+	 		             	 	    			    	if(!document.getElementById(unique[k])){
+	 		             	 	    			    		$scope.addNewChoice(newKey);
+	 		             	 	    			    	}
+	 		             	 	    			    	unique[k] = "*processed*";
+			             	 	    					break;
+	 		             	 	    			    }
+			             	 	    			}				             	 	    			
+			              	    		}
+			              	    		
+			              	    		//---reset to default
+			              	    		dataOrderInfo = [];
+			              	    		$scope.labelManyKeys = [];
+			              	    		
+	             	 	    			//---process none labels
+				              	    	for (j = 0; j < unique.length; j++){
+				              	    		if(unique[j] != "*processed*"){
+				              	    			// if not created yet
+				              	    			if(!document.getElementById(unique[j])){
+					                    			var index = unique[j].lastIndexOf("@");
+					                    			var newKey = unique[j].substring(0, index);
+		 		             	 	    		    $scope.addNewChoice(newKey);
+				              	    			}
+				              	    		}
+				              	    	}
+		              	    		}
+	            		    }
+	                    }
+	                    
+                    	if($scope.temp.policy.editPolicy){
+                    		//clean all the events of addNewChoice
+                    		$scope.$on('$destroy', addNewChoice);
+                    	}
+	                    
+                    }
+                    var ele = angular.element(document.getElementById("DynamicTemplate"));
+            		$compile(ele.contents())($scope);
+                    $scope.$apply();
+                },
+                error : function(data){
+                    alert("Error While Retrieving the Template Layout Pattern.");
+                }
+            });
+        }
+    };
+    
+    function getNumOfDigits(str_value, index){
+		// Get the number after @
+		var str = str_value.substring(index, str_value.length);	
+		var c = '';
+		var n = 0;
+		for (var x = 0; x < str.length; x++){			                    				
+		    c = str.charAt(x);
+			    if(!isNaN(c)){ 
+                n++;                                                     
+		    }else{
+                break;
+            }
+		}
+		return n;
+    }
+    
+    function getDictionary(attribute){
+    	var dicName = attribute;
+    	if(attribute){
+    	   if(attribute.includes(":")){
+    		   dicName = attribute.split(":")[0];
+    	   }
+    	}
+	    var dictionaryRegExp = new RegExp(dicName);
+	    listemunerateValues = [];
+	    if (dictionaryRegExp.test(dictionaryNameList)) {
+			for (p=0; p < dictionaryList.length; p += 1) {
+				if (dicName == dictionaryList[p].name) {
+					listemunerateValues.push(dictionaryList[p].value);
+				}
+			}
+	    }
+	    return listemunerateValues;
+    }
+    
+    function getList(attribute) {
+    	var enumName = attribute;
+    	console.log("In getList: attribute => " + attribute);
+    	if(attribute){
+    	   if(attribute.includes(":")){
+    		   enumName = attribute.split(":")[0];
+    	   }
+    	}   
+        var baseEnum = $scope.optimizationModelData.enumValues;
+        var enumList = [];
+        if(baseEnum != null){
+        	enumList = baseEnum.split(splitEnum);
+        }
+    	var enumAttributes;
+    	var patternTest = new RegExp(enumName);
+    	for (k=0; k < enumList.length; k += 1){
+    		if(patternTest.test(enumList[k]) == true){
+    			enumAttributes = enumList[k].trim();
+    		}
+    	}
+
+    	if(enumAttributes){
+	        enumAttributes = enumAttributes.replace("[", "");
+	       	enumAttributes = enumAttributes.replace("]", "");
+	       	enumAttributes = enumAttributes.replace(/ /g, '');
+			var dropListAfterCommaSplit = enumAttributes.split(splitEqual);
+			listemunerateValues  = dropListAfterCommaSplit[1].split(splitComma);
+	        return listemunerateValues;
+	     }
+           
+         return [];
+    }
+	    
+    function getBooleanList(){
+    	var booleanList = [];
+    	booleanList.push(true);
+    	booleanList.push(false);
+    	return booleanList;
+    }
+
+    function isArray(arrayTest) {
+        return Object.prototype.toString.call(arrayTest) === '[object Array]';
+    }
+	    
+	var lableList = [];
+	
+    $scope.layOutElementList = [];
+    $scope.layOutOnlyLableList = [];
+    
+    var elementOrderNum = 0;
+	    
+	function deconstructJSON(layOutData, level , name) {
+
+		 var array = false;
+		 var label = level;
+		 var stringValue = "java.lang.String";
+		 var string = "string";
+		 var intValue = "int";
+		 var integerValue = "integer";
+		 var double = "double";
+		 var boolean = "boolean";
+		 var baseLevel = level;
+		 var list = "list";
+		 var String = "String";
+		 
+		 var attributekey = "";
+		 
+		if (name.length > 1){
+			label = label + name + '.';
+		}
+		
+	    for (key in layOutData) {
+	    	array = isArray(layOutData[key]);
+	    	console.log("key: " + key , "value: " + layOutData[key]);
+   	
+	    	if (!!layOutData[key] && typeof(layOutData[key])=="object") {
+	    		
+	    		if (array==false && key!=="0"){
+	    			
+	    			if($scope.dataOrderInfo){
+	    			    var labelObject = {"label" : key, "level" : label, "array" : array};
+	    			    //save it to the list
+	    			    $scope.layOutOnlyLableList.push(labelObject);
+	    			    
+	    			}else {
+	    				//call label layout
+	    				$scope.labelLayout(label, key, array );
+	    			}
+	    			
+	    		}
+	    		
+	    		if (array == true && key!=0){
+	    			lableList.push(key);
+	    		}
+	    		
+	    		if (lableList.length > 0){
+	    			array = true;
+	    		}
+	    		if ( key==="0"){
+	    			var newKey = lableList.pop();
+	    			
+	    			if($scope.dataOrderInfo){
+	    				
+		    			var labelObject = {"label" : newKey, "level" : baseLevel, "array" : array};
+		    			//save it to the list
+		    			$scope.layOutOnlyLableList.push(labelObject);
+		    			
+	    			}else {
+	    				//call label layout 
+	    			    $scope.labelLayout(baseLevel, newKey, array );
+	    			}
+	    			
+	    			if (array){
+	    				label = baseLevel + newKey + '@0.';
+	    			} else {
+	    				label = baseLevel + newKey + '.';
+	    			}
+	    		}
+	        	deconstructJSON(layOutData[key] , label, key);
+	        } else {
+	        	var attirbuteLabel = label;
+	        	var defaultValue='';
+	        	var isRequired = false;
+	        	if (layOutData[key].includes('defaultValue-')){
+	        		defaultValue = layOutData[key].split('defaultValue-')[1];
+	        	}
+
+	        	if (key==="0"){
+	        		array = true;
+	        		attributekey = lableList.pop();
+	        		attirbuteLabel = baseLevel;
+	        	} else {
+	        		attributekey = key.split();
+	        	}
+	        	
+	        	if (layOutData[key].includes('required-true')){
+	        		isRequired = true;
+	        	}
+	    		
+	    		var subAttributes = $scope.optimizationModelData.sub_attributes;
+	    		
+	    		if(subAttributes){		    			
+	    			var jsonObject = JSON.parse(subAttributes);		    			
+	    			var allkeys = Object.keys(jsonObject);
+	    			if(allkeys){
+	    				for (var k = 0; k < allkeys.length; k++) {
+	    					var keyValue = allkeys[k];
+	    					console.log(" keyValue:jsonObject["+keyValue+ "]: " + jsonObject[keyValue]);
+	    					if(jsonObject[keyValue]){
+	    						var tempObject = jsonObject[keyValue];
+	    						if(tempObject && tempObject[key]){
+	    				        	if (tempObject[key].includes('required-true')){
+	    				        		isRequired = true;
+	    				        	}	
+	    						}
+	    					}
+	    				}		    				
+	    			}		    			
+	    		}
+	    		
+	    		var elementObject = {};
+	        	switch (layOutData[key].split(splitcolon)[0]){
+	        	
+	        		case stringValue:
+	        		case string:
+	        			if($scope.dataOrderInfo){		        				
+			        		elementOrderNum++;
+			        		elementObject = {"id": elementOrderNum,"attributekey" : attributekey, "array": array, "attirbuteLabel" : attirbuteLabel, "defaultValue": defaultValue, "isRequired": isRequired, "type":"text"};
+			        		$scope.layOutElementList.push(elementObject);
+	        			}else{
+	        				$scope.attributeBox(attributekey, array, attirbuteLabel, defaultValue, isRequired, "text");
+	        			}
+	        			break;		        			
+	        		case intValue: 
+	        		case integerValue: 
+	        			if($scope.dataOrderInfo){
+		        			elementOrderNum++;
+			        		elementObject = {"id": elementOrderNum,"attributekey" : attributekey, "array": array, "attirbuteLabel" : attirbuteLabel, "defaultValue": defaultValue,"isRequired": isRequired, "type":"number"};
+			        		$scope.layOutElementList.push(elementObject);
+	        			}else{
+	        				$scope.attributeBox(attributekey, array, attirbuteLabel, defaultValue, isRequired, "number");
+	        			}
+	        			break;		        			
+	        		case double:
+	        			if($scope.dataOrderInfo){
+		        			elementOrderNum++;
+			        		elementObject = {"id": elementOrderNum,"attributekey" : attributekey, "array": array, "attirbuteLabel" : attirbuteLabel, "defaultValue": defaultValue,"isRequired": isRequired, "type":"double"};
+			        		$scope.layOutElementList.push(elementObject);		        				
+	        			}else{
+	        				$scope.attributeBox(attributekey, array, attirbuteLabel, defaultValue, isRequired, "double");
+	        			}
+	        			break;
+	        		case boolean:
+	        			if($scope.dataOrderInfo){
+		        			elementOrderNum++;
+			        		elementObject = {"id": elementOrderNum,"attributekey" : attributekey, "array": array, "attirbuteLabel" : attirbuteLabel, "defaultValue": layOutData[key], "list": getBooleanList, "isRequired": isRequired, "type":"dropBox"};
+			        		$scope.layOutElementList.push(elementObject);
+	        			}else{
+	        				$scope.dropBoxLayout(attirbuteLabel, attributekey, array, layOutData[key], getBooleanList());
+	        			}
+	        			break;
+	        		default:
+	        			if (layOutData[key].includes('dictionary-')){
+	        				var list = getDictionary(layOutData[key].split('dictionary-')[1]);
+	        			}else{
+	        				//--- get dropdown values from enumValues
+	        				var list = getList(layOutData[key]);
+	        			}
+	        			if (list.length===0){ //not dropdown element
+	        				if($scope.dataOrderInfo){
+	        					elementOrderNum++;
+				        		elementObject = {"id": elementOrderNum,"attributekey" : attributekey, "array": array, "attirbuteLabel" : attirbuteLabel, "defaultValue": defaultValue,"isRequired": isRequired, "type":"text"};
+				        		$scope.layOutElementList.push(elementObject);
+	        					
+	        				}else{
+	        					$scope.attributeBox(attributekey, array, attirbuteLabel, defaultValue, isRequired, "text");
+	        				}		        				
+	        			}else{
+	        				if($scope.dataOrderInfo){
+		        				elementOrderNum++;
+				        		elementObject = {"id": elementOrderNum, "attributekey" : attributekey, "array": array, "attirbuteLabel" : attirbuteLabel, "defaultValue": layOutData[key],"isRequired": isRequired, "list":list, "type":"dropBox"};
+				        		$scope.layOutElementList.push(elementObject);		        					
+	        				}else{
+	        					$scope.dropBoxLayout(attirbuteLabel, attributekey, array, layOutData[key], list, isRequired);
+	        				}
+	        			}
+	        			break;
+	        	}
+	        }
+	    }
+	}  
+
+    $scope.validContionalRequired = function(parentId) {
+        console.log("ng-blur event: parentId : " + parentId);
+        var c = document.getElementById(parentId).children;
+        var i;
+        var hasValue = false;
+        for (i = 0; i < c.length; i++) {
+        	if(c[i].getAttribute("data-conditional")){
+        	    console.log(c[i].getAttribute("data-conditional"));
+        	    console.log(c[i].value);
+        	    if(c[i].value != null && c[i].value.trim() != ""){
+        	    	hasValue = true;
+        	    }
+        	}
+        }
+
+	    for (i = 0; i < c.length; i++) {
+	        if(c[i].getAttribute("data-conditional")){
+	        	if(hasValue){
+	        	    c[i].setAttribute("required", true);
+	        	}else{
+	        		c[i].removeAttribute("required");
+	        	}
+	        }
+	    }        	
+     }
+			
+    $scope.jsonLayout = function(layOutData){
+    	
+       deconstructJSON(layOutData , "", "");
+	    	   
+	   var orderValue = $scope.dataOrderInfo;
+	   var layOutElementList = $scope.layOutElementList;
+	   var labelList = $scope.layOutOnlyLableList;
+	    
+	   //reset to default
+	   elementOrderNum = 0;
+	   $scope.layOutElementList = [];
+	   $scope.layOutOnlyLableList = [];
+	   
+	   // Only layout in order if order info provided
+	   if(orderValue){
+		   
+		   if(orderValue.includes("[")){
+			  orderValue = orderValue.replace("[", "") ;
+			  orderValue = orderValue.replace("]", "") ;
+		   }
+		   
+		   orderValue = orderValue.split(',') ;
+		   
+		   for (i = 0; i < orderValue.length; i++) {
+			   console.log("orderValue["+i+"]"+  orderValue[i]);
+			   var key = orderValue[i].trim();
+			 
+			    //--- Create labels first {"label" : newKey, "level" : baseLevel, "array" : array};
+			   if(labelList){
+				   for (k = 0; k < labelList.length; k++){
+					   
+					  var label = labelList[k].label.toString().trim();
+					  var level = labelList[k].level.toString().trim();
+					  var array = labelList[k].array;
+					  
+					  if(key == label){	 	    					  
+						 $scope.labelLayout(level, label, array);
+	 	  	    		 //in case to have duplicate label names
+						 labelList[k].label = "*processed*";
+						 break;
+					  }
+				   }
+			   }
+			   //--- then layout each element based on its order defined in YAML file
+	    	   for (j = 0; j < layOutElementList.length; j++) { 
+	    		   
+	    		   var attributekey = layOutElementList[j].attributekey.toString().trim();	 	  	    		   
+	    		
+	    		   if(key == attributekey){ 	
+	
+	  	    		   var attirbuteLabel = layOutElementList[j].attirbuteLabel.toString().trim();
+	  	    		   var defaultValue = layOutElementList[j].defaultValue.toString().trim();
+	  	    		   var isRequired = layOutElementList[j].isRequired;
+	  	    		   
+	  	    		   console.log("layOutElementList[" +j+ "]: id:" + layOutElementList[j].id + ", attributekey:"+ layOutElementList[j].attributekey + ", attirbuteLabel:" + layOutElementList[j].attirbuteLabel);
+	        		  
+	  	    		   if (layOutElementList[j].type == "dropBox"){ 
+	        				$scope.dropBoxLayout(attirbuteLabel, attributekey, layOutElementList[j].array, defaultValue, layOutElementList[j].list, isRequired);
+	                        
+	        		   }else{
+	        			    $scope.attributeBox(attributekey, layOutElementList[j].array, attirbuteLabel, defaultValue, isRequired, layOutElementList[j].type);	
+	
+	        		   }
+	  	    		   
+	  	    		   //in case to have duplicate attribute names
+	  	    		   layOutElementList[j].attributekey = "*processed*";
+	        		   break;
+	    		   }
+	    	   
+	    	   }
+		   
+		   }
+	   }
+    }
+    
+    
+    $scope.attributeBox = function(attibuteKey, attributeManyKey, labelValue, defaultValue, isRequired, dataType ){
+		$scope.temp.policy.ruleGridData.push(attibuteKey);			
+		var br = document.createElement("BR");
+	
+		var label = document.createElement("Label");
+		var labeltext = null;
+		var requiredLabName = "";
+		if (matching.includes(attibuteKey)){
+			labeltext = document.createTextNode(attibuteKey + "*!");	
+			isRequired = true;  //set required as true for matching element
+		}else {
+			if(isRequired){
+				requiredLabName = attibuteKey + " * ";
+				labeltext = document.createTextNode(requiredLabName);
+			}else{
+			    labeltext = document.createTextNode(attibuteKey);	
+			}
+		}
+
+	
+		var divID = labelValue;
+		
+		if (labelValue.length  < 1){
+			divID = "DynamicTemplate";
+		}else if (labelValue.endsWith('.')){
+			var divID = 'div.'+ labelValue.substring(0, labelValue.length-1);
+		}
+		
+		label.appendChild(labeltext);
+		
+		var textField = document.createElement("INPUT");
+		
+		textField.setAttribute("class" , "form-control");
+		if(dataType){
+			   if(dataType == "double"){
+				   textField.setAttribute("type" , "number");
+				   textField.setAttribute("step" , "any");
+			   }else{
+			      textField.setAttribute("type" , dataType);
+			   }
+		}
+		textField.setAttribute("style" , "width:300px;");
+		textField.setAttribute("ng-disabled" , "temp.policy.readOnly");
+		var checkKey;
+		var id = "";
+		if(attributeManyKey){
+			checkKey = labelValue + attibuteKey+'@0';
+			textField.setAttribute("id" , ''+labelValue + attibuteKey+'@0'+''); 
+			var divTag = document.createElement("div");
+			divTag.setAttribute("id", "div."+ labelValue +attibuteKey);
+			var addButton = document.createElement("BUTTON");
+			var buttonaddLabel = document.createTextNode("+");       
+			addButton.appendChild(buttonaddLabel); 
+			addButton.setAttribute("id", labelValue + attibuteKey);
+			addButton.setAttribute("class", "btn btn-add-remove");
+			addButton.setAttribute("ng-click" ,  'addNewChoice("'+labelValue + attibuteKey+'");');
+			addButton.setAttribute("ng-disabled" , "temp.policy.readOnly");
+			var removeButton = document.createElement("BUTTON");
+			var buttonremoveLabel = document.createTextNode("-");       
+			removeButton.appendChild(buttonremoveLabel); 
+			removeButton.setAttribute("class", "btn btn-add-remove");
+			removeButton.setAttribute("ng-click" ,  'removeChoice("'+labelValue + attibuteKey+'");');
+			removeButton.setAttribute("ng-disabled" , "temp.policy.readOnly");
+			document.getElementById(divID).appendChild(addButton); 
+			document.getElementById(divID).appendChild(removeButton); 
+			document.getElementById(divID).appendChild(label); 
+			id = "div."+labelValue+attibuteKey;
+			divTag.setAttribute("id", id); 
+			document.getElementById(divID).appendChild(divTag);
+			textField.className += ' first_child';	
+			if(isRequired){
+				textField.setAttribute("required", "true");
+			}			
+			divTag.appendChild(textField); 			
+			document.getElementById(divID).appendChild(divTag); 
+			
+		}else{
+			checkKey = labelValue + attibuteKey;
+			textField.setAttribute("id" , ''+labelValue +attibuteKey+'');
+			if(document.getElementById(divID).hasAttribute('required') || !document.getElementById(divID).hasAttribute('data-conditional')){
+				if(requiredLabName.includes("*") || isRequired){
+					textField.setAttribute("required", "true");
+				}
+			}else if (document.getElementById(divID).hasAttribute('data-conditional')){
+				if(requiredLabName.includes("*")){					
+					var requiredNode = document.createElement('span');
+					requiredNode.setAttribute("class", "mstooltip");
+					requiredNode.textContent = "?";
+					label.appendChild(requiredNode);
+					
+					var requiredNodeToolTip = document.createElement('span');
+					requiredNodeToolTip.setAttribute("class", "tooltiptext");
+					requiredNodeToolTip.textContent = "Conditional Required";
+					requiredNode.appendChild(requiredNodeToolTip);
+					
+					textField.setAttribute("data-conditional", divID);
+					textField.setAttribute("ng-blur", "validContionalRequired('"+divID+"')");
+				}
+			}
+	        
+			document.getElementById(divID).appendChild(label);  
+			document.getElementById(divID).appendChild(textField);  
+			document.getElementById(divID).appendChild(br); 
+	
+		}
+
+		if(divID.includes("@0") && divID.includes("div.")){
+			var firstChild_Id = divID.split("@0")[0];
+			var firstChild_element = document.getElementById(firstChild_Id);
+			if(firstChild_element){
+				firstChild_element.className += ' children_group';  //here is a div with a group of children.
+			}
+		}
+		console.log('firstChild_Id: ' + firstChild_Id);
+		console.log('divID: ' + divID);
+		
+		if (defaultValue.length > 0){	
+			if(defaultValue.includes(":")){
+				defaultValue = defaultValue.split(":")[0];
+				if(defaultValue === "NA") {
+					defaultValue = "";
+				}				
+			}
+			if(defaultValue != "undefined" && defaultValue != undefined && defaultValue != "null"){
+		    	document.getElementById(checkKey).value = defaultValue;
+			}
+		}
+		
+		if($scope.temp.policy.ruleData != null){
+			if (attributeManyKey){
+				var newCheckKey = checkKey.replace(attibuteKey + '@0',attibuteKey);
+				if($scope.temp.policy.ruleData[newCheckKey +'@0'] != undefined && $scope.temp.policy.ruleData[newCheckKey +'@0'] != "undefined"){
+			  	    document.getElementById(newCheckKey +'@0').value = $scope.temp.policy.ruleData[newCheckKey +'@0'];
+				}
+			}else{
+				if($scope.temp.policy.ruleData[checkKey] != undefined && $scope.temp.policy.ruleData[checkKey] != "undefined"){
+				    document.getElementById(checkKey).value = $scope.temp.policy.ruleData[checkKey];
+				}
+			}
+		} 
+		plainAttributeKeys.push(labelValue + attibuteKey+'*'+attributeManyKey);	
+
+    };
+    
+    $scope.labelManyKeys = [];
+    $scope.labelLayout = function(labelValue, lableName, labelManyKey ){
+		var label = document.createElement("Label")
+		var divID = labelValue;
+		if (labelValue.endsWith('.')){
+			var workingLabel = labelValue.substring(0, labelValue.length-1);
+		}else {
+			var workingLabel = labelValue;
+		}
+		
+		if (labelValue.length  < 1){
+			divID = "DynamicTemplate";
+		} else if (labelValue.endsWith('.')){
+			var divID = 'div.'+ labelValue.substring(0, labelValue.length-1);
+		}
+		
+		var subAttributes = $scope.optimizationModelData.subattributes;
+	    var jsonObject = JSON.parse(subAttributes);	
+	    var lablInfo = findVal(jsonObject, lableName);
+		console.log("findValue : " + lableName +": "+ lablInfo);
+		var star = "";
+		var required = null;
+		if(lablInfo){
+			if(lablInfo.includes("required-true")){
+				star = " *";
+				required = true;
+			}else if (lablInfo.includes("required-false")){
+				required = false
+			}
+		}
+		
+		var labeltext = document.createTextNode(lableName + star);
+	
+		label.appendChild(labeltext);
+
+
+		if(labelManyKey){
+			var addButton = document.createElement("BUTTON");
+			var buttonLabel = document.createTextNode("+");       
+			addButton.appendChild(buttonLabel); 
+			addButton.setAttribute("class", "btn btn-add-remove");
+			addButton.setAttribute("ng-click" ,  'addNewChoice("'+labelValue + lableName+'");');
+			addButton.setAttribute("ng-disabled" , "temp.policy.readOnly");
+			var removeButton = document.createElement("BUTTON");
+			var buttonremoveLabel = document.createTextNode("-");       
+			removeButton.appendChild(buttonremoveLabel); 
+			removeButton.setAttribute("class", "btn btn-add-remove");
+			removeButton.setAttribute("ng-click" ,  'removeChoice("'+labelValue +lableName+'");');
+			removeButton.setAttribute("ng-disabled" , "temp.policy.readOnly"); 
+			document.getElementById(divID).appendChild(addButton); 
+			document.getElementById(divID).appendChild(removeButton);
+			document.getElementById(divID).appendChild(label);
+			var id = "div."+labelValue+lableName;
+			var divTag = document.createElement("div");
+			divTag.setAttribute("id", id); 
+			document.getElementById(divID).appendChild(divTag);
+			
+			var divTag = document.createElement("div");
+			divTag.setAttribute("id", id +'@0');  
+			
+			divTag.className += ' children_group'; //here is div with a group of children.
+			
+			if(required){
+			   divTag.setAttribute("required", required);  
+			}else if(required == false){
+			   divTag.setAttribute("data-conditional", "yes");  
+			}
+			
+			document.getElementById(id).appendChild(divTag);
+			
+			$scope.labelManyKeys.push(lableName);
+			
+		}else{
+			var divTag = document.createElement("div");
+			divTag.setAttribute("id", "div."+labelValue+lableName);
+			divTag.className += ' children_group'; //here is div with a group of children.
+			if(required){
+			    divTag.setAttribute("required", required);  
+			}else if(required == false){
+				divTag.setAttribute("data-conditional", "yes");  
+			}  
+			document.getElementById(divID).appendChild(label);  
+			document.getElementById(divID).appendChild(divTag);			
+		}
+    };
+
+    $scope.dropBoxLayout = function(labelLevel, attributeName, many , refValue, listemunerateValues, isRequired){
+		var br = document.createElement("BR");
+	
+		if (labelLevel.length  < 1){
+				var divID = "DynamicTemplate";
+		} else if (labelLevel.endsWith('.')){
+				var divID = 'div.'+ labelLevel.substring(0, labelLevel.length-1);
+		}	
+	
+	
+		var label = document.createElement("Label")
+		
+		var refAttributes = $scope.optimizationModelData.ref_attributes;
+		if(isRequired != true && refAttributes){ //check refAttributes also		
+		   		var refAttributesList = refAttributes.split(splitComma);
+		   		for (k = 0; k < refAttributesList.length; k++){
+		       		var refAttribute = refAttributesList[k].split(splitEqual);	       		
+		       		if (attributeName == refAttribute[0].trim() && refAttribute[1].includes("required-true")){
+		       			isRequired = true;
+		       		}
+		   		}
+		}
+		
+		if (matching.includes(attributeName)){
+			var labeltext = document.createTextNode(attributeName + "*!");
+			label.appendChild(labeltext);
+			isRequired = true;  //set required as true for matching element
+		}else {
+			var labeltext = document.createTextNode(attributeName);		
+			if(isRequired){
+			    var requiredLabName = attributeName+ " * ";
+				labeltext = document.createTextNode(requiredLabName);
+			}else{
+			    labeltext = document.createTextNode(attributeName);	
+			}
+		
+		    label.appendChild(labeltext);		
+		}
+		label.appendChild(labeltext);
+		// if this field is required, but its parent is not required
+		if(isRequired && document.getElementById(divID).hasAttribute('data-conditional')){
+		   	var requiredNode = document.createElement('span');
+			requiredNode.setAttribute("class", "mstooltip");
+			requiredNode.textContent = "?";
+			label.appendChild(requiredNode);
+				
+			var requiredNodeToolTip = document.createElement('span');
+			requiredNodeToolTip.setAttribute("class", "tooltiptext");
+			requiredNodeToolTip.textContent = "Conditional Required";
+			requiredNode.appendChild(requiredNodeToolTip);
+
+		}
+	
+		var listField = document.createElement("SELECT");
+		listField.setAttribute("class" , "form-control");
+		listField.setAttribute("style" , "width:300px;");
+		listField.setAttribute("ng-disabled" , "temp.policy.readOnly");
+		
+		if(isRequired){
+		    if(document.getElementById(divID).hasAttribute('data-conditional')){
+		    	listField.setAttribute("data-conditional", divID);
+		    	listField.setAttribute("ng-blur", "validContionalRequired('"+divID+"')");
+		    }else{
+				listField.setAttribute("required", true);
+		    }
+		}
+		if( many != true || isRequired != true){ // add an empty option for not required or not multiple select element
+			var optionFirst = document.createElement('option');
+			optionFirst.setAttribute('value', "");
+			listField.appendChild(optionFirst);	
+		}
+		
+		for (i=0; i < listemunerateValues.length; i += 1) {
+			if(listemunerateValues[i].includes("equal-sign")){
+				listemunerateValues[i] = listemunerateValues[i].replace('equal-sign','=');
+			}
+		    option = document.createElement('option');
+		    option.setAttribute('value', listemunerateValues[i]);
+		    option.appendChild(document.createTextNode(listemunerateValues[i]));
+		    option.setAttribute('value', listemunerateValues[i]);
+		    listField.appendChild(option);
+		}
+		listField.setAttribute("id" , ''+ labelLevel + attributeName + '');
+		
+		enumKeyList.push(attributeName);
+		
+		document.getElementById(divID).appendChild(label);  
+		document.getElementById(divID).appendChild(br);	
+				
+		if(many == true){
+			document.getElementById(divID).appendChild(listField).multiple = true;
+			plainAttributeKeys.push(labelLevel + attributeName+'*'+true);
+		}else {
+			document.getElementById(divID).appendChild(listField).multiple = false;
+			plainAttributeKeys.push(labelLevel + attributeName+'*'+false);
+		}
+	
+		if($scope.temp.policy.ruleData != null){
+			if (many == true){
+				document.getElementById(labelLevel +attributeName).options[0].selected = false;
+				for (i=0; i < listemunerateValues.length; i += 1) {
+					var testValue = $scope.temp.policy.ruleData[labelLevel +attributeName+'@' + i];
+					if (testValue === undefined){
+						testValue = $scope.temp.policy.ruleData[labelLevel +attributeName];
+						}
+					var location = listemunerateValues.indexOf(testValue);
+					if (location!=-1){
+						document.getElementById(labelLevel +attributeName).options[location].selected = true;
+						}
+					}			
+				}else {
+					    if($scope.temp.policy.ruleData[labelLevel + attributeName] != undefined && $scope.temp.policy.ruleData[labelLevel + attributeName] != "undefined"){
+		                    document.getElementById(labelLevel + attributeName).value = $scope.temp.policy.ruleData[labelLevel + attributeName];	
+					    }
+				}
+			}
+	    };
+    
+    function onlyUnique(value, index, self) { 
+        return self.indexOf(value) === index;
+    };
+    
+    $scope.savePolicy = function(policy){
+    	if(policy.itemContent != undefined){
+    		$scope.refreshCheck = true; 
+        	$scope.policyNavigator = policy.itemContent;
+        	policy.itemContent = "";
+    	}
+    	$scope.savebutton = false;
+    	var splitAt = '*';
+    	var dot ='.';
+    	var jsonPolicy = {};
+    	if(plainAttributeKeys != null){
+    		for(a = 0; a < plainAttributeKeys.length; a++){
+    			var splitPlainAttributeKey = plainAttributeKeys[a].split(splitAt);
+    			console.log("splitPlainAttributeKey: " + splitPlainAttributeKey);	
+    			var searchElement = document.getElementById(splitPlainAttributeKey[0]);
+    			var key = splitPlainAttributeKey[0];
+    			
+                if(searchElement == null || searchElement.nodeName == 'BUTTON'){
+                    searchElement = document.getElementById(splitPlainAttributeKey[0]+'@0');
+                    key = splitPlainAttributeKey[0]+'@0';
+                }
+                
+    			if(searchElement != null){
+    				var keySplit = key.split(dot);
+    				var elumentLocation = keySplit.length;
+    				var enumKey = key;
+    				if (elumentLocation > 1){
+    					enumKey = keySplit[keySplit.length - 1];
+    				}
+    				//check it is undefined or not
+    				if (enumKeyList != undefined && enumKeyList.indexOf(enumKey) != -1){
+						if (splitPlainAttributeKey[1]!= undefined && splitPlainAttributeKey[1].indexOf("true") !== -1){
+							var multiSlect = [];
+							for ( var i = 0; i < searchElement.selectedOptions.length; i++) {
+								multiSlect.push(searchElement.selectedOptions[i].value);
+								}
+							jsonPolicy[key]= multiSlect;
+						}else{
+							console.log(" searchElement.value = > " + searchElement.value);
+							jsonPolicy[key]= searchElement.value;
+						}
+    				} else {
+        				if(searchElement.value != null){
+							console.log(" searchElement.value = > " + searchElement.value);
+        					jsonPolicy[key]= searchElement.value;
+        				}
+    				}
+    			}
+    		}
+    	}
+        var uuu = "policycreation/save_policy";
+        var postData={policyData: policy, policyJSON : jsonPolicy};
+        $.ajax({
+            type : 'POST',
+            url : uuu,
+            dataType: 'json',
+            contentType: 'application/json',
+            data: JSON.stringify(postData),
+            success : function(data){
+                $scope.$apply(function(){
+                	$scope.data=data.policyData;
+                	if($scope.data == 'success'){
+                		$scope.temp.policy.readOnly = 'true';
+                		$scope.safetyChecker = data.policyData.split("#")[2];
+                		if ($scope.safetyChecker!=undefined) {
+                			Notification.success($scope.safetyChecker);
+                		}
+                		$scope.pushStatus=data.policyData.split("&")[1];
+                		if($scope.pushStatus=="successPush"){
+                			Notification.success("Policy pushed successfully");
+                		}
+                		Notification.success("Policy Saved Successfully.");	
+                	}else if ($scope.data == 'PolicyExists'){
+						$scope.savebutton = true;
+						Notification.error("Policy Already Exists with Same Name in Scope.");
+					}
+                });
+                console.log($scope.data);
+            },
+            error : function(data){
+            	Notification.error("Error Occured while saving Policy.");
+            }
+        });
+    };
+    
+    $scope.validatePolicy = function(policy){
+    	document.getElementById("validate").innerHTML = "";
+    	var splitAt = '*';
+    	var dot ='.';
+    	var jsonPolicy = {};
+    	if(plainAttributeKeys != null){
+    		for(a = 0; a < plainAttributeKeys.length; a++){
+    			var splitPlainAttributeKey = plainAttributeKeys[a].split(splitAt);
+    			console.log(splitPlainAttributeKey[1]);	
+    			var searchElement = document.getElementById(splitPlainAttributeKey[0]);
+    			var key = splitPlainAttributeKey[0];
+    			if(searchElement == null || searchElement.nodeName == 'BUTTON'){
+    				searchElement = document.getElementById(splitPlainAttributeKey[0]+'@0');
+    				key = splitPlainAttributeKey[0]+'@0';
+    			}
+    			if(searchElement != null){
+    				if (enumKeyList.indexOf(key) != -1){
+						if (splitPlainAttributeKey[1].indexOf("true") !== -1){
+							var multiSlect = [];
+							for ( var i = 0; i < searchElement.selectedOptions.length; i++) {
+								multiSlect.push(searchElement.selectedOptions[i].value);
+								}
+							jsonPolicy[key]= multiSlect;
+						}else{
+							jsonPolicy[key]= searchElement.value;
+						}
+    					if(searchElement.getAttribute("required")){
+    						if(!searchElement.value){
+    							return;
+    						}
+    					} 
+    				} else {
+        				if(searchElement.value != null){
+        					jsonPolicy[key]= searchElement.value;
+        					if(searchElement.getAttribute("required")){
+        						if(!searchElement.value){
+        							return;
+        						}
+        					}        					
+        				}
+    				}
+    			}
+    		}
+    	}
+        var uuu = "policyController/validate_policy.htm";        
+        var postData={policyData: policy, policyJSON : jsonPolicy};
+ 		$.ajax({
+ 			type : 'POST',
+ 			url : uuu,
+ 			dataType: 'json',
+ 			contentType: 'application/json',
+ 			data: JSON.stringify(postData),
+ 			success : function(data){
+ 				$scope.$apply(function(){
+ 					$scope.validateData = data.data.replace(/\"/g, "");
+					$scope.data=data.data.substring(1,8);
+						var size = data.data.length;
+						if($scope.data == 'success'){
+							Notification.success("Validation Success.");
+							$scope.savebutton = false;
+							if (size > 18){
+								var displayWarning = data.data.substring(19,size  - 1);
+								document.getElementById("validate").innerHTML = "Safe Policy Warning Message  :  "+displayWarning;
+								document.getElementById("validate").style.color = "white";
+								document.getElementById("validate").style.backgroundColor = "skyblue";
+							}
+ 						}else{
+ 							Notification.error("Validation Failed.");
+ 							document.getElementById("validate").innerHTML = $scope.validateData;
+ 							document.getElementById("validate").style.color = "white";
+ 							document.getElementById("validate").style.backgroundColor = "red";
+ 							$scope.savebutton = true;
+ 						}
+ 						
+ 				});
+ 				console.log($scope.data);	
+ 			},
+ 			error : function(data){
+ 				Notification.error("Validation Failed.");
+ 				$scope.savebutton = true;
+ 			}
+ 		});
+    };
+
+    function extend(obj, src) {
+        for (var key in src) {
+            if (src.hasOwnProperty(key)) obj[key] = src[key];
+        }
+        return obj;
+    }
+}]);/**
+ * 
+ */
\ No newline at end of file
diff --git a/POLICY-SDK-APP/src/main/webapp/app/policyApp/policy-models/Editor/PolicyTemplates/OptimizationPolicyTemplate.html b/POLICY-SDK-APP/src/main/webapp/app/policyApp/policy-models/Editor/PolicyTemplates/OptimizationPolicyTemplate.html
new file mode 100644
index 0000000..070a7a8
--- /dev/null
+++ b/POLICY-SDK-APP/src/main/webapp/app/policyApp/policy-models/Editor/PolicyTemplates/OptimizationPolicyTemplate.html
@@ -0,0 +1,108 @@
+<div ng-controller="optimizationController">
+	<form>
+		<div class="well">
+			<div class="form-group row">
+				<div class="form-group col-sm-6">
+					<label>Policy Name:<sup><b>*</b></sup></label> <input type="text"
+						class="form-control" ng-disabled="temp.policy.readOnly"
+						ng-readonly="temp.policy.editPolicy"
+						ng-model="temp.policy.policyName" required pattern="\S+"
+						title="Enter Policy Name without any spaces and special characters and will accept _." />
+				</div>
+				<div class="form-group col-sm-6">
+					<label>Description:</label> <input type="text" class="form-control"
+						ng-disabled="temp.policy.readOnly"
+						ng-model="temp.policy.policyDescription" 
+						title="Description field will accept any type of data."/>
+				</div>
+			</div>
+			<div class="form-group row">
+				<div class="form-group col-sm-3">
+					<label>Onap Name:<sup><b>*</b></sup></label> <select
+						class="form-control" ng-disabled="temp.policy.readOnly"
+						ng-model="temp.policy.onapName"
+						ng-options="option for option in onapNameDictionaryDatas track by option"
+						required pattern="\S+" title="Select the dropdown value driven from OnapName (common)Dictionary."></select>
+				</div>
+				<div class="form-group col-sm-3">
+					<label>Time to Live Date:</label> <input type="text" id="ttlDate"
+						class="form-control" name="ttlDate" ng-disabled="temp.policy.readOnly"
+						ng-model="temp.policy.ttlDate" title="Select the date from calender onclick on the field."/>
+				</div>
+				<div class="form-group col-sm-3">
+					<label>Guard:<sup><b>*</b></sup></label> <select
+						class="form-control" ng-disabled="temp.policy.readOnly"
+						ng-model="temp.policy.guard"
+						required pattern="\S+" title="Select the dropdown Guard value.">
+						<option>True</option>
+						<option>False</option></select>
+				</div>
+				<div class="form-group col-sm-3">
+					<label>Risk Type:<sup><b>*</b></sup></label> <select
+						class="form-control" ng-disabled="temp.policy.readOnly"
+						ng-model="temp.policy.riskType"
+						ng-options="option for option in riskTypeDictionaryDatas track by option"
+						required pattern="\S+" title="Select the dropdown value driven from RiskType (Safe Policy)Dictionary."></select>
+				</div>
+			</div>
+			<div class="form-group row">
+				<div class="form-group col-sm-3">
+					<label>Risk Level:<sup><b>*</b></sup></label> <select
+						class="form-control" ng-disabled="temp.policy.readOnly"
+						ng-model="temp.policy.riskLevel"
+						required pattern="\S+" title="Select the dropdown Risk level value.">
+						<option>1</option>
+						<option>2</option>
+						<option>3</option>
+						<option>4</option>
+						<option>5</option></select>
+				</div>
+				<div class="form-group col-sm-3">
+					<label>Priority:<sup><b>*</b></sup></label> <select
+						class="form-control" ng-disabled="temp.policy.readOnly"
+						ng-model="temp.policy.priority"
+						ng-options="option for option in priorityDatas track by option" title="Select the dropdown Priority value.">
+						<option value="">{{temp.policy.priority}}</option>
+					</select>
+				</div>
+				<div class="form-group col-sm-3">
+					<label>Optimization Model:<sup><b>*</b></sup></label> <select
+						class="form-control" ng-disabled="temp.policy.readOnly"
+						ng-model="temp.policy.serviceType"
+						ng-options="option for option in optimizationModelsDictionaryDatas track by option"
+						ng-init="pullVersion(temp.policy.serviceType);"
+						ng-click="pullVersion(temp.policy.serviceType);"
+						title="Select the dropdown value driven from Optimization Models (Optimization Policy)Dictionary."></select>
+				</div>
+				<div class="form-group col-sm-3">
+					<label>Optimization Model Version:<sup><b>*</b></sup></label> <select
+						class="form-control" ng-disabled="temp.policy.readOnly"
+						ng-model="temp.policy.version"
+						ng-options="option for option in optimizationModelsDictionaryVersionDatas track by option"
+						ng-init="addDataToFields(temp.policy.serviceType, temp.policy.version);"
+						ng-change="addDataToFields(temp.policy.serviceType, temp.policy.version);"
+						title="Select the dropdown value driven based on Optimization Models (Optimization Policy)Dictionary selection."></select>
+				</div>
+			</div>
+		</div>
+		<div class="well">
+			<div class="form-group col-sm-12" id="DynamicTemplate">
+				<label>Optimization Model Attributes:<sup><b>*</b></sup></label><br>
+			</div>
+			</br>
+			<div class="form-group row"></div>
+		</div>
+		<br />
+		<div id="validate" style="width: 70%"></div>
+		<br>
+		<div class="modal-footer">
+			<button class="btn btn-primary" herf="javascript:void(0)"
+				ng-disabled="temp.policy.readOnly"
+				ng-click="validatePolicy(temp.policy);" title="Validate the data entered in the Policy fields.">Validate</button>
+			<button class="btn btn-success" herf="javascript:void(0)"
+				ng-disabled="savebutton" ng-disabled="temp.policy.readOnly"
+				ng-click="savePolicy(temp);" title="Save the Policy with validated data.">Save</button>
+			<button type="button" class="btn btn-default" ng-click="refresh();" title="Close the template.">Close</button>
+		</div>
+	</form>
+</div>
diff --git a/POLICY-SDK-APP/src/main/webapp/app/policyApp/policy-models/Editor/PolicyTemplates/PolicyTypeTemplate.html b/POLICY-SDK-APP/src/main/webapp/app/policyApp/policy-models/Editor/PolicyTemplates/PolicyTypeTemplate.html
index 861e9d6..3230aa1 100644
--- a/POLICY-SDK-APP/src/main/webapp/app/policyApp/policy-models/Editor/PolicyTemplates/PolicyTypeTemplate.html
+++ b/POLICY-SDK-APP/src/main/webapp/app/policyApp/policy-models/Editor/PolicyTemplates/PolicyTypeTemplate.html
@@ -2,7 +2,7 @@
   ============LICENSE_START=======================================================
   ONAP Policy Engine
   ================================================================================
-  Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+  Copyright (C) 2017-2018 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.
@@ -59,6 +59,7 @@
 									<option>ClosedLoop_PM</option>
 									<option>Micro Service</option>
 									<option>Firewall Config</option>
+									<option>Optimization</option>
 								</select>
 							</div>
 						</div>
@@ -76,6 +77,8 @@
 							ng-include="'app/policyApp/policy-models/Editor/PolicyTemplates/DCAEMicroServicePolicyTemplate.html'"></div>
 						<div ng-if="temp.policy.configPolicyType == 'Firewall Config'"
 							ng-include="'app/policyApp/policy-models/Editor/PolicyTemplates/FirewallPolicyTemplate.html'"></div>
+						<div ng-if="temp.policy.configPolicyType == 'Optimization'"
+							ng-include="'app/policyApp/policy-models/Editor/PolicyTemplates/OptimizationPolicyTemplate.html'"></div>
 					</div>
 				</form>
 			</div>
diff --git a/POLICY-SDK-APP/src/main/webapp/app/policyApp/policy-models/Editor/css/main.css b/POLICY-SDK-APP/src/main/webapp/app/policyApp/policy-models/Editor/css/main.css
index 078e829..1e6da20 100644
--- a/POLICY-SDK-APP/src/main/webapp/app/policyApp/policy-models/Editor/css/main.css
+++ b/POLICY-SDK-APP/src/main/webapp/app/policyApp/policy-models/Editor/css/main.css
@@ -103,6 +103,11 @@
 	margin-top: 10px;
 }
 
+div#HeaderDefaultValues.modal-body {	
+    position: relative;
+    padding: 30px;
+}
+
 .btn {
   box-shadow: 0 2px 5px 0 rgba(0, 0, 0, .26);
   font-weight: 500;
@@ -420,4 +425,31 @@
 .tooltip:hover .tooltiptext {
     visibility: visible;
     opacity: 1;
+}
+
+.mstooltip {
+    position: relative;
+    display: inline-block;
+    color: orange;
+    font-weight: lighter;
+}
+
+.mstooltip .tooltiptext {
+    font-weight: lighter;
+    visibility: hidden;
+    width: 150px;
+    background-color: #555;
+    color: #fff;
+    text-align: center;
+    border-radius: 6px;
+    padding: 4px 5px;
+    margin-left: 5px;
+    position: absolute;
+    bottom: 100%;
+    left: 50%;
+    z-index: 1;
+}
+
+.mstooltip:hover .tooltiptext {
+    visibility: visible;
 }
\ No newline at end of file
diff --git a/POLICY-SDK-APP/src/main/webapp/app/policyApp/policy-models/policy_Dictionary.html b/POLICY-SDK-APP/src/main/webapp/app/policyApp/policy-models/policy_Dictionary.html
index c4559a4..690f43b 100644
--- a/POLICY-SDK-APP/src/main/webapp/app/policyApp/policy-models/policy_Dictionary.html
+++ b/POLICY-SDK-APP/src/main/webapp/app/policyApp/policy-models/policy_Dictionary.html
@@ -2,7 +2,7 @@
   ============LICENSE_START=======================================================
   ONAP Policy Engine
   ================================================================================
-  Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+  Copyright (C) 2017-2018 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.
@@ -101,9 +101,12 @@
 	<!--Micro Service Policy Dictionary's-->
 	<div  ng-if="option2 == 'DCAE UUID'" ng-include = "'app/policyApp/policy-models/Dictionary/MSDcaeUUIDDictionary.html'"></div>
 	<div  ng-if="option2 == 'MicroService ConfigName'" ng-include = "'app/policyApp/policy-models/Dictionary/MSConfigNameDictionary.html'"></div>
+	<div  ng-if="option2 == 'Header Default Values'" ng-include = "'app/policyApp/policy-models/Dictionary/MSHeaderDefaultValuesDictionary.html'"></div>
 	<div  ng-if="option2 == 'MicroService Location'" ng-include = "'app/policyApp/policy-models/Dictionary/MSLocationDictionary.html'"></div>
 	<div  ng-if="option2 == 'MicroService Models'" ng-include = "'app/policyApp/policy-models/Dictionary/MSModelDictionary.html'"></div>
 	<div  ng-if="option2 == 'MicroService Dictionary'" ng-include = "'app/policyApp/policy-models/Dictionary/ModelAttributeDictionary.html'"></div>
+	<!--Optimization Policy Dictionary's-->
+	<div  ng-if="option2 == 'ONAP Optimization Models'" ng-include = "'app/policyApp/policy-models/Dictionary/OptimizationModelDictionary.html'"></div>
 	<!-- Policy Scope Dictionary's -->
 	<div  ng-if="option2 == 'Closed Loop'" ng-include = "'app/policyApp/policy-models/Dictionary/PSClosedLoopDictionary.html'"></div>
 	<div  ng-if="option2 == 'Group Policy Scope'" ng-include = "'app/policyApp/policy-models/Dictionary/PSGroupPolicyScopeDictionary.html'"></div>
@@ -120,7 +123,7 @@
 <div class="modal-dialog modal-lg">
     <div class="modal-content">
         <div class="modal-header">
-            <h2 class="font-showcase-font-name" style="color : #157bb2">Import  Dictionary's</h2>
+            <h2 class="font-showcase-font-name" style="color : #157bb2">Import Dictionary's</h2>
         </div>
         <div class="modal-body">
             <div class="fn-ebz-container">
diff --git a/POLICY-SDK-APP/src/test/java/org/onap/policy/controller/CreateDcaeMicroServiceControllerTest.java b/POLICY-SDK-APP/src/test/java/org/onap/policy/controller/CreateDcaeMicroServiceControllerTest.java
index 8d8f57b..1301d3f 100644
--- a/POLICY-SDK-APP/src/test/java/org/onap/policy/controller/CreateDcaeMicroServiceControllerTest.java
+++ b/POLICY-SDK-APP/src/test/java/org/onap/policy/controller/CreateDcaeMicroServiceControllerTest.java
@@ -158,90 +158,6 @@
 	}
 
 	/**
-	 * Run the void stringBetweenDots(String, String) method test
-	 */
-	
-	 @Test
-	public void testStringBetweenDots() {
-
-		logger.debug("testStringBetweenDots: enter");
-		
-		//expect: uniqueKeys should contain a string value 
-		CreateDcaeMicroServiceController controllerA = new CreateDcaeMicroServiceController();
-		String str = "testing\\.byCorrectWay\\.OfDATA";
-		assertEquals(1, controllerA.stringBetweenDots(str));
-		
-		//expect: uniqueKeys should not contain a string value 
-		str = "testing\byWrongtWay.\\OfDATA";
-		CreateDcaeMicroServiceController controllerB = new CreateDcaeMicroServiceController();
-	    assertEquals(0, controllerB.stringBetweenDots(str));
-	    
-		logger.debug("testStringBetweenDots: exit");
-	}
-
-	/**
-	 * Run the Map<String,String> load(String) method test
-	 */
-	
-	@Test
-	public void testLoad() {
-		
-		logger.debug("testLoad: enter");
-		
-		boolean isLocalTesting = true;
-		CreateDcaeMicroServiceController controller = new CreateDcaeMicroServiceController();
-		String fileName = null;
-		Map<String,String> result = null;
-		try {
-			ClassLoader classLoader = getClass().getClassLoader();
-			fileName = new File(classLoader.getResource("policy_tosca_tca_v1707.yml").getFile()).getAbsolutePath();
-		} catch (Exception e1) {
-			logger.error("Exception Occured while loading file"+e1);
-		}
-		if(isLocalTesting){
-			try {
-				result = controller.load(fileName);
-			} catch (IOException e) {
-				logger.error("testLoad", e);
-				result = null;
-			}
-			
-			assertTrue(result != null && !result.isEmpty());				
-			logger.debug("result : " + result);
-		}
-
-		logger.debug("testLoad: exit");
-	}
-	
-	/**
-	 * Run the void parseTosca(String) method test
-	 */
-	
-	@Test
-	public void testParseTosca() {
-		
-		logger.debug("testParseTosca: enter");
-		boolean isLocalTesting = true;
-		String fileName = null;
-		try {
-			ClassLoader classLoader = getClass().getClassLoader();
-			fileName = new File(classLoader.getResource("policy_tosca_tca_v1707.yml").getFile()).getAbsolutePath();
-		} catch (Exception e1) {
-			logger.error("Exception Occured while loading file"+e1);
-		}
-		
-		CreateDcaeMicroServiceController contoller = new CreateDcaeMicroServiceController();
-        if(isLocalTesting){
-			try {
-			    contoller.parseTosca(fileName);
-			}catch (Exception e) {
-				fail("parseTosca caused error: " + e);
-			}
-        }
-		logger.debug("testParseTosca: exit");
-	}
-
-	/**
 	 * Run the ModelAndView getDCAEMSTemplateData(HttpServletRequest,
 	 * HttpServletResponse) method test
 	 */
@@ -584,9 +500,7 @@
 			logger.error("testSetMSModelData" + e);
 			e.printStackTrace();
 		}
-	    
-		//assertTrue(false);
-		
+	    		
 		logger.debug("testSetMSModelData: exit");
 	}
 
diff --git a/POLICY-SDK-APP/src/test/java/org/onap/policy/controller/CreateOptimizationControllerTest.java b/POLICY-SDK-APP/src/test/java/org/onap/policy/controller/CreateOptimizationControllerTest.java
new file mode 100644
index 0000000..af573c6
--- /dev/null
+++ b/POLICY-SDK-APP/src/test/java/org/onap/policy/controller/CreateOptimizationControllerTest.java
@@ -0,0 +1,464 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP Policy Engine
+ * ================================================================================
+ * Copyright (C) 2018 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.controller;
+
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.servlet.ReadListener;
+import javax.servlet.ServletInputStream;
+import javax.servlet.http.HttpServletRequest;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.policy.common.logging.flexlogger.FlexLogger;
+import org.onap.policy.common.logging.flexlogger.Logger;
+import org.onap.policy.rest.adapter.PolicyRestAdapter;
+import org.onap.policy.rest.dao.CommonClassDao;
+import org.onap.policy.rest.jpa.ConfigurationDataEntity;
+import org.onap.policy.rest.jpa.OptimizationModels;
+import org.onap.policy.rest.jpa.PolicyEntity;
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.springframework.mock.web.MockHttpServletResponse;
+
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.github.fge.jackson.JsonLoader;
+
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AllOfType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AnyOfType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeDesignatorType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeValueType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.MatchType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType;
+import oasis.names.tc.xacml._3_0.core.schema.wd_17.TargetType;
+
+/**
+ * The class <code>CreateOptimizationControllerTest</code> contains tests
+ * for the class {@link <code>CreateOptimizationController</code>}*
+ *
+ * All JUnits are designed to run in the local development environment
+ * where they have write privileges and can execute time-sensitive
+ * tasks.
+ */
+public class CreateOptimizationControllerTest {
+	
+	private static Logger logger = FlexLogger.getLogger(CreateOptimizationControllerTest.class);
+	private static CommonClassDao commonClassDao;
+	private String jsonString = null;
+	private String configBodyString = null;
+	private HttpServletRequest request = null;
+	
+	@Before
+	public void setUp() throws Exception {
+
+		logger.info("setUp: Entering");
+        commonClassDao = mock(CommonClassDao.class);
+        List<Object> optimizationModelsData = new ArrayList<Object>();
+        OptimizationModels testData = new OptimizationModels();
+        testData.setVersion("OpenOnap-Junit");        
+        optimizationModelsData.add(testData);
+
+        // mock the getDataById() call
+        when(commonClassDao.getDataById(OptimizationModels.class, "modelName", "test")).thenReturn(optimizationModelsData);
+        
+		jsonString = "{\"policyData\": {\"error\": \"\",	\"inprocess\": false,\"model\": {\"name\": \"testingdata\", "
+				+ " \"subScopename\": \"\",\"path\": [],\"type\": \"dir\",\"size\": 0,\"date\": \"2017-04-12T21:26:57.000Z\", "
+				+ " \"version\": \"\",\"createdBy\": \"someone\",	\"modifiedBy\": \"someone\",	\"content\": \"\",\"recursive\": false},"
+				+ " \"tempModel\": {\"name\": \"testingdata\",\"subScopename\": \"\"	},"
+				+ " \"policy\": {\"policyType\": \"Config\",\"configPolicyType\": \"OOF\",\"policyName\": \"testPolicy\", "
+				+ "	\"policyDescription\": \"testing input\", \"onapName\": \"test\",\"guard\": \"False\",\"riskType\": \"Risk12345\",\"riskLevel\": \"2\","
+				+ "	\"priority\": \"6\",\"serviceType\": \"DkatPolicyBody\",\"version\": \"1707.41.02\",\"ruleGridData\": [	[\"fileId\"]],\"ttlDate\": null}}, "
+				+ "	\"policyJSON\": {\"pmTableName\": \"test\",	\"dmdTopic\": \"1\",\"fileId\": \"56\"} }";
+
+		configBodyString = "{\"service\":\"PolicyEntityTest\",\"policyName\":\"someone\",\"description\":\"test\",\"templateVersion\":\"1607\",\"version\":\"HD\","
+				+ "\"priority\":\"2\",\"content\":{\"lastPolled\":\"1\",\"boolen-test\":\"true\",\"created\":\"test\",\"retiredDate\":\"test\",\"scope\":\"TEST_PLACEMENT_VDHV\","
+				+ "\"name\":\"test\",\"lastModified\":\"test\",\"state\":\"CREATED\",\"type\":\"CONFIG\",\"intent\":\"test\",\"target\":\"TEST\"}}";
+
+		request = mock(HttpServletRequest.class);        
+        BufferedReader br = new BufferedReader(new StringReader(jsonString));
+        // mock the getReader() call
+        when(request.getReader()).thenReturn(br);   
+        
+        logger.info("setUp: exit");
+	}
+		
+	
+	/**
+	 * Run the PolicyRestAdapter setDataToPolicyRestAdapter(PolicyRestAdapter,
+	 * JsonNode) method test
+	 */
+	
+	@Test
+	public void testSetDataToPolicyRestAdapter() {
+		
+		logger.debug("testSetDataToPolicyRestAdapter: enter");
+		
+		CreateOptimizationController controller = new CreateOptimizationController();
+		CreateOptimizationController.setCommonClassDao(commonClassDao);
+	
+		JsonNode root = null;
+		ObjectMapper mapper = new ObjectMapper();
+		mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+		PolicyRestAdapter policyData = null;
+		try {
+			root = JsonLoader.fromString(jsonString);
+			policyData = (PolicyRestAdapter)mapper.readValue(root.get("policyData").get("policy").toString(), PolicyRestAdapter.class);
+		} catch (Exception e) {
+			logger.error("testSetDataToPolicyRestAdapter", e);			
+		} 
+		
+		PolicyRestAdapter result = controller.setDataToPolicyRestAdapter(policyData,	root);
+		assertTrue(result != null && result.getJsonBody() != null && !result.getJsonBody().isEmpty());
+	
+		logger.debug("result.getJsonBody() : " + result.getJsonBody());
+		logger.debug("testSetDataToPolicyRestAdapter: exit");
+	}
+	
+
+	/**
+	 * Run the ModelAndView getOptimizationTemplateData(HttpServletRequest,
+	 * HttpServletResponse) method test
+	 */
+	
+	 @Test
+	public void testGetOptimizationTemplateData() {
+		
+		logger.debug("testGetOptimizationTemplateData: enter");
+		
+		CreateOptimizationController controller = new CreateOptimizationController();
+		MockHttpServletResponse response =  new MockHttpServletResponse();
+		String modelJson = "{\"policyData\":\"testPolicyBody\"}";
+		try {	
+			
+			CreateOptimizationController.setCommonClassDao(commonClassDao);
+	        
+	        BufferedReader br = new BufferedReader(new StringReader(modelJson));
+	        // mock the getReader() call
+	        when(request.getReader()).thenReturn(br); 
+	        
+	        List<Object> optimizationModelsData = new ArrayList<Object>();
+	        OptimizationModels testData = new OptimizationModels();
+	        testData.setVersion("1707.4.1.2-Junit");        
+	        optimizationModelsData.add(testData);
+	        // mock the getDataById() call with the same MS model name 
+	        when(commonClassDao.getDataById(OptimizationModels.class, "modelName", "testPolicyBody")).thenReturn(optimizationModelsData);	
+	        
+			controller.getOptimizationTemplateData(request, response);
+			
+			assertTrue( response.getContentAsString() != null && response.getContentAsString().contains("optimizationModelData"));
+			
+			logger.debug("response: "  + response.getContentAsString());
+			
+		} catch (Exception e) {
+			logger.error("testGetOptimizationTemplateData", e);
+		}		
+	
+		logger.debug("testGetOptimizationTemplateData: exit");
+	}
+
+	/**
+	 * Run the ModelAndView getModelServiceVersionData(HttpServletRequest,
+	 * HttpServletResponse) method test
+	 */
+	
+	@Test
+	public void testGetModelServiceVersionData() {
+		
+		logger.debug("testGetModelServiceVersionData: enter");
+		
+		CreateOptimizationController controller = new CreateOptimizationController();
+		MockHttpServletResponse response =  new MockHttpServletResponse();
+		String modelJson = "{\"policyData\":\"TestPolicyBody\"}";
+		try {
+			
+			CreateOptimizationController.setCommonClassDao(commonClassDao);
+	        
+	        BufferedReader br = new BufferedReader(new StringReader(modelJson));
+	        // mock the getReader() call
+	        when(request.getReader()).thenReturn(br);   
+	        
+	        List<Object> optimizationModelsData = new ArrayList<Object>();
+	        OptimizationModels testData = new OptimizationModels();
+	        testData.setVersion("1707.4.1.2-Junit");        
+	        optimizationModelsData.add(testData);
+
+	        // mock the getDataById() call with the same MS model name 
+	        when(commonClassDao.getDataById(OptimizationModels.class, "modelName", "TestPolicyBody")).thenReturn(optimizationModelsData);
+			controller.getModelServiceVersionData(request, response);	
+						
+			assertTrue( response.getContentAsString() != null && response.getContentAsString().contains("1707.4.1.2-Junit"));
+			
+			logger.debug("response: "  + response.getContentAsString());
+			
+		} catch (Exception e) {
+			logger.error("testGetModelServiceVersionData", e);
+			fail("testGetModelServiceVersionData failed due to: " + e);
+		}
+
+		logger.debug("testGetModelServiceVersionData: exit");
+	}
+
+	/**
+	 * Run the void prePopulateDCAEMSPolicyData(PolicyRestAdapter,
+	 * PolicyEntity) method test
+	 */
+	
+	@Test
+	public void testPrePopulatePolicyData() {
+		
+		logger.debug("testPrePopulatePolicyData: enter");
+		
+		CreateOptimizationController controller = new CreateOptimizationController();
+	    
+	    // populate an entity object for testing
+		PolicyEntity entity = new PolicyEntity();
+		ConfigurationDataEntity configData = new ConfigurationDataEntity();
+		configData.setConfigBody(configBodyString);		
+		entity.setConfigurationData(configData);
+		
+		JsonNode root = null;
+		ObjectMapper mapper = new ObjectMapper();
+		mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+		PolicyRestAdapter restAdapter = null;
+
+		try {
+			root = JsonLoader.fromString(jsonString);
+			restAdapter = (PolicyRestAdapter)mapper.readValue(root.get("policyData").get("policy").toString(), PolicyRestAdapter.class);
+			PolicyType policyType = new PolicyType();
+			TargetType target = new TargetType(); 
+			
+			// create guard attribute 
+			AnyOfType anyOfType = new AnyOfType();			
+			AllOfType alltype = new AllOfType();
+			MatchType matchType = new MatchType();
+			// set value
+			AttributeValueType attributeValue1 = new AttributeValueType();
+			attributeValue1.getContent().add("True");
+			matchType.setAttributeValue(attributeValue1);
+            // set Id
+			AttributeDesignatorType designator = new AttributeDesignatorType();
+			designator.setAttributeId("guard");
+			matchType.setAttributeDesignator(designator);
+			alltype.getMatch().add(matchType);	
+			
+			// add a dummy MatchType object since while (matchList.size()>1 ...)
+			MatchType matchDummy = new MatchType();
+			// set value
+			AttributeValueType dummyValue = new AttributeValueType();
+			dummyValue.getContent().add("dummy");
+			matchDummy.setAttributeValue(dummyValue);
+            // set Id
+			AttributeDesignatorType designatorDummy = new AttributeDesignatorType();
+			designatorDummy.setAttributeId("dummyId");
+			matchDummy.setAttributeDesignator(designatorDummy);
+			
+			alltype.getMatch().add(matchDummy);
+			anyOfType.getAllOf().add(alltype);
+			
+			target.getAnyOf().add(anyOfType);
+			
+			// create RiskType attribute 
+			AnyOfType anyRiskType = new AnyOfType();			
+			AllOfType allRiskType = new AllOfType();
+			MatchType matchRiskType = new MatchType();
+			// set value
+			AttributeValueType riskTypeValue = new AttributeValueType();
+			riskTypeValue.getContent().add("test");
+			matchRiskType.setAttributeValue(riskTypeValue);
+            // set Id
+			AttributeDesignatorType designatorRiskType = new AttributeDesignatorType();
+			designatorRiskType.setAttributeId("RiskType");
+			matchRiskType.setAttributeDesignator(designatorRiskType);
+			allRiskType.getMatch().add(matchRiskType);	
+			
+			// add a dummy MatchType object since while (matchList.size()>1 ...)
+			MatchType matchDummy1 = new MatchType();
+			// set value
+			AttributeValueType dummy1Value = new AttributeValueType();
+			dummy1Value.getContent().add("dummy");
+			matchDummy1.setAttributeValue(dummy1Value);
+            // set Id
+			AttributeDesignatorType designatorDummy1 = new AttributeDesignatorType();
+			designatorDummy1.setAttributeId("dummyId");
+			matchDummy1.setAttributeDesignator(designatorDummy1);
+			
+			allRiskType.getMatch().add(matchDummy1);
+			
+			anyRiskType.getAllOf().add(allRiskType);
+			
+			target.getAnyOf().add(anyRiskType);
+			
+			// create RiskLevel attribute 
+			AnyOfType anyRiskLevel = new AnyOfType();			
+			AllOfType allRiskLevel = new AllOfType();
+			MatchType matchRiskLevel = new MatchType();
+			// set value
+			AttributeValueType riskLevel = new AttributeValueType();
+			riskLevel.getContent().add("3");
+			matchRiskLevel.setAttributeValue(riskLevel);
+            // set Id
+			AttributeDesignatorType designatorRiskLevel = new AttributeDesignatorType();
+			designatorRiskLevel.setAttributeId("RiskLevel");
+			matchRiskLevel.setAttributeDesignator(designatorRiskLevel);
+			allRiskLevel.getMatch().add(matchRiskLevel);
+			
+			// add a dummy MatchType object since while (matchList.size()>1 ...)
+			MatchType matchDummy2 = new MatchType();
+			// set value
+			AttributeValueType dummy2Value = new AttributeValueType();
+			dummy2Value.getContent().add("dummy");
+			matchDummy2.setAttributeValue(dummy2Value);
+            // set Id
+			AttributeDesignatorType designatorDummy2 = new AttributeDesignatorType();
+			designatorDummy2.setAttributeId("dummyId");
+			matchDummy2.setAttributeDesignator(designatorDummy2);
+			
+			allRiskLevel.getMatch().add(matchDummy2);
+			
+			anyRiskLevel.getAllOf().add(allRiskLevel);
+			target.getAnyOf().add(anyRiskLevel);
+			
+			policyType.setTarget(target);
+			
+			restAdapter.setPolicyData(policyType);
+			
+			controller.prePopulatePolicyData(restAdapter, entity);
+			
+			logger.error("restAdapter.getRiskType() : " + restAdapter.getRiskType());
+			logger.error("restAdapter.getRiskLevel() : " + restAdapter.getRiskLevel());
+			logger.error("restAdapter.getGuard() : " + restAdapter.getGuard());
+			
+			assertEquals("True", restAdapter.getGuard());
+			assertEquals("3", restAdapter.getRiskLevel());
+			assertEquals("test", restAdapter.getRiskType());
+			
+		} catch (Exception e) {
+			logger.error("testPrePopulatePolicyData", e);
+			fail("testPrePopulatePolicyData failed due to: " + e);
+		} 
+		
+		logger.debug("testPrePopulatePolicyData: exit");
+		
+	}
+	
+	/**
+	 * Run the void SetMSModelData(HttpServletRequest, HttpServletResponse)
+	 * method test
+	 */
+	
+	@Test
+	public void testSetModelData() {		
+		
+		logger.debug("testSetModelData: enter");
+
+	    HttpServletRequest request = createMock(HttpServletRequest.class);
+	    expect(request.getContentType()).andReturn("multipart/form-data; boundary=----WebKitFormBoundaryWcRUaIbC8kXgjr3p");
+	    expect(request.getMethod()).andReturn("post");
+	    expect(request.getHeader("Content-length")).andReturn("7809");
+	    
+	    expect(request.getContentLength()).andReturn(7809);
+
+	    try {
+	    	// value of fileName needs to be matched to your local directory
+	    	String fileName = "";
+	    	try {
+				ClassLoader classLoader = getClass().getClassLoader();
+				fileName = new File(classLoader.getResource("schedulerPolicies-v1707.xmi").getFile()).getAbsolutePath();
+			} catch (Exception e1) {
+				logger.error("Exception Occured while loading file"+e1);
+			}
+			expect(request.getInputStream()).andReturn(new MockServletInputStream(fileName));	    
+		    expect(request.getCharacterEncoding()).andReturn("UTF-8");
+		    expect(request.getContentLength()).andReturn(1024);
+		    replay(request);
+			
+		} catch (Exception e) {
+			logger.error("testSetModelData" + e);
+			e.printStackTrace();
+		}
+	    		
+		logger.debug("testSetModelData: exit");
+	}
+
+	/**
+	 * 
+	 * @ Get File Stream
+	 *
+	 */
+	private class MockServletInputStream extends ServletInputStream {
+
+		InputStream fis = null;
+		public MockServletInputStream(String fileName) {
+			try {
+				fis = new FileInputStream(fileName);
+			} catch (Exception genExe) {
+				genExe.printStackTrace();
+			}
+		}
+		@Override
+		public int read() throws IOException {
+			if(fis.available() > 0) {
+				return fis.read();
+			}
+			return 0;
+		}
+
+		@Override
+		public int read(byte[] bytes, int len, int size) throws IOException {
+			if(fis.available() > 0) {
+				int length = fis.read(bytes, len, size);
+				return length;
+			}
+			return -1;
+		}
+		@Override
+		public boolean isFinished() {
+			return false;
+		}
+		@Override
+		public boolean isReady() {
+			return false;
+		}
+		@Override
+		public void setReadListener(ReadListener arg0) {
+
+		}
+	}	
+	
+}
\ No newline at end of file
diff --git a/PolicyEngineAPI/src/main/java/org/onap/policy/api/AttributeType.java b/PolicyEngineAPI/src/main/java/org/onap/policy/api/AttributeType.java
index 0a46219..bb6b08d 100644
--- a/PolicyEngineAPI/src/main/java/org/onap/policy/api/AttributeType.java
+++ b/PolicyEngineAPI/src/main/java/org/onap/policy/api/AttributeType.java
@@ -42,6 +42,10 @@
 	 */
 	MICROSERVICE("microService"),
 	/**
+	 * Indicates Attributes required to create Optimization policy.
+	 */
+	OPTIMIZATION("optimization"),
+	/**
 	 * Indicates Attributes required to create settings for Decision Policy.
 	 */
 	SETTINGS("settings"),
diff --git a/PolicyEngineAPI/src/main/java/org/onap/policy/api/DictionaryType.java b/PolicyEngineAPI/src/main/java/org/onap/policy/api/DictionaryType.java
index 56b7322..e0f0264 100644
--- a/PolicyEngineAPI/src/main/java/org/onap/policy/api/DictionaryType.java
+++ b/PolicyEngineAPI/src/main/java/org/onap/policy/api/DictionaryType.java
@@ -52,6 +52,10 @@
      */
     MicroService("MicroService"),
     /**
+     * Indicates Optimization Policy Dictionaries
+     */
+    Optimization("Optimization"),
+    /**
      * Indicates Descriptive Scope Dictionaries
      */
     DescriptiveScope("DescriptiveScope"),
diff --git a/PolicyEngineAPI/src/main/java/org/onap/policy/api/ImportParameters.java b/PolicyEngineAPI/src/main/java/org/onap/policy/api/ImportParameters.java
index 3914864..51398f3 100644
--- a/PolicyEngineAPI/src/main/java/org/onap/policy/api/ImportParameters.java
+++ b/PolicyEngineAPI/src/main/java/org/onap/policy/api/ImportParameters.java
@@ -39,7 +39,8 @@
 	
 	public enum IMPORT_TYPE {
 	    MICROSERVICE,
-	    BRMSPARAM
+	    BRMSPARAM,
+	    OPTIMIZATION
 	}
 
 	/**
diff --git a/PolicyEngineAPI/src/main/java/org/onap/policy/api/PolicyConfigType.java b/PolicyEngineAPI/src/main/java/org/onap/policy/api/PolicyConfigType.java
index 2fb5d96..21861da 100644
--- a/PolicyEngineAPI/src/main/java/org/onap/policy/api/PolicyConfigType.java
+++ b/PolicyEngineAPI/src/main/java/org/onap/policy/api/PolicyConfigType.java
@@ -58,8 +58,12 @@
 	 */
 	MicroService("MS"),
 	/**
-	 * Indicates Custom Extended Policy type. 
+	 * Indicates OOF Optimization Policy. 
 	 */
+	Optimization("Optimization"),
+	/**
+	 * Indicates Custom Extended Policy type. 
+	 */	
 	Extended("EXTENDED")
 	;
 	
diff --git a/PolicyEngineClient/src/test/java/org/onap/policyengine/OptimizationPolicyJavaAPIClient.java b/PolicyEngineClient/src/test/java/org/onap/policyengine/OptimizationPolicyJavaAPIClient.java
new file mode 100644
index 0000000..090ec39
--- /dev/null
+++ b/PolicyEngineClient/src/test/java/org/onap/policyengine/OptimizationPolicyJavaAPIClient.java
@@ -0,0 +1,128 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * PolicyEngineClient
+ * ================================================================================
+ * 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.policyengine;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringReader;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.UUID;
+import javax.json.Json;
+import javax.json.JsonObject;
+import javax.json.JsonReader;
+
+import org.onap.policy.api.PolicyChangeResponse;
+import org.onap.policy.api.PolicyConfigType;
+import org.onap.policy.api.PolicyEngine;
+import org.onap.policy.api.PolicyParameters;
+import org.onap.policy.api.PolicyType;
+public class OptimizationPolicyJavaAPIClient {
+	
+/*
+ * THIS IS AN EXAMPLE JAVA CLIENT API FOR CREATE/UPDATE Optimization Policies
+ */
+//For updating a Optmization  policy set the "isEdit" flag to true.   
+//For creating a Optmization  policy set the "isEdit" flag to false.  
+static Boolean isEdit = false;
+     
+//Builds JSONObject from File  
+private static JsonObject buildJSON(File jsonInput, String jsonString) throws FileNotFoundException {
+    JsonObject json = null;;
+    JsonReader jsonReader = null;  
+    if (jsonString != null && jsonInput == null) {
+        StringReader in = null;
+            in = new StringReader(jsonString);
+            jsonReader = Json.createReader(in);
+            json = jsonReader.readObject();
+            in.close();
+    }
+    else {
+        InputStream in = null;
+        in = new FileInputStream(jsonInput);
+        jsonReader = Json.createReader(in);
+        json = jsonReader.readObject();
+        try {
+			in.close();
+		} catch (IOException e) {
+			System.err.println("Exception Occured while closing input stream"+e);
+		}
+    }
+    jsonReader.close();    
+    return json;
+}
+public static void main(String[] args) {
+		try {
+			PolicyEngine policyEngine = new PolicyEngine("config.properties");
+			PolicyParameters policyParameters = new PolicyParameters();
+			// Set Policy Type 
+			policyParameters.setPolicyConfigType(PolicyConfigType.Optimization);
+			policyParameters.setPolicyName("Mike.testOOFPolicyFromJavaClient");
+			policyParameters.setPolicyDescription("This is a sample Optimization policy");
+			policyParameters.setOnapName("OOF");
+
+			File jsonFile = null;
+			String OOFjsonString= null;
+			
+			//path where you store the json payload
+			Path file = Paths.get("/home/users/PolicyEngine/json/optimizationPolicy.json");
+			jsonFile = file.toFile();
+			
+			policyParameters.setConfigBody(buildJSON(jsonFile, OOFjsonString).toString());		
+			policyParameters.setConfigBodyType(PolicyType.JSON);
+
+			policyParameters.setRequestID(UUID.randomUUID());
+            // Set Safe Policy value for Risk Type
+			SimpleDateFormat dateformat3 = new SimpleDateFormat("dd/MM/yyyy");
+			Date date = dateformat3.parse("15/10/2016");
+			policyParameters.setTtlDate(date);
+			// Set Safe Policy value for Guard
+			policyParameters.setGuard(false);
+			// Set Safe Policy value for Risk Level
+			policyParameters.setRiskLevel("5");
+			// Set Safe Policy value for Risk Type
+			policyParameters.setRiskType("TEST");
+			
+			// API method to create or update Policy. 
+ 	        PolicyChangeResponse response = null;
+	        if (!isEdit) {
+	            response = policyEngine.createPolicy(policyParameters);
+	        } 
+	        else {	
+	        	response = policyEngine.updatePolicy(policyParameters);
+	        }
+	        
+			if(response.getResponseCode()==200){
+				System.out.println(response.getResponseMessage());
+				System.out.println("Policy Created Successfully!");
+			}else{
+				System.out.println("Error! " + response.getResponseMessage());
+			}
+		} catch (Exception e) {
+			System.err.println(e.getMessage());
+		}
+	}
+}
diff --git a/PolicyEngineUtils/src/main/java/org/onap/policy/utils/PolicyUtils.java b/PolicyEngineUtils/src/main/java/org/onap/policy/utils/PolicyUtils.java
index e17ddc6..0626385 100644
--- a/PolicyEngineUtils/src/main/java/org/onap/policy/utils/PolicyUtils.java
+++ b/PolicyEngineUtils/src/main/java/org/onap/policy/utils/PolicyUtils.java
@@ -158,6 +158,21 @@
     } 
     
     /**
+     * Validate a field (accepts Dash) if it contains unacceptable policy input and return "success" if good. 
+     * 
+     * @param field
+     * @return
+     */
+    public static String  policySpecialCharWithDashValidator(String field){
+        String error;
+        if ("".equals(field) || !field.matches("^[a-zA-Z0-9_-]*$")) {
+            error = "The Value in Required Field will allow only '{0-9}, {a-z}, {A-Z}, _, -' following set of Combinations";
+            return error;
+        }
+        return SUCCESS;   
+    } 
+    
+    /**
      * Validate the XACML description tag and return "success" if good. 
      * 
      * @param field
diff --git a/packages/base/src/files/install/mysql/data/180601_downgrade_script.sql b/packages/base/src/files/install/mysql/data/180601_downgrade_script.sql
new file mode 100644
index 0000000..593f3ac
--- /dev/null
+++ b/packages/base/src/files/install/mysql/data/180601_downgrade_script.sql
@@ -0,0 +1,24 @@
+/*-
+* ============LICENSE_START=======================================================
+* ONAP Policy Engine
+* ================================================================================
+* Copyright (C) 2018 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=========================================================
+*/
+use onap_sdk;
+drop table if exists optimizationmodels;
+drop table if exists microserviceheaderdefaults;
+
+ALTER TABLE `onap_sdk`.`microservicemodels` DROP `dataOrderInfo`;
\ No newline at end of file
diff --git a/packages/base/src/files/install/mysql/data/180601_upgrade_script.sql b/packages/base/src/files/install/mysql/data/180601_upgrade_script.sql
new file mode 100644
index 0000000..070feee
--- /dev/null
+++ b/packages/base/src/files/install/mysql/data/180601_upgrade_script.sql
@@ -0,0 +1,53 @@
+/*-
+* ============LICENSE_START=======================================================
+* ONAP Policy Engine
+* ================================================================================
+* Copyright (C) 2018 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=========================================================
+*/
+use onap_sdk;
+
+drop table if exists `onap_sdk`.`optimizationmodels`;
+create table `onap_sdk`.`optimizationmodels` (
+`id` int(11) not null auto_increment,
+`modelname` varchar(767) not null,
+`description` varchar(1024) default null,
+`dependency` varchar(1024) default null,
+`imported_by` varchar(45) not null,
+`attributes` longtext,
+`ref_attributes` longtext,
+`sub_attributes` longtext,
+`version` varchar(45) default null,
+`annotation` longtext,
+`enumValues` longtext, 
+`dataOrder` varchar(2000) DEFAULT NULL,
+primary key (`id`),
+unique key `optimizationmodels_uniq` (`modelname`,`version`)
+);
+
+drop table if exists `onap_sdk`.`MicroServiceHeaderDefaults`;
+CREATE TABLE `onap_sdk`.`MicroServiceHeaderDefaults` (
+  `ID` int(11) NOT NULL AUTO_INCREMENT,
+  `onapName` varchar(255) DEFAULT NULL,
+  `guard` varchar(255) DEFAULT NULL,
+  `priority` varchar(3) DEFAULT NULL,
+  `riskType` varchar(255) DEFAULT NULL,  
+  `riskLevel` varchar(3) DEFAULT NULL,   
+  `modelName` varchar(1024) NOT NULL,
+  PRIMARY KEY (`ID`)
+);
+
+ALTER TABLE `onap_sdk`.`microservicemodels` 
+ADD COLUMN `dataOrderInfo` VARCHAR(2000) NULL DEFAULT 'Null' AFTER `enumValues`;
diff --git a/packages/base/src/files/install/servers/console/bin/xacml.admin.properties b/packages/base/src/files/install/servers/console/bin/xacml.admin.properties
index e0f760b..a890a29 100644
--- a/packages/base/src/files/install/servers/console/bin/xacml.admin.properties
+++ b/packages/base/src/files/install/servers/console/bin/xacml.admin.properties
@@ -159,6 +159,7 @@
 xacml.rest.closedLoopPM=OpenSource.version.1
 xacml.rest.microServices=OpenSource.version.1
 xacml.rest.firewallPolicy=OpenSource.version.1
+xacml.rest.optimization=OpenSource.version.1
 
 #***Properties for IntegrityMonitor integration defined in XACMLRestProperties.java***
 #The name of the Admin.  Must be unique across the system