Provide tosca function to List entries 80/132580/10
authorimamSidero <imam.hussain@est.tech>
Mon, 5 Dec 2022 14:13:39 +0000 (14:13 +0000)
committerVasyl Razinkov <vasyl.razinkov@est.tech>
Mon, 19 Dec 2022 17:36:36 +0000 (17:36 +0000)
Providing the capability to add tosca function as the List entries

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

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-ui/src/app/models/properties-inputs/derived-fe-property.ts
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.less
catalog-ui/src/app/ng2/components/logic/properties-table/dynamic-property/dynamic-property.component.ts
catalog-ui/src/app/ng2/components/logic/properties-table/properties-table.component.less
catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.page.component.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 9734a0a..1500074 100644 (file)
@@ -1374,6 +1374,7 @@ public class YamlTemplateParsingHandler {
 
     @SuppressWarnings("unchecked")
     private void fillInputsListRecursively(UploadPropInfo propertyDef, List<Object> propValueList) {
+        int index = 0;
         for (Object objValue : propValueList) {
             if (objValue instanceof Map) {
                 Map<String, Object> objMap = (Map<String, Object>) objValue;
@@ -1383,10 +1384,24 @@ public class YamlTemplateParsingHandler {
                     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++;
         }
     }
 
index e867d06..3797fb9 100644 (file)
@@ -43,6 +43,7 @@ import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.collections.MapUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.json.JSONArray;
 import org.json.JSONObject;
 import org.onap.sdc.tosca.datatypes.model.PropertyType;
 import org.openecomp.sdc.be.components.impl.exceptions.BusinessLogicException;
@@ -1979,13 +1980,20 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic {
                     toscaFunctionValidator.validate(property, containerComponent);
                     property.setValue(property.getToscaFunction().getValue());
                 }
-
-                if (CollectionUtils.isNotEmpty(property.getSubPropertyToscaFunctions())){
-                    final JSONObject jObject  = property.getValue() == null ? new JSONObject() : new JSONObject(property.getValue());
-                    property.getSubPropertyToscaFunctions().stream().forEach(subToscaFunction -> {
-                        setJsonObjectForSubProperty(jObject, subToscaFunction.getSubPropertyPath(), subToscaFunction.getToscaFunction().getValue());
-                    });
-                    property.setValue(jObject.toString());
+                if (CollectionUtils.isNotEmpty(property.getSubPropertyToscaFunctions())) {
+                    if (StringUtils.isNumeric(property.getSubPropertyToscaFunctions().iterator().next().getSubPropertyPath().get(0))) {
+                        final JSONArray jsonArray = property.getValue() == null ? new JSONArray() : new JSONArray(property.getValue());
+                        property.getSubPropertyToscaFunctions().stream().forEach(subToscaFunction -> {
+                            addE(jsonArray, subToscaFunction.getSubPropertyPath(), subToscaFunction.getToscaFunction().getValue());
+                        });
+                        property.setValue(jsonArray.toString());
+                    } else {
+                        final JSONObject jObject = property.getValue() == null ? new JSONObject() : new JSONObject(property.getValue());
+                        property.getSubPropertyToscaFunctions().stream().forEach(subToscaFunction -> {
+                            addE(jObject, subToscaFunction.getSubPropertyPath(), subToscaFunction.getToscaFunction().getValue());
+                        });
+                        property.setValue(jObject.toString());
+                    }
                 }
                 Either<String, ResponseFormat> updatedPropertyValue = updatePropertyObjectValue(property, containerComponent.getModel());
                 if (updatedPropertyValue.isRight()) {
@@ -2031,7 +2039,60 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic {
             graphLockOperation.unlockComponent(componentId, componentTypeEnum.getNodeType());
         }
     }
-    
+
+    private void addE(JSONArray jsonArray, List<String> path, String value) {
+        Object objectForPath = jsonArray.opt(Integer.parseInt(path.get(0)));
+        if (objectForPath == null) {
+            if (path.size() > 1) {
+                if (StringUtils.isNumeric(path.get(1))) {
+                    objectForPath = new JSONArray();
+                } else {
+                    objectForPath = new JSONObject();
+                }
+                jsonArray.put(Integer.parseInt(path.get(0)), objectForPath);
+            }
+        }
+
+        if (path.size() == 1) {
+            Object valueAsObject = new Yaml().loadAs(value, Object.class);
+            jsonArray.put(Integer.parseInt(path.get(0)), valueAsObject);
+        } else {
+            if (objectForPath instanceof JSONObject) {
+                addE((JSONObject)objectForPath, path.subList(1, path.size()), value);
+            } else {
+                addE((JSONArray)objectForPath, path.subList(1, path.size()), value);
+            }
+        }
+    }
+
+    private void addE(JSONObject jsonObject, List<String> path, String value) {
+
+        Object objectForPath = null;
+        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 (path.size() == 1) {
+            Object valueAsObject = new Yaml().loadAs(value, Object.class);
+            jsonObject.put(path.get(0), valueAsObject);
+        } else {
+            if (objectForPath instanceof JSONObject) {
+                addE((JSONObject)objectForPath, path.subList(1, path.size()), value);
+            } else {
+                addE((JSONArray)objectForPath, path.subList(1, path.size()), value);
+            }
+        }
+    }
+
     private void setJsonObjectForSubProperty(final JSONObject jObject, final List<String> path, String value) {
         if (path.size() == 1) {
             Object valueAsObject = new Yaml().loadAs(value, Object.class);
index 7d832c5..60d2726 100644 (file)
@@ -55,7 +55,7 @@ export class DerivedFEProperty extends PropertyBEModel {
             this.canBeDeclared = true; //defaults to true
         } else { //creating a direct child of list or map (ie. Item that can be deleted, with UUID instead of name)
             super(null);
-            if(property.type === PROPERTY_TYPES.MAP && property.subPropertyToscaFunctions != null){
+            if(property.subPropertyToscaFunctions != null){
                 property.subPropertyToscaFunctions.forEach((item : SubPropertyToscaFunction) => {
                     if(item.subPropertyPath[0] === key){
                         this.toscaFunction = item.toscaFunction;
@@ -69,7 +69,17 @@ export class DerivedFEProperty extends PropertyBEModel {
             this.propertiesName = parentName + '#' + this.name;
             
             if (property.type == PROPERTY_TYPES.LIST) {
-                this.mapKey = property.schema.property.type.split('.').pop();
+                if(property.value != null) {
+                    const valueJson = JSON.parse(property.value);
+                    if (key != '') {
+                        this.mapKey = key;
+                    }else{
+                        let indexNumber = Number(Object.keys(valueJson).sort().reverse()[0]) + 1;
+                        this.mapKey = indexNumber.toString();
+                    }
+                }else {
+                    this.mapKey = "0";
+                }
                 this.mapKeyError = null;
                 this.type = property.schema.property.type;
                 if (this.type == PROPERTY_TYPES.MAP){
index 2431a70..d79c6db 100644 (file)
@@ -43,7 +43,7 @@
     <!-- 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)">
         <div class="table-cell">
-            <checkbox class="inline-checkBox" *ngIf="(nestedLevel == 1 && property.isChildOfListOrMap && propType == derivedPropertyTypes.MAP && property.schema.property.isSimpleType)" [(checked)]="property.isSelected" [disabled]="property.isDisabled || readonly || property.mapKey == ''" (checkedChange)="toggleTosca.emit(property)" ></checkbox>
+            <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"
                 pattern="validationUtils.getValidationPattern(property.type)"
                 [value]="(property.isDeclared || property.isToscaFunction()) ? property.value : property.valueObj"
@@ -66,7 +66,7 @@
         <div class="table-cell empty"></div>
     </ng-container>
     <!-- ICONS: add, delete, and expand -->
-    <ng-container *ngIf="(!property.isDeclared && !property.isToscaFunction()) || (property.isToscaFunction() && property.isChildOfListOrMap && propType == derivedPropertyTypes.MAP && property.schema.property.isSimpleType)">
+    <ng-container *ngIf="(!property.isDeclared && !property.isToscaFunction()) || (property.isToscaFunction() && property.isChildOfListOrMap && property.schema.property.isSimpleType)">
             <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>
index 4d2cc89..6b0f445 100644 (file)
 }
 .inline-checkBox {
     float: left;
-    width: 7%;
+    width: 9%;
     margin-left: -5px;
     margin-top: 4px;
 }
+.inline-checkBox-List {
+    float: left;
+    width: 5%;
+    margin-left: 0;
+    margin-top: 4px;
+}
index 57b991b..edcbd43 100644 (file)
@@ -171,7 +171,6 @@ export class DynamicPropertyComponent {
             this.expandChildById(newProps[0].propertiesName);
 
             this.updateMapKeyValueOnMainParent(newProps);
-            this.emitter.emit();
         }
     }
 
@@ -219,23 +218,22 @@ export class DynamicPropertyComponent {
             if (!itemParent) {
                 return;
             }
-
+            const oldKey = item.getActualMapKey();
+            if (this.property.subPropertyToscaFunctions !== null) {
+                let tempSubToscaFunction: SubPropertyToscaFunction[] = [];
+                this.property.subPropertyToscaFunctions.forEach((item : SubPropertyToscaFunction, index) => {
+                    if(item.subPropertyPath[0] != oldKey){
+                        tempSubToscaFunction.push(item);
+                    }
+                });
+                this.property.subPropertyToscaFunctions = tempSubToscaFunction;
+            }
             if (item.derivedDataType == DerivedPropertyType.MAP && !item.mapInlist) {
-                const oldKey = item.getActualMapKey();
                 delete itemParent.valueObj[oldKey];
                 if (itemParent instanceof PropertyFEModel) {
                     delete itemParent.valueObjValidation[oldKey];
                     itemParent.valueObjIsValid = itemParent.calculateValueObjIsValid();
                 }
-                if (this.property.subPropertyToscaFunctions !== null) {
-                    let tempSubToscaFunction: SubPropertyToscaFunction[] = [];
-                    this.property.subPropertyToscaFunctions.forEach((item : SubPropertyToscaFunction, index) => {
-                        if(item.subPropertyPath[0] != oldKey){
-                            tempSubToscaFunction.push(item);
-                        }
-                    });
-                    this.property.subPropertyToscaFunctions = tempSubToscaFunction;
-                }
                 this.property.childPropMapKeyUpdated(item, null);  // remove map key
             } else {
                 const itemIndex: number = this.property.flattenedChildren.filter(prop => prop.parentName == item.parentName).map(prop => prop.propertiesName).indexOf(item.propertiesName);
index 8c2c6ce..b5abcb3 100644 (file)
@@ -2,7 +2,7 @@
 @import '../../../../../assets/styles/sprite';
 @smaller-screen: ~"only screen and (max-width: 1580px)";
 
-:host /deep/ input { width:100%;}
+:host /deep/ input { width:96%;}
 
 .properties-table {
     display:flex;
index 767acb4..2bf1b10 100644 (file)
@@ -580,22 +580,33 @@ export class PropertiesAssignmentComponent {
 
     private clearCheckedInstancePropertyValue() {
         const checkedInstanceProperty: PropertyBEModel = this.buildCheckedInstanceProperty();
-        let currentValue = checkedInstanceProperty.value;
+        const currentValue : any = checkedInstanceProperty.value;
         checkedInstanceProperty.getInputValues = null;
         checkedInstanceProperty.value = null;
         checkedInstanceProperty.toscaFunction = null;
         if (checkedInstanceProperty instanceof PropertyDeclareAPIModel && (<PropertyDeclareAPIModel>checkedInstanceProperty).propertiesName){
             const propertiesNameArray = (<PropertyDeclareAPIModel>checkedInstanceProperty).propertiesName;
             const parts = propertiesNameArray.split("#");
-            const currentKey = checkedInstanceProperty.type === PROPERTY_TYPES.MAP ? (<DerivedFEProperty>checkedInstanceProperty.input).mapKey : null;
+            const currentKey = (checkedInstanceProperty.type == PROPERTY_TYPES.MAP || checkedInstanceProperty.type == PROPERTY_TYPES.LIST) ? (<DerivedFEProperty>checkedInstanceProperty.input).mapKey : null;
             if (propertiesNameArray.length > 1){
                 const index = checkedInstanceProperty.subPropertyToscaFunctions.findIndex(existingSubPropertyToscaFunction => this.areEqual(existingSubPropertyToscaFunction.subPropertyPath, currentKey != null ? [currentKey] : parts.slice(1)));
                 checkedInstanceProperty.subPropertyToscaFunctions.splice(index, 1);
             }
             if(currentValue !== null && currentKey !== null){
                 let valueJson = JSON.parse(currentValue);
+                let tempValue = valueJson[currentKey];
                 delete valueJson[currentKey];
-                checkedInstanceProperty.value = JSON.stringify(valueJson);
+                if (checkedInstanceProperty.type == PROPERTY_TYPES.LIST) {
+                    let listValue = [];
+                    valueJson.forEach(item => {
+                        if (item != null && item != '' && item != tempValue) {
+                            listValue.push(item);
+                        }
+                    });
+                    checkedInstanceProperty.value = JSON.stringify(listValue);
+                } else {
+                    checkedInstanceProperty.value = JSON.stringify(valueJson);
+                }
             }
         }
         if (this.selectedInstanceData instanceof ComponentInstance) {
@@ -612,7 +623,7 @@ 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 ? (<DerivedFEProperty>checkedProperty.input).mapKey : null;
+            const currentKey = (checkedProperty.type == PROPERTY_TYPES.MAP || checkedProperty.type == PROPERTY_TYPES.LIST) ? (<DerivedFEProperty>checkedProperty.input).mapKey : null;
             if (checkedProperty.subPropertyToscaFunctions == null){
                 checkedProperty.subPropertyToscaFunctions = [];
             }
index bc73796..0198dfd 100644 (file)
@@ -101,7 +101,7 @@ 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 ? [(<DerivedFEProperty>this.property.input).mapKey] : propertiesPath.slice(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)));
 
                 if (subPropertyToscaFunction){
index 0757e3d..46541cf 100644 (file)
@@ -261,7 +261,7 @@ export class ToscaGetFunctionComponent implements OnInit, OnChanges {
     }
 
     private propertyTypeToString() {
-           if (this.isSubProperty() && this.property.type != PROPERTY_TYPES.MAP){
+           if (this.isSubProperty() && this.property.type != PROPERTY_TYPES.MAP && this.property.type != PROPERTY_TYPES.LIST){
                return this.getType((<PropertyDeclareAPIModel>this.property).propertiesName.split("#").slice(1),  this.property.type);
         }
         if (this.property.schemaType) {
@@ -367,7 +367,7 @@ 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 instanceof PropertyDeclareAPIModel && (<PropertyDeclareAPIModel> this.property).input instanceof DerivedFEProperty){
+            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 (!property.schema || !property.schema.property) {