From 7d62e922e727300c6949be7c631081e735a4bc08 Mon Sep 17 00:00:00 2001 From: "waqas.ikram" Date: Mon, 7 Sep 2020 08:48:46 +0100 Subject: Adding Basic NSD parser Change-Id: I9b34054aac1649f71e0dece2a3a17e958d74d5be Issue-ID: SO-3219 Signed-off-by: waqas.ikram --- .../etsi/nfvo/ns/lcm/bpmn/flows/nsd/FileEntry.java | 111 +++++++++++ .../nfvo/ns/lcm/bpmn/flows/nsd/FileParser.java | 32 ++++ .../bpmn/flows/nsd/NetworkServiceDescriptor.java | 121 ++++++++++++ .../flows/nsd/NetworkServiceDescriptorParser.java | 209 +++++++++++++++++++++ .../nfvo/ns/lcm/bpmn/flows/nsd/ToscaMetadata.java | 75 ++++++++ .../ns/lcm/bpmn/flows/nsd/ToscaMetadataParser.java | 67 +++++++ .../lcm/bpmn/flows/nsd/VirtualNetworkFunction.java | 123 ++++++++++++ .../nfvo/ns/lcm/bpmn/flows/nsd/YamlFileParser.java | 39 ++++ .../nsd/NetworkServiceDescriptorParserTest.java | 64 +++++++ .../src/test/resources/application.yaml | 2 +- .../src/test/resources/invalid_ns.csar | Bin 0 -> 778 bytes .../src/test/resources/ns.csar | Bin 0 -> 2952 bytes 12 files changed, 842 insertions(+), 1 deletion(-) create mode 100644 so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/FileEntry.java create mode 100644 so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/FileParser.java create mode 100644 so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/NetworkServiceDescriptor.java create mode 100644 so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/NetworkServiceDescriptorParser.java create mode 100644 so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/ToscaMetadata.java create mode 100644 so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/ToscaMetadataParser.java create mode 100644 so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/VirtualNetworkFunction.java create mode 100644 so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/YamlFileParser.java create mode 100644 so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/NetworkServiceDescriptorParserTest.java create mode 100644 so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/resources/invalid_ns.csar create mode 100644 so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/resources/ns.csar diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/FileEntry.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/FileEntry.java new file mode 100644 index 0000000000..d1364b9e38 --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/FileEntry.java @@ -0,0 +1,111 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Ericsson. All rights reserved. + * ================================================================================ + * 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.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.nsd; + +import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.utils.Utils.toIndentedString; +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.util.Objects; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +public class FileEntry { + + private boolean isDirectory; + private String filePath; + private byte[] fileContent; + + public boolean isDirectory() { + return isDirectory; + } + + public void setDirectory(final boolean isDirectory) { + this.isDirectory = isDirectory; + } + + public FileEntry isDirectory(final boolean isDirectory) { + this.isDirectory = isDirectory; + return this; + } + + public String getFilePath() { + return filePath; + } + + public void setFilename(final String filePath) { + this.filePath = filePath; + } + + public FileEntry filePath(final String filePath) { + this.filePath = filePath; + return this; + } + + public byte[] getFileContent() { + return fileContent; + } + + public void setFileContent(final byte[] fileContent) { + this.fileContent = fileContent; + } + + public FileEntry fileContent(final byte[] fileContent) { + this.fileContent = fileContent; + return this; + } + + public InputStream getFileContentAsStream() { + if (fileContent == null || fileContent.length == 0) { + return null; + } + return new ByteArrayInputStream(fileContent); + } + + @Override + public int hashCode() { + return Objects.hash(isDirectory, filePath, fileContent); + } + + @Override + public boolean equals(final Object obj) { + if (obj instanceof FileEntry) { + final FileEntry other = (FileEntry) obj; + return Objects.equals(isDirectory, other.isDirectory) && Objects.equals(filePath, other.filePath) + && Objects.equals(fileContent, other.fileContent); + } + return false; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder(); + sb.append("class FileEntry {\n"); + sb.append(" isDirectory: ").append(toIndentedString(isDirectory)).append("\n"); + sb.append(" filePath: ").append(toIndentedString(filePath)).append("\n"); + sb.append(" fileContent size: ").append(toIndentedString(fileContent != null ? fileContent.length : 0)) + .append("\n"); + sb.append("}"); + return sb.toString(); + } + + +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/FileParser.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/FileParser.java new file mode 100644 index 0000000000..9df5262302 --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/FileParser.java @@ -0,0 +1,32 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 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.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.nsd; + +import java.util.Map; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +public interface FileParser { + + Map getFileContent(final FileEntry entryDefinitionFileEntry); + +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/NetworkServiceDescriptor.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/NetworkServiceDescriptor.java new file mode 100644 index 0000000000..694b476ce3 --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/NetworkServiceDescriptor.java @@ -0,0 +1,121 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Ericsson. All rights reserved. + * ================================================================================ + * 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.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.nsd; + +import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.utils.Utils.toIndentedString; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +public class NetworkServiceDescriptor implements Serializable { + + private static final long serialVersionUID = -1739293595041180242L; + + private String type; + + private Map properties = new HashMap<>(); + + private List vnfs = new ArrayList<>(); + + public String getType() { + return type; + } + + public void setType(final String type) { + this.type = type; + } + + public NetworkServiceDescriptor type(final String type) { + this.type = type; + return this; + } + + public Map getProperties() { + return properties; + } + + public void setProperties(final Map properties) { + this.properties = properties; + } + + public NetworkServiceDescriptor properties(final Map properties) { + this.properties = properties; + return this; + } + + public List getVnfs() { + return vnfs; + } + + public void setVnfs(final List vnfs) { + if (vnfs != null) { + this.vnfs = vnfs; + } else { + this.vnfs = new ArrayList<>(); + } + } + + public NetworkServiceDescriptor addVnfPkgIdsItem(final VirtualNetworkFunction vnf) { + if (this.vnfs == null) { + this.vnfs = new ArrayList<>(); + } + this.vnfs.add(vnf); + return this; + } + + public NetworkServiceDescriptor vnfs(final List vnfs) { + this.vnfs = vnfs; + return this; + } + + @Override + public int hashCode() { + return Objects.hash(type, properties, vnfs); + } + + @Override + public boolean equals(final Object obj) { + if (obj instanceof NetworkServiceDescriptor) { + final NetworkServiceDescriptor other = (NetworkServiceDescriptor) obj; + return Objects.equals(type, other.type) && Objects.equals(properties, other.properties) + && Objects.equals(vnfs, other.vnfs); + } + return false; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder(); + sb.append("class NetworkServiceDescriptor {\n"); + sb.append(" type: ").append(toIndentedString(type)).append("\n"); + sb.append(" properties: ").append(toIndentedString(properties)).append("\n"); + sb.append(" vnfs: ").append(toIndentedString(vnfs)).append("\n"); + sb.append("}"); + return sb.toString(); + } + +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/NetworkServiceDescriptorParser.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/NetworkServiceDescriptorParser.java new file mode 100644 index 0000000000..3012893dc9 --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/NetworkServiceDescriptorParser.java @@ -0,0 +1,209 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Ericsson. All rights reserved. + * ================================================================================ + * 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.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.nsd; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Optional; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; +import org.apache.commons.io.IOUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +@Service +public class NetworkServiceDescriptorParser { + public static final String NS_NODE_TYPE = "tosca.nodes.nfv.NS"; + private static final String NODE_TYPE = "node_type"; + private static final String SUBSTITUTION_MAPPINGS = "substitution_mappings"; + private static final Logger logger = LoggerFactory.getLogger(NetworkServiceDescriptorParser.class); + private static final String VNF_TYPE = "tosca.nodes.nfv.VNF"; + private static final String PROPERTIES = "properties"; + private static final String TYPE = "type"; + private static final String NODE_TEMPLATES = "node_templates"; + private static final String TOPOLOGY_TEMPLATE = "topology_template"; + private static final String ENTRY_DEFINITIONS = "Entry-Definitions"; + private static final String TOSCA_META_PATH_FILE_NAME = "TOSCA-Metadata/TOSCA.meta"; + private final ToscaMetadataParser toscaMetadataParser; + private final FileParser fileParser; + + @Autowired + public NetworkServiceDescriptorParser(final ToscaMetadataParser toscaMetadataParser, final FileParser fileParser) { + this.toscaMetadataParser = toscaMetadataParser; + this.fileParser = fileParser; + } + + public Optional parser(final byte[] zipBytes) { + try { + final Map files = getZipContent(zipBytes); + if (isMetaFilePresent(files)) { + final Optional optional = + toscaMetadataParser.parse(files.get(TOSCA_META_PATH_FILE_NAME)); + if (optional.isPresent()) { + final ToscaMetadata toscaMetadata = optional.get(); + logger.info("Parsed ToscaMetadata {}", toscaMetadata); + final String entryDefinitionFile = toscaMetadata.getEntry(ENTRY_DEFINITIONS); + if (entryDefinitionFile != null && files.containsKey(entryDefinitionFile)) { + final Map fileContent = + fileParser.getFileContent(files.get(entryDefinitionFile)); + final Map topologyTemplates = getTopologyTemplates(fileContent); + final Map nodeTemplates = getNodeTemplates(topologyTemplates); + + final Optional nsdOptional = + getNetworkServiceDescriptor(topologyTemplates);; + if (nsdOptional.isPresent()) { + final NetworkServiceDescriptor networkServiceDescriptor = nsdOptional.get(); + networkServiceDescriptor.setVnfs(getVirtualNetworkFunctions(nodeTemplates)); + return Optional.of(networkServiceDescriptor); + } + + } + } + + } + + } catch (final Exception exception) { + logger.error("Unable to parser nsd zip content", exception); + } + logger.error("Unable to parser nsd zip content"); + return Optional.empty(); + } + + @SuppressWarnings("unchecked") + private Optional getNetworkServiceDescriptor( + final Map topologyTemplates) { + final Map substitutionMappings = + (Map) topologyTemplates.get(SUBSTITUTION_MAPPINGS); + final Object nodeType = substitutionMappings.get(NODE_TYPE); + if (substitutionMappings != null && nodeType != null && NS_NODE_TYPE.equals(nodeType)) { + final NetworkServiceDescriptor networkServiceDescriptor = new NetworkServiceDescriptor(); + networkServiceDescriptor.setType(nodeType.toString()); + networkServiceDescriptor.setProperties((Map) substitutionMappings.get(PROPERTIES)); + return Optional.of(networkServiceDescriptor); + } + logger.error("No {} found in fileContent: {}", SUBSTITUTION_MAPPINGS, topologyTemplates); + + return Optional.empty(); + } + + private List getVirtualNetworkFunctions(final Map nodeTemplates) { + final List vnfs = new ArrayList<>(); + for (final Entry entry : nodeTemplates.entrySet()) { + @SuppressWarnings("unchecked") + final Map entryValue = (Map) entry.getValue(); + final Object type = entryValue.get(TYPE); + if (type != null && type.equals(VNF_TYPE)) { + @SuppressWarnings("unchecked") + final Map vnfProperties = (Map) entryValue.get(PROPERTIES); + final VirtualNetworkFunction vnf = new VirtualNetworkFunction(); + vnf.setVnfName(entry.getKey()); + + if (vnfProperties != null && !vnfProperties.isEmpty()) { + final Object vnfDescriptorId = vnfProperties.get("descriptor_id"); + @SuppressWarnings("unchecked") + final List vnfmInfoList = (List) vnfProperties.get("vnfm_info"); + if (vnfDescriptorId != null && vnfmInfoList != null) { + vnf.setVnfmInfoList(vnfmInfoList); + vnf.setVnfdId(vnfDescriptorId.toString()); + vnf.setProperties(vnfProperties); + vnfs.add(vnf); + } else { + logger.warn("descriptor_id missing {}", entryValue); + } + } + } + + } + return vnfs; + } + + private Map getNodeTemplates(final Map topologyTemplates) { + @SuppressWarnings("unchecked") + final Map nodeTemplates = (Map) topologyTemplates.get(NODE_TEMPLATES); + if (nodeTemplates != null) { + logger.debug("Found nodeTemplates: {}", topologyTemplates); + return nodeTemplates; + } + logger.error("No {} found in fileContent: {}", NODE_TEMPLATES, topologyTemplates); + return Collections.emptyMap(); + } + + private Map getTopologyTemplates(final Map fileContent) { + @SuppressWarnings("unchecked") + final Map topologyTemplates = (Map) fileContent.get(TOPOLOGY_TEMPLATE); + if (topologyTemplates != null) { + logger.debug("Found {}: {}", TOPOLOGY_TEMPLATE, topologyTemplates); + + return topologyTemplates; + } + logger.error("No {} found in fileContent: {}", TOPOLOGY_TEMPLATE, fileContent); + return Collections.emptyMap(); + } + + private boolean isMetaFilePresent(final Map files) { + return files.containsKey(TOSCA_META_PATH_FILE_NAME); + } + + private Map getZipContent(final byte[] zipBytes) { + final Map files = new HashMap<>(); + try (final ZipInputStream inputZipStream = new ZipInputStream(new ByteArrayInputStream(zipBytes));) { + ZipEntry zipEntry; + while ((zipEntry = inputZipStream.getNextEntry()) != null) { + logger.info("{} : {}", zipEntry.getName(), zipEntry.isDirectory()); + if (files.get(zipEntry.getName()) != null) { + logger.warn("{} File entry already exists ...", zipEntry.getName()); + } else { + final FileEntry fileEntry = new FileEntry().filePath(zipEntry.getName()) + .fileContent(getBytes(inputZipStream)).isDirectory(zipEntry.isDirectory()); + files.put(zipEntry.getName(), fileEntry); + + } + + } + return files; + } catch (final Exception exception) { + logger.error("Unable to parser nsd zip content", exception); + return Collections.emptyMap(); + } + } + + private byte[] getBytes(final ZipInputStream inputZipStream) throws IOException { + try { + return IOUtils.toByteArray(inputZipStream); + } catch (final IOException exception) { + logger.error("Could not read bytes from file", exception); + throw exception; + } + } + + +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/ToscaMetadata.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/ToscaMetadata.java new file mode 100644 index 0000000000..bf7648d8c0 --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/ToscaMetadata.java @@ -0,0 +1,75 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Ericsson. All rights reserved. + * ================================================================================ + * 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.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.nsd; + +import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.utils.Utils.toIndentedString; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +public class ToscaMetadata { + + private Map entries = new HashMap<>(); + + public Map getEntries() { + return entries; + } + + public void addEntry(final String name, final String value) { + this.entries.put(name, value); + } + + public boolean hasEntry(final String name) { + return this.entries.containsKey(name); + } + + public String getEntry(final String name) { + return this.entries.get(name); + } + + @Override + public int hashCode() { + return Objects.hash(entries); + } + + @Override + public boolean equals(final Object obj) { + if (obj instanceof ToscaMetadata) { + final ToscaMetadata other = (ToscaMetadata) obj; + return Objects.equals(entries, other.entries); + } + return false; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder(); + sb.append("class ToscaMetadata {\n"); + sb.append(" entries: ").append(toIndentedString(entries)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/ToscaMetadataParser.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/ToscaMetadataParser.java new file mode 100644 index 0000000000..795319c957 --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/ToscaMetadataParser.java @@ -0,0 +1,67 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Ericsson. All rights reserved. + * ================================================================================ + * 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.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.nsd; + +import static org.apache.commons.lang3.StringUtils.isNotBlank; +import java.util.List; +import java.util.Optional; +import org.apache.commons.io.IOUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +@Service +public class ToscaMetadataParser { + private static final String ATTRIBUTE_VALUE_SEPARATOR = ":"; + private static final Logger logger = LoggerFactory.getLogger(ToscaMetadataParser.class); + + public Optional parse(final FileEntry toscaMetaFile) { + try { + final ToscaMetadata toscaMetadata = new ToscaMetadata(); + final List lines = IOUtils.readLines(toscaMetaFile.getFileContentAsStream(), "utf-8"); + for (final String line : lines) { + final String trimmedLine = line.trim(); + if (!trimmedLine.isEmpty() && trimmedLine.contains(ATTRIBUTE_VALUE_SEPARATOR)) { + final String[] entry = trimmedLine.split(ATTRIBUTE_VALUE_SEPARATOR); + if (entry.length >= 2 && isNotBlank(entry[0]) && isNotBlank(entry[1])) { + toscaMetadata.addEntry(entry[0].trim(), entry[1].trim()); + } else { + logger.warn("Unexpected line in metadata file: {}", line); + } + } else { + logger.warn("Unexpected line does not contain valid separator {} in metadata file: {}", + ATTRIBUTE_VALUE_SEPARATOR, line); + } + + } + return Optional.of(toscaMetadata); + + } catch (final Exception exception) { + logger.error("Unable to parser metadata file content", exception); + } + return Optional.empty(); + } + + +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/VirtualNetworkFunction.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/VirtualNetworkFunction.java new file mode 100644 index 0000000000..06ea01c744 --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/VirtualNetworkFunction.java @@ -0,0 +1,123 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Ericsson. All rights reserved. + * ================================================================================ + * 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.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.nsd; + +import static org.onap.so.etsi.nfvo.ns.lcm.database.beans.utils.Utils.toIndentedString; +import java.io.Serializable; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +public class VirtualNetworkFunction implements Serializable { + + private static final long serialVersionUID = 3164293220359211834L; + + private String vnfdId; + private String vnfName; + private List vnfmInfoList; + private Map properties = new HashMap<>(); + + public String getVnfdId() { + return vnfdId; + } + + public void setVnfdId(final String vnfdId) { + this.vnfdId = vnfdId; + } + + public VirtualNetworkFunction vnfdId(final String vnfdId) { + this.vnfdId = vnfdId; + return this; + } + + public String getVnfName() { + return vnfName; + } + + public void setVnfName(final String vnfName) { + this.vnfName = vnfName; + } + + public VirtualNetworkFunction vnfName(final String vnfName) { + this.vnfName = vnfName; + return this; + } + + public List getVnfmInfoList() { + return vnfmInfoList; + } + + public void setVnfmInfoList(final List vnfmInfoList) { + this.vnfmInfoList = vnfmInfoList; + } + + public VirtualNetworkFunction vnfmInfoList(final List vnfmInfoList) { + this.vnfmInfoList = vnfmInfoList; + return this; + } + + public Map getProperties() { + return properties; + } + + public void setProperties(final Map properties) { + this.properties = properties; + } + + public VirtualNetworkFunction properties(final Map properties) { + this.properties = properties; + return this; + } + + @Override + public int hashCode() { + return Objects.hash(vnfdId, vnfName, vnfmInfoList, properties); + } + + @Override + public boolean equals(final Object obj) { + if (obj instanceof VirtualNetworkFunction) { + final VirtualNetworkFunction other = (VirtualNetworkFunction) obj; + return Objects.equals(vnfdId, other.vnfdId) && Objects.equals(vnfName, other.vnfName) + && Objects.equals(vnfmInfoList, other.vnfmInfoList) && Objects.equals(properties, other.properties); + } + return false; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder(); + sb.append("class VirtualNetworkFunction {\n"); + sb.append(" vnfdId: ").append(toIndentedString(vnfdId)).append("\n"); + sb.append(" vnfName: ").append(toIndentedString(vnfName)).append("\n"); + sb.append(" vnfmInfo: ").append(toIndentedString(vnfmInfoList)).append("\n"); + sb.append(" properties: ").append(toIndentedString(properties)).append("\n"); + + sb.append("}"); + return sb.toString(); + } + + +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/YamlFileParser.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/YamlFileParser.java new file mode 100644 index 0000000000..ac8f782a99 --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/main/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/YamlFileParser.java @@ -0,0 +1,39 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 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.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.nsd; + +import java.util.Map; +import org.springframework.stereotype.Service; +import org.yaml.snakeyaml.Yaml; + +/** + * @author Waqas Ikram (waqas.ikram@est.tech) + * + */ +@Service +public class YamlFileParser implements FileParser { + + @Override + public Map getFileContent(final FileEntry entryDefinitionFileEntry) { + final Yaml yaml = new Yaml(); + return yaml.load(entryDefinitionFileEntry.getFileContentAsStream()); + } + +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/NetworkServiceDescriptorParserTest.java b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/NetworkServiceDescriptorParserTest.java new file mode 100644 index 0000000000..29a70ecca8 --- /dev/null +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/java/org/onap/so/etsi/nfvo/ns/lcm/bpmn/flows/nsd/NetworkServiceDescriptorParserTest.java @@ -0,0 +1,64 @@ +package org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.nsd; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.Map; +import java.util.Optional; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.onap.so.etsi.nfvo.ns.lcm.bpmn.flows.TestApplication; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit4.SpringRunner; + + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = TestApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@ActiveProfiles("test") +public class NetworkServiceDescriptorParserTest { + + private static final String VALID_ETSI_NSD_FILE = "src/test/resources/ns.csar"; + private static final String INVALID_ETSI_NSD_FILE = "src/test/resources/invalid_ns.csar"; + + @Autowired + private NetworkServiceDescriptorParser objUnderTest; + + @Test + public void testValidEtsiNsd_ableToParserIt() throws IOException { + final byte[] zipBytes = Files.readAllBytes(Paths.get(getAbsolutePath(VALID_ETSI_NSD_FILE))); + final Optional optional = objUnderTest.parser(zipBytes); + assertTrue(optional.isPresent()); + final NetworkServiceDescriptor actualNsd = optional.get(); + assertEquals(NetworkServiceDescriptorParser.NS_NODE_TYPE, actualNsd.getType()); + assertFalse(actualNsd.getProperties().isEmpty()); + + final Map actualNsdProperties = actualNsd.getProperties(); + assertEquals(5, actualNsdProperties.size()); + assertEquals("ffdddc5d-a44b-45ae-8fc3-e6551cce350f", actualNsdProperties.get("descriptor_id")); + assertEquals(5, actualNsd.getVnfs().size()); + + } + + @Test + public void testEmptyEtsiNsd_ableToParserIt() throws IOException { + assertFalse(objUnderTest.parser(new byte[] {}).isPresent()); + } + + @Test + public void testInvalidEtsiNsd_ableToParserIt() throws IOException { + final byte[] zipBytes = Files.readAllBytes(Paths.get(getAbsolutePath(INVALID_ETSI_NSD_FILE))); + assertFalse(objUnderTest.parser(zipBytes).isPresent()); + } + + private String getAbsolutePath(final String path) { + final File file = new File(path); + return file.getAbsolutePath(); + } + +} diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/resources/application.yaml b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/resources/application.yaml index 3faa62c51d..5c4f27c8ab 100644 --- a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/resources/application.yaml +++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/resources/application.yaml @@ -22,7 +22,7 @@ spring: pool-name: ns-lcm-bpmn-pool registerMbeans: true nfvo: - jdbcUrl: jdbc:h2:mem:nfvo;DB_CLOSE_DELAY=-1;INIT=CREATE SCHEMA IF NOT EXISTS nfvo; + jdbcUrl: jdbc:h2:mem:nfvo;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE;INIT=CREATE SCHEMA IF NOT EXISTS nfvo; driver-class-name: org.h2.Driver pool-name: ns-lcm-bpmn-pool registerMbeans: true diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/resources/invalid_ns.csar b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/resources/invalid_ns.csar new file mode 100644 index 0000000000..63bad965b7 Binary files /dev/null and b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/resources/invalid_ns.csar differ diff --git a/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/resources/ns.csar b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/resources/ns.csar new file mode 100644 index 0000000000..eb19c762ae Binary files /dev/null and b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/resources/ns.csar differ -- cgit 1.2.3-korg