Removing jackson to mitigate cve-2017-4995
[vfc/nfvo/driver/vnfm/svnfm.git] / nokiav2 / driver / src / main / java / org / onap / vfc / nfvo / driver / vnfm / svnfm / nokia / vnfm / CatalogManager.java
1 /*
2  * Copyright 2016-2017, Nokia Corporation
3  *
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
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 package org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm;
18
19 import com.google.common.io.ByteStreams;
20 import com.nokia.cbam.catalog.v1.api.DefaultApi;
21 import com.nokia.cbam.catalog.v1.model.CatalogAdapterVnfpackage;
22 import java.io.ByteArrayInputStream;
23 import java.io.ByteArrayOutputStream;
24 import java.io.IOException;
25 import java.io.InputStream;
26 import java.util.HashSet;
27 import java.util.NoSuchElementException;
28 import java.util.Set;
29 import java.util.zip.ZipEntry;
30 import java.util.zip.ZipInputStream;
31 import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.api.IPackageProvider;
32 import org.slf4j.Logger;
33 import org.springframework.beans.factory.annotation.Autowired;
34 import org.springframework.stereotype.Component;
35
36 import static com.google.common.base.Splitter.on;
37 import static com.google.common.collect.Iterables.filter;
38 import static okhttp3.MediaType.parse;
39 import static okhttp3.RequestBody.create;
40 import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.util.CbamUtils.buildFatalFailure;
41 import static org.slf4j.LoggerFactory.getLogger;
42 import static org.springframework.http.MediaType.APPLICATION_OCTET_STREAM;
43
44
45 /**
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
49  */
50 @Component
51 public class CatalogManager {
52     /**
53      * The location of the CBAM package within the ONAP package
54      */
55     public static final String CBAM_PACKAGE_NAME_IN_ZIP = "Artifacts/Deployment/OTHER/cbam.package.zip";
56     private static final String TOSCA_META_PATH = "TOSCA-Metadata/TOSCA.meta";
57     private static final String TOSCA_VNFD_KEY = "Entry-Definitions";
58     private static Logger logger = getLogger(CatalogManager.class);
59     private final CbamRestApiProvider cbamRestApiProvider;
60     private final IPackageProvider packageProvider;
61
62     @Autowired
63     CatalogManager(CbamRestApiProvider cbamRestApiProvider, IPackageProvider packageProvider) {
64         this.cbamRestApiProvider = cbamRestApiProvider;
65         this.packageProvider = packageProvider;
66     }
67
68     /**
69      * @param zip  the zip
70      * @param path the path of the file to be returned
71      * @return the file in the zip
72      */
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();
77         return fileContent;
78     }
79
80     /**
81      * @param stream the CBAM VNF package
82      * @return the location of the VNFD within the CBAM package
83      */
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();
88     }
89
90     private static ByteArrayOutputStream getFileInZip(ZipInputStream zipInputStream, String path) throws IOException {
91         ZipEntry zipEntry;
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;
99             }
100         }
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);
103     }
104
105     /**
106      * Prepare the VNF package in CBAM. If the package is not available in the catalog it is uploaded.
107      *
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
111      */
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)) {
116             try {
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())).execute().body();
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);
126                 } else {
127                     throw buildFatalFailure(logger, "Unable to create VNF with " + csarId + " CSAR identifier in package in CBAM", e);
128                 }
129             }
130         }
131         return queryPackageFromCBAM(cbamVnfdId, cbamCatalogApi);
132     }
133
134     /**
135      * Gets the content of the VNFD from the CBAM package uploaded to CBAM
136      *
137      * @param vnfmId the identifier of the VNFM
138      * @param vnfdId the identifier of the VNFD
139      * @return the content of the CBAM VNFD
140      */
141     public String getCbamVnfdContent(String vnfmId, String vnfdId) {
142         try {
143             byte[] vnfdContent = cbamRestApiProvider.getCbamCatalogApi(vnfmId).content(vnfdId).execute().body().bytes();
144             String vnfdPath = getVnfdLocation(new ByteArrayInputStream(vnfdContent));
145             return new String(getFileInZip(new ByteArrayInputStream(vnfdContent), vnfdPath).toByteArray());
146         } catch (Exception e) {
147             throw buildFatalFailure(logger, "Unable to get package with (" + vnfdId + ")", e);
148         }
149     }
150
151     private boolean isPackageReplicated(String cbamVnfdId, DefaultApi cbamCatalogApi) {
152         try {
153             return isPackageReplicatedToCbam(cbamVnfdId, cbamCatalogApi);
154         } catch (Exception e) {
155             throw buildFatalFailure(logger, "Unable to determine if the VNF package has been replicated in CBAM", e);
156         }
157     }
158
159     private CatalogAdapterVnfpackage queryPackageFromCBAM(String cbamVnfdId, DefaultApi cbamCatalogApi) {
160         try {
161             return cbamCatalogApi.getById(cbamVnfdId).execute().body();
162         } catch (Exception e) {
163             throw buildFatalFailure(logger, "Unable to query VNF package with " + cbamVnfdId + " from CBAM", e);
164         }
165     }
166
167     private boolean isPackageReplicatedToCbam(String cbamVnfdId, DefaultApi cbamCatalogApi) throws IOException {
168         for (CatalogAdapterVnfpackage vnfPackage : cbamCatalogApi.list().execute().body()) {
169             if (vnfPackage.getVnfdId().equals(cbamVnfdId)) {
170                 return true;
171             }
172         }
173         return false;
174     }
175 }