Fix warning/sonar
[clamp.git] / src / main / java / org / onap / clamp / clds / sdc / controller / installer / CsarInstallerImpl.java
index 6a9828d..6dc4183 100644 (file)
  * See the License for the specific language governing permissions and
  * limitations under the License.
  * ============LICENSE_END============================================
+ * Modifications copyright (c) 2019 Nokia
  * ===================================================================
- * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ *
  */
 
 package org.onap.clamp.clds.sdc.controller.installer;
 
-import com.att.aft.dme2.internal.apache.commons.io.IOUtils;
 import com.att.eelf.configuration.EELFLogger;
 import com.att.eelf.configuration.EELFManager;
-
+import com.google.gson.JsonObject;
 import java.io.IOException;
+import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
-
+import java.util.Optional;
+import java.util.Set;
 import javax.annotation.PostConstruct;
-
+import javax.xml.transform.TransformerException;
+import org.apache.commons.io.IOUtils;
 import org.json.simple.parser.ParseException;
 import org.onap.clamp.clds.client.DcaeInventoryServices;
 import org.onap.clamp.clds.config.sdc.BlueprintParserFilesConfiguration;
 import org.onap.clamp.clds.config.sdc.BlueprintParserMappingConfiguration;
 import org.onap.clamp.clds.dao.CldsDao;
+import org.onap.clamp.clds.exception.policy.PolicyModelException;
 import org.onap.clamp.clds.exception.sdc.controller.SdcArtifactInstallerException;
 import org.onap.clamp.clds.model.CldsModel;
 import org.onap.clamp.clds.model.CldsTemplate;
+import org.onap.clamp.clds.model.dcae.DcaeInventoryResponse;
+import org.onap.clamp.clds.model.properties.ModelProperties;
 import org.onap.clamp.clds.service.CldsService;
 import org.onap.clamp.clds.service.CldsTemplateService;
-import org.springframework.transaction.annotation.Transactional;
+import org.onap.clamp.clds.transform.XslTransformer;
+import org.onap.clamp.clds.util.JsonUtils;
+import org.onap.clamp.clds.util.drawing.SvgFacade;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.context.ApplicationContext;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
 import org.yaml.snakeyaml.Yaml;
 
 /**
@@ -57,71 +67,110 @@ import org.yaml.snakeyaml.Yaml;
  * There is no state kept by the bean. It's used to deploy the csar/notification
  * received from SDC in DB.
  */
+@Component
 public class CsarInstallerImpl implements CsarInstaller {
 
     private static final EELFLogger logger = EELFManager.getInstance().getLogger(CsarInstallerImpl.class);
     private Map<String, BlueprintParserFilesConfiguration> bpmnMapping = new HashMap<>();
-    public static final String TEMPLATE_NAME_PREFIX = "DCAE-Designer-ClosedLoopTemplate-";
-    public static final String MODEL_NAME_PREFIX = "ClosedLoop-";
+    public static final String TEMPLATE_NAME_PREFIX = "DCAE-Designer-Template-";
+    public static final String CONTROL_NAME_PREFIX = "ClosedLoop-";
     public static final String GET_INPUT_BLUEPRINT_PARAM = "get_input";
+    // This will be used later as the policy scope
+    public static final String MODEL_NAME_PREFIX = "CLAMP";
     /**
      * The file name that will be loaded by Spring.
      */
     @Value("${clamp.config.sdc.blueprint.parser.mapping:'classpath:/clds/blueprint-parser-mapping.json'}")
     protected String blueprintMappingFile;
-    @Autowired
     protected ApplicationContext appContext;
-    @Autowired
     private CldsDao cldsDao;
-    @Autowired
     CldsTemplateService cldsTemplateService;
-    @Autowired
     CldsService cldsService;
-    @Autowired
     DcaeInventoryServices dcaeInventoryService;
+    private XslTransformer cldsBpmnTransformer;
+
+    @Autowired
+    public CsarInstallerImpl(ApplicationContext appContext,
+                             CldsDao cldsDao, CldsTemplateService cldsTemplateService, CldsService cldsService,
+                             DcaeInventoryServices dcaeInventoryService, XslTransformer cldsBpmnTransformer) {
+        this.appContext = appContext;
+        this.cldsDao = cldsDao;
+        this.cldsTemplateService = cldsTemplateService;
+        this.cldsService = cldsService;
+        this.dcaeInventoryService = dcaeInventoryService;
+        this.cldsBpmnTransformer = cldsBpmnTransformer;
+    }
+
+    @Autowired
+    private BlueprintParser blueprintParser;
+
+    @Autowired
+    private ChainGenerator chainGenerator;
+
+    @Autowired
+    private SvgFacade svgFacade;
 
     @PostConstruct
     public void loadConfiguration() throws IOException {
         BlueprintParserMappingConfiguration
-                .createFromJson(appContext.getResource(blueprintMappingFile).getInputStream()).stream()
-                .forEach(e -> bpmnMapping.put(e.getBlueprintKey(), e.getFiles()));
+            .createFromJson(appContext.getResource(blueprintMappingFile).getInputStream()).stream()
+            .forEach(e -> bpmnMapping.put(e.getBlueprintKey(), e.getFiles()));
     }
 
     @Override
     public boolean isCsarAlreadyDeployed(CsarHandler csar) throws SdcArtifactInstallerException {
-        return (CldsModel.retrieve(cldsDao, buildModelName(csar), true).getId() != null) ? true : false;
+        boolean alreadyInstalled = true;
+        for (Entry<String, BlueprintArtifact> blueprint : csar.getMapOfBlueprints().entrySet()) {
+            alreadyInstalled = alreadyInstalled
+                && CldsModel.retrieve(cldsDao, buildModelName(csar, blueprint.getValue()), true).getId() != null;
+        }
+        return alreadyInstalled;
     }
 
-    public static String buildModelName(CsarHandler csar) {
-        return csar.getSdcCsarHelper().getServiceMetadata().getValue("name") + " v"
-                + csar.getSdcNotification().getServiceVersion();
+    public static String buildModelName(CsarHandler csar, BlueprintArtifact artifact)
+        throws SdcArtifactInstallerException {
+        String policyScopePrefix = searchForPolicyScopePrefix(artifact);
+        if (policyScopePrefix.contains("*")) {
+            // This is policy_filter type
+            policyScopePrefix = policyScopePrefix.replaceAll("\\*", "");
+        } else {
+            // This is normally the get_input case
+            policyScopePrefix = MODEL_NAME_PREFIX;
+        }
+        return (policyScopePrefix + "_" + csar.getSdcCsarHelper().getServiceMetadata().getValue("name") + "_v"
+            + csar.getSdcNotification().getServiceVersion() + "_"
+            + artifact.getResourceAttached().getResourceInstanceName().replaceAll(" ", "") + "_"
+            + artifact.getBlueprintArtifactName().replace(".yaml", "")).replace('.', '_');
     }
 
     @Override
     @Transactional
-    public void installTheCsar(CsarHandler csar) throws SdcArtifactInstallerException {
+    public void installTheCsar(CsarHandler csar)
+        throws SdcArtifactInstallerException, InterruptedException, PolicyModelException {
         try {
             logger.info("Installing the CSAR " + csar.getFilePath());
             for (Entry<String, BlueprintArtifact> blueprint : csar.getMapOfBlueprints().entrySet()) {
                 logger.info("Processing blueprint " + blueprint.getValue().getBlueprintArtifactName());
-                String serviceTypeId = queryDcaeToGetServiceTypeId(blueprint.getValue());
-                createFakeCldsModel(csar, blueprint.getValue(), createFakeCldsTemplate(csar, blueprint.getValue(),
-                        this.searchForRightMapping(blueprint.getValue())), serviceTypeId);
+                createFakeCldsModel(csar, blueprint.getValue(),
+                    createFakeCldsTemplate(csar, blueprint.getValue(),
+                        this.searchForRightMapping(blueprint.getValue())),
+                    queryDcaeToGetServiceTypeId(blueprint.getValue()));
             }
+            createPolicyModel(csar);
             logger.info("Successfully installed the CSAR " + csar.getFilePath());
         } catch (IOException e) {
             throw new SdcArtifactInstallerException("Exception caught during the Csar installation in database", e);
-        } catch (ParseException | InterruptedException e) {
+        } catch (ParseException e) {
             throw new SdcArtifactInstallerException("Exception caught during the Dcae query to get ServiceTypeId", e);
         }
     }
 
-    private BlueprintParserFilesConfiguration searchForRightMapping(BlueprintArtifact blueprintArtifact)
-            throws SdcArtifactInstallerException {
+    BlueprintParserFilesConfiguration searchForRightMapping(BlueprintArtifact blueprintArtifact)
+        throws SdcArtifactInstallerException {
         List<BlueprintParserFilesConfiguration> listConfig = new ArrayList<>();
         Yaml yaml = new Yaml();
         Map<String, Object> templateNodes = ((Map<String, Object>) ((Map<String, Object>) yaml
-                .load(blueprintArtifact.getDcaeBlueprint())).get("node_templates"));
+            .load(blueprintArtifact.getDcaeBlueprint())).get("node_templates"));
         bpmnMapping.entrySet().forEach(e -> {
             if (templateNodes.keySet().stream().anyMatch(t -> t.contains(e.getKey()))) {
                 listConfig.add(e.getValue());
@@ -129,29 +178,56 @@ public class CsarInstallerImpl implements CsarInstaller {
         });
         if (listConfig.size() > 1) {
             throw new SdcArtifactInstallerException(
-                    "The code does not currently support multiple MicroServices in the blueprint");
+                "The code does not currently support multiple MicroServices in the blueprint");
         } else if (listConfig.isEmpty()) {
             throw new SdcArtifactInstallerException("There is no recognized MicroService found in the blueprint");
         }
         logger.info("Mapping found for blueprint " + blueprintArtifact.getBlueprintArtifactName() + " is "
-                + listConfig.get(0).getBpmnXmlFilePath());
+            + listConfig.get(0).getBpmnXmlFilePath());
         return listConfig.get(0);
     }
 
-    private String searchForPolicyName(BlueprintArtifact blueprintArtifact) throws SdcArtifactInstallerException {
+    String getAllBlueprintParametersInJson(BlueprintArtifact blueprintArtifact) {
+        JsonObject node = new JsonObject();
+        Yaml yaml = new Yaml();
+        Map<String, Object> inputsNodes = ((Map<String, Object>) ((Map<String, Object>) yaml
+            .load(blueprintArtifact.getDcaeBlueprint())).get("inputs"));
+        inputsNodes.entrySet().stream().filter(e -> !e.getKey().contains("policy_id")).forEach(elem -> {
+            Object defaultValue = ((Map<String, Object>) elem.getValue()).get("default");
+            if (defaultValue != null) {
+                addPropertyToNode(node, elem.getKey(), defaultValue);
+            } else {
+                node.addProperty(elem.getKey(), "");
+            }
+        });
+        node.addProperty("policy_id", "AUTO_GENERATED_POLICY_ID_AT_SUBMIT");
+        return node.toString();
+    }
+
+    private void createPolicyModel(CsarHandler csar) throws PolicyModelException {
+        try{
+            Optional<String> policyModelYaml = csar.getPolicyModelYaml();
+            // save policy model into the database
+        } catch (IOException e) {
+            throw new PolicyModelException("TransformerException when decoding the YamlText", e);
+        }
+    }
+
+    private static String searchForPolicyScopePrefix(BlueprintArtifact blueprintArtifact)
+        throws SdcArtifactInstallerException {
         String policyName = null;
         Yaml yaml = new Yaml();
         List<String> policyNameList = new ArrayList<>();
         Map<String, Object> templateNodes = ((Map<String, Object>) ((Map<String, Object>) yaml
-                .load(blueprintArtifact.getDcaeBlueprint())).get("node_templates"));
-        templateNodes.entrySet().stream().filter(e -> e.getKey().contains("policy_")).forEach(ef -> {
+            .load(blueprintArtifact.getDcaeBlueprint())).get("node_templates"));
+        templateNodes.entrySet().stream().filter(e -> e.getKey().contains("policy")).forEach(ef -> {
             String filteredPolicyName = (String) ((Map<String, Object>) ((Map<String, Object>) ef.getValue())
-                    .get("properties")).get("policy_filter");
+                .get("properties")).get("policy_filter");
             if (policyName != null) {
                 policyNameList.add(filteredPolicyName);
             } else {
                 String inputPolicyName = (String) ((Map<String, Object>) ((Map<String, Object>) ((Map<String, Object>) ef
-                        .getValue()).get("properties")).get("policy_id")).get(GET_INPUT_BLUEPRINT_PARAM);
+                    .getValue()).get("properties")).get("policy_id")).get(GET_INPUT_BLUEPRINT_PARAM);
                 if (inputPolicyName != null) {
                     policyNameList.add(GET_INPUT_BLUEPRINT_PARAM);
                 }
@@ -159,63 +235,112 @@ public class CsarInstallerImpl implements CsarInstaller {
         });
         if (policyNameList.size() > 1) {
             throw new SdcArtifactInstallerException(
-                    "The code does not currently support multiple Policy MicroServices in the blueprint");
+                "The code does not currently support multiple Policy MicroServices in the blueprint");
         } else if (policyNameList.isEmpty()) {
             throw new SdcArtifactInstallerException(
-                    "There is no recognized Policy MicroService found in the blueprint");
+                "There is no recognized Policy MicroService found in the blueprint");
         }
         logger.info("policyName found in blueprint " + blueprintArtifact.getBlueprintArtifactName() + " is "
-                + policyNameList.get(0));
+            + policyNameList.get(0));
         return policyNameList.get(0);
     }
 
-    private String queryDcaeToGetServiceTypeId(BlueprintArtifact blueprintArtifact) throws IOException, ParseException {
+    /**
+     * This call must be done when deploying the SDC notification as this call get
+     * the latest version of the artifact (version can be specified to DCAE call)
+     *
+     * @return The DcaeInventoryResponse object containing the dcae values
+     */
+    private DcaeInventoryResponse queryDcaeToGetServiceTypeId(BlueprintArtifact blueprintArtifact)
+        throws IOException, ParseException, InterruptedException {
         return dcaeInventoryService.getDcaeInformation(blueprintArtifact.getBlueprintArtifactName(),
-                blueprintArtifact.getBlueprintInvariantServiceUuid(),
-                blueprintArtifact.getBlueprintInvariantResourceUuid()).getTypeId();
+            blueprintArtifact.getBlueprintInvariantServiceUuid(),
+            blueprintArtifact.getResourceAttached().getResourceInvariantUUID());
     }
 
     private CldsTemplate createFakeCldsTemplate(CsarHandler csar, BlueprintArtifact blueprintArtifact,
-            BlueprintParserFilesConfiguration configFiles) throws IOException {
+        BlueprintParserFilesConfiguration configFiles) throws IOException, SdcArtifactInstallerException {
+
+        Set<MicroService> microServicesFromBlueprint = blueprintParser.getMicroServices(blueprintArtifact.getDcaeBlueprint()) ;
+        List<MicroService> microServicesChain = chainGenerator.getChainOfMicroServices(microServicesFromBlueprint);
+        if(microServicesChain.isEmpty()) {
+            microServicesChain = blueprintParser.fallbackToOneMicroService(blueprintArtifact.getDcaeBlueprint());
+        }
+        String imageText = svgFacade.getSvgImage(microServicesChain);
+
         CldsTemplate template = new CldsTemplate();
         template.setBpmnId("Sdc-Generated");
-        template.setBpmnText(
-                IOUtils.toString(appContext.getResource(configFiles.getBpmnXmlFilePath()).getInputStream()));
+        template.setBpmnText(IOUtils.toString(appContext.getResource(configFiles.getBpmnXmlFilePath()).getInputStream(),
+            StandardCharsets.UTF_8));
         template.setPropText(
-                "{\"global\":[{\"name\":\"service\",\"value\":[\"" + blueprintArtifact.getDcaeBlueprint() + "\"]}]}");
-        template.setImageText(
-                IOUtils.toString(appContext.getResource(configFiles.getSvgXmlFilePath()).getInputStream()));
-        template.setName(TEMPLATE_NAME_PREFIX + buildModelName(csar));
+            "{\"global\":[{\"name\":\"service\",\"value\":[\"" + blueprintArtifact.getDcaeBlueprint() + "\"]}]}");
+        template
+            .setImageText(imageText);
+        template.setName(TEMPLATE_NAME_PREFIX + buildModelName(csar, blueprintArtifact));
         template.save(cldsDao, null);
         logger.info("Fake Clds Template created for blueprint " + blueprintArtifact.getBlueprintArtifactName()
-                + " with name " + template.getName());
+            + " with name " + template.getName());
         return template;
     }
 
     private CldsModel createFakeCldsModel(CsarHandler csar, BlueprintArtifact blueprintArtifact,
-            CldsTemplate cldsTemplate, String serviceTypeId) throws SdcArtifactInstallerException {
-        CldsModel cldsModel = new CldsModel();
-        String policyName = searchForPolicyName(blueprintArtifact);
-        if (policyName.contains("*")) {
-            // It's a filter must add a specific prefix
-            cldsModel.setControlNamePrefix(policyName);
-        } else {
-            cldsModel.setControlNamePrefix(MODEL_NAME_PREFIX);
+        CldsTemplate cldsTemplate, DcaeInventoryResponse dcaeInventoryResponse) throws SdcArtifactInstallerException {
+
+        if (dcaeInventoryResponse == null) {
+            throw new SdcArtifactInstallerException(
+                "DCAE inventory response is NULL, query to DCAE fail to be answered properly, this is required to deploy CSAR properly !!!");
         }
-        cldsModel.setName(buildModelName(csar));
-        cldsModel.setBlueprintText(blueprintArtifact.getDcaeBlueprint());
-        cldsModel.setTemplateName(cldsTemplate.getName());
-        cldsModel.setTemplateId(cldsTemplate.getId());
-        cldsModel.setPropText("{\"global\":[{\"name\":\"service\",\"value\":[\""
-                + blueprintArtifact.getBlueprintInvariantServiceUuid() + "\"]},{\"name\":\"vf\",\"value\":[\""
-                + blueprintArtifact.getBlueprintInvariantResourceUuid()
-                + "\"]},{\"name\":\"actionSet\",\"value\":[\"vnfRecipe\"]},{\"name\":\"location\",\"value\":[\"DC1\"]},{\"name\":\"deployParameters\",\"value\":{\n"
-                + "        \"policy_id\": \"" + "test" + "\"" + "      }}]}");
-        cldsModel.setBpmnText(cldsTemplate.getBpmnText());
-        cldsModel.setTypeId(serviceTypeId);
-        cldsModel.save(cldsDao, null);
-        logger.info("Fake Clds Model created for blueprint " + blueprintArtifact.getBlueprintArtifactName()
+        try {
+            CldsModel cldsModel = new CldsModel();
+            cldsModel.setName(buildModelName(csar, blueprintArtifact));
+            cldsModel.setBlueprintText(blueprintArtifact.getDcaeBlueprint());
+            cldsModel.setTemplateName(cldsTemplate.getName());
+            cldsModel.setTemplateId(cldsTemplate.getId());
+            cldsModel.setBpmnText(cldsTemplate.getBpmnText());
+            cldsModel.setTypeId(dcaeInventoryResponse.getTypeId());
+            cldsModel.setTypeName(dcaeInventoryResponse.getTypeName());
+            cldsModel.setControlNamePrefix(CONTROL_NAME_PREFIX);
+            // We must save it otherwise object won't be created in db
+            // and proptext will always be null
+            cldsModel.setPropText("{\"global\":[]}");
+            // Must save first to have the generated id available to generate
+            // the policyId
+            cldsModel = cldsModel.save(cldsDao, null);
+            cldsModel = setModelPropText(cldsModel, blueprintArtifact, cldsTemplate);
+            logger.info("Fake Clds Model created for blueprint " + blueprintArtifact.getBlueprintArtifactName()
                 + " with name " + cldsModel.getName());
-        return cldsModel;
+            return cldsModel;
+        } catch (TransformerException e) {
+            throw new SdcArtifactInstallerException("TransformerException when decoding the BpmnText", e);
+        }
+    }
+
+    private CldsModel setModelPropText(CldsModel cldsModel, BlueprintArtifact blueprintArtifact,
+        CldsTemplate cldsTemplate) throws TransformerException {
+        // Do a test to validate the BPMN
+        new ModelProperties(cldsModel.getName(), cldsModel.getControlName(), "PUT", false,
+            cldsBpmnTransformer.doXslTransformToString(cldsTemplate.getBpmnText()), "{}");
+        String inputParams = "{\"name\":\"deployParameters\",\"value\":"
+            + getAllBlueprintParametersInJson(blueprintArtifact) + "}";
+        cldsModel.setPropText("{\"global\":[{\"name\":\"service\",\"value\":[\""
+            + blueprintArtifact.getBlueprintInvariantServiceUuid() + "\"]},{\"name\":\"vf\",\"value\":[\""
+            + blueprintArtifact.getResourceAttached().getResourceInvariantUUID()
+            + "\"]},{\"name\":\"actionSet\",\"value\":[\"vnfRecipe\"]},{\"name\":\"location\",\"value\":[\"DC1\"]},"
+            + inputParams + "]}");
+        return cldsModel.save(cldsDao, null);
+    }
+
+    private void addPropertyToNode(JsonObject node, String key, Object value) {
+        if (value instanceof String) {
+            node.addProperty(key, (String) value);
+        } else if (value instanceof Number) {
+            node.addProperty(key, (Number) value);
+        } else if (value instanceof Boolean) {
+            node.addProperty(key, (Boolean) value);
+        } else if (value instanceof Character) {
+            node.addProperty(key, (Character) value);
+        } else {
+            node.addProperty(key, JsonUtils.GSON.toJson(value));
+        }
     }
 }