Merge "Removing so-monitoring module"
[so.git] / so-etsi-nfvo / so-etsi-nfvo-ns-lcm / so-etsi-nfvo-ns-lcm-bpmn-flows / src / main / java / org / onap / so / etsi / nfvo / ns / lcm / bpmn / flows / nsd / parser / NetworkServiceDescriptorParser.java
1 /*-
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2020 Nordix Foundation.
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  * SPDX-License-Identifier: Apache-2.0
18  * ============LICENSE_END=========================================================
19  */
20 package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.nsd.parser;
21
22 import java.io.ByteArrayInputStream;
23 import java.io.IOException;
24 import java.util.ArrayList;
25 import java.util.Collections;
26 import java.util.HashMap;
27 import java.util.List;
28 import java.util.Map;
29 import java.util.Map.Entry;
30 import java.util.Optional;
31 import java.util.zip.ZipEntry;
32 import java.util.zip.ZipInputStream;
33 import org.apache.commons.io.IOUtils;
34 import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.nsd.FileEntry;
35 import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.nsd.NetworkServiceDescriptor;
36 import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.nsd.ToscaMetadata;
37 import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.nsd.VirtualNetworkFunction;
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory;
40 import org.springframework.beans.factory.annotation.Autowired;
41 import org.springframework.stereotype.Service;
42
43 /**
44  * @author Waqas Ikram (waqas.ikram@est.tech)
45  *
46  */
47 @Service
48 public class NetworkServiceDescriptorParser {
49     public static final String NS_NODE_TYPE = "tosca.nodes.nfv.NS";
50     private static final String NODE_TYPE = "node_type";
51     private static final String SUBSTITUTION_MAPPINGS = "substitution_mappings";
52     private static final Logger logger = LoggerFactory.getLogger(NetworkServiceDescriptorParser.class);
53     private static final String VNF_TYPE = "tosca.nodes.nfv.VNF";
54     private static final String PROPERTIES = "properties";
55     private static final String TYPE = "type";
56     private static final String NODE_TEMPLATES = "node_templates";
57     private static final String TOPOLOGY_TEMPLATE = "topology_template";
58     private static final String ENTRY_DEFINITIONS = "Entry-Definitions";
59     private static final String TOSCA_META_PATH_FILE_NAME = "TOSCA-Metadata/TOSCA.meta";
60     private final ToscaMetadataParser toscaMetadataParser;
61     private final FileParser fileParser;
62
63     @Autowired
64     public NetworkServiceDescriptorParser(final ToscaMetadataParser toscaMetadataParser, final FileParser fileParser) {
65         this.toscaMetadataParser = toscaMetadataParser;
66         this.fileParser = fileParser;
67     }
68
69     public Optional<NetworkServiceDescriptor> parse(final byte[] zipBytes) {
70         try {
71             final Map<String, FileEntry> files = getZipContent(zipBytes);
72             if (isMetaFilePresent(files)) {
73                 final Optional<ToscaMetadata> optional =
74                         toscaMetadataParser.parse(files.get(TOSCA_META_PATH_FILE_NAME));
75                 if (optional.isPresent()) {
76                     final ToscaMetadata toscaMetadata = optional.get();
77                     logger.info("Parsed ToscaMetadata {}", toscaMetadata);
78                     final String entryDefinitionFile = toscaMetadata.getEntry(ENTRY_DEFINITIONS);
79                     if (entryDefinitionFile != null && files.containsKey(entryDefinitionFile)) {
80                         final Map<String, Object> fileContent =
81                                 fileParser.getFileContent(files.get(entryDefinitionFile));
82                         final Map<String, Object> topologyTemplates = getTopologyTemplates(fileContent);
83                         final Map<String, Object> nodeTemplates = getNodeTemplates(topologyTemplates);
84
85                         final Optional<NetworkServiceDescriptor> nsdOptional =
86                                 getNetworkServiceDescriptor(topologyTemplates);
87                         if (nsdOptional.isPresent()) {
88                             final NetworkServiceDescriptor networkServiceDescriptor = nsdOptional.get();
89                             networkServiceDescriptor.setVnfs(getVirtualNetworkFunctions(nodeTemplates));
90                             return Optional.of(networkServiceDescriptor);
91                         }
92
93                     }
94                 }
95
96             }
97
98             logger.error("Unable to find {} file in {}", TOSCA_META_PATH_FILE_NAME, files);
99         } catch (final Exception exception) {
100             logger.error("Unable to parse nsd zip content", exception);
101         }
102         return Optional.empty();
103     }
104
105     @SuppressWarnings("unchecked")
106     private Optional<NetworkServiceDescriptor> getNetworkServiceDescriptor(
107             final Map<String, Object> topologyTemplates) {
108         final Map<String, Object> substitutionMappings =
109                 (Map<String, Object>) topologyTemplates.get(SUBSTITUTION_MAPPINGS);
110         final Object nodeType = substitutionMappings.get(NODE_TYPE);
111         if (substitutionMappings != null && NS_NODE_TYPE.equals(nodeType)) {
112             final NetworkServiceDescriptor networkServiceDescriptor = new NetworkServiceDescriptor();
113             networkServiceDescriptor.setType(nodeType.toString());
114             networkServiceDescriptor.setProperties((Map<String, Object>) substitutionMappings.get(PROPERTIES));
115             return Optional.of(networkServiceDescriptor);
116         }
117         logger.error("No {} found in fileContent: {}", SUBSTITUTION_MAPPINGS, topologyTemplates);
118
119         return Optional.empty();
120     }
121
122     private List<VirtualNetworkFunction> getVirtualNetworkFunctions(final Map<String, Object> nodeTemplates) {
123         final List<VirtualNetworkFunction> vnfs = new ArrayList<>();
124         for (final Entry<String, Object> entry : nodeTemplates.entrySet()) {
125             @SuppressWarnings("unchecked")
126             final Map<String, Object> entryValue = (Map<String, Object>) entry.getValue();
127             final Object type = entryValue.get(TYPE);
128             if (type != null && type.equals(VNF_TYPE)) {
129                 @SuppressWarnings("unchecked")
130                 final Map<String, Object> vnfProperties = (Map<String, Object>) entryValue.get(PROPERTIES);
131                 final VirtualNetworkFunction vnf = new VirtualNetworkFunction();
132                 vnf.setVnfName(entry.getKey());
133
134                 if (vnfProperties != null && !vnfProperties.isEmpty()) {
135                     final Object vnfDescriptorId = vnfProperties.get("descriptor_id");
136                     @SuppressWarnings("unchecked")
137                     final List<String> vnfmInfoList = (List<String>) vnfProperties.get("vnfm_info");
138                     if (vnfDescriptorId != null && vnfmInfoList != null) {
139                         vnf.setVnfmInfoList(vnfmInfoList);
140                         vnf.setVnfdId(vnfDescriptorId.toString());
141                         vnf.setProperties(vnfProperties);
142                         vnfs.add(vnf);
143                     } else {
144                         logger.warn("descriptor_id missing {}", entryValue);
145                     }
146                 }
147             }
148
149         }
150         return vnfs;
151     }
152
153     private Map<String, Object> getNodeTemplates(final Map<String, Object> topologyTemplates) {
154         @SuppressWarnings("unchecked")
155         final Map<String, Object> nodeTemplates = (Map<String, Object>) topologyTemplates.get(NODE_TEMPLATES);
156         if (nodeTemplates != null) {
157             logger.debug("Found nodeTemplates: {}", topologyTemplates);
158             return nodeTemplates;
159         }
160         logger.error("No {} found in fileContent: {}", NODE_TEMPLATES, topologyTemplates);
161         return Collections.emptyMap();
162     }
163
164     private Map<String, Object> getTopologyTemplates(final Map<String, Object> fileContent) {
165         @SuppressWarnings("unchecked")
166         final Map<String, Object> topologyTemplates = (Map<String, Object>) fileContent.get(TOPOLOGY_TEMPLATE);
167         if (topologyTemplates != null) {
168             logger.debug("Found {}: {}", TOPOLOGY_TEMPLATE, topologyTemplates);
169
170             return topologyTemplates;
171         }
172         logger.error("No {} found in fileContent: {}", TOPOLOGY_TEMPLATE, fileContent);
173         return Collections.emptyMap();
174     }
175
176     private boolean isMetaFilePresent(final Map<String, FileEntry> files) {
177         return files.containsKey(TOSCA_META_PATH_FILE_NAME);
178     }
179
180     private Map<String, FileEntry> getZipContent(final byte[] zipBytes) {
181         final Map<String, FileEntry> files = new HashMap<>();
182         try (final ZipInputStream inputZipStream = new ZipInputStream(new ByteArrayInputStream(zipBytes));) {
183             ZipEntry zipEntry;
184             while ((zipEntry = inputZipStream.getNextEntry()) != null) {
185                 logger.info("{} : {}", zipEntry.getName(), zipEntry.isDirectory());
186                 if (files.get(zipEntry.getName()) != null) {
187                     logger.warn("{} File entry already exists ...", zipEntry.getName());
188                 } else {
189                     final FileEntry fileEntry = new FileEntry().filePath(zipEntry.getName())
190                             .fileContent(getBytes(inputZipStream)).isDirectory(zipEntry.isDirectory());
191                     files.put(zipEntry.getName(), fileEntry);
192
193                 }
194
195             }
196             return files;
197         } catch (final Exception exception) {
198             logger.error("Unable to parse nsd zip content", exception);
199             return Collections.emptyMap();
200         }
201     }
202
203     private byte[] getBytes(final ZipInputStream inputZipStream) throws IOException {
204         try {
205             return IOUtils.toByteArray(inputZipStream);
206         } catch (final IOException exception) {
207             logger.error("Could not read bytes from file", exception);
208             throw exception;
209         }
210     }
211
212
213 }