summaryrefslogtreecommitdiffstats
path: root/so-etsi-nfvo
diff options
context:
space:
mode:
authorwaqas.ikram <waqas.ikram@est.tech>2020-09-07 08:48:46 +0100
committerwaqas.ikram <waqas.ikram@est.tech>2020-09-07 10:08:42 +0100
commit7d62e922e727300c6949be7c631081e735a4bc08 (patch)
treec3a5c2be4bfb8ed66e15293de04ec6495869fa6c /so-etsi-nfvo
parent2e715d8ceea7cb9f6e11af16bb21d37895ba8c9b (diff)
Adding Basic NSD parser
Change-Id: I9b34054aac1649f71e0dece2a3a17e958d74d5be Issue-ID: SO-3219 Signed-off-by: waqas.ikram <waqas.ikram@est.tech>
Diffstat (limited to 'so-etsi-nfvo')
-rw-r--r--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.java111
-rw-r--r--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.java32
-rw-r--r--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.java121
-rw-r--r--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.java209
-rw-r--r--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.java75
-rw-r--r--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.java67
-rw-r--r--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.java123
-rw-r--r--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.java39
-rw-r--r--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.java64
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/resources/application.yaml2
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/resources/invalid_ns.csarbin0 -> 778 bytes
-rw-r--r--so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/resources/ns.csarbin0 -> 2952 bytes
12 files changed, 842 insertions, 1 deletions
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<String, Object> 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<String, Object> properties = new HashMap<>();
+
+ private List<VirtualNetworkFunction> 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<String, Object> getProperties() {
+ return properties;
+ }
+
+ public void setProperties(final Map<String, Object> properties) {
+ this.properties = properties;
+ }
+
+ public NetworkServiceDescriptor properties(final Map<String, Object> properties) {
+ this.properties = properties;
+ return this;
+ }
+
+ public List<VirtualNetworkFunction> getVnfs() {
+ return vnfs;
+ }
+
+ public void setVnfs(final List<VirtualNetworkFunction> 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<VirtualNetworkFunction> 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<NetworkServiceDescriptor> parser(final byte[] zipBytes) {
+ try {
+ final Map<String, FileEntry> files = getZipContent(zipBytes);
+ if (isMetaFilePresent(files)) {
+ final Optional<ToscaMetadata> 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<String, Object> fileContent =
+ fileParser.getFileContent(files.get(entryDefinitionFile));
+ final Map<String, Object> topologyTemplates = getTopologyTemplates(fileContent);
+ final Map<String, Object> nodeTemplates = getNodeTemplates(topologyTemplates);
+
+ final Optional<NetworkServiceDescriptor> 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<NetworkServiceDescriptor> getNetworkServiceDescriptor(
+ final Map<String, Object> topologyTemplates) {
+ final Map<String, Object> substitutionMappings =
+ (Map<String, Object>) 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<String, Object>) substitutionMappings.get(PROPERTIES));
+ return Optional.of(networkServiceDescriptor);
+ }
+ logger.error("No {} found in fileContent: {}", SUBSTITUTION_MAPPINGS, topologyTemplates);
+
+ return Optional.empty();
+ }
+
+ private List<VirtualNetworkFunction> getVirtualNetworkFunctions(final Map<String, Object> nodeTemplates) {
+ final List<VirtualNetworkFunction> vnfs = new ArrayList<>();
+ for (final Entry<String, Object> entry : nodeTemplates.entrySet()) {
+ @SuppressWarnings("unchecked")
+ final Map<String, Object> entryValue = (Map<String, Object>) entry.getValue();
+ final Object type = entryValue.get(TYPE);
+ if (type != null && type.equals(VNF_TYPE)) {
+ @SuppressWarnings("unchecked")
+ final Map<String, Object> vnfProperties = (Map<String, Object>) 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<String> vnfmInfoList = (List<String>) 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<String, Object> getNodeTemplates(final Map<String, Object> topologyTemplates) {
+ @SuppressWarnings("unchecked")
+ final Map<String, Object> nodeTemplates = (Map<String, Object>) 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<String, Object> getTopologyTemplates(final Map<String, Object> fileContent) {
+ @SuppressWarnings("unchecked")
+ final Map<String, Object> topologyTemplates = (Map<String, Object>) 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<String, FileEntry> files) {
+ return files.containsKey(TOSCA_META_PATH_FILE_NAME);
+ }
+
+ private Map<String, FileEntry> getZipContent(final byte[] zipBytes) {
+ final Map<String, FileEntry> 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<String, String> entries = new HashMap<>();
+
+ public Map<String, String> 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<ToscaMetadata> parse(final FileEntry toscaMetaFile) {
+ try {
+ final ToscaMetadata toscaMetadata = new ToscaMetadata();
+ final List<String> 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<String> vnfmInfoList;
+ private Map<String, Object> 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<String> getVnfmInfoList() {
+ return vnfmInfoList;
+ }
+
+ public void setVnfmInfoList(final List<String> vnfmInfoList) {
+ this.vnfmInfoList = vnfmInfoList;
+ }
+
+ public VirtualNetworkFunction vnfmInfoList(final List<String> vnfmInfoList) {
+ this.vnfmInfoList = vnfmInfoList;
+ return this;
+ }
+
+ public Map<String, Object> getProperties() {
+ return properties;
+ }
+
+ public void setProperties(final Map<String, Object> properties) {
+ this.properties = properties;
+ }
+
+ public VirtualNetworkFunction properties(final Map<String, Object> 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<String, Object> 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<NetworkServiceDescriptor> 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<String, Object> 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
--- /dev/null
+++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/resources/invalid_ns.csar
Binary files 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
--- /dev/null
+++ b/so-etsi-nfvo/so-etsi-nfvo-ns-lcm/so-etsi-nfvo-ns-lcm-bpmn-flows/src/test/resources/ns.csar
Binary files differ