Provide tosca function to custom datatypes of list and map 23/132823/5
authorimamSidero <imam.hussain@est.tech>
Wed, 21 Dec 2022 17:51:43 +0000 (17:51 +0000)
committerimamSidero <imam.hussain@est.tech>
Tue, 3 Jan 2023 15:03:15 +0000 (15:03 +0000)
Providing the capability to add tosca function as the custom datatypes of list and map

Issue-ID: SDC-4311
Signed-off-by: Imam hussain <imam.hussain@est.tech>
Change-Id: I7ec8943d8008440b091fc4eaa2aba49cdadcda8d

catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/YamlTemplateParsingHandler.java
catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogic.java
catalog-be/src/main/java/org/openecomp/sdc/be/datamodel/utils/PropertyValueConstraintValidationUtil.java
catalog-model/src/main/java/org/openecomp/sdc/be/model/PropertyDefinition.java
catalog-ui/src/app/ng2/components/logic/properties-table/dynamic-property/dynamic-property.component.html
catalog-ui/src/app/ng2/components/logic/properties-table/dynamic-property/dynamic-property.component.ts
catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.page.component.ts
catalog-ui/src/app/ng2/pages/properties-assignment/services/properties.utils.ts
catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-function.component.ts
catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-get-function/tosca-get-function.component.ts

index 1500074..5a6a7c9 100644 (file)
@@ -1378,25 +1378,23 @@ public class YamlTemplateParsingHandler {
         for (Object objValue : propValueList) {
             if (objValue instanceof Map) {
                 Map<String, Object> objMap = (Map<String, Object>) objValue;
+                Map<String, Object> propValueMap = new HashMap<String, Object>();
+                propValueMap.put(String.valueOf(index),objValue);
+                final Collection<SubPropertyToscaFunction> subPropertyToscaFunctions = buildSubPropertyToscaFunctions(propValueMap, new ArrayList<>());
+                if (CollectionUtils.isNotEmpty(subPropertyToscaFunctions)) {
+                    Collection<SubPropertyToscaFunction> existingSubPropertyToscaFunctions = propertyDef.getSubPropertyToscaFunctions();
+                    if (existingSubPropertyToscaFunctions == null) {
+                        propertyDef.setSubPropertyToscaFunctions(subPropertyToscaFunctions);
+                    } else {
+                        propertyDef.getSubPropertyToscaFunctions().addAll(subPropertyToscaFunctions);
+                    }
+                }
                 if (objMap.containsKey(GET_INPUT.getElementName())) {
                     fillInputRecursively(propertyDef.getName(), objMap, propertyDef);
                 } else {
                     Set<String> keys = objMap.keySet();
                     findAndFillInputsListRecursively(propertyDef, objMap, keys);
                 }
-                if (toscaFunctionYamlParsingHandler.isPropertyValueToscaFunction(objValue)) {
-                    Map<String, Object> propValueMap = new HashMap<String, Object>();
-                    propValueMap.put(String.valueOf(index),objValue);
-                    final Collection<SubPropertyToscaFunction> subPropertyToscaFunctions = buildSubPropertyToscaFunctions(propValueMap, new ArrayList<>());
-                    if (CollectionUtils.isNotEmpty(subPropertyToscaFunctions)) {
-                        Collection<SubPropertyToscaFunction> existingSubPropertyToscaFunctions = propertyDef.getSubPropertyToscaFunctions();
-                        if (existingSubPropertyToscaFunctions == null) {
-                            propertyDef.setSubPropertyToscaFunctions(subPropertyToscaFunctions);
-                        } else {
-                            propertyDef.getSubPropertyToscaFunctions().addAll(subPropertyToscaFunctions);
-                        }
-                    }
-                }
             } else if (objValue instanceof List) {
                 List<Object> propSubValueList = (List<Object>) objValue;
                 fillInputsListRecursively(propertyDef, propSubValueList);
index 3797fb9..fe6ea03 100644 (file)
@@ -2071,14 +2071,12 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic {
         if (jsonObject.has(path.get(0))) {
             objectForPath =  jsonObject.get(path.get(0));
         } else {
-            if (path.size() > 1) {
-                if (StringUtils.isNumeric(path.get(1))) {
-                    objectForPath = new JSONArray();
-                } else {
-                    objectForPath = new JSONObject();
-                }
-                jsonObject.put(path.get(0), objectForPath);
+            if (StringUtils.isNumeric(path.get(0))) {
+                objectForPath = new JSONArray();
+            } else {
+                objectForPath = new JSONObject();
             }
+            jsonObject.put(path.get(0), objectForPath);
         }
 
         if (path.size() == 1) {
index 6aa59e4..19fe69e 100644 (file)
@@ -34,6 +34,7 @@ import org.apache.commons.lang3.StringUtils;
 import org.openecomp.sdc.be.components.impl.ResponseFormatManager;
 import org.openecomp.sdc.be.dao.api.ActionStatus;
 import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition;
+import org.openecomp.sdc.be.datatypes.elements.SubPropertyToscaFunction;
 import org.openecomp.sdc.be.model.ComponentInstanceInput;
 import org.openecomp.sdc.be.model.DataTypeDefinition;
 import org.openecomp.sdc.be.model.InputDefinition;
@@ -186,6 +187,21 @@ public class PropertyValueConstraintValidationUtil {
         try {
             PropertyDefinition newPropertyWithValue;
             if (valueMap.containsKey(prop.getName())) {
+                if (propertyDefinition.getSubPropertyToscaFunctions() != null) {
+                    for (SubPropertyToscaFunction subPropertyToscaFunction : propertyDefinition.getSubPropertyToscaFunctions()) {
+                        final List<String> path = subPropertyToscaFunction.getSubPropertyPath();
+                        if (path.size() == 1) {
+                            if (path.get(0).equals(prop.getName())) {
+                                return;
+                            }
+                        }
+                        if (path.size() > 1) {
+                            if (path.get(0).equals(propertyDefinition.getToscaSubPath()) && path.get(1).equals(prop.getName())) {
+                                return;
+                            }
+                        }
+                    }
+                }
                 if (ToscaType.isPrimitiveType(prop.getType())) {
                     newPropertyWithValue = copyPropertyWithNewValue(prop, String.valueOf(valueMap.get(prop.getName())));
                     if (isPropertyToEvaluate(newPropertyWithValue)) {
@@ -297,9 +313,14 @@ public class PropertyValueConstraintValidationUtil {
             if (propertyDefinition.getSchemaType() == null) {
                 propertyDefinition.setSchema(createStringSchema());
             }
-            Collection<Object> list = ConstraintUtil.parseToCollection(propertyDefinition.getValue(), new TypeReference<>() {
-            });
-            evaluateCollectionType(propertyDefinition, list);
+            Collection<Object> list = ConstraintUtil.parseToCollection(propertyDefinition.getValue(), new TypeReference<>() {});
+            final Map<String, Object> map = new HashMap<>();
+            int index = 0;
+            for (Object obj : list) {
+                map.put(String.valueOf(index),obj);
+                index++;
+            }
+            evaluateCollectionType(propertyDefinition, map);
         } catch (ConstraintValueDoNotMatchPropertyTypeException e) {
             logger.debug(e.getMessage(), e);
             errorMessages.add(String.format(VALUE_PROVIDED_IN_INVALID_FORMAT_FOR_PROPERTY, getCompletePropertyName(propertyDefinition)));
@@ -321,7 +342,7 @@ public class PropertyValueConstraintValidationUtil {
             }
             final Map<String, Object> map = ConstraintUtil.parseToCollection(propertyDefinition.getValue(), new TypeReference<>() {
             });
-            evaluateCollectionType(propertyDefinition, map.values());
+            evaluateCollectionType(propertyDefinition, map);
         } catch (ConstraintValueDoNotMatchPropertyTypeException e) {
             logger.debug(e.getMessage(), e);
             errorMessages.add(String.format(VALUE_PROVIDED_IN_INVALID_FORMAT_FOR_PROPERTY, getCompletePropertyName(propertyDefinition)));
@@ -338,12 +359,14 @@ public class PropertyValueConstraintValidationUtil {
         }
     }
 
-    private void evaluateCollectionType(final PropertyDefinition propertyDefinition, final Collection<Object> valueList) {
+    private void evaluateCollectionType(final PropertyDefinition propertyDefinition, final Map<String, Object> valueMap) {
         final String schemaType = propertyDefinition.getSchemaType();
-        for (final Object value : valueList) {
+        for (String mapKey : valueMap.keySet()) {
+            final Object value = valueMap.get(mapKey);
             try {
                 final PropertyDefinition propertyCopyWithNewValue = copyPropertyWithNewValue(propertyDefinition,
                     objectMapper.writeValueAsString(value));
+                propertyCopyWithNewValue.setToscaSubPath(mapKey);
                 if (ToscaType.isPrimitiveType(schemaType)) {
                     evaluateCollectionPrimitiveSchemaType(propertyCopyWithNewValue, schemaType);
                 } else if (ToscaType.isCollectionType(schemaType)) {
index d9add3f..f612514 100644 (file)
@@ -39,6 +39,16 @@ public class PropertyDefinition extends PropertyDataDefinition implements IOpera
         super();
     }
 
+    public String getToscaSubPath() {
+        return toscaSubPath;
+    }
+
+    public void setToscaSubPath(String toscaSubPath) {
+        this.toscaSubPath = toscaSubPath;
+    }
+
+    private String toscaSubPath;
+
     public PropertyDefinition(PropertyDataDefinition p) {
         super(p);
         getConstraints();
index d79c6db..a5c2b60 100644 (file)
@@ -25,6 +25,7 @@
             <div class="inner-cell-div" tooltip="{{property.name}}"><span>{{property.name}}</span></div>
         </div>
         <div class="table-cell" *ngIf="!canBeDeclared && !property.isChildOfListOrMap">
+            <checkbox *ngIf="nestedLevel != 1" [(checked)]="property.isSelected" [disabled]="property.isDisabled || readonly || property.mapKey == ''" (checkedChange)="toggleTosca.emit(property)" ></checkbox>
             <div class="inner-cell-div" tooltip="{{property.name}}"><span>{{property.name}}</span></div>
         </div> <!-- simple children of complex type within map or list -->
         <div class="table-cell map-entry" *ngIf="property.isChildOfListOrMap && propType == derivedPropertyTypes.MAP && !property.mapInlist"><!-- map left cell -->
@@ -41,7 +42,7 @@
         </div>
     </ng-container>
     <!-- RIGHT CELL OR FULL WIDTH CELL-->
-    <ng-container *ngIf="propType == derivedPropertyTypes.SIMPLE || property.isDeclared || property.isToscaFunction() || (property.isChildOfListOrMap && propType == derivedPropertyTypes.MAP && property.schema.property.isSimpleType)">
+    <ng-container *ngIf="propType == derivedPropertyTypes.SIMPLE || property.isDeclared || (property.isToscaFunction() && !property.isChildOfListOrMap) || (property.isChildOfListOrMap && propType == derivedPropertyTypes.MAP && property.schema.property.isSimpleType)">
         <div class="table-cell">
             <checkbox class="{{propType == derivedPropertyTypes.MAP ? 'inline-checkBox' : 'inline-checkBox-List'}}" *ngIf="(nestedLevel == 1 && property.isChildOfListOrMap && property.schema.property.isSimpleType)" [(checked)]="property.isSelected" [disabled]="property.isDisabled || readonly || property.mapKey == ''" (checkedChange)="toggleTosca.emit(property)" ></checkbox>
             <dynamic-element class="value-input"
             ></dynamic-element>
         </div>
     </ng-container>
-    <ng-container *ngIf="!isPropertyFEModel && propType != derivedPropertyTypes.SIMPLE && !property.isDeclared && !property.isToscaFunction()"> <!-- right cell for complex elements, or list complex -->
+    <ng-container *ngIf="!isPropertyFEModel && propType != derivedPropertyTypes.SIMPLE && !property.isDeclared && (!property.isToscaFunction() || (property.isToscaFunction() && property.isChildOfListOrMap && propType != derivedPropertyTypes.SIMPLE))"> <!-- right cell for complex elements, or list complex -->
         <div class="table-cell" *ngIf="propType == derivedPropertyTypes.COMPLEX">{{property.type | contentAfterLastDot }}</div>
         <div class="table-cell" *ngIf="propType == derivedPropertyTypes.MAP && !property.schema.property.isSimpleType">{{property.schema.property.type | contentAfterLastDot }}</div>
     </ng-container>
-    <ng-container *ngIf="isPropertyFEModel && (propType == derivedPropertyTypes.LIST || propType == derivedPropertyTypes.MAP) && !property.isDeclared && !property.isToscaFunction()"><!-- empty, full-width table cell - for PropertyFEModel of type list or map -->
+    <ng-container *ngIf="isPropertyFEModel && (propType == derivedPropertyTypes.LIST || propType == derivedPropertyTypes.MAP) && !property.isDeclared && (!property.isToscaFunction() || (property.isToscaFunction() && property.isChildOfListOrMap && propType != derivedPropertyTypes.SIMPLE))"><!-- empty, full-width table cell - for PropertyFEModel of type list or map -->
         <div class="table-cell empty"></div>
     </ng-container>
     <!-- ICONS: add, delete, and expand -->
-    <ng-container *ngIf="(!property.isDeclared && !property.isToscaFunction()) || (property.isToscaFunction() && property.isChildOfListOrMap && property.schema.property.isSimpleType)">
+    <ng-container *ngIf="(!property.isDeclared && !property.isToscaFunction()) || (property.isToscaFunction() && property.isChildOfListOrMap)">
             <a *ngIf="(propType == derivedPropertyTypes.LIST) && (!property.isChildOfListOrMap || property.mapInlist)" class="property-icon add-item" (click)="createNewChildProperty();" [ngClass]="{'disabled':readonly || preventInsertItem(property)}" [attr.data-tests-id]="'add-to-list-' + propertyTestsId">Add value to list</a>
             <a *ngIf="(propType == derivedPropertyTypes.MAP) && (!property.isChildOfListOrMap || property.mapInlist)" class="property-icon add-item" (click)="createNewChildProperty();" [ngClass]="{'disabled':readonly || preventInsertItem(property)}" [attr.data-tests-id]="'add-to-list-' + propertyTestsId">Add value to map</a>
             <span *ngIf="property.isChildOfListOrMap" (click)="deleteItem.emit(property);" class="property-icon sprite-new delete-item-icon" [ngClass]="{'disabled':readonly}" [attr.data-tests-id]="'delete-from-list-' + propertyTestsId"></span>
@@ -75,7 +76,7 @@
 
 </div>
 <!-- FLAT CHILDREN -->
-<div class="flat-children-container" *ngIf="isPropertyFEModel && !property.isDeclared && !property.isToscaFunction()">
+<div class="flat-children-container" *ngIf="isPropertyFEModel && !property.isDeclared && (!property.isToscaFunction() || (property.isToscaFunction() && property.isChildOfListOrMap && propType != derivedPropertyTypes.SIMPLE))">
     <ng-container *ngFor="let prop of property.flattenedChildren | filterChildProperties: expandedChildId; trackBy:prop?.propertiesName">
         <dynamic-property
             [selectedPropertyId]="selectedPropertyId"
index edcbd43..b1ceb93 100644 (file)
@@ -152,8 +152,22 @@ export class DynamicPropertyComponent {
     };
 
     createNewChildProperty = (): void => {
-       
-        let newProps: Array<DerivedFEProperty> = this.propertiesUtils.createListOrMapChildren(this.property, "", null);
+
+        let mapKeyValue = this.property instanceof DerivedFEProperty ? this.property.mapKey : "";
+        if (this.property.type == PROPERTY_TYPES.LIST && mapKeyValue === "") {
+            if(this.property.value != null) {
+                const valueJson = JSON.parse(this.property.value);
+                if(this.property instanceof PropertyFEModel && this.property.expandedChildPropertyId != null){
+                    let indexNumber = Number(Object.keys(valueJson).sort().reverse()[0]) + 1;
+                    mapKeyValue = indexNumber.toString();
+                }else{
+                    mapKeyValue = Object.keys(valueJson).sort().reverse()[0];
+                }
+            }else {
+                mapKeyValue = "0";
+            }
+        }
+        let newProps: Array<DerivedFEProperty> = this.propertiesUtils.createListOrMapChildren(this.property, mapKeyValue, null);
 
         this.propertiesUtils.assignFlattenedChildrenValues(this.property.valueObj, [newProps[0]], this.property.propertiesName);
         if (this.property instanceof PropertyFEModel) {
@@ -255,6 +269,11 @@ export class DynamicPropertyComponent {
         if (this.property instanceof PropertyFEModel) {
             let oldKey = childProp.getActualMapKey();
             this.property.childPropMapKeyUpdated(childProp, newMapKey);
+            this.property.flattenedChildren.forEach(tempDervObj => {
+                if (childProp.propertiesName === tempDervObj.parentName) {
+                    tempDervObj.mapKey = newMapKey;
+                }
+            });
             if (this.property.subPropertyToscaFunctions != null) {
                 this.property.subPropertyToscaFunctions.forEach((item : SubPropertyToscaFunction) => {
                     if(item.subPropertyPath[0] === oldKey){
index 2bf1b10..a347779 100644 (file)
@@ -46,7 +46,7 @@ import {ComponentServiceNg2} from "../../services/component-services/component.s
 import {TopologyTemplateService} from "../../services/component-services/topology-template.service";
 import {ComponentInstanceServiceNg2} from "../../services/component-instance-services/component-instance.service"
 import {KeysPipe} from 'app/ng2/pipes/keys.pipe';
-import {EVENTS, PROPERTY_TYPES, WorkspaceMode} from "../../../utils/constants";
+import {EVENTS, PROPERTY_TYPES, WorkspaceMode, PROPERTY_DATA} from "../../../utils/constants";
 import {EventListenerService} from "app/services/event-listener-service"
 import {HierarchyDisplayOptions} from "../../components/logic/hierarchy-navigtion/hierarchy-display-options";
 import {FilterPropertiesAssignmentComponent} from "../../components/logic/filter-properties-assignment/filter-properties-assignment.component";
@@ -587,21 +587,29 @@ export class PropertiesAssignmentComponent {
         if (checkedInstanceProperty instanceof PropertyDeclareAPIModel && (<PropertyDeclareAPIModel>checkedInstanceProperty).propertiesName){
             const propertiesNameArray = (<PropertyDeclareAPIModel>checkedInstanceProperty).propertiesName;
             const parts = propertiesNameArray.split("#");
-            const currentKey = (checkedInstanceProperty.type == PROPERTY_TYPES.MAP || checkedInstanceProperty.type == PROPERTY_TYPES.LIST) ? (<DerivedFEProperty>checkedInstanceProperty.input).mapKey : null;
+            let currentKey = [];
+            if (this.isListOrMap(checkedInstanceProperty.type)) {
+                currentKey.push((<DerivedFEProperty>checkedInstanceProperty.input).mapKey);
+                if (this.isComplexSchemaType(checkedInstanceProperty.schemaType)) {
+                    currentKey.push(parts.reverse()[0]);
+                }
+            }
             if (propertiesNameArray.length > 1){
-                const index = checkedInstanceProperty.subPropertyToscaFunctions.findIndex(existingSubPropertyToscaFunction => this.areEqual(existingSubPropertyToscaFunction.subPropertyPath, currentKey != null ? [currentKey] : parts.slice(1)));
+                const index = checkedInstanceProperty.subPropertyToscaFunctions.findIndex(existingSubPropertyToscaFunction => this.areEqual(existingSubPropertyToscaFunction.subPropertyPath, currentKey.length > 0 ? currentKey : parts.slice(1)));
                 checkedInstanceProperty.subPropertyToscaFunctions.splice(index, 1);
             }
-            if(currentValue !== null && currentKey !== null){
+            if(currentValue !== null && currentKey.length > 0){
                 let valueJson = JSON.parse(currentValue);
-                let tempValue = valueJson[currentKey];
-                delete valueJson[currentKey];
-                if (checkedInstanceProperty.type == PROPERTY_TYPES.LIST) {
-                    let listValue = [];
-                    valueJson.forEach(item => {
-                        if (item != null && item != '' && item != tempValue) {
-                            listValue.push(item);
-                        }
+                if(currentKey.length >1){
+                    let innerObj = valueJson[currentKey[0]];
+                    delete innerObj[currentKey[1]];
+                    valueJson[currentKey[0]] = innerObj;
+                }else{
+                    delete valueJson[currentKey[0]];
+                }
+                if (checkedInstanceProperty.type == PROPERTY_TYPES.LIST && currentKey.length == 1) {
+                    let listValue = valueJson.filter(function (item) {
+                        return item != null && item != '';
                     });
                     checkedInstanceProperty.value = JSON.stringify(listValue);
                 } else {
@@ -623,17 +631,23 @@ export class PropertiesAssignmentComponent {
         if (checkedProperty instanceof PropertyDeclareAPIModel && (<PropertyDeclareAPIModel>checkedProperty).propertiesName){
             const propertiesName = (<PropertyDeclareAPIModel>checkedProperty).propertiesName;
             const parts = propertiesName.split("#");
-            const currentKey = (checkedProperty.type == PROPERTY_TYPES.MAP || checkedProperty.type == PROPERTY_TYPES.LIST) ? (<DerivedFEProperty>checkedProperty.input).mapKey : null;
+            let currentKey = [];
+            if (this.isListOrMap(checkedProperty.type)) {
+                currentKey.push((<DerivedFEProperty>checkedProperty.input).mapKey);
+                if (this.isComplexSchemaType(checkedProperty.schemaType)) {
+                    currentKey.push(parts.reverse()[0]);
+                }
+            }
             if (checkedProperty.subPropertyToscaFunctions == null){
                 checkedProperty.subPropertyToscaFunctions = [];
             }
-            let subPropertyToscaFunction = checkedProperty.subPropertyToscaFunctions.find(existingSubPropertyToscaFunction => this.areEqual(existingSubPropertyToscaFunction.subPropertyPath, currentKey != null ? [currentKey] : parts.slice(1)));
+            let subPropertyToscaFunction = checkedProperty.subPropertyToscaFunctions.find(existingSubPropertyToscaFunction => this.areEqual(existingSubPropertyToscaFunction.subPropertyPath, currentKey.length > 0 ? currentKey : parts.slice(1)));
             if (!subPropertyToscaFunction){
                  subPropertyToscaFunction = new SubPropertyToscaFunction();
                  checkedProperty.subPropertyToscaFunctions.push(subPropertyToscaFunction);
             }
             subPropertyToscaFunction.toscaFunction = toscaFunction;
-            subPropertyToscaFunction.subPropertyPath = currentKey != null ? [currentKey] : parts.slice(1);
+            subPropertyToscaFunction.subPropertyPath = currentKey.length > 0 ? currentKey : parts.slice(1);
    
         } else {
             checkedProperty.subPropertyToscaFunctions = null;
@@ -648,6 +662,14 @@ export class PropertiesAssignmentComponent {
         }
     }
 
+    private isComplexSchemaType(propertyType: string): boolean {
+        return PROPERTY_DATA.SIMPLE_TYPES.indexOf(propertyType) === -1;
+    }
+
+    private isListOrMap(propertyType: string): boolean {
+        return PROPERTY_TYPES.MAP === propertyType || PROPERTY_TYPES.LIST === propertyType;
+    }
+
     private areEqual(array1: string[], array2: string[]): boolean {
         return array1.length === array2.length && array1.every(function(value, index) { return value === array2[index]})
     }
index 876fc8e..0b984ac 100644 (file)
@@ -108,9 +108,21 @@ export class PropertiesUtils {
         newProps.push(parentProp);
 
         if (!property.schema.property.isSimpleType) {
-            let additionalChildren:Array<DerivedFEProperty> = this.createFlattenedChildren(property.schema.property.type, parentProp.propertiesName);
+            let additionalChildren:Array<DerivedFEProperty> = this.createFlattenedChildren(property.schema.property.type, parentProp.propertiesName, key);
             this.assignFlattenedChildrenValues(parentProp.valueObj, additionalChildren, parentProp.propertiesName);
-            additionalChildren.forEach(prop => prop.canBeDeclared = false);
+            additionalChildren.forEach(prop => {
+                prop.canBeDeclared = false;
+                if (property.subPropertyToscaFunctions != null) {
+                    const subToscaFunctArray : SubPropertyToscaFunction[] = property.subPropertyToscaFunctions;
+                    subToscaFunctArray.forEach(subToscaFunct => {
+                        const keyArray : string[] = subToscaFunct.subPropertyPath;
+                        if (keyArray.length > 1 && prop.mapKey == keyArray[0] && prop.name == keyArray[1]) {
+                            prop.toscaFunction = subToscaFunct.toscaFunction;
+                        }
+                    });
+                    
+                }
+            });
             newProps.push(...additionalChildren);
         }
         return newProps;
@@ -119,10 +131,13 @@ export class PropertiesUtils {
     /**
      * Creates derivedFEProperties of a specified type and returns them.
      */
-    private createFlattenedChildren = (type: string, parentName: string):Array<DerivedFEProperty> => {
+    private createFlattenedChildren = (type: string, parentName: string, key: string):Array<DerivedFEProperty> => {
         let tempProps: Array<DerivedFEProperty> = [];
         let dataTypeObj: DataTypeModel = this.dataTypeService.getDataTypeByTypeName(type);
         this.dataTypeService.getDerivedDataTypeProperties(dataTypeObj, tempProps, parentName);
+        tempProps.forEach(tempDervObj => {
+            tempDervObj.mapKey = key;
+        });
         return _.sortBy(tempProps, ['propertiesName']);
     }
 
@@ -151,7 +166,7 @@ export class PropertiesUtils {
                     }
                 });
             } else if (property.derivedDataType === DerivedPropertyType.COMPLEX) {
-                property.flattenedChildren = this.createFlattenedChildren(property.type, property.name);
+                property.flattenedChildren = this.createFlattenedChildren(property.type, property.name, "");
                 this.assignFlattenedChildrenValues(property.valueObj, property.flattenedChildren, property.name);
                 this.setFlattenedChildernToscaFunction(property.subPropertyToscaFunctions, property.flattenedChildren, property.name);
                 property.flattenedChildren.forEach((childProp) => {
index 0198dfd..6b43cb0 100644 (file)
@@ -29,7 +29,7 @@ import {ToscaFunctionType} from "../../../../models/tosca-function-type.enum";
 import {ToscaGetFunctionValidationEvent} from "./tosca-get-function/tosca-get-function.component";
 import {ToscaFunction} from "../../../../models/tosca-function";
 import {ToscaConcatFunctionValidationEvent} from "./tosca-concat-function/tosca-concat-function.component";
-import {PROPERTY_TYPES} from "../../../../utils/constants";
+import {PROPERTY_TYPES, PROPERTY_DATA} from "../../../../utils/constants";
 import {YamlFunctionValidationEvent} from "./yaml-function/yaml-function.component";
 import {ToscaConcatFunction} from "../../../../models/tosca-concat-function";
 import {YamlFunction} from "../../../../models/yaml-function";
@@ -101,8 +101,14 @@ export class ToscaFunctionComponent implements OnInit, OnChanges {
            if (this.property instanceof PropertyDeclareAPIModel && this.property.subPropertyToscaFunctions && (<PropertyDeclareAPIModel> this.property).propertiesName){
                let propertiesPath = (<PropertyDeclareAPIModel> this.property).propertiesName.split("#");
             if (propertiesPath.length > 1){
-                let keyToFind = (this.property.type == PROPERTY_TYPES.MAP || this.property.type == PROPERTY_TYPES.LIST) ? [(<DerivedFEProperty>this.property.input).mapKey] : propertiesPath.slice(1);
-                let subPropertyToscaFunction = this.property.subPropertyToscaFunctions.find(subPropertyToscaFunction => this.areEqual(subPropertyToscaFunction.subPropertyPath, keyToFind !== null ? keyToFind : propertiesPath.slice(1)));
+                let keyToFind = [];
+                if (this.property.type == PROPERTY_TYPES.MAP || this.property.type == PROPERTY_TYPES.LIST) {
+                    keyToFind.push((<DerivedFEProperty>this.property.input).mapKey);
+                    if (PROPERTY_DATA.SIMPLE_TYPES.indexOf(this.property.schemaType) === -1) {
+                        keyToFind.push(propertiesPath.reverse()[0]);
+                    }
+                }
+                let subPropertyToscaFunction = this.property.subPropertyToscaFunctions.find(subPropertyToscaFunction => this.areEqual(subPropertyToscaFunction.subPropertyPath, keyToFind.length > 0 ? keyToFind : propertiesPath.slice(1)));
 
                 if (subPropertyToscaFunction){
                        this.toscaFunction = subPropertyToscaFunction.toscaFunction;
index 46541cf..84018fd 100644 (file)
@@ -261,7 +261,15 @@ export class ToscaGetFunctionComponent implements OnInit, OnChanges {
     }
 
     private propertyTypeToString() {
-           if (this.isSubProperty() && this.property.type != PROPERTY_TYPES.MAP && this.property.type != PROPERTY_TYPES.LIST){
+           if (this.isSubProperty()){
+            if (this.typeHasSchema(this.property.type) && this.property instanceof PropertyDeclareAPIModel && 
+                    (<PropertyDeclareAPIModel> this.property).input instanceof DerivedFEProperty) {
+                if(this.isComplexType(this.property.schemaType)){
+                    return this.property.input.type;
+                }else{
+                    return this.property.schema.property.type;
+                }
+            }
                return this.getType((<PropertyDeclareAPIModel>this.property).propertiesName.split("#").slice(1),  this.property.type);
         }
         if (this.property.schemaType) {
@@ -367,8 +375,12 @@ export class ToscaGetFunctionComponent implements OnInit, OnChanges {
 
     private hasSameType(property: PropertyBEModel | AttributeBEModel): boolean {
         if (this.typeHasSchema(this.property.type)) {
-            if ((this.property.type === PROPERTY_TYPES.MAP || this.property.type === PROPERTY_TYPES.LIST) && this.property instanceof PropertyDeclareAPIModel && (<PropertyDeclareAPIModel> this.property).input instanceof DerivedFEProperty) {
-                return property.type === this.property.schema.property.type;
+            if (this.property instanceof PropertyDeclareAPIModel && (<PropertyDeclareAPIModel> this.property).input instanceof DerivedFEProperty) {
+                if(this.isComplexType(this.property.schemaType)){
+                    return property.type === this.property.input.type;
+                }else{
+                    return property.type === this.property.schema.property.type;
+                }
             }
             if (!property.schema || !property.schema.property) {
                 return false;