UI support for default custom function names with get_input structure 98/134498/5
authorJvD_Ericsson <jeff.van.dam@est.tech>
Thu, 4 May 2023 12:27:26 +0000 (13:27 +0100)
committerMichael Morris <michael.morris@est.tech>
Thu, 18 May 2023 10:41:07 +0000 (10:41 +0000)
Issue-ID: SDC-4493
Signed-off-by: JvD_Ericsson <jeff.van.dam@est.tech>
Change-Id: Iba3eda9bb5d57aabbe86045b6150564e17a0ff3e

13 files changed:
catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/ToscaFunctionYamlParsingHandler.java
catalog-be/src/test/java/org/openecomp/sdc/be/components/csar/ToscaFunctionYamlParsingHandlerTest.java
catalog-ui/src/app/ng2/components/logic/properties-table/properties-table.component.html
catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-custom-function/tosca-custom-function.component.html
catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-custom-function/tosca-custom-function.component.ts
catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-function.component.html
catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-function.component.ts
catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-get-function/tosca-get-function.component.html
catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-get-function/tosca-get-function.component.ts
common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/ToscaCustomFunction.java
common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/ToscaFunctionJsonDeserializer.java
common-be/src/test/java/org/openecomp/sdc/be/datatypes/elements/ToscaFunctionJsonDeserializerTest.java
common-be/src/test/resources/toscaFunctionJsonDeserializer/customFunctionGetInputType.json [new file with mode: 0644]

index 0b9432b..0651e35 100644 (file)
@@ -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.
      *
index 1dfb7a9..4791015 100644 (file)
@@ -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);
 
@@ -157,6 +161,32 @@ class ToscaFunctionYamlParsingHandlerTest {
         assertGetInput(getFunction, List.of("inputName"));
     }
 
+    @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()));
@@ -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
index 526ccf2..b348d81 100644 (file)
@@ -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">
index f77af54..831ce49 100644 (file)
     </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>
index 7746d38..35f1649 100644 (file)
@@ -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 {
index 65a024c..0d5a497 100644 (file)
                                  (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>
index ecaff25..b955983 100644 (file)
@@ -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 {
index 387bb5c..4a9e110 100644 (file)
@@ -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>
index 284c559..1b0a1a3 100644 (file)
@@ -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;
         }
     }
index 3f0c4fa..981d4ec 100644 (file)
 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())
         );
     }
 
index 2e57a41..de8e30b 100644 (file)
@@ -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");
index d7c2e7c..5128c63 100644 (file)
@@ -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 (file)
index 0000000..81ae571
--- /dev/null
@@ -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