2 * Copyright © 2019 iconectiv
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.openecomp.core.externaltesting.impl;
19 import lombok.EqualsAndHashCode;
20 import org.apache.commons.io.IOUtils;
21 import org.apache.commons.lang3.StringUtils;
22 import org.apache.commons.lang3.tuple.Pair;
23 import org.openecomp.core.externaltesting.api.VtpTestExecutionRequest;
24 import org.openecomp.core.externaltesting.errors.ExternalTestingException;
25 import org.openecomp.sdc.vendorsoftwareproduct.OrchestrationTemplateCandidateManager;
26 import org.openecomp.sdc.vendorsoftwareproduct.OrchestrationTemplateCandidateManagerFactory;
27 import org.openecomp.sdc.vendorsoftwareproduct.VendorSoftwareProductManager;
28 import org.openecomp.sdc.vendorsoftwareproduct.VspManagerFactory;
29 import org.openecomp.sdc.versioning.VersioningManager;
30 import org.openecomp.sdc.versioning.VersioningManagerFactory;
31 import org.openecomp.sdc.versioning.dao.types.Version;
32 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
34 import org.springframework.core.io.ByteArrayResource;
35 import org.springframework.util.MultiValueMap;
37 import javax.annotation.PostConstruct;
38 import java.io.ByteArrayInputStream;
39 import java.io.IOException;
40 import java.util.List;
42 import java.util.Optional;
43 import java.util.stream.Collectors;
44 import java.util.zip.ZipEntry;
45 import java.util.zip.ZipInputStream;
48 * The CSAR Metadata variable resolver is responsible for processing of
49 * variables in the test request. It looks for variables with the "csar:" prefix
50 * and extracts the contents of the uploaded CSAR file for a VSP.
52 public class CsarMetadataVariableResolver implements VariableResolver {
54 private Logger logger = LoggerFactory.getLogger(CsarMetadataVariableResolver.class);
56 static final String VSP_ID = "vspId";
57 static final String VSP_VERSION = "vspVersion";
58 static final String CSAR_PREFIX = "csar:";
60 private VersioningManager versioningManager;
61 private VendorSoftwareProductManager vendorSoftwareProductManager;
62 private OrchestrationTemplateCandidateManager candidateManager;
64 CsarMetadataVariableResolver(VersioningManager versioningManager,
65 VendorSoftwareProductManager vendorSoftwareProductManager,
66 OrchestrationTemplateCandidateManager candidateManager) {
68 this.versioningManager = versioningManager;
69 this.vendorSoftwareProductManager = vendorSoftwareProductManager;
70 this.candidateManager = candidateManager;
73 CsarMetadataVariableResolver() {
79 if (versioningManager == null) {
80 versioningManager = VersioningManagerFactory.getInstance().createInterface();
82 if (vendorSoftwareProductManager == null) {
83 vendorSoftwareProductManager =
84 VspManagerFactory.getInstance().createInterface();
86 if (candidateManager == null) {
88 OrchestrationTemplateCandidateManagerFactory.getInstance().createInterface();
93 public boolean resolvesVariablesForRequest(VtpTestExecutionRequest requestItem) {
94 Map<String,String> params = requestItem.getParameters();
96 // no params, quickly return.
101 // no match, quickly return
102 if (!params.containsKey(VSP_ID) || !params.containsKey(VSP_VERSION)) {
106 return (params.keySet().stream().anyMatch(s -> StringUtils.startsWith(s, CSAR_PREFIX)));
110 public void resolve(VtpTestExecutionRequest requestItem, MultiValueMap<String, Object> body) {
111 logger.debug("run {} variable resolver...", this.getClass().getSimpleName());
112 Map<String,String> params = requestItem.getParameters();
113 String vspId = params.get(VSP_ID);
114 String version = params.get(VSP_VERSION);
117 extractMetadata(requestItem, body, vspId, version);
119 catch (IOException ex) {
120 logger.error("metadata extraction failed", ex);
125 * Extract the metadata from the VSP CSAR file.
126 * @param requestItem item to add metadata to for processing
127 * @param vspId VSP identifier
128 * @param version VSP version
130 @SuppressWarnings("WeakerAccess")
131 protected void extractMetadata(VtpTestExecutionRequest requestItem, MultiValueMap<String, Object> body, String vspId, String version) throws IOException {
133 Version ver = new Version(version);
134 logger.debug("attempt to retrieve archive for VSP {} version {}", vspId, ver.getId());
136 Optional<Pair<String, byte[]>> ozip = candidateManager.get(vspId, new Version(version));
137 if (!ozip.isPresent()) {
138 ozip = vendorSoftwareProductManager.get(vspId, ver);
141 if (!ozip.isPresent()) {
142 List<Version> versions = versioningManager.list(vspId);
143 String knownVersions = versions
145 .map(v -> String.format("%d.%d: %s (%s)", v.getMajor(), v.getMinor(), v.getStatus(), v.getId()))
146 .collect(Collectors.joining("\n"));
148 String detail = String.format("Unable to find archive for VSP ID %s and Version %s. Known versions are:\n%s",
149 vspId, version, knownVersions);
151 throw new ExternalTestingException("Archive Processing Failed", 500, detail);
154 // safe here to do get.
155 Pair<String, byte[]> zip = ozip.get();
156 processArchive(requestItem, body, zip.getRight());
159 @EqualsAndHashCode(callSuper = false)
160 private class NamedByteArrayResource extends ByteArrayResource {
161 private String filename;
162 private NamedByteArrayResource(byte[] bytes, String filename) {
163 super(bytes, filename);
164 this.filename = filename;
167 public String getFilename() {
168 return this.filename;
173 @SuppressWarnings("WeakerAccess")
174 protected void processArchive(VtpTestExecutionRequest requestItem, MultiValueMap<String, Object> body, byte[] zip) {
176 ZipInputStream zipStream = new ZipInputStream(new ByteArrayInputStream(zip));
178 while ((entry = zipStream.getNextEntry()) != null) {
179 String entryName = entry.getName();
180 logger.debug("csar contains entry {}", entryName);
181 Map<String,String> params = requestItem.getParameters();
182 params.forEach((key,val) -> {
183 if (key.startsWith(CSAR_PREFIX)) {
184 addToBody(requestItem, body, zipStream, entryName, key);
188 } catch (IOException ex) {
189 logger.error("IO Exception parsing zip", ex);
193 private void addToBody(VtpTestExecutionRequest requestItem, MultiValueMap<String, Object> body, ZipInputStream zipStream, String entryName, String key) {
194 String filename = key.substring(CSAR_PREFIX.length());
195 logger.debug("match {} with {}", entryName, filename);
196 if (StringUtils.equals(entryName, filename)) {
198 NamedByteArrayResource res = new NamedByteArrayResource(IOUtils.toByteArray(zipStream), filename);
199 body.add("file", res);
201 // we've added the file to the body. need to replace the value in the request for this
202 // parameter to match the VTP requirement that it start with a file URL protocol handler.
203 requestItem.getParameters().put(key, "file://" + entryName);
205 } catch (IOException ex) {
206 logger.error("failed to read zip entry content for {}", entryName, ex);