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