Add Create loop dialog 50/102450/6
authorsebdet <sebastien.determe@intl.att.com>
Wed, 26 Feb 2020 23:47:30 +0000 (15:47 -0800)
committersebdet <sebastien.determe@intl.att.com>
Thu, 27 Feb 2020 14:17:02 +0000 (06:17 -0800)
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>
37 files changed:
docs/swagger/swagger.pdf
src/main/java/org/onap/clamp/clds/client/PolicyEngineServices.java
src/main/java/org/onap/clamp/clds/config/CldsUserJsonDecoder.java
src/main/java/org/onap/clamp/clds/config/DefaultUserConfiguration.java
src/main/java/org/onap/clamp/clds/util/drawing/ClampGraphBuilder.java
src/main/java/org/onap/clamp/clds/util/drawing/Painter.java
src/main/java/org/onap/clamp/loop/Loop.java
src/main/java/org/onap/clamp/loop/LoopController.java
src/main/java/org/onap/clamp/loop/LoopService.java
src/main/java/org/onap/clamp/loop/template/LoopTemplatesService.java
src/main/java/org/onap/clamp/loop/template/PolicyModel.java
src/main/java/org/onap/clamp/loop/template/PolicyModelsService.java
src/main/java/org/onap/clamp/policy/microservice/MicroServicePolicy.java
src/main/java/org/onap/clamp/policy/microservice/MicroServicePolicyService.java
src/main/java/org/onap/clamp/policy/operational/OperationalPolicy.java
src/main/java/org/onap/clamp/policy/operational/OperationalPolicyService.java
src/main/resources/META-INF/resources/swagger.html
src/main/resources/clds/camel/rest/clamp-api-v2.xml
src/test/java/org/onap/clamp/clds/util/drawing/ClampGraphBuilderTest.java
src/test/java/org/onap/clamp/clds/util/drawing/SvgLoopGeneratorTest.java
src/test/java/org/onap/clamp/loop/DcaeComponentTest.java
src/test/java/org/onap/clamp/loop/DeployFlowTestItCase.java
src/test/java/org/onap/clamp/loop/LoopRepositoriesItCase.java
src/test/java/org/onap/clamp/loop/LoopServiceTestItCase.java
src/test/java/org/onap/clamp/loop/LoopToJsonTest.java
src/test/java/org/onap/clamp/loop/PolicyModelServiceItCase.java
src/test/java/org/onap/clamp/policy/microservice/MicroServicePayloadTest.java
src/test/java/org/onap/clamp/policy/microservice/OperationalPolicyPayloadTest.java
ui-react/src/LoopUI.js
ui-react/src/__snapshots__/LoopUI.test.js.snap
ui-react/src/__snapshots__/OnapClamp.test.js.snap
ui-react/src/api/LoopService.js
ui-react/src/api/TemplateService.js
ui-react/src/components/dialogs/Loop/CreateLoopModal.js [new file with mode: 0644]
ui-react/src/components/dialogs/Policy/PolicyModal.js
ui-react/src/components/menu/MenuBar.js
ui-react/src/components/menu/__snapshots__/MenuBar.test.js.snap

index d9acf9d..18a6316 100644 (file)
@@ -4,8 +4,8 @@
 << /Title (Clamp Rest API)
 /Creator (Asciidoctor PDF 1.5.0.alpha.10, based on Prawn 1.3.0)
 /Producer (Asciidoctor PDF 1.5.0.alpha.10, based on Prawn 1.3.0)
-/CreationDate (D:20200226131758+01'00')
-/ModDate (D:20200226131758+01'00')
+/CreationDate (D:20200226154251-08'00')
+/ModDate (D:20200226154251-08'00')
 >>
 endobj
 2 0 obj
index b3fcb6f..44abc9d 100644 (file)
@@ -25,10 +25,8 @@ package org.onap.clamp.clds.client;
 
 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 java.util.Map;
 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 @@ public class PolicyEngineServices {
     /**
      * 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 @@ public class PolicyEngineServices {
     /**
      * 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 @@ public class PolicyEngineServices {
         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 @@ public class PolicyEngineServices {
     /**
      * 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");
index 626227e..a7ef107 100644 (file)
 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 {
index a451586..1261a5e 100644 (file)
@@ -27,12 +27,10 @@ package org.onap.clamp.clds.config;
 
 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;
index 7edf6c1..8e3b06a 100755 (executable)
@@ -88,12 +88,10 @@ public class ClampGraphBuilder {
     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;
     }
index af62d84..5ec59db 100755 (executable)
@@ -83,7 +83,7 @@ public class Painter {
 
         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())
index 676626a..b3fe58f 100644 (file)
@@ -60,6 +60,7 @@ import org.onap.clamp.loop.components.external.ExternalComponent;
 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 @@ public class Loop extends AuditEntity implements Serializable {
         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;
     }
index c161c55..7b037da 100644 (file)
@@ -40,16 +40,22 @@ import org.springframework.stereotype.Controller;
 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();
     }
index 6ea412c..34be203 100644 (file)
@@ -28,6 +28,7 @@ import java.util.List;
 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 @@ public class LoopService {
     @Autowired
     private PolicyModelsService policyModelsService;
 
+    @Autowired
+    private LoopTemplatesService loopTemplateService;
+
     Loop saveOrUpdateLoop(Loop loop) {
         return loopsRepository.save(loop);
     }
@@ -69,6 +73,17 @@ public class LoopService {
         loopsRepository.deleteById(loopName);
     }
 
+    /**
+     * 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.
      *
@@ -96,7 +111,7 @@ public class LoopService {
         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);
     }
 
index 2938213..09bc80f 100644 (file)
@@ -49,6 +49,17 @@ public class LoopTemplatesService {
         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();
     }
index 7334ece..66b05f6 100644 (file)
@@ -35,7 +35,6 @@ import javax.persistence.Id;
 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 @@ public class PolicyModel extends AuditEntity implements Serializable, Comparable
      */
     @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 @@ public class PolicyModel extends AuditEntity implements Serializable, Comparable
     /**
      * 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 @@ public class PolicyModel extends AuditEntity implements Serializable, Comparable
 
     /**
      * 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
index b38be94..7e21cc3 100644 (file)
@@ -52,8 +52,7 @@ public class PolicyModelsService {
     /**
      * 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 @@ public class PolicyModelsService {
     /**
      * 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 @@ public class PolicyModelsService {
         }
     }
 
-     /**
+    /**
      * 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 @@ public class PolicyModelsService {
             }
 
             if (supportedPdpGroups.size() > 0) {
-                JsonObject supportedPdpJson = new JsonObject ();
+                JsonObject supportedPdpJson = new JsonObject();
                 supportedPdpJson.add("supportedPdpGroups", supportedPdpGroups);
                 policyModel.setPolicyPdpGroup(supportedPdpJson);
                 policyModelsRepository.save(policyModel);
index 8d9017e..75efca7 100644 (file)
@@ -51,6 +51,7 @@ import org.onap.clamp.clds.tosca.ToscaYamlToJsonConvertor;
 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 @@ public class MicroServicePolicy extends Policy implements Serializable {
     }
 
     /**
-     * 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 @@ public class MicroServicePolicy extends Policy implements Serializable {
     /**
      * 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
index b17bf1a..2af8ec7 100644 (file)
 
 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 @@ public class MicroServicePolicyService implements PolicyService<MicroServicePoli
         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 @@ public class MicroServicePolicyService implements PolicyService<MicroServicePoli
      * @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) {
index 0825ea9..52b8772 100644 (file)
@@ -55,6 +55,7 @@ import org.hibernate.annotations.TypeDef;
 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 @@ public class OperationalPolicy extends Policy implements Serializable {
 
     /**
      * 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(
index 174912b..cc636ba 100644 (file)
@@ -52,7 +52,7 @@ public class OperationalPolicyService implements PolicyService<OperationalPolicy
                                 .map(p -> setConfigurationJson(p, policy.getConfigurationsJson()))
                                 .orElse(new OperationalPolicy(policy.getName(), loop,
                                         policy.getConfigurationsJson(),
-                                        policy.getPolicyModel())))
+                                        policy.getPolicyModel(), null)))
                 .collect(Collectors.toSet());
     }
 
index 0138d9a..74322f3 100644 (file)
@@ -3758,7 +3758,7 @@ body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-b
 </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>
index 1f92726..280b808 100644 (file)
                                </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>
                                </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
index 63209e9..2ccecf3 100644 (file)
@@ -70,7 +70,7 @@ public class ClampGraphBuilderTest {
                 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);
 
index aad11ad..7b83a4c 100644 (file)
 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 @@ public class SvgLoopGeneratorTest {
         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);
index 57e99a3..50e2e8d 100644 (file)
@@ -28,7 +28,6 @@ import static org.assertj.core.api.Assertions.assertThat;
 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 @@ public class DcaeComponentTest {
 
         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);
index 4fd78d1..3c2ce17 100644 (file)
@@ -29,7 +29,6 @@ import com.google.gson.Gson;
 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 @@ public class DeployFlowTestItCase {
         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;
index fa4909c..acde66d 100644 (file)
@@ -31,7 +31,6 @@ import com.google.gson.Gson;
 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 @@ public class LoopRepositoriesItCase {
     }
 
     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 @@ public class LoopRepositoriesItCase {
     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;
     }
index 5eca90c..849ca5c 100644 (file)
@@ -46,7 +46,6 @@ import org.onap.clamp.policy.operational.OperationalPolicy;
 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 @@ public class LoopServiceTestItCase {
         // 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 @@ public class LoopServiceTestItCase {
         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 @@ public class LoopServiceTestItCase {
         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 @@ public class LoopServiceTestItCase {
         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",
index a2a4536..34d524a 100644 (file)
@@ -33,7 +33,6 @@ import com.google.gson.GsonBuilder;
 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 @@ public class LoopToJsonTest {
 
     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 @@ public class LoopToJsonTest {
                                                      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 @@ public class LoopToJsonTest {
         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 @@ public class LoopToJsonTest {
         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 @@ public class LoopToJsonTest {
                 "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\"}",
index f8aadba..80545c1 100644 (file)
@@ -25,6 +25,7 @@ package org.onap.clamp.loop;
 
 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.beans.factory.annotation.Autowired;
 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 @@ public class PolicyModelServiceItCase {
     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 @@ public class PolicyModelServiceItCase {
                 .isEqualToIgnoringGivenFields(policyModel, "createdDate", "updatedDate", "createdBy", "updatedBy");
     }
 
+    /**
+     * This tests a getAllPolicyModelTypes get.
+     */
     @Test
     @Transactional
     public void shouldReturnAllPolicyModelTypes() {
@@ -125,6 +127,9 @@ public class PolicyModelServiceItCase {
         assertThat(policyModelTypesList).contains(policyModel1.getPolicyModelType(), policyModel2.getPolicyModelType());
     }
 
+    /**
+     * This tests a getAllPolicyModels get.
+     */
     @Test
     @Transactional
     public void shouldReturnAllPolicyModels() {
@@ -138,6 +143,9 @@ public class PolicyModelServiceItCase {
         assertThat(policyModelsService.getAllPolicyModels()).contains(policyModel1, policyModel2);
     }
 
+    /**
+     * This tests a getAllPolicyModelsByType get.
+     */
     @Test
     @Transactional
     public void shouldReturnAllModelsByType() {
@@ -152,6 +160,9 @@ public class PolicyModelServiceItCase {
                 policyModel2);
     }
 
+    /**
+     * This tests the sorting of policyModel.
+     */
     @Test
     @Transactional
     public void shouldReturnSortedSet() {
@@ -167,14 +178,17 @@ public class PolicyModelServiceItCase {
 
         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 @@ public class PolicyModelServiceItCase {
         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);
 
index 3911494..ea12182 100644 (file)
@@ -25,7 +25,6 @@ package org.onap.clamp.policy.microservice;
 
 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 class MicroServicePayloadTest {
     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"),
index f42bbc1..bdc7e80 100644 (file)
@@ -41,7 +41,7 @@ public class OperationalPolicyPayloadTest {
     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 @@ public class OperationalPolicyPayloadTest {
         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 class OperationalPolicyPayloadTest {
     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();
 
index 9510670..471e872 100644 (file)
@@ -37,10 +37,12 @@ import LoopCache from './api/LoopCache';
 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 @@ export default class LoopUI extends React.Component {
                                        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}/>)} />
index 3d0137c..7d2c446 100644 (file)
@@ -28,6 +28,10 @@ exports[`Verify LoopUI Test the render method 1`] = `
     path="/configurationPolicyModal/:policyName"
     render={[Function]}
   />
+  <Route
+    path="/createLoop"
+    render={[Function]}
+  />
   <Route
     path="/openLoop"
     render={[Function]}
index 1c456e1..e195523 100644 (file)
@@ -53,6 +53,10 @@ exports[`Verify OnapClamp Test the render method 1`] = `
       path="/configurationPolicyModal/:policyName"
       render={[Function]}
     />
+    <Route
+      path="/createLoop"
+      render={[Function]}
+    />
     <Route
       path="/openLoop"
       render={[Function]}
index 432eabe..d665f81 100644 (file)
@@ -38,6 +38,24 @@ export default class LoopService {
                        });
        }
 
+       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',
index 10e0b54..6a65d9a 100644 (file)
  */
 
 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 (file)
index 0000000..d6c5e35
--- /dev/null
@@ -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
index 75ac2c4..51a6464 100644 (file)
@@ -61,14 +61,14 @@ export default class PolicyModal extends React.Component {
                }
                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 @@ export default class PolicyModal extends React.Component {
                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);
         }
index c1a7ac3..2f13cfe 100644 (file)
@@ -95,10 +95,11 @@ export default class MenuBar extends React.Component {
                                <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">
index a7e66ed..63d3f65 100644 (file)
@@ -199,6 +199,57 @@ exports[`Verify MenuBar Test the render method 1`] = `
               [Function],
               ";
        }
+",
+            ],
+          },
+          "displayName": "Styled(Link)",
+          "foldedComponentIds": Array [],
+          "render": [Function],
+          "styledComponentId": "sc-bdVaJa",
+          "target": [Function],
+          "toString": [Function],
+          "warnTooManyClasses": [Function],
+          "withComponent": [Function],
+        }
+      }
+      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],
+              ";
+       }
 ",
             ],
           },
@@ -215,7 +266,7 @@ exports[`Verify MenuBar Test the render method 1`] = `
       disabled={false}
       to="/openLoop"
     >
-      Open Loop
+      Open
     </DropdownItem>
     <DropdownItem
       as={
@@ -365,7 +416,7 @@ exports[`Verify MenuBar Test the render method 1`] = `
           "withComponent": [Function],
         }
       }
-      disabled={false}
+      disabled={true}
       to="/modifyLoop"
     >
       Modify