Merge "Fix invocation of resource receipe" into casablanca
[so.git] / bpmn / MSOCommonBPMN / src / main / java / org / onap / so / bpmn / common / resource / ResourceRequestBuilder.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
4  * ================================================================================
5  * Copyright (C) 2018 Huawei Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.so.bpmn.common.resource;
22
23 import java.io.File;
24 import java.io.IOException;
25 import java.util.ArrayList;
26 import java.util.HashMap;
27 import java.util.LinkedHashMap;
28 import java.util.List;
29 import java.util.Map;
30 import java.util.Optional;
31
32 import javax.ws.rs.core.Response;
33 import javax.ws.rs.core.UriBuilder;
34
35 import org.camunda.bpm.engine.runtime.Execution;
36 import org.onap.sdc.tosca.parser.api.ISdcCsarHelper;
37 import org.onap.sdc.tosca.parser.exceptions.SdcToscaParserException;
38 import org.onap.sdc.tosca.parser.impl.SdcToscaParserFactory;
39 import org.onap.sdc.toscaparser.api.NodeTemplate;
40 import org.onap.sdc.toscaparser.api.Property;
41 import org.onap.sdc.toscaparser.api.RequirementAssignment;
42 import org.onap.sdc.toscaparser.api.RequirementAssignments;
43 import org.onap.sdc.toscaparser.api.functions.GetInput;
44 import org.onap.sdc.toscaparser.api.parameters.Input;
45 import org.onap.so.bpmn.core.UrnPropertiesReader;
46 import org.onap.so.bpmn.core.json.JsonUtils;
47 import org.onap.so.client.HttpClient;
48 import org.onap.so.logger.MessageEnum;
49 import org.onap.so.logger.MsoLogger;
50 import org.onap.so.utils.TargetEntity;
51
52 import com.fasterxml.jackson.core.JsonProcessingException;
53 import com.fasterxml.jackson.databind.ObjectMapper;
54 import com.fasterxml.jackson.databind.SerializationFeature;
55 import com.google.gson.Gson;
56 import com.google.gson.reflect.TypeToken;
57
58 public class ResourceRequestBuilder {
59
60     private static String CUSTOMIZATION_UUID = "customizationUUID";
61
62     private static String SERVICE_URL_TOSCA_CSAR = "/v3/serviceToscaCsar";
63
64     private static MsoLogger LOGGER = MsoLogger.getMsoLogger(MsoLogger.Catalog.RA, ResourceRequestBuilder.class);
65
66     static JsonUtils jsonUtil = new JsonUtils();
67
68         public static List<String> getResourceSequence(Execution execution, String serviceUuid) {
69                 List<String> resouceSequence = new ArrayList<String>();
70                 List<NodeTemplate> resultList = new ArrayList<NodeTemplate>();
71                 String csarpath = null;
72                 try {
73                         csarpath = getCsarFromUuid(serviceUuid);
74
75                         SdcToscaParserFactory toscaParser = SdcToscaParserFactory.getInstance();
76                         ISdcCsarHelper iSdcCsarHelper = toscaParser.getSdcCsarHelper(csarpath, false);
77                         List<NodeTemplate> nodeTemplates = iSdcCsarHelper.getServiceNodeTemplates();
78                         List<NodeTemplate> nodes = new ArrayList<NodeTemplate>();
79                         nodes.addAll(nodeTemplates);
80
81                         for (NodeTemplate nodeTemplate : nodeTemplates) {
82                                 RequirementAssignments requirement = iSdcCsarHelper.getRequirementsOf(nodeTemplate);
83
84                                 if (requirement == null || requirement.getAll() == null || requirement.getAll().isEmpty()) {
85                                         resultList.add(nodeTemplate);
86                                         nodes.remove(nodeTemplate);
87                                 }
88                         }
89
90                         resultList = getRequirementList(resultList, nodes, iSdcCsarHelper);
91                         
92                         for (NodeTemplate node : resultList) {
93                                 String templateName = node.getMetaData().getValue("name");
94                                 if (!resouceSequence.contains(templateName)) {
95                                         resouceSequence.add(templateName);
96                                 }
97                         }
98
99                 } catch (SdcToscaParserException toscarParserE) {
100                         LOGGER.debug("sdc tosca parser failed for csar: " + csarpath, toscarParserE);
101                         return resouceSequence;
102                 } catch (Exception e) {
103                         LOGGER.debug("csar file is not available for service uuid:" + serviceUuid, e);
104                         return resouceSequence;
105                 }
106                 
107                 return resouceSequence;
108         }
109
110         private static List<NodeTemplate> getRequirementList(List<NodeTemplate> resultList, List<NodeTemplate> nodeTemplates,
111                         ISdcCsarHelper iSdcCsarHelper) {
112
113                 List<NodeTemplate> nodes = new ArrayList<NodeTemplate>();
114                 nodes.addAll(nodeTemplates);
115
116                 for (NodeTemplate nodeTemplate : nodeTemplates) {
117                         RequirementAssignments requirement = iSdcCsarHelper.getRequirementsOf(nodeTemplate);
118                         List<RequirementAssignment> reqAs = requirement.getAll();
119                         for (RequirementAssignment ra : reqAs) {
120                                 String reqNode = ra.getNodeTemplateName();
121                                 for (NodeTemplate rNode : resultList) {
122                                         if (rNode.getName().equals(reqNode)) {
123                                                 if(!resultList.contains(nodeTemplate)) {
124                                                         resultList.add(nodeTemplate);
125                                                 }
126                                                 if(nodes.contains(nodeTemplate)) {
127                                                         nodes.remove(nodeTemplate);
128                                                 }
129                                                 break;
130                                         }
131                                 }
132                         }
133                 }
134
135                 if (!nodes.isEmpty()) {
136                         getRequirementList(resultList, nodes, iSdcCsarHelper);
137                 }
138
139                 return resultList;
140         }
141
142      /* build the resource Parameters detail.
143      * It's a json string for resource instantiant
144      * {
145      *     "locationConstraints":[...]
146      *     "requestInputs":{K,V}
147      * }
148      * <br>
149      *
150      * @param execution Execution context
151      * @param serviceUuid The service template uuid
152      * @param resourceCustomizationUuid The resource customization uuid
153      * @param serviceParameters the service parameters passed from the API
154      * @return the resource instantiate parameters
155      * @since ONAP Beijing Release
156      */
157     @SuppressWarnings("unchecked")
158     public static String buildResourceRequestParameters(Execution execution, String serviceUuid, String resourceCustomizationUuid, String serviceParameters) {
159         List<String> resourceList = jsonUtil.StringArrayToList(execution, (String)JsonUtils.getJsonValue(serviceParameters, "resources"));
160         //Get the right location str for resource. default is an empty array.
161         String locationConstraints ="[]";
162         String resourceInputsFromUui = "";
163         for(String resource: resourceList){
164             String resCusUuid = (String)JsonUtils.getJsonValue(resource, "resourceCustomizationUuid");
165             if(resourceCustomizationUuid.equals(resCusUuid)){
166                 String resourceParameters = JsonUtils.getJsonValue(resource, "parameters");
167                 locationConstraints = JsonUtils.getJsonValue(resourceParameters, "locationConstraints");
168                 resourceInputsFromUui = JsonUtils.getJsonValue(resourceParameters, "requestInputs");
169             }
170         }
171         Map<String, Object> serviceInput = null;
172         if (JsonUtils.getJsonValue(serviceParameters, "requestInputs") != null) {
173             serviceInput = getJsonObject((String)JsonUtils.getJsonValue(serviceParameters, "requestInputs"), Map.class);
174         }
175
176         Map<String, Object> resourceInputsFromUuiMap = getJsonObject(resourceInputsFromUui, Map.class);
177
178         if (serviceInput == null) {
179             serviceInput = new HashMap();
180         }
181
182         if (resourceInputsFromUuiMap == null) {
183             resourceInputsFromUuiMap = new HashMap();
184         }
185
186         try {
187             Map<String, Object> resourceInputsFromServiceDeclaredLevel = buildResouceRequest(serviceUuid, resourceCustomizationUuid, serviceInput);
188             resourceInputsFromUuiMap.putAll(resourceInputsFromServiceDeclaredLevel);
189         } catch(SdcToscaParserException e) {
190                 LOGGER.error("SdcToscaParserException", e);
191         }
192         String resourceInputsStr = getJsonString(resourceInputsFromUuiMap);
193         String result = "{\n"
194                 + "\"locationConstraints\":" + locationConstraints +",\n"
195                 + "\"requestInputs\":" + resourceInputsStr +"\n"
196                 +"}";
197         return result;
198     }
199
200     public static Map<String, Object> buildResouceRequest(String serviceUuid, String resourceCustomizationUuid, Map<String, Object> serviceInputs)
201             throws SdcToscaParserException {
202
203         Map<String, Object> resouceRequest = new HashMap<>();
204
205         String csarpath = null;
206         try {
207             csarpath = getCsarFromUuid(serviceUuid);
208         } catch(Exception e) {
209             LOGGER.debug("csar file is not available for service uuid:" + serviceUuid, e);
210             return resouceRequest;
211         }
212
213         SdcToscaParserFactory toscaParser = SdcToscaParserFactory.getInstance();
214         ISdcCsarHelper iSdcCsarHelper = toscaParser.getSdcCsarHelper(csarpath, false);
215
216         List<Input> serInput = iSdcCsarHelper.getServiceInputs();
217         Optional<NodeTemplate> nodeTemplateOpt = iSdcCsarHelper.getServiceNodeTemplates().stream()
218                 .filter(e -> e.getMetaData().getValue(CUSTOMIZATION_UUID).equals(resourceCustomizationUuid)).findFirst();
219
220         if(nodeTemplateOpt.isPresent()) {
221             NodeTemplate nodeTemplate = nodeTemplateOpt.get();
222             LinkedHashMap<String, Property> resourceProperties = nodeTemplate.getProperties();
223
224             for(String key : resourceProperties.keySet()) {
225                 Property property = resourceProperties.get(key);
226
227                 Object value = getValue(property.getValue(), serviceInputs, serInput);
228                 resouceRequest.put(key, value);
229             }
230         }
231         return resouceRequest;
232     }
233
234     private static Object getValue(Object value, Map<String, Object> serviceInputs, List<Input> servInputs) {
235         if(value instanceof Map) {
236             Map<String, Object> valueMap = new HashMap<>();
237
238             Map<String, Object> propertyMap = (Map<String, Object>)value;
239
240             for(String key : propertyMap.keySet()) {
241                 valueMap.put(key, getValue(propertyMap.get(key), serviceInputs, servInputs));
242             }
243             return valueMap; // return if the value is nested hashmap
244         } else if(value instanceof GetInput) {
245             String inputName = ((GetInput)value).getInputName();
246
247             if(serviceInputs.get(inputName) != null) {
248                 value = serviceInputs.get(inputName);
249             } else {
250                 for(Input input : servInputs) {
251                     if(input.getName().equals(inputName)) {
252                         return input.getDefault(); // return default value
253                     }
254                 }
255             }
256         }
257         return value; // return property value
258     }
259
260     private static String getCsarFromUuid(String uuid) throws Exception {
261                 String catalogEndPoint = UrnPropertiesReader.getVariable("mso.catalog.db.endpoint");
262         HttpClient client = new HttpClient(UriBuilder.fromUri(catalogEndPoint).path(SERVICE_URL_TOSCA_CSAR).queryParam("serviceModelUuid", uuid).build().toURL(), "application/json", TargetEntity.CATALOG_DB);
263         
264         Response response = client.get();
265         String value = response.readEntity(String.class);
266
267         HashMap<String, String> map = new Gson().fromJson(value, new TypeToken<HashMap<String, String>>() {}.getType());
268
269         String filePath = System.getProperty("mso.config.path") + "/ASDC/" +  map.get("version") + "/" + map.get("name");
270
271         File csarFile = new File(filePath);
272
273         if(!csarFile.exists()) {
274             throw new Exception("csar file does not exist.");
275         }
276
277         return csarFile.getAbsolutePath();
278     }
279     
280     public static <T> T getJsonObject(String jsonstr, Class<T> type) {
281         ObjectMapper mapper = new ObjectMapper();
282         mapper.configure(SerializationFeature.WRAP_ROOT_VALUE, true);
283         try {
284             return mapper.readValue(jsonstr, type);
285         } catch(IOException e) {
286             LOGGER.error(MessageEnum.RA_NS_EXC, "", "", MsoLogger.ErrorCode.BusinessProcesssError, "fail to unMarshal json", e);
287         }
288         return null;
289     }
290
291     public static String getJsonString(Object srcObj)  {
292         ObjectMapper mapper = new ObjectMapper();
293         mapper.configure(SerializationFeature.WRAP_ROOT_VALUE, false);
294         String jsonStr = null;
295         try {
296             jsonStr = mapper.writeValueAsString(srcObj);
297         } catch(JsonProcessingException e) {
298                 LOGGER.error("SdcToscaParserException", e);
299         }
300         return jsonStr;
301     }
302 }