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