diff options
13 files changed, 307 insertions, 35 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 0b9432b3a1..0651e3504e 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.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; @@ -28,6 +29,8 @@ import java.util.Optional; import java.util.stream.Collectors; import java.util.stream.Stream; import org.apache.commons.lang3.StringUtils; +import org.openecomp.sdc.be.config.Configuration; +import org.openecomp.sdc.be.config.ConfigurationManager; import org.openecomp.sdc.be.datatypes.elements.CustomYamlFunction; import org.openecomp.sdc.be.datatypes.elements.ToscaConcatFunction; import org.openecomp.sdc.be.datatypes.elements.ToscaCustomFunction; @@ -74,7 +77,7 @@ public class ToscaFunctionYamlParsingHandler { List<String> 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.setPropertyPathFromSource(propertySourceIndex.subList(0, (propertySourceIndex.size() - 1))); toscaGetFunction.setToscaIndex(toscaIndexValue); } else { toscaGetFunction.setPropertyPathFromSource(propertySourceIndex); @@ -105,7 +108,7 @@ public class ToscaFunctionYamlParsingHandler { } 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.setPropertyPathFromSource(functionParameters.subList(0, (functionParameters.size() - 1))); toscaGetFunction.setToscaIndex(toscaIndexValue); } else { toscaGetFunction.setPropertyPathFromSource(functionParameters); @@ -155,6 +158,14 @@ public class ToscaFunctionYamlParsingHandler { final ToscaCustomFunction toscaCustomFunction = new ToscaCustomFunction(); toscaCustomFunction.setName(functionType.substring(1)); final Object functionValueObj = toscaFunctionPropertyValueMap.get(functionType); + toscaCustomFunction.setToscaFunctionType(getCustomFunctionType(toscaCustomFunction.getName())); + if (ToscaFunctionType.GET_INPUT.equals(toscaCustomFunction.getToscaFunctionType())) { + return handelCustomFunctionGetInputType(toscaCustomFunction, functionValueObj); + } + return handelCustomFunctionCustomType(toscaCustomFunction, functionValueObj); + } + + private Optional<ToscaFunction> handelCustomFunctionCustomType(ToscaCustomFunction toscaCustomFunction, Object functionValueObj) { if (!(functionValueObj instanceof List)) { return Optional.empty(); } @@ -181,6 +192,35 @@ public class ToscaFunctionYamlParsingHandler { return Optional.of(toscaCustomFunction); } + private Optional<ToscaFunction> handelCustomFunctionGetInputType(ToscaCustomFunction toscaCustomFunction, Object functionValueObj) { + if (!(functionValueObj instanceof String)) { + return Optional.empty(); + } + final String parameter = (String) functionValueObj; + Map<String, Object> parameterMap = new HashMap<>(); + parameterMap.put(ToscaFunctionType.GET_INPUT.getName(), parameter); + buildToscaFunctionBasedOnPropertyValue(parameterMap).ifPresent(toscaFunction -> { + if (toscaFunction instanceof ToscaFunctionParameter) { + toscaCustomFunction.addParameter((ToscaFunctionParameter) toscaFunction); + } + }); + return Optional.of(toscaCustomFunction); + } + + private ToscaFunctionType getCustomFunctionType(String name) { + List<Configuration.CustomToscaFunction> customFunctions = + ConfigurationManager.getConfigurationManager().getConfiguration().getDefaultCustomToscaFunctions(); + if (customFunctions.isEmpty()) { + return ToscaFunctionType.CUSTOM; + } + Optional<Configuration.CustomToscaFunction> optionalFunc = customFunctions.stream().filter(func -> func.getName().equals(name)).findFirst(); + if (optionalFunc.isEmpty()) { + return ToscaFunctionType.CUSTOM; + } + String type = optionalFunc.get().getType(); + return ToscaFunctionType.findType(type).get(); + } + /** * Checks if the property value is a supported TOSCA function. * diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/csar/ToscaFunctionYamlParsingHandlerTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/csar/ToscaFunctionYamlParsingHandlerTest.java index 1dfb7a9113..4791015d76 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/csar/ToscaFunctionYamlParsingHandlerTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/csar/ToscaFunctionYamlParsingHandlerTest.java @@ -26,11 +26,14 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; import org.junit.jupiter.api.Test; +import org.openecomp.sdc.be.config.Configuration; +import org.openecomp.sdc.be.config.ConfigurationManager; import org.openecomp.sdc.be.datatypes.elements.ToscaConcatFunction; import org.openecomp.sdc.be.datatypes.elements.ToscaCustomFunction; import org.openecomp.sdc.be.datatypes.elements.ToscaFunction; @@ -134,6 +137,7 @@ class ToscaFunctionYamlParsingHandlerTest { @Test void buildToscaFunctionBasedOnPropertyValue_CustomTest() { + setDefaultCustomToscaFunctionOnConfiguration(); final List<Object> customValue = List.of("string1", "-", Map.of(ToscaFunctionType.GET_INPUT.getName(), "inputName")); final Map<String, Object> customValueMap = Map.of("$customFuncName", customValue); @@ -158,6 +162,32 @@ class ToscaFunctionYamlParsingHandlerTest { } @Test + void buildToscaFunctionBasedOnPropertyValue_CustomFunctionGetInputTypeTest() { + setDefaultCustomToscaFunctionOnConfiguration(); + final Map<String, Object> customValueMap = Map.of("$custom_function_get_input_type", "controller_actor"); + + final Optional<ToscaFunction> actualToscaFunctionOpt = toscaFunctionYamlParsingHandler.buildToscaFunctionBasedOnPropertyValue(customValueMap); + assertTrue(actualToscaFunctionOpt.isPresent()); + final ToscaFunction actualToscaFunction = actualToscaFunctionOpt.get(); + assertEquals(ToscaFunctionType.CUSTOM, actualToscaFunction.getType()); + assertTrue(actualToscaFunction instanceof ToscaCustomFunction); + final ToscaCustomFunction toscaCustomFunction = (ToscaCustomFunction) actualToscaFunction; + final String functionName = toscaCustomFunction.getName(); + assertEquals("custom_function_get_input_type", functionName); + assertEquals(1, toscaCustomFunction.getParameters().size()); + assertTrue(toscaCustomFunction.getParameters().get(0) instanceof ToscaGetFunctionDataDefinition); + final ToscaGetFunctionDataDefinition parameter1 = (ToscaGetFunctionDataDefinition) toscaCustomFunction.getParameters().get(0); + assertGetInput(parameter1, List.of("controller_actor")); +// assertEquals("string1", parameter1.getValue()); +// assertTrue(toscaCustomFunction.getParameters().get(1) instanceof ToscaStringParameter); +// final ToscaStringParameter parameter2 = (ToscaStringParameter) toscaCustomFunction.getParameters().get(1); +// assertEquals("-", parameter2.getValue()); +// assertTrue(toscaCustomFunction.getParameters().get(2) instanceof ToscaGetFunctionDataDefinition); +// final ToscaGetFunctionDataDefinition getFunction = (ToscaGetFunctionDataDefinition) toscaCustomFunction.getParameters().get(2); +// assertGetInput(getFunction, List.of("inputName")); + } + + @Test void isPropertyValueToscaFunctionTest() { assertFalse(toscaFunctionYamlParsingHandler.isPropertyValueToscaFunction(ToscaFunctionType.GET_INPUT.getName())); assertFalse(toscaFunctionYamlParsingHandler.isPropertyValueToscaFunction(new HashMap<>())); @@ -172,4 +202,16 @@ class ToscaFunctionYamlParsingHandlerTest { assertFalse(toscaFunctionYamlParsingHandler.isPropertyValueToscaFunction(Map.of(ToscaFunctionType.YAML.getName(), ""))); assertFalse(toscaFunctionYamlParsingHandler.isPropertyValueToscaFunction(Map.of(ToscaFunctionType.STRING.getName(), ""))); } + + private void setDefaultCustomToscaFunctionOnConfiguration() { + final var configurationManager = new ConfigurationManager(); + final var configuration = new Configuration(); + List<Configuration.CustomToscaFunction> defaultCustomToscaFunctions = new ArrayList<>(); + Configuration.CustomToscaFunction defaultCustomType = new Configuration.CustomToscaFunction(); + defaultCustomType.setName("custom_function_get_input_type"); + defaultCustomType.setType("get_input"); + defaultCustomToscaFunctions.add(defaultCustomType); + configuration.setDefaultCustomToscaFunctions(defaultCustomToscaFunctions); + configurationManager.setConfiguration(configuration); + } }
\ No newline at end of file diff --git a/catalog-ui/src/app/ng2/components/logic/properties-table/properties-table.component.html b/catalog-ui/src/app/ng2/components/logic/properties-table/properties-table.component.html index 526ccf21ce..b348d81353 100644 --- a/catalog-ui/src/app/ng2/components/logic/properties-table/properties-table.component.html +++ b/catalog-ui/src/app/ng2/components/logic/properties-table/properties-table.component.html @@ -46,7 +46,6 @@ <div class="table-row" *ngFor="let property of fePropertiesMap[instanceId] | searchFilter:'name':searchTerm | propertiesOrderBy:{path: path, direction: direction}; trackBy:property?.name " (click)="onClickPropertyRow(property, instanceId, $event)" [ngClass]="{'selected': selectedPropertyId && selectedPropertyId === property.name, 'readonly': property.isDisabled || property.isDeclared}"> - <div class="table-cell col1" [ngClass]="{'filtered':property.name === propertyNameSearchText}" [class.round-checkbox]="property.isDeclared"> <!-- Property Name --> <div class="property-name"> diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-custom-function/tosca-custom-function.component.html b/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-custom-function/tosca-custom-function.component.html index f77af54c77..831ce49de8 100644 --- a/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-custom-function/tosca-custom-function.component.html +++ b/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-custom-function/tosca-custom-function.component.html @@ -29,26 +29,36 @@ </div> <div formArrayName="customParameterList"> <div *ngFor="let parameter of parameters; let idx = index"> - <div *ngIf="idx > 0" class="text-center"><span class="custom-plus-icon"></span></div> - <div class="parameter-card"> + <div *ngIf="idx > 0 && type != GET_INPUT" class="text-center"><span class="custom-plus-icon"></span></div> + <div class="parameter-card" *ngIf="type != GET_INPUT"> <div class="card-content"> <ng-container *ngIf="parameter.type === STRING_FUNCTION_TYPE"> <input type="text" [formControlName]="idx" [value]="parameter.value"/><br/> </ng-container> <ng-container *ngIf="parameter.type !== STRING_FUNCTION_TYPE"> - <tosca-function [property]="propertyInputList[idx]" [customToscaFunctions]="customToscaFunctions" [componentInstanceMap]="componentInstanceMap" [allowClear]="false" + <tosca-function [property]="propertyInputList[idx]" + [customToscaFunctions]="customToscaFunctions" + [componentInstanceMap]="componentInstanceMap" + [allowClear]="false" (onValidityChange)="onFunctionValidityChange($event, idx)"> </tosca-function> </ng-container> - <div class="buttons-container"> + <div *ngIf="type != GET_INPUT" class="buttons-container"> <span class="delete-icon" (click)="removeParameter(idx)"></span> </div> </div> </div> + <ng-container *ngIf="type === GET_INPUT"> + <app-tosca-get-function [property]="propertyInputList[idx]" [toscaGetFunction]="toscaGetFunction" + [componentInstanceMap]="componentInstanceMap" + [functionType]="GET_INPUT" + (onValidityChange)="onGetFunctionValidityChange($event, idx)"> + </app-tosca-get-function> + </ng-container> </div> </div> </ng-container> - <div class="buttons-container"> + <div *ngIf="type != GET_INPUT" class="buttons-container"> <a class="add-link" (click)="addStringParameter()">String Value</a> <a class="add-link" (click)="addFunction()">TOSCA Function Expression</a> </div> </div> diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-custom-function/tosca-custom-function.component.ts b/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-custom-function/tosca-custom-function.component.ts index 7746d3845f..35f1649ec6 100644 --- a/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-custom-function/tosca-custom-function.component.ts +++ b/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-custom-function/tosca-custom-function.component.ts @@ -30,7 +30,9 @@ import {PROPERTY_TYPES} from "../../../../../utils/constants"; import {InstanceFeDetails} from "../../../../../models/instance-fe-details"; import {ToscaFunctionValidationEvent} from "../tosca-function.component"; import {ToscaFunction} from "../../../../../models/tosca-function"; +import {ToscaGetFunction} from "../../../../../models/tosca-get-function"; import {CustomToscaFunction} from "../../../../../models/default-custom-functions"; +import {ToscaGetFunctionValidationEvent} from "../tosca-get-function/tosca-get-function.component"; @Component({ selector: 'app-tosca-custom-function', @@ -43,10 +45,14 @@ export class ToscaCustomFunctionComponent implements OnInit { @Input() componentInstanceMap: Map<string, InstanceFeDetails> = new Map<string, InstanceFeDetails>(); @Input() customToscaFunctions: Array<CustomToscaFunction> = []; @Input() name: string; + @Input() type: ToscaFunctionType; + @Input() propertyType: string; + @Input() propertySchemaType: string = undefined; @Input() isDefaultCustomFunction: boolean; @Output() onValidFunction: EventEmitter<ToscaCustomFunction> = new EventEmitter<ToscaCustomFunction>(); @Output() onValidityChange: EventEmitter<ToscaCustomFunctionValidationEvent> = new EventEmitter<ToscaCustomFunctionValidationEvent>(); + toscaGetFunction: ToscaFunction; customFunctionFormName: FormControl = new FormControl('', [Validators.required, Validators.minLength(1)]); customParameterFormArray: FormArray = new FormArray([], Validators.minLength(1)); formGroup: FormGroup = new FormGroup( @@ -58,20 +64,29 @@ export class ToscaCustomFunctionComponent implements OnInit { parameters: ToscaFunctionParameter[] = []; propertyInputList: Array<PropertyBEModel> = []; + previousType: ToscaFunctionType; - STRING_FUNCTION_TYPE = ToscaFunctionType.STRING + STRING_FUNCTION_TYPE = ToscaFunctionType.STRING; + GET_INPUT = ToscaFunctionType.GET_INPUT; ngOnInit() { this.initForm(); } ngOnChanges() { + if (this.previousType && this.previousType != this.type) { + this.propertyInputList = []; + this.customParameterFormArray = new FormArray([], Validators.minLength(1)); + this.parameters = []; + } + this.fillVariables(); if (this.name && this.isDefaultCustomFunction) { this.customFunctionFormName.setValue(this.name); this.emitOnValidityChange(); } else { - this.name = ""; + this.name = ''; } + this.previousType = this.type; } private initForm(): void { @@ -81,7 +96,13 @@ export class ToscaCustomFunctionComponent implements OnInit { this.onValidFunction.emit(this.buildCustomFunctionFromForm()); } }); + } + + private fillVariables() { if (!this.toscaCustomFunction) { + if (this.type === this.GET_INPUT && this.parameters.length < 1) { + this.addFunction(); + } return; } if (this.toscaCustomFunction.parameters) { @@ -89,13 +110,13 @@ export class ToscaCustomFunctionComponent implements OnInit { this.customFunctionFormName.setValue(this.name) this.parameters = Array.from(this.toscaCustomFunction.parameters); for (const parameter of this.parameters) { + if (this.type === this.GET_INPUT) { + this.toscaGetFunction = parameter as ToscaGetFunction; + this.addToscaFunctionToParameters(parameter); + return; + } if (parameter.type !== PROPERTY_TYPES.STRING) { - const propertyBEModel = this.createProperty(parameter.value); - propertyBEModel.toscaFunction = <ToscaFunction> parameter; - this.propertyInputList.push(propertyBEModel); - this.customParameterFormArray.push( - new FormControl(parameter, [Validators.required, Validators.minLength(1)]) - ); + this.addToscaFunctionToParameters(parameter); } else { this.propertyInputList.push(undefined); this.customParameterFormArray.push( @@ -104,6 +125,18 @@ export class ToscaCustomFunctionComponent implements OnInit { } } } + if (this.type === this.GET_INPUT && this.parameters.length < 1) { + this.addFunction(); + } + } + + private addToscaFunctionToParameters(parameter: ToscaFunctionParameter) { + const propertyBEModel = this.createProperty(parameter.value); + propertyBEModel.toscaFunction = <ToscaFunction> parameter; + this.propertyInputList.push(propertyBEModel); + this.customParameterFormArray.push( + new FormControl(parameter, [Validators.required, Validators.minLength(1)]) + ); } private buildCustomFunctionFromForm(): ToscaCustomFunction { @@ -111,6 +144,9 @@ export class ToscaCustomFunctionComponent implements OnInit { toscaCustomFunction1.name = this.customFunctionFormName.value; this.customParameterFormArray.controls.forEach(control => { const value = control.value; + if (!value) { + return; + } if (typeof value === 'string') { const stringParameter = new ToscaStringParameter(); stringParameter.value = value; @@ -140,12 +176,13 @@ export class ToscaCustomFunctionComponent implements OnInit { addStringParameter(): void { const toscaStringParameter = new ToscaStringParameter(); - toscaStringParameter.value = '' - this.parameters.push(toscaStringParameter); + toscaStringParameter.value = ''; this.propertyInputList.push(undefined); this.customParameterFormArray.push( new FormControl('', [Validators.required, Validators.minLength(1)]) ); + this.parameters.push(toscaStringParameter); + console.log(this.customParameterFormArray) } removeParameter(position): void { @@ -156,7 +193,15 @@ export class ToscaCustomFunctionComponent implements OnInit { createProperty(value?: any): PropertyBEModel { const property = new PropertyBEModel(); - property.type = PROPERTY_TYPES.ANY; + if (this.type === this.GET_INPUT) { + property.type = this.propertyType; + if (this.propertySchemaType) { + property.schemaType = this.propertySchemaType; + } + } else { + property.type = PROPERTY_TYPES.ANY; + } + property.value = value ? value : undefined; return property; } @@ -168,6 +213,15 @@ export class ToscaCustomFunctionComponent implements OnInit { this.customParameterFormArray.controls[index].setValue(undefined); } } + + onGetFunctionValidityChange(event: ToscaGetFunctionValidationEvent, index: number): void { + if (event.isValid && event.toscaGetFunction) { + this.customParameterFormArray.controls[index].setValue(event.toscaGetFunction); + } else { + this.customParameterFormArray.controls[index].setValue(undefined); + } + this.emitOnValidityChange(); + } } export interface ToscaCustomFunctionValidationEvent { diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-function.component.html b/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-function.component.html index 65a024cde4..0d5a4973da 100644 --- a/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-function.component.html +++ b/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-function.component.html @@ -38,8 +38,16 @@ (onValidityChange)="onConcatFunctionValidityChange($event)"></app-tosca-concat-function> </div> <div *ngIf="isCustomSelected()"> - <app-tosca-custom-function [toscaCustomFunction]="toscaFunction" [customToscaFunctions]="customToscaFunctions" [name]="getCustomFunctionName()" [componentInstanceMap]="componentInstanceMap" - [isDefaultCustomFunction]="isDefaultCustomFunction()" (onValidityChange)="onCustomFunctionValidityChange($event)"></app-tosca-custom-function> + <app-tosca-custom-function [toscaCustomFunction]="toscaFunction" + [customToscaFunctions]="customToscaFunctions" + [name]="getCustomFunctionName()" + [type]="getCustomFunctionType()" + [propertyType]="property.type" + [propertySchemaType]="property.schemaType" + [componentInstanceMap]="componentInstanceMap" + [isDefaultCustomFunction]="isDefaultCustomFunction()" + (onValidityChange)="onCustomFunctionValidityChange($event)"> + </app-tosca-custom-function> </div> <div *ngIf="isGetFunctionSelected()"> <app-tosca-get-function [property]="property" [toscaGetFunction]="toscaFunction" @@ -48,7 +56,8 @@ [functionType]="toscaFunctionTypeForm.value" [compositionMap]="compositionMap" [compositionMapKey]="compositionMapKey" - (onValidityChange)="onGetFunctionValidityChange($event)"></app-tosca-get-function> + (onValidityChange)="onGetFunctionValidityChange($event)"> + </app-tosca-get-function> </div> <div *ngIf="isYamlFunctionSelected()"> <app-yaml-function [yamlFunction]="toscaFunction" (onValidityChange)="onYamlFunctionValidityChange($event)"></app-yaml-function> diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-function.component.ts b/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-function.component.ts index ecaff252d3..b9559838f4 100644 --- a/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-function.component.ts +++ b/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-function.component.ts @@ -192,6 +192,11 @@ export class ToscaFunctionComponent implements OnInit, OnChanges { return toscaFunctionType.name; } + getCustomFunctionType():string { + let toscaFunctionType: CustomToscaFunction = this.getCustomToscaFunction(); + return toscaFunctionType.type; + } + isDefaultCustomFunction(): boolean { let toscaFunctionType: CustomToscaFunction = this.getCustomToscaFunction(); if (toscaFunctionType.name === "other") { @@ -223,7 +228,7 @@ export class ToscaFunctionComponent implements OnInit, OnChanges { isCustomSelected(): boolean { let toscaFunctionType: CustomToscaFunction = this.getCustomToscaFunction(); - return toscaFunctionType && toscaFunctionType.type === ToscaFunctionType.CUSTOM; + return toscaFunctionType && (toscaFunctionType.type === ToscaFunctionType.CUSTOM || toscaFunctionType.type === ToscaFunctionType.GET_INPUT); } isGetFunctionSelected(): boolean { diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-get-function/tosca-get-function.component.html b/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-get-function/tosca-get-function.component.html index 387bb5cbcb..4a9e110982 100644 --- a/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-get-function/tosca-get-function.component.html +++ b/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-get-function/tosca-get-function.component.html @@ -17,7 +17,7 @@ ~ ============LICENSE_END========================================================= --> -<div class="tosca-function"> +<div> <form class="w-sdc-form" [formGroup]="formGroup"> <div class="i-sdc-form-item" *ngIf="showPropertySourceDropdown()"> <label class="i-sdc-form-label required">{{'TOSCA_FUNCTION_PROPERTY_SOURCE_LABEL' | translate}}</label> 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 284c559c55..1b0a1a34ee 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 @@ -100,7 +100,6 @@ export class ToscaGetFunctionComponent implements OnInit, OnChanges { this.initToscaGetFunction().subscribe(() => { this.isInitialized = true; }); - } ngOnChanges(_changes: SimpleChanges): void { @@ -410,7 +409,8 @@ export class ToscaGetFunctionComponent implements OnInit, OnChanges { if (this.property.type === PROPERTY_TYPES.ANY) { return true; } - let validPropertyType = property.type === PROPERTY_TYPES.LIST ? property.schemaType : property.type; + let validPropertyType = property.type; + let validPropertyTypeSchema = property.schemaType; if (this.typeHasSchema(this.property.type)) { if ((this.property instanceof PropertyDeclareAPIModel && (<PropertyDeclareAPIModel> this.property).input instanceof DerivedFEProperty) || this.compositionMap) { let childObject : DerivedFEProperty = (<DerivedFEProperty>(<PropertyDeclareAPIModel> this.property).input); @@ -421,13 +421,13 @@ export class ToscaGetFunctionComponent implements OnInit, OnChanges { } return validPropertyType === childObject.type; }else{ - return validPropertyType === this.property.schema.property.type; + return validPropertyType === this.property.schemaType; } } if (!property.schema || !property.schema.property) { return false; } - return validPropertyType === this.property.type && this.property.schema.property.type === property.schema.property.type; + return validPropertyType === this.property.type && this.property.schemaType === validPropertyTypeSchema; } if (this.property.schema.property.isDataType && this.property instanceof PropertyDeclareAPIModel && (<PropertyDeclareAPIModel>this.property).propertiesName){ let typeToMatch = (<PropertyDeclareAPIModel> this.property).input.type; @@ -438,7 +438,7 @@ export class ToscaGetFunctionComponent implements OnInit, OnChanges { return validPropertyType === typeToMatch; } - return validPropertyType === this.property.type; + return validPropertyType === this.property.type || (validPropertyType === PROPERTY_TYPES.LIST && validPropertyTypeSchema === this.property.type); } private getType(propertyPath:string[], type: string): string { @@ -499,7 +499,7 @@ export class ToscaGetFunctionComponent implements OnInit, OnChanges { this.toscaIndexFlag = false; this.toscaIndex.reset(); const selectedProperty: PropertyDropdownValue = this.selectedProperty.value; - if (selectedProperty.isList) { + if (selectedProperty.isList && this.property.type != PROPERTY_TYPES.LIST) { this.toscaIndexFlag = true; } } diff --git a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/ToscaCustomFunction.java b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/ToscaCustomFunction.java index 3f0c4fa8a5..981d4ecf8e 100644 --- a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/ToscaCustomFunction.java +++ b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/ToscaCustomFunction.java @@ -22,19 +22,20 @@ package org.openecomp.sdc.be.datatypes.elements; import com.google.gson.Gson; -import lombok.Getter; -import lombok.Setter; - import java.util.ArrayList; +import java.util.Collection; import java.util.List; import java.util.Map; import java.util.stream.Collectors; +import lombok.Getter; +import lombok.Setter; @Getter @Setter public class ToscaCustomFunction implements ToscaFunction, ToscaFunctionParameter { private String name; + private ToscaFunctionType toscaFunctionType; private List<ToscaFunctionParameter> parameters = new ArrayList<>(); @Override @@ -49,9 +50,18 @@ public class ToscaCustomFunction implements ToscaFunction, ToscaFunctionParamete @Override public Object getJsonObjectValue() { + if (ToscaFunctionType.GET_INPUT.equals(this.toscaFunctionType)) { + Map<String, Object> getInput = parameters.stream().collect(Collectors.toMap( + input -> "$" + name, + input -> { + Map<String, Object> inputMap = (Map<String, Object>) input.getJsonObjectValue(); + return inputMap.get(ToscaFunctionType.GET_INPUT.getName()); + })); + return getInput; + } return Map.of( - "$" + name, - parameters.stream().map(ToscaFunctionParameter::getJsonObjectValue).collect(Collectors.toList()) + "$" + name, + parameters.stream().map(ToscaFunctionParameter::getJsonObjectValue).collect(Collectors.toList()) ); } 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 2e57a4158a..de8e30b897 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 @@ -29,7 +29,10 @@ import com.fasterxml.jackson.databind.deser.std.StdDeserializer; import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.Optional; import org.apache.commons.lang3.StringUtils; +import org.openecomp.sdc.be.config.Configuration; +import org.openecomp.sdc.be.config.ConfigurationManager; import org.openecomp.sdc.be.datatypes.enums.PropertySource; import org.openecomp.sdc.be.datatypes.tosca.ToscaGetFunctionType; import org.slf4j.Logger; @@ -178,11 +181,40 @@ public class ToscaFunctionJsonDeserializer extends StdDeserializer<ToscaFunction throw context.instantiationException(List.class, "Expecting a string for the 'name' entry"); } toscaCustomFunction.setName(name); + toscaCustomFunction.setToscaFunctionType(getCustomFunctionType(name)); List<ToscaFunctionParameter> functionParameterList = getParameters(customFunctionJsonNode, context); toscaCustomFunction.setParameters(functionParameterList); + if (ToscaFunctionType.GET_INPUT.equals(toscaCustomFunction.getToscaFunctionType())) { + validateGetInput(toscaCustomFunction, context); + } return toscaCustomFunction; } + private ToscaFunctionType getCustomFunctionType(String name) { + List<Configuration.CustomToscaFunction> customFunctions = + ConfigurationManager.getConfigurationManager().getConfiguration().getDefaultCustomToscaFunctions(); + if (customFunctions.isEmpty()) { + return ToscaFunctionType.CUSTOM; + } + Optional<Configuration.CustomToscaFunction> optionalFunc = customFunctions.stream().filter(func -> func.getName().equals(name)).findFirst(); + if (optionalFunc.isEmpty()) { + return ToscaFunctionType.CUSTOM; + } + String type = optionalFunc.get().getType(); + return ToscaFunctionType.findType(type).get(); + } + + private void validateGetInput(ToscaCustomFunction toscaCustomFunction, final DeserializationContext context) throws IOException { + List<ToscaFunctionParameter> functionParameterList = toscaCustomFunction.getParameters(); + if (functionParameterList.size() != 1) { + throw context.instantiationException(List.class, "Custom GET_INPUT function must contain one GET_INPUT parameter"); + } + ToscaFunctionParameter parameter = functionParameterList.get(0); + if (!ToscaFunctionType.GET_INPUT.equals(parameter.getType())) { + throw context.instantiationException(List.class, "Custom GET_INPUT function must contain a GET_INPUT parameter"); + } + } + private List<ToscaFunctionParameter> getParameters(final JsonNode functionJsonNode, final DeserializationContext context) throws IOException { final List<ToscaFunctionParameter> functionParameterList = new ArrayList<>(); final JsonNode parametersNode = functionJsonNode.get("parameters"); diff --git a/common-be/src/test/java/org/openecomp/sdc/be/datatypes/elements/ToscaFunctionJsonDeserializerTest.java b/common-be/src/test/java/org/openecomp/sdc/be/datatypes/elements/ToscaFunctionJsonDeserializerTest.java index d7c2e7c65e..5128c63668 100644 --- a/common-be/src/test/java/org/openecomp/sdc/be/datatypes/elements/ToscaFunctionJsonDeserializerTest.java +++ b/common-be/src/test/java/org/openecomp/sdc/be/datatypes/elements/ToscaFunctionJsonDeserializerTest.java @@ -33,9 +33,12 @@ import com.fasterxml.jackson.databind.exc.ValueInstantiationException; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; +import java.util.ArrayList; import java.util.List; import java.util.Map; import org.junit.jupiter.api.Test; +import org.openecomp.sdc.be.config.Configuration; +import org.openecomp.sdc.be.config.ConfigurationManager; import org.openecomp.sdc.be.datatypes.enums.PropertySource; import org.openecomp.sdc.be.datatypes.tosca.ToscaGetFunctionType; import org.yaml.snakeyaml.Yaml; @@ -142,6 +145,7 @@ class ToscaFunctionJsonDeserializerTest { @Test void testCustomToscaFunction() throws IOException { //given + setDefaultCustomToscaFunctionOnConfiguration(); final String toscaCustomFunction = Files.readString(TEST_RESOURCES_PATH.resolve("customFunction.json")); //when final ToscaFunction toscaFunction = parseToscaFunction(toscaCustomFunction); @@ -189,6 +193,55 @@ class ToscaFunctionJsonDeserializerTest { assertEquals("string3", customParameters.get(1)); } + @Test + void testCustomToscaFunctionGetInputType() throws IOException { + //given + setDefaultCustomToscaFunctionOnConfiguration(); + final String toscaCustomFunctionFile = Files.readString(TEST_RESOURCES_PATH.resolve("customFunctionGetInputType.json")); + //when + final ToscaFunction toscaFunction = parseToscaFunction(toscaCustomFunctionFile); + //then + assertTrue(toscaFunction instanceof ToscaCustomFunction); + ToscaCustomFunction toscaCustomFunction = (ToscaCustomFunction) toscaFunction; + final Object yamlObject = new Yaml().load(toscaFunction.getValue()); + assertTrue(yamlObject instanceof Map); + final Map<String, Object> yamlMap = (Map<String, Object>) yamlObject; + assertEquals(1, yamlMap.size()); + final Object customFunctionGetInputValue = yamlMap.get("$" + ((ToscaCustomFunction) toscaFunction).getName()); + assertTrue(customFunctionGetInputValue instanceof ArrayList); + ArrayList<Object> customFunctionGetInputValueList = (ArrayList<Object>) customFunctionGetInputValue; + assertEquals(1, customFunctionGetInputValueList.size()); + assertEquals(1, customFunctionGetInputValueList.size()); + assertEquals("controller_actor", customFunctionGetInputValueList.get(0)); + + List<ToscaFunctionParameter> parameters = toscaCustomFunction.getParameters(); + assertEquals(1, parameters.size()); + ToscaFunctionParameter paramFunction = toscaCustomFunction.getParameters().get(0); + assertTrue(paramFunction instanceof ToscaGetFunctionDataDefinition); + + final ToscaGetFunctionDataDefinition toscaGetFunction = (ToscaGetFunctionDataDefinition) paramFunction; + assertEquals(ToscaFunctionType.GET_INPUT, toscaGetFunction.getType()); + assertEquals(ToscaGetFunctionType.GET_INPUT, toscaGetFunction.getFunctionType()); + assertEquals("dd0ec4d2-7e74-4d92-af2f-89c7436baa63.controller_actor", toscaGetFunction.getPropertyUniqueId()); + assertEquals(PropertySource.SELF, toscaGetFunction.getPropertySource()); + assertEquals("controller_actor", toscaGetFunction.getPropertyName()); + assertEquals("testService", toscaGetFunction.getSourceName()); + assertEquals("dd0ec4d2-7e74-4d92-af2f-89c7436baa63", toscaGetFunction.getSourceUniqueId()); + assertEquals(List.of("controller_actor"), toscaGetFunction.getPropertyPathFromSource()); + } + + private void setDefaultCustomToscaFunctionOnConfiguration() { + final var configurationManager = new ConfigurationManager(); + final var configuration = new Configuration(); + List<Configuration.CustomToscaFunction> defaultCustomToscaFunctions = new ArrayList<>(); + Configuration.CustomToscaFunction defaultCustomType = new Configuration.CustomToscaFunction(); + defaultCustomType.setName("custom_function_get_input_type"); + defaultCustomType.setType("get_input"); + defaultCustomToscaFunctions.add(defaultCustomType); + configuration.setDefaultCustomToscaFunctions(defaultCustomToscaFunctions); + configurationManager.setConfiguration(configuration); + } + private ToscaFunction parseToscaFunction(final String toscaFunctionJson) throws JsonProcessingException { return new ObjectMapper().readValue(toscaFunctionJson, ToscaFunction.class); } diff --git a/common-be/src/test/resources/toscaFunctionJsonDeserializer/customFunctionGetInputType.json b/common-be/src/test/resources/toscaFunctionJsonDeserializer/customFunctionGetInputType.json new file mode 100644 index 0000000000..81ae571c01 --- /dev/null +++ b/common-be/src/test/resources/toscaFunctionJsonDeserializer/customFunctionGetInputType.json @@ -0,0 +1,18 @@ +{ + "type": "CUSTOM", + "name": "custom_function_get_input_type", + "parameters": [ + { + "propertyUniqueId": "dd0ec4d2-7e74-4d92-af2f-89c7436baa63.controller_actor", + "propertyName": "controller_actor", + "propertySource": "SELF", + "sourceUniqueId": "dd0ec4d2-7e74-4d92-af2f-89c7436baa63", + "sourceName": "testService", + "functionType": "GET_INPUT", + "propertyPathFromSource": [ + "controller_actor" + ], + "type": "GET_INPUT" + } + ] +}
\ No newline at end of file |