Provide input name when declaring service property as input 39/133239/12
authorKrupaNagabhushan <krupa.nagabhushan@est.tech>
Fri, 10 Feb 2023 18:41:01 +0000 (18:41 +0000)
committerVasyl Razinkov <vasyl.razinkov@est.tech>
Fri, 10 Mar 2023 11:25:05 +0000 (11:25 +0000)
Issue-ID: SDC-4385
Signed-off-by: KrupaNagabhushan <krupa.nagabhushan@est.tech>
Change-Id: I2b71e04b97ba69195380d2aa29d9d98a3bd5e981

23 files changed:
catalog-be/src/main/docker/backend/chef-repo/cookbooks/sdc-catalog-be/files/default/error-configuration.yaml
catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InputsBusinessLogic.java
catalog-be/src/main/java/org/openecomp/sdc/be/components/property/DefaultPropertyDeclarator.java
catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaExportHandler.java
catalog-dao/src/main/java/org/openecomp/sdc/be/dao/api/ActionStatus.java
catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstancePropInput.java
catalog-ui/src/app/models/properties-inputs/derived-fe-property.ts
catalog-ui/src/app/models/properties-inputs/property-be-model.ts
catalog-ui/src/app/models/properties-inputs/property-declare-api-model.ts
catalog-ui/src/app/modules/directive-module.ts
catalog-ui/src/app/ng2/app.module.ts
catalog-ui/src/app/ng2/pages/properties-assignment/declare-input/declare-input.component.html [new file with mode: 0644]
catalog-ui/src/app/ng2/pages/properties-assignment/declare-input/declare-input.component.spec.ts [new file with mode: 0644]
catalog-ui/src/app/ng2/pages/properties-assignment/declare-input/declare-input.component.ts [new file with mode: 0644]
catalog-ui/src/app/ng2/pages/properties-assignment/declare-input/declare-input.module.ts [new file with mode: 0644]
catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.page.component.html
catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.page.component.ts
catalog-ui/src/app/ng2/pages/properties-assignment/services/properties.utils.ts
catalog-ui/src/assets/languages/en_US.json
integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/execute/sanity/ServiceTemplateDesignUiTests.java
integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/ResourcePropertiesAssignmentInputTab.java
integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/ResourcePropertiesAssignmentPage.java
integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/ResourcePropertiesAssignmentTab.java

index 0530298..fe32ad0 100644 (file)
@@ -2869,4 +2869,11 @@ errors:
         code: 400,
         message: "Cannot change this properties constraints as the resource is an instance.",
         messageId: "SVC4015"
+    }
+
+    #---------SVC4016-----------------------------
+    INPUT_NAME_ALREADY_EXIST: {
+        code: 400,
+        message: "Input name already exist.",
+        messageId: "SVC4016"
     }
\ No newline at end of file
index 12a6936..b632abf 100644 (file)
@@ -30,6 +30,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Optional;
+import java.util.concurrent.atomic.AtomicReference;
 import java.util.stream.Collectors;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.collections4.ListUtils;
@@ -398,6 +399,11 @@ public class InputsBusinessLogic extends BaseBusinessLogic {
         try {
             validateUserExists(userId);
             component = getAndValidateComponentForCreate(userId, componentId, componentType, shouldLockComp);
+            StorageOperationStatus status = validateInputName(component, componentInstInputsMapUi);
+            if (status != StorageOperationStatus.OK) {
+                log.debug("Input name already exist");
+                throw new ByResponseFormatComponentException(componentsUtils.getResponseFormat(ActionStatus.INPUT_NAME_ALREADY_EXIST));
+            }
             result = propertyDeclarationOrchestrator.declarePropertiesToInputs(component, componentInstInputsMapUi).left()
                 .bind(inputsToCreate -> prepareInputsForCreation(userId, componentId, inputsToCreate)).right()
                 .map(componentsUtils::getResponseFormat);
@@ -423,6 +429,31 @@ public class InputsBusinessLogic extends BaseBusinessLogic {
         }
     }
 
+    private StorageOperationStatus validateInputName(final Component component, final ComponentInstInputsMap componentInstInputsMap) {
+        AtomicReference<StorageOperationStatus> storageOperationStatus = new AtomicReference<>(StorageOperationStatus.OK);
+        Map<String, List<ComponentInstancePropInput>> inputDeclaredProperties = new HashMap<>();
+        if (MapUtils.isNotEmpty(componentInstInputsMap.getComponentInstanceProperties())) {
+            inputDeclaredProperties = componentInstInputsMap.getComponentInstanceProperties();
+        } else if (MapUtils.isNotEmpty(componentInstInputsMap.getServiceProperties())) {
+            inputDeclaredProperties = componentInstInputsMap.getServiceProperties();
+        }
+
+        if (MapUtils.isNotEmpty(inputDeclaredProperties) && CollectionUtils.isNotEmpty(component.getInputs())) {
+            inputDeclaredProperties.values()
+                .forEach(componentInstancePropInputs ->
+                    componentInstancePropInputs
+                        .forEach(componentInstancePropInput -> component.getInputs()
+                            .forEach(existingInput -> {
+                                if (existingInput.getName().equals(componentInstancePropInput.getInputName())) {
+                                    storageOperationStatus.set(StorageOperationStatus.INVALID_VALUE);
+                                }
+                            })
+                        )
+                );
+        }
+        return storageOperationStatus.get();
+    }
+
     /**
      * Creates a list input with a data type which has properties specified.
      *
index eba66d2..31a27b0 100644 (file)
@@ -255,7 +255,12 @@ public abstract class DefaultPropertyDeclarator<PROPERTYOWNER extends Properties
             generatedInputPrefix =
                 generatedInputPrefix == null || generatedInputPrefix.isEmpty() ? capName : generatedInputPrefix + UNDERSCORE + capName;
         }
-        String generatedInputName = generateInputName(generatedInputPrefix, propInput);
+        String generatedInputName = null;
+        if (StringUtils.isNotEmpty(propInput.getInputName())) {
+            generatedInputName = propInput.getInputName();
+        } else {
+            generatedInputName = generateInputName(generatedInputPrefix, propInput);
+        }
         log.debug("createInput: propOwner.uniqueId={}, propInput.parentUniqueId={}", propertiesOwner.getUniqueId(), propInput.getParentUniqueId());
         return createInputFromProperty(component.getUniqueId(), propertiesOwner, generatedInputName, propInput, prop);
     }
index 245fec3..186bcd2 100644 (file)
@@ -1764,8 +1764,24 @@ public class ToscaExportHandler {
         if (component == null || CollectionUtils.isEmpty(component.getInputs())) {
             return Collections.emptyMap();
         }
-        return component.getInputs().stream().filter(InputDefinition::isMappedToComponentProperty).map(PropertyDataDefinition::getName)
-            .collect(Collectors.toMap(inputName -> inputName, inputName -> new String[]{inputName}, (inputName1, inputName2) -> inputName1));
+        Map<String, String[]> propertyMapping = new HashMap<>();
+        List<InputDefinition> propertyMappedInputList = component.getInputs().stream().filter(InputDefinition::isMappedToComponentProperty).collect(
+            Collectors.toList());
+
+        if (CollectionUtils.isNotEmpty(propertyMappedInputList)) {
+            propertyMappedInputList.forEach(inputDefinition -> {
+                if (StringUtils.isNotEmpty(inputDefinition.getPropertyId())) {
+                    Optional<PropertyDefinition> property = component.getProperties().stream()
+                        .filter(propertyDefinition -> propertyDefinition.getUniqueId().equals(inputDefinition.getPropertyId())).findFirst();
+                    if (property.isPresent()) {
+                        propertyMapping.put(property.get().getName(), new String[]{inputDefinition.getName()});
+                    }
+                } else {
+                    propertyMapping.put(inputDefinition.getName(), new String[]{inputDefinition.getName()});
+                }
+            });
+        }
+        return propertyMapping;
     }
 
     private Map<String, String[]> buildSubstitutionMappingAttributesMapping(final Component component) {
index d2b1409..2717c0c 100644 (file)
@@ -92,7 +92,7 @@ public enum ActionStatus {
     // cache
     CONVERT_COMPONENT_ERROR, COMPONENT_NOT_FOUND,
     // Inputs
-    INPUT_IS_NOT_CHILD_OF_COMPONENT, CFVC_LOOP_DETECTED, INPUT_ALREADY_EXIST,
+    INPUT_IS_NOT_CHILD_OF_COMPONENT, CFVC_LOOP_DETECTED, INPUT_ALREADY_EXIST, INPUT_NAME_ALREADY_EXIST,
     // Outputs
     OUTPUT_IS_NOT_CHILD_OF_COMPONENT, OUTPUT_ALREADY_EXIST,
     //Forwarding Path related
index 048a952..c32838d 100644 (file)
  */
 package org.openecomp.sdc.be.model;
 
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
 public class ComponentInstancePropInput extends ComponentInstanceProperty {
 
     private String propertiesName;
     private PropertyDefinition input;
+    private String inputName;
 
     public ComponentInstancePropInput() {
         super();
@@ -32,22 +38,6 @@ public class ComponentInstancePropInput extends ComponentInstanceProperty {
         super(p);
     }
 
-    public String getPropertiesName() {
-        return propertiesName;
-    }
-
-    public void setPropertiesName(String propertiesName) {
-        this.propertiesName = propertiesName;
-    }
-
-    public PropertyDefinition getInput() {
-        return input;
-    }
-
-    public void setInput(PropertyDefinition input) {
-        this.input = input;
-    }
-
     public String[] getParsedPropNames() {
         String[] tokens = null;
         if (propertiesName != null && !propertiesName.isEmpty()) {
index c2ea1ec..7ca1fee 100644 (file)
@@ -45,7 +45,8 @@ export class DerivedFEProperty extends PropertyBEModel {
     canBeDeclared: boolean;
     mapKey: string;
     mapKeyError: string;
-    mapInlist: boolean;
+    mapInlist: boolean
+    inputName: string;
     parentMapKey: string;
 
     constructor(property: PropertyBEModel, parentName?: string, createChildOfListOrMap?: boolean, key?:string, value?:any) {
@@ -69,7 +70,7 @@ export class DerivedFEProperty extends PropertyBEModel {
             this.parentName = parentName;
             this.propertiesName = parentName + '#' + this.name;
             
-            if (property.type == PROPERTY_TYPES.LIST) { 
+            if (property.type == PROPERTY_TYPES.LIST) {
                 let parentKey : string = null;
                 if(property.value != null) {
                     const valueJson = JSON.parse(property.value);
@@ -128,6 +129,7 @@ export class DerivedFEProperty extends PropertyBEModel {
         // this.constraints = property ? property.constraints : null;
         this.valueObjIsValid = true;
         this.derivedDataType = this.getDerivedPropertyType();
+        this.inputName = property.inputName;
     }
 
     public getActualMapKey() {
index ae72977..e4c0f81 100644 (file)
@@ -69,6 +69,7 @@ export class PropertyBEModel {
     parentPropertyType: string;
     subPropertyInputPath: string;
     inputPath: string;
+    inputName: string;
     toscaPresentation: ToscaPresentationData;
     metadata: Metadata;
     propertyConstraints: any;
@@ -103,6 +104,7 @@ export class PropertyBEModel {
             this.toscaPresentation = property.toscaPresentation;
             this.getPolicyValues = property.getPolicyValues;
             this.inputPath = property.inputPath;
+            this.inputName = property.inputName;
             this.metadata = property.metadata;
             if (property.toscaFunction) {
                 this.toscaFunction = property.toscaFunction;
index 5b1c120..84970ad 100644 (file)
@@ -25,6 +25,7 @@ import { PropertyBEModel, PropertyFEModel, DerivedFEProperty } from "../../model
 export class PropertyDeclareAPIModel extends PropertyBEModel{
     input: PropertyBEModel;
     propertiesName: string;
+    inputName: string;
 
 
     constructor(property: PropertyFEModel, childProperty?: DerivedFEProperty) {
@@ -32,6 +33,7 @@ export class PropertyDeclareAPIModel extends PropertyBEModel{
         if (childProperty) {
             this.input = childProperty;
             this.propertiesName = childProperty.propertiesName;
+            this.inputName = childProperty.inputName;
         }
     }
 
index adc88cb..40e701a 100644 (file)
@@ -99,6 +99,7 @@ import {ToscaFunctionComponent} from '../ng2/pages/properties-assignment/tosca-f
 import {ConstraintsComponent} from '../ng2/pages/properties-assignment/constraints/constraints.component';
 import {TypeWorkspaceComponent} from "../ng2/pages/type-workspace/type-workspace.component";
 import {TypeWorkspaceGeneralComponent} from "../ng2/pages/type-workspace/type-workspace-general/type-workspace-general.component";
+import {DeclareInputComponent} from "../ng2/pages/properties-assignment/declare-input/declare-input.component";
 
 let moduleName: string = 'Sdc.Directives';
 let directiveModule: ng.IModule = angular.module(moduleName, []);
@@ -342,3 +343,9 @@ directiveModule.directive('appTypeWorkspaceGeneral', downgradeComponent({
   inputs: [],
   outputs: []
 }) as angular.IDirectiveFactory);
+
+directiveModule.directive('declareInput', downgradeComponent({
+  component: DeclareInputComponent,
+  inputs: ['property'],
+  outputs: []
+}) as angular.IDirectiveFactory);
index 1e23bb6..0c5b10f 100644 (file)
@@ -110,6 +110,7 @@ import {ModelService} from "./services/model.service";
 import {ToscaArtifactService} from "./services/tosca-artifact.service";
 import {InterfaceDefinitionModule} from "./pages/interface-definition/interface-definition.module";
 import {TypeWorkspaceModule} from "./pages/type-workspace/type-workspace.module";
+import {DeclareInputModule} from "./pages/properties-assignment/declare-input/declare-input.module";
 
 declare const __ENV__: string;
 
@@ -158,6 +159,7 @@ export function configServiceFactory(config: ConfigService, authService: Authent
     PropertiesAssignmentModule,
     AttributesOutputsModule,
     PropertyCreatorModule,
+    DeclareInputModule,
     DeclareListModule,
     ToscaFunctionModule,
     ConstraintsModule,
diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/declare-input/declare-input.component.html b/catalog-ui/src/app/ng2/pages/properties-assignment/declare-input/declare-input.component.html
new file mode 100644 (file)
index 0000000..19b2359
--- /dev/null
@@ -0,0 +1,22 @@
+<!--
+  ~ ============LICENSE_START=======================================================
+  ~  Copyright (C) 2023 Nordix Foundation
+  ~  ================================================================================
+  ~  Licensed under the Apache License, Version 2.0 (the "License");
+  ~  you may not use this file except in compliance with the License.
+  ~  You may obtain a copy of the License at
+  ~
+  ~        http://www.apache.org/licenses/LICENSE-2.0
+  ~  Unless required by applicable law or agreed to in writing, software
+  ~  distributed under the License is distributed on an "AS IS" BASIS,
+  ~  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~  See the License for the specific language governing permissions and
+  ~  limitations under the License.
+  ~
+  ~  SPDX-License-Identifier: Apache-2.0
+  ~  ============LICENSE_END=========================================================
+  -->
+
+<div class="declare-input">
+  <input id="myText" type="text" (keyup)="setInputName($event)"/>
+</div>
diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/declare-input/declare-input.component.spec.ts b/catalog-ui/src/app/ng2/pages/properties-assignment/declare-input/declare-input.component.spec.ts
new file mode 100644 (file)
index 0000000..c3fa1f5
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 Nordix Foundation
+ *  ================================================================================
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *  SPDX-License-Identifier: Apache-2.0
+ *  ============LICENSE_END=========================================================
+ */
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { DeclareInputComponent } from './declare-input.component';
+
+describe('DeclareInputComponent', () => {
+  let component: DeclareInputComponent;
+  let fixture: ComponentFixture<DeclareInputComponent>;
+
+  beforeEach(async(() => {
+    TestBed.configureTestingModule({
+      declarations: [ DeclareInputComponent ]
+    })
+    .compileComponents();
+  }));
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(DeclareInputComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/declare-input/declare-input.component.ts b/catalog-ui/src/app/ng2/pages/properties-assignment/declare-input/declare-input.component.ts
new file mode 100644 (file)
index 0000000..d156383
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 Nordix Foundation
+ *  ================================================================================
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *  SPDX-License-Identifier: Apache-2.0
+ *  ============LICENSE_END=========================================================
+ */
+import {Component, Input, OnInit} from '@angular/core';
+import {FormControl, FormGroup} from "@angular/forms";
+
+@Component({
+  selector: 'declare-input',
+  templateUrl: './declare-input.component.html'
+})
+export class DeclareInputComponent implements OnInit {
+  inputNameForm: FormControl = new FormControl(undefined);
+  formGroup: FormGroup = new FormGroup({
+    'inputName': this.inputNameForm,
+  });
+  inputName: string;
+  constructor() { }
+  ngOnInit() {
+  }
+  setInputName(event) {
+    this.inputName = event.target.value;
+    this.inputNameForm.setValue(this.inputName);
+  }
+
+}
diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/declare-input/declare-input.module.ts b/catalog-ui/src/app/ng2/pages/properties-assignment/declare-input/declare-input.module.ts
new file mode 100644 (file)
index 0000000..0dae0a2
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 Nordix Foundation
+ *  ================================================================================
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *  SPDX-License-Identifier: Apache-2.0
+ *  ============LICENSE_END=========================================================
+ */
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { FormsModule } from '@angular/forms';
+import {DeclareInputComponent} from "./declare-input.component";
+
+@NgModule({
+    imports: [
+        CommonModule,
+        FormsModule
+    ],
+    declarations: [DeclareInputComponent],
+    exports: [DeclareInputComponent],
+    entryComponents: [
+        DeclareInputComponent
+    ],
+})
+
+export class DeclareInputModule { }
index 1eed6df..36d316e 100644 (file)
                     <span class="sprite search-icon" data-tests-id="search-button"></span>
                     <filter-properties-assignment *ngIf="isPropertiesTabSelected" #advanceSearch class="advance-search" [componentType]="component.componentType" (searchProperties)="searchPropertiesInstances($event)"></filter-properties-assignment>
                 </div>
-                <button (click)="selectToscaFunctionAndValues()"
+                <button (click)="openToscaGetFunctionModal()"
                         *ngIf="isPropertiesTabSelected && !isSelf()"
                         [disabled]="(checkedPropertiesCount != 1 || isReadonly || hasChangedData) && !enableToscaFunction"
                         class="tlv-btn blue declare-button"
                         data-tests-id="declare-button select-tosca-function">{{'TOSCA_FUNCTION_LABEL' | translate}}</button>
-                <button class="tlv-btn blue declare-button" [disabled]="!checkedPropertiesCount || isReadonly || hasChangedData" (click)="declareProperties()" data-tests-id="declare-button declare-input">Declare Input</button>
+                <button class="tlv-btn blue declare-button" [disabled]="!checkedPropertiesCount || isReadonly || hasChangedData" (click)="openAddInputNameAndDeclareInputModal()" data-tests-id="declare-button declare-input">Declare Input</button>
                 <button class="tlv-btn blue declare-button" [disabled]="!checkedPropertiesCount || isReadonly || hasChangedData || isSelf()" (click)="declarePropertiesToPolicies()" data-tests-id="declare-button declare-policy">Declare Policy</button>
                 <button class="tlv-btn blue declare-button" [disabled]="!checkedPropertiesCount || checkedChildPropertiesCount || isReadonly || hasChangedData" (click)="declareListProperties()" data-tests-id="declare-but($event)ton declare-list-input">Create List Input</button>
             </div>
index a1e4f41..2592227 100644 (file)
@@ -70,6 +70,7 @@ import {Observable} from "rxjs";
 import {TranslateService} from "../../shared/translator/translate.service";
 import {ToscaFunction} from "../../../models/tosca-function";
 import {SubPropertyToscaFunction} from "../../../models/sub-property-tosca-function";
+import {DeclareInputComponent} from "./declare-input/declare-input.component";
 
 const SERVICE_SELF_TITLE = "SELF";
 @Component({
@@ -728,7 +729,7 @@ export class PropertiesAssignmentComponent {
     }
 
     /*** DECLARE PROPERTIES/INPUTS ***/
-    declareProperties = (): void => {
+    declareInputFromProperties = (inputName:string): void => {
         console.debug("==>" + this.constructor.name + ": declareProperties");
 
         let selectedComponentInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
@@ -743,6 +744,9 @@ export class PropertiesAssignmentComponent {
                 if (!this.isInput(selectedInstanceData.originType)) {
                     // convert Property FE model -> Property BE model, extract only checked
                     selectedComponentInstancesProperties[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
+                    if (inputName) {
+                        selectedComponentInstancesProperties[instanceId][0].inputName = inputName;
+                    }
                 } else {
                     selectedComponentInstancesInputs[instanceId] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
                 }
@@ -801,6 +805,37 @@ export class PropertiesAssignmentComponent {
             }, error => {}); //ignore error
     };
 
+    private openAddInputNameAndDeclareInputModal = (): void => {
+        const modalTitle = this.translateService.translate('ADD_INPUT_NAME_TO_DECLARE');
+        const modalButtons = [];
+        const modal = this.modalService.createCustomModal(new ModalModel(
+            'sm',
+            modalTitle,
+            null,
+            modalButtons,
+            null /* type */
+        ));
+        modalButtons.push(new ButtonModel(this.translateService.translate('MODAL_SAVE'), 'blue',
+            () => {
+                const inputName: string = modal.instance.dynamicContent.instance.inputNameForm.value;
+                if (inputName) {
+                    this.declareInputFromProperties(inputName);
+                } else {
+                    this.notification.warning({
+                        message: 'Failed to set input name',
+                        title: 'Warning'
+                    });
+                }
+                this.modalService.closeCurrentModal();
+            }
+        ));
+        modalButtons.push(new ButtonModel(this.translateService.translate('MODAL_CANCEL'), 'outline grey', () => {
+            this.modalService.closeCurrentModal();
+        }));
+        this.modalService.addDynamicContentToModal(modal, DeclareInputComponent, {});
+        modal.instance.open();
+    }
+
     declareListProperties = (): void => {
         // get selected properties
         let selectedComponentInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
index 0b984ac..bc5345c 100644 (file)
@@ -65,9 +65,6 @@ export class PropertiesUtils {
                     newFEProp.updateExpandedChildPropertyId(newFEProp.name); //display only the first level of children
                     this.dataTypeService.checkForCustomBehavior(newFEProp);
 
-                    if (newFEProp.isToscaFunction()) {
-                        return;
-                    }
                     //if this prop (or any children) are declared, set isDeclared and disable checkbox on parents/children
                     if (newFEProp.getInputValues && newFEProp.getInputValues.length) {
                         newFEProp.getInputValues.forEach(propInputDetail => {
index 5828884..1881328 100644 (file)
   "=========== PROPERTIES ASSIGNMENT DECLARE AS POLICY ===========": "",
   "DELETE_POLICY_TITLE": "Delete Policy",
   "DELETE_POLICY_MSG": "Are you sure you want to delete policy '{{policyName}}'?",
+  "=========== PROPERTIES ASSIGNMENT DECLARE AS INPUT ===========": "",
+  "ADD_INPUT_NAME_TO_DECLARE": "Enter name of input to be created",
   "=========== PROPERTIES ASSIGNMENT TOSCA FUNCTION BUTTON ===========": "",
   "TOSCA_FUNCTION_LABEL": "TOSCA function",
   "TOSCA_FUNCTION_PROPERTY_SOURCE_LABEL": "Property Source",
index 7409588..6652ada 100644 (file)
@@ -485,9 +485,9 @@ public class ServiceTemplateDesignUiTests extends SetupCDTest {
 
     private void declareInputToBaseService(ResourcePropertiesAssignmentPage propertiesAssignmentPage, String propertyName) {
         propertiesAssignmentPage.selectProperty(propertyName);
-        propertiesAssignmentPage.clickOnDeclareInput();
+        propertiesAssignmentPage.clickOnDeclareInput("inputName1");
         propertiesAssignmentPage.clickInputTab(propertyName);
-        propertiesAssignmentPage.isInputPresent(vfResourceCreateData.getName() + "_" + propertyName);
+        propertiesAssignmentPage.isInputPresent("inputName1");
     }
 
     private void declareInputToInstanceProperties(ResourcePropertiesAssignmentPage propertiesAssignmentPage, String propertyName) {
@@ -495,9 +495,9 @@ public class ServiceTemplateDesignUiTests extends SetupCDTest {
         propertiesAssignmentPage.loadCompositionTab();
         propertiesAssignmentPage.loadComponentInstanceProperties(vfcs.get(0).getName().concat(" 0"));
         propertiesAssignmentPage.selectProperty(propertyName);
-        propertiesAssignmentPage.clickOnDeclareInput();
+        propertiesAssignmentPage.clickOnDeclareInput("inputName2");
         propertiesAssignmentPage.clickInputTab(propertyName);
-        propertiesAssignmentPage.isInputPresent(vfResourceCreateData.getName() + "_" + vfcs.get(0).getName());
+        propertiesAssignmentPage.isInputPresent("inputName2");
     }
 
     private CreateVfFlow createVF() {
@@ -815,7 +815,7 @@ public class ServiceTemplateDesignUiTests extends SetupCDTest {
         final Map<String, Object> inputsTosca = getMapEntry(topologyTemplateTosca, "inputs");
         assertThat(String.format("'%s' should contain a inputs entry", toscaYaml), inputsTosca, notNullValue());
         assertEquals(2, inputsTosca.keySet().stream()
-            .filter(s -> (s.contains("resourceSubtype") || s.contains("property1"))).count());
+            .filter(s -> (s.contains("inputName"))).count());
         final Map<String, Object> substitutionMapping = getMapEntry(topologyTemplateTosca, "substitution_mappings");
         assertThat(String.format("'%s' should contain a substitution_mappings entry", toscaYaml), substitutionMapping,
             notNullValue());
index b83be25..937740b 100644 (file)
@@ -136,7 +136,7 @@ public class ResourcePropertiesAssignmentInputTab extends AbstractPageObject {
     public boolean isInputPresent(final String inputName) {
         isInputPropertiesTableLoaded();
         try {
-            waitForElementVisibility(By.xpath(XpathSelector.INPUT_CHECKBOX.formatXpath(inputName)), 5);
+            waitForElementVisibility(By.xpath(XpathSelector.INPUT_TABLE.formatXpath(inputName)), 5);
         } catch (final Exception ignored) {
             return false;
         }
@@ -151,7 +151,7 @@ public class ResourcePropertiesAssignmentInputTab extends AbstractPageObject {
     private enum XpathSelector {
         INPUT_TAB("//*[contains(@data-tests-id, 'Inputs') and contains(@class, 'active')]"),
         PROPERTIES_TABLE("//div[contains(@class,'properties-table')]"),
-        INPUT_CHECKBOX("//checkbox[@data-tests-id='%s']"),
+        INPUT_TABLE("//*[contains(@class, 'property-name') and text()='%s']"),
         NO_DATA_MESSAGE("//div[contains(@class,'no-data') and text()='No data to display']"),
         PROPERTY_SAVE_BTN("//button[@data-tests-id='properties-save-button']"),
         PROPERTY_SAVE_MESSAGE("//div[contains(text(), 'Successfully saved')]"),
index cb4345c..83d4c3f 100644 (file)
@@ -138,8 +138,8 @@ public class ResourcePropertiesAssignmentPage extends ComponentPage {
         resourcePropertiesAssignmentTab.loadComponentInstanceProperties(instanceName);
     }
 
-    public void clickOnDeclareInput(){
-        resourcePropertiesAssignmentTab.clickOnDeclareInput();
+    public void clickOnDeclareInput(final String inputName){
+        resourcePropertiesAssignmentTab.clickOnDeclareInput(inputName);
     }
 
     public void loadCompositionTab(){
index 81ce7ff..2b3d2e0 100644 (file)
@@ -344,8 +344,16 @@ public class ResourcePropertiesAssignmentTab extends AbstractPageObject {
         waitToBeClickable(By.xpath(ResourcePropertiesAssignmentTab.XpathSelector.INSTANCE_SPAN.getXpath(instanceName))).click();
     }
 
-    public void clickOnDeclareInput(){
+    public void clickOnDeclareInput(final String inputName){
         waitToBeClickable(By.xpath(ResourcePropertiesAssignmentTab.XpathSelector.DECLARE_INPUT_BTN.getXpath())).click();
+        declareInputWithSetInputName(inputName);
+    }
+
+    private void declareInputWithSetInputName(final String inputName) {
+        final By setInputNameLocator = By.xpath(XpathSelector.SET_INPUT_NAME_FIELD.getXpath());
+        final WebElement inputNameField = waitForElementVisibility(setInputNameLocator, 5);
+        inputNameField.sendKeys(inputName);
+        waitToBeClickable(By.xpath(XpathSelector.INPUT_NAME_SAVE_BTN.getXpath())).click();
     }
 
     public void loadCompositionTab(){
@@ -364,6 +372,7 @@ public class ResourcePropertiesAssignmentTab extends AbstractPageObject {
         SOFTWARE_VERSION_PROPERTY_CHECKBOX("software_versions", "//checkbox[@data-tests-id='%s']"),
         SOFTWARE_VERSION_INPUT("value-prop-software_versions", "//input[starts-with(@data-tests-id,'%s')]"),
         PROPERTY_CHECKBOX("//checkbox[@data-tests-id='%s']"),
+        SET_INPUT_NAME_FIELD("//*[@id=\"myText\"]"),
         PROPERTY_SAVE_BTN("properties-save-button", "//button[@data-tests-id='%s']"),
         PROPERTY_ADD_RIGHT_COLUMN_DIV("right-column", "//div[@class='%s']"),
         PROPERTY_ADD_BTN("add-btn", "//div[contains(@class,'%s')]"),
@@ -376,6 +385,7 @@ public class ResourcePropertiesAssignmentTab extends AbstractPageObject {
         PROPERTY_TYPES("//*[contains(@data-tests-id, 'propertyType')]"),
         PROPERTY_NAMES("//*[contains(@data-tests-id, 'propertyName')]"),
         DECLARE_INPUT_BTN("declare-button declare-input", "//button[@data-tests-id='%s']"),
+        INPUT_NAME_SAVE_BTN("//button[@data-tests-id='Save']"),
         COMPOSITION_TAB("Composition", "//div[contains(@class,'tab') and contains(text(), '%s')]"),
         INSTANCE_SPAN("//span[@data-tests-id='%s']");