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.io.ByteStreams;
20 import com.nokia.cbam.catalog.v1.ApiException;
21 import com.nokia.cbam.catalog.v1.api.DefaultApi;
22 import com.nokia.cbam.catalog.v1.model.CatalogAdapterVnfpackage;
23 import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.api.IPackageProvider;
24 import org.slf4j.Logger;
25 import org.springframework.beans.factory.annotation.Autowired;
26 import org.springframework.stereotype.Component;
29 import java.nio.file.Path;
30 import java.util.HashSet;
31 import java.util.NoSuchElementException;
33 import java.util.zip.ZipEntry;
34 import java.util.zip.ZipInputStream;
36 import static com.google.common.base.Splitter.on;
37 import static com.google.common.collect.Iterables.filter;
38 import static java.nio.file.Files.createTempFile;
39 import static java.nio.file.Files.write;
40 import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.util.CbamUtils.buildFatalFailure;
41 import static org.slf4j.LoggerFactory.getLogger;
45 * Responsible for handling the CBAM catalog
46 * - the VNF package is uploaded as part of the instantiation
47 * - 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 private static final String TOSCA_META_PATH = "TOSCA-Metadata/TOSCA.meta";
56 private static final String TOSCA_VNFD_KEY = "Entry-Definitions";
57 private static Logger logger = getLogger(CatalogManager.class);
58 private final CbamRestApiProvider cbamRestApiProvider;
59 private final IPackageProvider packageProvider;
62 CatalogManager(CbamRestApiProvider cbamRestApiProvider, IPackageProvider packageProvider) {
63 this.cbamRestApiProvider = cbamRestApiProvider;
64 this.packageProvider = packageProvider;
69 * @param path the path of the file to be returned
70 * @return the file in the zip
72 public static ByteArrayOutputStream getFileInZip(InputStream zip, String path) throws IOException {
73 ZipInputStream zipInputStream = new ZipInputStream(zip);
74 ByteArrayOutputStream fileContent = getFileInZip(zipInputStream, path);
75 zipInputStream.close();
80 * @param stream the CBAM VNF package
81 * @return the location of the VNFD within the CBAM package
83 public static String getVnfdLocation(InputStream stream) throws IOException {
84 String toscaMetadata = new String(getFileInZip(stream, TOSCA_META_PATH).toByteArray());
85 String toscaVnfdLine = filter(on("\n").split(toscaMetadata), line -> line.contains(TOSCA_VNFD_KEY)).iterator().next();
86 return toscaVnfdLine.replace(TOSCA_VNFD_KEY + ":", "").trim();
89 private static ByteArrayOutputStream getFileInZip(ZipInputStream zipInputStream, String path) throws IOException {
91 Set<String> items = new HashSet<>();
92 while ((zipEntry = zipInputStream.getNextEntry()) != null) {
93 items.add(zipEntry.getName());
94 if (zipEntry.getName().matches(path)) {
95 ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
96 ByteStreams.copy(zipInputStream, byteArrayOutputStream);
97 return byteArrayOutputStream;
100 logger.error("Unable to find the {} in archive found: {}", path, items);
101 throw new NoSuchElementException("Unable to find the " + path + " in archive found: " + items);
105 * Prepare the VNF package in CBAM. If the package is not available in the catalog it is uploaded.
107 * @param vnfmId the identifier of the VNFM
108 * @param csarId the CSAR identifier of the package in ONAP catalog
109 * @return the package in CBAM catalog
111 public CatalogAdapterVnfpackage preparePackageInCbam(String vnfmId, String csarId) {
112 String cbamVnfdId = packageProvider.getCbamVnfdId(csarId);
113 DefaultApi cbamCatalogApi = cbamRestApiProvider.getCbamCatalogApi(vnfmId);
114 if (!isPackageReplicated(cbamVnfdId, cbamCatalogApi)) {
116 Path tempFile = createTempFile("cbam", "zip");
117 ByteArrayOutputStream cbamPackage = getFileInZip(new ByteArrayInputStream(packageProvider.getPackage(csarId)), CBAM_PACKAGE_NAME_IN_ZIP);
118 write(tempFile, cbamPackage.toByteArray());
120 return cbamCatalogApi.create(tempFile.toFile());
121 } catch (Exception e) {
122 logger.debug("Probably concurrent package uploads", e);
123 //retest if the VNF package exists in CBAM. It might happen that an other operation
124 //triggered the replication making this API fail. The replication is considered to be
125 //successful if the package exist in CBAM even if the current package transfer failed
126 if (isPackageReplicated(cbamVnfdId, cbamCatalogApi)) {
127 return queryPackageFromCBAM(cbamVnfdId, cbamCatalogApi);
129 throw buildFatalFailure(logger, "Unable to create VNF with " + csarId + " CSAR identifier in package in CBAM", e);
133 return queryPackageFromCBAM(cbamVnfdId, cbamCatalogApi);
137 * Gets the content of the VNFD from the CBAM package uploaded to CBAM
139 * @param vnfmId the identifier of the VNFM
140 * @param vnfdId the identifier of the VNFD
141 * @return the content of the CBAM VNFD
143 public String getCbamVnfdContent(String vnfmId, String vnfdId) {
145 File content = cbamRestApiProvider.getCbamCatalogApi(vnfmId).content(vnfdId);
146 String vnfdPath = getVnfdLocation(new FileInputStream(content));
147 return new String(getFileInZip(new FileInputStream(content), vnfdPath).toByteArray());
148 } catch (Exception e) {
149 throw buildFatalFailure(logger, "Unable to get package with (" + vnfdId + ")", e);
153 private boolean isPackageReplicated(String cbamVnfdId, DefaultApi cbamCatalogApi) {
155 return isPackageReplicatedToCbam(cbamVnfdId, cbamCatalogApi);
156 } catch (Exception e) {
157 throw buildFatalFailure(logger, "Unable to determine if the VNF package has been replicated in CBAM", e);
161 private CatalogAdapterVnfpackage queryPackageFromCBAM(String cbamVnfdId, DefaultApi cbamCatalogApi) {
163 return cbamCatalogApi.getById(cbamVnfdId);
164 } catch (ApiException e) {
165 throw buildFatalFailure(logger, "Unable to query VNF package with " + cbamVnfdId + " from CBAM", e);
169 private boolean isPackageReplicatedToCbam(String cbamVnfdId, DefaultApi cbamCatalogApi) throws ApiException {
170 for (CatalogAdapterVnfpackage vnfPackage : cbamCatalogApi.list()) {
171 if (vnfPackage.getVnfdId().equals(cbamVnfdId)) {