From df1d6ebebe45708040048abc33aebb8980a0c9f2 Mon Sep 17 00:00:00 2001 From: franciscovila Date: Tue, 20 Jun 2023 10:38:45 +0100 Subject: Support custom tosca functions in operation input values Issue-ID: SDC-4545 Signed-off-by: franciscovila Change-Id: Icd466d4e2e1d2136f6e41b5c345e9244d5f295f6 --- .../impl/ServiceImportBusinessLogic.java | 18 +- .../service-dependencies.component.ts | 18 ++ .../tosca-custom-function.component.ts | 3 +- .../tosca-function/tosca-function.component.html | 1 + .../service-dependencies-editor.component.html | 4 + .../service-dependencies-editor.component.ts | 19 +- .../src/app/utils/filter-constraint-helper.ts | 4 +- catalog-ui/src/app/utils/tosca-function-helper.ts | 3 + .../sdc/be/datatypes/enums/FilterValueType.java | 1 + ...opertyFilterConstraintDataDefinitionHelper.java | 269 ++++++++++++++++++++- 10 files changed, 320 insertions(+), 20 deletions(-) diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceImportBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceImportBusinessLogic.java index 7d2f8c3170..b6a7fccff4 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceImportBusinessLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceImportBusinessLogic.java @@ -2296,13 +2296,17 @@ public class ServiceImportBusinessLogic { //Inputs ListDataDefinition instanceInputs = instanceOperation.getInputs(); mergeOperationInputDefinitions(templateOperation.getInputs(), instanceInputs); - component.getProperties() - .forEach(property -> instanceInputs.getListToscaDataDefinition().stream() - .filter(instanceInput -> instanceInput.getToscaFunction() instanceof ToscaGetFunctionDataDefinition && - property.getName().equals(instanceInput.getToscaFunction() != null ? - ((ToscaGetFunctionDataDefinition) instanceInput.getToscaFunction()).getPropertyName() : null)) - .forEach(oldInput -> oldInput.setType(property.getType())) - ); + if (null != instanceInputs) { + component.getProperties() + .forEach(property -> instanceInputs.getListToscaDataDefinition().stream() + .filter(instanceInput -> + instanceInput.getToscaFunction() instanceof ToscaGetFunctionDataDefinition && + property.getName().equals(instanceInput.getToscaFunction() != null ? + ((ToscaGetFunctionDataDefinition) instanceInput.getToscaFunction()).getPropertyName() : + null)) + .forEach(oldInput -> oldInput.setType(property.getType())) + ); + } templateOperation.setInputs(instanceInputs); //Implementation templateOperation.setImplementation(instanceOperation.getImplementation()); diff --git a/catalog-ui/src/app/ng2/components/logic/service-dependencies/service-dependencies.component.ts b/catalog-ui/src/app/ng2/components/logic/service-dependencies/service-dependencies.component.ts index 9a63dff739..a0588c0daa 100644 --- a/catalog-ui/src/app/ng2/components/logic/service-dependencies/service-dependencies.component.ts +++ b/catalog-ui/src/app/ng2/components/logic/service-dependencies/service-dependencies.component.ts @@ -30,6 +30,7 @@ import {CompositionService} from "../../../pages/composition/composition.service import {FilterConstraint} from "app/models/filter-constraint"; import {PropertyFilterConstraintUi} from "../../../../models/ui-models/property-filter-constraint-ui"; import {ConstraintOperatorType, FilterConstraintHelper} from "../../../../utils/filter-constraint-helper"; +import {CustomToscaFunction} from "../../../../models/default-custom-functions"; export enum SourceType { STATIC = 'static', @@ -99,6 +100,7 @@ export class ServiceDependenciesComponent implements OnInit, OnChanges { properties: string = ToscaFilterConstraintType.PROPERTIES; private componentInstancesConstraints: FilterConstraint[] = []; isEditable: boolean; + customToscaFunctions: Array; @Input() readonly: boolean; @Input() compositeService: ComponentMetadata; @@ -138,12 +140,24 @@ export class ServiceDependenciesComponent implements OnInit, OnChanges { this.parentServiceInputs = result.inputs; this.parentServiceProperties = result.properties; }); + this.initCustomToscaFunctions(); this.loadNodeFilter(); this.translateService.languageChangedObservable.subscribe((lang) => { I18nTexts.translateTexts(this.translateService); }); } + private initCustomToscaFunctions() { + if (!this.customToscaFunctions) { + this.customToscaFunctions = []; + this.topologyTemplateService.getDefaultCustomFunction().toPromise().then((data) => { + for (let customFunction of data) { + this.customToscaFunctions.push(new CustomToscaFunction(customFunction)); + } + }); + } + } + ngOnChanges(changes): void { if (changes.currentServiceInstance) { this.currentServiceInstance = changes.currentServiceInstance.currentValue; @@ -264,6 +278,7 @@ export class ServiceDependenciesComponent implements OnInit, OnChanges { 'parentServiceInputs': this.parentServiceInputs, 'parentServiceProperties': this.parentServiceProperties, 'selectedInstanceProperties': this.selectedInstanceProperties, + 'customToscaFunctions': this.customToscaFunctions, 'filterType': FilterType.PROPERTY, } ); @@ -298,6 +313,7 @@ export class ServiceDependenciesComponent implements OnInit, OnChanges { } createNodeFilter = (constraintType: string): void => { + this.customToscaFunctions = this.modalInstance.instance.dynamicContent.instance.customToscaFunctions; this.isLoading = true; this.topologyTemplateService.createServiceFilterConstraints( this.compositeService.uniqueId, @@ -372,9 +388,11 @@ export class ServiceDependenciesComponent implements OnInit, OnChanges { 'parentServiceInputs': this.parentServiceInputs, 'parentServiceProperties': this.parentServiceProperties, 'selectedInstanceProperties': this.selectedInstanceProperties, + 'customToscaFunctions': this.customToscaFunctions, 'filterType': FilterType.PROPERTY } ); + this.modalInstance.instance.open(); } 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 ad72adad22..7db332236b 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 @@ -49,6 +49,7 @@ export class ToscaCustomFunctionComponent implements OnInit { @Input() propertyType: string; @Input() propertySchemaType: string = undefined; @Input() isDefaultCustomFunction: boolean; + @Input() overridingType: PROPERTY_TYPES; @Output() onValidFunction: EventEmitter = new EventEmitter(); @Output() onValidityChange: EventEmitter = new EventEmitter(); @@ -194,7 +195,7 @@ export class ToscaCustomFunctionComponent implements OnInit { createProperty(value?: any): PropertyBEModel { const property = new PropertyBEModel(); if (this.type === this.GET_INPUT) { - property.type = this.propertyType; + property.type = this.overridingType ? this.overridingType.toString() : this.propertyType; if (this.propertySchemaType) { property.schemaType = this.propertySchemaType; } 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 0d5a4973da..db96f1cece 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 @@ -45,6 +45,7 @@ [propertyType]="property.type" [propertySchemaType]="property.schemaType" [componentInstanceMap]="componentInstanceMap" + [overridingType]="overridingType" [isDefaultCustomFunction]="isDefaultCustomFunction()" (onValidityChange)="onCustomFunctionValidityChange($event)"> diff --git a/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.html b/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.html index c90cfd8210..b5cc0cdc9e 100644 --- a/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.html +++ b/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.html @@ -77,6 +77,8 @@ @@ -103,6 +105,7 @@ @@ -123,6 +126,7 @@ diff --git a/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.ts b/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.ts index 5897f272b3..d560285be9 100644 --- a/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.ts +++ b/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.ts @@ -72,6 +72,7 @@ export class ServiceDependenciesEditorComponent implements OnInit { @Input() capabilityNameAndPropertiesMap: Map; @Input() filterType: FilterType; @Input() filterConstraint: PropertyFilterConstraintUi; + @Input() customToscaFunctions: Array; //output currentRule: PropertyFilterConstraintUi; @@ -100,7 +101,7 @@ export class ServiceDependenciesEditorComponent implements OnInit { selectedProperty: PropertyFEModel; selectedSourceType: string; componentInstanceMap: Map = new Map(); - customToscaFunctions: Array; + capabilityDropdownList: DropdownValue[] = []; validValuesToscaFunctionList: ToscaFunction[]; rangeToscaFunctionList: ToscaFunction[]; @@ -133,13 +134,15 @@ export class ServiceDependenciesEditorComponent implements OnInit { } private initCustomToscaFunctions() { - this.customToscaFunctions = []; - this.topologyTemplateService.getDefaultCustomFunction().toPromise().then((data) => { - for (let customFunction of data) { - this.customToscaFunctions.push(new CustomToscaFunction(customFunction)); - } - }); -} + if (!this.customToscaFunctions) { + this.customToscaFunctions = []; + this.topologyTemplateService.getDefaultCustomFunction().toPromise().then((data) => { + for (let customFunction of data) { + this.customToscaFunctions.push(new CustomToscaFunction(customFunction)); + } + }); + } + } private initCapabilityDropdown(): void { if (this.filterType == FilterType.CAPABILITY) { diff --git a/catalog-ui/src/app/utils/filter-constraint-helper.ts b/catalog-ui/src/app/utils/filter-constraint-helper.ts index 7ee9d27efe..2666bbfd81 100644 --- a/catalog-ui/src/app/utils/filter-constraint-helper.ts +++ b/catalog-ui/src/app/utils/filter-constraint-helper.ts @@ -27,9 +27,11 @@ export class FilterConstraintHelper { public static buildFilterConstraintLabel(constraint: FilterConstraint): string { let value; if (ToscaFunctionHelper.isValueToscaFunction(constraint.value)) { + console.error(constraint.value); const toscaFunction = ToscaFunctionHelper.convertObjectToToscaFunction(constraint.value); if (toscaFunction) { - value = toscaFunction.buildValueString(); + value = toscaFunction.value; + console.error(value); } else { value = JSON.stringify(constraint.value, null, 4); } diff --git a/catalog-ui/src/app/utils/tosca-function-helper.ts b/catalog-ui/src/app/utils/tosca-function-helper.ts index 714f22ef57..7cef768770 100644 --- a/catalog-ui/src/app/utils/tosca-function-helper.ts +++ b/catalog-ui/src/app/utils/tosca-function-helper.ts @@ -24,6 +24,7 @@ import {ToscaConcatFunction} from "../models/tosca-concat-function"; import {ToscaGetFunction} from "../models/tosca-get-function"; import {YamlFunction} from "../models/yaml-function"; import {ToscaFunction} from "../models/tosca-function"; +import {ToscaCustomFunction} from "../models/tosca-custom-function"; export class ToscaFunctionHelper { @@ -41,6 +42,8 @@ export class ToscaFunctionHelper { return new ToscaGetFunction(value); case ToscaFunctionType.YAML: return new YamlFunction(value); + case ToscaFunctionType.CUSTOM: + return new ToscaCustomFunction(value); case ToscaFunctionType.STRING: return { type: ToscaFunctionType.STRING, diff --git a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/FilterValueType.java b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/FilterValueType.java index 62a19b8041..30d86fda4e 100644 --- a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/FilterValueType.java +++ b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/FilterValueType.java @@ -35,6 +35,7 @@ public enum FilterValueType { GET_INPUT("get_input", "service_input"), GET_ATTRIBUTE("get_attribute", null), YAML("yaml", null), + CUSTOM("custom", null), CONCAT("concat", null), SEVERAL("several", null); diff --git a/common-be/src/main/java/org/openecomp/sdc/be/utils/PropertyFilterConstraintDataDefinitionHelper.java b/common-be/src/main/java/org/openecomp/sdc/be/utils/PropertyFilterConstraintDataDefinitionHelper.java index 6377152a13..1f7459c59d 100644 --- a/common-be/src/main/java/org/openecomp/sdc/be/utils/PropertyFilterConstraintDataDefinitionHelper.java +++ b/common-be/src/main/java/org/openecomp/sdc/be/utils/PropertyFilterConstraintDataDefinitionHelper.java @@ -22,17 +22,24 @@ package org.openecomp.sdc.be.utils; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; +import java.util.stream.Stream; import lombok.AccessLevel; import lombok.NoArgsConstructor; +import org.apache.commons.collections.CollectionUtils; 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.PropertyFilterConstraintDataDefinition; import org.openecomp.sdc.be.datatypes.elements.ToscaConcatFunction; +import org.openecomp.sdc.be.datatypes.elements.ToscaCustomFunction; import org.openecomp.sdc.be.datatypes.elements.ToscaFunction; import org.openecomp.sdc.be.datatypes.elements.ToscaFunctionParameter; import org.openecomp.sdc.be.datatypes.elements.ToscaFunctionType; @@ -81,9 +88,16 @@ public class PropertyFilterConstraintDataDefinitionHelper { if (!(toscaFunctionTypeObject instanceof String)) { return Optional.empty(); } - final ToscaFunctionType toscaFunctionType = ToscaFunctionType.findType((String) toscaFunctionTypeObject).orElse(null); + ToscaFunctionType toscaFunctionType = ToscaFunctionType.findType((String) toscaFunctionTypeObject).orElse(null); if (toscaFunctionType == null) { - return Optional.empty(); + if (((String) toscaFunctionTypeObject).equalsIgnoreCase("$get_input_ext") || + ((String) toscaFunctionTypeObject).equalsIgnoreCase("$juel") || + ((String) toscaFunctionTypeObject).equalsIgnoreCase("$other")) { + toscaFunctionType = ToscaFunctionType.CUSTOM; + } + else { + return Optional.empty(); + } } switch (toscaFunctionType) { case GET_INPUT: @@ -93,11 +107,256 @@ public class PropertyFilterConstraintDataDefinitionHelper { return readLegacyGetPropertyConstraintValue(filterValueAsMap, toscaFunctionTypeObject, toscaFunctionType); case CONCAT: return readLegacyConcatConstraintValue(filterValueAsMap, toscaFunctionTypeObject); + case CUSTOM: + return handleCustomFunction((Map)filterValueAsMap, (String)toscaFunctionTypeObject); + default: + return Optional.empty(); + } + } + + private static Optional handleCustomFunction(Map toscaFunctionPropertyValueMap, String functionType) { + 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 handleCustomFunctionGetInputType(toscaCustomFunction, functionValueObj); + } + return handelCustomFunctionCustomType(toscaCustomFunction, functionValueObj); + } + + private static Optional handleCustomFunctionGetInputType(ToscaCustomFunction toscaCustomFunction, Object functionValueObj) { + if (!(functionValueObj instanceof String) && !(functionValueObj instanceof List)) { + return Optional.empty(); + } + Map parameterMap = new HashMap<>(); + parameterMap.put(ToscaFunctionType.GET_INPUT.getName(), functionValueObj); + buildToscaFunctionBasedOnPropertyValue(parameterMap).ifPresent(toscaFunction -> { + if (toscaFunction instanceof ToscaFunctionParameter) { + toscaCustomFunction.addParameter((ToscaFunctionParameter) toscaFunction); + } + }); + return Optional.of(toscaCustomFunction); + } + + private static Optional buildToscaFunctionBasedOnPropertyValue(final Map toscaFunctionPropertyValueMap) { + if (!isPropertyValueToscaFunction(toscaFunctionPropertyValueMap)) { + return Optional.empty(); + } + final String functionType = toscaFunctionPropertyValueMap.keySet().iterator().next(); + final ToscaFunctionType toscaFunctionType = + ToscaFunctionType.findType(functionType).orElse(functionType.startsWith("$") ? ToscaFunctionType.CUSTOM : null); + if (toscaFunctionType == null) { + return Optional.empty(); + } + switch (toscaFunctionType) { + case GET_INPUT: { + return handleGetInputFunction(toscaFunctionPropertyValueMap, functionType); + } + case GET_PROPERTY: + case GET_ATTRIBUTE: { + return handleGetPropertyFunction(toscaFunctionPropertyValueMap, functionType, toscaFunctionType); + } + case CONCAT: + return handleConcatFunction(toscaFunctionPropertyValueMap, functionType); + case CUSTOM: + return handleCustomFunction(toscaFunctionPropertyValueMap, functionType); default: return Optional.empty(); } } + private static Optional handleConcatFunction(Map toscaFunctionPropertyValueMap, String functionType) { + final ToscaConcatFunction toscaConcatFunction = new ToscaConcatFunction(); + final Object functionValueObj = toscaFunctionPropertyValueMap.get(functionType); + if (!(functionValueObj instanceof List)) { + return Optional.empty(); + } + final List functionParameters = (List) functionValueObj; + if (functionParameters.size() < 2) { + return Optional.empty(); + } + functionParameters.forEach(parameter -> { + if (parameter instanceof String) { + final var stringParameter = new ToscaStringParameter(); + stringParameter.setValue((String) parameter); + toscaConcatFunction.addParameter(stringParameter); + return; + } + if (isPropertyValueToscaFunction(parameter)) { + buildToscaFunctionBasedOnPropertyValue((Map) parameter).ifPresent(toscaFunction -> { + if (toscaFunction instanceof ToscaFunctionParameter) { + toscaConcatFunction.addParameter((ToscaFunctionParameter) toscaFunction); + } + }); + return; + } + final var customYamlFunction = new CustomYamlFunction(); + customYamlFunction.setYamlValue(parameter); + toscaConcatFunction.addParameter(customYamlFunction); + }); + return Optional.of(toscaConcatFunction); + } + + private static Optional handleGetPropertyFunction(Map toscaFunctionPropertyValueMap, String functionType, + ToscaFunctionType toscaFunctionType) { + final ToscaGetFunctionDataDefinition toscaGetFunction = new ToscaGetFunctionDataDefinition(); + toscaGetFunction.setFunctionType( + toscaFunctionType == ToscaFunctionType.GET_PROPERTY ? ToscaGetFunctionType.GET_PROPERTY : ToscaGetFunctionType.GET_ATTRIBUTE + ); + final Object functionValueObj = toscaFunctionPropertyValueMap.get(functionType); + if (!(functionValueObj instanceof List)) { + return Optional.empty(); + } + final List functionParameters; + try { + functionParameters = ((List) functionValueObj).stream() + .map(object -> Objects.toString(object, null)) + .collect(Collectors.toList()); + } catch (final ClassCastException ignored) { + return Optional.empty(); + } + if (functionParameters.size() < 2) { + return Optional.empty(); + } + final String propertySourceType = functionParameters.get(0); + final PropertySource propertySource = PropertySource.findType(propertySourceType).orElse(null); + if (propertySource == PropertySource.SELF) { + toscaGetFunction.setPropertySource(propertySource); + } else { + toscaGetFunction.setPropertySource(PropertySource.INSTANCE); + toscaGetFunction.setSourceName(propertySourceType); + } + List propertySourceIndex = functionParameters.subList(1, functionParameters.size()); + 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); + } + + private static Optional handleGetInputFunction(Map toscaFunctionPropertyValueMap, String functionType) { + final ToscaGetFunctionDataDefinition toscaGetFunction = new ToscaGetFunctionDataDefinition(); + toscaGetFunction.setFunctionType(ToscaGetFunctionType.GET_INPUT); + toscaGetFunction.setPropertySource(PropertySource.SELF); + final Object functionValueObj = toscaFunctionPropertyValueMap.get(functionType); + if (!(functionValueObj instanceof List) && !(functionValueObj instanceof String)) { + return Optional.empty(); + } + if (functionValueObj instanceof String) { + toscaGetFunction.setPropertyPathFromSource(List.of((String) functionValueObj)); + } else { + final List functionParameters; + try { + functionParameters = ((List) functionValueObj).stream() + .map(object -> Objects.toString(object, null)) + .collect(Collectors.toList()); + } catch (final ClassCastException ignored) { + return Optional.empty(); + } + 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); + return Optional.of(toscaGetFunction); + } + + public static boolean isPropertyValueToscaFunction(final Object propValueObj) { + if (propValueObj instanceof Map) { + final Map propValueMap = (Map) propValueObj; + if (propValueMap.keySet().size() > 1) { + return false; + } + if (propValueMap.keySet().stream().anyMatch(keyValue -> keyValue.startsWith("$"))) { + return true; + } + + return Stream.of(ToscaFunctionType.GET_INPUT, ToscaFunctionType.GET_PROPERTY, ToscaFunctionType.GET_ATTRIBUTE, ToscaFunctionType.CONCAT) + .anyMatch(type -> propValueMap.containsKey(type.getName())); + } + return false; + } + + private static ToscaFunctionType getCustomFunctionType(String name) { + List customFunctions = + ConfigurationManager.getConfigurationManager().getConfiguration().getDefaultCustomToscaFunctions(); + if (CollectionUtils.isEmpty(customFunctions)) { + return ToscaFunctionType.CUSTOM; + } + Optional 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 static Optional handelCustomFunctionCustomType(ToscaCustomFunction toscaCustomFunction, Object functionValueObj) { + if (!(functionValueObj instanceof List)) { + return Optional.empty(); + } + final List functionParameters = (List) functionValueObj; + functionParameters.forEach(parameter -> { + if (parameter instanceof String) { + final var stringParameter = new ToscaStringParameter(); + stringParameter.setValue((String) parameter); + toscaCustomFunction.addParameter(stringParameter); + return; + } + if (isPropertyValueToscaFunction(parameter)) { + buildToscaFunctionBasedOnPropertyValue((Map) parameter).ifPresent(toscaFunction -> { + if (toscaFunction instanceof ToscaFunctionParameter) { + toscaCustomFunction.addParameter((ToscaFunctionParameter) toscaFunction); + } + }); + return; + } + final var customYamlFunction = new CustomYamlFunction(); + customYamlFunction.setYamlValue(parameter); + toscaCustomFunction.addParameter(customYamlFunction); + }); + return Optional.of(toscaCustomFunction); + } + public static Optional convertFromToscaFunctionType(final ToscaFunctionType toscaFunctionType) { return FilterValueType.findByName(toscaFunctionType.getName()); } @@ -244,8 +503,12 @@ public class PropertyFilterConstraintDataDefinitionHelper { if (valueAsMap.containsKey(ToscaFunctionType.GET_INPUT.getName())) { return FilterValueType.GET_INPUT; } + if (valueAsMap.containsKey("$get_input_ext") || + valueAsMap.containsKey("$juel") || + valueAsMap.containsKey("$other")) { + return FilterValueType.CUSTOM; + } } - return FilterValueType.STATIC; } -- cgit 1.2.3-korg