Merge "Fix vulnerability report"
[externalapi/nbi.git] / src / main / java / org / onap / nbi / apis / servicecatalog / ToscaInfosProcessor.java
1 /**
2  *     Copyright (c) 2018 Orange
3  *
4  *     Licensed under the Apache License, Version 2.0 (the "License");
5  *     you may not use this file except in compliance with the License.
6  *     You may obtain a copy of the License at
7  *
8  *         http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *     Unless required by applicable law or agreed to in writing, software
11  *     distributed under the License is distributed on an "AS IS" BASIS,
12  *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *     See the License for the specific language governing permissions and
14  *     limitations under the License.
15  */
16 package org.onap.nbi.apis.servicecatalog;
17
18 import java.io.File;
19 import java.io.FileInputStream;
20 import java.io.FileOutputStream;
21 import java.io.IOException;
22 import java.sql.Timestamp;
23 import java.util.ArrayList;
24 import java.util.LinkedHashMap;
25 import java.util.List;
26 import java.util.zip.ZipEntry;
27 import java.util.zip.ZipInputStream;
28 import org.apache.commons.collections.CollectionUtils;
29 import org.apache.commons.io.FileUtils;
30 import org.onap.nbi.exceptions.TechnicalException;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
33 import org.springframework.beans.factory.annotation.Autowired;
34 import org.springframework.stereotype.Service;
35 import com.fasterxml.jackson.databind.ObjectMapper;
36 import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
37
38 @Service
39 public class ToscaInfosProcessor {
40
41     @Autowired
42     SdcClient sdcClient;
43
44     final ObjectMapper mapper = new ObjectMapper(new YAMLFactory()); // jackson databind
45
46     private static final Logger LOGGER = LoggerFactory.getLogger(ToscaInfosProcessor.class);
47
48     public void buildResponseWithToscaInfos(LinkedHashMap toscaInfosTopologyTemplate,
49             LinkedHashMap serviceCatalogResponse) {
50         if (toscaInfosTopologyTemplate.get("inputs") != null) {
51             ArrayList serviceSpecCharacteristic = new ArrayList();
52             LinkedHashMap toscaInfos = (LinkedHashMap) toscaInfosTopologyTemplate.get("inputs");
53             for (Object key : toscaInfos.keySet()) {
54                 String keyString = (String) key;
55                 LinkedHashMap inputParameter = (LinkedHashMap) toscaInfos.get(key);
56                 LinkedHashMap mapParameter = new LinkedHashMap();
57                 String parameterType = (String) inputParameter.get("type");
58                 mapParameter.put("name", keyString);
59                 mapParameter.put("description", inputParameter.get("description"));
60                 mapParameter.put("valueType", parameterType);
61                 mapParameter.put("@type", "ONAPserviceCharacteristic");
62                 mapParameter.put("required", inputParameter.get("required"));
63                 mapParameter.put("status", inputParameter.get("status"));
64                 List<LinkedHashMap> serviceSpecCharacteristicValues =
65                         buildServiceSpecCharacteristicsValues(inputParameter, parameterType);
66                 mapParameter.put("serviceSpecCharacteristicValue", serviceSpecCharacteristicValues);
67                 serviceSpecCharacteristic.add(mapParameter);
68             }
69
70             serviceCatalogResponse.put("serviceSpecCharacteristic", serviceSpecCharacteristic);
71         }
72         LinkedHashMap node_templates = (LinkedHashMap) toscaInfosTopologyTemplate.get("node_templates");
73
74         List<LinkedHashMap> resourceSpecifications =
75                 (List<LinkedHashMap>) serviceCatalogResponse.get("resourceSpecification");
76         for (LinkedHashMap resourceSpecification : resourceSpecifications) {
77             String id = (String) resourceSpecification.get("id");
78             LOGGER.debug("get tosca infos for service id: " + id);
79             LinkedHashMap toscaInfosFromResourceId = getToscaInfosFromResourceUUID(node_templates, id);
80             resourceSpecification.put("modelCustomizationId", toscaInfosFromResourceId.get("customizationUUID"));
81             resourceSpecification.put("modelCustomizationName", toscaInfosFromResourceId.get("name"));
82
83         }
84     }
85
86     private List<LinkedHashMap> buildServiceSpecCharacteristicsValues(LinkedHashMap parameter, String parameterType) {
87         List<LinkedHashMap> serviceSpecCharacteristicValues = new ArrayList<>();
88         if (!"map".equalsIgnoreCase(parameterType) && !"list".equalsIgnoreCase(parameterType)) {
89             LOGGER.debug("get tosca infos for serviceSpecCharacteristicValues of type map or string : " + parameter);
90             Object aDefault = parameter.get("default");
91             if (parameter.get("entry_schema") != null) {
92                 ArrayList entry_schema = (ArrayList) parameter.get("entry_schema");
93                 if (CollectionUtils.isNotEmpty(entry_schema)) {
94                     buildCharacteristicValuesFormShema(parameterType, serviceSpecCharacteristicValues, aDefault,
95                             entry_schema);
96                 }
97             }
98         }
99         return serviceSpecCharacteristicValues;
100     }
101
102     private void buildCharacteristicValuesFormShema(String parameterType,
103             List<LinkedHashMap> serviceSpecCharacteristicValues, Object aDefault, ArrayList entry_schema) {
104         LinkedHashMap constraints = (LinkedHashMap) entry_schema.get(0);
105         if (constraints != null) {
106             ArrayList constraintsList = (ArrayList) constraints.get("constraints");
107             if (CollectionUtils.isNotEmpty(constraintsList)) {
108                 LinkedHashMap valuesMap = (LinkedHashMap) constraintsList.get(0);
109                 if (valuesMap != null) {
110                     List<Object> values = (List<Object>) valuesMap.get("valid_values");
111                     for (Object value : values) {
112                         String stringValue = value.toString();
113                         LinkedHashMap serviceSpecCharacteristicValue = new LinkedHashMap();
114                         serviceSpecCharacteristicValue.put("isDefault",
115                                 aDefault != null && aDefault.toString().equals(stringValue));
116                         serviceSpecCharacteristicValue.put("value", stringValue);
117                         serviceSpecCharacteristicValue.put("valueType", parameterType);
118                         serviceSpecCharacteristicValues.add(serviceSpecCharacteristicValue);
119                     }
120                 }
121             }
122         }
123     }
124
125
126     private LinkedHashMap getToscaInfosFromResourceUUID(LinkedHashMap node_templates, String name) {
127         for (Object nodeTemplateObject : node_templates.values()) {
128             LinkedHashMap nodeTemplate = (LinkedHashMap) nodeTemplateObject;
129             LinkedHashMap metadata = (LinkedHashMap) nodeTemplate.get("metadata");
130             String metadataUUID = (String) metadata.get("UUID");
131             String metadataType = (String) metadata.get("type");
132             if ("VF".equalsIgnoreCase(metadataType) && name.equalsIgnoreCase(metadataUUID)) {
133                 return metadata;
134             }
135         }
136         return null;
137     }
138
139
140     public LinkedHashMap getToscaInfos(LinkedHashMap sdcResponse) {
141         String toscaModelUrl = (String) sdcResponse.get("toscaModelURL");
142         String serviceId = (String) sdcResponse.get("uuid");
143         File toscaFile = sdcClient.callGetWithAttachment(toscaModelUrl);
144         Timestamp timestamp = new Timestamp(System.currentTimeMillis());
145         String tempFolderName = serviceId + timestamp;
146         File folderTemp = null;
147         LinkedHashMap topology_template = null;
148         try {
149             unZipArchive(toscaFile.getName(), tempFolderName);
150             folderTemp = new File(tempFolderName);
151             LOGGER.debug("temp folder for tosca files : " + folderTemp.getName());
152
153             LinkedHashMap toscaMetaFileHashMap = parseToscaFile(tempFolderName + "/TOSCA-Metadata/TOSCA.meta");
154             if (toscaMetaFileHashMap.get("Entry-Definitions") == null) {
155                 throw new NullPointerException("no Entry-Definitions node in TOSCA.meta");
156             }
157             String toscaFilePath = (String) toscaMetaFileHashMap.get("Entry-Definitions");
158             LinkedHashMap toscaFileHashMap = parseToscaFile(tempFolderName + "/" + toscaFilePath);
159
160             if (toscaFileHashMap.get("topology_template") == null) {
161                 throw new NullPointerException("no topology_template node in tosca file");
162             }
163             topology_template = (LinkedHashMap) toscaFileHashMap.get("topology_template");
164
165         } catch (NullPointerException e) {
166             LOGGER.error("unable to parse tosca file for id : " + serviceId + ", " + e.getMessage());
167             return null;
168         } finally {
169             try {
170                 LOGGER.debug("deleting temp folder for tosca files : " + folderTemp.getName());
171                 FileUtils.deleteDirectory(folderTemp);
172                 LOGGER.debug("deleting tosca archive : " + toscaFile.getName());
173                 FileUtils.forceDelete(toscaFile);
174                 return topology_template;
175             } catch (IOException e) {
176                 LOGGER.error("unable to delete temp directory tosca file for id : " + serviceId);
177                 return null;
178
179             }
180         }
181     }
182
183
184     private LinkedHashMap parseToscaFile(String fileName) {
185
186         File toscaFile = new File(fileName);
187         if (toscaFile == null) {
188             throw new TechnicalException("unable to find  file : " + fileName);
189         }
190         try {
191             return (LinkedHashMap) mapper.readValue(toscaFile, Object.class);
192         } catch (IOException e) {
193             LOGGER.error("unable to parse tosca file : " + fileName);
194             LOGGER.error(e.getMessage());
195             throw new TechnicalException("Unable to parse tosca file : " + fileName);
196
197         } catch (NullPointerException e) {
198             LOGGER.error("unable to find tosca file : " + fileName);
199             LOGGER.error(e.getMessage());
200             throw new TechnicalException("unable to find tosca file : " + fileName);
201         }
202     }
203
204
205     /**
206      * Unzip it
207      *
208      * @param zipFile input zip file
209      * @param outputFolder zip file output folder
210      */
211     private void unZipArchive(String zipFile, String outputFolder) {
212
213         byte[] buffer = new byte[1024];
214
215         try {
216
217             // create output directory is not exists
218             File folder = new File(outputFolder);
219             if (!folder.exists()) {
220                 folder.mkdir();
221             }
222
223             // get the zip file content
224             try (ZipInputStream zis = new ZipInputStream(new FileInputStream(zipFile))) {
225                 // get the zipped file list entry
226                 ZipEntry ze = zis.getNextEntry();
227
228                 while (ze != null) {
229
230                     String fileName = ze.getName();
231                     File newFile = new File(outputFolder + File.separator + fileName);
232
233                     LOGGER.debug("File to unzip : " + newFile.getAbsoluteFile());
234
235                     // create all non exists folders
236                     // else you will hit FileNotFoundException for compressed folder
237                     new File(newFile.getParent()).mkdirs();
238
239                     try (FileOutputStream fos = new FileOutputStream(newFile)) {
240
241                         int len;
242                         while ((len = zis.read(buffer)) > 0) {
243                             fos.write(buffer, 0, len);
244                         }
245
246                         fos.close();
247                     }
248                     ze = zis.getNextEntry();
249                 }
250
251                 zis.closeEntry();
252                 zis.close();
253             }
254
255             LOGGER.debug("Done");
256
257         } catch (IOException ex) {
258             LOGGER.error("Error while unzipping ToscaModel archive from ONAP : " + ex.getMessage());
259             throw new TechnicalException("Error while unzipping ToscaModel archive from ONAP");
260         }
261     }
262
263
264 }