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