Improve the policy model download
[clamp.git] / src / main / java / org / onap / clamp / clds / sdc / controller / installer / BlueprintParser.java
index 5a8ccca..5d5027d 100644 (file)
  * ===================================================================
  *
  */
+
 package org.onap.clamp.clds.sdc.controller.installer;
 
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
 import com.google.gson.Gson;
 import com.google.gson.JsonArray;
 import com.google.gson.JsonElement;
 import com.google.gson.JsonObject;
 
+import java.util.AbstractMap;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
@@ -36,62 +40,74 @@ import java.util.Map.Entry;
 import java.util.Set;
 
 import org.json.JSONObject;
-import org.springframework.stereotype.Component;
+import org.onap.clamp.clds.exception.sdc.controller.BlueprintParserException;
 import org.yaml.snakeyaml.Yaml;
 
-@Component
 public class BlueprintParser {
 
     static final String TCA = "TCA";
-    static final String HOLMES = "Holmes";
-    private static final String TCA_POLICY = "tca_policy";
-    private static final String HOLMES_PREFIX = "holmes";
     private static final String NODE_TEMPLATES = "node_templates";
     private static final String DCAE_NODES = "dcae.nodes.";
+    private static final String DCAE_NODES_POLICY = ".nodes.policy";
     private static final String TYPE = "type";
     private static final String PROPERTIES = "properties";
     private static final String NAME = "name";
-    private static final String POLICYID = "policy_id";
-    private static final String POLICY_TYPEID = "policy_type_id";
+    private static final String INPUT = "inputs";
+    private static final String GET_INPUT = "get_input";
+    private static final String POLICY_MODEL_ID = "policy_model_id";
+    private static final String POLICY_MODEL_VERSION = "policy_model_version";
     private static final String RELATIONSHIPS = "relationships";
     private static final String CLAMP_NODE_RELATIONSHIPS_GETS_INPUT_FROM = "clamp_node.relationships.gets_input_from";
     private static final String TARGET = "target";
+    public static final String DEFAULT_VERSION = "1.0.0";
+
+    private static final EELFLogger logger = EELFManager.getInstance().getLogger(BlueprintParser.class);
+
+    private BlueprintParser() {
 
-    public Set<MicroService> getMicroServices(String blueprintString) {
-        Set<MicroService> microServices = new HashSet<>();
-        JsonObject jsonObject = BlueprintParser.convertToJson(blueprintString);
-        JsonObject results = jsonObject.get(NODE_TEMPLATES).getAsJsonObject();
+    }
 
-        for (Entry<String, JsonElement> entry : results.entrySet()) {
+    /**
+     * Get all micro services from blueprint.
+     * 
+     * @param blueprintString the blueprint in a String
+     * @return A set of MircoService
+     * @throws BlueprintParserException In case of issues with the parsing
+     */
+    public static Set<BlueprintMicroService> getMicroServices(String blueprintString) throws BlueprintParserException {
+        Set<BlueprintMicroService> microServices = new HashSet<>();
+        JsonObject blueprintJson = BlueprintParser.convertToJson(blueprintString);
+        JsonObject nodeTemplateList = blueprintJson.get(NODE_TEMPLATES).getAsJsonObject();
+        JsonObject inputList = blueprintJson.get(INPUT).getAsJsonObject();
+
+        for (Entry<String, JsonElement> entry : nodeTemplateList.entrySet()) {
             JsonObject nodeTemplate = entry.getValue().getAsJsonObject();
-            if (nodeTemplate.get(TYPE).getAsString().contains(DCAE_NODES)) {
-                MicroService microService = getNodeRepresentation(entry);
-                microServices.add(microService);
+            if (!nodeTemplate.get(TYPE).getAsString().contains(DCAE_NODES_POLICY)
+                    && nodeTemplate.get(TYPE).getAsString().contains(DCAE_NODES)) {
+                BlueprintMicroService microService = getNodeRepresentation(entry, nodeTemplateList, inputList);
+                if (!microService.getModelType().isBlank()) {
+                    microServices.add(microService);
+                } else {
+                    logger.warn("Microservice " + microService.getName()
+                            + " will NOT be used by CLAMP as the model type is not defined or has not been found");
+                }
             }
         }
-        microServices.removeIf(ms -> TCA_POLICY.equals(ms.getName()));
+        logger.debug("Those microservices have been found in the blueprint:" + microServices);
         return microServices;
     }
 
-    public List<MicroService> fallbackToOneMicroService(String blueprintString) {
-        JsonObject jsonObject = BlueprintParser.convertToJson(blueprintString);
-        JsonObject results = jsonObject.get(NODE_TEMPLATES).getAsJsonObject();
-        String theBiggestMicroServiceContent = "";
-        String theBiggestMicroServiceKey = "";
-        for (Entry<String, JsonElement> entry : results.entrySet()) {
-            String msAsString = entry.getValue().toString();
-            int len = msAsString.length();
-            if (len > theBiggestMicroServiceContent.length()) {
-                theBiggestMicroServiceContent = msAsString;
-                theBiggestMicroServiceKey = entry.getKey();
-            }
-        }
-        String msName = theBiggestMicroServiceKey.toLowerCase().contains(HOLMES_PREFIX) ? HOLMES : TCA;
-        return Collections
-            .singletonList(new MicroService(msName, "onap.policy.monitoring.cdap.tca.hi.lo.app", "", "", ""));
+    /**
+     * Does a fallback to TCA.
+     * 
+     * @return The list of microservices
+     */
+    public static List<BlueprintMicroService> fallbackToOneMicroService() {
+        return Collections.singletonList(
+                new BlueprintMicroService(TCA, "onap.policies.monitoring.cdap.tca.hi.lo.app", "", DEFAULT_VERSION));
     }
 
-    String getName(Entry<String, JsonElement> entry) {
+    static String getName(Entry<String, JsonElement> entry) {
         String microServiceYamlName = entry.getKey();
         JsonObject ob = entry.getValue().getAsJsonObject();
         if (ob.has(PROPERTIES)) {
@@ -103,7 +119,7 @@ public class BlueprintParser {
         return microServiceYamlName;
     }
 
-    String getInput(Entry<String, JsonElement> entry) {
+    static String getInput(Entry<String, JsonElement> entry) {
         JsonObject ob = entry.getValue().getAsJsonObject();
         if (ob.has(RELATIONSHIPS)) {
             JsonArray relationships = ob.getAsJsonArray(RELATIONSHIPS);
@@ -117,45 +133,90 @@ public class BlueprintParser {
         return "";
     }
 
-    String getModelType(Entry<String, JsonElement> entry) {
-        JsonObject ob = entry.getValue().getAsJsonObject();
-        if (ob.has(PROPERTIES)) {
-            JsonObject properties = ob.get(PROPERTIES).getAsJsonObject();
-            if (properties.has(POLICYID)) {
-                JsonObject policyIdObj = properties.get(POLICYID).getAsJsonObject();
-                if (policyIdObj.has(POLICY_TYPEID)) {
-                    return policyIdObj.get(POLICY_TYPEID).getAsString();
+    static String findPropertyInRelationshipsArray(String propertyName, JsonArray relationshipsArray,
+            JsonObject blueprintNodeTemplateList, JsonObject blueprintInputList) throws BlueprintParserException {
+        for (JsonElement elem : relationshipsArray) {
+            if (blueprintNodeTemplateList.get(elem.getAsJsonObject().get(TARGET).getAsString()) == null) {
+                throw new BlueprintParserException(
+                        "The Target mentioned in the blueprint is not a known entry in the blueprint: "
+                                + elem.getAsJsonObject().get(TARGET).getAsString());
+            } else {
+                String property = getPropertyValue(propertyName,
+                        new AbstractMap.SimpleEntry<String, JsonElement>(
+                                elem.getAsJsonObject().get(TARGET).getAsString(), blueprintNodeTemplateList
+                                        .get(elem.getAsJsonObject().get(TARGET).getAsString()).getAsJsonObject()),
+                        blueprintNodeTemplateList, blueprintInputList);
+                if (!property.isEmpty()) {
+                    return property;
                 }
             }
         }
         return "";
     }
 
-    String getBlueprintName(Entry<String, JsonElement> entry) {
-        return entry.getKey();
+    static String getDirectOrInputPropertyValue(String propertyName, JsonObject blueprintInputList,
+            JsonObject nodeTemplateContent) {
+        JsonObject properties = nodeTemplateContent.get(PROPERTIES).getAsJsonObject();
+        if (properties.has(propertyName)) {
+            if (properties.get(propertyName).isJsonObject()) {
+                // it's a blueprint parameter
+                return blueprintInputList
+                        .get(properties.get(propertyName).getAsJsonObject().get(GET_INPUT).getAsString())
+                        .getAsJsonObject().get("default").getAsString();
+            } else {
+                // It's a direct value
+                return properties.get(propertyName).getAsString();
+            }
+        }
+        return "";
+    }
+
+    static String getPropertyValue(String propertyName, Entry<String, JsonElement> nodeTemplateEntry,
+            JsonObject blueprintNodeTemplateList, JsonObject blueprintIputList) throws BlueprintParserException {
+        JsonObject nodeTemplateContent = nodeTemplateEntry.getValue().getAsJsonObject();
+        // Search first in this node template
+        if (nodeTemplateContent.has(PROPERTIES)) {
+            String propValue = getDirectOrInputPropertyValue(propertyName, blueprintIputList, nodeTemplateContent);
+            if (!propValue.isBlank()) {
+                return propValue;
+            }
+        }
+        // Or it's may be defined in a relationship
+        if (nodeTemplateContent.has(RELATIONSHIPS)) {
+            return findPropertyInRelationshipsArray(propertyName,
+                    nodeTemplateContent.get(RELATIONSHIPS).getAsJsonArray(), blueprintNodeTemplateList,
+                    blueprintIputList);
+        }
+        return "";
     }
 
-    MicroService getNodeRepresentation(Entry<String, JsonElement> entry) {
-        String name = getName(entry);
-        String getInputFrom = getInput(entry);
-        String modelType = getModelType(entry);
-        String blueprintName = getBlueprintName(entry);
-        return new MicroService(name, modelType, getInputFrom, "", blueprintName);
+    static BlueprintMicroService getNodeRepresentation(Entry<String, JsonElement> nodeTemplateEntry,
+            JsonObject blueprintNodeTemplateList, JsonObject blueprintInputList) throws BlueprintParserException {
+        String modelIdFound = getPropertyValue(POLICY_MODEL_ID, nodeTemplateEntry, blueprintNodeTemplateList,
+                blueprintInputList);
+        String versionFound = getPropertyValue(POLICY_MODEL_VERSION, nodeTemplateEntry, blueprintNodeTemplateList,
+                blueprintInputList);
+        if (modelIdFound.isBlank()) {
+            logger.warn("policy_model_id is not defined for the node template:" + nodeTemplateEntry.getKey());
+        }
+        if (versionFound.isBlank()) {
+            logger.warn("policy_model_version is not defined (setting it to a default value) for the node template:"
+                    + nodeTemplateEntry.getKey());
+        }
+        return new BlueprintMicroService(getName(nodeTemplateEntry), modelIdFound, getInput(nodeTemplateEntry),
+                !versionFound.isBlank() ? versionFound : DEFAULT_VERSION);
     }
 
-    private String getTarget(JsonObject elementObject) {
+    private static String getTarget(JsonObject elementObject) {
         if (elementObject.has(TYPE) && elementObject.has(TARGET)
-            && elementObject.get(TYPE).getAsString().equals(CLAMP_NODE_RELATIONSHIPS_GETS_INPUT_FROM)) {
+                && elementObject.get(TYPE).getAsString().equals(CLAMP_NODE_RELATIONSHIPS_GETS_INPUT_FROM)) {
             return elementObject.get(TARGET).getAsString();
         }
         return "";
     }
 
     private static JsonObject convertToJson(String yamlString) {
-        Yaml yaml = new Yaml();
-        Map<String, Object> map = yaml.load(yamlString);
-
-        JSONObject jsonObject = new JSONObject(map);
-        return new Gson().fromJson(jsonObject.toString(), JsonObject.class);
+        Map<String, Object> map = new Yaml().load(yamlString);
+        return new Gson().fromJson(new JSONObject(map).toString(), JsonObject.class);
     }
 }