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 com.google.common.io.ByteStreams.toByteArray;
28 import static java.lang.String.format;
29 import static org.apache.http.HttpHeaders.ACCEPT;
30 import static org.apache.http.HttpHeaders.AUTHORIZATION;
31 import static org.onap.so.adapters.etsisol003adapter.lcm.NvfmAdapterUtils.abortOperation;
32 import static org.onap.so.adapters.etsisol003adapter.lcm.NvfmAdapterUtils.child;
33 import static org.onap.so.adapters.etsisol003adapter.lcm.NvfmAdapterUtils.childElement;
34 import static org.onap.so.adapters.etsisol003adapter.lcm.NvfmAdapterUtils.children;
35 import static org.slf4j.LoggerFactory.getLogger;
36 import static org.springframework.http.MediaType.APPLICATION_OCTET_STREAM_VALUE;
37 import java.io.ByteArrayInputStream;
38 import java.io.ByteArrayOutputStream;
39 import java.io.IOException;
40 import java.io.InputStream;
41 import java.nio.charset.StandardCharsets;
42 import java.util.HashSet;
43 import java.util.Iterator;
44 import java.util.List;
45 import java.util.NoSuchElementException;
47 import java.util.zip.ZipEntry;
48 import java.util.zip.ZipInputStream;
49 import javax.net.ssl.SSLContext;
50 import org.apache.commons.codec.binary.Base64;
51 import org.apache.http.HttpEntity;
52 import org.apache.http.client.methods.CloseableHttpResponse;
53 import org.apache.http.client.methods.HttpGet;
54 import org.apache.http.impl.client.CloseableHttpClient;
55 import org.apache.http.impl.client.HttpClients;
56 import org.onap.so.utils.CryptoUtils;
57 import org.slf4j.Logger;
58 import org.springframework.beans.factory.annotation.Value;
59 import org.springframework.stereotype.Component;
60 import org.yaml.snakeyaml.Yaml;
61 import com.google.common.io.ByteStreams;
62 import com.google.gson.Gson;
63 import com.google.gson.JsonObject;
66 public class SdcPackageProvider {
67 private static final String GET_PACKAGE_URL = "%s/sdc/v1/catalog/resources/%s/toscaModel";
68 @Value("${sdc.toscametapath:TOSCA-Metadata/TOSCA.meta}")
69 private List<String> toscaMetaPaths;
70 private static final String TOSCA_VNFD_KEY = "Entry-Definitions";
71 private static Logger logger = getLogger(SdcPackageProvider.class);
73 @Value("${sdc.username}")
74 private String sdcUsername;
75 @Value("${sdc.password}")
76 private String sdcPassword;
78 private String sdcKey;
79 @Value("${sdc.endpoint}")
80 private String baseUrl;
82 public String getVnfdId(final String csarId) {
83 return getVnfNodeProperty(csarId, "descriptor_id");
86 private String getVnfNodeProperty(final String csarId, final String propertyName) {
87 logger.debug("Getting " + propertyName + " from " + csarId);
88 final byte[] onapPackage = getPackage(csarId);
91 final String vnfdLocation = getVnfdLocation(new ByteArrayInputStream(onapPackage));
92 final String onapVnfdContent = getFileInZip(new ByteArrayInputStream(onapPackage), vnfdLocation).toString();
93 logger.debug("VNFD CONTENTS: " + onapVnfdContent);
94 final JsonObject root = new Gson().toJsonTree(new Yaml().load(onapVnfdContent)).getAsJsonObject();
96 final JsonObject topologyTemplates = child(root, "topology_template");
97 final JsonObject nodeTemplates = child(topologyTemplates, "node_templates");
98 for (final JsonObject child : children(nodeTemplates)) {
99 final String type = childElement(child, "type").getAsString();
100 String propertyValue = null;
101 if ("tosca.nodes.nfv.VNF".equals(type)) {
102 final JsonObject properties = child(child, "properties");
103 logger.debug("properties: " + properties.toString());
105 propertyValue = properties.get(propertyName).getAsJsonPrimitive().getAsString();
107 if (propertyValue == null) {
108 propertyValue = getValueFromNodeTypeDefinition(root, type, propertyName);
110 return propertyValue;
113 } catch (final Exception e) {
114 throw new IllegalArgumentException("Unable to extract " + propertyName + " from ONAP package", e);
116 throw new IllegalArgumentException("Unable to extract " + propertyName + " from ONAP package");
119 private String getValueFromNodeTypeDefinition(final JsonObject root, final String nodeTypeName,
120 final String propertyName) {
121 final JsonObject nodeTypes = child(root, "node_types");
122 final JsonObject nodeType = child(nodeTypes, nodeTypeName);
124 if ("tosca.nodes.nfv.VNF".equals(childElement(nodeType, "derived_from").getAsString())) {
125 final JsonObject properties = child(nodeType, "properties");
126 logger.debug("properties: " + properties.toString());
127 final JsonObject property = child(properties, propertyName);
128 logger.debug("property: " + property.toString());
129 logger.debug("property default: " + childElement(property, "default").toString());
130 return childElement(property, "default").getAsJsonPrimitive().getAsString();
135 private byte[] getPackage(final String csarId) {
136 final String SERVICE_NAME = "vnfm-adapter";
137 try (CloseableHttpClient client = HttpClients.custom().setSSLContext(SSLContext.getDefault()).build()) {
138 final HttpGet httpget = new HttpGet(format(GET_PACKAGE_URL, baseUrl, csarId));
139 httpget.setHeader(ACCEPT, APPLICATION_OCTET_STREAM_VALUE);
140 httpget.setHeader("X-ECOMP-InstanceID", SERVICE_NAME);
141 httpget.setHeader("X-FromAppId", SERVICE_NAME);
142 final String auth = sdcUsername + ":" + CryptoUtils.decrypt(sdcPassword, sdcKey);
143 final byte[] encodedAuth = Base64.encodeBase64(auth.getBytes(StandardCharsets.ISO_8859_1));
144 final String authHeader = "Basic " + new String(encodedAuth);
145 httpget.setHeader(AUTHORIZATION, authHeader);
146 logger.debug("Fetching from SDC: " + httpget);
147 final CloseableHttpResponse response = client.execute(httpget);
148 final HttpEntity entity = response.getEntity();
149 final InputStream is = entity.getContent();
150 return toByteArray(is);
151 } catch (final Exception e) {
152 throw abortOperation("Unable to download " + csarId + " package from SDC", e);
156 private String getVnfdLocation(final InputStream stream) throws IOException {
157 final Iterator<String> pathIterator = toscaMetaPaths.iterator();
158 while (pathIterator.hasNext()) {
159 final String toscaMetadata = new String(getFileInZip(stream, pathIterator.next()).toByteArray());
160 if (!toscaMetadata.isEmpty()) {
161 final String toscaVnfdLine =
162 filter(on("\n").split(toscaMetadata), line -> line.contains(TOSCA_VNFD_KEY)).iterator().next();
163 return toscaVnfdLine.replace(TOSCA_VNFD_KEY + ":", "").trim();
166 throw abortOperation("Unable to find valid Tosca Path");
169 private static ByteArrayOutputStream getFileInZip(final InputStream zip, final String path) throws IOException {
170 final ZipInputStream zipInputStream = new ZipInputStream(zip);
171 final ByteArrayOutputStream fileContent = getFileInZip(zipInputStream, path);
172 zipInputStream.close();
176 private static ByteArrayOutputStream getFileInZip(final ZipInputStream zipInputStream, final String path)
179 final Set<String> items = new HashSet<>();
180 while ((zipEntry = zipInputStream.getNextEntry()) != null) {
181 items.add(zipEntry.getName());
182 if (zipEntry.getName().matches(path)) {
183 final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
184 ByteStreams.copy(zipInputStream, byteArrayOutputStream);
185 return byteArrayOutputStream;
188 logger.error("Unable to find the {} in archive found: {}", path, items);
189 throw new NoSuchElementException("Unable to find the " + path + " in archive found: " + items);
192 public String getFlavourId(final String csarId) {
193 return getVnfNodeProperty(csarId, "flavour_id");