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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 * SPDX-License-Identifier: Apache-2.0
20 * ============LICENSE_END=========================================================
23 package org.onap.so.adapters.etsisol003adapter.lcm.extclients;
25 import static com.google.common.base.Splitter.on;
26 import static com.google.common.collect.Iterables.filter;
27 import static org.onap.so.adapters.etsisol003adapter.lcm.NvfmAdapterUtils.abortOperation;
28 import static org.onap.so.adapters.etsisol003adapter.lcm.NvfmAdapterUtils.child;
29 import static org.onap.so.adapters.etsisol003adapter.lcm.NvfmAdapterUtils.childElement;
30 import static org.onap.so.adapters.etsisol003adapter.lcm.NvfmAdapterUtils.children;
31 import static org.slf4j.LoggerFactory.getLogger;
32 import java.io.ByteArrayInputStream;
33 import java.io.ByteArrayOutputStream;
34 import java.io.IOException;
35 import java.io.InputStream;
36 import java.util.HashSet;
37 import java.util.NoSuchElementException;
38 import java.util.Optional;
40 import java.util.zip.ZipEntry;
41 import java.util.zip.ZipInputStream;
42 import org.onap.so.adapters.etsisol003adapter.pkgm.extclients.etsicatalog.EtsiCatalogServiceProviderImpl;
43 import org.onap.so.adapters.etsisol003adapter.pkgm.rest.exceptions.EtsiCatalogManagerRequestFailureException;
44 import org.slf4j.Logger;
45 import org.springframework.beans.factory.annotation.Autowired;
46 import org.springframework.stereotype.Component;
47 import org.yaml.snakeyaml.Yaml;
48 import com.google.common.io.ByteStreams;
49 import com.google.gson.Gson;
50 import com.google.gson.JsonObject;
53 public class EtsiPackageProvider {
54 private static final String TOCSA_METADATA_FILE_PATH = "TOSCA-Metadata/TOSCA.meta";
55 private static final String TOSCA_VNFD_KEY = "Entry-Definitions";
56 private static Logger logger = getLogger(EtsiPackageProvider.class);
59 private EtsiCatalogServiceProviderImpl etsiCatalogServiceProviderImpl;
61 public String getVnfdId(final String csarId) {
62 return getVnfNodeProperty(csarId, "descriptor_id");
65 private String getVnfNodeProperty(final String csarId, final String propertyName) {
66 logger.debug("Getting {} from {}", propertyName, csarId);
67 final byte[] onapPackage = getPackage(csarId);
70 final String vnfdLocation = getVnfdLocation(new ByteArrayInputStream(onapPackage));
71 final String onapVnfdContent = getFileInZip(new ByteArrayInputStream(onapPackage), vnfdLocation).toString();
72 logger.debug("VNFD CONTENTS: {}", onapVnfdContent);
73 final JsonObject root = new Gson().toJsonTree(new Yaml().load(onapVnfdContent)).getAsJsonObject();
75 final JsonObject topologyTemplates = child(root, "topology_template");
76 final JsonObject nodeTemplates = child(topologyTemplates, "node_templates");
77 for (final JsonObject child : children(nodeTemplates)) {
78 final String type = childElement(child, "type").getAsString();
79 String propertyValue = null;
80 if ("tosca.nodes.nfv.VNF".equals(type)) {
81 final JsonObject properties = child(child, "properties");
82 logger.debug("properties: {}", properties);
83 propertyValue = properties.get(propertyName).getAsJsonPrimitive().getAsString();
84 if (propertyValue == null) {
85 propertyValue = getValueFromNodeTypeDefinition(root, type, propertyName);
92 } catch (final Exception e) {
93 throw new IllegalArgumentException("Unable to extract " + propertyName + " from ONAP package", e);
95 throw new IllegalArgumentException("Unable to extract " + propertyName + " from ONAP package");
98 private String getValueFromNodeTypeDefinition(final JsonObject root, final String nodeTypeName,
99 final String propertyName) {
100 final JsonObject nodeTypes = child(root, "node_types");
101 final JsonObject nodeType = child(nodeTypes, nodeTypeName);
103 if ("tosca.nodes.nfv.VNF".equals(childElement(nodeType, "derived_from").getAsString())) {
104 final JsonObject properties = child(nodeType, "properties");
105 logger.debug("properties: {}", properties);
106 final JsonObject property = child(properties, propertyName);
107 logger.debug("property: {}", property);
108 logger.debug("property default: {}", childElement(property, "default"));
109 return childElement(property, "default").getAsJsonPrimitive().getAsString();
114 private byte[] getPackage(final String csarId) {
116 final Optional<byte[]> optional = etsiCatalogServiceProviderImpl.getVnfPackageContent(csarId);
117 if (optional.isPresent()) {
118 return optional.get();
120 } catch (final Exception exception) {
121 logger.error("Unable to retrieve package from ETSI Catalog Manager using pkgId: {}", csarId);
122 throw new EtsiCatalogManagerRequestFailureException("Value is not present", exception);
124 logger.error("Unable to retrieve package from ETSI Catalog Manager using pkgId: {}", csarId);
125 throw new EtsiCatalogManagerRequestFailureException("Value is not present");
128 private String getVnfdLocation(final InputStream stream) throws IOException {
129 final String toscaMetadata = new String(getFileInZip(stream, TOCSA_METADATA_FILE_PATH).toByteArray());
130 if (!toscaMetadata.isEmpty()) {
131 final String toscaVnfdLine =
132 filter(on("\n").split(toscaMetadata), line -> line.contains(TOSCA_VNFD_KEY)).iterator().next();
133 return toscaVnfdLine.replace(TOSCA_VNFD_KEY + ":", "").trim();
135 throw abortOperation("Unable to find valid Tosca Path");
138 private static ByteArrayOutputStream getFileInZip(final InputStream zip, final String path) throws IOException {
139 final ZipInputStream zipInputStream = new ZipInputStream(zip);
140 final ByteArrayOutputStream fileContent = getFileInZip(zipInputStream, path);
141 zipInputStream.close();
145 private static ByteArrayOutputStream getFileInZip(final ZipInputStream zipInputStream, final String path)
148 final Set<String> items = new HashSet<>();
149 while ((zipEntry = zipInputStream.getNextEntry()) != null) {
150 items.add(zipEntry.getName());
151 if (zipEntry.getName().matches(path)) {
152 final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
153 ByteStreams.copy(zipInputStream, byteArrayOutputStream);
154 return byteArrayOutputStream;
157 logger.error("Unable to find the {} in archive found: {}", path, items);
158 throw new NoSuchElementException("Unable to find the " + path + " in archive found: " + items);
161 public String getFlavourId(final String csarId) {
162 return getVnfNodeProperty(csarId, "flavour_id");