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