import org.openecomp.sdc.datatypes.error.ErrorMessage;
import org.openecomp.sdc.tosca.csar.OnboardingToscaMetadata;
import org.openecomp.sdc.tosca.csar.ToscaMetadata;
+import org.openecomp.sdc.tosca.csar.SOL004ManifestOnboarding;
import org.openecomp.sdc.tosca.datatypes.ToscaServiceModel;
import org.openecomp.sdc.tosca.services.impl.ToscaFileOutputServiceCsarImpl;
import org.openecomp.sdc.validation.util.ValidationManagerUtil;
import org.openecomp.sdc.vendorsoftwareproduct.errors.TranslationFileCreationErrorBuilder;
import org.openecomp.sdc.vendorsoftwareproduct.errors.VendorSoftwareProductInvalidErrorBuilder;
import org.openecomp.sdc.tosca.csar.Manifest;
-import org.openecomp.sdc.tosca.csar.OnboardingManifest;
import org.openecomp.sdc.vendorsoftwareproduct.informationArtifact.InformationArtifactGenerator;
import org.openecomp.sdc.vendorsoftwareproduct.services.impl.etsi.ETSIService;
import org.openecomp.sdc.vendorsoftwareproduct.services.filedatastructuremodule.CandidateService;
if(etsiService.isSol004WithToscaMetaDirectory(toscaServiceModel.getArtifactFiles())){
FileContentHandler handler = toscaServiceModel.getArtifactFiles();
try(InputStream manifestInputStream = getManifest(handler)) {
- Manifest onboardingManifest = OnboardingManifest.parse(manifestInputStream);
+ Manifest onboardingManifest = new SOL004ManifestOnboarding();
+ onboardingManifest.parse(manifestInputStream);
etsiService.moveNonManoFileToArtifactFolder(handler, onboardingManifest);
}
}
import org.openecomp.sdc.logging.api.Logger;
import org.openecomp.sdc.logging.api.LoggerFactory;
import org.openecomp.sdc.tosca.csar.Manifest;
-import org.openecomp.sdc.tosca.csar.OnboardingManifest;
+import org.openecomp.sdc.tosca.csar.ONAPManifestOnboarding;
import org.openecomp.sdc.tosca.csar.OnboardingToscaMetadata;
import org.openecomp.sdc.tosca.csar.ToscaMetadata;
import java.io.IOException;
try (InputStream fileContent = contentMap.getFileContent(MAIN_SERVICE_TEMPLATE_MF_FILE_NAME)) {
- Manifest onboardingManifest = OnboardingManifest.parse(fileContent);
+ Manifest onboardingManifest = new ONAPManifestOnboarding();
+ onboardingManifest.parse(fileContent);
if (!onboardingManifest.isValid()) {
onboardingManifest.getErrors().forEach(error -> uploadFileErrors.add(new ErrorMessage(ErrorLevel.ERROR,
error)));
import org.openecomp.sdc.logging.api.Logger;
import org.openecomp.sdc.logging.api.LoggerFactory;
import org.openecomp.sdc.tosca.csar.Manifest;
-import org.openecomp.sdc.tosca.csar.OnboardingManifest;
import org.openecomp.sdc.tosca.csar.OnboardingToscaMetadata;
+import org.openecomp.sdc.tosca.csar.SOL004ManifestOnboarding;
import org.openecomp.sdc.tosca.csar.ToscaMetadata;
import org.openecomp.sdc.vendorsoftwareproduct.impl.orchestration.exceptions.InvalidManifestMetadataException;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.stream.Collectors;
import static org.openecomp.sdc.tosca.csar.CSARConstants.CSAR_VERSION_1_0;
import static org.openecomp.sdc.tosca.csar.CSARConstants.CSAR_VERSION_1_1;
import static org.openecomp.sdc.tosca.csar.CSARConstants.MANIFEST_PNF_METADATA;
import static org.openecomp.sdc.tosca.csar.CSARConstants.MANIFEST_VNF_METADATA;
import static org.openecomp.sdc.tosca.csar.CSARConstants.NON_FILE_IMPORT_ATTRIBUTES;
+import static org.openecomp.sdc.tosca.csar.CSARConstants.TOSCA_MANIFEST_FILE_EXT;
import static org.openecomp.sdc.tosca.csar.CSARConstants.TOSCA_META_FILE_VERSION_ENTRY;
import static org.openecomp.sdc.tosca.csar.CSARConstants.TOSCA_META_CREATED_BY_ENTRY;
import static org.openecomp.sdc.tosca.csar.CSARConstants.TOSCA_META_CSAR_VERSION_ENTRY;
import static org.openecomp.sdc.tosca.csar.CSARConstants.TOSCA_META_ENTRY_TESTS;
import static org.openecomp.sdc.tosca.csar.CSARConstants.TOSCA_META_FILE_VERSION;
import static org.openecomp.sdc.tosca.csar.CSARConstants.TOSCA_META_PATH_FILE_NAME;
+import static org.openecomp.sdc.tosca.csar.CSARConstants.TOSCA_TYPE_PNF;
+import static org.openecomp.sdc.tosca.csar.CSARConstants.TOSCA_TYPE_VNF;
/**
* Validates the contents of the package to ensure it complies with the "CSAR with TOSCA-Metadata directory" structure
String manifestFileName = getFileName(entries.get(TOSCA_META_ENTRY_MANIFEST));
String manifestExtension = getFileExtension(entries.get(TOSCA_META_ENTRY_MANIFEST));
String mainDefinitionFileName= getFileName(entries.get(TOSCA_META_ENTRY_DEFINITIONS));
- if(!("mf").equals(manifestExtension)){
+ if(!(TOSCA_MANIFEST_FILE_EXT).equals(manifestExtension)){
reportError(ErrorLevel.ERROR, Messages.MANIFEST_INVALID_EXT.getErrorMessage());
}
if(!mainDefinitionFileName.equals(manifestFileName)){
private void verifyMetadataEntryVersions(String key, String version) {
if(!(isValidTOSCAVersion(key,version) || isValidCSARVersion(key, version) || TOSCA_META_CREATED_BY_ENTRY.equals(key))) {
- errorsByFile.add(new ErrorMessage(ErrorLevel.ERROR, Messages.ENTITY_NOT_FOUND.getErrorMessage()));
- LOGGER.error("{}: key {} - value {} ", Messages.ENTITY_NOT_FOUND.getErrorMessage(), key, version);
+ errorsByFile.add(new ErrorMessage(ErrorLevel.ERROR, String.format(Messages.METADATA_INVALID_VERSION.getErrorMessage(), key, version)));
+ LOGGER.error("{}: key {} - value {} ", Messages.METADATA_INVALID_VERSION.getErrorMessage(), key, version);
}
}
}
private boolean isValidCSARVersion(String value, String version){
- return "CSAR-Version".equals(value) && (CSAR_VERSION_1_1.equals(version)
+ return TOSCA_META_CSAR_VERSION_ENTRY.equals(value) && (CSAR_VERSION_1_1.equals(version)
|| CSAR_VERSION_1_0.equals(version));
}
private void validateManifestFile(FileContentHandler contentHandler, String filePath){
final Set<String> exitingFiles = contentHandler.getFileList();
if(verifyFileExists(exitingFiles, filePath)) {
- Manifest onboardingManifest = OnboardingManifest.parse(contentHandler.getFileContent(filePath));
+ Manifest onboardingManifest = new SOL004ManifestOnboarding();
+ onboardingManifest.parse(contentHandler.getFileContent(filePath));
if(onboardingManifest.isValid()){
try {
verifyManifestMetadata(onboardingManifest.getMetadata());
String metadataType = null;
for(String key: metadata.keySet()) {
if(metadataType == null){
- metadataType = key.contains("pnf") ? "pnf" : "vnf";
+ metadataType = key.contains(TOSCA_TYPE_PNF) ? TOSCA_TYPE_PNF : TOSCA_TYPE_VNF;
}else if(!key.contains(metadataType)){
throw new InvalidManifestMetadataException(Messages.MANIFEST_METADATA_INVALID_ENTRY.getErrorMessage());
}
}
- return "pnf".equals(metadataType);
+ return TOSCA_TYPE_PNF.equals(metadataType);
}
private void handleVnfMetadataEntries(Map<String, String> metadata) {
}
private void verifySourcesExists(Set<String> exitingFiles, Manifest onboardingManifest) {
- List<String> sources = onboardingManifest.getSources();
+ List<String> sources = filterSources(onboardingManifest.getSources());
Map<String, List<String>> nonManoArtifacts = onboardingManifest.getNonManoSources();
verifyFilesExist(exitingFiles, sources);
for (Map.Entry entry : nonManoArtifacts.entrySet()) {
- verifyFilesExist(exitingFiles, (List) entry.getValue());
+ verifyFilesExist(exitingFiles, filterSources((List)entry.getValue()));
}
}
+ private List<String> filterSources(List<String> source){
+ return source.stream()
+ .filter(this::externalFileReferences)
+ .collect(Collectors.toList());
+ }
+
+ private boolean externalFileReferences(String filePath){
+ return !filePath.contains("://");
+ }
+
private void validateOtherEntries(List<String> folderList, String folderPath){
if(!verifyFoldersExist(folderList, folderPath))
reportError(ErrorLevel.ERROR, String.format(Messages.METADATA_MISSING_OPTIONAL_FOLDERS.getErrorMessage(),
pnf_product_name: RadioNode
vnf_provider_id: Bilal Iqbal
pnf_package_version: 1.0
- vnf_release_date_time: 2019-12-14T11:25:00+00:00
-
-Source: Definitions/MainServiceTemplate.yaml
\ No newline at end of file
+ vnf_release_date_time: 2019-12-14T11:25:00+00:00
\ No newline at end of file
invalid_provider_id: Bilal Iqbal
invalid_package_version: 1.0
invalid_release_date_time: 2019-12-14T11:25:00+00:00
-
-Source: Definitions/MainServiceTemplate.yaml
\ No newline at end of file
vnf_provider_id: Bilal Iqbal
vnf_package_version: 1.0
vnf_release_date_time: 2019-12-14T11:26:00+00:00
-
-Source: Definitions/MainServiceTemplate.yaml
\ No newline at end of file
metadata:
pnf_product_name: RadioNode
pnf_release_date_time: 2019-12-14T11:25:00+00:00
-
-Source: Definitions/MainServiceTemplate.yaml
\ No newline at end of file
metadata:
- vnf_product_name: RadioNode
-
-Source: Definitions/MainServiceTemplate.yaml
\ No newline at end of file
+ vnf_product_name: RadioNode
\ No newline at end of file
pnf_package_version: 1.0
pnf_release_date_time: 2019-12-14T11:25:00+00:00
-Source: Definitions/MainServiceTemplate.yaml
\ No newline at end of file
+Source: Definitions/MainServiceTemplate.yaml
+Algorithm: SHA-abc
+Hash: 09e5a788acb180162c51679ae4c998039fa6644505db2415e35107d1ee213943
+
+Source: http://Definitions/MainServiceTemplate.yaml
+Algorithm: SHA-def
+Hash:36f945953929812aca2701b114b068c71bd8c95ceb3609711428c26325649165
+
+Source: ftp://Definitions/MainServiceTemplate.yaml
+Algorithm: SHA-ghi
+Hash: d0e7828293355a07c2dccaaa765c80b507e60e6167067c950dc2e6b0da0dbd8b
+
+
+----BEGIN CMS-----
+MIGDBgsqhkiG9w0BCRABCaB0MHICAQAwDQYLKoZIhvcNAQkQAwgwXgYJKoZIhvcN
+AQcBoFEET3icc87PK0nNK9ENqSxItVIoSa0o0S/ISczMs1ZIzkgsKk4tsQ0N1nUM
+dvb05OXi5XLPLEtViMwvLVLwSE0sKlFIVHAqSk3MBkkBAJv0Fx0=
+-----END CMS-----
+
+non_mano_artifact_sets:
+ onap_pm_events:
+ Source: Definitions/MainServiceTemplate.yaml
+ Source: http://Definitions/MainServiceTemplate.yaml
+ Source: ftp://Definitions/MainServiceTemplate.yaml
METADATA_PARSER_INTERNAL("Invalid Metadata file"),
METADATA_MISSING_OPTIONAL_FOLDERS("Missing folder %s in package"),
METADATA_UNSUPPORTED_ENTRY("Following entry not supported in TOSCA.meta %s"),
+ METADATA_INVALID_VERSION("Invalid entry %s value %s"),
METADATA_INVALID_VALUE("Invalid value %s in TOSCA.meta file"),
METADATA_MISSING_ENTRY("TOSCA.meta file missing entry %s"),
METADATA_NO_ENTRY_DEFINITIONS("TOSCA.meta must contain Entry Definitions"),
--- /dev/null
+/*
+ * Copyright © 2016-2017 European Support Limited
+ * Modification Copyright (C) 2019 Nordix Foundation.
+ *
+ * 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.openecomp.sdc.tosca.csar;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import org.openecomp.sdc.common.errors.Messages;
+import org.openecomp.sdc.logging.api.Logger;
+import org.openecomp.sdc.logging.api.LoggerFactory;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import static org.openecomp.core.validation.errors.ErrorMessagesFormatBuilder.getErrorWithParameters;
+import static org.openecomp.sdc.tosca.csar.CSARConstants.METADATA_MF_ATTRIBUTE;
+import static org.openecomp.sdc.tosca.csar.CSARConstants.SEPERATOR_MF_ATTRIBUTE;
+
+ abstract class AbstractOnboardingManifest implements Manifest{
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(AbstractOnboardingManifest.class);
+ protected Map<String, String> metadata;
+ protected List<String> sources;
+ protected List<String> errors;
+ protected Map<String, List<String>> nonManoSources;
+
+ protected AbstractOnboardingManifest() {
+ errors = new ArrayList<>();
+ sources = new ArrayList<>();
+ metadata = new HashMap<>();
+ nonManoSources = new HashMap<>();
+ }
+
+ @Override
+ public void parse(InputStream is) {
+ try {
+ ImmutableList<String> lines = readAllLines(is);
+ processManifest(lines);
+ } catch (IOException e){
+ LOGGER.error(e.getMessage(),e);
+ errors.add(Messages.MANIFEST_PARSER_INTERNAL.getErrorMessage());
+ }
+ }
+
+ protected void processManifest(ImmutableList<String> lines) {
+ if (isEmptyManifest(lines)){
+ return;
+ }
+ Iterator<String> iterator = lines.iterator();
+ //SOL004 #4.3.2: The manifest file shall start with the package metadata
+ String line = iterator.next();
+ if (!isMetadata(line)) {
+ return;
+ }
+ //handle metadata
+ processMetadata(iterator);
+ if (errors.isEmpty() && metadata.isEmpty()) {
+ errors.add(Messages.MANIFEST_NO_METADATA.getErrorMessage());
+ }
+ }
+
+ protected abstract void processMetadata(Iterator<String> iterator);
+
+ protected boolean isEmptyLine(Iterator<String> iterator, String line) {
+ if(line.isEmpty()){
+ processMetadata(iterator);
+ return true;
+ }
+ return false;
+ }
+
+ protected boolean isInvalidLine(String line, String[] metaSplit) {
+ if (metaSplit.length < 2){
+ reportError(line);
+ return true;
+ }
+ return false;
+ }
+
+ protected boolean isMetadata(String line) {
+ if(line.trim().equals(METADATA_MF_ATTRIBUTE + SEPERATOR_MF_ATTRIBUTE)){
+ return true;
+ }
+ reportError(line);
+ return false;
+ }
+
+ protected boolean isEmptyManifest(ImmutableList<String> lines) {
+ if(lines == null || lines.isEmpty()){
+ errors.add(Messages.MANIFEST_EMPTY.getErrorMessage());
+ return true;
+ }
+ return false;
+ }
+
+ protected void reportError(String line) {
+ errors.add(getErrorWithParameters(Messages.MANIFEST_INVALID_LINE.getErrorMessage(), line));
+ }
+
+ protected ImmutableList<String> readAllLines(InputStream is) throws IOException {
+ if(is == null){
+ throw new IOException("Input Stream cannot be null!");
+ }
+ ImmutableList.Builder<String> builder = ImmutableList.<String> builder();
+ try (BufferedReader bufferedReader = new BufferedReader(
+ new InputStreamReader(is, StandardCharsets.UTF_8.newDecoder()))) {
+ bufferedReader.lines().forEach(builder::add);
+ }
+ return builder.build();
+ }
+
+ public Map<String, String> getMetadata() {
+ if (!isValid()){
+ return Collections.emptyMap();
+ }
+ return ImmutableMap.copyOf(metadata);
+ }
+
+ public List<String> getSources() {
+ if (!isValid()){
+ return Collections.emptyList();
+ }
+ return ImmutableList.copyOf(sources);
+ }
+
+ public List<String> getErrors() {
+ return ImmutableList.copyOf(errors);
+ }
+
+ public boolean isValid() {
+ return errors.isEmpty();
+ }
+
+ public Map<String, List<String>> getNonManoSources() {
+ if (!isValid()){
+ return Collections.emptyMap();
+ }
+ return ImmutableMap.copyOf(nonManoSources);
+ }
+}
public static final int MANIFEST_METADATA_LIMIT = 4;
public static final String METADATA_MF_ATTRIBUTE = "metadata";
public static final String SOURCE_MF_ATTRIBUTE = "Source";
+ public static final String ALGORITHM_MF_ATTRIBUTE = "Algorithm";
+ public static final String HASH_MF_ATTRIBUTE = "Hash";
+ public static final String CMS_BEGIN = "----BEGIN CMS-----";
+ public static final String CMD_END = "----END CMS-----";
public static final String SEPERATOR_MF_ATTRIBUTE = ":";
public static final String NON_MANO_MF_ATTRIBUTE = "non_mano_artifact_sets";
public static final String TOSCA_META_ORIG_PATH_FILE_NAME="TOSCA-Metadata/TOSCA.meta.original";
public static final String CSAR_VERSION_1_1 = "1.1";
public static final ImmutableSet<String> NON_FILE_IMPORT_ATTRIBUTES =
ImmutableSet.of("repository", "namespace_uri", "namespace_prefix");
+ public static final String TOSCA_TYPE_PNF = "pnf";
+ public static final String TOSCA_TYPE_VNF = "vnf";
+ public static final String TOSCA_MANIFEST_FILE_EXT = "mf";
private CSARConstants() {
package org.openecomp.sdc.tosca.csar;
+import java.io.InputStream;
import java.util.List;
import java.util.Map;
public interface Manifest {
+
+ /**
+ * This Method will parse manifest, extracting fields mandatory/non-mandatory,
+ * if error occurred it's recorded and will be used for deciding if manifest is valid
+ * @param is manifest file input stream
+ */
+ void parse(InputStream is);
+
/**
* Returns if manifest is valid
* @return true/false
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2019 Nordix Foundation.
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.tosca.csar;
+
+import com.google.common.collect.ImmutableList;
+import org.openecomp.sdc.common.errors.Messages;
+import java.util.Iterator;
+
+import static org.openecomp.sdc.tosca.csar.CSARConstants.SEPERATOR_MF_ATTRIBUTE;
+import static org.openecomp.sdc.tosca.csar.CSARConstants.SOURCE_MF_ATTRIBUTE;
+
+public class ONAPManifestOnboarding extends AbstractOnboardingManifest implements Manifest {
+
+ @Override
+ protected void processManifest(ImmutableList<String> lines) {
+ super.processManifest(lines);
+ if (errors.isEmpty() && sources.isEmpty()) {
+ errors.add(Messages.MANIFEST_NO_SOURCES.getErrorMessage());
+ }
+ }
+
+ @Override
+ protected void processMetadata(Iterator<String> iterator) {
+ if(!iterator.hasNext()){
+ return;
+ }
+ String line = iterator.next();
+ if(isEmptyLine(iterator, line)) {
+ return;
+ }
+ String[] metaSplit = line.split(SEPERATOR_MF_ATTRIBUTE);
+ if (isInvalidLine(line, metaSplit)) {
+ return;
+ }
+ if (!metaSplit[0].equals(SOURCE_MF_ATTRIBUTE)){
+ String value = line.substring((metaSplit[0] + SEPERATOR_MF_ATTRIBUTE).length()).trim();
+ metadata.put(metaSplit[0].trim(),value.trim());
+ processMetadata(iterator);
+ }else if(metaSplit[0].startsWith(SOURCE_MF_ATTRIBUTE)){
+ String value = line.substring((metaSplit[0] + SEPERATOR_MF_ATTRIBUTE).length()).trim();
+ sources.add(value);
+ processMetadata(iterator);
+ }
+ }
+
+}
+++ /dev/null
-/*
- * Copyright © 2016-2017 European Support Limited
- *
- * 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.openecomp.sdc.tosca.csar;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import org.openecomp.sdc.common.errors.Messages;
-import org.openecomp.sdc.logging.api.Logger;
-import org.openecomp.sdc.logging.api.LoggerFactory;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import static org.openecomp.core.validation.errors.ErrorMessagesFormatBuilder.getErrorWithParameters;
-import static org.openecomp.sdc.tosca.csar.CSARConstants.METADATA_MF_ATTRIBUTE;
-import static org.openecomp.sdc.tosca.csar.CSARConstants.NON_MANO_MF_ATTRIBUTE;
-import static org.openecomp.sdc.tosca.csar.CSARConstants.SEPERATOR_MF_ATTRIBUTE;
-import static org.openecomp.sdc.tosca.csar.CSARConstants.SOURCE_MF_ATTRIBUTE;
-
-public class OnboardingManifest implements Manifest{
- private static final Logger LOGGER = LoggerFactory.getLogger(OnboardingManifest.class);
- private Map<String, String> metadata;
- private List<String> sources;
- private List<String> errors;
- private Map<String, List<String>> nonManoSources;
-
- private OnboardingManifest() {
- errors = new ArrayList<>();
- sources = new ArrayList<>();
- metadata = new HashMap<>();
- nonManoSources = new HashMap<>();
- }
-
- /**
- * This Method will parse manifest, extracting fields mandatory/non-mandatory,
- * if error occurred it's recorded and will be used for deciding if manifest is valid
- * @param is manifest file input stream
- * @return Manifest object
- */
- public static Manifest parse(InputStream is) {
- OnboardingManifest manifest = new OnboardingManifest();
- try {
- ImmutableList<String> lines = manifest.readAllLines(is);
- manifest.processManifest(lines);
- } catch (IOException e){
- LOGGER.error(e.getMessage(),e);
- manifest.errors.add(Messages.MANIFEST_PARSER_INTERNAL.getErrorMessage());
- }
- return manifest;
- }
-
- private void processManifest(ImmutableList<String> lines) {
- if(lines == null || lines.isEmpty()){
- errors.add(Messages.MANIFEST_EMPTY.getErrorMessage());
- return;
- }
- Iterator<String> iterator = lines.iterator();
- //SOL004 #4.3.2: The manifest file shall start with the package metadata
- String line = iterator.next();
- if(!line.trim().equals(METADATA_MF_ATTRIBUTE + SEPERATOR_MF_ATTRIBUTE)){
- reportError(line);
- return;
- }
- //handle metadata
- processMetadata(iterator);
-
- if (errors.isEmpty()) {
- if (metadata.isEmpty()) {
- errors.add(Messages.MANIFEST_NO_METADATA.getErrorMessage());
- }
- if (sources.isEmpty()) {
- errors.add(Messages.MANIFEST_NO_SOURCES.getErrorMessage());
- }
- }
- }
-
- private void processSourcesAndNonManoSources(Iterator<String> iterator, String prevLine) {
- if(prevLine.isEmpty()){
- if(iterator.hasNext()){
- processSourcesAndNonManoSources(iterator, iterator.next());
- }
- }else if(prevLine.startsWith(SOURCE_MF_ATTRIBUTE+SEPERATOR_MF_ATTRIBUTE)){
- processSource(iterator, prevLine);
- } else if(prevLine.startsWith(NON_MANO_MF_ATTRIBUTE+SEPERATOR_MF_ATTRIBUTE)){
- //non mano should be the last bit in manifest file,
- // all sources after non mano will be placed to the last non mano
- // key, if any other structure met error reported
- processNonManoInputs(iterator, iterator.next());
- }else{
- reportError(prevLine);
- }
- }
-
- private void processSource(Iterator<String> iterator, String prevLine) {
- String value = prevLine.substring((SOURCE_MF_ATTRIBUTE + SEPERATOR_MF_ATTRIBUTE).length()).trim();
- sources.add(value);
- if(iterator.hasNext()) {
- processSourcesAndNonManoSources(iterator, iterator.next());
- }
- }
-
- private void processMetadata(Iterator<String> iterator) {
- if(!iterator.hasNext()){
- return;
- }
- String line = iterator.next();
- if(line.isEmpty()){
- processMetadata(iterator);
- return;
- }
- String[] metaSplit = line.split(SEPERATOR_MF_ATTRIBUTE);
- if (metaSplit.length < 2){
- reportError(line);
- return;
- }
- if (!metaSplit[0].equals(SOURCE_MF_ATTRIBUTE) && !metaSplit[0].equals(NON_MANO_MF_ATTRIBUTE)){
- String value = line.substring((metaSplit[0] + SEPERATOR_MF_ATTRIBUTE).length()).trim();
- metadata.put(metaSplit[0].trim(),value.trim());
- processMetadata(iterator);
- }
- else {
- processSourcesAndNonManoSources(iterator, line);
- }
- }
-
- private void processNonManoInputs(Iterator<String> iterator, String prevLine) {
- //Non Mano input should always start with key, if no key available report an error
- if(prevLine.trim().equals(SOURCE_MF_ATTRIBUTE + SEPERATOR_MF_ATTRIBUTE)){
- reportError(prevLine);
- return;
- }
- //key should contain : separator
- if(!prevLine.contains(SEPERATOR_MF_ATTRIBUTE)){
- reportError(prevLine);
- return;
- }
- //key shouldn't have value in the same line
- String[] metaSplit = prevLine.trim().split(SEPERATOR_MF_ATTRIBUTE);
- if (metaSplit.length > 1){
- reportError(prevLine);
- return;
- }
- int index = prevLine.indexOf(':');
- if(index > 0){
- prevLine = prevLine.substring(0, index);
- }
- processNonManoSource(iterator, prevLine, new ArrayList<>());
-
- }
-
- private void processNonManoSource(Iterator<String> iterator, String key, List<String> sources) {
- if(!iterator.hasNext()){
- return;
- }
- String line = iterator.next();
- if(line.isEmpty()){
- processNonManoSource(iterator, key, sources);
- }else if(line.trim().startsWith(SOURCE_MF_ATTRIBUTE + SEPERATOR_MF_ATTRIBUTE)){
- String value = line.replace(SOURCE_MF_ATTRIBUTE + SEPERATOR_MF_ATTRIBUTE, "").trim();
- sources.add(value);
- processNonManoSource(iterator, key, sources);
- }else {
- processNonManoInputs(iterator, line);
- }
- nonManoSources.put(key.trim(), sources);
- }
-
- private void reportError(String line) {
- errors.add(getErrorWithParameters(Messages.MANIFEST_INVALID_LINE.getErrorMessage(), line));
- }
-
- private ImmutableList<String> readAllLines(InputStream is) throws IOException {
- if(is == null){
- throw new IOException("Input Stream cannot be null!");
- }
- ImmutableList.Builder<String> builder = ImmutableList.<String> builder();
- try (BufferedReader bufferedReader = new BufferedReader(
- new InputStreamReader(is, StandardCharsets.UTF_8.newDecoder()))) {
- bufferedReader.lines().forEach(builder::add);
- }
- return builder.build();
- }
-
- public Map<String, String> getMetadata() {
- if (!isValid()){
- return Collections.emptyMap();
- }
- return ImmutableMap.copyOf(metadata);
- }
-
- public List<String> getSources() {
- if (!isValid()){
- return Collections.emptyList();
- }
- return ImmutableList.copyOf(sources);
- }
-
- public List<String> getErrors() {
- return ImmutableList.copyOf(errors);
- }
-
- public boolean isValid() {
- return errors.isEmpty();
- }
-
- public Map<String, List<String>> getNonManoSources() {
- if (!isValid()){
- return Collections.emptyMap();
- }
- return ImmutableMap.copyOf(nonManoSources);
- }
-}
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2019 Nordix Foundation.
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.tosca.csar;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import static org.openecomp.sdc.tosca.csar.CSARConstants.ALGORITHM_MF_ATTRIBUTE;
+import static org.openecomp.sdc.tosca.csar.CSARConstants.CMD_END;
+import static org.openecomp.sdc.tosca.csar.CSARConstants.CMS_BEGIN;
+import static org.openecomp.sdc.tosca.csar.CSARConstants.HASH_MF_ATTRIBUTE;
+import static org.openecomp.sdc.tosca.csar.CSARConstants.NON_MANO_MF_ATTRIBUTE;
+import static org.openecomp.sdc.tosca.csar.CSARConstants.SEPERATOR_MF_ATTRIBUTE;
+import static org.openecomp.sdc.tosca.csar.CSARConstants.SOURCE_MF_ATTRIBUTE;
+
+public class SOL004ManifestOnboarding extends AbstractOnboardingManifest implements Manifest {
+
+ @Override
+ protected void processMetadata(Iterator<String> iterator) {
+ if(!iterator.hasNext()){
+ return;
+ }
+ String line = iterator.next();
+ if(isEmptyLine(iterator, line)){
+ return;
+ }
+ String[] metaSplit = line.split(SEPERATOR_MF_ATTRIBUTE);
+ if (isInvalidLine(line, metaSplit)) {
+ return;
+ }
+ if (!metaSplit[0].equals(SOURCE_MF_ATTRIBUTE) && !metaSplit[0].equals(NON_MANO_MF_ATTRIBUTE)){
+ String value = line.substring((metaSplit[0] + SEPERATOR_MF_ATTRIBUTE).length()).trim();
+ metadata.put(metaSplit[0].trim(),value.trim());
+ processMetadata(iterator);
+ } else {
+ processSourcesAndNonManoSources(iterator, line);
+ }
+ }
+
+ private void processSourcesAndNonManoSources(Iterator<String> iterator, String prevLine) {
+ if(prevLine.isEmpty()){
+ if(iterator.hasNext()){
+ processSourcesAndNonManoSources(iterator, iterator.next());
+ }
+ } else if(prevLine.startsWith(SOURCE_MF_ATTRIBUTE+SEPERATOR_MF_ATTRIBUTE)){
+ processSource(iterator, prevLine);
+ }
+ else if(prevLine.startsWith(ALGORITHM_MF_ATTRIBUTE + SEPERATOR_MF_ATTRIBUTE) ||
+ prevLine.startsWith(HASH_MF_ATTRIBUTE + SEPERATOR_MF_ATTRIBUTE)){
+ processSourcesAndNonManoSources(iterator, iterator.next());
+ }else if(prevLine.startsWith(CMS_BEGIN)){
+ String line = iterator.next();
+ while(iterator.hasNext() && !line.contains(CMD_END)){
+ line = iterator.next();
+ }
+ processSourcesAndNonManoSources(iterator, iterator.next());
+ }
+ else if(prevLine.startsWith(NON_MANO_MF_ATTRIBUTE+SEPERATOR_MF_ATTRIBUTE)){
+ //non mano should be the last bit in manifest file,
+ // all sources after non mano will be placed to the last non mano
+ // key, if any other structure met error reported
+ processNonManoInputs(iterator, iterator.next());
+ }else{
+ reportError(prevLine);
+ }
+ }
+
+ private void processSource(Iterator<String> iterator, String prevLine) {
+ String value = prevLine.substring((SOURCE_MF_ATTRIBUTE + SEPERATOR_MF_ATTRIBUTE).length()).trim();
+ sources.add(value);
+ if(iterator.hasNext()) {
+ processSourcesAndNonManoSources(iterator, iterator.next());
+ }
+ }
+
+ private void processNonManoInputs(Iterator<String> iterator, String prevLine) {
+ if(prevLine.trim().equals(SOURCE_MF_ATTRIBUTE + SEPERATOR_MF_ATTRIBUTE)){
+ reportError(prevLine);
+ return;
+ }
+ if(!prevLine.contains(SEPERATOR_MF_ATTRIBUTE)){
+ reportError(prevLine);
+ return;
+ }
+
+ String[] metaSplit = prevLine.trim().split(SEPERATOR_MF_ATTRIBUTE);
+ if (metaSplit.length > 1){
+ reportError(prevLine);
+ return;
+ }
+ int index = prevLine.indexOf(':');
+ if(index > 0){
+ prevLine = prevLine.substring(0, index);
+ }
+ processNonManoSource(iterator, prevLine, new ArrayList<>());
+
+ }
+
+ private void processNonManoSource(Iterator<String> iterator, String key, List<String> sources) {
+ if(!iterator.hasNext()){
+ return;
+ }
+ String line = iterator.next();
+ if(line.isEmpty()){
+ processNonManoSource(iterator, key, sources);
+ }else if(line.trim().startsWith(SOURCE_MF_ATTRIBUTE + SEPERATOR_MF_ATTRIBUTE)){
+ String value = line.replace(SOURCE_MF_ATTRIBUTE + SEPERATOR_MF_ATTRIBUTE, "").trim();
+ sources.add(value);
+ processNonManoSource(iterator, key, sources);
+ }else {
+ processNonManoInputs(iterator, line);
+ }
+ nonManoSources.put(key.trim(), sources);
+ }
+}
\ No newline at end of file
--- /dev/null
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2019 Nordix Foundation.
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.tosca.exceptions;
+
+/**
+ * Indicates failure in instantiating the on-boarding manifest object correctly.
+ */
+public class OnboardingManifestInstantiationException extends RuntimeException {
+
+ public OnboardingManifestInstantiationException(String message, Throwable e) {
+ super(message, e);
+ }
+}
\ No newline at end of file
package org.openecomp.sdc.tosca.csar;
+import org.junit.Before;
import org.junit.Test;
import org.openecomp.sdc.common.errors.Messages;
-
import java.io.IOException;
import java.io.InputStream;
public class ManifestParsingTest {
+ private Manifest manifest;
+
+ @Before
+ public void setUp(){
+ manifest = new SOL004ManifestOnboarding();
+ }
+
@Test
public void testSuccessfulParsing() throws IOException {
try (InputStream is = getClass()
.getResourceAsStream("/vspmanager.csar/manifest/ValidTosca.mf")) {
- Manifest onboardingManifest = OnboardingManifest.parse(is);
- assertTrue(onboardingManifest.isValid());
- assertEquals(onboardingManifest.getMetadata().size(), 4);
- assertEquals(onboardingManifest.getSources().size(), 5);
+ manifest.parse(is);
+ assertTrue(manifest.isValid());
+ assertEquals(manifest.getMetadata().size(), 4);
+ assertEquals(manifest.getSources().size(), 5);
}
}
public void testNoMetadataParsing() throws IOException {
try (InputStream is = getClass()
.getResourceAsStream("/vspmanager.csar/manifest/InvalidTosca1.mf")) {
- Manifest onboardingManifest = OnboardingManifest.parse(is);
- assertFalse(onboardingManifest.isValid());
- assertTrue(onboardingManifest.getErrors().stream().anyMatch(error -> error
+ manifest.parse(is);
+ assertFalse(manifest.isValid());
+ assertTrue(manifest.getErrors().stream().anyMatch(error -> error
.contains(Messages.MANIFEST_INVALID_LINE.getErrorMessage().substring(0, 10))));
}
}
public void testBrokenMDParsing() throws IOException {
try (InputStream is = getClass()
.getResourceAsStream("/vspmanager.csar/manifest/InvalidTosca2.mf")) {
- Manifest onboardingManifest = OnboardingManifest.parse(is);
- assertFalse(onboardingManifest.isValid());
- assertTrue(onboardingManifest.getErrors().stream().anyMatch(error -> error
+ manifest.parse(is);
+ assertFalse(manifest.isValid());
+ assertTrue(manifest.getErrors().stream().anyMatch(error -> error
.contains(Messages.MANIFEST_INVALID_LINE.getErrorMessage().substring(0, 10))));
}
}
public void testNoMetaParsing() throws IOException {
try (InputStream is = getClass()
.getResourceAsStream("/vspmanager.csar/manifest/InvalidTosca4.mf")) {
- Manifest onboardingManifest = OnboardingManifest.parse(is);
- assertFalse(onboardingManifest.isValid());
- assertTrue(onboardingManifest.getErrors().stream().anyMatch(error -> error
+ manifest.parse(is);
+ assertFalse(manifest.isValid());
+ assertTrue(manifest.getErrors().stream().anyMatch(error -> error
.contains(Messages.MANIFEST_NO_METADATA.getErrorMessage().substring(0, 10))));
}
}
public void testSuccessfulNonManoParsing() throws IOException {
try (InputStream is = getClass()
.getResourceAsStream("/vspmanager.csar/manifest/ValidNonManoTosca.mf")) {
- Manifest onboardingManifest = OnboardingManifest.parse(is);
- assertTrue(onboardingManifest.isValid());
- assertEquals(onboardingManifest.getMetadata().size(), 4);
- assertEquals(onboardingManifest.getSources().size(), 5);
- assertEquals(onboardingManifest.getNonManoSources().size(), 2);
+ manifest.parse(is);
+ assertTrue(manifest.isValid());
+ assertEquals(manifest.getMetadata().size(), 4);
+ assertEquals(manifest.getSources().size(), 5);
+ assertEquals(manifest.getNonManoSources().size(), 2);
}
}
public void testFailfulNonManoParsing() throws IOException {
try (InputStream is = getClass()
.getResourceAsStream("/vspmanager.csar/manifest/InValidNonManoTosca.mf")) {
- Manifest onboardingManifest = OnboardingManifest.parse(is);
- assertFalse(onboardingManifest.isValid());
+ manifest.parse(is);
+ assertFalse(manifest.isValid());
}
}
public void testFailfulNonManoParsingWithGarbadge() throws IOException {
try (InputStream is = getClass()
.getResourceAsStream("/vspmanager.csar/manifest/InvalidTocsaNonManoGarbadgeAtEnd.mf")) {
- Manifest onboardingManifest = OnboardingManifest.parse(is);
- assertFalse(onboardingManifest.isValid());
+ manifest.parse(is);
+ assertFalse(manifest.isValid());
}
}
public void testParseManifestWithNoFile() throws IOException {
try (InputStream is = getClass()
.getResourceAsStream("/vspmanager.csar/manifest/SOME_WRONG_FILE")) {
- Manifest onboardingManifest = OnboardingManifest.parse(is);
- assertFalse(onboardingManifest.isValid());
+ manifest.parse(is);
+ assertFalse(manifest.isValid());
}
}
}