ac0e882414a90432549abfa1be8001b951411318
[so.git] / adapters / etsi-sol003-adapter / etsi-sol003-lcm / etsi-sol003-lcm-adapter / src / main / java / org / onap / so / adapters / etsisol003adapter / lcm / extclients / EtsiPackageProvider.java
1 /*-
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2019 Nordix Foundation.
4  * ================================================================================
5  *  Modifications Copyright (c) 2019 Samsung
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  * SPDX-License-Identifier: Apache-2.0
20  * ============LICENSE_END=========================================================
21  */
22
23 package org.onap.so.adapters.etsisol003adapter.lcm.extclients;
24
25 import static com.google.common.base.Splitter.on;
26 import static com.google.common.collect.Iterables.filter;
27 import static java.lang.String.format;
28 import static org.onap.so.adapters.etsisol003adapter.lcm.NvfmAdapterUtils.abortOperation;
29 import static org.onap.so.adapters.etsisol003adapter.lcm.NvfmAdapterUtils.child;
30 import static org.onap.so.adapters.etsisol003adapter.lcm.NvfmAdapterUtils.childElement;
31 import static org.onap.so.adapters.etsisol003adapter.lcm.NvfmAdapterUtils.children;
32 import static org.slf4j.LoggerFactory.getLogger;
33 import java.io.ByteArrayInputStream;
34 import java.io.ByteArrayOutputStream;
35 import java.io.IOException;
36 import java.io.InputStream;
37 import java.util.HashSet;
38 import java.util.NoSuchElementException;
39 import java.util.Optional;
40 import java.util.Set;
41 import java.util.zip.ZipEntry;
42 import java.util.zip.ZipInputStream;
43 import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.EtsiCatalogServiceProviderImpl;
44 import org.onap.so.adapters.etsisol003adapter.pkgm.rest.exceptions.EtsiCatalogManagerRequestFailureException;
45 import org.slf4j.Logger;
46 import org.springframework.beans.factory.annotation.Autowired;
47 import org.springframework.stereotype.Component;
48 import org.yaml.snakeyaml.Yaml;
49 import com.google.common.io.ByteStreams;
50 import com.google.gson.Gson;
51 import com.google.gson.JsonObject;
52
53 @Component
54 public class EtsiPackageProvider {
55     private static final String TOCSA_METADATA_FILE_PATH = "TOSCA-Metadata/TOSCA.meta";
56     private static final String TOSCA_VNFD_KEY = "Entry-Definitions";
57     private static Logger logger = getLogger(EtsiPackageProvider.class);
58
59     @Autowired
60     private EtsiCatalogServiceProviderImpl etsiCatalogServiceProviderImpl;
61
62     public String getVnfdId(final String csarId) {
63         return getVnfNodeProperty(csarId, "descriptor_id");
64     }
65
66     private String getVnfNodeProperty(final String csarId, final String propertyName) {
67         logger.debug("Getting " + propertyName + " from " + csarId);
68         final byte[] onapPackage = getPackage(csarId);
69
70         try {
71             final String vnfdLocation = getVnfdLocation(new ByteArrayInputStream(onapPackage));
72             final String onapVnfdContent = getFileInZip(new ByteArrayInputStream(onapPackage), vnfdLocation).toString();
73             logger.debug("VNFD CONTENTS: " + onapVnfdContent);
74             final JsonObject root = new Gson().toJsonTree(new Yaml().load(onapVnfdContent)).getAsJsonObject();
75
76             final JsonObject topologyTemplates = child(root, "topology_template");
77             final JsonObject nodeTemplates = child(topologyTemplates, "node_templates");
78             for (final JsonObject child : children(nodeTemplates)) {
79                 final String type = childElement(child, "type").getAsString();
80                 String propertyValue = null;
81                 if ("tosca.nodes.nfv.VNF".equals(type)) {
82                     final JsonObject properties = child(child, "properties");
83                     logger.debug("properties: " + properties.toString());
84
85                     propertyValue = properties.get(propertyName).getAsJsonPrimitive().getAsString();
86                 }
87                 if (propertyValue == null) {
88                     propertyValue = getValueFromNodeTypeDefinition(root, type, propertyName);
89                 }
90                 return propertyValue;
91             }
92
93         } catch (final Exception e) {
94             throw new IllegalArgumentException("Unable to extract " + propertyName + " from ONAP package", e);
95         }
96         throw new IllegalArgumentException("Unable to extract " + propertyName + " from ONAP package");
97     }
98
99     private String getValueFromNodeTypeDefinition(final JsonObject root, final String nodeTypeName,
100             final String propertyName) {
101         final JsonObject nodeTypes = child(root, "node_types");
102         final JsonObject nodeType = child(nodeTypes, nodeTypeName);
103
104         if ("tosca.nodes.nfv.VNF".equals(childElement(nodeType, "derived_from").getAsString())) {
105             final JsonObject properties = child(nodeType, "properties");
106             logger.debug("properties: " + properties.toString());
107             final JsonObject property = child(properties, propertyName);
108             logger.debug("property: " + property.toString());
109             logger.debug("property default: " + childElement(property, "default").toString());
110             return childElement(property, "default").getAsJsonPrimitive().getAsString();
111         }
112         return null;
113     }
114
115     private byte[] getPackage(final String csarId) {
116         final Optional<byte[]> optional = etsiCatalogServiceProviderImpl.getVnfPackageContent(csarId);
117         try {
118             if (optional.isPresent()) {
119                 return optional.get();
120             }
121         } catch (final Exception exception) {
122             logger.error("Unable to retrieve package from ETSI Catalog Manager using pkgId: {}", csarId);
123             throw new EtsiCatalogManagerRequestFailureException("Value is not present", exception);
124         }
125         logger.error("Unable to retrieve package from ETSI Catalog Manager using pkgId: {}", csarId);
126         throw new EtsiCatalogManagerRequestFailureException("Value is not present");
127     }
128
129     private String getVnfdLocation(final InputStream stream) throws IOException {
130         final String toscaMetadata = new String(getFileInZip(stream, TOCSA_METADATA_FILE_PATH).toByteArray());
131         if (!toscaMetadata.isEmpty()) {
132             final String toscaVnfdLine =
133                     filter(on("\n").split(toscaMetadata), line -> line.contains(TOSCA_VNFD_KEY)).iterator().next();
134             return toscaVnfdLine.replace(TOSCA_VNFD_KEY + ":", "").trim();
135         }
136         throw abortOperation("Unable to find valid Tosca Path");
137     }
138
139     private static ByteArrayOutputStream getFileInZip(final InputStream zip, final String path) throws IOException {
140         final ZipInputStream zipInputStream = new ZipInputStream(zip);
141         final ByteArrayOutputStream fileContent = getFileInZip(zipInputStream, path);
142         zipInputStream.close();
143         return fileContent;
144     }
145
146     private static ByteArrayOutputStream getFileInZip(final ZipInputStream zipInputStream, final String path)
147             throws IOException {
148         ZipEntry zipEntry;
149         final Set<String> items = new HashSet<>();
150         while ((zipEntry = zipInputStream.getNextEntry()) != null) {
151             items.add(zipEntry.getName());
152             if (zipEntry.getName().matches(path)) {
153                 final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
154                 ByteStreams.copy(zipInputStream, byteArrayOutputStream);
155                 return byteArrayOutputStream;
156             }
157         }
158         logger.error("Unable to find the {} in archive found: {}", path, items);
159         throw new NoSuchElementException("Unable to find the " + path + " in archive found: " + items);
160     }
161
162     public String getFlavourId(final String csarId) {
163         return getVnfNodeProperty(csarId, "flavour_id");
164     }
165 }