2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2019 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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 * SPDX-License-Identifier: Apache-2.0
18 * ============LICENSE_END=========================================================
21 package org.onap.so.adapters.vnfmadapter.extclients;
23 import com.google.common.io.ByteStreams;
24 import com.google.gson.Gson;
25 import com.google.gson.JsonObject;
26 import org.apache.commons.codec.binary.Base64;
27 import org.apache.http.HttpEntity;
28 import org.apache.http.client.methods.CloseableHttpResponse;
29 import org.apache.http.client.methods.HttpGet;
30 import org.apache.http.impl.client.CloseableHttpClient;
31 import org.apache.http.impl.client.HttpClients;
32 import org.onap.so.utils.CryptoUtils;
33 import org.slf4j.Logger;
34 import org.springframework.beans.factory.annotation.Value;
35 import org.springframework.stereotype.Component;
36 import org.yaml.snakeyaml.Yaml;
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;
43 import java.util.zip.ZipEntry;
44 import java.util.zip.ZipInputStream;
45 import static com.google.common.base.Splitter.on;
46 import static com.google.common.collect.Iterables.filter;
47 import static com.google.common.io.ByteStreams.toByteArray;
48 import static java.lang.String.format;
49 import static org.apache.http.HttpHeaders.ACCEPT;
50 import static org.apache.http.HttpHeaders.AUTHORIZATION;
51 import static org.onap.so.adapters.vnfmadapter.NvfmAdapterUtils.*;
52 import static org.slf4j.LoggerFactory.getLogger;
53 import static org.springframework.http.MediaType.APPLICATION_OCTET_STREAM_VALUE;
57 public class SdcPackageProvider {
58 private static final String GET_PACKAGE_URL = "%s/catalog/resources/%s/toscaModel";
59 @Value("sdc.toscametapath:TOSCA-Metadata/TOSCA.meta")
60 private List<String> toscaMetaPaths;
61 private final String TOSCA_VNFD_KEY = "Entry-Definitions";
62 private static Logger logger = getLogger(SdcPackageProvider.class);
64 @Value("${sdc.username}")
65 private String sdcUsername;
66 @Value("${sdc.password}")
67 private String sdcPassword;
69 private String sdcKey;
70 @Value("${sdc.endpoint}")
71 private String baseUrl;
74 public String getVnfdId(String csarId) {
75 return getVnfNodeProperty(csarId, "descriptor_id");
78 private String getVnfNodeProperty(final String csarId, final String propertyName) {
79 logger.debug("Getting " + propertyName + " from " + csarId);
80 final byte[] onapPackage = getPackage(csarId);
83 final String vnfdLocation = getVnfdLocation(new ByteArrayInputStream(onapPackage));
84 final String onapVnfdContent = getFileInZip(new ByteArrayInputStream(onapPackage), vnfdLocation).toString();
85 final JsonObject root = new Gson().toJsonTree(new Yaml().load(onapVnfdContent)).getAsJsonObject();
87 final JsonObject topologyTemplates = child(root, "topology_template");
88 final JsonObject nodeTemplates = child(topologyTemplates, "node_templates");
89 for (final JsonObject child : children(nodeTemplates)) {
90 final String type = childElement(child, "type").getAsString();
91 String propertyValue = null;
92 if (type.equals("tosca.nodes.nfv.VNF")) {
93 final JsonObject properties = child(child, "properties");
94 logger.debug("properties: " + properties.toString());
96 propertyValue = properties.get(propertyName).getAsJsonPrimitive().getAsString();
98 if (propertyValue == null) {
99 propertyValue = getValueFromNodeTypeDefinition(root, type, propertyName);
101 return propertyValue;
104 } catch (final Exception e) {
105 throw new IllegalArgumentException("Unable to extract " + propertyName + " from ONAP package", e);
107 throw new IllegalArgumentException("Unable to extract " + propertyName + " from ONAP package");
110 private String getValueFromNodeTypeDefinition(final JsonObject root, final String nodeTypeName,
111 final String propertyName) {
112 final JsonObject nodeTypes = child(root, "node_types");
113 final JsonObject nodeType = child(nodeTypes, nodeTypeName);
115 if (childElement(nodeType, "derived_from").getAsString().equals("tosca.nodes.nfv.VNF")) {
116 final JsonObject properties = child(nodeType, "properties");
117 logger.debug("properties: " + properties.toString());
118 final JsonObject property = child(properties, propertyName);
119 logger.debug("property: " + property.toString());
120 logger.debug("property default: " + childElement(property, "default").toString());
121 return childElement(property, "default").getAsJsonPrimitive().getAsString();
126 private byte[] getPackage(String csarId) {
127 final String SERVICE_NAME = "vnfm-adapter";
129 CloseableHttpClient client = HttpClients.createDefault();
130 HttpGet httpget = new HttpGet(format(GET_PACKAGE_URL, baseUrl, csarId));
131 httpget.setHeader(ACCEPT, APPLICATION_OCTET_STREAM_VALUE);
132 httpget.setHeader("X-ECOMP-InstanceID", SERVICE_NAME);
133 httpget.setHeader("X-FromAppId", SERVICE_NAME);
134 String auth = sdcUsername + ":" + CryptoUtils.decrypt(sdcPassword, sdcKey);
135 byte[] encodedAuth = Base64.encodeBase64(auth.getBytes(StandardCharsets.ISO_8859_1));
136 String authHeader = "Basic " + new String(encodedAuth);
137 httpget.setHeader(AUTHORIZATION, authHeader);
138 logger.debug("Fetching from SDC: " + httpget);
139 CloseableHttpResponse response = client.execute(httpget);
140 HttpEntity entity = response.getEntity();
141 InputStream is = entity.getContent();
142 byte[] bytes = toByteArray(is);
145 } catch (Exception e) {
146 throw abortOperation("Unable to download " + csarId + " package from SDC", e);
150 private String getVnfdLocation(InputStream stream) throws IOException {
151 Iterator pathIterator = toscaMetaPaths.iterator();
152 while (pathIterator.hasNext()) {
153 String toscaMetadata = new String(getFileInZip(stream, pathIterator.next().toString()).toByteArray());
154 if (!toscaMetadata.isEmpty()) {
155 String toscaVnfdLine =
156 filter(on("\n").split(toscaMetadata), line -> line.contains(TOSCA_VNFD_KEY)).iterator().next();
157 return toscaVnfdLine.replace(TOSCA_VNFD_KEY + ":", "").trim();
160 throw abortOperation("Unable to find valid Tosca Path");
163 private static ByteArrayOutputStream getFileInZip(InputStream zip, String path) throws IOException {
164 ZipInputStream zipInputStream = new ZipInputStream(zip);
165 ByteArrayOutputStream fileContent = getFileInZip(zipInputStream, path);
166 zipInputStream.close();
170 private static ByteArrayOutputStream getFileInZip(ZipInputStream zipInputStream, String path) throws IOException {
172 Set<String> items = new HashSet<>();
173 while ((zipEntry = zipInputStream.getNextEntry()) != null) {
174 items.add(zipEntry.getName());
175 if (zipEntry.getName().matches(path)) {
176 ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
177 ByteStreams.copy(zipInputStream, byteArrayOutputStream);
178 return byteArrayOutputStream;
181 logger.error("Unable to find the {} in archive found: {}", path, items);
182 throw new NoSuchElementException("Unable to find the " + path + " in archive found: " + items);
186 public String getFlavourId(String csarId) {
187 return getVnfNodeProperty(csarId, "flavour_id");