From e3f5545168163fdbf0d83314ee9dd51983e4bcc8 Mon Sep 17 00:00:00 2001 From: imamSidero Date: Thu, 18 May 2023 17:56:32 +0100 Subject: [PATCH] Provide index token to tosca function for nested lists Index token capability is provided in tosca function for all nested levels of list and custom types Issue-ID: SDC-4505 Signed-off-by: Imam hussain Change-Id: If21c0078e0d17c44b5a31b00d6fac3e18ff6831d --- .../csar/ToscaFunctionYamlParsingHandler.java | 54 ++++-- .../impl/ComponentInstanceBusinessLogic.java | 2 +- .../validation/ToscaFunctionValidatorImpl.java | 2 +- .../validation/ToscaFunctionValidatorImplTest.java | 2 +- catalog-ui/src/app/models/tosca-get-function.ts | 12 +- .../dynamic-property.component.html | 2 +- .../tosca-get-function.component.html | 10 +- .../tosca-get-function.component.ts | 215 +++++++++++++++------ .../elements/ToscaFunctionJsonDeserializer.java | 38 ++-- .../elements/ToscaGetFunctionDataDefinition.java | 27 +-- .../ToscaGetFunctionDataDefinitionTest.java | 2 + 11 files changed, 261 insertions(+), 105 deletions(-) diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/ToscaFunctionYamlParsingHandler.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/ToscaFunctionYamlParsingHandler.java index 80608a82db..40604322d6 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/ToscaFunctionYamlParsingHandler.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/ToscaFunctionYamlParsingHandler.java @@ -21,6 +21,7 @@ package org.openecomp.sdc.be.components.csar; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -28,7 +29,6 @@ import java.util.Objects; import java.util.Optional; import java.util.stream.Collectors; import java.util.stream.Stream; - import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.openecomp.sdc.be.config.Configuration; @@ -77,13 +77,27 @@ public class ToscaFunctionYamlParsingHandler { toscaGetFunction.setSourceName(propertySourceType); } List propertySourceIndex = functionParameters.subList(1, functionParameters.size()); - String toscaIndexValue = propertySourceIndex.get((propertySourceIndex.size() - 1)); - if (propertySourceIndex.size() > 1 && (toscaIndexValue.equalsIgnoreCase("INDEX") || StringUtils.isNumeric(toscaIndexValue))) { - toscaGetFunction.setPropertyPathFromSource(propertySourceIndex.subList(0, (propertySourceIndex.size() - 1))); - toscaGetFunction.setToscaIndex(toscaIndexValue); - } else { - toscaGetFunction.setPropertyPathFromSource(propertySourceIndex); + List propertySourcePath = new ArrayList<>(); + propertySourcePath.add((String)propertySourceIndex.get(0)); + if (propertySourceIndex.size() > 1 ) { + List indexParsedList = new ArrayList(); + List indexObjectList = propertySourceIndex.subList(1,propertySourceIndex.size()); + boolean loopFlag = true; + for (String indexValue : indexObjectList) { + if (!indexValue.equalsIgnoreCase("INDEX") && !StringUtils.isNumeric(indexValue) && loopFlag) { + propertySourcePath.add(indexValue); + } else { + loopFlag = false; + if (StringUtils.isNumeric(indexValue)) { + indexParsedList.add(Integer.parseInt(indexValue)); + } else { + indexParsedList.add(indexValue); + } + } + } + toscaGetFunction.setToscaIndexList(indexParsedList); } + toscaGetFunction.setPropertyPathFromSource(propertySourcePath); final String propertyName = toscaGetFunction.getPropertyPathFromSource().get(toscaGetFunction.getPropertyPathFromSource().size() - 1); toscaGetFunction.setPropertyName(propertyName); return Optional.of(toscaGetFunction); @@ -108,13 +122,27 @@ public class ToscaFunctionYamlParsingHandler { } catch (final ClassCastException ignored) { return Optional.empty(); } - String toscaIndexValue = functionParameters.get((functionParameters.size() - 1)); - if (functionParameters.size() > 1 && (toscaIndexValue.equalsIgnoreCase("INDEX") || StringUtils.isNumeric(toscaIndexValue))) { - toscaGetFunction.setPropertyPathFromSource(functionParameters.subList(0, (functionParameters.size() - 1))); - toscaGetFunction.setToscaIndex(toscaIndexValue); - } else { - toscaGetFunction.setPropertyPathFromSource(functionParameters); + List propertySourcePath = new ArrayList<>(); + propertySourcePath.add((String)functionParameters.get(0)); + if (functionParameters.size() > 1 ) { + List indexParsedList = new ArrayList(); + List indexObjectList = functionParameters.subList(1,functionParameters.size()); + boolean loopFlag = true; + for (String indexValue : indexObjectList) { + if (!indexValue.equalsIgnoreCase("INDEX") && !StringUtils.isNumeric(indexValue) && loopFlag) { + propertySourcePath.add(indexValue); + } else { + loopFlag = false; + if (StringUtils.isNumeric(indexValue)) { + indexParsedList.add(Integer.parseInt(indexValue)); + } else { + indexParsedList.add(indexValue); + } + } + } + toscaGetFunction.setToscaIndexList(indexParsedList); } + toscaGetFunction.setPropertyPathFromSource(propertySourcePath); } final String propertyName = toscaGetFunction.getPropertyPathFromSource().get(toscaGetFunction.getPropertyPathFromSource().size() - 1); toscaGetFunction.setPropertyName(propertyName); diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogic.java index 16ec9ade96..c6007a3608 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogic.java @@ -2547,7 +2547,7 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { throw ToscaGetFunctionExceptionSupplier .propertyTypeDiverge(toscaGetFunction.getType(), referredProperty.getType(), property.getType()).get(); } - if (PropertyType.typeHasSchema(referredProperty.getType()) && !referredProperty.getSchemaType().equals(property.getType()) && !referredProperty.getSchemaType().equals(property.getSchemaType())) { + if (PropertyType.typeHasSchema(referredProperty.getType()) && !referredProperty.getSchemaType().equals(property.getType()) && !"list".equalsIgnoreCase(referredProperty.getType()) && !referredProperty.getSchemaType().equals(property.getSchemaType())) { throw ToscaGetFunctionExceptionSupplier .propertySchemaDiverge(toscaGetFunction.getType(), referredProperty.getSchemaType(), property.getSchemaType()).get(); } diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/validation/ToscaFunctionValidatorImpl.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/validation/ToscaFunctionValidatorImpl.java index 1e485d9b27..b76ae596a1 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/validation/ToscaFunctionValidatorImpl.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/validation/ToscaFunctionValidatorImpl.java @@ -133,7 +133,7 @@ public class ToscaFunctionValidatorImpl implements ToscaFunctionValidator { throw ToscaGetFunctionExceptionSupplier .propertyTypeDiverge(toscaGetFunction.getType(), referredProperty.getType(), property.getType()).get(); } - if (PropertyType.typeHasSchema(referredProperty.getType()) && !referredProperty.getSchemaType().equals(property.getType()) && !referredProperty.getSchemaType().equals(property.getSchemaType())) { + if (PropertyType.typeHasSchema(referredProperty.getType()) && !referredProperty.getSchemaType().equals(property.getType()) && !"list".equalsIgnoreCase(referredProperty.getType()) && !referredProperty.getSchemaType().equals(property.getSchemaType())) { throw ToscaGetFunctionExceptionSupplier .propertySchemaDiverge(toscaGetFunction.getType(), referredProperty.getSchemaType(), property.getSchemaType()).get(); } diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/validation/ToscaFunctionValidatorImplTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/validation/ToscaFunctionValidatorImplTest.java index 3b86d9db78..5ff31ba667 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/validation/ToscaFunctionValidatorImplTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/validation/ToscaFunctionValidatorImplTest.java @@ -283,7 +283,7 @@ class ToscaFunctionValidatorImplTest { final String inputId = String.format("%s.%s", containerComponentId, inputName); final String propertyName = "getInputProperty"; final String propertyId = String.format("%s.%s", containerComponentId, propertyName); - final String propertyType = "list"; + final String propertyType = "map"; final ComponentInstanceProperty propertyGetInput = createComponentInstanceProperty( propertyId, "getInputProperty", diff --git a/catalog-ui/src/app/models/tosca-get-function.ts b/catalog-ui/src/app/models/tosca-get-function.ts index 3bb207700b..67d9b0a836 100644 --- a/catalog-ui/src/app/models/tosca-get-function.ts +++ b/catalog-ui/src/app/models/tosca-get-function.ts @@ -35,7 +35,7 @@ export class ToscaGetFunction implements ToscaFunction, ToscaFunctionParameter { functionType: ToscaGetFunctionType; propertyPathFromSource: Array; value: any; - toscaIndex: string; + toscaIndexList: Array; constructor(toscaGetFunction?: ToscaGetFunction) { if (!toscaGetFunction) { @@ -49,7 +49,7 @@ export class ToscaGetFunction implements ToscaFunction, ToscaFunctionParameter { this.sourceUniqueId = toscaGetFunction.sourceUniqueId; this.sourceName = toscaGetFunction.sourceName; this.functionType = toscaGetFunction.functionType; - this.toscaIndex = toscaGetFunction.toscaIndex; + this.toscaIndexList = toscaGetFunction.toscaIndexList; if (toscaGetFunction.propertyPathFromSource) { this.propertyPathFromSource = [...toscaGetFunction.propertyPathFromSource]; } @@ -71,20 +71,20 @@ export class ToscaGetFunction implements ToscaFunction, ToscaFunctionParameter { private buildGetInputFunctionValue(): Object { if (this.propertyPathFromSource.length === 1) { - return {[this.functionType.toLowerCase()]: [this.propertyPathFromSource[0], this.toscaIndex]}; + return {[this.functionType.toLowerCase()]: [this.propertyPathFromSource[0], this.toscaIndexList]}; } - return {[this.functionType.toLowerCase()]: [this.propertyPathFromSource, this.toscaIndex]}; + return {[this.functionType.toLowerCase()]: [this.propertyPathFromSource, this.toscaIndexList]}; } private buildFunctionValueWithPropertySource(): Object { if (this.propertySource == PropertySource.SELF) { return { - [this.functionType.toLowerCase()]: [PropertySource.SELF, ...this.propertyPathFromSource, this.toscaIndex] + [this.functionType.toLowerCase()]: [PropertySource.SELF, ...this.propertyPathFromSource, this.toscaIndexList] }; } if (this.propertySource == PropertySource.INSTANCE) { return { - [this.functionType.toLowerCase()]: [this.sourceName, ...this.propertyPathFromSource,this.toscaIndex] + [this.functionType.toLowerCase()]: [this.sourceName, ...this.propertyPathFromSource,this.toscaIndexList] }; } } diff --git a/catalog-ui/src/app/ng2/components/logic/properties-table/dynamic-property/dynamic-property.component.html b/catalog-ui/src/app/ng2/components/logic/properties-table/dynamic-property/dynamic-property.component.html index c4a3893423..24d622fbe6 100644 --- a/catalog-ui/src/app/ng2/components/logic/properties-table/dynamic-property/dynamic-property.component.html +++ b/catalog-ui/src/app/ng2/components/logic/properties-table/dynamic-property/dynamic-property.component.html @@ -44,7 +44,7 @@
- + - -
{{dropDownErrorMsg}}
+
+ + + + +
diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-get-function/tosca-get-function.component.ts b/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-get-function/tosca-get-function.component.ts index 1b0a1a34ee..7987ba26cf 100644 --- a/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-get-function/tosca-get-function.component.ts +++ b/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-get-function/tosca-get-function.component.ts @@ -53,8 +53,7 @@ export class ToscaGetFunctionComponent implements OnInit, OnChanges { formGroup: FormGroup = new FormGroup({ 'selectedProperty': new FormControl(undefined, Validators.required), - 'propertySource': new FormControl(undefined, Validators.required), - 'toscaIndex' : new FormControl(undefined) + 'propertySource': new FormControl(undefined, Validators.required) }); isLoading: boolean = false; @@ -63,7 +62,7 @@ export class ToscaGetFunctionComponent implements OnInit, OnChanges { instanceNameAndIdMap: Map = new Map(); dropdownValuesLabel: string; dropDownErrorMsg: string; - toscaIndexFlag: boolean = false; + indexListValues:Array; private isInitialized: boolean = false; private componentMetadata: ComponentMetadata; @@ -77,23 +76,9 @@ export class ToscaGetFunctionComponent implements OnInit, OnChanges { ngOnInit(): void { this.componentMetadata = this.workspaceService.metadata; + this.indexListValues = []; this.formGroup.valueChanges.subscribe(() => { - if (!this.isInitialized) { - return; - } - let formGroupStatus : boolean = this.formGroup.valid; - const selectedProperty: PropertyDropdownValue = this.formGroup.value.selectedProperty; - if (selectedProperty != null && selectedProperty.isList && formGroupStatus - && (this.toscaIndex.value == null || this.toscaIndex.value == '')) { - formGroupStatus = false; - } - this.onValidityChange.emit({ - isValid: formGroupStatus, - toscaGetFunction: this.formGroup.valid ? this.buildGetFunctionFromForm() : undefined - }); - if (this.formGroup.valid) { - this.onValidFunction.emit(this.buildGetFunctionFromForm()); - } + this.formValidation(); }); this.loadPropertySourceDropdown(); this.loadPropertyDropdownLabel(); @@ -135,15 +120,36 @@ export class ToscaGetFunctionComponent implements OnInit, OnChanges { this.loadPropertyDropdown(() => { this.selectedProperty .setValue(this.propertyDropdownList.find(property => property.propertyName === this.toscaGetFunction.propertyName)); + if (this.toscaGetFunction.toscaIndexList.length > 0) { + let tempSelectedProperty : PropertyDropdownValue = this.selectedProperty.value; + this.toscaGetFunction.toscaIndexList.forEach((indexValue: string, index) => { + let tempIndexFlag = false; + let tempNestedFlag = false; + let tempIndexValue = "0"; + let tempIndexProperty = tempSelectedProperty; + let subPropertyDropdownList : Array = []; + if (index%2 == 0) { + tempIndexFlag = true; + tempIndexValue = indexValue; + tempSelectedProperty = null; + if (this.toscaGetFunction.toscaIndexList[index+1]) { + tempNestedFlag = true; + if (tempIndexProperty.schemaType != null) { + const dataTypeFound: DataTypeModel = this.dataTypeService.getDataTypeByModelAndTypeName(this.componentMetadata.model, tempIndexProperty.schemaType); + this.addPropertiesToDropdown(dataTypeFound.properties, subPropertyDropdownList); + tempSelectedProperty = subPropertyDropdownList.find(property => property.propertyName === this.toscaGetFunction.toscaIndexList[index+1]) + } + } + let tempIndexValueMap : ToscaIndexObject = {indexFlag : tempIndexFlag, nestedFlag : tempNestedFlag, indexValue: tempIndexValue, indexProperty: tempSelectedProperty, subPropertyArray: subPropertyDropdownList}; + this.indexListValues.push(tempIndexValueMap); + } + }); + } subscriber.next(); }); } else { subscriber.next(); } - if (this.toscaGetFunction.toscaIndex != null) { - this.toscaIndexFlag = true; - this.toscaIndex.setValue(this.toscaGetFunction.toscaIndex); - } }); } @@ -166,8 +172,16 @@ export class ToscaGetFunctionComponent implements OnInit, OnChanges { toscaGetFunction.propertyUniqueId = selectedProperty.propertyId; toscaGetFunction.propertyName = selectedProperty.propertyName; toscaGetFunction.propertyPathFromSource = selectedProperty.propertyPath; - toscaGetFunction.toscaIndex = this.toscaIndex.value; - + if (this.indexListValues.length > 0) { + let indexAndProperty : Array = []; + this.indexListValues.forEach((indexObject : ToscaIndexObject) => { + indexAndProperty.push(indexObject.indexValue); + if(indexObject.nestedFlag && indexObject.indexProperty != null) { + indexAndProperty.push(indexObject.indexProperty.propertyName); + } + }); + toscaGetFunction.toscaIndexList = indexAndProperty; + } return toscaGetFunction; } @@ -199,6 +213,33 @@ export class ToscaGetFunctionComponent implements OnInit, OnChanges { }); } + private formValidation(): void { + if (!this.isInitialized) { + return; + } + let formGroupStatus : boolean = this.formGroup.valid; + const selectedProperty: PropertyDropdownValue = this.formGroup.value.selectedProperty; + if (selectedProperty != null && selectedProperty.isList && formGroupStatus && this.indexListValues.length > 0) { + this.indexListValues.forEach((indexObject : ToscaIndexObject, index) => { + if (indexObject.indexValue == null) { + formGroupStatus = false; + return; + } + if (indexObject.nestedFlag && indexObject.indexProperty == null) { + formGroupStatus = false; + return; + } + }); + } + this.onValidityChange.emit({ + isValid: formGroupStatus, + toscaGetFunction: this.formGroup.valid ? this.buildGetFunctionFromForm() : undefined + }); + if (this.formGroup.valid) { + this.onValidFunction.emit(this.buildGetFunctionFromForm()); + } + } + private loadPropertyDropdown(onComplete?: () => any): void { this.loadPropertyDropdownLabel(); this.loadPropertyDropdownValues(onComplete); @@ -232,7 +273,7 @@ export class ToscaGetFunctionComponent implements OnInit, OnChanges { private resetPropertyDropdown(): void { this.dropDownErrorMsg = undefined; this.selectedProperty.reset(); - this.toscaIndex.reset(); + this.indexListValues = []; this.propertyDropdownList = []; } @@ -246,7 +287,7 @@ export class ToscaGetFunctionComponent implements OnInit, OnChanges { this.dropDownErrorMsg = this.translateService.translate(msgCode, {type: this.overridingType != undefined ? this.overridingType : this.propertyTypeToString()}); return; } - this.addPropertiesToDropdown(properties); + this.addPropertiesToDropdown(properties, this.propertyDropdownList); if (this.propertyDropdownList.length == 0) { const msgCode = this.getNotFoundMsgCode(); this.dropDownErrorMsg = this.translateService.translate(msgCode, {type: this.overridingType != undefined ? this.overridingType : this.propertyTypeToString()}); @@ -359,12 +400,12 @@ export class ToscaGetFunctionComponent implements OnInit, OnChanges { ); } - private addPropertyToDropdown(propertyDropdownValue: PropertyDropdownValue): void { - this.propertyDropdownList.push(propertyDropdownValue); - this.propertyDropdownList.sort((a, b) => a.propertyLabel.localeCompare(b.propertyLabel)); + private addPropertyToDropdown(propertyDropdownValue: PropertyDropdownValue, propertyList: Array): void { + propertyList.push(propertyDropdownValue); + propertyList.sort((a, b) => a.propertyLabel.localeCompare(b.propertyLabel)); } - private addPropertiesToDropdown(properties: Array): void { + private addPropertiesToDropdown(properties: Array, propertyList: Array): void { for (const property of properties) { if (this.hasSameType(property)) { this.addPropertyToDropdown({ @@ -372,15 +413,16 @@ export class ToscaGetFunctionComponent implements OnInit, OnChanges { propertyId: property.uniqueId, propertyLabel: property.name, propertyPath: [property.name], - isList: property.type === PROPERTY_TYPES.LIST - }); + isList: property.type === PROPERTY_TYPES.LIST, + schemaType: (property.type === PROPERTY_TYPES.LIST && this.isComplexType(property.schema.property.type)) ? property.schema.property.type : null + },propertyList); } else if (this.isComplexType(property.type)) { - this.fillPropertyDropdownWithMatchingChildProperties(property); + this.fillPropertyDropdownWithMatchingChildProperties(property,propertyList); } } } - private fillPropertyDropdownWithMatchingChildProperties(inputProperty: PropertyBEModel | AttributeBEModel, + private fillPropertyDropdownWithMatchingChildProperties(inputProperty: PropertyBEModel | AttributeBEModel, propertyList: Array, parentPropertyList: Array = []): void { const dataTypeFound: DataTypeModel = this.dataTypeService.getDataTypeByModelAndTypeName(this.componentMetadata.model, inputProperty.type); if (!dataTypeFound || !dataTypeFound.properties) { @@ -394,10 +436,11 @@ export class ToscaGetFunctionComponent implements OnInit, OnChanges { propertyId: parentPropertyList[0].uniqueId, propertyLabel: parentPropertyList.map(property => property.name).join('->') + '->' + dataTypeProperty.name, propertyPath: [...parentPropertyList.map(property => property.name), dataTypeProperty.name], - isList : dataTypeProperty.type === PROPERTY_TYPES.LIST - }); + isList : dataTypeProperty.type === PROPERTY_TYPES.LIST, + schemaType: (dataTypeProperty.type === PROPERTY_TYPES.LIST && this.isComplexType(dataTypeProperty.schema.property.type)) ? dataTypeProperty.schema.property.type : null + }, propertyList); } else if (this.isComplexType(dataTypeProperty.type)) { - this.fillPropertyDropdownWithMatchingChildProperties(dataTypeProperty, [...parentPropertyList]) + this.fillPropertyDropdownWithMatchingChildProperties(dataTypeProperty, propertyList, [...parentPropertyList]) } }); } @@ -409,8 +452,19 @@ export class ToscaGetFunctionComponent implements OnInit, OnChanges { if (this.property.type === PROPERTY_TYPES.ANY) { return true; } - let validPropertyType = property.type; - let validPropertyTypeSchema = property.schemaType; + let validPropertyType = (this.property.type != PROPERTY_TYPES.LIST && property.type === PROPERTY_TYPES.LIST) ? property.schema.property.type : property.type; + if (this.property.type != PROPERTY_TYPES.LIST && property.type === PROPERTY_TYPES.LIST && this.isComplexType(validPropertyType)) { + let returnFlag : boolean = false; + const dataTypeFound: DataTypeModel = this.dataTypeService.getDataTypeByModelAndTypeName(this.componentMetadata.model, validPropertyType); + if (dataTypeFound && dataTypeFound.properties) { + dataTypeFound.properties.forEach(dataTypeProperty => { + if (this.hasSameType(dataTypeProperty)) { + returnFlag = true; + } + }); + } + return returnFlag; + } if (this.typeHasSchema(this.property.type)) { if ((this.property instanceof PropertyDeclareAPIModel && ( this.property).input instanceof DerivedFEProperty) || this.compositionMap) { let childObject : DerivedFEProperty = (( this.property).input); @@ -421,13 +475,13 @@ export class ToscaGetFunctionComponent implements OnInit, OnChanges { } return validPropertyType === childObject.type; }else{ - return validPropertyType === this.property.schemaType; + return validPropertyType === this.property.schema.property.type; } } if (!property.schema || !property.schema.property) { return false; } - return validPropertyType === this.property.type && this.property.schemaType === validPropertyTypeSchema; + return validPropertyType === this.property.type && this.property.schema.property.type === property.schema.property.type; } if (this.property.schema.property.isDataType && this.property instanceof PropertyDeclareAPIModel && (this.property).propertiesName){ let typeToMatch = ( this.property).input.type; @@ -438,7 +492,7 @@ export class ToscaGetFunctionComponent implements OnInit, OnChanges { return validPropertyType === typeToMatch; } - return validPropertyType === this.property.type || (validPropertyType === PROPERTY_TYPES.LIST && validPropertyTypeSchema === this.property.type); + return validPropertyType === this.property.type; } private getType(propertyPath:string[], type: string): string { @@ -488,7 +542,7 @@ export class ToscaGetFunctionComponent implements OnInit, OnChanges { onPropertySourceChange(): void { this.selectedProperty.reset(); - this.toscaIndex.reset(); + this.indexListValues = []; if (!this.functionType || !this.propertySource.valid) { return; } @@ -496,22 +550,66 @@ export class ToscaGetFunctionComponent implements OnInit, OnChanges { } onPropertyValueChange(): void { - this.toscaIndexFlag = false; - this.toscaIndex.reset(); + let toscaIndexFlag = false; + let nestedToscaFlag = false; + this.indexListValues = []; + let subPropertyDropdownList : Array = []; const selectedProperty: PropertyDropdownValue = this.selectedProperty.value; - if (selectedProperty.isList && this.property.type != PROPERTY_TYPES.LIST) { - this.toscaIndexFlag = true; + if (selectedProperty.isList) { + toscaIndexFlag = true; + if (selectedProperty.schemaType != null) { + nestedToscaFlag = true; + const dataTypeFound: DataTypeModel = this.dataTypeService.getDataTypeByModelAndTypeName(this.componentMetadata.model, selectedProperty.schemaType); + this.addPropertiesToDropdown(dataTypeFound.properties, subPropertyDropdownList); + } + } + if (toscaIndexFlag || nestedToscaFlag) { + let indexValueMap : ToscaIndexObject = {indexFlag : toscaIndexFlag, nestedFlag : nestedToscaFlag, indexValue: "0", indexProperty: null, subPropertyArray: subPropertyDropdownList}; + this.indexListValues.push(indexValueMap); + } + this.formValidation(); + } + + onSubPropertyValueChange(indexObject : ToscaIndexObject, elementIndex: number): void { + let toscaIndexFlag = false; + let nestedToscaFlag = false; + let subPropertyDropdownList : Array = []; + let selectedProperty: PropertyDropdownValue = indexObject.indexProperty; + if (selectedProperty.isList) { + toscaIndexFlag = true; + if (selectedProperty.schemaType != null) { + nestedToscaFlag = true; + const dataTypeFound: DataTypeModel = this.dataTypeService.getDataTypeByModelAndTypeName(this.componentMetadata.model, selectedProperty.schemaType); + this.addPropertiesToDropdown(dataTypeFound.properties, subPropertyDropdownList); + } } + if (toscaIndexFlag || nestedToscaFlag) { + let indexValueMap : ToscaIndexObject = {indexFlag : toscaIndexFlag, nestedFlag : nestedToscaFlag, indexValue: "0", indexProperty: null, subPropertyArray: subPropertyDropdownList}; + if(!this.indexListValues[elementIndex+1]) { + this.indexListValues.push(indexValueMap); + } else { + this.indexListValues[elementIndex+1] = indexValueMap; + } + } else { + if(this.indexListValues[elementIndex+1]) { + this.indexListValues.splice((elementIndex+1),1); + } + } + this.formValidation(); } - indexTokenChange(): void { - if ((this.toscaIndex.value).toLowerCase() === 'index') { + indexTokenChange(indexObject : ToscaIndexObject): void { + if ((indexObject.indexValue).toLowerCase() === 'index') { + this.formValidation(); return; } - let indexTokenValue = Number(this.toscaIndex.value); + let indexTokenValue = Number(indexObject.indexValue); if (isNaN(indexTokenValue)) { - this.toscaIndex.reset(); + indexObject.indexValue = "0"; + this.formValidation(); + return; } + this.formValidation(); } showPropertySourceDropdown(): boolean { @@ -530,10 +628,6 @@ export class ToscaGetFunctionComponent implements OnInit, OnChanges { return this.formGroup.get('selectedProperty') as FormControl; } - private get toscaIndex(): FormControl { - return this.formGroup.get('toscaIndex') as FormControl; - } - } export interface PropertyDropdownValue { @@ -542,6 +636,15 @@ export interface PropertyDropdownValue { propertyLabel: string; propertyPath: Array; isList: boolean; + schemaType: string; +} + +export interface ToscaIndexObject { + indexFlag: boolean; + nestedFlag: boolean; + indexValue: string; + indexProperty: PropertyDropdownValue; + subPropertyArray: Array; } export interface ToscaGetFunctionValidationEvent { diff --git a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/ToscaFunctionJsonDeserializer.java b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/ToscaFunctionJsonDeserializer.java index de8e30b897..f77c6f949b 100644 --- a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/ToscaFunctionJsonDeserializer.java +++ b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/ToscaFunctionJsonDeserializer.java @@ -116,7 +116,8 @@ public class ToscaFunctionJsonDeserializer extends StdDeserializer @@ -149,20 +150,31 @@ public class ToscaFunctionJsonDeserializer extends StdDeserializer getNumberAsTextOrElseNull(final JsonNode node, final String fieldName, final DeserializationContext context) throws JsonMappingException{ + List toscaIndexList = new ArrayList(); final JsonNode jsonNode = node.get(fieldName); - if (jsonNode == null) { - return null; - } - if (jsonNode.asText().equalsIgnoreCase("INDEX")) { - return jsonNode.asText(); - } - try { - Integer.parseInt(jsonNode.asText()); - } catch(Exception e) { - return null; + if (jsonNode != null) { + if (!jsonNode.isArray()) { + throw context.instantiationException(ToscaGetFunctionDataDefinition.class, "Expecting an array for toscaIndexList attribute"); + } + for (int index=0;index propertyPathFromSource = new ArrayList<>(); - private Object toscaIndex; + private List toscaIndexList; public ToscaGetFunctionDataDefinition() { //necessary for JSON conversions @@ -89,10 +89,13 @@ public class ToscaGetFunctionDataDefinition implements ToscaFunction, ToscaFunct ); } if (propertySource == PropertySource.SELF) { - if (toscaIndex != null) { - Object toscaIndexValue = StringUtils.isNumeric(toscaIndex.toString()) ? Integer.parseInt(toscaIndex.toString()) : toscaIndex; + if (toscaIndexList.size() > 0) { + List parsedIndexList = new ArrayList(); + toscaIndexList.forEach((obj) -> { + parsedIndexList.add(StringUtils.isNumeric(obj.toString()) ? Integer.parseInt(obj.toString()) : obj); + }); return Map.of(functionType.getFunctionName(), - Stream.concat(Stream.of(PropertySource.SELF.getName()), Stream.concat(propertyPathFromSource.stream(),Stream.of(toscaIndexValue))).collect(Collectors.toList()) + Stream.concat(Stream.of(PropertySource.SELF.getName()), Stream.concat(propertyPathFromSource.stream(),parsedIndexList.stream())).collect(Collectors.toList()) ); } return Map.of(functionType.getFunctionName(), @@ -105,10 +108,13 @@ public class ToscaGetFunctionDataDefinition implements ToscaFunction, ToscaFunct String.format("sourceName is required in order to generate the %s from INSTANCE value", functionType.getFunctionName()) ); } - if (toscaIndex != null) { - Object toscaIndexValue = StringUtils.isNumeric(toscaIndex.toString()) ? Integer.parseInt(toscaIndex.toString()) : toscaIndex; + if (toscaIndexList.size() > 0) { + List parsedIndexList = new ArrayList(); + toscaIndexList.forEach((obj) -> { + parsedIndexList.add(StringUtils.isNumeric(obj.toString()) ? Integer.parseInt(obj.toString()) : obj); + }); return Map.of(functionType.getFunctionName(), - Stream.concat(Stream.of(sourceName), Stream.concat(propertyPathFromSource.stream(),Stream.of(toscaIndexValue))).collect(Collectors.toList()) + Stream.concat(Stream.of(sourceName), Stream.concat(propertyPathFromSource.stream(),parsedIndexList.stream())).collect(Collectors.toList()) ); } return Map.of(functionType.getFunctionName(), @@ -123,10 +129,9 @@ public class ToscaGetFunctionDataDefinition implements ToscaFunction, ToscaFunct List propertySourceCopy = new ArrayList(this.propertyPathFromSource); List propertySourceOneCopy = new ArrayList<>(); propertySourceOneCopy.add(this.propertyPathFromSource.get(0)); - if (toscaIndex != null) { - Object toscaIndexValue = StringUtils.isNumeric(toscaIndex.toString()) ? Integer.parseInt(toscaIndex.toString()) : toscaIndex; - propertySourceCopy.add(toscaIndexValue); - propertySourceOneCopy.add(toscaIndexValue); + if (toscaIndexList.size() > 0) { + propertySourceCopy.addAll(toscaIndexList); + propertySourceOneCopy.addAll(toscaIndexList); } if (this.propertyPathFromSource.size() == 1) { return Map.of(this.functionType.getFunctionName(), propertySourceOneCopy); diff --git a/common-be/src/test/java/org/openecomp/sdc/be/datatypes/elements/ToscaGetFunctionDataDefinitionTest.java b/common-be/src/test/java/org/openecomp/sdc/be/datatypes/elements/ToscaGetFunctionDataDefinitionTest.java index 581f62a91f..3add149e23 100644 --- a/common-be/src/test/java/org/openecomp/sdc/be/datatypes/elements/ToscaGetFunctionDataDefinitionTest.java +++ b/common-be/src/test/java/org/openecomp/sdc/be/datatypes/elements/ToscaGetFunctionDataDefinitionTest.java @@ -28,6 +28,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import com.google.gson.Gson; +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -206,6 +207,7 @@ class ToscaGetFunctionDataDefinitionTest { toscaGetFunction.setPropertySource(propertySource); toscaGetFunction.setPropertyPathFromSource(propertyPath); toscaGetFunction.setSourceName(sourceName); + toscaGetFunction.setToscaIndexList(new ArrayList<>()); return toscaGetFunction; } -- 2.16.6