Allow property to take its value from defined input list 27/120227/2
authorKrupaNagabhushan <krupa.nagabhushan@est.tech>
Tue, 12 Jan 2021 13:41:59 +0000 (13:41 +0000)
committerChristophe Closset <christophe.closset@intl.att.com>
Fri, 9 Apr 2021 06:46:27 +0000 (06:46 +0000)
Issue-ID: SDC-3547
Change-Id: Ic438e8f8943d0f1c656e386611b88b25f879e83b
Signed-off-by: KrupaNagabhushan <krupa.nagabhushan@est.tech>
Signed-off-by: andre.schmid <andre.schmid@est.tech>
24 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/ComponentInstanceBusinessLogic.java
catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogicTest.java
catalog-dao/src/main/java/org/openecomp/sdc/be/dao/api/ActionStatus.java
catalog-ui/src/app/models/properties-inputs/property-be-model.ts
catalog-ui/src/app/models/properties-inputs/property-input-detail.ts
catalog-ui/src/app/models/tosca-get-function-type.enum.ts [new file with mode: 0644]
catalog-ui/src/app/ng2/app.module.ts
catalog-ui/src/app/ng2/components/logic/properties-table/dynamic-property/dynamic-property.component.html
catalog-ui/src/app/ng2/components/logic/properties-table/dynamic-property/dynamic-property.component.ts
catalog-ui/src/app/ng2/pages/properties-assignment/input-list/input-list.component.html [new file with mode: 0644]
catalog-ui/src/app/ng2/pages/properties-assignment/input-list/input-list.component.less [new file with mode: 0644]
catalog-ui/src/app/ng2/pages/properties-assignment/input-list/input-list.component.ts [new file with mode: 0644]
catalog-ui/src/app/ng2/pages/properties-assignment/input-list/input-list.module.ts [new file with mode: 0644]
catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.module.ts
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/app/ng2/services/component-services/topology-template.service.ts
catalog-ui/src/app/ng2/services/properties.service.ts
catalog-ui/src/assets/languages/en_US.json
common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/GetInputValueDataDefinition.java
common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/PropertyDataDefinition.java
common-be/src/main/java/org/openecomp/sdc/be/datatypes/tosca/ToscaGetFunctionType.java [new file with mode: 0644]

index ecaf852..3e1b16d 100644 (file)
@@ -2430,3 +2430,10 @@ errors:
         message: "Error: Input name contains invalid characters. It should have only letters, numbers and underscores.",
         messageId: "SVC4736"
     }
+    #---------SVC4139------------------------------
+    # %1 - The action that is not supported
+    NOT_SUPPORTED: {
+        code: 400,
+        message: '%1 is not yet supported',
+        messageId: "SVC4139"
+    }
index 8515c5c..d0c72e5 100644 (file)
@@ -73,6 +73,7 @@ import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
 import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
+import org.openecomp.sdc.be.datatypes.tosca.ToscaGetFunctionType;
 import org.openecomp.sdc.be.impl.ComponentsUtils;
 import org.openecomp.sdc.be.impl.ForwardingPathUtils;
 import org.openecomp.sdc.be.impl.ServiceFilterUtils;
@@ -1972,6 +1973,8 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic {
             resultOp = Either.left(updatedProperties);
             return resultOp;
 
+        } catch (final ComponentException e) {
+            return Either.right(e.getResponseFormat());
         } finally {
             if (resultOp == null || resultOp.isRight()) {
                 janusGraphDao.rollback();
@@ -2169,10 +2172,17 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic {
             }
             innerType = propDef.getType();
         }
+
         // Specific Update Logic
+        String newValue = property.getValue();
+
+        if (property.getToscaGetFunctionType() != null) {
+            validateToscaGetFunction(property);
+            return Either.left(newValue);
+        }
+
         Either<Object, Boolean> isValid = propertyOperation
             .validateAndUpdatePropertyValue(propertyType, property.getValue(), true, innerType, allDataTypes);
-        String newValue = property.getValue();
         if (isValid.isRight()) {
             Boolean res = isValid.right().value();
             if (!res) {
@@ -2198,6 +2208,31 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic {
         return Either.left(newValue);
     }
 
+    private <T extends PropertyDefinition> void validateToscaGetFunction(T property) {
+        if (property.getToscaGetFunctionType() == ToscaGetFunctionType.GET_INPUT) {
+            final List<GetInputValueDataDefinition> getInputValues = property.getGetInputValues();
+            if (CollectionUtils.isEmpty(getInputValues)) {
+                log.debug("No input information provided. Cannot set get_input.");
+                throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
+            }
+            if (getInputValues.size() > 1) {
+                log.debug("More than one input provided. Cannot set get_input.");
+                throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
+            }
+            final GetInputValueDataDefinition getInputValueDataDefinition = getInputValues.get(0);
+
+            if (!property.getType().equals(getInputValueDataDefinition.getInputType())) {
+                log.debug("Input type '{}' diverges from the property type '{}'. Cannot set get_input.",
+                    getInputValueDataDefinition.getInputType(), property.getType());
+                throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
+            }
+            return;
+        }
+
+        throw new ByActionStatusComponentException(ActionStatus.NOT_SUPPORTED,
+            "Tosca function " + property.getToscaGetFunctionType().getToscaGetFunctionName());
+    }
+
     private ResponseFormat updateInputOnContainerComponent(ComponentInstanceInput input, String newValue, Component containerComponent,
                                                            ComponentInstance foundResourceInstance) {
         StorageOperationStatus status;
index 8a2cdef..07fff19 100644 (file)
@@ -423,10 +423,12 @@ class ComponentInstanceBusinessLogicTest {
         when(componentsUtils.convertFromStorageResponse(StorageOperationStatus.BAD_REQUEST))
             .thenReturn(ActionStatus.INVALID_CONTENT);
 
-        ComponentException e = assertThrows(ComponentException.class,
-            () -> componentInstanceBusinessLogic.createOrUpdatePropertiesValues(
-                ComponentTypeEnum.RESOURCE_INSTANCE, containerComponentID, resourceInstanceId, properties, "userId"));
-        assertThat(e.getActionStatus()).isEqualTo(ActionStatus.INVALID_CONTENT);
+        final Either<List<ComponentInstanceProperty>, ResponseFormat> response = componentInstanceBusinessLogic.createOrUpdatePropertiesValues(
+            ComponentTypeEnum.RESOURCE_INSTANCE, containerComponentID, resourceInstanceId, properties, "userId");
+        assertThat(response.isRight()).as("Response should be an error").isTrue();
+        final ResponseFormat responseFormat = response.right().value();
+        assertThat(responseFormat.getStatus()).as("Response status should be as expected").isEqualTo(400);
+        assertThat(responseFormat.getMessageId()).as("Error message id should be as expected").isEqualTo("SVC4000");
     }
 
     @Test
index 4b2bee9..a8f94e8 100644 (file)
@@ -21,7 +21,8 @@
 package org.openecomp.sdc.be.dao.api;
 
 public enum ActionStatus {
-    OK, ACCEPTED, CREATED, NO_CONTENT, GENERAL_ERROR, NOT_ALLOWED, MISSING_INFORMATION, RESTRICTED_OPERATION, RESTRICTED_ACCESS, INVALID_CONTENT, INVALID_PROPERTY_VALUES,
+    OK, ACCEPTED, CREATED, NO_CONTENT, GENERAL_ERROR, NOT_ALLOWED, MISSING_INFORMATION, RESTRICTED_OPERATION,
+       RESTRICTED_ACCESS, INVALID_CONTENT, INVALID_PROPERTY_VALUES, NOT_SUPPORTED,
     // User related
     USER_ALREADY_EXIST, USER_INACTIVE, USER_NOT_FOUND, USER_HAS_ACTIVE_ELEMENTS, INVALID_EMAIL_ADDRESS, INVALID_ROLE, DELETE_USER_ADMIN_CONFLICT, UPDATE_USER_ADMIN_CONFLICT, CANNOT_DELETE_USER_WITH_ACTIVE_ELEMENTS, CANNOT_UPDATE_USER_WITH_ACTIVE_ELEMENTS, INVALID_USER_ID, USER_DEFINED,
     // CapabilityType related
index aea5707..bd65c3a 100644 (file)
  * ============LICENSE_END=========================================================
  */
 
-import { PROPERTY_DATA, PROPERTY_TYPES } from 'app/utils/constants';
-import { SchemaProperty, SchemaPropertyGroupModel } from '../schema-property';
-import { ToscaPresentationData } from '../tosca-presentation';
-import { PropertyInputDetail } from './property-input-detail';
-import { Metadata } from '../metadata';
+import {PROPERTY_DATA, PROPERTY_TYPES} from 'app/utils/constants';
+import {SchemaProperty, SchemaPropertyGroupModel} from '../schema-property';
+import {ToscaPresentationData} from '../tosca-presentation';
+import {PropertyInputDetail} from './property-input-detail';
+import {Metadata} from '../metadata';
+import {ToscaGetFunctionType} from "../tosca-get-function-type.enum";
 
 export enum DerivedPropertyType {
     SIMPLE,
@@ -65,6 +66,7 @@ export class PropertyBEModel {
     inputPath: string;
     toscaPresentation: ToscaPresentationData;
     metadata: Metadata;
+    toscaGetFunctionType: ToscaGetFunctionType;
 
     constructor(property?: PropertyBEModel) {
         if (property) {
@@ -90,6 +92,7 @@ export class PropertyBEModel {
             this.getPolicyValues = property.getPolicyValues;
             this.inputPath = property.inputPath;
             this.metadata = property.metadata;
+            this.toscaGetFunctionType = property.toscaGetFunctionType;
         }
 
         if (!this.schema || !this.schema.property) {
@@ -117,5 +120,12 @@ export class PropertyBEModel {
             return DerivedPropertyType.COMPLEX;
         }
     }
+
+    /**
+     * Checks whether the property value is a tosca get function (e.g. get_input, get_property, get_attribute)
+     */
+    public isToscaGetFunction(): boolean {
+        return this.toscaGetFunctionType != null;
+    }
 }
 
index 8c1028c..38a14e6 100644 (file)
@@ -21,6 +21,7 @@
 export class PropertyInputDetail {
     inputId: string;
     inputName: string;
+    inputType: string;
     inputPath: string;
     list: boolean;
 }
diff --git a/catalog-ui/src/app/models/tosca-get-function-type.enum.ts b/catalog-ui/src/app/models/tosca-get-function-type.enum.ts
new file mode 100644 (file)
index 0000000..1ee4ae1
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2021 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=========================================================
+ */
+
+export enum ToscaGetFunctionType {
+  GET_INPUT = 'GET_INPUT',
+  GET_ATTRIBUTE = 'GET_ATTRIBUTE',
+  GET_PROPERTY = 'GET_PROPERTY'
+}
index 55dd969..88a5610 100644 (file)
@@ -93,6 +93,7 @@ import {ServiceDependenciesModule} from './components/logic/service-dependencies
 import {ServiceDependenciesEditorModule} from './pages/service-dependencies-editor/service-dependencies-editor.module';
 import {PropertyCreatorModule} from './pages/properties-assignment/property-creator/property-creator.module';
 import {DeclareListModule} from './pages/properties-assignment/declare-list/declare-list.module';
+import { InputListModule } from "./pages/properties-assignment/input-list/input-list.module";
 import {WorkflowServiceNg2} from './services/workflow.service';
 import {ToscaTypesServiceNg2} from "./services/tosca-types.service";
 import {CapabilitiesFilterPropertiesEditorComponentModule} from "./pages/composition/capabilities-filter-properties-editor/capabilities-filter-properties-editor.module";
@@ -149,6 +150,7 @@ export function configServiceFactory(config: ConfigService, authService: Authent
     AttributesOutputsModule,
     PropertyCreatorModule,
     DeclareListModule,
+    InputListModule,
     PluginFrameModule,
     PluginsModule,
     InterfaceOperationModule,
index f6396e6..78c3030 100644 (file)
  
  
 <div *ngIf="!property.hidden" class="dynamic-property-row nested-level-{{nestedLevel}}" [@fadeIn]
-    [ngClass]="{'selected': selectedPropertyId && selectedPropertyId === property.propertiesName, 'readonly':  property.isDisabled ||property.isDeclared}"
+    [ngClass]="{'selected': selectedPropertyId && selectedPropertyId === property.propertiesName, 'readonly':  property.isDisabled || property.isDeclared || property.isToscaGetFunction()}"
     [class.with-top-border]="property.isChildOfListOrMap"
     (click)="onClickPropertyRow(property, $event)">
     <!-- LEFT CELL -->
     <ng-container *ngIf="!isPropertyFEModel">
         <div class="table-cell" *ngIf="canBeDeclared" [ngClass]="{'filtered':property.name === propertyNameSearchText}" [class.round-checkbox]="property.isDeclared"> <!-- simple children of complex type [@checkEffect]="property.isDeclared"-->
-            <checkbox *ngIf="hasDeclareOption" [(checked)]="property.isSelected" [disabled]="property.isDisabled ||property.isDeclared || readonly" (checkedChange)="checkProperty.emit(property.propertiesName)" ></checkbox>
+            <checkbox *ngIf="hasDeclareOption" [(checked)]="property.isSelected" [disabled]="property.isDisabled || property.isDeclared || readonly || property.isToscaGetFunction()" (checkedChange)="checkProperty.emit(property.propertiesName)" ></checkbox>
             <div class="inner-cell-div" tooltip="{{property.name}}"><span>{{property.name}}</span></div>
         </div>
         <div class="table-cell" *ngIf="!canBeDeclared && !property.isChildOfListOrMap">
             <div class="inner-cell-div" tooltip="{{property.name}}"><span>{{property.name}}</span></div>
         </div> <!-- simple children of complex type within map or list -->
         <div class="table-cell map-entry" *ngIf="property.isChildOfListOrMap && propType == derivedPropertyTypes.MAP"><!-- map left cell -->
-            <!--<input [value]="property.mapKey" [placeholder]="property.name" (input)="mapKeyChanged.emit($event.target.value)" [readonly]="readonly" type="text" [ngClass]="{'disabled':readonly, 'error':property.mapKeyError}" required/>-->
             <dynamic-element #mapKeyInput
                 class="value-input"
                 pattern="validationUtils.getValidationPattern(string)"
         </div>
     </ng-container>
     <!-- RIGHT CELL OR FULL WIDTH CELL-->
-    <ng-container *ngIf="propType == derivedPropertyTypes.SIMPLE || property.isDeclared || (property.isChildOfListOrMap && propType == derivedPropertyTypes.MAP && property.schema.property.isSimpleType)">
+    <ng-container *ngIf="propType == derivedPropertyTypes.SIMPLE || property.isDeclared || property.isToscaGetFunction() || (property.isChildOfListOrMap && propType == derivedPropertyTypes.MAP && property.schema.property.isSimpleType)">
         <div class="table-cell">
             <dynamic-element class="value-input"
                 pattern="validationUtils.getValidationPattern(property.type)"
-                [value]="property.isDeclared ? property.value : property.valueObj"
-                [type]="property.isDeclared ? 'string' : property.type"
+                [value]="property.isDeclared || property.isToscaGetFunction() ? property.value : property.valueObj"
+                [type]="property.isDeclared || property.isToscaGetFunction() ? 'string' : property.type"
                 [name]="property.name"
                 [path]="property.propertiesName"
                 (elementChanged)="onElementChanged($event)"
-                [readonly]="readonly || property.isDeclared || property.isDisabled"
+                [readonly]="readonly || property.isDeclared || property.isDisabled || property.isToscaGetFunction()"
                 [testId]="'prop-' + propertyTestsId"
                 [declared] = "property.isDeclared"
                 [constraints] = "constraints"
             ></dynamic-element>
         </div>
     </ng-container>
-    <ng-container *ngIf="!isPropertyFEModel && propType != derivedPropertyTypes.SIMPLE && !property.isDeclared"> <!-- right cell for complex elements, or list complex -->
+    <ng-container *ngIf="!isPropertyFEModel && propType != derivedPropertyTypes.SIMPLE && !property.isDeclared && !property.isToscaGetFunction()"> <!-- right cell for complex elements, or list complex -->
         <div class="table-cell" *ngIf="propType == derivedPropertyTypes.COMPLEX">{{property.type | contentAfterLastDot }}</div>
         <div class="table-cell" *ngIf="propType == derivedPropertyTypes.MAP && !property.schema.property.isSimpleType">{{property.schema.property.type | contentAfterLastDot }}</div>
     </ng-container>
-    <ng-container *ngIf="isPropertyFEModel && (propType == derivedPropertyTypes.LIST || propType == derivedPropertyTypes.MAP) && !property.isDeclared"><!-- empty, full-width table cell - for PropertyFEModel of type list or map -->
+    <ng-container *ngIf="isPropertyFEModel && (propType == derivedPropertyTypes.LIST || propType == derivedPropertyTypes.MAP) && !property.isDeclared && !property.isToscaGetFunction()"><!-- empty, full-width table cell - for PropertyFEModel of type list or map -->
         <div class="table-cell empty"></div>
     </ng-container>
     <!-- ICONS: add, delete, and expand -->
-    <ng-container *ngIf="!property.isDeclared">
+    <ng-container *ngIf="!property.isDeclared && !property.isToscaGetFunction()">
             <a *ngIf="(propType == derivedPropertyTypes.LIST || propType == derivedPropertyTypes.MAP) && !property.isChildOfListOrMap" class="property-icon add-item" (click)="createNewChildProperty();" [ngClass]="{'disabled':readonly || preventInsertItem(property)}" [attr.data-tests-id]="'add-to-list-' + propertyTestsId">Add value to list</a>
             <span *ngIf="property.isChildOfListOrMap" (click)="deleteItem.emit(property);" class="property-icon sprite-new delete-item-icon" [ngClass]="{'disabled':readonly}" [attr.data-tests-id]="'delete-from-list-' + propertyTestsId"></span>
             <span *ngIf="!isPropertyFEModel && (propType == derivedPropertyTypes.COMPLEX || ((propType == derivedPropertyTypes.LIST || propType == derivedPropertyTypes.MAP) && hasChildren))" (click)="expandChildById(propPath)" class="property-icon sprite-new round-expand-icon" [class.open]="expandedChildId.indexOf(propPath) == 0" [attr.data-tests-id]="'expand-' + propertyTestsId" ></span>
@@ -74,7 +73,7 @@
 
 </div>
 <!-- FLAT CHILDREN -->
-<div class="flat-children-container" *ngIf="isPropertyFEModel && !property.isDeclared">
+<div class="flat-children-container" *ngIf="isPropertyFEModel && !property.isDeclared && !property.isToscaGetFunction()">
     <ng-container *ngFor="let prop of property.flattenedChildren | filterChildProperties: expandedChildId; trackBy:prop?.propertiesName">
         <dynamic-property
             [selectedPropertyId]="selectedPropertyId"
index 715426f..1e51b41 100644 (file)
@@ -84,7 +84,7 @@ export class DynamicPropertyComponent {
         let primitiveProperties = ['string', 'integer', 'float', 'boolean'];
 
         //Property has constraints
-        if(this.property.constraints){
+        if(this.property.constraints && this.property.constraints[0]){
             this.constraints = this.property.constraints[0].validValues
         }
 
diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/input-list/input-list.component.html b/catalog-ui/src/app/ng2/pages/properties-assignment/input-list/input-list.component.html
new file mode 100644 (file)
index 0000000..e080463
--- /dev/null
@@ -0,0 +1,31 @@
+<!--
+  ~ ============LICENSE_START=======================================================
+  ~  Copyright (C) 2021 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="input-list">
+  <loader [display]="isLoading" [loaderDelay]="500" [relative]="true" [size]="'large'"></loader>
+  <form class="w-sdc-form">
+    <div class="i-sdc-form-item">
+      <label class="i-sdc-form-label required">Input Value</label>
+      <select [(ngModel)]="selectInputValue" name="selectInputValue">
+        <option *ngFor="let index of inputModel"
+                [ngValue]="index">{{index.name}}</option>
+      </select>
+    </div>
+  </form>
+</div>
diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/input-list/input-list.component.less b/catalog-ui/src/app/ng2/pages/properties-assignment/input-list/input-list.component.less
new file mode 100644 (file)
index 0000000..e1e9b0d
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2021 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 '../../../../../assets/styles/variables.less';
+
+.input-list {
+    font-family: @font-opensans-regular;
+    user-select: none;
+    padding-top: 12px;
+    padding-bottom: 20px;
+
+    .i-sdc-form-label {
+        font-size: 12px;
+    }
+
+    .w-sdc-form .i-sdc-form-item {
+        margin-bottom: 15px;
+    }
+
+    .side-by-side {
+        display: flex;
+
+        .i-sdc-form-item {
+            flex-basis: 100%;
+        }
+    }
+}
diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/input-list/input-list.component.ts b/catalog-ui/src/app/ng2/pages/properties-assignment/input-list/input-list.component.ts
new file mode 100644 (file)
index 0000000..64ebcaa
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2021 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} from '@angular/core';
+import {InputBEModel, ComponentMetadata} from 'app/models';
+import {TopologyTemplateService} from "../../../services/component-services/topology-template.service";
+import {WorkspaceService} from "../../workspace/workspace.service";
+import {PropertiesService} from "../../../services/properties.service";
+
+@Component({
+    selector: 'input-list',
+    templateUrl: './input-list.component.html',
+    styleUrls: ['./input-list.component.less'],
+})
+
+export class InputListComponent {
+
+    selectInputValue;
+    inputModel: Array<InputBEModel> = [];
+    isLoading: boolean;
+    propertyType: string;
+
+    private componentMetadata: ComponentMetadata;
+
+    constructor(private topologyTemplateService: TopologyTemplateService,
+                private workspaceService: WorkspaceService,
+                private propertiesService: PropertiesService
+    ) {}
+
+    ngOnInit() {
+        this.componentMetadata = this.workspaceService.metadata;
+        this.propertyType = this.propertiesService.getCheckedPropertyType();
+        this.loadInputValues(this.propertyType);
+    }
+
+    private loadInputValues(propertyType: string): void {
+        this.isLoading = true;
+        this.topologyTemplateService.getComponentInputsValues(this.componentMetadata.componentType, this.componentMetadata.uniqueId)
+        .subscribe((response) => {
+            response.inputs.forEach((input: any) => {
+                if (input.type === propertyType) {
+                    this.inputModel.push(input);
+                }
+            });
+        }, () => {
+            //error ignored
+        }, () => {
+            this.isLoading = false;
+        });
+    }
+}
diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/input-list/input-list.module.ts b/catalog-ui/src/app/ng2/pages/properties-assignment/input-list/input-list.module.ts
new file mode 100644 (file)
index 0000000..50d7b08
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2021 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 { CommonModule } from '@angular/common';
+import { NgModule } from '@angular/core';
+import { FormsModule } from '@angular/forms';
+import { FormElementsModule } from 'app/ng2/components/ui/form-components/form-elements.module';
+import { UiElementsModule } from 'app/ng2/components/ui/ui-elements.module';
+import { TranslateModule } from '../../../shared/translator/translate.module';
+import { InputListComponent } from './input-list.component';
+import { SdcUiComponentsModule } from 'onap-ui-angular';
+
+@NgModule({
+    declarations: [
+        InputListComponent,
+    ],
+    imports: [
+        CommonModule,
+        FormsModule,
+        FormElementsModule,
+        UiElementsModule,
+        TranslateModule,
+        SdcUiComponentsModule
+    ],
+    exports: [],
+    entryComponents: [
+        InputListComponent
+    ],
+    providers: []
+})
+
+export class InputListModule {}
index 0d676ed..ae4aa57 100644 (file)
@@ -52,7 +52,8 @@ import {HierarchyNavigationModule} from "../../components/logic/hierarchy-navigt
     HierarchyNavigationModule,
     UiElementsModule,
     SdcUiComponentsModule,
-    ModalFormsModule],
+    ModalFormsModule
+  ],
 
   entryComponents: [PropertiesAssignmentComponent],
   exports: [
index 6b3e92a..7da0ecd 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)="selectInput()"
+                        *ngIf="isPropertiesTabSelected && !isSelf()"
+                        [disabled]="checkedPropertiesCount != 1 || isReadonly || hasChangedData"
+                        class="tlv-btn blue declare-button"
+                        data-tests-id="declare-button declare-input">{{btnSelectInputText}}</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 || 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-button declare-list-input">Create List Input</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>
         </div>
         <div class="right-column">
index 8cdc761..6d009a8 100644 (file)
  */
 
 import * as _ from "lodash";
-import { Component, ViewChild, Inject, TemplateRef } from "@angular/core";
-import { PropertiesService } from "../../services/properties.service";
-import { PropertyFEModel, InstanceFePropertiesMap, InstanceBePropertiesMap, InstancePropertiesAPIMap, Component as ComponentData, FilterPropertiesAssignmentData, ModalModel, ButtonModel } from "app/models";
-import { ResourceType } from "app/utils";
-import { ComponentServiceNg2 } from "../../services/component-services/component.service";
-import { TopologyTemplateService } from "../../services/component-services/topology-template.service";
-import { ComponentInstanceServiceNg2 } from "../../services/component-instance-services/component-instance.service"
-import { InputBEModel, InputFEModel, ComponentInstance, GroupInstance, PolicyInstance, PropertyBEModel, DerivedFEProperty, SimpleFlatProperty } from "app/models";
-import { KeysPipe } from 'app/ng2/pipes/keys.pipe';
-import { WorkspaceMode, EVENTS, PROPERTY_TYPES } from "../../../utils/constants";
-import { EventListenerService } from "app/services/event-listener-service"
-import { HierarchyDisplayOptions } from "../../components/logic/hierarchy-navigtion/hierarchy-display-options";
-import { FilterPropertiesAssignmentComponent } from "../../components/logic/filter-properties-assignment/filter-properties-assignment.component";
-import { PropertyRowSelectedEvent } from "../../components/logic/properties-table/properties-table.component";
-import { HierarchyNavService } from "./services/hierarchy-nav.service";
-import { PropertiesUtils } from "./services/properties.utils";
-import { ComponentModeService } from "../../services/component-services/component-mode.service";
-import { Tabs, Tab } from "../../components/ui/tabs/tabs.component";
-import { InputsUtils } from "./services/inputs.utils";
-import { InstanceFeDetails } from "../../../models/instance-fe-details";
-import { SdcUiServices, SdcUiCommon } from "onap-ui-angular";
-import { UnsavedChangesComponent } from "app/ng2/components/ui/forms/unsaved-changes/unsaved-changes.component";
+import {Component, Inject, ViewChild} from "@angular/core";
+import {PropertiesService} from "../../services/properties.service";
+import {
+    ButtonModel,
+    Component as ComponentData,
+    ComponentInstance,
+    DerivedFEProperty,
+    FilterPropertiesAssignmentData,
+    GroupInstance,
+    InputBEModel,
+    InputFEModel,
+    InstanceBePropertiesMap,
+    InstanceFePropertiesMap,
+    InstancePropertiesAPIMap,
+    ModalModel,
+    PolicyInstance,
+    PropertyBEModel,
+    PropertyFEModel,
+    PropertyInputDetail,
+    SimpleFlatProperty
+} from "app/models";
+import {ResourceType} from "app/utils";
+import {ComponentServiceNg2} from "../../services/component-services/component.service";
+import {TopologyTemplateService} from "../../services/component-services/topology-template.service";
+import {ComponentInstanceServiceNg2} from "../../services/component-instance-services/component-instance.service"
+import {KeysPipe} from 'app/ng2/pipes/keys.pipe';
+import {EVENTS, PROPERTY_TYPES, WorkspaceMode} from "../../../utils/constants";
+import {EventListenerService} from "app/services/event-listener-service"
+import {HierarchyDisplayOptions} from "../../components/logic/hierarchy-navigtion/hierarchy-display-options";
+import {FilterPropertiesAssignmentComponent} from "../../components/logic/filter-properties-assignment/filter-properties-assignment.component";
+import {PropertyRowSelectedEvent} from "../../components/logic/properties-table/properties-table.component";
+import {HierarchyNavService} from "./services/hierarchy-nav.service";
+import {PropertiesUtils} from "./services/properties.utils";
+import {ComponentModeService} from "../../services/component-services/component-mode.service";
+import {Tab, Tabs} from "../../components/ui/tabs/tabs.component";
+import {InputsUtils} from "./services/inputs.utils";
+import {InstanceFeDetails} from "../../../models/instance-fe-details";
+import {SdcUiCommon, SdcUiServices} from "onap-ui-angular";
+import {UnsavedChangesComponent} from "app/ng2/components/ui/forms/unsaved-changes/unsaved-changes.component";
 import {PropertyCreatorComponent} from "./property-creator/property-creator.component";
 import {ModalService} from "../../services/modal.service";
-import { DeclareListComponent } from "./declare-list/declare-list.component";
-import { CapabilitiesGroup, Capability } from "../../../models/capability";
-import { ToscaPresentationData } from "../../../models/tosca-presentation";
-import { Observable } from "rxjs";
+import {DeclareListComponent} from "./declare-list/declare-list.component";
+import {InputListComponent} from "./input-list/input-list.component";
+import {CapabilitiesGroup, Capability} from "../../../models/capability";
+import {ToscaPresentationData} from "../../../models/tosca-presentation";
+import {Observable} from "rxjs";
+import {ToscaGetFunctionType} from "../../../models/tosca-get-function-type.enum";
+import {TranslateService} from "../../shared/translator/translate.service";
 
 const SERVICE_SELF_TITLE = "SELF";
 @Component({
@@ -62,61 +82,65 @@ export class PropertiesAssignmentComponent {
     propertiesNavigationData = [];
     instancesNavigationData = [];
 
-    instanceFePropertiesMap:InstanceFePropertiesMap;
+    instanceFePropertiesMap: InstanceFePropertiesMap;
     inputs: Array<InputFEModel> = [];
     policies: Array<PolicyInstance> = [];
-    instances: Array<ComponentInstance|GroupInstance|PolicyInstance> = [];
+    instances: Array<ComponentInstance | GroupInstance | PolicyInstance> = [];
     searchQuery: string;
     propertyStructureHeader: string;
 
     selectedFlatProperty: SimpleFlatProperty = new SimpleFlatProperty();
-    selectedInstanceData: ComponentInstance|GroupInstance|PolicyInstance = null;
+    selectedInstanceData: ComponentInstance | GroupInstance | PolicyInstance = null;
     checkedPropertiesCount: number = 0;
     checkedChildPropertiesCount: number = 0;
 
-    hierarchyPropertiesDisplayOptions:HierarchyDisplayOptions = new HierarchyDisplayOptions('path', 'name', 'childrens');
-    hierarchyInstancesDisplayOptions:HierarchyDisplayOptions = new HierarchyDisplayOptions('uniqueId', 'name', 'archived', null, 'iconClass');
+    hierarchyPropertiesDisplayOptions: HierarchyDisplayOptions = new HierarchyDisplayOptions('path', 'name', 'childrens');
+    hierarchyInstancesDisplayOptions: HierarchyDisplayOptions = new HierarchyDisplayOptions('uniqueId', 'name', 'archived', null, 'iconClass');
     displayClearSearch = false;
-    searchPropertyName:string;
-    currentMainTab:Tab;
-    isInputsTabSelected:boolean;
-    isPropertiesTabSelected:boolean;
-    isPoliciesTabSelected:boolean;
-    isReadonly:boolean;
-    resourceIsReadonly:boolean;
-    loadingInstances:boolean = false;
-    loadingInputs:boolean = false;
-    loadingPolicies:boolean = false;
-    loadingProperties:boolean = false;
-    changedData:Array<PropertyFEModel|InputFEModel>;
-    hasChangedData:boolean;
-    isValidChangedData:boolean;
-    savingChangedData:boolean;
-    stateChangeStartUnregister:Function;
+    searchPropertyName: string;
+    currentMainTab: Tab;
+    isInputsTabSelected: boolean;
+    isPropertiesTabSelected: boolean;
+    isInputValueSelected: boolean = false;
+    isPoliciesTabSelected: boolean;
+    isReadonly: boolean;
+    resourceIsReadonly: boolean;
+    loadingInstances: boolean = false;
+    loadingInputs: boolean = false;
+    loadingPolicies: boolean = false;
+    loadingProperties: boolean = false;
+    changedData: Array<PropertyFEModel | InputFEModel>;
+    hasChangedData: boolean;
+    isValidChangedData: boolean;
+    savingChangedData: boolean;
+    stateChangeStartUnregister: Function;
     serviceBePropertiesMap: InstanceBePropertiesMap;
     serviceBeCapabilitiesPropertiesMap: InstanceBePropertiesMap;
     selectedInstance_FlattenCapabilitiesList: Capability[];
+    propertyType: string;
+    btnSelectInputText: string;
 
     @ViewChild('hierarchyNavTabs') hierarchyNavTabs: Tabs;
     @ViewChild('propertyInputTabs') propertyInputTabs: Tabs;
     @ViewChild('advanceSearch') advanceSearch: FilterPropertiesAssignmentComponent;
-   
+
     constructor(private propertiesService: PropertiesService,
                 private hierarchyNavService: HierarchyNavService,
-                private propertiesUtils:PropertiesUtils,
-                private inputsUtils:InputsUtils,
-                private componentServiceNg2:ComponentServiceNg2,
-                private componentInstanceServiceNg2:ComponentInstanceServiceNg2,
+                private propertiesUtils: PropertiesUtils,
+                private inputsUtils: InputsUtils,
+                private componentServiceNg2: ComponentServiceNg2,
+                private componentInstanceServiceNg2: ComponentInstanceServiceNg2,
                 @Inject("$stateParams") _stateParams,
-                @Inject("$scope") private $scope:ng.IScope,
-                @Inject("$state") private $state:ng.ui.IStateService,
-                @Inject("Notification") private Notification:any,
-                private componentModeService:ComponentModeService,
-                private EventListenerService:EventListenerService,
+                @Inject("$scope") private $scope: ng.IScope,
+                @Inject("$state") private $state: ng.ui.IStateService,
+                @Inject("Notification") private Notification: any,
+                private componentModeService: ComponentModeService,
+                private EventListenerService: EventListenerService,
                 private ModalServiceSdcUI: SdcUiServices.ModalService,
                 private ModalService: ModalService,
-                private keysPipe:KeysPipe,
-                private topologyTemplateService: TopologyTemplateService) {
+                private keysPipe: KeysPipe,
+                private topologyTemplateService: TopologyTemplateService,
+                private translateService: TranslateService) {
 
         this.instanceFePropertiesMap = new InstanceFePropertiesMap();
         /* This is the way you can access the component data, please do not use any data except metadata, all other data should be received from the new api calls on the first time
@@ -124,7 +148,6 @@ export class PropertiesAssignmentComponent {
         this.component = _stateParams.component;
         this.EventListenerService.registerObserverCallback(EVENTS.ON_LIFECYCLE_CHANGE, this.onCheckout);
         this.updateViewMode();
-
         this.changedData = [];
         this.updateHasChangedData();
         this.isValidChangedData = true;
@@ -132,52 +155,60 @@ export class PropertiesAssignmentComponent {
 
     ngOnInit() {
         console.log("==>" + this.constructor.name + ": ngOnInit");
+        this.btnSelectInputText = this.translateService.translate('SELECT_INPUT_LABEL');
         this.loadingInputs = true;
         this.loadingPolicies = true;
         this.loadingInstances = true;
         this.loadingProperties = true;
         this.topologyTemplateService
-            .getComponentInputsWithProperties(this.component.componentType, this.component.uniqueId)
-            .subscribe(response => {
-                _.forEach(response.inputs, (input: InputBEModel) => {
-                    const newInput: InputFEModel = new InputFEModel(input);
-                    this.inputsUtils.resetInputDefaultValue(newInput, input.defaultValue);
-                    this.inputs.push(newInput); //only push items that were declared via SDC
-                });
-                this.loadingInputs = false;
+        .getComponentInputsWithProperties(this.component.componentType, this.component.uniqueId)
+        .subscribe(response => {
+            _.forEach(response.inputs, (input: InputBEModel) => {
+                const newInput: InputFEModel = new InputFEModel(input);
+                this.inputsUtils.resetInputDefaultValue(newInput, input.defaultValue);
+                this.inputs.push(newInput); //only push items that were declared via SDC
+            });
+            this.loadingInputs = false;
 
-            }, error => {}); //ignore error
+        }, error => {
+        }); //ignore error
         this.componentServiceNg2
-            .getComponentResourcePropertiesData(this.component)
-            .subscribe(response => {
-                this.loadingPolicies = false;
-                this.instances = [];
-                this.instances.push(...response.componentInstances);
-                this.instances.push(...response.groupInstances);
-                this.instances.push(...response.policies);
-
-                _.forEach(response.policies, (policy: any) => {
-                    const newPolicy: InputFEModel = new InputFEModel(policy);
-                    this.inputsUtils.resetInputDefaultValue(newPolicy, policy.defaultValue);
-                    this.policies.push(policy);
-                });
-
-                // add the service self instance to the top of the list.
-                const serviceInstance = new ComponentInstance();
-                serviceInstance.name = SERVICE_SELF_TITLE;
-                serviceInstance.uniqueId = this.component.uniqueId;
-                this.instances.unshift(serviceInstance);
+        .getComponentResourcePropertiesData(this.component)
+        .subscribe(response => {
+            this.loadingPolicies = false;
+            this.instances = [];
+            this.instances.push(...response.componentInstances);
+            this.instances.push(...response.groupInstances);
+            this.instances.push(...response.policies);
+
+            _.forEach(response.policies, (policy: any) => {
+                const newPolicy: InputFEModel = new InputFEModel(policy);
+                this.inputsUtils.resetInputDefaultValue(newPolicy, policy.defaultValue);
+                this.policies.push(policy);
+            });
 
-                _.forEach(this.instances, (instance) => {
-                    this.instancesNavigationData.push(instance);
-                    this.componentInstanceNamesMap[instance.uniqueId] = <InstanceFeDetails>{name: instance.name, iconClass:instance.iconClass, originArchived:instance.originArchived};
-                });
-                this.loadingInstances = false;
-                if (this.instancesNavigationData[0] == undefined) {
-                    this.loadingProperties = false;
-                }
-                this.selectFirstInstanceByDefault();
-            }, error => { this.loadingInstances = false; }); //ignore error
+            // add the service self instance to the top of the list.
+            const serviceInstance = new ComponentInstance();
+            serviceInstance.name = SERVICE_SELF_TITLE;
+            serviceInstance.uniqueId = this.component.uniqueId;
+            this.instances.unshift(serviceInstance);
+
+            _.forEach(this.instances, (instance) => {
+                this.instancesNavigationData.push(instance);
+                this.componentInstanceNamesMap[instance.uniqueId] = <InstanceFeDetails>{
+                    name: instance.name,
+                    iconClass: instance.iconClass,
+                    originArchived: instance.originArchived
+                };
+            });
+            this.loadingInstances = false;
+            if (this.instancesNavigationData[0] == undefined) {
+                this.loadingProperties = false;
+            }
+            this.selectFirstInstanceByDefault();
+        }, error => {
+            this.loadingInstances = false;
+        }); //ignore error
 
         this.stateChangeStartUnregister = this.$scope.$on('$stateChangeStart', (event, toState, toParams) => {
             // stop if has changed properties
@@ -185,7 +216,8 @@ export class PropertiesAssignmentComponent {
                 event.preventDefault();
                 this.showUnsavedChangesAlert().then(() => {
                     this.$state.go(toState, toParams);
-                }, () => {});
+                }, () => {
+                });
             }
         });
     };
@@ -205,33 +237,33 @@ export class PropertiesAssignmentComponent {
         this.isReadonly = this.componentModeService.getComponentMode(this.component) === WorkspaceMode.VIEW;
     }
 
-    onCheckout = (component:ComponentData) => {
+    onCheckout = (component: ComponentData) => {
         this.component = component;
         this.updateViewMode();
     }
 
-    isSelf = ():boolean => {
+    isSelf = (): boolean => {
         return this.selectedInstanceData && this.selectedInstanceData.uniqueId == this.component.uniqueId;
     }
 
-    getServiceProperties(){
-        this.loadingProperties = false;
+    getServiceProperties() {
+        this.loadingProperties = true;
         this.topologyTemplateService
-            .getServiceProperties(this.component.uniqueId)
-            .subscribe((response) => {
-                this.serviceBePropertiesMap = new InstanceBePropertiesMap();
-                this.serviceBePropertiesMap[this.component.uniqueId] = response;
-                this.processInstancePropertiesResponse(this.serviceBePropertiesMap, false);
-                this.loadingProperties = false;
-            }, (error) => {
-                this.loadingProperties = false;
-            });
+        .getServiceProperties(this.component.uniqueId)
+        .subscribe((response) => {
+            this.serviceBePropertiesMap = new InstanceBePropertiesMap();
+            this.serviceBePropertiesMap[this.component.uniqueId] = response;
+            this.processInstancePropertiesResponse(this.serviceBePropertiesMap, false);
+            this.loadingProperties = false;
+        }, (error) => {
+            this.loadingProperties = false;
+        });
     }
 
-    onInstanceSelectedUpdate = (instance: ComponentInstance|GroupInstance|PolicyInstance) => {
+    onInstanceSelectedUpdate = (instance: ComponentInstance | GroupInstance | PolicyInstance) => {
         // stop if has changed properties
         if (this.hasChangedData) {
-            this.showUnsavedChangesAlert().then((resolve)=> {
+            this.showUnsavedChangesAlert().then((resolve) => {
                 this.changeSelectedInstance(instance)
             }, (reject) => {
             });
@@ -240,52 +272,62 @@ export class PropertiesAssignmentComponent {
         this.changeSelectedInstance(instance);
     };
 
-    changeSelectedInstance =  (instance: ComponentInstance|GroupInstance|PolicyInstance) => {
+    changeSelectedInstance = (instance: ComponentInstance | GroupInstance | PolicyInstance) => {
         this.selectedInstanceData = instance;
         this.loadingProperties = true;
         if (instance instanceof ComponentInstance) {
             let instanceBePropertiesMap: InstanceBePropertiesMap = new InstanceBePropertiesMap();
             if (this.isInput(instance.originType)) {
                 this.componentInstanceServiceNg2
-                    .getComponentInstanceInputs(this.component, instance)
-                    .subscribe(response => {
-                        instanceBePropertiesMap[instance.uniqueId] = response;
-                        this.processInstancePropertiesResponse(instanceBePropertiesMap, true);
-                        this.loadingProperties = false;
-                    }, error => {
-                    }); //ignore error
+                .getComponentInstanceInputs(this.component, instance)
+                .subscribe(response => {
+                    instanceBePropertiesMap[instance.uniqueId] = response;
+                    this.processInstancePropertiesResponse(instanceBePropertiesMap, true);
+                }, () => {
+                    //ignore error
+                }, () => {
+                    this.loadingProperties = false;
+                });
             } else if (this.isSelf()) {
                 this.getServiceProperties();
             } else {
                 this.componentInstanceServiceNg2
-                    .getComponentInstanceProperties(this.component, instance.uniqueId)
-                    .subscribe(response => {
-                        instanceBePropertiesMap[instance.uniqueId] = response;
-                        this.processInstancePropertiesResponse(instanceBePropertiesMap, false);
-                        this.loadingProperties = false;
-                    }, error => {
-                    }); //ignore error
+                .getComponentInstanceProperties(this.component, instance.uniqueId)
+                .subscribe(response => {
+                    instanceBePropertiesMap[instance.uniqueId] = response;
+                    this.processInstancePropertiesResponse(instanceBePropertiesMap, false);
+                }, () => {
+                    //ignore error
+                }, () => {
+                    this.loadingProperties = false;
+                });
             }
-
+            this.loadingProperties = false;
             this.resourceIsReadonly = (instance.componentName === "vnfConfiguration");
         } else if (instance instanceof GroupInstance) {
             let instanceBePropertiesMap: InstanceBePropertiesMap = new InstanceBePropertiesMap();
             this.componentInstanceServiceNg2
-                .getComponentGroupInstanceProperties(this.component, this.selectedInstanceData.uniqueId)
-                .subscribe((response) => {
-                    instanceBePropertiesMap[instance.uniqueId] = response;
-                    this.processInstancePropertiesResponse(instanceBePropertiesMap, false);
-                    this.loadingProperties = false;
-                });
+            .getComponentGroupInstanceProperties(this.component, this.selectedInstanceData.uniqueId)
+            .subscribe((response) => {
+                instanceBePropertiesMap[instance.uniqueId] = response;
+                this.processInstancePropertiesResponse(instanceBePropertiesMap, false);
+            }, () => {
+                //ignore error
+            }, () => {
+                this.loadingProperties = false;
+            });
         } else if (instance instanceof PolicyInstance) {
             let instanceBePropertiesMap: InstanceBePropertiesMap = new InstanceBePropertiesMap();
             this.componentInstanceServiceNg2
-                .getComponentPolicyInstanceProperties(this.component.componentType, this.component.uniqueId, this.selectedInstanceData.uniqueId)
-                .subscribe((response) => {
-                    instanceBePropertiesMap[instance.uniqueId] = response;
-                    this.processInstancePropertiesResponse(instanceBePropertiesMap, false);
-                    this.loadingProperties = false;
-                });
+            .getComponentPolicyInstanceProperties(this.component.componentType, this.component.uniqueId, this.selectedInstanceData.uniqueId)
+            .subscribe((response) => {
+                instanceBePropertiesMap[instance.uniqueId] = response;
+                this.processInstancePropertiesResponse(instanceBePropertiesMap, false);
+            }, () => {
+                //ignore error
+            }, () => {
+                this.loadingProperties = false;
+            });
         } else {
             this.loadingProperties = false;
         }
@@ -316,7 +358,7 @@ export class PropertiesAssignmentComponent {
             this.selectedInstance_FlattenCapabilitiesList,
             (result, cap: Capability) => {
                 isCapabilityOwnedByInstance = cap.ownerId === currentUniqueId ||
-                    selectedComponentInstanceData.isServiceProxy() || selectedComponentInstanceData.isServiceSubstitution() && 
+                    selectedComponentInstanceData.isServiceProxy() || selectedComponentInstanceData.isServiceSubstitution() &&
                     cap.ownerId === selectedComponentInstanceData.sourceModelUid;
                 if (cap.properties && isCapabilityOwnedByInstance) {
                     _.forEach(cap.properties, prop => {
@@ -344,7 +386,7 @@ export class PropertiesAssignmentComponent {
     };
 
     /*** VALUE CHANGE EVENTS ***/
-    dataChanged = (item:PropertyFEModel|InputFEModel) => {
+    dataChanged = (item: PropertyFEModel | InputFEModel) => {
         let itemHasChanged;
         if (this.isPropertiesTabSelected && item instanceof PropertyFEModel) {
             itemHasChanged = item.hasValueObjChanged();
@@ -384,14 +426,14 @@ export class PropertiesAssignmentComponent {
     onPropertySelectedUpdate = ($event) => {
         console.log("==>" + this.constructor.name + ": onPropertySelectedUpdate");
         this.selectedFlatProperty = $event;
-        let parentProperty:PropertyFEModel = this.propertiesService.getParentPropertyFEModelFromPath(this.instanceFePropertiesMap[this.selectedFlatProperty.instanceName], this.selectedFlatProperty.path);
+        let parentProperty: PropertyFEModel = this.propertiesService.getParentPropertyFEModelFromPath(this.instanceFePropertiesMap[this.selectedFlatProperty.instanceName], this.selectedFlatProperty.path);
         parentProperty.expandedChildPropertyId = this.selectedFlatProperty.path;
     };
 
     /**
      * When user select row in table, this will prepare the hirarchy object for the tree.
      */
-    selectPropertyRow = (propertyRowSelectedEvent:PropertyRowSelectedEvent) => {
+    selectPropertyRow = (propertyRowSelectedEvent: PropertyRowSelectedEvent) => {
         console.log("==>" + this.constructor.name + ": selectPropertyRow " + propertyRowSelectedEvent.propertyModel.name);
         let property = propertyRowSelectedEvent.propertyModel;
         let instanceName = propertyRowSelectedEvent.instanceName;
@@ -399,13 +441,13 @@ export class PropertiesAssignmentComponent {
 
         // Build hirarchy tree for the navigation and update propertiesNavigationData with it.
         if (!(this.selectedInstanceData instanceof ComponentInstance) || this.selectedInstanceData.originType !== ResourceType.VF) {
-            let simpleFlatProperty:Array<SimpleFlatProperty>;
+            let simpleFlatProperty: Array<SimpleFlatProperty>;
             if (property instanceof PropertyFEModel) {
                 simpleFlatProperty = this.hierarchyNavService.getSimplePropertiesTree(property, instanceName);
             } else if (property instanceof DerivedFEProperty) {
                 // Need to find parent PropertyFEModel
-                let parentPropertyFEModel:PropertyFEModel = _.find(this.instanceFePropertiesMap[instanceName], (tmpFeProperty):boolean => {
-                    return property.propertiesName.indexOf(tmpFeProperty.name)===0;
+                let parentPropertyFEModel: PropertyFEModel = _.find(this.instanceFePropertiesMap[instanceName], (tmpFeProperty): boolean => {
+                    return property.propertiesName.indexOf(tmpFeProperty.name) === 0;
                 });
                 simpleFlatProperty = this.hierarchyNavService.getSimplePropertiesTree(parentPropertyFEModel, instanceName);
             }
@@ -422,7 +464,7 @@ export class PropertiesAssignmentComponent {
 
 
     selectInstanceRow = ($event) => {//get instance name
-        this.selectedInstanceData =  _.find(this.instancesNavigationData, (instance:ComponentInstance) => {
+        this.selectedInstanceData = _.find(this.instancesNavigationData, (instance: ComponentInstance) => {
             return instance.name == $event;
         });
         this.hierarchyNavTabs.triggerTabChange('Composition');
@@ -434,7 +476,7 @@ export class PropertiesAssignmentComponent {
             this.propertyInputTabs.triggerTabChange(this.currentMainTab.title);
             this.showUnsavedChangesAlert().then((proceed) => {
                 this.propertyInputTabs.selectTab(this.propertyInputTabs.tabs.find((tab) => tab.title === event.title));
-            }, ()=> {
+            }, () => {
             });
             return;
         }
@@ -448,6 +490,92 @@ export class PropertiesAssignmentComponent {
         this.searchQuery = '';
     };
 
+    /**Select Properties value from defined input values**/
+    selectInput = (): void => {
+        let instancesIds = this.keysPipe.transform(this.instanceFePropertiesMap, []);
+        angular.forEach(instancesIds, (instanceId: string): void => {
+            let selectedInstanceData: any = this.instances.find(instance => instance.uniqueId == instanceId
+                && instance instanceof ComponentInstance);
+            if (selectedInstanceData) {
+                let checkedProperties: PropertyBEModel[] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
+                angular.forEach(checkedProperties, (property: PropertyBEModel) => {
+                    this.propertiesService.setCheckedPropertyType(property.type);
+                    if (property.toscaGetFunctionType != null) {
+                        this.loadingProperties = true;
+                        property.getInputValues = null;
+                        property.value = null;
+                        property.toscaGetFunctionType = null;
+                        this.updateInstancePropertiesWithInput(checkedProperties, selectedInstanceData);
+                    } else {
+                        let modalTitle = 'Select value from Input';
+                        const modal = this.ModalService.createCustomModal(new ModalModel(
+                            'sm',
+                            modalTitle,
+                            null,
+                            [
+                                new ButtonModel('Save', 'blue',
+                                    () => {
+                                        this.loadingProperties = true;
+                                        let selectInputValue: InputFEModel = modal.instance.dynamicContent.instance.selectInputValue;
+                                        property.getInputValues = [];
+                                        const propertyInputDetail = new PropertyInputDetail();
+                                        propertyInputDetail.inputId = selectInputValue.uniqueId;
+                                        propertyInputDetail.inputName = selectInputValue.name;
+                                        propertyInputDetail.inputType = selectInputValue.type;
+                                        property.getInputValues.push(propertyInputDetail);
+                                        property.value = '{"get_input":"' + selectInputValue.name + '"}';
+                                        property.toscaGetFunctionType = ToscaGetFunctionType.GET_INPUT;
+                                        this.updateInstancePropertiesWithInput(checkedProperties, selectedInstanceData);
+                                        modal.instance.close();
+                                    }
+                                ),
+                                new ButtonModel('Cancel', 'outline grey', () => {
+                                    modal.instance.close();
+                                }),
+                            ],
+                            null /* type */
+                        )); //modal
+                        this.ModalService.addDynamicContentToModal(modal, InputListComponent);
+                        modal.instance.open();
+                    }
+                });
+            }
+        });
+    };
+
+    updateInstancePropertiesWithInput(checkedProperties: PropertyBEModel[], selectedInstanceData: any) {
+        this.componentInstanceServiceNg2.updateInstanceProperties(this.component.componentType, this.component.uniqueId,
+            this.selectedInstanceData.uniqueId, checkedProperties)
+        .subscribe(() => {
+            this.changeSelectedInstance(selectedInstanceData);
+        }, (error) => {
+            this.Notification.error({
+                message: 'Failed to select/deselect get_input call: ' + error,
+                title: 'Failure'
+            });
+        }, () => {
+            this.loadingProperties = false;
+            this.btnSelectInputText = this.translateService.translate('SELECT_INPUT_LABEL');
+        });
+    }
+
+    selectInputBtnLabel = () => {
+        let instancesIds = this.keysPipe.transform(this.instanceFePropertiesMap, []);
+        angular.forEach(instancesIds, (instanceId: string): void => {
+            let checkedProperties: PropertyBEModel[] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
+            angular.forEach(checkedProperties, (property: PropertyBEModel) => {
+                if(this.checkedPropertiesCount == 1) {
+                    if (property.toscaGetFunctionType == null) {
+                        this.btnSelectInputText = this.translateService.translate('SELECT_INPUT_LABEL');
+                    } else {
+                        this.btnSelectInputText = this.translateService.translate('DESELECT_INPUT_LABEL');
+                    }
+                } else {
+                    this.btnSelectInputText = this.translateService.translate('SELECT_INPUT_LABEL');
+                }
+            });
+        });
+    }
 
 
     /*** DECLARE PROPERTIES/INPUTS ***/
@@ -735,6 +863,7 @@ export class PropertiesAssignmentComponent {
                         };
                     } else {
                         if (this.isSelf()) {
+                            console.log("changedProperties", changedProperties);
                             request = this.topologyTemplateService.updateServiceProperties(this.component.uniqueId,  _.map(changedProperties, cp => {
                                 delete cp.constraints;
                                 return cp;
@@ -932,6 +1061,7 @@ export class PropertiesAssignmentComponent {
     updateCheckedPropertyCount = (increment: boolean): void => {
         this.checkedPropertiesCount += (increment) ? 1 : -1;
         console.log("CheckedProperties count is now.... " + this.checkedPropertiesCount);
+        this.selectInputBtnLabel();
     };
 
     updateCheckedChildPropertyCount = (increment: boolean): void => {
index bd7ccd1..544eb81 100644 (file)
@@ -53,6 +53,9 @@ export class PropertiesUtils {
                     newFEProp.updateExpandedChildPropertyId(newFEProp.name); //display only the first level of children
                     this.dataTypeService.checkForCustomBehavior(newFEProp);
 
+                    if (newFEProp.isToscaGetFunction()) {
+                        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 0249912..9921499 100644 (file)
@@ -123,6 +123,10 @@ export class TopologyTemplateService {
         return this.getComponentDataByFieldsName(component.componentType, component.uniqueId, [COMPONENT_FIELDS.COMPONENT_INPUTS]);
     }
 
+    getComponentInputsValues(componentType: string, componentId: string): Observable<ComponentGenericResponse> {
+        return this.getComponentDataByFieldsName(componentType, componentId, [COMPONENT_FIELDS.COMPONENT_INPUTS]);
+    }
+
     getComponentInputsWithProperties(componentType: string, componentId: string): Observable<ComponentGenericResponse> {
         return this.getComponentDataByFieldsName(componentType, componentId,
             [COMPONENT_FIELDS.COMPONENT_INPUTS, COMPONENT_FIELDS.COMPONENT_INSTANCES, COMPONENT_FIELDS.COMPONENT_INSTANCES_PROPERTIES, COMPONENT_FIELDS.COMPONENT_PROPERTIES]);
@@ -208,7 +212,7 @@ export class TopologyTemplateService {
         return this.http.get<InstanceBePropertiesMap>(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/filteredproperties/' + filterData.propertyName, {params: params});
     }
 
-    createServiceProperty(componentId: string, propertyModel: PropertyBEModel): Observable<PropertyBEModel> {
+     createServiceProperty(componentId: string, propertyModel: PropertyBEModel): Observable<PropertyBEModel> {
         const serverObject = {};
         serverObject[propertyModel.name] = propertyModel;
         return this.http.post<PropertyBEModel>(this.baseUrl + 'services/' + componentId + '/properties', serverObject)
index c86d207..f6b7732 100644 (file)
@@ -25,6 +25,8 @@ import { PropertyFEModel, PropertyBEModel, PropertyDeclareAPIModel, DerivedFEPro
 @Injectable()
 export class PropertiesService {
 
+    checkedPropertyType: string;
+
     constructor() {
     }
 
@@ -81,5 +83,13 @@ export class PropertiesService {
         return selectedProps;
     }
 
+    setCheckedPropertyType(type: string){
+        this.checkedPropertyType = type;
+    }
+
+    getCheckedPropertyType(){
+        return this.checkedPropertyType;
+    }
+
 
 }
index df869c3..cf27783 100644 (file)
     "DELETE_POLICY_TITLE": "Delete Policy",
     "DELETE_POLICY_MSG": "Are you sure you want to delete policy '{{policyName}}'?",
 
+    "=========== PROPERTIES ASSIGNMENT SELECT INPUT BUTTON ===========": "",
+    "SELECT_INPUT_LABEL": "Select Input" ,
+    "DESELECT_INPUT_LABEL": "Deselect Input",
+
     "=========== AUTOMATED UPGRADE ===========": "",
     "RESOURCE_UPGRADE_TITLE" : "Upgrade Services",
     "SERVICE_UPGRADE_TITLE" : "Update Service References",
index 010840e..f4171b2 100644 (file)
 
 package org.openecomp.sdc.be.datatypes.elements;
 
-import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
-
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
 import java.util.Map;
+import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
 
+@Getter
+@Setter
+@EqualsAndHashCode
+@ToString
 public class GetInputValueDataDefinition extends ToscaDataDefinition {
 
     private String propName;
     private String inputName;
+    private String inputType;
+    @EqualsAndHashCode.Exclude
+    @ToString.Exclude
     private String inputId;
     private Integer indexValue;
     private GetInputValueDataDefinition getInputIndex;
@@ -49,120 +59,5 @@ public class GetInputValueDataDefinition extends ToscaDataDefinition {
         this.setIndexValue(p.getIndexValue());
         this.setGetInputIndex(p.getGetInputIndex());
         this.setList(p.isList());
-
-
-    }
-
-    public String getPropName() {
-        return propName;
-    }
-
-    public void setPropName(String propName) {
-        this.propName = propName;
-    }
-
-    public String getInputName() {
-        return inputName;
-    }
-
-    public void setInputName(String inputName) {
-        this.inputName = inputName;
-    }
-
-    public Integer getIndexValue() {
-        return indexValue;
-    }
-
-    public void setIndexValue(Integer indexValue) {
-        this.indexValue = indexValue;
-    }
-
-    public GetInputValueDataDefinition getGetInputIndex() {
-        return getInputIndex;
     }
-
-    public void setGetInputIndex(GetInputValueDataDefinition getInputIndex) {
-        this.getInputIndex = getInputIndex;
-    }
-
-    public boolean isList() {
-        return isList;
-    }
-
-    public void setList(boolean isList) {
-        this.isList = isList;
-    }
-
-
-    public String getInputId() {
-        return inputId;
-    }
-
-    public void setInputId(String inputId) {
-        this.inputId = inputId;
-    }
-
-    @Override
-    public String toString() {
-        return "GetInputValueDataDefinition [propName=" + propName + ", inputName=" + inputName + ", indexValue=" + indexValue + ", getInputIndex=" + getInputIndex + ", isList=" + isList + "]";
-    }
-
-    @Override
-    public int hashCode() {
-        final int hashingNumerList = 1231;
-        final int hashingNumerNoList = 1237;
-        final int prime = 31;
-        int result = 1;
-        result = prime * result + ((getInputIndex == null) ? 0 : getInputIndex.hashCode());
-        result = prime * result + ((indexValue == null) ? 0 : indexValue.hashCode());
-        result = prime * result + ((inputName == null) ? 0 : inputName.hashCode());
-        result = prime * result + (isList ? hashingNumerList : hashingNumerNoList);
-        result = prime * result + ((propName == null) ? 0 : propName.hashCode());
-        return result;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj == null) {
-            return false;
-        }
-        if (getClass() != obj.getClass()) {
-            return false;
-        }
-        GetInputValueDataDefinition other = (GetInputValueDataDefinition) obj;
-        if (getInputIndex == null) {
-            if (other.getInputIndex != null) {
-                return false;
-            }
-        } else if (!getInputIndex.equals(other.getInputIndex)) {
-            return false;
-        }
-        if (indexValue == null) {
-            if (other.indexValue != null) {
-                return false;
-            }
-        } else if (!indexValue.equals(other.indexValue)) {
-            return false;
-        }
-        if (inputName == null) {
-            if (other.inputName != null) {
-                return false;
-            }
-        } else if (!inputName.equals(other.inputName)) {
-            return false;
-        }
-        if (isList != other.isList) {
-            return false;
-        }
-        if (propName == null) {
-            return other.propName == null;
-        } else {
-            return propName.equals(other.propName);
-        }
-    }
-
-
 }
index fdd3b58..871492c 100644 (file)
@@ -35,6 +35,7 @@ import lombok.EqualsAndHashCode;
 
 import org.apache.commons.collections.MapUtils;
 import static org.apache.commons.collections.CollectionUtils.isNotEmpty;
+import org.openecomp.sdc.be.datatypes.tosca.ToscaGetFunctionType;
 
 @EqualsAndHashCode(callSuper = false)
 @Data
@@ -55,6 +56,8 @@ public class PropertyDataDefinition extends ToscaDataDefinition {
     private String label;
     private Boolean immutable = Boolean.FALSE;
     private Boolean mappedToComponentProperty = Boolean.TRUE;
+    private ToscaGetFunctionType toscaGetFunctionType;
+
     private String inputPath;
     private String status;
     private String inputId;
@@ -107,6 +110,7 @@ public class PropertyDataDefinition extends ToscaDataDefinition {
         this.setInputId(propertyDataDefinition.getInputId());
         this.setInstanceUniqueId(propertyDataDefinition.getInstanceUniqueId());
         this.setPropertyId(propertyDataDefinition.getPropertyId());
+        this.setToscaGetFunctionType(propertyDataDefinition.getToscaGetFunctionType());
         this.parentPropertyType = propertyDataDefinition.getParentPropertyType();
         this.subPropertyInputPath = propertyDataDefinition.getSubPropertyInputPath();
         if (isNotEmpty(propertyDataDefinition.annotations)) {
diff --git a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/tosca/ToscaGetFunctionType.java b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/tosca/ToscaGetFunctionType.java
new file mode 100644 (file)
index 0000000..7e4299c
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2021 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=========================================================
+ */
+
+package org.openecomp.sdc.be.datatypes.tosca;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+@AllArgsConstructor
+public enum ToscaGetFunctionType {
+    GET_INPUT("get_input"),
+    GET_PROPERTY("get_property"),
+    GET_ATTRIBUTE("get_attribute");
+
+    @Getter
+    private final String toscaGetFunctionName;
+}