2 * Copyright 2016-2017, Nokia Corporation
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm;
19 import com.google.common.base.Charsets;
20 import com.google.common.io.ByteStreams;
21 import com.nokia.cbam.catalog.v1.api.DefaultApi;
22 import com.nokia.cbam.catalog.v1.model.CatalogAdapterVnfpackage;
23 import java.io.ByteArrayInputStream;
24 import java.io.ByteArrayOutputStream;
25 import java.io.IOException;
26 import java.io.InputStream;
27 import java.util.HashSet;
28 import java.util.NoSuchElementException;
30 import java.util.zip.ZipEntry;
31 import java.util.zip.ZipInputStream;
32 import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.api.IPackageProvider;
33 import org.slf4j.Logger;
35 import static com.google.common.base.Splitter.on;
36 import static com.google.common.collect.Iterables.filter;
37 import static okhttp3.MediaType.parse;
38 import static okhttp3.RequestBody.create;
39 import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.util.CbamUtils.buildFatalFailure;
40 import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.LifecycleManager.ETSI_CONFIG;
41 import static org.slf4j.LoggerFactory.getLogger;
42 import static org.springframework.http.MediaType.APPLICATION_OCTET_STREAM;
46 * Responsible for handling the CBAM catalog
47 * - the VNF package is uploaded as part of the instantiation
48 * - the VNF package is not deleted after VNF deletion
50 public class CatalogManager {
52 * The location of the CBAM package within the ONAP package
54 public static final String CBAM_PACKAGE_NAME_IN_ZIP = "Artifacts/Deployment/OTHER/cbam.package.zip";
55 public static final String ETSI_CONFIG_NAME_IN_ZIP = "Artifacts/Deployment/OTHER/" + ETSI_CONFIG +".json";
57 private static final String TOSCA_META_PATH = "TOSCA-Metadata/TOSCA.meta";
58 private static final String TOSCA_VNFD_KEY = "Entry-Definitions";
59 private static Logger logger = getLogger(CatalogManager.class);
60 private final CbamRestApiProvider cbamRestApiProvider;
61 private final IPackageProvider packageProvider;
63 CatalogManager(CbamRestApiProvider cbamRestApiProvider, IPackageProvider packageProvider) {
64 this.cbamRestApiProvider = cbamRestApiProvider;
65 this.packageProvider = packageProvider;
70 * @param path the path of the file to be returned
71 * @return the file in the zip
73 public static ByteArrayOutputStream getFileInZip(InputStream zip, String path) throws IOException {
74 ZipInputStream zipInputStream = new ZipInputStream(zip);
75 ByteArrayOutputStream fileContent = getFileInZip(zipInputStream, path);
76 zipInputStream.close();
81 * @param stream the CBAM VNF package
82 * @return the location of the VNFD within the CBAM package
84 public static String getVnfdLocation(InputStream stream) throws IOException {
85 String toscaMetadata = new String(getFileInZip(stream, TOSCA_META_PATH).toByteArray());
86 String toscaVnfdLine = filter(on("\n").split(toscaMetadata), line -> line.contains(TOSCA_VNFD_KEY)).iterator().next();
87 return toscaVnfdLine.replace(TOSCA_VNFD_KEY + ":", "").trim();
90 private static ByteArrayOutputStream getFileInZip(ZipInputStream zipInputStream, String path) throws IOException {
92 Set<String> items = new HashSet<>();
93 while ((zipEntry = zipInputStream.getNextEntry()) != null) {
94 items.add(zipEntry.getName());
95 if (zipEntry.getName().matches(path)) {
96 ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
97 ByteStreams.copy(zipInputStream, byteArrayOutputStream);
98 return byteArrayOutputStream;
101 logger.error("Unable to find the {} in archive found: {}", path, items);
102 throw new NoSuchElementException("Unable to find the " + path + " in archive found: " + items);
106 * Prepare the VNF package in CBAM. If the package is not available in the catalog it is uploaded.
108 * @param vnfmId the identifier of the VNFM
109 * @param csarId the CSAR identifier of the package in ONAP catalog
110 * @return the package in CBAM catalog
112 public CatalogAdapterVnfpackage preparePackageInCbam(String vnfmId, String csarId) {
113 String cbamVnfdId = packageProvider.getCbamVnfdId(csarId);
114 DefaultApi cbamCatalogApi = cbamRestApiProvider.getCbamCatalogApi(vnfmId);
115 if (!isPackageReplicated(cbamVnfdId, cbamCatalogApi)) {
117 ByteArrayOutputStream cbamPackage = getFileInZip(new ByteArrayInputStream(packageProvider.getPackage(csarId)), CBAM_PACKAGE_NAME_IN_ZIP);
118 return cbamCatalogApi.create(create(parse(APPLICATION_OCTET_STREAM.toString()), cbamPackage.toByteArray())).blockingFirst();
119 } catch (Exception e) {
120 logger.debug("Probably concurrent package uploads", e);
121 //retest if the VNF package exists in CBAM. It might happen that an other operation
122 //triggered the replication making this API fail. The replication is considered to be
123 //successful if the package exist in CBAM even if the current package transfer failed
124 if (isPackageReplicated(cbamVnfdId, cbamCatalogApi)) {
125 return queryPackageFromCBAM(cbamVnfdId, cbamCatalogApi);
127 throw buildFatalFailure(logger, "Unable to create VNF with " + csarId + " CSAR identifier in package in CBAM", e);
131 return queryPackageFromCBAM(cbamVnfdId, cbamCatalogApi);
135 * Download the ETSI configuration of the VNF
136 * @param csarId the CSAR identifier of the package in ONAP catalog
137 * @return the content of the ETSI configuration
139 public String getEtsiConfiguration(String csarId){
141 ByteArrayOutputStream etsiConfig = getFileInZip(new ByteArrayInputStream(packageProvider.getPackage(csarId)), ETSI_CONFIG_NAME_IN_ZIP);
142 return new String(etsiConfig.toByteArray(), Charsets.UTF_8);
145 throw buildFatalFailure(logger, "Unable to download the ETSI configuration file");
150 * Gets the content of the VNFD from the CBAM package uploaded to CBAM
152 * @param vnfmId the identifier of the VNFM
153 * @param vnfdId the identifier of the VNFD
154 * @return the content of the CBAM VNFD
156 public String getCbamVnfdContent(String vnfmId, String vnfdId) {
158 byte[] vnfdContent = cbamRestApiProvider.getCbamCatalogApi(vnfmId).content(vnfdId).blockingFirst().bytes();
159 String vnfdPath = getVnfdLocation(new ByteArrayInputStream(vnfdContent));
160 return new String(getFileInZip(new ByteArrayInputStream(vnfdContent), vnfdPath).toByteArray());
161 } catch (Exception e) {
162 throw buildFatalFailure(logger, "Unable to get package with (" + vnfdId + ")", e);
166 private boolean isPackageReplicated(String cbamVnfdId, DefaultApi cbamCatalogApi) {
168 return isPackageReplicatedToCbam(cbamVnfdId, cbamCatalogApi);
169 } catch (Exception e) {
170 throw buildFatalFailure(logger, "Unable to determine if the VNF package has been replicated in CBAM", e);
174 private CatalogAdapterVnfpackage queryPackageFromCBAM(String cbamVnfdId, DefaultApi cbamCatalogApi) {
176 return cbamCatalogApi.getById(cbamVnfdId).blockingFirst();
177 } catch (Exception e) {
178 throw buildFatalFailure(logger, "Unable to query VNF package with " + cbamVnfdId + " from CBAM", e);
182 private boolean isPackageReplicatedToCbam(String cbamVnfdId, DefaultApi cbamCatalogApi) {
183 for (CatalogAdapterVnfpackage vnfPackage : cbamCatalogApi.list().blockingFirst()) {
184 if (vnfPackage.getVnfdId().equals(cbamVnfdId)) {