Add helm artifacts in the CSAR package 12/12512/1
authoraravind.est <aravindhan.a@est.tech>
Wed, 7 Feb 2024 16:45:22 +0000 (16:45 +0000)
committeraravind.est <aravindhan.a@est.tech>
Wed, 7 Feb 2024 16:48:56 +0000 (16:48 +0000)
Helm artifacts added in CSAR package.
Validation added for the HELM artifacts when creating rApp with package.
Create rApp API added with specific error messages.

Issue-ID: NONRTRIC-975
Change-Id: I9ed99e460d440015f43057354faa8352695b31fa
Signed-off-by: aravind.est <aravindhan.a@est.tech>
15 files changed:
rapp-manager-application/src/test/resources/valid-rapp-package.csar
rapp-manager-dme/src/test/java/com/oransc/rappmanager/dme/service/DmeAcmInterceptorTest.java
rapp-manager-models/src/main/java/com/oransc/rappmanager/models/csar/RappCsarConfigurationHandler.java
rapp-manager-models/src/test/java/com/oransc/rappmanager/models/RappServiceEnablerTest.java
rapp-manager-models/src/test/java/com/oransc/rappmanager/models/csar/RappCsarConfigurationHandlerTest.java
rapp-manager-models/src/test/resources/invalid-rapp-package-missing-artifact.csar [new file with mode: 0755]
rapp-manager-models/src/test/resources/invalid-rapp-package-no-acm-composition.csar [new file with mode: 0755]
rapp-manager-models/src/test/resources/invalid-rapp-package-no-asd-yaml.csar [new file with mode: 0755]
rapp-manager-models/src/test/resources/invalid-rapp-package-no-tosca.csar [new file with mode: 0755]
rapp-manager-models/src/test/resources/valid-rapp-package.csar
sample-rapp-generator/rapp-all/Artifacts/Deployment/HELM/orufhrecovery-1.0.0.tgz [new file with mode: 0755]
sample-rapp-generator/rapp-all/Artifacts/Deployment/HELM/ransliceassurance-1.0.0.tgz [new file with mode: 0755]
sample-rapp-generator/rapp-all/Definitions/asd.yaml
sample-rapp-generator/rapp-all/Definitions/asd_types.yaml
sample-rapp-generator/rapp-all/asd.mf

index 2bbc2ef..ffe2f4b 100755 (executable)
Binary files a/rapp-manager-application/src/test/resources/valid-rapp-package.csar and b/rapp-manager-application/src/test/resources/valid-rapp-package.csar differ
index b5c9c64..fb51f29 100755 (executable)
@@ -1,6 +1,6 @@
 /*-
  * ============LICENSE_START======================================================================
- * Copyright (C) 2023 OpenInfra Foundation Europe. All rights reserved.
+ * Copyright (C) 2023-2024 OpenInfra Foundation Europe. 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.
@@ -20,6 +20,7 @@ package com.oransc.rappmanager.dme.service;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
 
+import com.fasterxml.jackson.databind.ObjectMapper;
 import com.google.gson.JsonArray;
 import com.google.gson.JsonParser;
 import com.oransc.rappmanager.models.csar.RappCsarConfigurationHandler;
@@ -47,7 +48,7 @@ import org.onap.policy.models.tosca.authorative.concepts.ToscaTopologyTemplate;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.context.SpringBootTest;
 
-@SpringBootTest(classes = {RappCsarConfigurationHandler.class, DmeAcmInterceptor.class})
+@SpringBootTest(classes = {ObjectMapper.class, RappCsarConfigurationHandler.class, DmeAcmInterceptor.class})
 class DmeAcmInterceptorTest {
 
     @Autowired
index be6fe88..1def6e5 100755 (executable)
@@ -1,6 +1,7 @@
 /*-
  * ============LICENSE_START======================================================================
  * Copyright (C) 2023 Nordix Foundation. All rights reserved.
+ * Copyright (C) 2024 OpenInfra Foundation Europe. 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.
 
 package com.oransc.rappmanager.models.csar;
 
+import static com.google.common.base.Splitter.on;
+import static com.google.common.collect.Iterables.filter;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.gson.Gson;
+import com.oransc.rappmanager.models.exception.RappHandlerException;
 import com.oransc.rappmanager.models.rapp.Rapp;
 import com.oransc.rappmanager.models.rapp.RappResources;
 import com.oransc.rappmanager.models.rappinstance.RappACMInstance;
@@ -27,23 +35,32 @@ import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.nio.file.Path;
+import java.util.List;
 import java.util.Set;
 import java.util.UUID;
 import java.util.function.Predicate;
 import java.util.stream.Collectors;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipFile;
+import lombok.RequiredArgsConstructor;
 import org.apache.commons.compress.archivers.ArchiveEntry;
 import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.springframework.http.HttpStatus;
 import org.springframework.stereotype.Service;
 import org.springframework.web.multipart.MultipartFile;
+import org.yaml.snakeyaml.Yaml;
 
 @Service
+@RequiredArgsConstructor
 public class RappCsarConfigurationHandler {
 
     Logger logger = LoggerFactory.getLogger(RappCsarConfigurationHandler.class);
+
+    private final ObjectMapper objectMapper;
+    private static final String TOSCA_METADATA_LOCATION = "TOSCA-Metadata/TOSCA.meta";
+    private static final String ENTRY_DEFINITIONS_INDEX = "Entry-Definitions";
     private static final String ACM_COMPOSITION_JSON_LOCATION = "Files/Acm/definition/compositions.json";
     private static final String ACM_DEFINITION_LOCATION = "Files/Acm/definition";
     private static final String ACM_INSTANCES_LOCATION = "Files/Acm/instances";
@@ -60,7 +77,8 @@ public class RappCsarConfigurationHandler {
         String originalFilename = multipartFile.getOriginalFilename();
         if (originalFilename != null) {
             return originalFilename.endsWith(".csar") && isFileExistsInCsar(multipartFile,
-                    ACM_COMPOSITION_JSON_LOCATION);
+                    ACM_COMPOSITION_JSON_LOCATION) && isFileExistsInCsar(multipartFile, TOSCA_METADATA_LOCATION)
+                           && containsValidArtifactDefinition(multipartFile);
         }
         return false;
     }
@@ -73,10 +91,10 @@ public class RappCsarConfigurationHandler {
                     return Boolean.TRUE;
                 }
             }
-            return Boolean.FALSE;
+            throw new RappHandlerException(HttpStatus.BAD_REQUEST, "rApp package missing a file " + fileLocation);
         } catch (IOException e) {
             logger.error("Unable to find the CSAR file", e);
-            return Boolean.FALSE;
+            throw new RappHandlerException(HttpStatus.BAD_REQUEST, "rApp package missing a file " + fileLocation);
         }
     }
 
@@ -100,10 +118,30 @@ public class RappCsarConfigurationHandler {
                 getRappPackageLocation(rapp.getPackageLocation(), rapp.getName(), rapp.getPackageName()).toUri());
     }
 
+    ByteArrayOutputStream getFileFromCsar(MultipartFile multipartFile, String fileLocation) {
+        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+        try (ZipArchiveInputStream zipArchiveInputStream = new ZipArchiveInputStream(multipartFile.getInputStream())) {
+            byteArrayOutputStream = getFileFromCsar(zipArchiveInputStream, fileLocation);
+        } catch (IOException e) {
+            logger.info("Unable to get file {} from the multipart CSAR file", fileLocation, e);
+        }
+        return byteArrayOutputStream;
+    }
+
     ByteArrayOutputStream getFileFromCsar(File csarFile, String fileLocation) {
         ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
         try (FileInputStream fileInputStream = new FileInputStream(csarFile);
              ZipArchiveInputStream zipArchiveInputStream = new ZipArchiveInputStream(fileInputStream)) {
+            byteArrayOutputStream = getFileFromCsar(zipArchiveInputStream, fileLocation);
+        } catch (IOException e) {
+            logger.info("Unable to get file {} from the CSAR file", fileLocation, e);
+        }
+        return byteArrayOutputStream;
+    }
+
+    ByteArrayOutputStream getFileFromCsar(ZipArchiveInputStream zipArchiveInputStream, String fileLocation) {
+        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+        try {
             ArchiveEntry entry;
             while ((entry = zipArchiveInputStream.getNextEntry()) != null) {
                 if (!entry.isDirectory() && entry.getName().equals(fileLocation)) {
@@ -115,11 +153,48 @@ public class RappCsarConfigurationHandler {
                 }
             }
         } catch (IOException e) {
-            logger.error("Unable to find the CSAR file", e);
+            logger.info("Unable to get file {} from the zip archive CSAR file", fileLocation, e);
         }
         return byteArrayOutputStream;
     }
 
+    boolean containsValidArtifactDefinition(MultipartFile multipartFile) {
+        String asdLocation = getAsdDefinitionLocation(multipartFile);
+        if (asdLocation != null && !asdLocation.isEmpty() && isFileExistsInCsar(multipartFile, asdLocation)) {
+            try {
+                String asdContent = getFileFromCsar(multipartFile, asdLocation).toString();
+                String asdJsonContent = new Gson().toJsonTree(new Yaml().load(asdContent)).toString();
+                JsonNode jsonNode = objectMapper.readTree(asdJsonContent);
+                List<String> artifactFileList =
+                        jsonNode.at("/topology_template/node_templates/applicationServiceDescriptor/artifacts")
+                                .findValuesAsText("file");
+                return artifactFileList.stream()
+                               .allMatch(artifactFile -> isFileExistsInCsar(multipartFile, artifactFile));
+            } catch (RappHandlerException e) {
+                throw e;
+            } catch (Exception e) {
+                logger.warn("Unable to validate artifact definition", e);
+                throw new RappHandlerException(HttpStatus.BAD_REQUEST, "ASD definition in rApp package is invalid.");
+            }
+        }
+        throw new RappHandlerException(HttpStatus.BAD_REQUEST, "ASD definition in rApp package is invalid.");
+    }
+
+    String getAsdDefinitionLocation(final MultipartFile multipartFile) {
+        String asdLocation = "";
+        final ByteArrayOutputStream fileContent = getFileFromCsar(multipartFile, TOSCA_METADATA_LOCATION);
+        if (fileContent != null) {
+            final String toscaMetadata = fileContent.toString();
+            if (!toscaMetadata.isEmpty()) {
+                final String entry =
+                        filter(on("\n").split(toscaMetadata), line -> line.contains(ENTRY_DEFINITIONS_INDEX)).iterator()
+                                .next();
+                asdLocation = entry.replace(ENTRY_DEFINITIONS_INDEX + ":", "").trim();
+            }
+        }
+        return asdLocation;
+    }
+
 
     public String getSmeProviderDomainPayload(Rapp rapp, RappSMEInstance rappSMEInstance) {
         return getPayload(rapp, getResourceUri(SME_PROVIDER_FUNCS_LOCATION, rappSMEInstance.getProviderFunction()));
index 4c51287..69ddc9b 100755 (executable)
@@ -21,6 +21,7 @@ package com.oransc.rappmanager.models;
 import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
+import com.fasterxml.jackson.databind.ObjectMapper;
 import com.oransc.rappmanager.models.csar.RappCsarConfigurationHandler;
 import com.oransc.rappmanager.models.rapp.Rapp;
 import com.oransc.rappmanager.models.rapp.RappResources;
@@ -35,7 +36,7 @@ import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.test.context.ContextConfiguration;
 
 @SpringBootTest
-@ContextConfiguration(classes = RappCsarConfigurationHandler.class)
+@ContextConfiguration(classes = {ObjectMapper.class, RappCsarConfigurationHandler.class})
 class RappServiceEnablerTest {
 
     @Autowired
index 8c416ee..81468ee 100755 (executable)
@@ -1,6 +1,7 @@
 /*-
  * ============LICENSE_START======================================================================
  * Copyright (C) 2023 Nordix Foundation. All rights reserved.
+ * Copyright (C) 2024 OpenInfra Foundation Europe. 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.
@@ -22,8 +23,15 @@ import static org.assertj.core.api.Assertions.assertThat;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doCallRealMethod;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
 
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.oransc.rappmanager.models.exception.RappHandlerException;
 import com.oransc.rappmanager.models.rapp.Rapp;
 import com.oransc.rappmanager.models.rapp.RappResources;
 import com.oransc.rappmanager.models.rappinstance.RappACMInstance;
@@ -35,21 +43,26 @@ import java.io.FileInputStream;
 import java.io.IOException;
 import java.util.Set;
 import java.util.UUID;
+import java.util.stream.Stream;
 import org.apache.http.entity.ContentType;
 import org.json.JSONException;
 import org.json.JSONObject;
 import org.junit.jupiter.api.Test;
-import org.springframework.beans.factory.annotation.Autowired;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
 import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.mock.mockito.SpyBean;
+import org.springframework.http.HttpStatus;
 import org.springframework.mock.web.MockMultipartFile;
 import org.springframework.test.context.ContextConfiguration;
 import org.springframework.web.multipart.MultipartFile;
 
 @SpringBootTest
-@ContextConfiguration(classes = RappCsarConfigurationHandler.class)
+@ContextConfiguration(classes = {ObjectMapper.class, RappCsarConfigurationHandler.class})
 class RappCsarConfigurationHandlerTest {
 
-    @Autowired
+    @SpyBean
     RappCsarConfigurationHandler rappCsarConfigurationHandler;
 
     String validCsarFileLocation = "src/test/resources/";
@@ -68,17 +81,46 @@ class RappCsarConfigurationHandlerTest {
         assertEquals(Boolean.TRUE, rappCsarConfigurationHandler.isValidRappPackage(multipartFile));
     }
 
-    @Test
-    void testCsarPackageValidationFailure() throws IOException {
-        String rappCsarPath = validCsarFileLocation + File.separator + invalidRappFile;
+    @ParameterizedTest
+    @MethodSource("getInvalidCsarPackage")
+    void testCsarPackageValidationFailure(MultipartFile multipartFile) {
+        System.out.println(multipartFile.getOriginalFilename());
+        RappHandlerException exception = assertThrows(RappHandlerException.class,
+                () -> rappCsarConfigurationHandler.isValidRappPackage(multipartFile));
+        assertEquals(HttpStatus.BAD_REQUEST, exception.getStatusCode());
+    }
+
+
+    private static Stream<Arguments> getInvalidCsarPackage() throws IOException {
+        String validCsarFileLocation = "src/test/resources";
+        String rappCsarPath = validCsarFileLocation + File.separator + "invalid-rapp-package.csar";
         MultipartFile multipartFile =
                 new MockMultipartFile(rappCsarPath, rappCsarPath, ContentType.MULTIPART_FORM_DATA.getMimeType(),
                         new FileInputStream(rappCsarPath));
-        assertEquals(Boolean.FALSE, rappCsarConfigurationHandler.isValidRappPackage(multipartFile));
+        String rappCsarPathNoTosca = validCsarFileLocation + File.separator + "invalid-rapp-package-no-tosca.csar";
+        MultipartFile multipartFileNoTosca = new MockMultipartFile(rappCsarPathNoTosca, rappCsarPathNoTosca,
+                ContentType.MULTIPART_FORM_DATA.getMimeType(), new FileInputStream(rappCsarPathNoTosca));
+        String rappCsarPathNoAsdYaml = validCsarFileLocation + File.separator + "invalid-rapp-package-no-asd-yaml.csar";
+        MultipartFile multipartFileNoAsdYaml = new MockMultipartFile(rappCsarPathNoAsdYaml, rappCsarPathNoAsdYaml,
+                ContentType.MULTIPART_FORM_DATA.getMimeType(), new FileInputStream(rappCsarPathNoAsdYaml));
+        String rappCsarPathMissingArtifact =
+                validCsarFileLocation + File.separator + "invalid-rapp-package-missing-artifact.csar";
+        MultipartFile multipartFileMissingArtifact =
+                new MockMultipartFile(rappCsarPathMissingArtifact, rappCsarPathMissingArtifact,
+                        ContentType.MULTIPART_FORM_DATA.getMimeType(),
+                        new FileInputStream(rappCsarPathMissingArtifact));
+        String rappCsarPathNoComposition =
+                validCsarFileLocation + File.separator + "invalid-rapp-package-no-acm-composition.csar";
+        MultipartFile multipartFileNoComposition =
+                new MockMultipartFile(rappCsarPathNoComposition, rappCsarPathNoComposition,
+                        ContentType.MULTIPART_FORM_DATA.getMimeType(), new FileInputStream(rappCsarPathNoComposition));
+        return Stream.of(Arguments.of(multipartFile), Arguments.of(multipartFileNoTosca),
+                Arguments.of(multipartFileNoAsdYaml), Arguments.of(multipartFileMissingArtifact),
+                Arguments.of(multipartFileNoComposition));
     }
 
     @Test
-    void testCsarPackageValidationFailureWithoutOrginalName() throws IOException {
+    void testCsarPackageValidationFailureWithoutOrginalName() {
         MultipartFile multipartFile = mock(MultipartFile.class);
         assertEquals(Boolean.FALSE, rappCsarConfigurationHandler.isValidRappPackage(multipartFile));
     }
@@ -86,7 +128,60 @@ class RappCsarConfigurationHandlerTest {
     @Test
     void testInvalidCsarFileExist() {
         MultipartFile multipartFile = mock(MultipartFile.class);
-        assertEquals(Boolean.FALSE, rappCsarConfigurationHandler.isFileExistsInCsar(multipartFile, "INVALID_LOCATION"));
+        RappHandlerException exception = assertThrows(RappHandlerException.class,
+                () -> rappCsarConfigurationHandler.isFileExistsInCsar(multipartFile, "INVALID_LOCATION"));
+        assertEquals(HttpStatus.BAD_REQUEST, exception.getStatusCode());
+    }
+
+    @Test
+    void testCsarContainsValidAsdFile() throws IOException {
+        String rappCsarPath = validCsarFileLocation + File.separator + validRappFile;
+        MultipartFile multipartFile =
+                new MockMultipartFile(rappCsarPath, rappCsarPath, ContentType.MULTIPART_FORM_DATA.getMimeType(),
+                        new FileInputStream(rappCsarPath));
+        assertTrue(rappCsarConfigurationHandler.containsValidArtifactDefinition(multipartFile));
+    }
+
+    @Test
+    void testCsarContainsValidAsdFileFailure() throws IOException {
+        String rappCsarPath = validCsarFileLocation + File.separator + invalidRappFile;
+        MultipartFile multipartFile =
+                new MockMultipartFile(rappCsarPath, rappCsarPath, ContentType.MULTIPART_FORM_DATA.getMimeType(),
+                        new FileInputStream(rappCsarPath));
+        RappHandlerException exception = assertThrows(RappHandlerException.class,
+                () -> rappCsarConfigurationHandler.containsValidArtifactDefinition(multipartFile));
+        assertEquals(HttpStatus.BAD_REQUEST, exception.getStatusCode());
+    }
+
+    @Test
+    void testCsarNoAsdFailure() {
+        MultipartFile multipartFile = mock(MultipartFile.class);
+        RappHandlerException exception = assertThrows(RappHandlerException.class,
+                () -> rappCsarConfigurationHandler.containsValidArtifactDefinition(multipartFile));
+        assertEquals(HttpStatus.BAD_REQUEST, exception.getStatusCode());
+    }
+
+    @Test
+    void testCsarAsdContentInvalidFailure() throws IOException {
+        String rappCsarPath = validCsarFileLocation + File.separator + validRappFile;
+        MultipartFile multipartFile =
+                new MockMultipartFile(rappCsarPath, rappCsarPath, ContentType.MULTIPART_FORM_DATA.getMimeType(),
+                        new FileInputStream(rappCsarPath));
+        String invalidJson = "{asasdasd";
+        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+        byteArrayOutputStream.write(invalidJson.getBytes(), 0, invalidJson.getBytes().length);
+        doCallRealMethod().doReturn(byteArrayOutputStream).when(rappCsarConfigurationHandler)
+                .getFileFromCsar(any(MultipartFile.class), any());
+        RappHandlerException exception = assertThrows(RappHandlerException.class,
+                () -> rappCsarConfigurationHandler.containsValidArtifactDefinition(multipartFile));
+        assertEquals(HttpStatus.BAD_REQUEST, exception.getStatusCode());
+    }
+
+    @Test
+    void testgetFileFromCsarFailure() throws IOException {
+        MultipartFile multipartFile = mock(MultipartFile.class);
+        when(multipartFile.getInputStream()).thenThrow(new IOException());
+        assertThat(rappCsarConfigurationHandler.getFileFromCsar(multipartFile, null).size()).isZero();
     }
 
     @Test
@@ -143,7 +238,7 @@ class RappCsarConfigurationHandlerTest {
     @Test
     void testListInvalidResources() {
         UUID rappId = UUID.randomUUID();
-        Rapp rapp = Rapp.builder().rappId(rappId).name("").build();
+        Rapp rapp = Rapp.builder().rappId(rappId).name("").packageName("").packageLocation("").build();
         RappResources rappResources = rappCsarConfigurationHandler.getRappResource(rapp);
         assertThat(rappResources).isNotNull();
         assertNull(rappResources.getAcm());
diff --git a/rapp-manager-models/src/test/resources/invalid-rapp-package-missing-artifact.csar b/rapp-manager-models/src/test/resources/invalid-rapp-package-missing-artifact.csar
new file mode 100755 (executable)
index 0000000..d56f4ef
Binary files /dev/null and b/rapp-manager-models/src/test/resources/invalid-rapp-package-missing-artifact.csar differ
diff --git a/rapp-manager-models/src/test/resources/invalid-rapp-package-no-acm-composition.csar b/rapp-manager-models/src/test/resources/invalid-rapp-package-no-acm-composition.csar
new file mode 100755 (executable)
index 0000000..d986fb4
Binary files /dev/null and b/rapp-manager-models/src/test/resources/invalid-rapp-package-no-acm-composition.csar differ
diff --git a/rapp-manager-models/src/test/resources/invalid-rapp-package-no-asd-yaml.csar b/rapp-manager-models/src/test/resources/invalid-rapp-package-no-asd-yaml.csar
new file mode 100755 (executable)
index 0000000..a2168ff
Binary files /dev/null and b/rapp-manager-models/src/test/resources/invalid-rapp-package-no-asd-yaml.csar differ
diff --git a/rapp-manager-models/src/test/resources/invalid-rapp-package-no-tosca.csar b/rapp-manager-models/src/test/resources/invalid-rapp-package-no-tosca.csar
new file mode 100755 (executable)
index 0000000..7ba7c33
Binary files /dev/null and b/rapp-manager-models/src/test/resources/invalid-rapp-package-no-tosca.csar differ
index 1b96b0b..ffe2f4b 100755 (executable)
Binary files a/rapp-manager-models/src/test/resources/valid-rapp-package.csar and b/rapp-manager-models/src/test/resources/valid-rapp-package.csar differ
diff --git a/sample-rapp-generator/rapp-all/Artifacts/Deployment/HELM/orufhrecovery-1.0.0.tgz b/sample-rapp-generator/rapp-all/Artifacts/Deployment/HELM/orufhrecovery-1.0.0.tgz
new file mode 100755 (executable)
index 0000000..4dc0b27
Binary files /dev/null and b/sample-rapp-generator/rapp-all/Artifacts/Deployment/HELM/orufhrecovery-1.0.0.tgz differ
diff --git a/sample-rapp-generator/rapp-all/Artifacts/Deployment/HELM/ransliceassurance-1.0.0.tgz b/sample-rapp-generator/rapp-all/Artifacts/Deployment/HELM/ransliceassurance-1.0.0.tgz
new file mode 100755 (executable)
index 0000000..348e1a6
Binary files /dev/null and b/sample-rapp-generator/rapp-all/Artifacts/Deployment/HELM/ransliceassurance-1.0.0.tgz differ
index 39ce4ed..e369010 100755 (executable)
@@ -1,6 +1,6 @@
 tosca_definitions_version: tosca_simple_yaml_1_2\r
 \r
-description: First drop of free5gc and ueransim ASD\r
+description: rApp all\r
 \r
 imports:\r
   - asd_types.yaml\r
@@ -9,104 +9,26 @@ topology_template:
   node_templates:\r
    applicationServiceDescriptor:\r
       type: tosca.nodes.asd\r
-      description: "Free5gc"\r
+      description: "rapp-all"\r
       properties:\r
         descriptor_id: 123e4567-e89b-12d3-a456-426614174000\r
         descriptor_invariant_id: 123e4yyy-e89b-12d3-a456-426614174abc\r
         descriptor_version: 1.0\r
         schema_version: 2.0\r
-        function_description: free5gc description\r
+        function_description: rApp description\r
         provider: EST\r
-        application_name: free5gc-app\r
-        application_version: 2.3\r
-        ext_cpds:\r
-          - id: 1\r
-            description: webpage-service\r
-            virtual_link_requirement: endUser\r
-            network_interface_realization_requirements:\r
-              trunk_mode: false\r
-              ipam: orchestrated\r
-              interface_type: direct.userdriver\r
-              interface_option:\r
-                - virtio\r
-                - memif\r
-              interface_redundancy: actPassBond\r
-              nic_options:\r
-                - nic id1\r
-                - nic id2\r
-            input_param_mappings:\r
-              loadbalancer_IP: 1.2.3.4\r
-              external_IPs:\r
-                - 5.6.7.8\r
-                - 10.11.12.13\r
-              nad_names:\r
-                - nad name 1\r
-                - nad name 2\r
-              nad_namespace: myNamespace\r
-            resource_mapping: my resource manifest\r
-          - id: 2\r
-            description: transactionAPI\r
-            virtual_link_requirement: backhaul\r
-            network_interface_realization_requirements:\r
-              trunk_mode: true\r
-              ipam: orchestrated\r
-              interface_type: direct.userdriver\r
-              interface_option:\r
-                - virtio\r
-              interface_redundancy: actPassBond\r
-              nic_options:\r
-                - nic id3\r
-                - nic id4\r
-            input_param_mappings:\r
-              loadbalancer_IP: 192.168.1.0\r
-              external_IPs:\r
-                - 192.168.1.1\r
-                - 192.168.1.2\r
-              nad_names:\r
-                - nad name 3\r
-                - nad name 4\r
-              nad_namespace: myNamespace2\r
-            resource_mapping: my resource manifest\r
-        enhanced_cluster_capabilities:\r
-          min_kernel_version: 1.2.3\r
-          required_kernel_modules:\r
-            - ip6_tables\r
-            - cryptd\r
-          conflicting_kernel_modules:\r
-            - nf_nat\r
-          required_custom_resources:\r
-            - kind: myKind\r
-              api_version: myVersion\r
-            - kind: mySecondKind\r
-              api_version: mySecondVersion\r
-          cluster_labels:\r
-            - label 1\r
-            - label 2\r
-          required_plugin:\r
-            - name: plugin1Name\r
-              version: 1.2.3\r
-            - name: plugin2Name\r
-              version: 4.5.6\r
+        application_name: rapp-all\r
+        application_version: 1.0\r
       artifacts:\r
-        free5gc:\r
+        ransliceassurance:\r
           type: tosca.artifacts.asd.deploymentItem\r
-          file: "Artifacts/Deployment/HELM/free5gc-1.1.3.tgz"\r
+          file: "Artifacts/Deployment/HELM/ransliceassurance-1.0.0.tgz"\r
           properties:\r
             artifact_type: "helm_chart"\r
             itemId: 1\r
-            deployment_order: 1\r
-            lifecycle_parameters:\r
-              - ".Values.global.n2network.masterIf"\r
-              - ".Values.global.n3network.masterIf"\r
-              - ".Values.global.n4network.masterIf"\r
-              - ".Values.global.n6network.masterIf"\r
-        ueransim-free5gc:\r
+        oru-app:\r
           type: tosca.artifacts.asd.deploymentItem\r
-          file: "Artifacts/Deployment/HELM/ueransim-2.0.14.tgz"\r
+          file: "Artifacts/Deployment/HELM/orufhrecovery-1.0.0.tgz"\r
           properties:\r
             artifact_type: "helm_chart"\r
             itemId: 2\r
-            deployment_order: 2\r
-            lifecycle_parameters:\r
-              - ".Values.global.n2network.masterIf"\r
-              - ".Values.global.n3network.masterIf"\r
index b004aa2..e2a788a 100755 (executable)
@@ -1,313 +1,5 @@
 tosca_definitions_version: tosca_simple_yaml_1_2
 description: ASD types definitions version 0.1
-data_types:
-tosca.datatypes.asd.networkInterfaceRequirements:
-  derived_from: tosca.datatypes.Root
-  version: 0.1
-  description: "Describes the datatype for network interface requirements"
-  properties:
-    trunk_mode:
-      description: >
-        Information about whether the CP instantiated from this Cp is
-        in Trunk mode (802.1Q or other). When operating in "trunk mode",
-        the Cp is capable of carrying traffic for several VLANs.
-        Absence of this property implies that trunkMode is not configured
-        for the Cp i.e. It is equivalent to boolean value "false".
-      required: true
-      type: boolean
-      default: false
-    ipam:
-      description: >
-        Identifies whether application expects IP address assignment to be
-        managed by the cluster infrastructure (CNI IPAM plugin), or
-        configured by orchestrator via for example helm input parameter,
-        or if IP assignment is handled by the application itself.
-      required: true
-      type: string
-      constraints:
-        - valid_values: ["infraProvided", "orchestrated", "userManaged"]
-      default: "infraProvided"
-    interface_type:
-      description: >
-        Indicates what type of network interface the application expects.
-        Kernel based virtual netdev based on CNIs such as ovs | bridge |
-        macvlan | ipvlan, or PCIe dev directly visible in application
-        namespace with kernel or userspace driver or bonded with the Bond
-        CNI, or userspace-CNI based network interface
-        (requires DPDK-OVS/VPP vSwitch).
-      required: true
-      type: string
-      constraints:
-        - valid_values: ["kernel.netdev", "direct.userdriver", "direct.kerneldriver", "direct.bond", "userspace"]
-      default: "kernel.netdev"
-    interface_option:
-      description: >
-        This attribute describes verified realization options for the
-        network interface in question. Currently listed options
-        (virtio and memif) are applicable for the interfaceType “userspace”.
-      required: false
-      type: list
-      entry_schema:
-        type: string
-        constraints:
-          - valid_values: ["virtio", "memif"]
-    interface_redundancy:
-      description: >
-        Identifies switch-plane redundancy method the application uses,
-        and that node infrastructure is required to comply with.
-        "infraProvided", “left” and “right”: The container sees a
-        single vNIC that a) the infrastructure bonds over both switchplanes
-        or b) that is connected to the network via only left or
-        right the switchplane.
-        The other cases are for a mated pair of vnics connecting to
-        same network, but where one vNIC connects
-        via left switch plane and the other via right switch plane,
-        and where the application manages the redundancy.
-        "activePassiveBond": the application bonds with move of MAC address.
-        "activeActiveBond“: bonded left/right links must be part of a multi-chassis LAG
-        "activePassiveL3": application will move application IP address between the vNICs.
-        "activeActiveL3": the application uses anycast/ECMP.
-      required: true
-      type: string
-      constraints:
-        - valid_values: ["infraProvided", "actPassBond", "actActBond", "actPassL3", "actActL3", "Left", "Right"]
-      default: "infraProvided"
-    nic_options:
-      description: >
-        Identifies for the direct.userdriver interface type, the physical
-        nics the driver is verified to work with.
-        Allowed values for nic types must be handled via a registry or be standardized.
-      required: false
-      type: list
-      entry_schema:
-        type: string
-
-tosca.datatypes.asd.paramMappings:
-  version: 0.1
-  derived_from: tosca.datatypes.Root
-  description: "Describes the datatype for parameter mapping"
-  properties:
-    loadbalancer_IP:
-      description: >
-        When present, this attribute specifies the name of the deployment
-        artifact input parameter through which the orchestrator can
-        configure the loadbalancerIP parameter of the K8s service
-        or ingress controller that the extCpdData represents.
-        Note: The format of the Content strings is specific for each different
-        orchestration templating technology used (Helm, Teraform, etc.).
-        Currently only a format for use with Helm charts is suggested:
-        "<helmchartname>:[<subchartname>.]^(0..N)[<parentparamname>.]^(0..N)<paramname>".
-        Whether the optional parts of the format are present depends on how the
-        parameter is declared in the helm chart. An example is:
-        "chartName:subChart1.subChart2.subChart3.Parent1.Parent2.Parent3.LBIP".
-      required: false
-      type: string
-    external_IPs:
-      description: >
-        When present, this attribute specifies the name of the deployment
-        artifact input parameter through which the orchestrator can
-        configure the extermalIPs parameter of the K8s service or ingress
-        controller, or the pod network interface annotation, that the
-        extCpdData represents.
-        Note: The format of the Content strings is specific for each different
-        orchestration templating technology used (Helm, Teraform, etc.).
-        Currently only a format for use with Helm charts is suggested:
-        "<helmchartname>:[<subchartname>.]^(0..N)[<parentparamname>.]^(0..N)<paramname>".
-        Whether the optional parts of the format are present depends on how the
-        parameter is declared in the helm chart. An example is:
-        "chartName:subChart1.subChart2.subChart3.Parent1.Parent2.Parent3.extIP".
-      required: false
-      type: list
-      entry_schema:
-        type: string
-    nad_names:
-      description: >
-        Specifies, for an extCpdData respesenting a secondary network interface,
-        the name(s) of the deployment artifact input parameter(s) through which
-        the orchestrator can provide the names of the network attachment
-        definitions (NADs) the orchestrator has created as base for the network
-        interface the extCpdData represents.
-        Note 1: When the extCpdData represent a networkRedundant/mated-pair of
-        sriov interfaces, there are references to 2 or 3 related NADs needed
-        to be passed, while for other interface types only one NAD reference
-        is needed to be passed.
-        Note 2: The format of the Content strings is specific for each different
-        orchestration templating technology used (Helm, Teraform, etc.).
-        Currently only a format for use with Helm charts is suggested:
-        "<helmchartname>:[<subchartname>.]^(0..N)[<parentparamname>.]^(0..N)<paramname>".
-        Whether the optional parts of the format are present depends on how the
-        parameter is declared in the helm chart. An example is:
-        chartName:"subChart1.subChart2.subChart3.Parent1.Parent2.Parent3.nadName".
-        Note 3: A direct attached (passthrough) network interface, such as an sriov
-        interface, attaches to a network via only one of the two switch planes
-        in the infrastructure.
-        When using a direct attached network interface one therefore commonly in a
-        pod uses a mated pair of sriov network attachments, where each interface
-        attaches same network but via different switchplane.
-        The application uses the mated pair of network interfaces as a single
-        logical “swith-path-redundant” network interface – and this is represented
-        by a single extCpdData.
-        Also there is a case where a third “bond” attachment interface is used in
-        the pod, bonding the two direct interfaces so that the application do not
-        need to handle the redundancy issues – application just uses the bond interface.
-        In this case, all three attachments are together making up a logical
-        “switch-path-redundant” network interface represented by a single extCpdData.
-        When three NADs are used in the extCpdData the NAD implementing the bond attachment
-        interface is provided through the parameter indicated in the third place in
-        the nadNames attribute.
-      required: false
-      type: list
-      entry_schema:
-        type: string
-    nad_namespace:
-      description: >
-        Specifies, for an extCpdData respesenting a secondary network interface,
-        the name of the deployment artifact input parameter through which the orchestrator
-        can provide the namespace where the NetworkAttachmentDefinitions (NADs) are located.
-        Attribute may be omitted if the namespace is same as the application
-        namespace.
-        Note: The format of the Content strings is specific for each different
-        orchestration templating technology used (Helm, Teraform, etc.).
-        Currently only a format for use with Helm charts is suggested:
-        "<helmchartname>:[<subchartname>.]^(0..N)[<parentparamname>.]^(0..N)<paramname>".
-        Whether the optional parts of the format are present depends on how the
-        parameter is declared in the helm chart. An example is:
-        "chartName:subChart1.subChart2.subChart3.Parent1.Parent2.Parent3.NameSpace".
-      required: false
-      type: string
-
-tosca.datatypes.asd.extCpdData:
-  version: 0.1
-  derived_from: tosca.datatypes.Root
-  description: "Describes the datatype for external connection point definition data"
-  properties:
-    id:
-      description: "The identifier of this extCpdData"
-      required: true
-      type: string
-    description:
-      description: >
-        This property describes for a particular ExtCpd instance
-        what service it exposes.
-      required: true
-      type: string
-    virtual_link_requirement:
-      description: >
-        Refers in an abstract way to the network or multiple networks that
-        the ExtCpd shall be exposed on (ex: OAM, EndUser, backhaul, LI, etc)
-      required: true
-      type: string
-    network_interface_realization_requirements:
-      description: >
-        Details container implementation specific requirements on
-        the NetworkAttachmentDefinition
-      required: false
-      type: tosca.datatypes.asd.networkInterfaceRequirements
-    input_param_mappings:
-      description: >
-        Information on what helm chart input parameters that
-        are required to be configured for this extCpd
-      required: false
-      type: tosca.datatypes.asd.paramMappings
-    resource_mapping:
-      description: >
-        Kubernetes API resource name for the resource manifest for the service,
-        ingress controller or pod
-      required: false
-      type: string
-
-tosca.datatypes.asd.enhancedClusterCapabilities:
-  version: 0.1
-  derived_from: tosca.datatypes.Root
-  description: "Describes the datatype for parameter mapping"
-  properties:
-    min_kernel_version:
-      description: >
-        Describes the minimal required Kernel version, e.g. 4.15.0.
-        Coded as displayed by linux command uname –r
-      required: true
-      type: string
-    required_kernel_modules:
-      description: >
-        Required kernel modules are coded as listed by linux lsmod command,
-        e.g. ip6_tables, cryptd, nf_nat etc.
-      required: false
-      type: list
-      entry_schema:
-        type: string
-    conflicting_kernel_modules:
-      description: >
-        Kernel modules, which must not be present in the target environment.
-        The kernel modules are coded as listed by linux lsmod command,
-        e.g., ip6_tables, cryptd, nf_nat etc.
-        Example: Linux kernel SCTP module, which would conflict with use of
-        proprietary user space SCTP stack provided by the application.
-      required: false
-      type: list
-      entry_schema:
-        type: string
-    required_custom_resources:
-      description: >
-        List the custom resource kinds required to be supported in the target
-        environment. The list shall include those custom resource kinds which
-        are not delivered with the application.
-      required: false
-      type: list
-      entry_schema:
-        type: tosca.datatypes.asd.customResourceRequirement
-    cluster_labels:
-      description: >
-        This attribute allows to associate arbitrary labels to clusters.
-        These can indicate special infrastructure capabilities (e.g., NW acceleration,
-        GPU compute, etc.). The intent of these labels is to serve as a set of
-        values that can help in application placement decisions.
-        clusterLabels follow the Kubernetes label key-value-nomenclature
-        (https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/).
-        It is recommended that labels follow a standardized meaning e.g. for node
-        features (https://kubernetes-sigs.github.io/node-feature-discovery/v0.9/get-started/features.html#table-of-contents).
-        Example:
-        ClusterLabels
-          - feature.node.kubernetes.io/cpu-cpuid.AESNI: true
-      required: false
-      type: list
-      entry_schema:
-        type: string
-    required_plugin:
-      description: a list of the name of the required K8s plugin
-      required: false
-      type: list
-      entry_schema:
-        type: tosca.datatypes.asd.requiredPlugin
-
-tosca.datatypes.asd.customResourceRequirement:
-  version: 0.1
-  derived_from: tosca.datatypes.Root
-  description: >
-    kind: "Redis", apiVersion: "kubedb.com/v1alpha1"
-  properties:
-    kind:
-      description: "the name of the custom resource requirement"
-      type: string
-      required: true
-    api_version:
-      description: "the api version of the custom resource requirement"
-      type: string
-      required: true
-
-tosca.datatypes.asd.requiredPlugin:
-  version: 0.1
-  derived_from: tosca.datatypes.Root
-  description: "the required K8s plugin"
-  properties:
-    name:
-      description: "the name of the required K8s plugin"
-      type: string
-      required: true
-    version:
-      description: "the version of the required K8s plugin"
-      type: string
-      required: true
-
 node_types:
   tosca.nodes.asd:
     derived_from: tosca.nodes.Root
@@ -348,78 +40,13 @@ node_types:
         type: string
         required: true
         description: Identifies the version of the application service described by this ASD.
-      ext_cpds:
-        type: list
-        required: false
-        entry_schema:
-          type: tosca.datatypes.asd.extCpdData
-        description: >
-          Describes the externally exposed connection points of the application
-          service described by this ASD
-      enhanced_cluster_capabilities:
-        type: tosca.datatypes.asd.enhancedClusterCapabilities
-        required: false
-        description: >
-          A list of  expected capabilities of the target Kubernetes cluster to aid
-          placement of the application service on a suitable cluster.
-  tosca.nodes.asdInNsd:
-    derived_from: tosca.nodes.nfv.VNF
-    description: "The generic ASD node types for NS requirements. Optional properties are not list here."
-    version: 0.1
-    properties:
-      descriptor_id:
-        type: string # UUID
-        description: Identifier of an ASD. It is in UUID format as specified in RFC 4122
-        required: true
-      descriptor_version:
-        type: string
-        description: Identifies the version of the ASD.
-        required: true
-        default: ""
-      provider:
-        type: string
-        description: Identifies the provider of the ASD
-        required: true
-        default: ""
-      product_name:
-        type: string
-        description: Please use the application_name property
-        required: true
-        default: ""
-      software_version:
-        type: string
-        description: Please use the application_version property
-        required: true
-        default: ""
-      flavour_id:
-        type: string
-        required: true
-        constraints: [ equal: "simple" ]
-        default: "simple"
-      flavour_description:
-        type: string
-        required: true
-        default: ""
-      vnfm_info:
-        type: list
-        required: true
-        entry_schema:
-          type: list
-    requirements:
-      - virtual_link:
-          capability: tosca.capabilities.nfv.VirtualLinkable
-          relationship: tosca.relationships.nfv.VirtualLinkableTo
-          occurrences: [ 0,0 ]
-      - virtual_links:
-          capability: tosca.capabilities.nfv.VirtualLinkable
-          relationship: tosca.relationships.nfv.VirtualLinkableTo
-          occurrences: [ 0,UNBOUNDED ]
+
 artifact_types:
 tosca.artifacts.asd.deploymentItem:
     version: 0.1
     derived_from: tosca.artifacts.Root
     description: "Describes the artifact type of asd deployment item"
-    file: "URI or path of the artifact"
+    file: "Relative path of the artifact in the package"
     properties:
         item_id:
             description: "The identifier of this asd deployment item"
@@ -431,18 +58,4 @@ tosca.artifacts.asd.deploymentItem:
             required: true
             type: string
             constraints:
-                - valid_values: ["helm_chart", "helmfile", "crd", "terraform" ]
-        deployment_order:
-            description: >
-                Specifies the deployment stage that the DeploymentArtifact belongs to.
-                A lower value specifies that the DeploymentArtifact belongs to an earlier
-                deployment stage. When this value is omitted, the deployment order
-                will be decided by the orchestrator.
-            required: false
-            type: integer
-        lifecycle_parameters:
-            description: "list of parameters that can be overridden at deployment time "
-            required: false
-            type: list
-            entry_schema:
-                type: string
+                - valid_values: ["helm_chart"]
index a63de54..b190fa7 100755 (executable)
@@ -5,6 +5,8 @@ metadata:
   entry_definition_type: asd\r
 \r
 Source: asd.mf\r
+Source: Artifacts/Deployment/HELM/orufhrecovery-1.0.0.tgz\r
+Source: Artifacts/Deployment/HELM/ransliceassurance-1.0.0.tgz\r
 Source: Definitions/asd.yaml\r
 Source: Definitions/asd_types.yaml\r
 Source: Files/Guides/user_guide.txt\r