Add Create loop dialog

Add create loop dialog and backend part associated (this is based on this PR https://gerrit.onap.org/r/c/clamp/+/102156)

Issue-ID: CLAMP-587

Change-Id: I58524bc2d5bfbf5ca5a3acf5c59823df06fd4cd9
Signed-off-by: sebdet <sebastien.determe@intl.att.com>
diff --git a/docs/swagger/swagger.pdf b/docs/swagger/swagger.pdf
index d9acf9d..18a6316 100644
--- a/docs/swagger/swagger.pdf
+++ b/docs/swagger/swagger.pdf
Binary files differ
diff --git a/src/main/java/org/onap/clamp/clds/client/PolicyEngineServices.java b/src/main/java/org/onap/clamp/clds/client/PolicyEngineServices.java
index b3fcb6f..44abc9d 100644
--- a/src/main/java/org/onap/clamp/clds/client/PolicyEngineServices.java
+++ b/src/main/java/org/onap/clamp/clds/client/PolicyEngineServices.java
@@ -25,10 +25,8 @@
 
 import com.att.eelf.configuration.EELFLogger;
 import com.att.eelf.configuration.EELFManager;
-
 import com.google.gson.JsonArray;
 import com.google.gson.JsonObject;
-
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.LinkedHashMap;
@@ -38,27 +36,21 @@
 import org.apache.camel.CamelContext;
 import org.apache.camel.Exchange;
 import org.apache.camel.builder.ExchangeBuilder;
-import org.json.simple.parser.ParseException;
 import org.onap.clamp.clds.config.ClampProperties;
 import org.onap.clamp.clds.sdc.controller.installer.BlueprintMicroService;
 import org.onap.clamp.clds.util.JsonUtils;
 import org.onap.clamp.loop.template.PolicyModel;
-import org.onap.clamp.loop.template.PolicyModelId;
 import org.onap.clamp.loop.template.PolicyModelsService;
 import org.onap.clamp.policy.pdpgroup.PdpGroup;
-
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 import org.yaml.snakeyaml.Yaml;
 
 
-
-
 /**
  * The class implements the communication with the Policy Engine to retrieve
  * policy models (tosca). It mainly delegates the physical calls to Camel
  * engine.
- *
  */
 @Component
 public class PolicyEngineServices {
@@ -76,16 +68,15 @@
     /**
      * Default constructor.
      *
-     * @param camelContext Camel context bean
-     * @param clampProperties ClampProperties bean
-     * @param policyModelsSService policyModel repository bean
+     * @param camelContext        Camel context bean
+     * @param clampProperties     ClampProperties bean
      * @param policyModelsService policyModel service
      */
     @Autowired
     public PolicyEngineServices(CamelContext camelContext, ClampProperties clampProperties,
-                                PolicyModelsService policyModelsSService) {
+                                PolicyModelsService policyModelsService) {
         this.camelContext = camelContext;
-        this.policyModelsService = policyModelsSService;
+        this.policyModelsService = policyModelsService;
         if (clampProperties.getStringValue(POLICY_RETRY_LIMIT) != null) {
             retryLimit = Integer.parseInt(clampProperties.getStringValue(POLICY_RETRY_LIMIT));
         }
@@ -97,7 +88,7 @@
     /**
      * This method query Policy engine and create a PolicyModel object with type and version.
      *
-     * @param policyType The policyType id
+     * @param policyType    The policyType id
      * @param policyVersion The policy version of that type
      * @return A PolicyModel created from policyEngine data
      */
@@ -130,7 +121,8 @@
         List<LinkedHashMap<String, Object>> policyTypesList = (List<LinkedHashMap<String, Object>>) loadedYaml
                 .get("policy_types");
         policyTypesList.parallelStream().forEach(policyType -> {
-            Map.Entry<String, Object> policyTypeEntry = (Map.Entry<String, Object>) new ArrayList(policyType.entrySet()).get(0);
+            Map.Entry<String, Object> policyTypeEntry =
+                    (Map.Entry<String, Object>) new ArrayList(policyType.entrySet()).get(0);
 
             policyModelsService.createPolicyInDbIfNeeded(
                     createPolicyModelFromPolicyEngine(policyTypeEntry.getKey(),
@@ -141,31 +133,34 @@
     /**
      * This method can be used to download all policy types + data types defined in
      * policy engine.
-     * 
+     *
      * @return A yaml containing all policy Types and all data types
      */
     public String downloadAllPolicies() {
-        return callCamelRoute(ExchangeBuilder.anExchange(camelContext).build(), "direct:get-all-policy-models", "Get all policies");
+        return callCamelRoute(ExchangeBuilder.anExchange(camelContext).build(), "direct:get-all-policy-models",
+                "Get all policies");
     }
 
     /**
      * This method can be used to download a policy tosca model on the engine.
-     * 
+     *
      * @param policyType    The policy type (id)
      * @param policyVersion The policy version
      * @return A string with the whole policy tosca model
      */
     public String downloadOnePolicy(String policyType, String policyVersion) {
         return callCamelRoute(ExchangeBuilder.anExchange(camelContext).withProperty("policyModelName", policyType)
-                .withProperty("policyModelVersion", policyVersion).build(), "direct:get-policy-model", "Get one policy");
+                        .withProperty("policyModelVersion", policyVersion).build(), "direct:get-policy-model",
+                "Get one policy");
     }
 
     /**
      * This method can be used to download all Pdp Groups data from policy engine.
-     * 
      */
     public void downloadPdpGroups() {
-        String responseBody = callCamelRoute(ExchangeBuilder.anExchange(camelContext).build(), "direct:get-all-pdp-groups", "Get Pdp Groups");
+        String responseBody =
+                callCamelRoute(ExchangeBuilder.anExchange(camelContext).build(), "direct:get-all-pdp-groups",
+                        "Get Pdp Groups");
 
         if (responseBody == null || responseBody.isEmpty()) {
             logger.warn("getPdpGroups returned by policy engine could not be decoded, as it's null or empty");
diff --git a/src/main/java/org/onap/clamp/clds/config/CldsUserJsonDecoder.java b/src/main/java/org/onap/clamp/clds/config/CldsUserJsonDecoder.java
index 626227e..a7ef107 100644
--- a/src/main/java/org/onap/clamp/clds/config/CldsUserJsonDecoder.java
+++ b/src/main/java/org/onap/clamp/clds/config/CldsUserJsonDecoder.java
@@ -26,14 +26,12 @@
 package org.onap.clamp.clds.config;
 
 import com.google.gson.JsonParseException;
-
 import java.io.IOException;
 import java.io.InputStream;
 import java.nio.charset.StandardCharsets;
-
 import org.apache.commons.io.IOUtils;
-import org.onap.clamp.clds.exception.CldsUsersException;
 import org.onap.clamp.authorization.CldsUser;
+import org.onap.clamp.clds.exception.CldsUsersException;
 import org.onap.clamp.clds.util.JsonUtils;
 
 public class CldsUserJsonDecoder {
diff --git a/src/main/java/org/onap/clamp/clds/config/DefaultUserConfiguration.java b/src/main/java/org/onap/clamp/clds/config/DefaultUserConfiguration.java
index a451586..1261a5e 100644
--- a/src/main/java/org/onap/clamp/clds/config/DefaultUserConfiguration.java
+++ b/src/main/java/org/onap/clamp/clds/config/DefaultUserConfiguration.java
@@ -27,12 +27,10 @@
 
 import com.att.eelf.configuration.EELFLogger;
 import com.att.eelf.configuration.EELFManager;
-
 import java.io.IOException;
-
+import org.onap.clamp.authorization.CldsUser;
 import org.onap.clamp.clds.exception.CldsConfigException;
 import org.onap.clamp.clds.exception.CldsUsersException;
-import org.onap.clamp.authorization.CldsUser;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.context.annotation.Configuration;
diff --git a/src/main/java/org/onap/clamp/clds/util/drawing/ClampGraphBuilder.java b/src/main/java/org/onap/clamp/clds/util/drawing/ClampGraphBuilder.java
index 7edf6c1..8e3b06a 100755
--- a/src/main/java/org/onap/clamp/clds/util/drawing/ClampGraphBuilder.java
+++ b/src/main/java/org/onap/clamp/clds/util/drawing/ClampGraphBuilder.java
@@ -88,12 +88,10 @@
     public ClampGraphBuilder addLoopElementModel(LoopElementModel loopElementModel) {
         if (LoopElementModel.MICRO_SERVICE_TYPE.equals(loopElementModel.getLoopElementType())) {
             microServices.add(new MicroServicePolicy(loopElementModel.getName(),
-                    loopElementModel.getPolicyModels().first(),
-                    false,
-                    null));
+                    loopElementModel.getPolicyModels().first(), false, loopElementModel));
         } else if (LoopElementModel.OPERATIONAL_POLICY_TYPE.equals(loopElementModel.getLoopElementType())) {
             policies.add(new OperationalPolicy(loopElementModel.getName(), null, null,
-                    loopElementModel.getPolicyModels().first()));
+                    loopElementModel.getPolicyModels().first(), loopElementModel));
         }
         return this;
     }
diff --git a/src/main/java/org/onap/clamp/clds/util/drawing/Painter.java b/src/main/java/org/onap/clamp/clds/util/drawing/Painter.java
index af62d84..5ec59db 100755
--- a/src/main/java/org/onap/clamp/clds/util/drawing/Painter.java
+++ b/src/main/java/org/onap/clamp/clds/util/drawing/Painter.java
@@ -83,7 +83,7 @@
 
         for (MicroServicePolicy ms : microServices) {
             ib.arrow().rectangle(ms.getName(),
-                    RectTypes.MICROSERVICE, ms.getPolicyModel().getPolicyAcronym());
+                    RectTypes.MICROSERVICE, ms.getPolicyModel().getPolicyAcronym()).arrow();
         }
         for (OperationalPolicy policy : policies) {
             ib.arrow().rectangle(policy.getName(), RectTypes.POLICY, policy.getPolicyModel().getPolicyAcronym())
diff --git a/src/main/java/org/onap/clamp/loop/Loop.java b/src/main/java/org/onap/clamp/loop/Loop.java
index 676626a..b3fe58f 100644
--- a/src/main/java/org/onap/clamp/loop/Loop.java
+++ b/src/main/java/org/onap/clamp/loop/Loop.java
@@ -60,6 +60,7 @@
 import org.onap.clamp.loop.components.external.PolicyComponent;
 import org.onap.clamp.loop.log.LoopLog;
 import org.onap.clamp.loop.service.Service;
+import org.onap.clamp.loop.template.LoopElementModel;
 import org.onap.clamp.loop.template.LoopTemplate;
 import org.onap.clamp.policy.microservice.MicroServicePolicy;
 import org.onap.clamp.policy.operational.OperationalPolicy;
@@ -155,6 +156,28 @@
         initializeExternalComponents();
     }
 
+    /**
+     * This constructor creates a loop from a loop template.
+     *
+     * @param name         The loop name
+     * @param loopTemplate The loop template from which a new loop instance must be created
+     */
+    public Loop(String name, LoopTemplate loopTemplate) {
+        this(name,"");
+        this.setLoopTemplate(loopTemplate);
+        this.setModelService(loopTemplate.getModelService());
+        loopTemplate.getLoopElementModelsUsed().forEach(element -> {
+            if (LoopElementModel.MICRO_SERVICE_TYPE.equals(element.getLoopElementModel().getLoopElementType())) {
+                this.addMicroServicePolicy(new MicroServicePolicy(name,
+                        element.getLoopElementModel().getPolicyModels().first(), false, element.getLoopElementModel()));
+            } else if (LoopElementModel.OPERATIONAL_POLICY_TYPE
+                    .equals(element.getLoopElementModel().getLoopElementType())) {
+                this.addOperationalPolicy(new OperationalPolicy(name, null, new JsonObject(),
+                        element.getLoopElementModel().getPolicyModels().first(), element.getLoopElementModel()));
+            }
+        });
+    }
+
     public String getName() {
         return name;
     }
diff --git a/src/main/java/org/onap/clamp/loop/LoopController.java b/src/main/java/org/onap/clamp/loop/LoopController.java
index c161c55..7b037da 100644
--- a/src/main/java/org/onap/clamp/loop/LoopController.java
+++ b/src/main/java/org/onap/clamp/loop/LoopController.java
@@ -40,16 +40,22 @@
 public class LoopController {
 
     private final LoopService loopService;
-    private static final Type OPERATIONAL_POLICY_TYPE = new TypeToken<List<OperationalPolicy>>() {}
-        .getType();
-    private static final Type MICROSERVICE_POLICY_TYPE = new TypeToken<List<MicroServicePolicy>>() {}
-        .getType();
+    private static final Type OPERATIONAL_POLICY_TYPE = new TypeToken<List<OperationalPolicy>>() {
+    }
+            .getType();
+    private static final Type MICROSERVICE_POLICY_TYPE = new TypeToken<List<MicroServicePolicy>>() {
+    }
+            .getType();
 
     @Autowired
     public LoopController(LoopService loopService) {
         this.loopService = loopService;
     }
 
+    public Loop createLoop(String loopName, String templateName) {
+        return loopService.createLoopFromTemplate(loopName, templateName);
+    }
+
     public List<String> getLoopNames() {
         return loopService.getClosedLoopNames();
     }
diff --git a/src/main/java/org/onap/clamp/loop/LoopService.java b/src/main/java/org/onap/clamp/loop/LoopService.java
index 6ea412c..34be203 100644
--- a/src/main/java/org/onap/clamp/loop/LoopService.java
+++ b/src/main/java/org/onap/clamp/loop/LoopService.java
@@ -28,6 +28,7 @@
 import java.util.Set;
 import javax.persistence.EntityNotFoundException;
 import org.apache.commons.lang3.RandomStringUtils;
+import org.onap.clamp.loop.template.LoopTemplatesService;
 import org.onap.clamp.loop.template.PolicyModel;
 import org.onap.clamp.loop.template.PolicyModelsService;
 import org.onap.clamp.policy.Policy;
@@ -53,6 +54,9 @@
     @Autowired
     private PolicyModelsService policyModelsService;
 
+    @Autowired
+    private LoopTemplatesService loopTemplateService;
+
     Loop saveOrUpdateLoop(Loop loop) {
         return loopsRepository.save(loop);
     }
@@ -70,6 +74,17 @@
     }
 
     /**
+     * Creates a Loop Instance from Loop Template Name.
+     *
+     * @param loopName Name of the Loop to be created
+     * @param templateName Loop Template to used for Loop
+     * @return Loop Instance
+     */
+    public Loop createLoopFromTemplate(String loopName, String templateName) {
+        return loopsRepository.save(new Loop(loopName,loopTemplateService.getLoopTemplate(templateName)));
+    }
+
+    /**
      * This method is used to refresh the DCAE deployment status fields.
      *
      * @param loop          The loop instance to be modified
@@ -96,7 +111,7 @@
         loop.addOperationalPolicy(
                 new OperationalPolicy(Policy.generatePolicyName("OPERATIONAL", loop.getModelService().getName(),
                         loop.getModelService().getVersion(), RandomStringUtils.randomAlphanumeric(3),
-                        RandomStringUtils.randomAlphanumeric(4)), loop, null, policyModel));
+                        RandomStringUtils.randomAlphanumeric(4)), loop, null, policyModel, null));
         return loopsRepository.save(loop);
     }
 
diff --git a/src/main/java/org/onap/clamp/loop/template/LoopTemplatesService.java b/src/main/java/org/onap/clamp/loop/template/LoopTemplatesService.java
index 2938213..09bc80f 100644
--- a/src/main/java/org/onap/clamp/loop/template/LoopTemplatesService.java
+++ b/src/main/java/org/onap/clamp/loop/template/LoopTemplatesService.java
@@ -49,6 +49,17 @@
         return loopTemplatesRepository.save(loopTemplate);
     }
 
+
+    /**
+     * Get the SVG representation of the loopTemplate.
+     *
+     * @param templateName The loopTemplate name
+     * @return The SVG representation in xml
+     */
+    public String getSvgRepresentation(String templateName) {
+        return loopTemplatesRepository.findById(templateName).orElse(new LoopTemplate()).getSvgRepresentation();
+    }
+
     public List<String> getLoopTemplateNames() {
         return loopTemplatesRepository.getAllLoopTemplateNames();
     }
diff --git a/src/main/java/org/onap/clamp/loop/template/PolicyModel.java b/src/main/java/org/onap/clamp/loop/template/PolicyModel.java
index 7334ece..66b05f6 100644
--- a/src/main/java/org/onap/clamp/loop/template/PolicyModel.java
+++ b/src/main/java/org/onap/clamp/loop/template/PolicyModel.java
@@ -35,7 +35,6 @@
 import javax.persistence.IdClass;
 import javax.persistence.ManyToMany;
 import javax.persistence.Table;
-
 import org.hibernate.annotations.Type;
 import org.hibernate.annotations.TypeDef;
 import org.hibernate.annotations.TypeDefs;
@@ -72,7 +71,7 @@
      */
     @Id
     @Expose
-    @Column(name = "version",nullable = false)
+    @Column(name = "version", nullable = false)
     private String version;
 
     @Column(columnDefinition = "MEDIUMTEXT", name = "policy_tosca")
@@ -198,17 +197,17 @@
     /**
      * Constructor.
      *
-     * @param policyType The policyType (referenced in the blueprint
+     * @param policyType       The policyType (referenced in the blueprint
      * @param policyModelTosca The policy tosca model in yaml
-     * @param version the version like 1.0.0
-     * @param policyAcronym Subtype for policy if it exists (could be used by UI)
+     * @param version          the version like 1.0.0
+     * @param policyAcronym    Subtype for policy if it exists (could be used by UI)
      */
     public PolicyModel(String policyType, String policyModelTosca, String version,
-        String policyAcronym) {
+                       String policyAcronym) {
         this.policyModelType = policyType;
         this.policyModelTosca = policyModelTosca;
         this.version = version;
-        this.policyAcronym=policyAcronym;
+        this.policyAcronym = policyAcronym;
         if (this.policyAcronym == null) {
             this.policyAcronym = createDefaultPolicyAcronym(policyType);
         }
@@ -216,7 +215,7 @@
 
     /**
      * Constructor with acronym generated by default from policyType.
-     * 
+     *
      * @param policyType       The policyType (referenced in the blueprint
      * @param policyModelTosca The policy tosca model in yaml
      * @param version          the version like 1.0.0
diff --git a/src/main/java/org/onap/clamp/loop/template/PolicyModelsService.java b/src/main/java/org/onap/clamp/loop/template/PolicyModelsService.java
index b38be94..7e21cc3 100644
--- a/src/main/java/org/onap/clamp/loop/template/PolicyModelsService.java
+++ b/src/main/java/org/onap/clamp/loop/template/PolicyModelsService.java
@@ -52,8 +52,7 @@
     /**
      * Save or Update Policy Model.
      *
-     * @param policyModel
-     *        The policyModel
+     * @param policyModel The policyModel
      * @return The Policy Model
      */
     public PolicyModel saveOrUpdatePolicyModel(PolicyModel policyModel) {
@@ -63,8 +62,7 @@
     /**
      * Verify whether Policy Model exist by ID.
      *
-     * @param policyModelId
-     *        The policyModel Id
+     * @param policyModelId The policyModel Id
      * @return The flag indicates whether Policy Model exist
      */
     public boolean existsById(PolicyModelId policyModelId) {
@@ -157,14 +155,14 @@
         }
     }
 
-     /**
+    /**
      * Update the Pdp Group info in Policy Model DB.
      *
      * @param pdpGroupList The list of Pdp Group info received from Policy Engine
      */
     public void updatePdpGroupInfo(List<PdpGroup> pdpGroupList) {
         List<PolicyModel> policyModelList = policyModelsRepository.findAll();
-        for (PolicyModel policyModel :  policyModelList) {
+        for (PolicyModel policyModel : policyModelList) {
             JsonArray supportedPdpGroups = new JsonArray();
             for (PdpGroup pdpGroup : pdpGroupList) {
                 JsonObject supportedPdpGroup = pdpGroup.getSupportedSubgroups(policyModel.getPolicyModelType(),
@@ -175,7 +173,7 @@
             }
 
             if (supportedPdpGroups.size() > 0) {
-                JsonObject supportedPdpJson = new JsonObject ();
+                JsonObject supportedPdpJson = new JsonObject();
                 supportedPdpJson.add("supportedPdpGroups", supportedPdpGroups);
                 policyModel.setPolicyPdpGroup(supportedPdpJson);
                 policyModelsRepository.save(policyModel);
diff --git a/src/main/java/org/onap/clamp/policy/microservice/MicroServicePolicy.java b/src/main/java/org/onap/clamp/policy/microservice/MicroServicePolicy.java
index 8d9017e..75efca7 100644
--- a/src/main/java/org/onap/clamp/policy/microservice/MicroServicePolicy.java
+++ b/src/main/java/org/onap/clamp/policy/microservice/MicroServicePolicy.java
@@ -51,6 +51,7 @@
 import org.onap.clamp.clds.util.JsonUtils;
 import org.onap.clamp.dao.model.jsontype.StringJsonUserType;
 import org.onap.clamp.loop.Loop;
+import org.onap.clamp.loop.template.LoopElementModel;
 import org.onap.clamp.loop.template.PolicyModel;
 import org.onap.clamp.policy.Policy;
 import org.yaml.snakeyaml.Yaml;
@@ -110,23 +111,17 @@
     }
 
     /**
-     * The constructor that create the json representation from the policyTosca
+     * The constructor that creates the json representation from the policyTosca
      * using the ToscaYamlToJsonConvertor.
      *
      * @param name        The name of the MicroService
      * @param policyModel The policy model of the MicroService
      * @param shared      The flag indicate whether the MicroService is shared
-     * @param usedByLoops The list of loops that uses this MicroService
      */
-    public MicroServicePolicy(String name, PolicyModel policyModel, Boolean shared,
-                              Set<Loop> usedByLoops) {
-        this.name = name;
-        this.policyModel = policyModel;
-        this.shared = shared;
-        this.setJsonRepresentation(JsonUtils.GSON_JPA_MODEL
+    public MicroServicePolicy(String name, PolicyModel policyModel, Boolean shared, LoopElementModel loopElementModel) {
+        this(name,policyModel,shared,JsonUtils.GSON_JPA_MODEL
                 .fromJson(new ToscaYamlToJsonConvertor().parseToscaYaml(policyModel.getPolicyModelTosca(),
-                        policyModel.getPolicyModelType()), JsonObject.class));
-        this.usedByLoops = usedByLoops;
+                        policyModel.getPolicyModelType()), JsonObject.class),loopElementModel);
     }
 
     private JsonObject createJsonFromPolicyTosca() {
@@ -138,21 +133,20 @@
     /**
      * The constructor that does not make use of ToscaYamlToJsonConvertor but take
      * the jsonRepresentation instead.
-     *
      * @param name               The name of the MicroService
      * @param policyModel        The policy model type of the MicroService
      * @param shared             The flag indicate whether the MicroService is
-     *                           shared
+ *                           shared
      * @param jsonRepresentation The UI representation in json format
-     * @param usedByLoops        The list of loops that uses this MicroService
+     * @param loopElementModel The loop element model from which this instance should be created
      */
     public MicroServicePolicy(String name, PolicyModel policyModel, Boolean shared,
-                              JsonObject jsonRepresentation, Set<Loop> usedByLoops) {
+                              JsonObject jsonRepresentation, LoopElementModel loopElementModel) {
         this.name = name;
         this.policyModel = policyModel;
         this.shared = shared;
-        this.usedByLoops = usedByLoops;
         this.setJsonRepresentation(jsonRepresentation);
+        this.setLoopElementModel(loopElementModel);
     }
 
     @Override
diff --git a/src/main/java/org/onap/clamp/policy/microservice/MicroServicePolicyService.java b/src/main/java/org/onap/clamp/policy/microservice/MicroServicePolicyService.java
index b17bf1a..2af8ec7 100644
--- a/src/main/java/org/onap/clamp/policy/microservice/MicroServicePolicyService.java
+++ b/src/main/java/org/onap/clamp/policy/microservice/MicroServicePolicyService.java
@@ -23,12 +23,9 @@
 
 package org.onap.clamp.policy.microservice;
 
-import com.google.common.collect.Sets;
-
 import java.util.List;
 import java.util.Set;
 import java.util.stream.Collectors;
-
 import org.onap.clamp.loop.Loop;
 import org.onap.clamp.policy.PolicyService;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -66,7 +63,7 @@
         return repository.save(
                 repository.findById(policy.getName()).map(p -> updateMicroservicePolicyProperties(p, policy, loop))
                         .orElse(new MicroServicePolicy(policy.getName(), policy.getPolicyModel(),
-                                policy.getShared(), policy.getJsonRepresentation(), Sets.newHashSet(loop))));
+                                policy.getShared(), policy.getJsonRepresentation(),null)));
     }
 
     private MicroServicePolicy updateMicroservicePolicyProperties(MicroServicePolicy oldPolicy,
@@ -84,7 +81,6 @@
      * @param microServicePolicy The micro service policy
      * @param deploymentId       The deployment ID as returned by DCAE
      * @param deploymentUrl      The Deployment URL as returned by DCAE
-     * @throws MicroServicePolicy doesn't exist in DB
      */
     public void updateDcaeDeploymentFields(MicroServicePolicy microServicePolicy, String deploymentId,
             String deploymentUrl) {
diff --git a/src/main/java/org/onap/clamp/policy/operational/OperationalPolicy.java b/src/main/java/org/onap/clamp/policy/operational/OperationalPolicy.java
index 0825ea9..52b8772 100644
--- a/src/main/java/org/onap/clamp/policy/operational/OperationalPolicy.java
+++ b/src/main/java/org/onap/clamp/policy/operational/OperationalPolicy.java
@@ -55,6 +55,7 @@
 import org.hibernate.annotations.TypeDefs;
 import org.onap.clamp.dao.model.jsontype.StringJsonUserType;
 import org.onap.clamp.loop.Loop;
+import org.onap.clamp.loop.template.LoopElementModel;
 import org.onap.clamp.loop.template.PolicyModel;
 import org.onap.clamp.policy.Policy;
 import org.yaml.snakeyaml.DumperOptions;
@@ -93,18 +94,20 @@
 
     /**
      * The constructor.
-     *
-     * @param name               The name of the operational policy
+     *  @param name               The name of the operational policy
      * @param loop               The loop that uses this operational policy
      * @param configurationsJson The operational policy property in the format of
-     *                           json
+ *                           json
      * @param policyModel        The policy model associated if any, can be null
+     * @param loopElementModel The loop element from which this instance is supposed to be created
      */
-    public OperationalPolicy(String name, Loop loop, JsonObject configurationsJson, PolicyModel policyModel) {
+    public OperationalPolicy(String name, Loop loop, JsonObject configurationsJson, PolicyModel policyModel,
+                             LoopElementModel loopElementModel) {
         this.name = name;
         this.loop = loop;
         this.setPolicyModel(policyModel);
         this.setConfigurationsJson(configurationsJson);
+        this.setLoopElementModel(loopElementModel);
         LegacyOperationalPolicy.preloadConfiguration(configurationsJson, loop);
         try {
             this.setJsonRepresentation(
diff --git a/src/main/java/org/onap/clamp/policy/operational/OperationalPolicyService.java b/src/main/java/org/onap/clamp/policy/operational/OperationalPolicyService.java
index 174912b..cc636ba 100644
--- a/src/main/java/org/onap/clamp/policy/operational/OperationalPolicyService.java
+++ b/src/main/java/org/onap/clamp/policy/operational/OperationalPolicyService.java
@@ -52,7 +52,7 @@
                                 .map(p -> setConfigurationJson(p, policy.getConfigurationsJson()))
                                 .orElse(new OperationalPolicy(policy.getName(), loop,
                                         policy.getConfigurationsJson(),
-                                        policy.getPolicyModel())))
+                                        policy.getPolicyModel(), null)))
                 .collect(Collectors.toSet());
     }
 
diff --git a/src/main/resources/META-INF/resources/swagger.html b/src/main/resources/META-INF/resources/swagger.html
index 0138d9a..74322f3 100644
--- a/src/main/resources/META-INF/resources/swagger.html
+++ b/src/main/resources/META-INF/resources/swagger.html
@@ -3758,7 +3758,7 @@
 </div>
 <div id="footer">
 <div id="footer-text">
-Last updated 2019-05-27 14:30:20 CEST
+Last updated 2020-02-12 02:20:53 PST
 </div>
 </div>
 </body>
diff --git a/src/main/resources/clds/camel/rest/clamp-api-v2.xml b/src/main/resources/clds/camel/rest/clamp-api-v2.xml
index 1f92726..280b808 100644
--- a/src/main/resources/clds/camel/rest/clamp-api-v2.xml
+++ b/src/main/resources/clds/camel/rest/clamp-api-v2.xml
@@ -612,7 +612,40 @@
 				</doTry>
 			</route>
 		</put>
-
+		<post
+				uri="/v2/loop/create/{loopName}?templateName={templateName}"
+				outType="org.onap.clamp.loop.Loop" consumes="application/json"
+				produces="application/json">
+			<route>
+				<removeHeaders
+						pattern="*"
+						excludePattern="loopName|templateName" />
+				<doTry>
+					<to
+							uri="bean:org.onap.clamp.flow.log.FlowLogOperation?method=startLog(*, 'Create Loop')" />
+					<to
+							uri="bean:org.onap.clamp.authorization.AuthorizationController?method=authorize(*,'cl','','update')" />
+					<to
+							uri="bean:org.onap.clamp.loop.LoopController?method=createLoop(${header.loopName}, ${header.templateName})" />
+					<to
+							uri="bean:org.onap.clamp.flow.log.FlowLogOperation?method=endLog()" />
+					<doCatch>
+						<exception>java.lang.Exception</exception>
+						<handled>
+							<constant>true</constant>
+						</handled>
+						<setHeader headerName="CamelHttpResponseCode">
+							<constant>500</constant>
+						</setHeader>
+						<transform>
+							<simple>ERROR: ${exception.message}</simple>
+					</transform>
+						<to
+								uri="bean:org.onap.clamp.flow.log.FlowLogOperation?method=errorLog()" />
+					</doCatch>
+				</doTry>
+			</route>
+		</post>
 		<get uri="/v2/dictionary"
 			outType="org.onap.clamp.tosca.Dictionary" produces="application/json">
 			<route>
@@ -1050,6 +1083,30 @@
 				</doTry>
 			</route>
 		</get>
+		<get uri="/v2/templates/{templateName}/svgRepresentation"
+			 outType="java.lang.String" produces="application/xml">
+			<route>
+				<removeHeaders pattern="*" excludePattern="templateName" />
+				<doTry>
+					<to
+							uri="bean:org.onap.clamp.flow.log.FlowLogOperation?method=startLog(*, 'Get SVG Representation for Loop template')" />
+					<to
+							uri="bean:org.onap.clamp.authorization.AuthorizationController?method=authorize(*,'template','','read')" />
+					<to
+							uri="bean:org.onap.clamp.loop.template.LoopTemplatesService?method=getSvgRepresentation(${header.templateName})" />
+					<to
+							uri="bean:org.onap.clamp.flow.log.FlowLogOperation?method=endLog()" />
+					<doCatch>
+						<exception>java.lang.Exception</exception>
+						<handled>
+							<constant>false</constant>
+						</handled>
+						<to
+								uri="bean:org.onap.clamp.flow.log.FlowLogOperation?method=errorLog()" />
+					</doCatch>
+				</doTry>
+			</route>
+		</get>
 		<get uri="/v2/clampInformation" outType="org.onap.clamp.clds.model.ClampInformation"
 			 produces="application/json">
 			<to
diff --git a/src/test/java/org/onap/clamp/clds/util/drawing/ClampGraphBuilderTest.java b/src/test/java/org/onap/clamp/clds/util/drawing/ClampGraphBuilderTest.java
index 63209e9..2ccecf3 100644
--- a/src/test/java/org/onap/clamp/clds/util/drawing/ClampGraphBuilderTest.java
+++ b/src/test/java/org/onap/clamp/clds/util/drawing/ClampGraphBuilderTest.java
@@ -70,7 +70,7 @@
                 null);
 
         OperationalPolicy opPolicy = new OperationalPolicy("OperationalPolicy", new Loop(), new JsonObject(),
-                new PolicyModel("org.onap.opolicy", null, "1.0.0", "opolicy1"));
+                new PolicyModel("org.onap.opolicy", null, "1.0.0", "opolicy1"), null);
         final Set<OperationalPolicy> opPolicies = Set.of(opPolicy);
         final Set<MicroServicePolicy> microServices = Set.of(ms1, ms2);
 
diff --git a/src/test/java/org/onap/clamp/clds/util/drawing/SvgLoopGeneratorTest.java b/src/test/java/org/onap/clamp/clds/util/drawing/SvgLoopGeneratorTest.java
index aad11ad..7b83a4c 100644
--- a/src/test/java/org/onap/clamp/clds/util/drawing/SvgLoopGeneratorTest.java
+++ b/src/test/java/org/onap/clamp/clds/util/drawing/SvgLoopGeneratorTest.java
@@ -24,10 +24,8 @@
 package org.onap.clamp.clds.util.drawing;
 
 import static org.assertj.core.api.Assertions.assertThat;
-
 import com.google.gson.JsonObject;
 import java.io.IOException;
-import java.util.HashSet;
 import javax.xml.parsers.ParserConfigurationException;
 import org.junit.Test;
 import org.onap.clamp.loop.Loop;
@@ -41,12 +39,12 @@
         MicroServicePolicy ms1 =
                 new MicroServicePolicy("ms1", new PolicyModel("org.onap.ms1", "", "1.0.0", "short.ms1"),
                         false,
-                        new HashSet<Loop>());
+                        null);
         MicroServicePolicy ms2 =
                 new MicroServicePolicy("ms2", new PolicyModel("org.onap.ms2", "", "1.0.0", "short.ms2"),
-                        false, new HashSet<Loop>());
+                        false, null);
         OperationalPolicy opPolicy = new OperationalPolicy("OperationalPolicy", new Loop(), new JsonObject(),
-                new PolicyModel("org.onap.opolicy", null, "1.0.0", "short.OperationalPolicy"));
+                new PolicyModel("org.onap.opolicy", null, "1.0.0", "short.OperationalPolicy"), null);
         Loop loop = new Loop();
         loop.addMicroServicePolicy(ms1);
         loop.addMicroServicePolicy(ms2);
diff --git a/src/test/java/org/onap/clamp/loop/DcaeComponentTest.java b/src/test/java/org/onap/clamp/loop/DcaeComponentTest.java
index 57e99a3..50e2e8d 100644
--- a/src/test/java/org/onap/clamp/loop/DcaeComponentTest.java
+++ b/src/test/java/org/onap/clamp/loop/DcaeComponentTest.java
@@ -28,7 +28,6 @@
 import com.google.gson.Gson;
 import com.google.gson.JsonObject;
 import java.io.IOException;
-import java.util.HashSet;
 import java.util.List;
 import org.apache.camel.Exchange;
 import org.apache.camel.Message;
@@ -55,7 +54,7 @@
 
         MicroServicePolicy microServicePolicy = new MicroServicePolicy("configPolicyTest", new PolicyModel("policy1",
                 "tosca_definitions_version: tosca_simple_yaml_1_0_0","1.0.0"), true,
-                new Gson().fromJson("{\"configtype\":\"json\"}", JsonObject.class), new HashSet<>());
+                new Gson().fromJson("{\"configtype\":\"json\"}", JsonObject.class), null);
         microServicePolicy.setConfigurationsJson(new Gson().fromJson("{\"param1\":\"value1\"}", JsonObject.class));
 
         loopTest.addMicroServicePolicy(microServicePolicy);
diff --git a/src/test/java/org/onap/clamp/loop/DeployFlowTestItCase.java b/src/test/java/org/onap/clamp/loop/DeployFlowTestItCase.java
index 4fd78d1..3c2ce17 100644
--- a/src/test/java/org/onap/clamp/loop/DeployFlowTestItCase.java
+++ b/src/test/java/org/onap/clamp/loop/DeployFlowTestItCase.java
@@ -29,7 +29,6 @@
 import com.google.gson.JsonObject;
 import com.google.gson.JsonSyntaxException;
 import java.io.IOException;
-import java.util.HashSet;
 import java.util.Set;
 import javax.transaction.Transactional;
 import org.apache.camel.CamelContext;
@@ -298,7 +297,7 @@
         policyModelsService.saveOrUpdatePolicyModel(policyModel);
         MicroServicePolicy microService = new MicroServicePolicy(name, policyModel,
                 shared,
-                gson.fromJson(jsonRepresentation, JsonObject.class), new HashSet<>());
+                gson.fromJson(jsonRepresentation, JsonObject.class), null);
 
         microService.setConfigurationsJson(new Gson().fromJson(jsonProperties, JsonObject.class));
         return microService;
diff --git a/src/test/java/org/onap/clamp/loop/LoopRepositoriesItCase.java b/src/test/java/org/onap/clamp/loop/LoopRepositoriesItCase.java
index fa4909c..acde66d 100644
--- a/src/test/java/org/onap/clamp/loop/LoopRepositoriesItCase.java
+++ b/src/test/java/org/onap/clamp/loop/LoopRepositoriesItCase.java
@@ -31,7 +31,6 @@
 import com.google.gson.GsonBuilder;
 import com.google.gson.JsonObject;
 import java.time.Instant;
-import java.util.HashSet;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.onap.clamp.clds.Application;
@@ -91,7 +90,7 @@
     }
 
     private OperationalPolicy getOperationalPolicy(String configJson, String name, PolicyModel policyModel) {
-        return new OperationalPolicy(name, null, new Gson().fromJson(configJson, JsonObject.class), policyModel);
+        return new OperationalPolicy(name, null, new Gson().fromJson(configJson, JsonObject.class), policyModel, null);
     }
 
     private LoopElementModel getLoopElementModel(String yaml, String name, String policyType, String createdBy,
@@ -131,7 +130,7 @@
     private MicroServicePolicy getMicroServicePolicy(String name, String jsonRepresentation, String jsonProperties,
                                                      boolean shared, PolicyModel policyModel) {
         MicroServicePolicy microService = new MicroServicePolicy(name, policyModel, shared,
-                gson.fromJson(jsonRepresentation, JsonObject.class), new HashSet<>());
+                gson.fromJson(jsonRepresentation, JsonObject.class), null);
         microService.setConfigurationsJson(new Gson().fromJson(jsonProperties, JsonObject.class));
         return microService;
     }
diff --git a/src/test/java/org/onap/clamp/loop/LoopServiceTestItCase.java b/src/test/java/org/onap/clamp/loop/LoopServiceTestItCase.java
index 5eca90c..849ca5c 100644
--- a/src/test/java/org/onap/clamp/loop/LoopServiceTestItCase.java
+++ b/src/test/java/org/onap/clamp/loop/LoopServiceTestItCase.java
@@ -46,7 +46,6 @@
 import org.onap.clamp.policy.operational.OperationalPolicyService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.test.annotation.Commit;
 import org.springframework.test.context.junit4.SpringRunner;
 
 @RunWith(SpringRunner.class)
@@ -102,7 +101,7 @@
         // given
         saveTestLoopToDb();
         OperationalPolicy operationalPolicy = new OperationalPolicy("policyName", null,
-                JsonUtils.GSON.fromJson(EXAMPLE_JSON, JsonObject.class), null);
+                JsonUtils.GSON.fromJson(EXAMPLE_JSON, JsonObject.class), null, null);
 
         // when
         Loop actualLoop = loopService.updateAndSaveOperationalPolicies(EXAMPLE_LOOP_NAME,
@@ -233,11 +232,11 @@
         JsonObject newJsonConfiguration = JsonUtils.GSON.fromJson("{}", JsonObject.class);
 
         OperationalPolicy firstOperationalPolicy = new OperationalPolicy("firstPolicyName", null,
-                JsonUtils.GSON.fromJson(EXAMPLE_JSON, JsonObject.class), null);
+                JsonUtils.GSON.fromJson(EXAMPLE_JSON, JsonObject.class), null, null);
         loopService.updateAndSaveOperationalPolicies(EXAMPLE_LOOP_NAME, Lists.newArrayList(firstOperationalPolicy));
 
         OperationalPolicy secondOperationalPolicy = new OperationalPolicy("secondPolicyName", null,
-                newJsonConfiguration, null);
+                newJsonConfiguration, null, null);
 
         // when
         firstOperationalPolicy.setConfigurationsJson(newJsonConfiguration);
@@ -264,11 +263,11 @@
         saveTestLoopToDb();
 
         OperationalPolicy firstOperationalPolicy = new OperationalPolicy("firstPolicyName", null,
-                JsonUtils.GSON.fromJson(EXAMPLE_JSON, JsonObject.class), null);
+                JsonUtils.GSON.fromJson(EXAMPLE_JSON, JsonObject.class), null, null);
         loopService.updateAndSaveOperationalPolicies(EXAMPLE_LOOP_NAME, Lists.newArrayList(firstOperationalPolicy));
 
         OperationalPolicy secondOperationalPolicy = new OperationalPolicy("policyName", null,
-                JsonUtils.GSON.fromJson("{}", JsonObject.class), null);
+                JsonUtils.GSON.fromJson("{}", JsonObject.class), null, null);
 
         // when
         Loop actualLoop = loopService.updateAndSaveOperationalPolicies(EXAMPLE_LOOP_NAME,
@@ -320,7 +319,7 @@
         loop = loopService.saveOrUpdateLoop(loop);
         // Add op policy
         OperationalPolicy operationalPolicy = new OperationalPolicy("opPolicy", null,
-                JsonUtils.GSON.fromJson(EXAMPLE_JSON, JsonObject.class), null);
+                JsonUtils.GSON.fromJson(EXAMPLE_JSON, JsonObject.class), null, null);
         loopService.updateAndSaveOperationalPolicies(EXAMPLE_LOOP_NAME, Lists.newArrayList(operationalPolicy));
 
         PolicyModel policyModel = new PolicyModel("org.policies.microPolicy",
diff --git a/src/test/java/org/onap/clamp/loop/LoopToJsonTest.java b/src/test/java/org/onap/clamp/loop/LoopToJsonTest.java
index a2a4536f..34d524a 100644
--- a/src/test/java/org/onap/clamp/loop/LoopToJsonTest.java
+++ b/src/test/java/org/onap/clamp/loop/LoopToJsonTest.java
@@ -33,7 +33,6 @@
 import com.google.gson.JsonObject;
 import com.google.gson.JsonSyntaxException;
 import java.io.IOException;
-import java.util.HashSet;
 import java.util.Random;
 import org.junit.Test;
 import org.onap.clamp.clds.util.JsonUtils;
@@ -55,7 +54,7 @@
 
     private OperationalPolicy getOperationalPolicy(String configJson, String name) {
         return new OperationalPolicy(name, null, gson.fromJson(configJson, JsonObject.class),
-                getPolicyModel("org.onap.policy.drools", "yaml", "1.0.0", "Drools", "type1"));
+                getPolicyModel("org.onap.policy.drools", "yaml", "1.0.0", "Drools", "type1"), null);
     }
 
     private Loop getLoop(String name, String svgRepresentation, String blueprint, String globalPropertiesJson,
@@ -73,7 +72,7 @@
                                                      String policyTosca, String jsonProperties, boolean shared) {
         MicroServicePolicy microService = new MicroServicePolicy(name, new PolicyModel(modelType, policyTosca, "1.0.0"),
                 shared,
-                gson.fromJson(jsonRepresentation, JsonObject.class), new HashSet<>());
+                gson.fromJson(jsonRepresentation, JsonObject.class), null);
         microService.setConfigurationsJson(new Gson().fromJson(jsonProperties, JsonObject.class));
         return microService;
     }
@@ -106,6 +105,10 @@
         return log;
     }
 
+    /**
+     * This tests a GSON encode/decode.
+     * @throws IOException In case of failure
+     */
     @Test
     public void loopGsonTest() throws IOException {
         Loop loopTest = getLoop("ControlLoopTest", "<xml></xml>", "yamlcontent", "{\"testname\":\"testvalue\"}",
@@ -146,6 +149,11 @@
         assertThat(loopTestDeserialized.getLoopTemplate()).isEqualTo(loopTemplate);
     }
 
+    /**
+     * This tests the service object GSON encode/decode.
+     *
+     * @throws IOException In case of issues
+     */
     @Test
     public void loopServiceTest() throws IOException {
         Loop loopTest2 = getLoop("ControlLoopTest", "<xml></xml>", "yamlcontent", "{\"testname\":\"testvalue\"}",
@@ -166,6 +174,11 @@
                 "blueprint", "components");
     }
 
+    /**
+     * This tests the GSON encode/decode of pdpGroup.
+     *
+     * @throws IOException In case of issues
+     */
     @Test
     public void createPoliciesPayloadPdpGroupTest() throws IOException {
         Loop loopTest = getLoop("ControlLoopTest", "<xml></xml>", "yamlcontent", "{\"testname\":\"testvalue\"}",
diff --git a/src/test/java/org/onap/clamp/loop/PolicyModelServiceItCase.java b/src/test/java/org/onap/clamp/loop/PolicyModelServiceItCase.java
index f8aadba..80545c1 100644
--- a/src/test/java/org/onap/clamp/loop/PolicyModelServiceItCase.java
+++ b/src/test/java/org/onap/clamp/loop/PolicyModelServiceItCase.java
@@ -25,6 +25,7 @@
 
 import static org.assertj.core.api.Assertions.assertThat;
 
+import com.google.gson.JsonObject;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.SortedSet;
@@ -46,8 +47,6 @@
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.test.context.junit4.SpringRunner;
 
-import com.google.gson.JsonObject;
-
 @RunWith(SpringRunner.class)
 @SpringBootTest(classes = Application.class)
 public class PolicyModelServiceItCase {
@@ -68,7 +67,7 @@
     private static final String POLICY_MODEL_TYPE_2_VERSION_2 = "2.0.0";
 
     private PolicyModel getPolicyModel(String policyType, String policyModelTosca, String version, String policyAcronym,
-            String policyVariant, String createdBy) {
+                                       String policyVariant, String createdBy) {
         PolicyModel policyModel = new PolicyModel();
         policyModel.setCreatedBy(createdBy);
         policyModel.setPolicyAcronym(policyAcronym);
@@ -110,6 +109,9 @@
                 .isEqualToIgnoringGivenFields(policyModel, "createdDate", "updatedDate", "createdBy", "updatedBy");
     }
 
+    /**
+     * This tests a getAllPolicyModelTypes get.
+     */
     @Test
     @Transactional
     public void shouldReturnAllPolicyModelTypes() {
@@ -125,6 +127,9 @@
         assertThat(policyModelTypesList).contains(policyModel1.getPolicyModelType(), policyModel2.getPolicyModelType());
     }
 
+    /**
+     * This tests a getAllPolicyModels get.
+     */
     @Test
     @Transactional
     public void shouldReturnAllPolicyModels() {
@@ -138,6 +143,9 @@
         assertThat(policyModelsService.getAllPolicyModels()).contains(policyModel1, policyModel2);
     }
 
+    /**
+     * This tests a getAllPolicyModelsByType get.
+     */
     @Test
     @Transactional
     public void shouldReturnAllModelsByType() {
@@ -152,6 +160,9 @@
                 policyModel2);
     }
 
+    /**
+     * This tests the sorting of policyModel.
+     */
     @Test
     @Transactional
     public void shouldReturnSortedSet() {
@@ -167,14 +178,17 @@
 
         SortedSet<PolicyModel> sortedSet = new TreeSet<>();
         policyModelsService.getAllPolicyModels().forEach(sortedSet::add);
-        List<PolicyModel> listToCheck = sortedSet.stream().filter(
-            policy -> policy.equals(policyModel3) || policy.equals(policyModel2) || policy.equals(policyModel1))
-                .collect(Collectors.toList());
+        List<PolicyModel> listToCheck = sortedSet.stream()
+                .filter(policy -> policy.equals(policyModel3) || policy.equals(policyModel2)
+                        || policy.equals(policyModel1)).collect(Collectors.toList());
         assertThat(listToCheck.get(0)).isEqualByComparingTo(policyModel2);
         assertThat(listToCheck.get(1)).isEqualByComparingTo(policyModel1);
         assertThat(listToCheck.get(2)).isEqualByComparingTo(policyModel3);
     }
 
+    /**
+     * This tests the pdpgroup GSON encode/decode and saving.
+     */
     @Test
     @Transactional
     public void shouldAddPdpGroupInfo() {
@@ -229,12 +243,14 @@
         policyModelsService.updatePdpGroupInfo(pdpGroupList);
 
         JsonObject res1 = policyModelsService.getPolicyModel("org.onap.testos", "1.0.0").getPolicyPdpGroup();
-        String expectedRes1 = "{\"supportedPdpGroups\":[{\"pdpGroup1\":[\"subGroup1\"]},{\"pdpGroup2\":[\"subGroup1\"]}]}";
+        String expectedRes1 =
+                "{\"supportedPdpGroups\":[{\"pdpGroup1\":[\"subGroup1\"]},{\"pdpGroup2\":[\"subGroup1\"]}]}";
         JsonObject expectedJson1 = JsonUtils.GSON.fromJson(expectedRes1, JsonObject.class);
         assertThat(res1).isEqualTo(expectedJson1);
 
         JsonObject res2 = policyModelsService.getPolicyModel("org.onap.testos2", "2.0.0").getPolicyPdpGroup();
-        String expectedRes2 = "{\"supportedPdpGroups\":[{\"pdpGroup1\":[\"subGroup1\"]},{\"pdpGroup2\":[\"subGroup1\",\"subGroup2\"]}]}";
+        String expectedRes2 =
+                "{\"supportedPdpGroups\":[{\"pdpGroup1\":[\"subGroup1\"]},{\"pdpGroup2\":[\"subGroup1\",\"subGroup2\"]}]}";
         JsonObject expectedJson2 = JsonUtils.GSON.fromJson(expectedRes2, JsonObject.class);
         assertThat(res2).isEqualTo(expectedJson2);
 
diff --git a/src/test/java/org/onap/clamp/policy/microservice/MicroServicePayloadTest.java b/src/test/java/org/onap/clamp/policy/microservice/MicroServicePayloadTest.java
index 3911494..ea12182 100644
--- a/src/test/java/org/onap/clamp/policy/microservice/MicroServicePayloadTest.java
+++ b/src/test/java/org/onap/clamp/policy/microservice/MicroServicePayloadTest.java
@@ -25,7 +25,6 @@
 
 import com.google.gson.JsonObject;
 import java.io.IOException;
-import java.util.HashSet;
 import org.junit.Test;
 import org.onap.clamp.clds.util.JsonUtils;
 import org.onap.clamp.clds.util.ResourceFileUtil;
@@ -38,7 +37,7 @@
     public void testPayloadConstruction() throws IOException {
         MicroServicePolicy policy = new MicroServicePolicy("testPolicy", new PolicyModel(
                 "onap.policies.monitoring.cdap.tca.hi.lo.app",
-            ResourceFileUtil.getResourceAsString("tosca/tosca_example.yaml"),"1.0.0"), false, new HashSet<>());
+            ResourceFileUtil.getResourceAsString("tosca/tosca_example.yaml"),"1.0.0"), false, null);
         policy.setConfigurationsJson(JsonUtils.GSON.fromJson(
             ResourceFileUtil.getResourceAsString("tosca/micro-service-policy-properties.json"), JsonObject.class));
         JSONAssert.assertEquals(ResourceFileUtil.getResourceAsString("tosca/micro-service-policy-payload.json"),
diff --git a/src/test/java/org/onap/clamp/policy/microservice/OperationalPolicyPayloadTest.java b/src/test/java/org/onap/clamp/policy/microservice/OperationalPolicyPayloadTest.java
index f42bbc1..bdc7e80 100644
--- a/src/test/java/org/onap/clamp/policy/microservice/OperationalPolicyPayloadTest.java
+++ b/src/test/java/org/onap/clamp/policy/microservice/OperationalPolicyPayloadTest.java
@@ -41,7 +41,7 @@
     public void testOperationalPolicyPayloadConstruction() throws IOException {
         JsonObject jsonConfig = new GsonBuilder().create().fromJson(
                 ResourceFileUtil.getResourceAsString("tosca/operational-policy-properties.json"), JsonObject.class);
-        OperationalPolicy policy = new OperationalPolicy("testPolicy", null, jsonConfig, null);
+        OperationalPolicy policy = new OperationalPolicy("testPolicy", null, jsonConfig, null, null);
 
         assertThat(policy.createPolicyPayloadYaml())
                 .isEqualTo(ResourceFileUtil.getResourceAsString("tosca/operational-policy-payload.yaml"));
@@ -63,7 +63,7 @@
         JsonObject jsonConfig = new GsonBuilder().create().fromJson(
                 ResourceFileUtil.getResourceAsString("tosca/operational-policy-no-guard-properties.json"),
                 JsonObject.class);
-        OperationalPolicy policy = new OperationalPolicy("testPolicy", null, jsonConfig, null);
+        OperationalPolicy policy = new OperationalPolicy("testPolicy", null, jsonConfig, null, null);
         Map<String, String> guardsMap = policy.createGuardPolicyPayloads();
         assertThat(guardsMap).isEmpty();
         assertThat(guardsMap.entrySet()).isEmpty();
@@ -73,7 +73,7 @@
     public void testGuardPolicyPayloadConstruction() throws IOException {
         JsonObject jsonConfig = new GsonBuilder().create().fromJson(
                 ResourceFileUtil.getResourceAsString("tosca/operational-policy-properties.json"), JsonObject.class);
-        OperationalPolicy policy = new OperationalPolicy("testPolicy", null, jsonConfig, null);
+        OperationalPolicy policy = new OperationalPolicy("testPolicy", null, jsonConfig, null, null);
 
         Map<String, String> guardsMap = policy.createGuardPolicyPayloads();
 
diff --git a/ui-react/src/LoopUI.js b/ui-react/src/LoopUI.js
index 9510670..471e872 100644
--- a/ui-react/src/LoopUI.js
+++ b/ui-react/src/LoopUI.js
@@ -37,10 +37,12 @@
 import LoopActionService from './api/LoopActionService';
 
 import { Route } from 'react-router-dom'
+import CreateLoopModal from './components/dialogs/Loop/CreateLoopModal';
 import OpenLoopModal from './components/dialogs/Loop/OpenLoopModal';
 import ModifyLoopModal from './components/dialogs/Loop/ModifyLoopModal';
 import OperationalPolicyModal from './components/dialogs/OperationalPolicy/OperationalPolicyModal';
 import ConfigurationPolicyModal from './components/dialogs/ConfigurationPolicy/ConfigurationPolicyModal';
+import PolicyModal from './components/dialogs/Policy/PolicyModal';
 import LoopPropertiesModal from './components/dialogs/Loop/LoopPropertiesModal';
 import UserInfoModal from './components/dialogs/UserInfoModal';
 import LoopService from './api/LoopService';
@@ -257,6 +259,7 @@
 					render={(routeProps) => (<OperationalPolicyModal {...routeProps} loopCache={this.getLoopCache()} loadLoopFunction={this.loadLoop} updateLoopFunction={this.updateLoopCache} showAlert={this.showAlert}/>)} />
 				<Route path="/policyModal/:policyInstanceType/:policyName" render={(routeProps) => (<PolicyModal {...routeProps} loopCache={this.getLoopCache()} loadLoopFunction={this.loadLoop}/>)} />
 				<Route path="/configurationPolicyModal/:policyName" render={(routeProps) => (<ConfigurationPolicyModal {...routeProps} loopCache={this.getLoopCache()} loadLoopFunction={this.loadLoop}/>)} />
+				<Route path="/createLoop" render={(routeProps) => (<CreateLoopModal {...routeProps} loadLoopFunction={this.loadLoop} />)} />
 				<Route path="/openLoop" render={(routeProps) => (<OpenLoopModal {...routeProps} loadLoopFunction={this.loadLoop} />)} />
 				<Route path="/loopProperties" render={(routeProps) => (<LoopPropertiesModal {...routeProps} loopCache={this.getLoopCache()} loadLoopFunction={this.loadLoop}/>)} />
 				<Route path="/modifyLoop" render={(routeProps) => (<ModifyLoopModal {...routeProps} loopCache={this.getLoopCache()} loadLoopFunction={this.loadLoop}/>)} />
diff --git a/ui-react/src/__snapshots__/LoopUI.test.js.snap b/ui-react/src/__snapshots__/LoopUI.test.js.snap
index 3d0137c..7d2c446 100644
--- a/ui-react/src/__snapshots__/LoopUI.test.js.snap
+++ b/ui-react/src/__snapshots__/LoopUI.test.js.snap
@@ -29,6 +29,10 @@
     render={[Function]}
   />
   <Route
+    path="/createLoop"
+    render={[Function]}
+  />
+  <Route
     path="/openLoop"
     render={[Function]}
   />
diff --git a/ui-react/src/__snapshots__/OnapClamp.test.js.snap b/ui-react/src/__snapshots__/OnapClamp.test.js.snap
index 1c456e1..e195523 100644
--- a/ui-react/src/__snapshots__/OnapClamp.test.js.snap
+++ b/ui-react/src/__snapshots__/OnapClamp.test.js.snap
@@ -54,6 +54,10 @@
       render={[Function]}
     />
     <Route
+      path="/createLoop"
+      render={[Function]}
+    />
+    <Route
       path="/openLoop"
       render={[Function]}
     />
diff --git a/ui-react/src/api/LoopService.js b/ui-react/src/api/LoopService.js
index 432eabe..d665f81 100644
--- a/ui-react/src/api/LoopService.js
+++ b/ui-react/src/api/LoopService.js
@@ -38,6 +38,24 @@
 			});
 	}
 
+	static createLoop(loopName, templateName) {
+		return fetch('/restservices/clds/v2/loop/create/' + loopName + '?templateName=' + templateName, {
+			method: 'POST',
+			headers: {
+				"Content-Type": "application/json"
+			},
+			credentials: 'same-origin'
+		})
+			.then(function (response) {
+				console.debug("CreateLoop response received: ", response.status);
+				return response.json();
+			})
+			.catch(function (error) {
+				console.error("CreateLoop error received", error);
+				return "";
+			});
+	}
+
 	static getLoop(loopName) {
 		return fetch('/restservices/clds/v2/loop/' + loopName, {
 			method: 'GET',
diff --git a/ui-react/src/api/TemplateService.js b/ui-react/src/api/TemplateService.js
index 10e0b54..6a65d9a 100644
--- a/ui-react/src/api/TemplateService.js
+++ b/ui-react/src/api/TemplateService.js
@@ -21,6 +21,22 @@
  */
 
 export default class TemplateService {
+	static getTemplateNames() {
+		return fetch('/restservices/clds/v2/templates/names', { method: 'GET', credentials: 'same-origin' })
+			.then(function (response) {
+				console.debug("GetTemplateNames response received: ", response.status);
+				if (response.ok) {
+					return response.json();
+				} else {
+					console.error("GetTemplateNames query failed");
+					return {};
+				}
+			})
+			.catch(function (error) {
+				console.error("GetTemplateNames error received", error);
+				return {};
+			});
+	}
 
   static getBlueprintMicroServiceTemplates() {
     return fetch('restservices/clds/v2/templates', { method: 'GET', credentials: 'same-origin', })
diff --git a/ui-react/src/components/dialogs/Loop/CreateLoopModal.js b/ui-react/src/components/dialogs/Loop/CreateLoopModal.js
new file mode 100644
index 0000000..d6c5e35
--- /dev/null
+++ b/ui-react/src/components/dialogs/Loop/CreateLoopModal.js
@@ -0,0 +1,133 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2020 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============================================
+ * ===================================================================
+ *
+ */
+
+import React from 'react'
+import Select from 'react-select';
+import Button from 'react-bootstrap/Button';
+import Modal from 'react-bootstrap/Modal';
+import Form from 'react-bootstrap/Form';
+import Row from 'react-bootstrap/Row';
+import Col from 'react-bootstrap/Col';
+import styled from 'styled-components';
+import LoopService from '../../../api/LoopService';
+import TemplateService from '../../../api/TemplateService';
+
+const ModalStyled = styled(Modal)`
+	background-color: transparent;
+`
+
+export default class CreateLoopModal extends React.Component {
+	constructor(props, context) {
+		super(props, context);
+
+		this.getTemplateNames = this.getTemplateNames.bind(this);
+		this.handleCreate = this.handleCreate.bind(this);
+		this.handleModelName = this.handleModelName.bind(this);
+		this.handleClose = this.handleClose.bind(this);
+		this.handleDropdownListChange = this.handleDropdownListChange.bind(this);
+		this.state = {
+			show: true,
+			chosenTemplateName: '',
+			modelName: '',
+			templateNames: []
+		};
+	}
+
+	componentWillMount() {
+		this.getTemplateNames();
+	}
+
+	handleClose() {
+		this.setState({ show: false });
+		this.props.history.push('/');
+	}
+
+	handleDropdownListChange(e) {
+		this.setState({ chosenTemplateName: e.value });
+	}
+
+	getTemplateNames() {
+		TemplateService.getTemplateNames().then(templateNames => {
+			const templateOptions = templateNames.map((templateName) => { return { label: templateName, value: templateName } });
+			this.setState({ templateNames: templateOptions })
+		});
+	}
+
+	handleCreate() {
+		if (!this.state.modelName) {
+			alert("A model name is required");
+			return;
+		}
+		console.info("Create Model " + this.state.modelName + ", Template " + this.state.chosenTemplateName + " is chosen");
+		this.setState({ show: false });
+		LoopService.createLoop("LOOP_" + this.state.modelName, this.state.chosenTemplateName).then(text => {
+			console.debug("CreateLoop response received: ", text);
+			try {
+				this.props.history.push('/');
+				this.props.loadLoopFunction("LOOP_" + this.state.modelName);
+			} catch(err) {
+				alert(text);
+				this.props.history.push('/');
+			}
+		})
+		.catch(error => {
+			console.debug("Create Loop failed");
+		});
+
+	}
+
+	handleModelName = event => {
+    	this.setState({
+      		modelName: event.target.value
+    	})
+	}
+
+	render() {
+		return (
+			<ModalStyled size="lg" show={this.state.show} onHide={this.handleClose}>
+				<Modal.Header closeButton>
+					<Modal.Title>Create Model</Modal.Title>
+				</Modal.Header>
+				<Modal.Body>
+					<Form.Group as={Row} controlId="formPlaintextEmail">
+						<Form.Label column sm="2">Template Name</Form.Label>
+						<Col sm="10">
+							<Select onChange={this.handleDropdownListChange} options={this.state.templateNames} />
+						</Col>
+					</Form.Group>
+					<Form.Group controlId="formPlaintextEmail">
+						<Form.Label column sm="2">Model Name:</Form.Label>
+						<input type="text" style={{width: '50%'}}
+							value={this.state.modelName}
+							onChange={this.handleModelName}
+						/>
+					</Form.Group>
+				</Modal.Body>
+				<Modal.Footer>
+					<Button variant="secondary" type="null" onClick={this.handleClose}>Cancel</Button>
+					<Button variant="primary" type="submit" onClick={this.handleCreate}>Create</Button>
+				</Modal.Footer>
+			</ModalStyled>
+
+		);
+	}
+}
\ No newline at end of file
diff --git a/ui-react/src/components/dialogs/Policy/PolicyModal.js b/ui-react/src/components/dialogs/Policy/PolicyModal.js
index 75ac2c4..51a6464 100644
--- a/ui-react/src/components/dialogs/Policy/PolicyModal.js
+++ b/ui-react/src/components/dialogs/Policy/PolicyModal.js
@@ -61,14 +61,14 @@
 		}
 		else {
 			console.info("NO validation errors found in policy data");
-			if (policyInstanceType === 'MICRO-SERVICE-POLICY') {
+			if (this.state.policyInstanceType === 'MICRO-SERVICE-POLICY') {
                 this.state.loopCache.updateMicroServiceProperties(this.state.policyName, editorData[0]);
                 LoopService.setMicroServiceProperties(this.state.loopCache.getLoopName(), this.state.loopCache.getMicroServiceForName(this.state.policyName)).then(resp => {
                     this.setState({ show: false });
                     this.props.history.push('/');
                     this.props.loadLoopFunction(this.state.loopCache.getLoopName());
                 });
-			} else if (policyInstanceType === 'OPERATIONAL-POLICY') {
+			} else if (this.state.policyInstanceType === 'OPERATIONAL-POLICY') {
 			    this.state.loopCache.updateOperationalPolicyProperties(editorData);
             	LoopService.setOperationalPolicyProperties(this.state.loopCache.getLoopName(), this.state.loopCache.getOperationalPolicyForName(this.state.policyName)).then(resp => {
             		this.setState({ show: false });
@@ -92,10 +92,10 @@
 		console.debug("Rendering PolicyModal ", this.state.policyName);
 		var toscaModel = {};
 	    var editorData = {};
-	    if (policyInstanceType === 'MICRO-SERVICE-POLICY') {
+	    if (this.state.policyInstanceType === 'MICRO-SERVICE-POLICY') {
             toscaModel = this.state.loopCache.getMicroServiceJsonRepresentationForName(this.state.policyName);
             editorData = this.state.loopCache.getMicroServicePropertiesForName(this.state.policyName);
-        } else if (policyInstanceType === 'OPERATIONAL-POLICY') {
+        } else if (this.state.policyInstanceType === 'OPERATIONAL-POLICY') {
             toscaModel = this.state.loopCache.getOperationalPolicyJsonRepresentationForName(this.state.policyName);
             editorData = this.state.loopCache.getOperationalPolicyPropertiesForName(this.state.policyName);
         }
diff --git a/ui-react/src/components/menu/MenuBar.js b/ui-react/src/components/menu/MenuBar.js
index c1a7ac3..2f13cfe 100644
--- a/ui-react/src/components/menu/MenuBar.js
+++ b/ui-react/src/components/menu/MenuBar.js
@@ -95,10 +95,11 @@
                     		<NavDropdown.Item as={StyledLink} to="/viewToscaPolicyModal">View Tosca Models</NavDropdown.Item>
                     </StyledNavDropdown>
 					<StyledNavDropdown title="Loop Instance">
-							<NavDropdown.Item as={StyledLink} to="/openLoop">Open Loop</NavDropdown.Item>
+					        <NavDropdown.Item as={StyledLink} to="/createLoop">Create</NavDropdown.Item>
+							<NavDropdown.Item as={StyledLink} to="/openLoop">Open</NavDropdown.Item>
 							<NavDropdown.Item as={StyledLink} to="/loopProperties" disabled={this.state.disabled}>Properties</NavDropdown.Item>
 							<NavDropdown.Item as={StyledLink} to="/closeLoop" disabled={this.state.disabled}>Close</NavDropdown.Item>
-							<NavDropdown.Item as={StyledLink} to="/modifyLoop" >Modify</NavDropdown.Item>
+							<NavDropdown.Item as={StyledLink} to="/modifyLoop" disabled={this.state.disabled}>Modify</NavDropdown.Item>
 							<NavDropdown.Item as={StyledLink} to="/refreshStatus" disabled={this.state.disabled}>Refresh Status</NavDropdown.Item>
 					</StyledNavDropdown>
 					<StyledNavDropdown title="Loop Operations">
diff --git a/ui-react/src/components/menu/__snapshots__/MenuBar.test.js.snap b/ui-react/src/components/menu/__snapshots__/MenuBar.test.js.snap
index a7e66ed..63d3f65 100644
--- a/ui-react/src/components/menu/__snapshots__/MenuBar.test.js.snap
+++ b/ui-react/src/components/menu/__snapshots__/MenuBar.test.js.snap
@@ -213,9 +213,60 @@
         }
       }
       disabled={false}
+      to="/createLoop"
+    >
+      Create
+    </DropdownItem>
+    <DropdownItem
+      as={
+        Object {
+          "$$typeof": Symbol(react.forward_ref),
+          "attrs": Array [],
+          "componentStyle": ComponentStyle {
+            "componentId": "sc-bdVaJa",
+            "isStatic": false,
+            "rules": Array [
+              "
+	color: ",
+              [Function],
+              ";
+	background-color: ",
+              [Function],
+              ";
+	font-weight: normal;
+	display: block;
+	width: 100%;
+	padding: .25rem 1.5rem;
+	clear: both;
+	text-align: inherit;
+	white-space: nowrap;
+	border: 0;
+	:hover {
+		text-decoration: none;
+		background-color: ",
+              [Function],
+              ";
+		color:  ",
+              [Function],
+              ";
+	}
+",
+            ],
+          },
+          "displayName": "Styled(Link)",
+          "foldedComponentIds": Array [],
+          "render": [Function],
+          "styledComponentId": "sc-bdVaJa",
+          "target": [Function],
+          "toString": [Function],
+          "warnTooManyClasses": [Function],
+          "withComponent": [Function],
+        }
+      }
+      disabled={false}
       to="/openLoop"
     >
-      Open Loop
+      Open
     </DropdownItem>
     <DropdownItem
       as={
@@ -365,7 +416,7 @@
           "withComponent": [Function],
         }
       }
-      disabled={false}
+      disabled={true}
       to="/modifyLoop"
     >
       Modify