981a2041673eb0c92ed0d7a23d93f39670a1aa9a
[clamp.git] / src / main / java / org / onap / clamp / clds / sdc / controller / installer / BlueprintParser.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP CLAMP
4  * ================================================================================
5  * Copyright (C) 2019 Nokia Intellectual Property. All rights
6  *                             reserved.
7  * ================================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ============LICENSE_END============================================
20  * Modifications copyright (c) 2019 AT&T
21  * ===================================================================
22  *
23  */
24
25 package org.onap.clamp.clds.sdc.controller.installer;
26
27 import com.att.eelf.configuration.EELFLogger;
28 import com.att.eelf.configuration.EELFManager;
29 import com.google.gson.Gson;
30 import com.google.gson.JsonArray;
31 import com.google.gson.JsonElement;
32 import com.google.gson.JsonObject;
33
34 import java.util.AbstractMap;
35 import java.util.Collections;
36 import java.util.HashSet;
37 import java.util.List;
38 import java.util.Map;
39 import java.util.Map.Entry;
40 import java.util.Set;
41
42 import org.json.JSONObject;
43 import org.onap.clamp.clds.exception.sdc.controller.BlueprintParserException;
44 import org.yaml.snakeyaml.Yaml;
45
46 public class BlueprintParser {
47
48     static final String TCA = "TCA";
49     private static final String NODE_TEMPLATES = "node_templates";
50     private static final String DCAE_NODES = "dcae.nodes.";
51     private static final String DCAE_NODES_POLICY = "dcae.nodes.policy";
52     private static final String TYPE = "type";
53     private static final String PROPERTIES = "properties";
54     private static final String NAME = "name";
55     private static final String INPUT = "inputs";
56     private static final String GET_INPUT = "get_input";
57     private static final String POLICY_MODEL_ID = "policy_model_id";
58     private static final String POLICY_MODEL_VERSION = "policy_model_version";
59     private static final String RELATIONSHIPS = "relationships";
60     private static final String CLAMP_NODE_RELATIONSHIPS_GETS_INPUT_FROM = "clamp_node.relationships.gets_input_from";
61     private static final String TARGET = "target";
62     public static final String DEFAULT_VERSION = "1.0.0";
63
64     private static final EELFLogger logger = EELFManager.getInstance().getLogger(BlueprintParser.class);
65
66     private BlueprintParser() {
67
68     }
69
70     /**
71      * Get all micro services from blueprint.
72      * 
73      * @param blueprintString the blueprint in a String
74      * @return A set of MircoService
75      * @throws BlueprintParserException In case of issues with the parsing
76      */
77     public static Set<BlueprintMicroService> getMicroServices(String blueprintString) throws BlueprintParserException {
78         Set<BlueprintMicroService> microServices = new HashSet<>();
79         JsonObject blueprintJson = BlueprintParser.convertToJson(blueprintString);
80         JsonObject nodeTemplateList = blueprintJson.get(NODE_TEMPLATES).getAsJsonObject();
81         JsonObject inputList = blueprintJson.get(INPUT).getAsJsonObject();
82
83         for (Entry<String, JsonElement> entry : nodeTemplateList.entrySet()) {
84             JsonObject nodeTemplate = entry.getValue().getAsJsonObject();
85             if (!nodeTemplate.get(TYPE).getAsString().contains(DCAE_NODES_POLICY)
86                     && nodeTemplate.get(TYPE).getAsString().contains(DCAE_NODES)) {
87                 BlueprintMicroService microService = getNodeRepresentation(entry, nodeTemplateList, inputList);
88                 if (!microService.getModelType().isBlank()) {
89                     microServices.add(microService);
90                 } else {
91                     logger.warn("Microservice " + microService.getName()
92                             + " will NOT be used by CLAMP as the model type is not defined or has not been found");
93                 }
94             }
95         }
96         logger.debug("Those microservices have been found in the blueprint:" + microServices);
97         return microServices;
98     }
99
100     /**
101      * Does a fallback to TCA.
102      * 
103      * @return The list of microservices
104      */
105     public static List<BlueprintMicroService> fallbackToOneMicroService() {
106         return Collections.singletonList(
107                 new BlueprintMicroService(TCA, "onap.policies.monitoring.cdap.tca.hi.lo.app", "", DEFAULT_VERSION));
108     }
109
110     static String getName(Entry<String, JsonElement> entry) {
111         String microServiceYamlName = entry.getKey();
112         JsonObject ob = entry.getValue().getAsJsonObject();
113         if (ob.has(PROPERTIES)) {
114             JsonObject properties = ob.get(PROPERTIES).getAsJsonObject();
115             if (properties.has(NAME)) {
116                 return properties.get(NAME).getAsString();
117             }
118         }
119         return microServiceYamlName;
120     }
121
122     static String getInput(Entry<String, JsonElement> entry) {
123         JsonObject ob = entry.getValue().getAsJsonObject();
124         if (ob.has(RELATIONSHIPS)) {
125             JsonArray relationships = ob.getAsJsonArray(RELATIONSHIPS);
126             for (JsonElement element : relationships) {
127                 String target = getTarget(element.getAsJsonObject());
128                 if (!target.isEmpty()) {
129                     return target;
130                 }
131             }
132         }
133         return "";
134     }
135
136     static String findPropertyInRelationshipsArray(String propertyName, JsonArray relationshipsArray,
137             JsonObject blueprintNodeTemplateList, JsonObject blueprintInputList) throws BlueprintParserException {
138         for (JsonElement elem : relationshipsArray) {
139             if (blueprintNodeTemplateList.get(elem.getAsJsonObject().get(TARGET).getAsString()) == null) {
140                 throw new BlueprintParserException(
141                         "The Target mentioned in the blueprint is not a known entry in the blueprint: "
142                                 + elem.getAsJsonObject().get(TARGET).getAsString());
143             } else {
144                 String property = getPropertyValue(propertyName,
145                         new AbstractMap.SimpleEntry<String, JsonElement>(
146                                 elem.getAsJsonObject().get(TARGET).getAsString(), blueprintNodeTemplateList
147                                         .get(elem.getAsJsonObject().get(TARGET).getAsString()).getAsJsonObject()),
148                         blueprintNodeTemplateList, blueprintInputList);
149                 if (!property.isEmpty()) {
150                     return property;
151                 }
152             }
153         }
154         return "";
155     }
156
157     static String getDirectOrInputPropertyValue(String propertyName, JsonObject blueprintInputList,
158             JsonObject nodeTemplateContent) {
159         JsonObject properties = nodeTemplateContent.get(PROPERTIES).getAsJsonObject();
160         if (properties.has(propertyName)) {
161             if (properties.get(propertyName).isJsonObject()) {
162                 // it's a blueprint parameter
163                 return blueprintInputList
164                         .get(properties.get(propertyName).getAsJsonObject().get(GET_INPUT).getAsString())
165                         .getAsJsonObject().get("default").getAsString();
166             } else {
167                 // It's a direct value
168                 return properties.get(propertyName).getAsString();
169             }
170         }
171         return "";
172     }
173
174     static String getPropertyValue(String propertyName, Entry<String, JsonElement> nodeTemplateEntry,
175             JsonObject blueprintNodeTemplateList, JsonObject blueprintIputList) throws BlueprintParserException {
176         JsonObject nodeTemplateContent = nodeTemplateEntry.getValue().getAsJsonObject();
177         // Search first in this node template
178         if (nodeTemplateContent.has(PROPERTIES)) {
179             String propValue = getDirectOrInputPropertyValue(propertyName, blueprintIputList, nodeTemplateContent);
180             if (!propValue.isBlank()) {
181                 return propValue;
182             }
183         }
184         // Or it's may be defined in a relationship
185         if (nodeTemplateContent.has(RELATIONSHIPS)) {
186             return findPropertyInRelationshipsArray(propertyName,
187                     nodeTemplateContent.get(RELATIONSHIPS).getAsJsonArray(), blueprintNodeTemplateList,
188                     blueprintIputList);
189         }
190         return "";
191     }
192
193     static BlueprintMicroService getNodeRepresentation(Entry<String, JsonElement> nodeTemplateEntry,
194             JsonObject blueprintNodeTemplateList, JsonObject blueprintInputList) throws BlueprintParserException {
195         String modelIdFound = getPropertyValue(POLICY_MODEL_ID, nodeTemplateEntry, blueprintNodeTemplateList,
196                 blueprintInputList);
197         String versionFound = getPropertyValue(POLICY_MODEL_VERSION, nodeTemplateEntry, blueprintNodeTemplateList,
198                 blueprintInputList);
199         if (modelIdFound.isBlank()) {
200             logger.warn("policy_model_id is not defined for the node template:" + nodeTemplateEntry.getKey());
201         }
202         if (versionFound.isBlank()) {
203             logger.warn("policy_model_version is not defined (setting it to a default value) for the node template:"
204                     + nodeTemplateEntry.getKey());
205         }
206         return new BlueprintMicroService(getName(nodeTemplateEntry), modelIdFound, getInput(nodeTemplateEntry),
207                 !versionFound.isBlank() ? versionFound : DEFAULT_VERSION);
208     }
209
210     private static String getTarget(JsonObject elementObject) {
211         if (elementObject.has(TYPE) && elementObject.has(TARGET)
212                 && elementObject.get(TYPE).getAsString().equals(CLAMP_NODE_RELATIONSHIPS_GETS_INPUT_FROM)) {
213             return elementObject.get(TARGET).getAsString();
214         }
215         return "";
216     }
217
218     private static JsonObject convertToJson(String yamlString) {
219         Map<String, Object> map = new Yaml().load(yamlString);
220         return new Gson().fromJson(new JSONObject(map).toString(), JsonObject.class);
221     }
222 }