diff options
author | andre.schmid <andre.schmid@est.tech> | 2022-06-15 15:30:40 +0100 |
---|---|---|
committer | Michael Morris <michael.morris@est.tech> | 2022-06-22 20:36:22 +0000 |
commit | 7a7b13726c195e2944ccc59e4d5c5ade57318763 (patch) | |
tree | c22384a2abfc24adeb1c69a3696cda15c8e37548 | |
parent | fbab79aeaccf74385c9a55b697a1055a86bdf171 (diff) |
Support TOSCA get_attribute function
Adds support to TOSCA get_attribute function in the Property Assignment
TOSCA Function modal.
Change-Id: I73dda215a7c9d7fecf0803cc259634279c3bdfb6
Issue-ID: SDC-4053
Signed-off-by: andre.schmid <andre.schmid@est.tech>
12 files changed, 176 insertions, 116 deletions
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogic.java index ab01b99957..4bf81727e6 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogic.java @@ -107,6 +107,7 @@ import org.openecomp.sdc.be.model.RequirementCapabilityRelDef; import org.openecomp.sdc.be.model.RequirementDefinition; import org.openecomp.sdc.be.model.Resource; import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.model.ToscaPropertyData; import org.openecomp.sdc.be.model.User; import org.openecomp.sdc.be.model.jsonjanusgraph.config.ContainerInstanceTypesData; import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ArtifactsOperations; @@ -2387,13 +2388,25 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { return; } + if (toscaGetFunction.getFunctionType() == ToscaGetFunctionType.GET_ATTRIBUTE) { + if (toscaGetFunction.getPropertySource() == PropertySource.SELF) { + validateGetFunction(property, parentComponent.getAttributes(), parentComponent.getModel()); + } else if (toscaGetFunction.getPropertySource() == PropertySource.INSTANCE) { + final ComponentInstance componentInstance = + parentComponent.getComponentInstanceById(toscaGetFunction.getSourceUniqueId()) + .orElseThrow(ToscaGetFunctionExceptionSupplier.instanceNotFound(toscaGetFunction.getSourceName())); + validateGetFunction(property, componentInstance.getAttributes(), parentComponent.getModel()); + } + + return; + } throw ToscaGetFunctionExceptionSupplier.functionNotSupported(toscaGetFunction.getFunctionType()).get(); } - private <T extends PropertyDefinition, U extends PropertyDefinition> void validateGetFunction(final T property, - final List<U> parentProperties, - final String model) { + private <T extends PropertyDefinition> void validateGetFunction(final T property, + final List<? extends ToscaPropertyData> parentProperties, + final String model) { final ToscaGetFunctionDataDefinition toscaGetFunction = property.getToscaGetFunction(); if (CollectionUtils.isEmpty(parentProperties)) { throw ToscaGetFunctionExceptionSupplier @@ -2402,7 +2415,7 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { ).get(); } final String getFunctionPropertyUniqueId = toscaGetFunction.getPropertyUniqueId(); - T referredProperty = (T) parentProperties.stream() + ToscaPropertyData referredProperty = parentProperties.stream() .filter(property1 -> getFunctionPropertyUniqueId.equals(property1.getUniqueId())) .findFirst() .orElseThrow(ToscaGetFunctionExceptionSupplier @@ -2423,8 +2436,9 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { } } - private <T extends PropertyDefinition> T findSubProperty(final T referredProperty, final ToscaGetFunctionDataDefinition toscaGetFunction, - final String model) { + private ToscaPropertyData findSubProperty(final ToscaPropertyData referredProperty, + final ToscaGetFunctionDataDefinition toscaGetFunction, + final String model) { final Map<String, DataTypeDefinition> dataTypeMap = loadDataTypes(model); final List<String> propertyPathFromSource = toscaGetFunction.getPropertyPathFromSource(); DataTypeDefinition dataType = dataTypeMap.get(referredProperty.getType()); @@ -2432,10 +2446,10 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { throw ToscaGetFunctionExceptionSupplier .propertyDataTypeNotFound(propertyPathFromSource.get(0), referredProperty.getType(), toscaGetFunction.getFunctionType()).get(); } - T foundProperty = referredProperty; + ToscaPropertyData foundProperty = referredProperty; for (int i = 1; i < propertyPathFromSource.size(); i++) { final String currentPropertyName = propertyPathFromSource.get(i); - foundProperty = (T) dataType.getProperties().stream() + foundProperty = dataType.getProperties().stream() .filter(propertyDefinition -> currentPropertyName.equals(propertyDefinition.getName())).findFirst() .orElseThrow( ToscaGetFunctionExceptionSupplier diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogicTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogicTest.java index bf3ec3cb7e..cd916d0d1e 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogicTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogicTest.java @@ -678,54 +678,6 @@ class ComponentInstanceBusinessLogicTest { assertEquals(expectedResponse.getStatus(), actualResponse.getStatus()); } - @Test - void testToscaGetFunctionValidation_toscaFunctionNotSupportedTest() { - final String userId = "userId"; - final String containerComponentId = "containerComponentId"; - final String containerComponentName = "containerComponentName"; - final String resourceInstanceId = "resourceInstanceId"; - final List<ComponentInstanceProperty> properties = new ArrayList<>(); - final ComponentInstanceProperty propertyGetInput = new ComponentInstanceProperty(); - propertyGetInput.setName("anyName"); - final var toscaGetFunction = new ToscaGetFunctionDataDefinition(); - toscaGetFunction.setFunctionType(ToscaGetFunctionType.GET_ATTRIBUTE); - toscaGetFunction.setPropertySource(PropertySource.SELF); - toscaGetFunction.setPropertyPathFromSource(List.of("sourcePath")); - toscaGetFunction.setSourceName("sourceName"); - toscaGetFunction.setSourceUniqueId("sourceUniqueId"); - toscaGetFunction.setPropertyName("propertyName"); - toscaGetFunction.setPropertyUniqueId("propertyId"); - propertyGetInput.setToscaGetFunction(toscaGetFunction); - properties.add(propertyGetInput); - - final Component component = new Service(); - component.setName(containerComponentName); - component.setUniqueId(containerComponentId); - component.setLastUpdaterUserId(userId); - component.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); - - final Map<String, List<ComponentInstanceProperty>> componentInstanceProps = new HashMap<>(); - componentInstanceProps.put(resourceInstanceId, properties); - component.setComponentInstancesProperties(componentInstanceProps); - - final ComponentInstance resourceInstance = createComponentInstance("componentInstance1"); - resourceInstance.setUniqueId(resourceInstanceId); - component.setComponentInstances(List.of(resourceInstance)); - - mockComponentForToscaGetFunctionValidation(component); - //when - final Either<List<ComponentInstanceProperty>, ResponseFormat> responseFormatEither = - componentInstanceBusinessLogic - .createOrUpdatePropertiesValues(ComponentTypeEnum.RESOURCE_INSTANCE, containerComponentId, resourceInstanceId, properties, userId); - //then - assertTrue(responseFormatEither.isRight(), "Expecting an error"); - final ResponseFormat actualResponse = responseFormatEither.right().value(); - final ResponseFormat expectedResponse = ToscaGetFunctionExceptionSupplier - .functionNotSupported(toscaGetFunction.getFunctionType()).get().getResponseFormat(); - assertEquals(expectedResponse.getFormattedMessage(), actualResponse.getFormattedMessage()); - assertEquals(expectedResponse.getStatus(), actualResponse.getStatus()); - } - @ParameterizedTest @MethodSource("getToscaFunctionForValidation") void testToscaGetFunctionValidation_AttributesNotFoundTest(final ToscaGetFunctionDataDefinition toscaGetFunction, @@ -762,9 +714,8 @@ class ComponentInstanceBusinessLogicTest { //then assertTrue(responseFormatEither.isRight(), "Expecting an error"); final ResponseFormat actualResponse = responseFormatEither.right().value(); - final ResponseFormat expectedResponse = expectedValidationResponse; - assertEquals(expectedResponse.getFormattedMessage(), actualResponse.getFormattedMessage()); - assertEquals(expectedResponse.getStatus(), actualResponse.getStatus()); + assertEquals(expectedValidationResponse.getFormattedMessage(), actualResponse.getFormattedMessage()); + assertEquals(expectedValidationResponse.getStatus(), actualResponse.getStatus()); } @Test diff --git a/catalog-be/src/test/resources/config/catalog-be/error-configuration.yaml b/catalog-be/src/test/resources/config/catalog-be/error-configuration.yaml index 2100dc8292..293bd49632 100644 --- a/catalog-be/src/test/resources/config/catalog-be/error-configuration.yaml +++ b/catalog-be/src/test/resources/config/catalog-be/error-configuration.yaml @@ -2392,3 +2392,12 @@ errors: message: "The %1 '%2' type '%3' was not found.", messageId: "SVC4170" } + + #-----------SVC4172--------------------------- + #%1 - TOSCA function attribute + TOSCA_FUNCTION_MISSING_ATTRIBUTE: { + code: 400, + message: "Missing TOSCA function '%1'.", + messageId: "SVC4172" + } + diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/AttributeDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/AttributeDefinition.java index d1bcedc8ea..be9bee0d53 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/AttributeDefinition.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/AttributeDefinition.java @@ -21,9 +21,10 @@ package org.openecomp.sdc.be.model; import lombok.NoArgsConstructor; import org.openecomp.sdc.be.datatypes.elements.AttributeDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition; @NoArgsConstructor -public class AttributeDefinition extends AttributeDataDefinition implements IOperationParameter, IComplexDefaultValue { +public class AttributeDefinition extends AttributeDataDefinition implements IOperationParameter, IComplexDefaultValue, ToscaPropertyData { public AttributeDefinition(final AttributeDataDefinition attributeDataDefinition) { super(attributeDataDefinition); @@ -49,4 +50,14 @@ public class AttributeDefinition extends AttributeDataDefinition implements IOpe return "AttributeDefinition{" + "name=" + getName() + "uniqueId=" + getUniqueId() + "ownerId=" + getOwnerId() + "type=" + getType() + "description=" + getDescription() + "default=" + getDefaultValue() + '}'; } + + @Override + public String getSchemaType() { + final SchemaDefinition schema = getSchema(); + if (schema == null || schema.getProperty() == null) { + return null; + } + return schema.getProperty().getType(); + } + } diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/PropertyDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/PropertyDefinition.java index 6e313eda6c..d9add3f425 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/PropertyDefinition.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/PropertyDefinition.java @@ -31,7 +31,7 @@ import org.apache.commons.collections.CollectionUtils; import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; import org.openecomp.sdc.be.model.operations.impl.PropertyOperation; -public class PropertyDefinition extends PropertyDataDefinition implements IOperationParameter, IComplexDefaultValue { +public class PropertyDefinition extends PropertyDataDefinition implements IOperationParameter, IComplexDefaultValue, ToscaPropertyData { private List<PropertyConstraint> constraints; diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ToscaPropertyData.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ToscaPropertyData.java new file mode 100644 index 0000000000..14c95757c7 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ToscaPropertyData.java @@ -0,0 +1,31 @@ +/* + * - + * ============LICENSE_START======================================================= + * Copyright (C) 2022 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.model; + +/** + * Represents basic/common TOSCA Property, Attribute or Input methods + */ +public interface ToscaPropertyData { + String getUniqueId(); + String getType(); + String getSchemaType(); +} diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-function.component.html b/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-function.component.html index f0db645b0e..b6b313d93c 100644 --- a/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-function.component.html +++ b/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-function.component.html @@ -27,14 +27,14 @@ [ngValue]="toscaFunction">{{toscaFunction | lowercase}}</option> </select> </div> - <div class="i-sdc-form-item" *ngIf="toscaGetFunction.functionType === TOSCA_FUNCTION_GET_PROPERTY"> + <div class="i-sdc-form-item" *ngIf="showPropertySourceDropdown()"> <label class="i-sdc-form-label required">{{'TOSCA_FUNCTION_PROPERTY_SOURCE_LABEL' | translate}}</label> <select name="propertySource" [(ngModel)]="propertySource" (change)="onPropertySourceChange()"> <option *ngFor="let propertySource of propertySourceList" [ngValue]="propertySource">{{propertySource}}</option> </select> </div> - <div *ngIf="showDropdown()" class="i-sdc-form-item"> + <div *ngIf="showPropertyDropdown()" class="i-sdc-form-item"> <label class="i-sdc-form-label required">{{dropdownValuesLabel}}</label> <select [(ngModel)]="selectedProperty" name="selectedProperty" (change)="onPropertyChange()"> <option *ngFor="let value of propertyDropdownList" [ngValue]="value">{{value.propertyLabel}}</option> diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-function.component.ts b/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-function.component.ts index 4eefbcb467..b71a61dc01 100644 --- a/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-function.component.ts +++ b/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-function.component.ts @@ -18,7 +18,7 @@ */ import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core'; -import {ComponentMetadata, DataTypeModel, PropertyBEModel, PropertyModel} from 'app/models'; +import {AttributeModel, ComponentMetadata, DataTypeModel, PropertyBEModel, PropertyModel} from 'app/models'; import {TopologyTemplateService} from "../../../services/component-services/topology-template.service"; import {WorkspaceService} from "../../workspace/workspace.service"; import {PropertiesService} from "../../../services/properties.service"; @@ -82,8 +82,6 @@ export class ToscaFunctionComponent implements OnInit { 'toscaGetFunction': this.toscaGetFunctionForm }); - TOSCA_FUNCTION_GET_PROPERTY = ToscaGetFunctionType.GET_PROPERTY; - selectedProperty: PropertyDropdownValue; isLoading: boolean = false; propertyDropdownList: Array<PropertyDropdownValue> = []; @@ -123,7 +121,7 @@ export class ToscaFunctionComponent implements OnInit { } this.toscaGetFunction = new ToscaGetFunction(this.property.toscaGetFunction); this.toscaGetFunctionForm.setValue(this.toscaGetFunction); - if (this.toscaGetFunction.functionType === ToscaGetFunctionType.GET_PROPERTY) { + if (this.isGetPropertySelected() || this.isGetAttributeSelected()) { if (this.toscaGetFunction.propertySource === PropertySource.SELF) { this.propertySource = PropertySource.SELF; } else { @@ -138,6 +136,7 @@ export class ToscaFunctionComponent implements OnInit { } private loadToscaFunctions(): void { + this.toscaFunctions.push(ToscaGetFunctionType.GET_ATTRIBUTE); this.toscaFunctions.push(ToscaGetFunctionType.GET_INPUT); this.toscaFunctions.push(ToscaGetFunctionType.GET_PROPERTY); } @@ -210,6 +209,8 @@ export class ToscaFunctionComponent implements OnInit { this.dropdownValuesLabel = this.translateService.translate('INPUT_DROPDOWN_LABEL'); } else if (this.isGetPropertySelected()) { this.dropdownValuesLabel = this.translateService.translate('TOSCA_FUNCTION_PROPERTY_DROPDOWN_LABEL'); + } else if (this.isGetAttributeSelected()) { + this.dropdownValuesLabel = this.translateService.translate('TOSCA_FUNCTION_ATTRIBUTE_DROPDOWN_LABEL'); } } @@ -231,19 +232,20 @@ export class ToscaFunctionComponent implements OnInit { this.startLoading(); const propertiesObservable: Observable<ComponentGenericResponse> = this.getPropertyObservable(); propertiesObservable.subscribe( (response: ComponentGenericResponse) => { - const properties: PropertyBEModel[] = this.extractProperties(response); + const properties: Array<PropertyBEModel | AttributeModel> = this.extractProperties(response); if (!properties || properties.length === 0) { - const msgCode = this.isGetInputSelected() ? 'TOSCA_FUNCTION_NO_INPUT_FOUND' : 'TOSCA_FUNCTION_NO_PROPERTY_FOUND'; + const msgCode = this.getNotFoundMsgCode(); this.dropDownErrorMsg = this.translateService.translate(msgCode, {type: this.propertyTypeToString()}); return; } this.addPropertiesToDropdown(properties); if (this.propertyDropdownList.length == 0) { - const msgCode = this.isGetInputSelected() ? 'TOSCA_FUNCTION_NO_INPUT_FOUND' : 'TOSCA_FUNCTION_NO_PROPERTY_FOUND'; + const msgCode = this.getNotFoundMsgCode(); this.dropDownErrorMsg = this.translateService.translate(msgCode, {type: this.propertyTypeToString()}); } }, (error) => { console.error('An error occurred while loading properties.', error); + this.stopLoading(); }, () => { if (onComplete) { onComplete(); @@ -252,6 +254,20 @@ export class ToscaFunctionComponent implements OnInit { }); } + private getNotFoundMsgCode(): string { + if (this.isGetInputSelected()) { + return 'TOSCA_FUNCTION_NO_INPUT_FOUND'; + } + if (this.isGetAttributeSelected()) { + return 'TOSCA_FUNCTION_NO_ATTRIBUTE_FOUND'; + } + if (this.isGetPropertySelected()) { + return 'TOSCA_FUNCTION_NO_PROPERTY_FOUND'; + } + + return undefined; + } + private propertyTypeToString() { if (this.property.schemaType) { return `${this.property.type} of ${this.property.schemaType}`; @@ -259,7 +275,7 @@ export class ToscaFunctionComponent implements OnInit { return this.property.type; } - private extractProperties(componentGenericResponse: ComponentGenericResponse): PropertyBEModel[] { + private extractProperties(componentGenericResponse: ComponentGenericResponse): Array<PropertyBEModel | AttributeModel> { if (this.isGetInputSelected()) { return componentGenericResponse.inputs; } @@ -270,6 +286,10 @@ export class ToscaFunctionComponent implements OnInit { const componentInstanceProperties: PropertyModel[] = componentGenericResponse.componentInstancesProperties[this.instanceNameAndIdMap.get(this.propertySource)]; return this.removeSelectedProperty(componentInstanceProperties); } + if (this.propertySource === PropertySource.SELF) { + return componentGenericResponse.attributes; + } + return componentGenericResponse.componentInstancesAttributes[this.instanceNameAndIdMap.get(this.propertySource)]; } private getPropertyObservable(): Observable<ComponentGenericResponse> { @@ -282,6 +302,12 @@ export class ToscaFunctionComponent implements OnInit { } return this.topologyTemplateService.getComponentInstanceProperties(this.componentMetadata.componentType, this.componentMetadata.uniqueId); } + if (this.isGetAttributeSelected()) { + if (this.propertySource === PropertySource.SELF) { + return this.topologyTemplateService.findAllComponentAttributes(this.componentMetadata.componentType, this.componentMetadata.uniqueId); + } + return this.topologyTemplateService.findAllComponentInstanceAttributes(this.componentMetadata.componentType, this.componentMetadata.uniqueId); + } } private removeSelectedProperty(componentInstanceProperties: PropertyModel[]): PropertyModel[] { @@ -299,7 +325,7 @@ export class ToscaFunctionComponent implements OnInit { this.propertyDropdownList.sort((a, b) => a.propertyLabel.localeCompare(b.propertyLabel)); } - private addPropertiesToDropdown(properties: PropertyBEModel[]): void { + private addPropertiesToDropdown(properties: Array<PropertyBEModel | AttributeModel>): void { for (const property of properties) { if (this.hasSameType(property)) { this.addPropertyToDropdown({ @@ -314,7 +340,8 @@ export class ToscaFunctionComponent implements OnInit { } } - private fillPropertyDropdownWithMatchingChildProperties(inputProperty: PropertyBEModel, parentPropertyList: Array<PropertyBEModel> = []): void { + private fillPropertyDropdownWithMatchingChildProperties(inputProperty: PropertyBEModel | AttributeModel, + parentPropertyList: Array<PropertyBEModel | AttributeModel> = []): void { const dataTypeFound: DataTypeModel = this.dataTypeService.getDataTypeByModelAndTypeName(this.componentMetadata.model, inputProperty.type); if (!dataTypeFound || !dataTypeFound.properties) { return; @@ -334,7 +361,7 @@ export class ToscaFunctionComponent implements OnInit { }); } - private hasSameType(property: PropertyBEModel) { + private hasSameType(property: PropertyBEModel | AttributeModel) { if (this.typeHasSchema(this.property.type)) { if (!property.schema || !property.schema.property) { return false; @@ -349,6 +376,10 @@ export class ToscaFunctionComponent implements OnInit { return this.toscaGetFunction.functionType === ToscaGetFunctionType.GET_PROPERTY; } + private isGetAttributeSelected(): boolean { + return this.toscaGetFunction.functionType === ToscaGetFunctionType.GET_ATTRIBUTE; + } + private isGetInputSelected(): boolean { return this.toscaGetFunction.functionType === ToscaGetFunctionType.GET_INPUT; } @@ -369,8 +400,8 @@ export class ToscaFunctionComponent implements OnInit { this.isLoading = true; } - showDropdown(): boolean { - if (this.toscaGetFunction.functionType === ToscaGetFunctionType.GET_PROPERTY) { + showPropertyDropdown(): boolean { + if (this.isGetPropertySelected() || this.isGetAttributeSelected()) { return this.toscaGetFunction.propertySource && !this.isLoading && !this.dropDownErrorMsg; } @@ -416,6 +447,10 @@ export class ToscaFunctionComponent implements OnInit { showClearButton(): boolean { return this.allowClear && this.toscaGetFunction.functionType !== undefined; } + + showPropertySourceDropdown(): boolean { + return this.isGetPropertySelected() || this.isGetAttributeSelected(); + } } export interface PropertyDropdownValue { diff --git a/catalog-ui/src/app/ng2/services/component-services/topology-template.service.ts b/catalog-ui/src/app/ng2/services/component-services/topology-template.service.ts index 92a12c8305..a2abb38f65 100644 --- a/catalog-ui/src/app/ng2/services/component-services/topology-template.service.ts +++ b/catalog-ui/src/app/ng2/services/component-services/topology-template.service.ts @@ -22,27 +22,28 @@ */ import * as _ from "lodash"; -import {Injectable, Inject} from '@angular/core'; +import {Inject, Injectable} from '@angular/core'; import {Observable} from 'rxjs/Observable'; import 'rxjs/add/operator/map'; import 'rxjs/add/operator/toPromise'; import { + ArtifactModel, + AttributeModel, + Capability, Component, + FilterPropertiesAssignmentData, + IFileDownload, InputBEModel, InstancePropertiesAPIMap, - FilterPropertiesAssignmentData, - ArtifactModel, + OperationModel, PropertyModel, - IFileDownload, - AttributeModel, - Capability, Requirement, BEOperationModel, InterfaceModel + Requirement } from "app/models"; -import {ArtifactGroupType, COMPONENT_FIELDS} from "app/utils"; +import {API_QUERY_PARAMS, ArtifactGroupType, COMPONENT_FIELDS} from "app/utils"; import {ComponentGenericResponse} from "../responses/component-generic-response"; import {InstanceBePropertiesMap} from "../../../models/properties-inputs/property-fe-map"; -import {API_QUERY_PARAMS} from "app/utils"; import {ComponentType, ServerTypeUrl, SERVICE_FIELDS} from "../../../utils/constants"; -import {SdcConfigToken, ISdcConfig} from "../../config/sdc-config.config"; +import {ISdcConfig, SdcConfigToken} from "../../config/sdc-config.config"; import {IDependenciesServerResponse} from "../responses/dependencies-server-response"; import {AutomatedUpgradeGenericResponse} from "../responses/automated-upgrade-response"; import {IAutomatedUpgradeRequestObj} from "../../pages/automated-upgrade/automated-upgrade.service"; @@ -50,26 +51,15 @@ import {ComponentInstance} from "../../../models/componentsInstances/componentIn import {CommonUtils} from "../../../utils/common-utils"; import {RelationshipModel} from "../../../models/graph/relationship"; import {ServiceGenericResponse} from "../responses/service-generic-response"; -import { HttpClient, HttpParams, HttpHeaders } from "@angular/common/http"; -import { HttpHelperService } from "../http-hepler.service"; -import { - Component as TopologyTemplate, - FullComponentInstance, - Service, - OperationModel, -} from 'app/models'; -import { ConsumptionInput } from "../../components/logic/service-consumption/service-consumption.component"; -import { ConstraintObject } from "../../components/logic/service-dependencies/service-dependencies.component"; -import { ComponentMetadata } from "../../../models/component-metadata"; -import { PolicyInstance } from "../../../models/graph/zones/policy-instance"; -import { PropertyBEModel } from "../../../models/properties-inputs/property-be-model"; +import {HttpClient, HttpHeaders, HttpParams} from "@angular/common/http"; +import {HttpHelperService} from "../http-hepler.service"; +import {ConsumptionInput} from "../../components/logic/service-consumption/service-consumption.component"; +import {ConstraintObject} from "../../components/logic/service-dependencies/service-dependencies.component"; +import {PolicyInstance} from "../../../models/graph/zones/policy-instance"; +import {PropertyBEModel} from "../../../models/properties-inputs/property-be-model"; import {map} from "rxjs/operators"; import {CapabilitiesConstraintObject} from "../../components/logic/capabilities-constraint/capabilities-constraint.component"; -import { - BEInterfaceOperationModel, - ComponentInterfaceDefinitionModel, - InterfaceOperationModel -} from "../../../models/interfaceOperation"; +import {BEInterfaceOperationModel, InterfaceOperationModel} from "../../../models/interfaceOperation"; import {AttributeBEModel} from "../../../models/attributes-outputs/attribute-be-model"; import {InstanceAttributesAPIMap} from "../../../models/attributes-outputs/attribute-fe-map"; @@ -169,6 +159,10 @@ export class TopologyTemplateService { return this.getComponentDataByFieldsName(componentType, componentUniqueId, [COMPONENT_FIELDS.COMPONENT_PROPERTIES]); } + findAllComponentAttributes(componentType: string, componentUniqueId: string): Observable<ComponentGenericResponse> { + return this.getComponentDataByFieldsName(componentType, componentUniqueId, [COMPONENT_FIELDS.COMPONENT_ATTRIBUTES]); + } + getCapabilitiesAndRequirements(componentType: string, componentId: string): Observable<ComponentGenericResponse> { return this.getComponentDataByFieldsName(componentType, componentId, [COMPONENT_FIELDS.COMPONENT_REQUIREMENTS, COMPONENT_FIELDS.COMPONENT_CAPABILITIES]); } @@ -393,7 +387,7 @@ export class TopologyTemplateService { } updateProperty = (componentType: string, componentId: string, property: PropertyModel): Observable<PropertyModel> => { - var propertiesList:PropertyBEModel[] = [property]; + const propertiesList: PropertyBEModel[] = [property]; return this.http.put<PropertyModel>(this.baseUrl + this.getServerTypeUrl(componentType) + componentId + '/properties', propertiesList) .map((response) => { return new PropertyModel(response[Object.keys(response)[0]]); @@ -470,6 +464,10 @@ export class TopologyTemplateService { return this.getComponentDataByFieldsName(componentType, componentId, [COMPONENT_FIELDS.COMPONENT_INSTANCES_PROPERTIES]); } + findAllComponentInstanceAttributes(componentType: string, componentId: string): Observable<ComponentGenericResponse> { + return this.getComponentDataByFieldsName(componentType, componentId, [COMPONENT_FIELDS.COMPONENT_INSTANCES_ATTRIBUTES]); + } + getComponentInstanceCapabilityProperties(componentType: string, componentId: string): Observable<ComponentGenericResponse> { return this.getComponentDataByFieldsName(componentType, componentId, [COMPONENT_FIELDS.COMPONENT_CAPABILITIES, COMPONENT_FIELDS.COMPONENT_CAPABILITIES_PROPERTIES]); diff --git a/catalog-ui/src/assets/languages/en_US.json b/catalog-ui/src/assets/languages/en_US.json index 238e09958f..96e01dbaf9 100644 --- a/catalog-ui/src/assets/languages/en_US.json +++ b/catalog-ui/src/assets/languages/en_US.json @@ -517,8 +517,10 @@ "TOSCA_FUNCTION_MODAL_TITLE": "Set value using TOSCA functions", "INPUT_DROPDOWN_LABEL": "Input", "TOSCA_FUNCTION_PROPERTY_DROPDOWN_LABEL": "Property", + "TOSCA_FUNCTION_ATTRIBUTE_DROPDOWN_LABEL": "Attribute", "TOSCA_FUNCTION_NO_INPUT_FOUND": "No input found with type {{type}}", "TOSCA_FUNCTION_NO_PROPERTY_FOUND": "No property found with type {{type}}", + "TOSCA_FUNCTION_NO_ATTRIBUTE_FOUND": "No attribute found with type {{type}}", "=========== AUTOMATED UPGRADE ===========": "", "RESOURCE_UPGRADE_TITLE": "Upgrade Services", "SERVICE_UPGRADE_TITLE": "Update Service References", diff --git a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/ToscaGetFunctionDataDefinition.java b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/ToscaGetFunctionDataDefinition.java index adc2ad6b44..0741d6849e 100644 --- a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/ToscaGetFunctionDataDefinition.java +++ b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/ToscaGetFunctionDataDefinition.java @@ -63,8 +63,8 @@ public class ToscaGetFunctionDataDefinition { } final var gson = new Gson(); - if (functionType == ToscaGetFunctionType.GET_PROPERTY) { - return gson.toJson(buildGetPropertyFunctionValue()); + if (functionType == ToscaGetFunctionType.GET_PROPERTY || functionType == ToscaGetFunctionType.GET_ATTRIBUTE) { + return gson.toJson(buildFunctionValueWithPropertySource()); } if (functionType == ToscaGetFunctionType.GET_INPUT) { return gson.toJson(buildGetInputFunctionValue()); @@ -73,9 +73,11 @@ public class ToscaGetFunctionDataDefinition { throw new UnsupportedOperationException(String.format("ToscaGetFunctionType '%s' is not supported yet", functionType)); } - private Map<String, Object> buildGetPropertyFunctionValue() { + private Map<String, Object> buildFunctionValueWithPropertySource() { if (propertySource == null) { - throw new IllegalStateException("propertySource is required in order to generate the get_property value"); + throw new IllegalStateException( + String.format("propertySource is required in order to generate the %s value", functionType.getFunctionName()) + ); } if (propertySource == PropertySource.SELF) { return Map.of(functionType.getFunctionName(), @@ -84,7 +86,9 @@ public class ToscaGetFunctionDataDefinition { } if (propertySource == PropertySource.INSTANCE) { if (sourceName == null) { - throw new IllegalStateException("sourceName is required in order to generate the get_property from INSTANCE value"); + throw new IllegalStateException( + String.format("sourceName is required in order to generate the %s from INSTANCE value", functionType.getFunctionName()) + ); } return Map.of(functionType.getFunctionName(), Stream.concat(Stream.of(sourceName), propertyPathFromSource.stream()).collect(Collectors.toList()) diff --git a/common-be/src/test/java/org/openecomp/sdc/be/datatypes/elements/ToscaGetFunctionDataDefinitionTest.java b/common-be/src/test/java/org/openecomp/sdc/be/datatypes/elements/ToscaGetFunctionDataDefinitionTest.java index 1c4a678010..a199f5ec97 100644 --- a/common-be/src/test/java/org/openecomp/sdc/be/datatypes/elements/ToscaGetFunctionDataDefinitionTest.java +++ b/common-be/src/test/java/org/openecomp/sdc/be/datatypes/elements/ToscaGetFunctionDataDefinitionTest.java @@ -21,7 +21,10 @@ package org.openecomp.sdc.be.datatypes.elements; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; import com.google.gson.Gson; import java.util.List; @@ -29,6 +32,8 @@ import java.util.Map; import java.util.stream.Collectors; import java.util.stream.Stream; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; import org.openecomp.sdc.be.datatypes.enums.PropertySource; import org.openecomp.sdc.be.datatypes.tosca.ToscaGetFunctionType; @@ -78,10 +83,10 @@ class ToscaGetFunctionDataDefinitionTest { assertEquals(value, toscaGetFunction.getPropertyPathFromSource()); } - @Test - void generateValueForGetPropertyFromSelfTest() { + @ParameterizedTest + @EnumSource(value = ToscaGetFunctionType.class, names = {"GET_ATTRIBUTE", "GET_PROPERTY"}) + void generateValueForGetFunctionWithSelfAsSourceTest(final ToscaGetFunctionType toscaFunction) { //given - final ToscaGetFunctionType toscaFunction = ToscaGetFunctionType.GET_PROPERTY; final var toscaGetFunction = createGetFunction(toscaFunction, PropertySource.SELF, List.of("property"), null); //when String actualValue = toscaGetFunction.generatePropertyValue(); @@ -110,10 +115,10 @@ class ToscaGetFunctionDataDefinitionTest { assertEquals(expectedGetPropertyValue, actualGetPropertyValue); } - @Test - void generateValueForGetPropertyFromInstanceTest() { + @ParameterizedTest + @EnumSource(value = ToscaGetFunctionType.class, names = {"GET_ATTRIBUTE", "GET_PROPERTY"}) + void generateValueForGetFunctionWithInstanceAsSourceTest(final ToscaGetFunctionType toscaFunction) { //given - final ToscaGetFunctionType toscaFunction = ToscaGetFunctionType.GET_PROPERTY; final var toscaGetFunction = createGetFunction(toscaFunction, PropertySource.INSTANCE, List.of("property"), "sourceName"); //when String actualValue = toscaGetFunction.generatePropertyValue(); |