2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2019 Nordix Foundation.
4 * ================================================================================
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
17 * SPDX-License-Identifier: Apache-2.0
18 * ============LICENSE_END=========================================================
21 package org.openecomp.sdc.tosca.csar;
23 import java.util.ArrayList;
24 import java.util.List;
25 import java.util.Map.Entry;
26 import java.util.Optional;
27 import org.apache.commons.lang.StringUtils;
28 import org.openecomp.sdc.common.errors.Messages;
31 * Processes a SOL004 Manifest.
33 public class SOL004ManifestOnboarding extends AbstractOnboardingManifest {
36 protected void processMetadata() {
37 Optional<String> currentLine = getCurrentLine();
38 //SOL004 #4.3.2: The manifest file shall start with the package metadata
39 if (!currentLine.isPresent() || !isMetadata(currentLine.get())) {
40 reportError(Messages.MANIFEST_START_METADATA);
41 continueToProcess = false;
44 while (continueToProcess) {
45 currentLine = readNextNonEmptyLine();
46 if (!currentLine.isPresent()) {
47 continueToProcess = validateMetadata();
50 final String metadataLine = currentLine.get();
51 final String metadataEntry = readEntryName(metadataLine).orElse(null);
52 if (!isMetadataEntry(metadataEntry)) {
53 if (metadata.size() < MAX_ALLOWED_MANIFEST_META_ENTRIES) {
54 reportError(Messages.MANIFEST_METADATA_INVALID_ENTRY1, metadataLine);
55 continueToProcess = false;
58 continueToProcess = validateMetadata();
61 final String metadataValue = readEntryValue(metadataLine).orElse(null);
62 addToMetadata(metadataEntry, metadataValue);
63 continueToProcess = isValid();
65 readNextNonEmptyLine();
69 protected void processBody() {
70 while (continueToProcess) {
71 final ManifestTokenType manifestTokenType = detectLineEntry().orElse(null);
72 if (manifestTokenType == null) {
73 getCurrentLine().ifPresent(line -> reportInvalidLine());
77 switch (manifestTokenType) {
81 case NON_MANO_ARTIFACT_SETS:
82 processNonManoArtifactEntry();
83 continueToProcess = false;
89 getCurrentLine().ifPresent(line -> reportInvalidLine());
90 continueToProcess = false;
97 * Processes the {@link ManifestTokenType#NON_MANO_ARTIFACT_SETS} entry.
99 private void processNonManoArtifactEntry() {
100 Optional<String> currentLine = readNextNonEmptyLine();
101 while (currentLine.isPresent()) {
102 final ManifestTokenType manifestTokenType = detectLineEntry().orElse(null);
103 if (manifestTokenType != null) {
104 reportError(Messages.MANIFEST_INVALID_NON_MANO_KEY, manifestTokenType.getToken());
105 continueToProcess = false;
108 final String nonManoKey = readCurrentEntryName().orElse(null);
109 if (nonManoKey == null) {
110 reportError(Messages.MANIFEST_INVALID_NON_MANO_KEY, currentLine.get());
111 continueToProcess = false;
114 readNextNonEmptyLine();
115 final List<String> nonManoSourceList = readNonManoSourceList();
117 continueToProcess = false;
120 if (nonManoSourceList.isEmpty()) {
121 reportError(Messages.MANIFEST_EMPTY_NON_MANO_KEY, nonManoKey);
122 continueToProcess = false;
125 if (nonManoSources.get(nonManoKey) == null) {
126 nonManoSources.put(nonManoKey, nonManoSourceList);
128 nonManoSources.get(nonManoKey).addAll(nonManoSourceList);
130 currentLine = getCurrentLine();
135 * Processes {@link ManifestTokenType#SOURCE} entries in {@link ManifestTokenType#NON_MANO_ARTIFACT_SETS}.
137 * @return A list of sources paths
139 private List<String> readNonManoSourceList() {
140 final List<String> nonManoSourceList = new ArrayList<>();
141 while (getCurrentLine().isPresent()) {
142 final ManifestTokenType manifestTokenType = detectLineEntry().orElse(null);
143 if (manifestTokenType != ManifestTokenType.SOURCE) {
147 final String value = readCurrentEntryValue().orElse(null);
148 if (!StringUtils.isEmpty(value)) {
149 nonManoSourceList.add(value);
151 reportError(Messages.MANIFEST_EMPTY_NON_MANO_SOURCE);
155 readNextNonEmptyLine();
157 return nonManoSourceList;
161 * Reads a manifest CMS signature.
163 private void readCmsSignature() {
164 if (cmsSignature != null) {
165 reportError(Messages.MANIFEST_DUPLICATED_CMS_SIGNATURE);
166 continueToProcess = false;
169 Optional<String> currentLine = readNextNonEmptyLine();
170 if(!getCurrentLine().isPresent()) {
173 StringBuilder stringBuilder = new StringBuilder();
174 while (currentLine.isPresent() && detectLineEntry().orElse(null) != ManifestTokenType.CMS_END) {
175 stringBuilder.append(currentLine.get());
176 stringBuilder.append("\n");
177 currentLine = readNextNonEmptyLine();
180 if (currentLine.isPresent()) {
181 cmsSignature = stringBuilder.toString();
182 readNextNonEmptyLine();
187 * Detects the current line manifest token.
189 * @return the current line manifest token.
191 private Optional<ManifestTokenType> detectLineEntry() {
192 final Optional<String> currentLine = getCurrentLine();
193 if (currentLine.isPresent()) {
194 final String line = currentLine.get();
195 final String entry = readEntryName(line).orElse(null);
197 return ManifestTokenType.parse(line);
199 return ManifestTokenType.parse(entry);
202 return Optional.empty();
206 * Validates the manifest metadata content, reporting errors found.
208 * @return {@code true} if the metadata content is valid, {@code false} otherwise.
210 private boolean validateMetadata() {
211 if (metadata.isEmpty()) {
212 reportError(Messages.MANIFEST_NO_METADATA);
216 final Entry<String, String> firstManifestEntry = metadata.entrySet().iterator().next();
217 final ManifestTokenType firstManifestEntryTokenType =
218 ManifestTokenType.parse(firstManifestEntry.getKey()).orElse(null);
219 if (firstManifestEntryTokenType == null) {
220 reportError(Messages.MANIFEST_METADATA_INVALID_ENTRY1, firstManifestEntry.getKey());
223 for (final Entry<String, String> manifestEntry : metadata.entrySet()) {
224 final ManifestTokenType manifestEntryTokenType = ManifestTokenType.parse(manifestEntry.getKey())
226 if (manifestEntryTokenType == null) {
227 reportError(Messages.MANIFEST_METADATA_INVALID_ENTRY1, manifestEntry.getKey());
230 if ((firstManifestEntryTokenType.isMetadataVnfEntry() && !manifestEntryTokenType.isMetadataVnfEntry())
231 || (firstManifestEntryTokenType.isMetadataPnfEntry() && !manifestEntryTokenType.isMetadataPnfEntry())) {
232 reportError(Messages.MANIFEST_METADATA_UNEXPECTED_ENTRY_TYPE);
237 if (metadata.entrySet().size() != MAX_ALLOWED_MANIFEST_META_ENTRIES) {
238 reportError(Messages.MANIFEST_METADATA_DOES_NOT_MATCH_LIMIT, MAX_ALLOWED_MANIFEST_META_ENTRIES);
246 * Processes a Manifest {@link ManifestTokenType#SOURCE} entry.
248 private void processSource() {
249 final Optional<String> currentLine = getCurrentLine();
250 if (!currentLine.isPresent()) {
253 final ManifestTokenType manifestTokenType = detectLineEntry().orElse(null);
254 if (manifestTokenType != ManifestTokenType.SOURCE) {
258 final String sourceLine = currentLine.get();
259 final String sourcePath = readEntryValue(sourceLine).orElse(null);
261 if (sourcePath == null) {
262 reportError(Messages.MANIFEST_EXPECTED_SOURCE_PATH);
265 sources.add(sourcePath);
266 readAlgorithmEntry(sourcePath);
270 * Processes entries {@link ManifestTokenType#ALGORITHM} and {@link ManifestTokenType#HASH} of a {@link
271 * ManifestTokenType#SOURCE} entry.
273 * @param sourcePath the source path related to the algorithm entry.
275 private void readAlgorithmEntry(final String sourcePath) {
276 Optional<String> currentLine = readNextNonEmptyLine();
277 if (!currentLine.isPresent()) {
280 final ManifestTokenType manifestTokenType = detectLineEntry().orElse(null);
281 if (manifestTokenType == ManifestTokenType.HASH) {
282 reportError(Messages.MANIFEST_EXPECTED_ALGORITHM_BEFORE_HASH);
283 continueToProcess = false;
286 if (manifestTokenType != ManifestTokenType.ALGORITHM) {
289 final String algorithmLine = currentLine.get();
290 final String algorithmType = readEntryValue(algorithmLine).orElse(null);
291 if (algorithmType == null) {
292 reportError(Messages.MANIFEST_EXPECTED_ALGORITHM_VALUE);
293 continueToProcess = false;
297 currentLine = readNextNonEmptyLine();
298 if (!currentLine.isPresent() || detectLineEntry().orElse(null) != ManifestTokenType.HASH) {
299 reportError(Messages.MANIFEST_EXPECTED_HASH_ENTRY);
300 continueToProcess = false;
304 final String hashLine = currentLine.get();
305 final String hash = readEntryValue(hashLine).orElse(null);
307 reportError(Messages.MANIFEST_EXPECTED_HASH_VALUE);
308 continueToProcess = false;
311 sourceAndChecksumMap.put(sourcePath, new AlgorithmDigest(algorithmType, hash));
312 readNextNonEmptyLine();