JTosca Parser – support Annotations
authorSheshukov, Natalia (ns019t) <ns019t@intl.att.com>
Sun, 15 Apr 2018 10:11:15 +0000 (13:11 +0300)
committerSheshukov, Natalia (ns019t) <ns019t@intl.att.com>
Sun, 15 Apr 2018 15:53:14 +0000 (18:53 +0300)
Change-Id: I256e42e5f4a6e5259c17b8de56d64b44afb7f42d
Issue-ID: SDC-1223
Signed-off-by: Sheshukov, Natalia (ns019t) <ns019t@intl.att.com>
src/main/java/org/onap/sdc/toscaparser/api/Property.java
src/main/java/org/onap/sdc/toscaparser/api/ToscaTemplate.java
src/main/java/org/onap/sdc/toscaparser/api/elements/enums/ToscaElementNames.java [new file with mode: 0644]
src/main/java/org/onap/sdc/toscaparser/api/parameters/Annotation.java [new file with mode: 0644]
src/main/java/org/onap/sdc/toscaparser/api/parameters/Input.java
src/test/java/org/onap/sdc/toscaparser/api/JToscaImportTest.java
src/test/resources/csars/service-AdiodVmxVpeBvService-csar.csar [new file with mode: 0644]

index 227da0a..6d05af0 100644 (file)
@@ -2,7 +2,10 @@ package org.onap.sdc.toscaparser.api;
 
 import java.util.ArrayList;
 import java.util.LinkedHashMap;
+import java.util.Map;
 
+import org.onap.sdc.toscaparser.api.elements.PropertyDef;
+import org.onap.sdc.toscaparser.api.elements.StatefulEntityType;
 import org.onap.sdc.toscaparser.api.elements.constraints.Constraint;
 import org.onap.sdc.toscaparser.api.elements.constraints.Schema;
 import org.onap.sdc.toscaparser.api.functions.Function;
@@ -29,6 +32,10 @@ public class Property {
        private Schema schema;
        private LinkedHashMap<String,Object> customDef;
 
+       public Property(Map.Entry<String,Object> propertyEntry){
+        name = propertyEntry.getKey();
+        value = propertyEntry.getValue();
+       }
        public Property(String propname,
                                        Object propvalue,
                                        LinkedHashMap<String,Object> propschemaDict,
index ea76a09..bfd0716 100644 (file)
@@ -1,28 +1,34 @@
 package org.onap.sdc.toscaparser.api;
 
-import org.onap.sdc.toscaparser.api.common.JToscaValidationIssue;
-import org.onap.sdc.toscaparser.api.common.ValidationIssueCollector;
-import org.onap.sdc.toscaparser.api.parameters.Output;
-import org.onap.sdc.toscaparser.api.utils.ThreadLocalsHolder;
-
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
-import java.util.*;
-import java.util.concurrent.ConcurrentHashMap;
 import java.nio.file.Files;
-import java.util.function.Predicate;
 import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.function.Predicate;
 
 import org.onap.sdc.toscaparser.api.common.JToscaException;
+import org.onap.sdc.toscaparser.api.common.JToscaValidationIssue;
+import org.onap.sdc.toscaparser.api.common.ValidationIssueCollector;
 import org.onap.sdc.toscaparser.api.elements.EntityType;
 import org.onap.sdc.toscaparser.api.elements.Metadata;
 import org.onap.sdc.toscaparser.api.extensions.ExtTools;
 import org.onap.sdc.toscaparser.api.parameters.Input;
+import org.onap.sdc.toscaparser.api.parameters.Output;
 import org.onap.sdc.toscaparser.api.prereq.CSAR;
 import org.onap.sdc.toscaparser.api.utils.JToscaErrorCodes;
+import org.onap.sdc.toscaparser.api.utils.ThreadLocalsHolder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.yaml.snakeyaml.Yaml;
@@ -281,10 +287,12 @@ public class ToscaTemplate extends Object {
                return (String)tpl.get(DESCRIPTION);
        }
 
+       @SuppressWarnings("unchecked")
        private ArrayList<Object> _tplImports() {
                return (ArrayList<Object>)tpl.get(IMPORTS);
        }
 
+       @SuppressWarnings("unchecked")
        private ArrayList<Repository> _tplRepositories() {
                LinkedHashMap<String,Object> repositories = 
                                (LinkedHashMap<String,Object>)tpl.get(REPOSITORIES);
@@ -302,11 +310,6 @@ public class ToscaTemplate extends Object {
                return (LinkedHashMap<String,Object>)_getCustomTypes(RELATIONSHIP_TYPES,null);
        }
 
-       @SuppressWarnings("unchecked")
-       private LinkedHashMap<String,Object> _tplRelationshipTemplates() {
-               return (LinkedHashMap<String,Object>)_tplTopologyTemplate().get(RELATIONSHIP_TEMPLATES);
-       }
-
        @SuppressWarnings("unchecked")
        private LinkedHashMap<String,Object> _tplTopologyTemplate() {
                return (LinkedHashMap<String,Object>)tpl.get(TOPOLOGY_TEMPLATE);
@@ -332,6 +335,7 @@ public class ToscaTemplate extends Object {
         * @param alImports all imports which needs to be processed
         * @return the linked hash map containing all import definitions
         */
+       @SuppressWarnings("unchecked")
        private LinkedHashMap<String,Object> _getAllCustomDefs(Object alImports) {
 
                String types[] = {
@@ -346,7 +350,7 @@ public class ToscaTemplate extends Object {
                                imports = sortImports(imports);
 
                                for (Map<String, Object> map : imports) {
-                                       List<Map<String, Object>> singleImportList = new ArrayList();
+                                       List<Map<String, Object>> singleImportList = new ArrayList<>();
                                        singleImportList.add(map);
 
                                        Map<String, String> importNameDetails = getValidFileNameForImportReference(singleImportList);
@@ -398,7 +402,7 @@ public class ToscaTemplate extends Object {
                List<Map<String, Object>> finalList2 = new ArrayList<>();
                Iterator<Map<String, Object>> itr = customImports.iterator();
                while(itr.hasNext()) {
-                       Map innerMap = itr.next();
+                       Map<String, Object> innerMap = itr.next();
                        if (innerMap.toString().contains("../")) {
                                finalList2.add(innerMap);
                                itr.remove();
@@ -451,8 +455,7 @@ public class ToscaTemplate extends Object {
         * @param customImports the custom imports
         * @return the map containing import file full and relative paths
         */
-       private Map<String, String> getValidFileNameForImportReference(List<Map<String, Object>>
-                                                                                                                                                                                                                                                                                customImports){
+       private Map<String, String> getValidFileNameForImportReference(List<Map<String, Object>> customImports){
                String importFileName;
                Map<String, String> retMap = new HashMap<>();
                for (Map<String, Object> map1 : customImports) {
@@ -575,6 +578,7 @@ public class ToscaTemplate extends Object {
        }
 
        // multi level nesting - RECURSIVE
+       @SuppressWarnings("unchecked")
        private void _handleNestedToscaTemplatesWithTopology(TopologyTemplate tt) {
                if(++nestingLoopCounter > 10) {
                        log.error("ToscaTemplate - _handleNestedToscaTemplatesWithTopology - Nested Topologies Loop: too many levels, aborting");
@@ -583,7 +587,6 @@ public class ToscaTemplate extends Object {
                // Reset Processed Imports for nested templates
                this.processedImports = new HashSet<>();
                for(Map.Entry<String,Object> me: nestedToscaTplsWithTopology.entrySet()) {
-                       String fname = me.getKey();
                        LinkedHashMap<String,Object> toscaTpl = 
                                                        (LinkedHashMap<String,Object>)me.getValue();
                        for(NodeTemplate nt: tt.getNodeTemplates()) {
@@ -761,6 +764,9 @@ public class ToscaTemplate extends Object {
        }
        
        public ArrayList<Input> getInputs() {
+               if(inputs != null){
+                       inputs.stream().forEach(Input::resetAnnotaions);
+               }
                return inputs;
        }
        
@@ -821,6 +827,7 @@ public class ToscaTemplate extends Object {
                return pparams;
        }
 
+       @SuppressWarnings("unchecked")
        private String getSubMappingNodeType(LinkedHashMap<String,Object> toscaTpl) {
                // Return substitution mappings node type
                if(toscaTpl != null) {
@@ -830,12 +837,6 @@ public class ToscaTemplate extends Object {
                return null;
        }
 
-       private boolean _hasSubstitutionMapping() {
-        // Return True if the template has valid substitution mappings
-        return topologyTemplate != null &&
-            topologyTemplate.getSubstitutionMappings() != null;
-       }
-
        public boolean hasNestedTemplates() {
         // Return True if the tosca template has nested templates
         return nestedToscaTemplatesWithTopology != null &&
@@ -881,6 +882,14 @@ public class ToscaTemplate extends Object {
                                ", nestingLoopCounter=" + nestingLoopCounter +
                                '}';
        }
+
+       public List<Input> getInputs(boolean annotationsRequired) {
+               if(inputs != null && annotationsRequired){
+                       inputs.stream().forEach(Input::parseAnnotations);
+                       return inputs;
+               }
+               return getInputs();
+       }
 }
 
 /*python
diff --git a/src/main/java/org/onap/sdc/toscaparser/api/elements/enums/ToscaElementNames.java b/src/main/java/org/onap/sdc/toscaparser/api/elements/enums/ToscaElementNames.java
new file mode 100644 (file)
index 0000000..0ee201c
--- /dev/null
@@ -0,0 +1,20 @@
+package org.onap.sdc.toscaparser.api.elements.enums;
+
+public enum ToscaElementNames {
+       
+       TYPE ("type"),
+       PROPERTIES ("properties"),
+       ANNOTATIONS ("annotations"),
+       SOURCE_TYPE ("source_type");
+       
+       private String name;
+       
+       ToscaElementNames(String name){
+               this.name = name;
+       }
+
+       public String getName() {
+               return name;
+       }
+       
+}
diff --git a/src/main/java/org/onap/sdc/toscaparser/api/parameters/Annotation.java b/src/main/java/org/onap/sdc/toscaparser/api/parameters/Annotation.java
new file mode 100644 (file)
index 0000000..74b738f
--- /dev/null
@@ -0,0 +1,76 @@
+package org.onap.sdc.toscaparser.api.parameters;
+
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+import org.onap.sdc.toscaparser.api.Property;
+import org.onap.sdc.toscaparser.api.elements.enums.ToscaElementNames;
+
+public class Annotation{
+       
+       private final static String HEAT = "HEAT";
+       
+       private String name;
+       private String type;
+       private ArrayList<Property> properties;
+       
+       public Annotation(){}
+       @SuppressWarnings("unchecked")
+       public Annotation(Map.Entry<String,Object> annotationEntry){
+               if(annotationEntry != null){
+                       name = annotationEntry.getKey();
+                       Map<String, Object> annValue = (Map<String, Object>) annotationEntry.getValue();
+                       type = (String) annValue.get(ToscaElementNames.TYPE.getName());
+                       properties = fetchProperties((Map<String, Object>) annValue.get(ToscaElementNames.PROPERTIES.getName()));
+               }
+       }
+
+       public String getName() {
+               return name;
+       }
+       
+       public void setName(String name) {
+               this.name = name;
+       }
+       
+       public String getType() {
+               return type;
+       }
+       
+       public void setType(String type) {
+               this.type = type;
+       }
+       
+       public ArrayList<Property> getProperties() {
+               return properties;
+       }
+       
+       public void setProperties(ArrayList<Property> properties) {
+               this.properties = properties;
+       }
+       
+       private ArrayList<Property> fetchProperties(Map<String, Object> properties) {
+               if(properties != null){
+                       return (ArrayList<Property>) properties.entrySet().stream()
+                                       .map(Property::new)
+                                       .collect(Collectors.toList());
+               }
+               return null;
+       }
+       
+       public boolean isHeatSourceType(){
+               if(properties == null){
+                       return false;
+               }
+               Optional<Property> sourceType = properties.stream()
+                               .filter(p -> p.getName().equals(ToscaElementNames.SOURCE_TYPE.getName()))
+                               .findFirst();
+               if(!sourceType.isPresent()){
+                       return false;
+               }
+               return sourceType.get().getValue() != null && ((String)sourceType.get().getValue()).equals(HEAT);
+       }
+       
+}
index 7e83cfb..e7a1246 100644 (file)
@@ -1,16 +1,18 @@
 package org.onap.sdc.toscaparser.api.parameters;
 
-import org.onap.sdc.toscaparser.api.DataEntity;
-import org.onap.sdc.toscaparser.api.common.JToscaValidationIssue;
-import org.onap.sdc.toscaparser.api.utils.ThreadLocalsHolder;
-
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.stream.Collectors;
 
+import org.onap.sdc.toscaparser.api.DataEntity;
+import org.onap.sdc.toscaparser.api.common.JToscaValidationIssue;
 import org.onap.sdc.toscaparser.api.elements.EntityType;
 import org.onap.sdc.toscaparser.api.elements.constraints.Constraint;
 import org.onap.sdc.toscaparser.api.elements.constraints.Schema;
+import org.onap.sdc.toscaparser.api.elements.enums.ToscaElementNames;
+import org.onap.sdc.toscaparser.api.utils.ThreadLocalsHolder;
 
 public class Input {
        
@@ -41,6 +43,7 @@ public class Input {
     private String name;
     private Schema schema;
        private LinkedHashMap<String,Object> customDefs;
+       private Map<String, Annotation> annotations;
        
        public Input(){
                /**
@@ -53,7 +56,20 @@ public class Input {
                schema = new Schema(_name,_schemaDict);
                customDefs = _customDefs;
        }
-       
+
+       @SuppressWarnings("unchecked")
+       public void parseAnnotations() {
+               if(schema.getSchema() != null){
+                       LinkedHashMap<String, Object> annotations = (LinkedHashMap<String, Object>) schema.getSchema().get(ToscaElementNames.ANNOTATIONS.getName());
+                       if(annotations != null){
+                               setAnnotations(annotations.entrySet().stream()
+                               .map(Annotation::new)
+                               .filter(Annotation::isHeatSourceType)
+                               .collect(Collectors.toMap(a -> a.getName(), a -> a)));
+                       }
+               }
+       }
+
        public String getName() {
                return name;
        }
@@ -124,7 +140,8 @@ public class Input {
                }
     }
     
-    private void _validateValue(Object value) {
+    @SuppressWarnings("unchecked")
+       private void _validateValue(Object value) {
        Object datatype = null;
        if(EntityType.TOSCA_DEF.get(getType()) != null) {
                datatype = EntityType.TOSCA_DEF.get(getType());
@@ -147,87 +164,16 @@ public class Input {
        
        DataEntity.validateDatatype(getType(), value, null, (LinkedHashMap<String,Object>)datatype, null);
     }
-}
-
-/*python
-
-from toscaparser.common.exception import ValidationIssueCollector
-from toscaparser.common.exception import MissingRequiredFieldError
-from toscaparser.common.exception import UnknownFieldError
-from toscaparser.dataentity import DataEntity
-from toscaparser.elements.constraints import Schema
-from toscaparser.elements.entity_type import EntityType
-from toscaparser.utils.gettextutils import _
-
-
-log = logging.getLogger('tosca')
-
 
-class Input(object):
-
-    INPUTFIELD = (TYPE, DESCRIPTION, DEFAULT, CONSTRAINTS, REQUIRED, STATUS,
-                  ENTRY_SCHEMA) = ('type', 'description', 'default',
-                                   'constraints', 'required', 'status',
-                                   'entry_schema')
-
-    def __init__(self, name, schema_dict):
-        self.name = name
-        self.schema = Schema(name, schema_dict)
-
-        self._validate_field()
-        self.validate_type(self.type)
-
-    @property
-    def type(self):
-        return self.schema.type
-
-    @property
-    def required(self):
-        return self.schema.required
-
-    @property
-    def description(self):
-        return self.schema.description
-
-    @property
-    def default(self):
-        return self.schema.default
-
-    @property
-    def constraints(self):
-        return self.schema.constraints
-
-    @property
-    def status(self):
-        return self.schema.status
-
-    def validate(self, value=None):
-        if value is not None:
-            self._validate_value(value)
-
-    def _validate_field(self):
-        for name in self.schema.schema:
-            if name not in self.INPUTFIELD:
-                ValidationIssueCollector.appendException(
-                    UnknownFieldError(what='Input "%s"' % self.name,
-                                      field=name))
-
-    def validate_type(self, input_type):
-        if input_type not in Schema.PROPERTY_TYPES:
-            ValidationIssueCollector.appendException(
-                ValueError(_('Invalid type "%s".') % type))
-
-    # tODO(anyone) Need to test for any built-in datatype not just network
-    # that is, tosca.datatypes.* and not assume tosca.datatypes.network.*
-    # tODO(anyone) Add support for tosca.datatypes.Credential
-    def _validate_value(self, value):
-        tosca = EntityType.TOSCA_DEF
-        datatype = None
-        if self.type in tosca:
-            datatype = tosca[self.type]
-        elif EntityType.DATATYPE_NETWORK_PREFIX + self.type in tosca:
-            datatype = tosca[EntityType.DATATYPE_NETWORK_PREFIX + self.type]
-
-        DataEntity.validate_datatype(self.type, value, None, datatype)
+       public Map<String, Annotation> getAnnotations() {
+               return annotations;
+       }
 
-*/
+       private void setAnnotations(Map<String, Annotation> annotations) {
+               this.annotations = annotations;
+       }
+       
+       public void resetAnnotaions(){
+               annotations = null;
+       }
+}
index 589e47c..7d0c54c 100644 (file)
@@ -2,63 +2,116 @@ package org.onap.sdc.toscaparser.api;
 
 import org.junit.Test;
 import org.onap.sdc.toscaparser.api.common.JToscaException;
+import org.onap.sdc.toscaparser.api.parameters.Annotation;
+import org.onap.sdc.toscaparser.api.parameters.Input;
 import org.onap.sdc.toscaparser.api.utils.ThreadLocalsHolder;
 
 import java.io.File;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Optional;
 import java.util.stream.Collectors;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
 
 public class JToscaImportTest {
 
-    @Test
-    public void testNoMissingTypeValidationError() throws JToscaException {
-        String fileStr = JToscaImportTest.class.getClassLoader().getResource
-            ("csars/sdc-onboarding_csar.csar").getFile();
-        File file = new File(fileStr);
-        new ToscaTemplate(file.getAbsolutePath(), null, true, null);
-        List<String> missingTypeErrors = ThreadLocalsHolder.getCollector()
-            .getValidationIssueReport()
-            .stream()
-            .filter(s -> s.contains("JE136"))
-            .collect(Collectors.toList());
-        assertEquals(0, missingTypeErrors.size());
-    }
-
-    @Test
-    public void testNoStackOverFlowError() {
-        Exception jte = null;
-        try {
-            String fileStr = JToscaImportTest.class.getClassLoader().getResource
-                ("csars/sdc-onboarding_csar.csar").getFile();
-            File file = new File(fileStr);
-            new ToscaTemplate(file.getAbsolutePath(), null, true, null);
-        } catch (Exception e){
-            jte = e;
-        }
-        assertEquals(null, jte);
-    }
-
-  @Test
-  public void testNoInvalidImports() throws JToscaException {
-    List<String> fileNames = new ArrayList<>();
-    fileNames.add("csars/tmpCSAR_Huawei_vSPGW_fixed.csar");
-    fileNames.add("csars/sdc-onboarding_csar.csar");
-    fileNames.add("csars/resource-Spgw-csar-ZTE.csar");
-
-    for (String fileName : fileNames) {
-      String fileStr = JToscaImportTest.class.getClassLoader().getResource(fileName).getFile();
-      File file = new File(fileStr);
-      new ToscaTemplate(file.getAbsolutePath(), null, true, null);
-      List<String> invalidImportErrors = ThreadLocalsHolder.getCollector()
-          .getValidationIssueReport()
-          .stream()
-          .filter(s -> s.contains("JE195"))
-          .collect(Collectors.toList());
-      assertEquals(0, invalidImportErrors.size());
-    }
-  }
+       @Test
+       public void testNoMissingTypeValidationError() throws JToscaException {
+               String fileStr = JToscaImportTest.class.getClassLoader().getResource("csars/sdc-onboarding_csar.csar")
+                               .getFile();
+               File file = new File(fileStr);
+               new ToscaTemplate(file.getAbsolutePath(), null, true, null);
+               List<String> missingTypeErrors = ThreadLocalsHolder.getCollector().getValidationIssueReport().stream()
+                               .filter(s -> s.contains("JE136")).collect(Collectors.toList());
+               assertEquals(0, missingTypeErrors.size());
+       }
+
+       @Test
+       public void testNoStackOverFlowError() {
+               Exception jte = null;
+               try {
+                       String fileStr = JToscaImportTest.class.getClassLoader().getResource("csars/sdc-onboarding_csar.csar")
+                                       .getFile();
+                       File file = new File(fileStr);
+                       new ToscaTemplate(file.getAbsolutePath(), null, true, null);
+               } catch (Exception e) {
+                       jte = e;
+               }
+               assertEquals(null, jte);
+       }
+
+       @Test
+       public void testNoInvalidImports() throws JToscaException {
+               List<String> fileNames = new ArrayList<>();
+               fileNames.add("csars/tmpCSAR_Huawei_vSPGW_fixed.csar");
+               fileNames.add("csars/sdc-onboarding_csar.csar");
+               fileNames.add("csars/resource-Spgw-csar-ZTE.csar");
+
+               for (String fileName : fileNames) {
+                       String fileStr = JToscaImportTest.class.getClassLoader().getResource(fileName).getFile();
+                       File file = new File(fileStr);
+                       new ToscaTemplate(file.getAbsolutePath(), null, true, null);
+                       List<String> invalidImportErrors = ThreadLocalsHolder.getCollector().getValidationIssueReport().stream()
+                                       .filter(s -> s.contains("JE195")).collect(Collectors.toList());
+                       assertEquals(0, invalidImportErrors.size());
+               }
+       }
+       
+       @Test
+       public void testParseAnnotations() throws JToscaException {
+
+               String fileStr = JToscaImportTest.class.getClassLoader().getResource("csars/service-AdiodVmxVpeBvService-csar.csar").getFile();
+               File file = new File(fileStr);
+               ToscaTemplate toscaTemplate = new ToscaTemplate(file.getAbsolutePath(), null, true, null);
+               
+               List<Input> inputs = toscaTemplate.getInputs();
+               assertNotNull(inputs);
+               assertTrue(inputs.stream().filter(i -> i.getAnnotations() != null).collect(Collectors.toList()).isEmpty());
+               
+               inputs.forEach(Input::parseAnnotations);
+               assertTrue(!inputs.stream().filter(i -> i.getAnnotations() != null).collect(Collectors.toList()).isEmpty());
+       }
+
+       @Test
+       public void testGetInputsWithAndWithoutAnnotations() throws JToscaException {
+
+               String fileStr = JToscaImportTest.class.getClassLoader().getResource("csars/service-AdiodVmxVpeBvService-csar.csar").getFile();
+               File file = new File(fileStr);
+               ToscaTemplate toscaTemplate = new ToscaTemplate(file.getAbsolutePath(), null, true, null);
+               List<Input> inputs = toscaTemplate.getInputs();
+               assertNotNull(inputs);
+               assertTrue(inputs.stream().filter(i -> i.getAnnotations() != null).collect(Collectors.toList()).isEmpty());
+
+               inputs = toscaTemplate.getInputs(true);
+               assertNotNull(inputs);
+               validateInputsAnnotations(inputs);
+
+               inputs = toscaTemplate.getInputs(false);
+               assertNotNull(inputs);
+               assertTrue(inputs.stream().filter(i -> i.getAnnotations() != null).collect(Collectors.toList()).isEmpty());
+       }
+
+       private void validateInputsAnnotations(List<Input> inputs) {
+               List<Input> inputsWithAnnotations = inputs.stream().filter(i -> i.getAnnotations() != null)
+                               .collect(Collectors.toList());
+               assertTrue(!inputs.isEmpty());
+               inputsWithAnnotations.stream().forEach(i -> validateAnnotations(i));
+       }
+
+       private void validateAnnotations(Input input) {
+               assertNotNull(input.getAnnotations());
+               assertEquals(input.getAnnotations().size(), 1);
+               Annotation annotation = input.getAnnotations().get("source");
+               assertEquals(annotation.getName(), "source");
+               assertEquals(annotation.getType().toLowerCase(), "org.openecomp.annotations.source");
+               assertNotNull(annotation.getProperties());
+               Optional<Property> source_type = annotation.getProperties().stream()
+                               .filter(p -> p.getName().equals("source_type")).findFirst();
+               assertTrue(source_type.isPresent());
+               assertEquals(source_type.get().getValue(), "HEAT");
+       }
 
 }
diff --git a/src/test/resources/csars/service-AdiodVmxVpeBvService-csar.csar b/src/test/resources/csars/service-AdiodVmxVpeBvService-csar.csar
new file mode 100644 (file)
index 0000000..28aa6f4
Binary files /dev/null and b/src/test/resources/csars/service-AdiodVmxVpeBvService-csar.csar differ