summaryrefslogtreecommitdiffstats
path: root/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/vnfm/CatalogManager.java
blob: aeeae423c05410135902df4fb5affbfa11652458 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
/*
 * Copyright 2016-2017, Nokia Corporation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm;

import com.google.common.io.ByteStreams;
import com.nokia.cbam.catalog.v1.api.DefaultApi;
import com.nokia.cbam.catalog.v1.model.CatalogAdapterVnfpackage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashSet;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.api.IPackageProvider;
import org.slf4j.Logger;

import static com.google.common.base.Splitter.on;
import static com.google.common.collect.Iterables.filter;
import static okhttp3.MediaType.parse;
import static okhttp3.RequestBody.create;
import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.util.CbamUtils.buildFatalFailure;
import static org.slf4j.LoggerFactory.getLogger;
import static org.springframework.http.MediaType.APPLICATION_OCTET_STREAM;


/**
 * Responsible for handling the CBAM catalog
 * - the VNF package is uploaded as part of the instantiation
 * - the VNF package is not deleted after VNF deletion
 */
public class CatalogManager {
    /**
     * The location of the CBAM package within the ONAP package
     */
    public static final String CBAM_PACKAGE_NAME_IN_ZIP = "Artifacts/Deployment/OTHER/cbam.package.zip";
    private static final String TOSCA_META_PATH = "TOSCA-Metadata/TOSCA.meta";
    private static final String TOSCA_VNFD_KEY = "Entry-Definitions";
    private static Logger logger = getLogger(CatalogManager.class);
    private final CbamRestApiProvider cbamRestApiProvider;
    private final IPackageProvider packageProvider;

    CatalogManager(CbamRestApiProvider cbamRestApiProvider, IPackageProvider packageProvider) {
        this.cbamRestApiProvider = cbamRestApiProvider;
        this.packageProvider = packageProvider;
    }

    /**
     * @param zip  the zip
     * @param path the path of the file to be returned
     * @return the file in the zip
     */
    public static ByteArrayOutputStream getFileInZip(InputStream zip, String path) throws IOException {
        ZipInputStream zipInputStream = new ZipInputStream(zip);
        ByteArrayOutputStream fileContent = getFileInZip(zipInputStream, path);
        zipInputStream.close();
        return fileContent;
    }

    /**
     * @param stream the CBAM VNF package
     * @return the location of the VNFD within the CBAM package
     */
    public static String getVnfdLocation(InputStream stream) throws IOException {
        String toscaMetadata = new String(getFileInZip(stream, TOSCA_META_PATH).toByteArray());
        String toscaVnfdLine = filter(on("\n").split(toscaMetadata), line -> line.contains(TOSCA_VNFD_KEY)).iterator().next();
        return toscaVnfdLine.replace(TOSCA_VNFD_KEY + ":", "").trim();
    }

    private static ByteArrayOutputStream getFileInZip(ZipInputStream zipInputStream, String path) throws IOException {
        ZipEntry zipEntry;
        Set<String> items = new HashSet<>();
        while ((zipEntry = zipInputStream.getNextEntry()) != null) {
            items.add(zipEntry.getName());
            if (zipEntry.getName().matches(path)) {
                ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
                ByteStreams.copy(zipInputStream, byteArrayOutputStream);
                return byteArrayOutputStream;
            }
        }
        logger.error("Unable to find the {} in archive found: {}", path, items);
        throw new NoSuchElementException("Unable to find the " + path + " in archive found: " + items);
    }

    /**
     * Prepare the VNF package in CBAM. If the package is not available in the catalog it is uploaded.
     *
     * @param vnfmId the identifier of the VNFM
     * @param csarId the CSAR identifier of the package in ONAP catalog
     * @return the package in CBAM catalog
     */
    public CatalogAdapterVnfpackage preparePackageInCbam(String vnfmId, String csarId) {
        String cbamVnfdId = packageProvider.getCbamVnfdId(csarId);
        DefaultApi cbamCatalogApi = cbamRestApiProvider.getCbamCatalogApi(vnfmId);
        if (!isPackageReplicated(cbamVnfdId, cbamCatalogApi)) {
            try {
                ByteArrayOutputStream cbamPackage = getFileInZip(new ByteArrayInputStream(packageProvider.getPackage(csarId)), CBAM_PACKAGE_NAME_IN_ZIP);
                return cbamCatalogApi.create(create(parse(APPLICATION_OCTET_STREAM.toString()), cbamPackage.toByteArray())).blockingFirst();
            } catch (Exception e) {
                logger.debug("Probably concurrent package uploads", e);
                //retest if the VNF package exists in CBAM. It might happen that an other operation
                //triggered the replication making this API fail. The replication is considered to be
                //successful if the package exist in CBAM even if the current package transfer failed
                if (isPackageReplicated(cbamVnfdId, cbamCatalogApi)) {
                    return queryPackageFromCBAM(cbamVnfdId, cbamCatalogApi);
                } else {
                    throw buildFatalFailure(logger, "Unable to create VNF with " + csarId + " CSAR identifier in package in CBAM", e);
                }
            }
        }
        return queryPackageFromCBAM(cbamVnfdId, cbamCatalogApi);
    }

    /**
     * Gets the content of the VNFD from the CBAM package uploaded to CBAM
     *
     * @param vnfmId the identifier of the VNFM
     * @param vnfdId the identifier of the VNFD
     * @return the content of the CBAM VNFD
     */
    public String getCbamVnfdContent(String vnfmId, String vnfdId) {
        try {
            byte[] vnfdContent = cbamRestApiProvider.getCbamCatalogApi(vnfmId).content(vnfdId).blockingFirst().bytes();
            String vnfdPath = getVnfdLocation(new ByteArrayInputStream(vnfdContent));
            return new String(getFileInZip(new ByteArrayInputStream(vnfdContent), vnfdPath).toByteArray());
        } catch (Exception e) {
            throw buildFatalFailure(logger, "Unable to get package with (" + vnfdId + ")", e);
        }
    }

    private boolean isPackageReplicated(String cbamVnfdId, DefaultApi cbamCatalogApi) {
        try {
            return isPackageReplicatedToCbam(cbamVnfdId, cbamCatalogApi);
        } catch (Exception e) {
            throw buildFatalFailure(logger, "Unable to determine if the VNF package has been replicated in CBAM", e);
        }
    }

    private CatalogAdapterVnfpackage queryPackageFromCBAM(String cbamVnfdId, DefaultApi cbamCatalogApi) {
        try {
            return cbamCatalogApi.getById(cbamVnfdId).blockingFirst();
        } catch (Exception e) {
            throw buildFatalFailure(logger, "Unable to query VNF package with " + cbamVnfdId + " from CBAM", e);
        }
    }

    private boolean isPackageReplicatedToCbam(String cbamVnfdId, DefaultApi cbamCatalogApi) {
        for (CatalogAdapterVnfpackage vnfPackage : cbamCatalogApi.list().blockingFirst()) {
            if (vnfPackage.getVnfdId().equals(cbamVnfdId)) {
                return true;
            }
        }
        return false;
    }
}