List of Input Parameters for VSP
[sdc.git] / openecomp-be / lib / openecomp-sdc-externaltesting-lib / openecomp-sdc-externaltesting-impl / src / main / java / org / openecomp / core / externaltesting / impl / CsarMetadataVariableResolver.java
1 /*
2  * Copyright © 2019 iconectiv
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.openecomp.core.externaltesting.impl;
18
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;
36
37 import javax.annotation.PostConstruct;
38 import java.io.ByteArrayInputStream;
39 import java.io.IOException;
40 import java.util.List;
41 import java.util.Map;
42 import java.util.Optional;
43 import java.util.stream.Collectors;
44 import java.util.zip.ZipEntry;
45 import java.util.zip.ZipInputStream;
46
47 /**
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.
51  */
52 public class CsarMetadataVariableResolver implements VariableResolver {
53
54   private Logger logger = LoggerFactory.getLogger(CsarMetadataVariableResolver.class);
55
56   static final String VSP_ID = "vspId";
57   static final String VSP_VERSION = "vspVersion";
58   static final String CSAR_PREFIX = "csar:";
59
60   private VersioningManager versioningManager;
61   private VendorSoftwareProductManager vendorSoftwareProductManager;
62   private OrchestrationTemplateCandidateManager candidateManager;
63
64   CsarMetadataVariableResolver(VersioningManager versioningManager,
65                                       VendorSoftwareProductManager vendorSoftwareProductManager,
66                                       OrchestrationTemplateCandidateManager candidateManager) {
67     this();
68     this.versioningManager = versioningManager;
69     this.vendorSoftwareProductManager = vendorSoftwareProductManager;
70     this.candidateManager = candidateManager;
71   }
72
73   CsarMetadataVariableResolver() {
74
75   }
76
77   @PostConstruct
78   public void init() {
79     if (versioningManager == null) {
80       versioningManager = VersioningManagerFactory.getInstance().createInterface();
81     }
82     if (vendorSoftwareProductManager == null) {
83       vendorSoftwareProductManager =
84           VspManagerFactory.getInstance().createInterface();
85     }
86     if (candidateManager == null) {
87       candidateManager =
88           OrchestrationTemplateCandidateManagerFactory.getInstance().createInterface();
89     }
90   }
91
92   @Override
93   public boolean resolvesVariablesForRequest(VtpTestExecutionRequest requestItem) {
94     Map<String,String> params = requestItem.getParameters();
95
96     // no params, quickly return.
97     if (params == null) {
98       return false;
99     }
100
101     // no match, quickly return
102     if (!params.containsKey(VSP_ID) || !params.containsKey(VSP_VERSION)) {
103       return false;
104     }
105
106     return (params.keySet().stream().anyMatch(s -> StringUtils.startsWith(s, CSAR_PREFIX)));
107   }
108
109   @Override
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);
115
116     try {
117       extractMetadata(requestItem, body, vspId, version);
118     }
119     catch (IOException ex) {
120       logger.error("metadata extraction failed", ex);
121     }
122   }
123
124   /**
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
129    */
130   @SuppressWarnings("WeakerAccess")
131   protected void extractMetadata(VtpTestExecutionRequest requestItem, MultiValueMap<String, Object> body, String vspId, String version) throws IOException {
132
133     Version ver = new Version(version);
134     logger.debug("attempt to retrieve archive for VSP {} version {}", vspId, ver.getId());
135
136     Optional<Pair<String, byte[]>> ozip = candidateManager.get(vspId, new Version(version));
137     if (!ozip.isPresent()) {
138       ozip = vendorSoftwareProductManager.get(vspId, ver);
139     }
140
141     if (!ozip.isPresent()) {
142       List<Version> versions = versioningManager.list(vspId);
143       String knownVersions = versions
144           .stream()
145           .map(v -> String.format("%d.%d: %s (%s)", v.getMajor(), v.getMinor(), v.getStatus(), v.getId()))
146           .collect(Collectors.joining("\n"));
147
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);
150
151       throw new ExternalTestingException("Archive Processing Failed", 500, detail);
152     }
153
154     // safe here to do get.
155     Pair<String, byte[]> zip = ozip.get();
156     processArchive(requestItem, body, zip.getRight());
157   }
158
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;
165     }
166     @Override
167     public String getFilename() {
168       return this.filename;
169     }
170
171   }
172
173   @SuppressWarnings("WeakerAccess")
174   protected void processArchive(VtpTestExecutionRequest requestItem, MultiValueMap<String, Object> body, byte[] zip) {
175     try {
176       ZipInputStream zipStream = new ZipInputStream(new ByteArrayInputStream(zip));
177       ZipEntry entry;
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);
185             }
186         });
187       }
188     } catch (IOException ex) {
189       logger.error("IO Exception parsing zip", ex);
190     }
191   }
192
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)) {
197       try {
198         NamedByteArrayResource res = new NamedByteArrayResource(IOUtils.toByteArray(zipStream), filename);
199         body.add("file", res);
200
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);
204
205       } catch (IOException ex) {
206         logger.error("failed to read zip entry content for {}", entryName, ex);
207       }
208     }
209   }
210 }