diff options
44 files changed, 2112 insertions, 601 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 4bf81727e6..dcccfd961d 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 @@ -48,6 +48,7 @@ import org.openecomp.sdc.be.components.impl.exceptions.BusinessLogicException; import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException; import org.openecomp.sdc.be.components.impl.exceptions.ByResponseFormatComponentException; import org.openecomp.sdc.be.components.impl.exceptions.ComponentException; +import org.openecomp.sdc.be.components.impl.exceptions.ToscaFunctionExceptionSupplier; import org.openecomp.sdc.be.components.impl.exceptions.ToscaGetFunctionExceptionSupplier; import org.openecomp.sdc.be.components.impl.instance.ComponentInstanceChangeOperationOrchestrator; import org.openecomp.sdc.be.components.impl.utils.DirectivesUtil; @@ -1960,9 +1961,14 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { validateMandatoryFields(property); validatePropertyExistsOnComponent(property, containerComponent, foundResourceInstance); String propertyParentUniqueId = property.getParentUniqueId(); - if (property.isGetFunction()) { - validateToscaGetFunction(property, containerComponent); - property.setValue(property.getToscaGetFunction().generatePropertyValue()); + if (property.isToscaFunction()) { + if (property.getToscaFunction().getType() == null) { + throw ToscaFunctionExceptionSupplier.missingFunctionType().get(); + } + if (property.isToscaGetFunction()) { + validateToscaGetFunction(property, containerComponent); + } + property.setValue(property.getToscaFunction().getValue()); } Either<String, ResponseFormat> updatedPropertyValue = updatePropertyObjectValue(property, containerComponent.getModel()); if (updatedPropertyValue.isRight()) { @@ -2297,7 +2303,7 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { // Specific Update Logic String newValue = property.getValue(); - if (property.hasGetFunction()) { + if (property.hasToscaFunction()) { return Either.left(newValue); } @@ -2369,7 +2375,7 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { } private <T extends PropertyDefinition> void validateToscaGetFunction(T property, Component parentComponent) { - final ToscaGetFunctionDataDefinition toscaGetFunction = property.getToscaGetFunction(); + final ToscaGetFunctionDataDefinition toscaGetFunction = (ToscaGetFunctionDataDefinition) property.getToscaFunction(); validateGetToscaFunctionAttributes(toscaGetFunction); validateGetPropertySource(toscaGetFunction.getFunctionType(), toscaGetFunction.getPropertySource()); if (toscaGetFunction.getFunctionType() == ToscaGetFunctionType.GET_INPUT) { @@ -2407,7 +2413,7 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { private <T extends PropertyDefinition> void validateGetFunction(final T property, final List<? extends ToscaPropertyData> parentProperties, final String model) { - final ToscaGetFunctionDataDefinition toscaGetFunction = property.getToscaGetFunction(); + final ToscaGetFunctionDataDefinition toscaGetFunction = (ToscaGetFunctionDataDefinition) property.getToscaFunction(); if (CollectionUtils.isEmpty(parentProperties)) { throw ToscaGetFunctionExceptionSupplier .propertyNotFoundOnTarget(toscaGetFunction.getPropertyName(), toscaGetFunction.getPropertySource(), @@ -2428,11 +2434,11 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { if (!property.getType().equals(referredProperty.getType())) { throw ToscaGetFunctionExceptionSupplier - .propertyTypeDiverge(toscaGetFunction.getFunctionType(), referredProperty.getType(), property.getType()).get(); + .propertyTypeDiverge(toscaGetFunction.getType(), referredProperty.getType(), property.getType()).get(); } if (PropertyType.typeHasSchema(referredProperty.getType()) && !referredProperty.getSchemaType().equals(property.getSchemaType())) { throw ToscaGetFunctionExceptionSupplier - .propertySchemaDiverge(toscaGetFunction.getFunctionType(), referredProperty.getSchemaType(), property.getSchemaType()).get(); + .propertySchemaDiverge(toscaGetFunction.getType(), referredProperty.getSchemaType(), property.getSchemaType()).get(); } } diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/GroupBusinessLogicNew.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/GroupBusinessLogicNew.java index 7c01a35a32..e810999504 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/GroupBusinessLogicNew.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/GroupBusinessLogicNew.java @@ -140,8 +140,8 @@ public class GroupBusinessLogicNew { if (!isOnlyGroupPropertyValueChanged(gp, originalProperties.get(updatedPropertyName))) { throw new ByActionStatusComponentException(ActionStatus.INVALID_PROPERTY, updatedPropertyName); } - if (gp.hasGetFunction()) { - gp.setValue(gp.getToscaGetFunction().generatePropertyValue()); + if (gp.hasToscaFunction()) { + gp.setValue(gp.getToscaFunction().getValue()); } if (StringUtils.isEmpty(gp.getValue())) { gp.setValue(originalProperties.get(updatedPropertyName).getDefaultValue()); @@ -237,13 +237,13 @@ public class GroupBusinessLogicNew { groupProperty1Duplicate.setValue(null); groupProperty1Duplicate.setSchema(null); groupProperty1Duplicate.setParentUniqueId(null); - groupProperty1Duplicate.setToscaGetFunction(null); + groupProperty1Duplicate.setToscaFunction(null); groupProperty1Duplicate.setToscaGetFunctionType(null); GroupProperty groupProperty2Duplicate = new GroupProperty(groupProperty2); groupProperty2Duplicate.setValue(null); groupProperty2Duplicate.setSchema(null); groupProperty2Duplicate.setParentUniqueId(null); - groupProperty2Duplicate.setToscaGetFunction(null); + groupProperty2Duplicate.setToscaFunction(null); groupProperty2Duplicate.setToscaGetFunctionType(null); return StringUtils.equals(groupProperty1Duplicate.getValueUniqueUid(), groupProperty2Duplicate.getValueUniqueUid()) && groupProperty1Duplicate .equals(groupProperty2Duplicate); diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/exceptions/ToscaFunctionExceptionSupplier.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/exceptions/ToscaFunctionExceptionSupplier.java new file mode 100644 index 0000000000..2ba72ab80b --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/exceptions/ToscaFunctionExceptionSupplier.java @@ -0,0 +1,36 @@ +/* + * - + * ============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.components.impl.exceptions; + +import java.util.function.Supplier; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import org.openecomp.sdc.be.dao.api.ActionStatus; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class ToscaFunctionExceptionSupplier { + + public static Supplier<ByActionStatusComponentException> missingFunctionType() { + return () -> new ByActionStatusComponentException(ActionStatus.TOSCA_FUNCTION_MISSING_ATTRIBUTE, "type"); + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/exceptions/ToscaGetFunctionExceptionSupplier.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/exceptions/ToscaGetFunctionExceptionSupplier.java index 44d6f50740..7adc93765a 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/exceptions/ToscaGetFunctionExceptionSupplier.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/exceptions/ToscaGetFunctionExceptionSupplier.java @@ -26,7 +26,7 @@ import java.util.function.Supplier; import lombok.AccessLevel; import lombok.NoArgsConstructor; import org.openecomp.sdc.be.dao.api.ActionStatus; -import org.openecomp.sdc.be.datatypes.elements.ToscaGetFunctionDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.ToscaFunctionType; import org.openecomp.sdc.be.datatypes.enums.PropertySource; import org.openecomp.sdc.be.datatypes.tosca.ToscaGetFunctionType; @@ -38,6 +38,7 @@ public class ToscaGetFunctionExceptionSupplier { final String errorMsg = String.format("%s on %s", toscaGetFunctionType.getFunctionName(), propertySource.getName()); return () -> new ByActionStatusComponentException(ActionStatus.NOT_SUPPORTED, errorMsg); } + public static Supplier<ByActionStatusComponentException> propertyNotFoundOnTarget(final String propertyName, final PropertySource propertySource, final ToscaGetFunctionType functionType) { @@ -106,21 +107,21 @@ public class ToscaGetFunctionExceptionSupplier { return () -> new ByActionStatusComponentException(ActionStatus.NOT_SUPPORTED, "Tosca function " + functionType.getFunctionName()); } - public static Supplier<ByActionStatusComponentException> propertyTypeDiverge(final ToscaGetFunctionType functionType, + public static Supplier<ByActionStatusComponentException> propertyTypeDiverge(final ToscaFunctionType functionType, final String referredPropertyType, final String propertyType) { return () -> new ByActionStatusComponentException( ActionStatus.TOSCA_GET_FUNCTION_TYPE_DIVERGE, - functionType.getFunctionName(), referredPropertyType, propertyType + functionType.getName(), referredPropertyType, propertyType ); } - public static Supplier<ByActionStatusComponentException> propertySchemaDiverge(final ToscaGetFunctionType functionType, + public static Supplier<ByActionStatusComponentException> propertySchemaDiverge(final ToscaFunctionType functionType, final String referredPropertySchemaType, final String propertySchemaType) { return () -> new ByActionStatusComponentException( ActionStatus.TOSCA_GET_FUNCTION_SCHEMA_DIVERGE, - functionType.getFunctionName(), referredPropertySchemaType, propertySchemaType + functionType.getName(), referredPropertySchemaType, propertySchemaType ); } diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/impl/ComponentsUtils.java b/catalog-be/src/main/java/org/openecomp/sdc/be/impl/ComponentsUtils.java index c1f45fe7ad..7d58687bfd 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/impl/ComponentsUtils.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/impl/ComponentsUtils.java @@ -83,6 +83,8 @@ import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus; import org.openecomp.sdc.be.datamodel.utils.ConstraintConvertor; import org.openecomp.sdc.be.datatypes.elements.AdditionalInfoParameterInfo; import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterPropertyDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.ToscaFunction; +import org.openecomp.sdc.be.datatypes.elements.ToscaFunctionJsonDeserializer; import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields; import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; @@ -228,6 +230,7 @@ public class ComponentsUtils { log.trace("convert json to object. json=\n{}", data); SimpleModule module = new SimpleModule("customDeserializationModule"); module.addDeserializer(PropertyConstraint.class, new PropertyConstraintJacksonDeserializer()); + module.addDeserializer(ToscaFunction.class, new ToscaFunctionJsonDeserializer()); mapper.registerModule(module); component = mapper.readValue(data, clazz); if (component == null) { 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 cd916d0d1e..96c6762d74 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 @@ -73,6 +73,7 @@ import org.mockito.MockitoAnnotations; import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException; import org.openecomp.sdc.be.components.impl.exceptions.ByResponseFormatComponentException; import org.openecomp.sdc.be.components.impl.exceptions.ComponentException; +import org.openecomp.sdc.be.components.impl.exceptions.ToscaFunctionExceptionSupplier; import org.openecomp.sdc.be.components.impl.exceptions.ToscaGetFunctionExceptionSupplier; import org.openecomp.sdc.be.components.validation.UserValidations; import org.openecomp.sdc.be.config.ConfigurationManager; @@ -385,7 +386,7 @@ class ComponentInstanceBusinessLogicTest { propertyGetInput.setType("list"); final SchemaDefinition listStringPropertySchema = createSchema(schemaType); propertyGetInput.setSchema(listStringPropertySchema); - propertyGetInput.setToscaGetFunction( + propertyGetInput.setToscaFunction( createGetToscaFunction(inputName, inputId, List.of(propertyGetInput.getName()), PropertySource.SELF, ToscaGetFunctionType.GET_INPUT, containerComponentId, containerComponentName) ); @@ -552,7 +553,7 @@ class ComponentInstanceBusinessLogicTest { componentInstanceProperty.setSchema(schemaDefinition); } if (toscaGetFunction != null) { - componentInstanceProperty.setToscaGetFunction(toscaGetFunction); + componentInstanceProperty.setToscaFunction(toscaGetFunction); } return componentInstanceProperty; @@ -612,7 +613,7 @@ class ComponentInstanceBusinessLogicTest { final ResponseFormat actualResponse = responseFormatEither.right().value(); final ResponseFormat expectedResponse = ToscaGetFunctionExceptionSupplier - .propertySchemaDiverge(propertyGetInput.getToscaGetFunction().getFunctionType(), inputDefinition.getSchemaType(), + .propertySchemaDiverge(propertyGetInput.getToscaFunction().getType(), inputDefinition.getSchemaType(), propertyGetInput.getSchemaType()) .get().getResponseFormat(); assertEquals(expectedResponse.getFormattedMessage(), actualResponse.getFormattedMessage()); @@ -672,7 +673,7 @@ class ComponentInstanceBusinessLogicTest { final ResponseFormat actualResponse = responseFormatEither.right().value(); final ResponseFormat expectedResponse = ToscaGetFunctionExceptionSupplier - .propertyTypeDiverge(propertyGetInput.getToscaGetFunction().getFunctionType(), inputDefinition.getType(), propertyGetInput.getType()) + .propertyTypeDiverge(propertyGetInput.getToscaFunction().getType(), inputDefinition.getType(), propertyGetInput.getType()) .get().getResponseFormat(); assertEquals(expectedResponse.getFormattedMessage(), actualResponse.getFormattedMessage()); assertEquals(expectedResponse.getStatus(), actualResponse.getStatus()); @@ -689,7 +690,7 @@ class ComponentInstanceBusinessLogicTest { final List<ComponentInstanceProperty> properties = new ArrayList<>(); final ComponentInstanceProperty propertyGetInput = new ComponentInstanceProperty(); propertyGetInput.setName("anyName"); - propertyGetInput.setToscaGetFunction(toscaGetFunction); + propertyGetInput.setToscaFunction(toscaGetFunction); properties.add(propertyGetInput); final Component component = new Service(); @@ -2659,8 +2660,8 @@ class ComponentInstanceBusinessLogicTest { private static Stream<Arguments> getToscaFunctionForValidation() { final var toscaGetFunction1 = new ToscaGetFunctionDataDefinition(); - final ResponseFormat expectedResponse1 = ToscaGetFunctionExceptionSupplier - .targetFunctionTypeNotFound().get().getResponseFormat(); + final ResponseFormat expectedResponse1 = ToscaFunctionExceptionSupplier + .missingFunctionType().get().getResponseFormat(); final var toscaGetFunction2 = new ToscaGetFunctionDataDefinition(); toscaGetFunction2.setFunctionType(ToscaGetFunctionType.GET_INPUT); diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/GroupsOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/GroupsOperation.java index d20d2afea0..d346d9364a 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/GroupsOperation.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/GroupsOperation.java @@ -313,8 +313,7 @@ public class GroupsOperation extends BaseOperation { Optional<PropertyDataDefinition> currentProp = properties.stream().filter(p -> p.getName().equals(np.getName())).findAny(); if (currentProp.isPresent()) { currentProp.get().setValue(np.getValue()); - currentProp.get().setToscaGetFunction(np.getToscaGetFunction()); - currentProp.get().setToscaGetFunctionType(np.getToscaGetFunctionType()); + currentProp.get().setToscaFunction(np.getToscaFunction()); } }); updateVersion(promoteMinorVersion, group); diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/GroupsOperationTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/GroupsOperationTest.java index ab4e991b7f..bb45b9b7e1 100644 --- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/GroupsOperationTest.java +++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/GroupsOperationTest.java @@ -22,6 +22,8 @@ package org.openecomp.sdc.be.model.jsonjanusgraph.operations; import static java.util.Arrays.asList; import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; import fj.data.Either; import java.util.List; @@ -33,9 +35,11 @@ import org.openecomp.sdc.be.dao.config.JanusGraphSpringConfig; import org.openecomp.sdc.be.dao.janusgraph.HealingJanusGraphDao; import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus; import org.openecomp.sdc.be.dao.jsongraph.GraphVertex; +import org.openecomp.sdc.be.datatypes.enums.PromoteVersionEnum; import org.openecomp.sdc.be.model.Component; import org.openecomp.sdc.be.model.ComponentParametersView; import org.openecomp.sdc.be.model.GroupDefinition; +import org.openecomp.sdc.be.model.GroupProperty; import org.openecomp.sdc.be.model.ModelTestBase; import org.openecomp.sdc.be.model.Resource; import org.openecomp.sdc.be.model.config.ModelOperationsSpringConfig; @@ -75,7 +79,7 @@ public class GroupsOperationTest extends ModelTestBase { } @Test - public void addGroups_whenContainerHasNoGroups_associateContainerWithGroup() { + void addGroups_whenContainerHasNoGroups_associateContainerWithGroup() { GroupDefinition g1 = createGroupDefinition("g1"); GroupDefinition g2 = createGroupDefinition("g2"); Either<List<GroupDefinition>, StorageOperationStatus> createGroups = groupsOperation.addGroups(container, asList(g1, g2)); @@ -90,7 +94,7 @@ public class GroupsOperationTest extends ModelTestBase { } @Test - public void addGroups_whenContainerHasGroups_addTheGivenGroupsToTheGroupsList() { + void addGroups_whenContainerHasGroups_addTheGivenGroupsToTheGroupsList() { GroupDefinition g1 = createGroupDefinition("g1"); GroupDefinition g2 = createGroupDefinition("g2"); groupsOperation.addGroups(container, asList(g1, g2)).left().value(); @@ -109,6 +113,27 @@ public class GroupsOperationTest extends ModelTestBase { } + @Test + void updateGroupPropertiesOnComponent() { + final GroupDefinition group = createGroupDefinition("groupId"); + final GroupProperty groupProperty1 = new GroupProperty(); + groupProperty1.setName("property1"); + + final GroupProperty groupProperty2 = new GroupProperty(); + groupProperty1.setName("property2"); + group.setProperties(List.of(groupProperty1, groupProperty2)); + + final GroupProperty newProperty1 = new GroupProperty(); + newProperty1.setName("property2"); + final List<GroupProperty> newGroupProperties = List.of(newProperty1); + + final Either<List<GroupProperty>, StorageOperationStatus> resultEither = + groupsOperation.updateGroupPropertiesOnComponent(CONTAINER_ID, group, newGroupProperties, PromoteVersionEnum.MINOR); + + assertTrue(resultEither.isLeft()); + assertEquals(newGroupProperties, resultEither.left().value()); + } + private GroupDefinition createGroupDefinition(String id) { GroupDefinition groupDefinition = new GroupDefinition(); groupDefinition.setUniqueId(id); diff --git a/catalog-ui/src/app/models/properties-inputs/property-be-model.ts b/catalog-ui/src/app/models/properties-inputs/property-be-model.ts index a5bf3cb7a0..ae7141353b 100644 --- a/catalog-ui/src/app/models/properties-inputs/property-be-model.ts +++ b/catalog-ui/src/app/models/properties-inputs/property-be-model.ts @@ -23,9 +23,10 @@ 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"; -import {ToscaGetFunctionDto} from '../tosca-get-function-dto'; -import {PropertySource} from '../property-source'; +import {ToscaFunction} from "../tosca-function"; +import {ToscaGetFunction} from "../tosca-get-function"; +import {ToscaGetFunctionTypeConverter} from "../tosca-get-function-type-converter"; +import {ToscaGetFunctionDto} from "../tosca-get-function-dto"; export enum DerivedPropertyType { SIMPLE, @@ -68,9 +69,11 @@ export class PropertyBEModel { inputPath: string; toscaPresentation: ToscaPresentationData; metadata: Metadata; - //deprecated - toscaGetFunctionType: ToscaGetFunctionType; + /** + * @deprecated Use toscaFunction instead + */ toscaGetFunction: ToscaGetFunctionDto; + toscaFunction: ToscaFunction; constructor(property?: PropertyBEModel) { if (property) { @@ -96,12 +99,20 @@ export class PropertyBEModel { this.getPolicyValues = property.getPolicyValues; this.inputPath = property.inputPath; this.metadata = property.metadata; - if (property.toscaGetFunction) { - this.toscaGetFunction = property.toscaGetFunction; - } else if (property.toscaGetFunctionType) { - this.toscaGetFunction = new ToscaGetFunctionDto(); - this.toscaGetFunction.functionType = property.toscaGetFunctionType; - this.toscaGetFunction.propertySource = PropertySource.SELF; + if (property.toscaFunction) { + this.toscaFunction = property.toscaFunction; + } else if (property.toscaGetFunction) { + //support for legacy tosca function + const toscaGetFunction1 = new ToscaGetFunction(); + toscaGetFunction1.type = ToscaGetFunctionTypeConverter.convertToToscaFunctionType(property.toscaGetFunction.functionType); + toscaGetFunction1.propertyUniqueId = property.toscaGetFunction.propertyUniqueId; + toscaGetFunction1.propertyName = property.toscaGetFunction.propertyName; + toscaGetFunction1.propertySource = property.toscaGetFunction.propertySource; + toscaGetFunction1.sourceUniqueId = property.toscaGetFunction.sourceUniqueId; + toscaGetFunction1.sourceName = property.toscaGetFunction.sourceName; + toscaGetFunction1.functionType = property.toscaGetFunction.functionType; + toscaGetFunction1.propertyPathFromSource = property.toscaGetFunction.propertyPathFromSource; + this.toscaFunction = toscaGetFunction1; } } @@ -181,7 +192,7 @@ export class PropertyBEModel { * Checks whether the property value is a tosca get function (e.g. get_input, get_property, get_attribute) */ public isToscaGetFunction(): boolean { - return this.toscaGetFunction != null; + return this.toscaFunction != null; } } diff --git a/catalog-ui/src/app/models/tosca-concat-function.ts b/catalog-ui/src/app/models/tosca-concat-function.ts new file mode 100644 index 0000000000..9656d8ddb9 --- /dev/null +++ b/catalog-ui/src/app/models/tosca-concat-function.ts @@ -0,0 +1,38 @@ +/* + * - + * ============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========================================================= + */ + +import {ToscaFunction} from "./tosca-function"; +import {ToscaFunctionType} from "./tosca-function-type.enum"; +import {ToscaFunctionParameter} from "./tosca-function-parameter"; + +export class ToscaConcatFunction implements ToscaFunction, ToscaFunctionParameter { + type = ToscaFunctionType.CONCAT; + value: any; + parameters: Array<ToscaFunctionParameter> = []; + + constructor(toscaConcatFunction?: ToscaConcatFunction) { + if (!toscaConcatFunction) { + return; + } + this.value = toscaConcatFunction.value; + } + +}
\ No newline at end of file diff --git a/catalog-ui/src/app/models/tosca-function-parameter.ts b/catalog-ui/src/app/models/tosca-function-parameter.ts new file mode 100644 index 0000000000..84c4f0b014 --- /dev/null +++ b/catalog-ui/src/app/models/tosca-function-parameter.ts @@ -0,0 +1,27 @@ +/* + * - + * ============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========================================================= + */ + +import {ToscaFunctionType} from "./tosca-function-type.enum"; + +export interface ToscaFunctionParameter { + type: ToscaFunctionType; + value: any; +}
\ No newline at end of file diff --git a/catalog-ui/src/app/models/tosca-function-type.enum.ts b/catalog-ui/src/app/models/tosca-function-type.enum.ts new file mode 100644 index 0000000000..116c8815ab --- /dev/null +++ b/catalog-ui/src/app/models/tosca-function-type.enum.ts @@ -0,0 +1,8 @@ +export enum ToscaFunctionType { + GET_INPUT = 'GET_INPUT', + GET_ATTRIBUTE = 'GET_ATTRIBUTE', + GET_PROPERTY = 'GET_PROPERTY', + CONCAT = 'CONCAT', + YAML = 'YAML', + STRING = 'STRING' +} diff --git a/catalog-ui/src/app/models/tosca-function.ts b/catalog-ui/src/app/models/tosca-function.ts new file mode 100644 index 0000000000..ebb024ee7c --- /dev/null +++ b/catalog-ui/src/app/models/tosca-function.ts @@ -0,0 +1,27 @@ +/* + * - + * ============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========================================================= + */ + +import {ToscaFunctionType} from "./tosca-function-type.enum"; + +export interface ToscaFunction { + type: ToscaFunctionType; + value: any; +}
\ No newline at end of file diff --git a/catalog-ui/src/app/models/tosca-get-function-dto.ts b/catalog-ui/src/app/models/tosca-get-function-dto.ts index b5ddad7b71..b16ae8be9a 100644 --- a/catalog-ui/src/app/models/tosca-get-function-dto.ts +++ b/catalog-ui/src/app/models/tosca-get-function-dto.ts @@ -21,8 +21,10 @@ import {ToscaGetFunctionType} from './tosca-get-function-type'; import {PropertySource} from './property-source'; +import {ToscaFunctionType} from "./tosca-function-type.enum"; export class ToscaGetFunctionDto { + type: ToscaFunctionType; propertyUniqueId: string; propertyName: string; propertySource: PropertySource; @@ -31,46 +33,3 @@ export class ToscaGetFunctionDto { functionType: ToscaGetFunctionType; propertyPathFromSource: Array<string>; } - -export class ToscaGetFunctionDtoBuilder { - toscaGetFunctionDto: ToscaGetFunctionDto = new ToscaGetFunctionDto(); - - withPropertyUniqueId(propertyUniqueId: string): ToscaGetFunctionDtoBuilder { - this.toscaGetFunctionDto.propertyUniqueId = propertyUniqueId; - return this; - } - - withPropertyName(propertyName: string): ToscaGetFunctionDtoBuilder { - this.toscaGetFunctionDto.propertyName = propertyName; - return this; - } - - withPropertySource(propertySource: PropertySource): ToscaGetFunctionDtoBuilder { - this.toscaGetFunctionDto.propertySource = propertySource; - return this; - } - - withSourceUniqueId(sourceUniqueId: string): ToscaGetFunctionDtoBuilder { - this.toscaGetFunctionDto.sourceUniqueId = sourceUniqueId; - return this; - } - - withSourceName(sourceName: string): ToscaGetFunctionDtoBuilder { - this.toscaGetFunctionDto.sourceName = sourceName; - return this; - } - - withFunctionType(functionType: ToscaGetFunctionType): ToscaGetFunctionDtoBuilder { - this.toscaGetFunctionDto.functionType = functionType; - return this; - } - - withPropertyPathFromSource(propertyPathFromSource: Array<string>): ToscaGetFunctionDtoBuilder { - this.toscaGetFunctionDto.propertyPathFromSource = propertyPathFromSource; - return this; - } - - build(): ToscaGetFunctionDto { - return this.toscaGetFunctionDto; - } -} diff --git a/catalog-ui/src/app/models/tosca-get-function-type-converter.ts b/catalog-ui/src/app/models/tosca-get-function-type-converter.ts index 0447c4bce3..ad3385af64 100644 --- a/catalog-ui/src/app/models/tosca-get-function-type-converter.ts +++ b/catalog-ui/src/app/models/tosca-get-function-type-converter.ts @@ -20,28 +20,47 @@ */ import {ToscaGetFunctionType} from './tosca-get-function-type'; +import {ToscaFunctionType} from "./tosca-function-type.enum"; export class ToscaGetFunctionTypeConverter { - static convertFromString(toscaGetFunction: string): ToscaGetFunctionType { - if (!toscaGetFunction) { - return; - } + static convertFromString(toscaGetFunction: string): ToscaGetFunctionType { + if (!toscaGetFunction) { + return; + } - if (ToscaGetFunctionType.GET_INPUT === toscaGetFunction.toUpperCase()) { - return ToscaGetFunctionType.GET_INPUT; - } + if (ToscaGetFunctionType.GET_INPUT === toscaGetFunction.toUpperCase()) { + return ToscaGetFunctionType.GET_INPUT; + } - if (ToscaGetFunctionType.GET_PROPERTY === toscaGetFunction.toUpperCase()) { - return ToscaGetFunctionType.GET_PROPERTY; - } + if (ToscaGetFunctionType.GET_PROPERTY === toscaGetFunction.toUpperCase()) { + return ToscaGetFunctionType.GET_PROPERTY; + } + + if (ToscaGetFunctionType.GET_ATTRIBUTE === toscaGetFunction.toUpperCase()) { + return ToscaGetFunctionType.GET_ATTRIBUTE; + } + + return undefined; - if (ToscaGetFunctionType.GET_ATTRIBUTE === toscaGetFunction.toUpperCase()) { - return ToscaGetFunctionType.GET_ATTRIBUTE; } - return undefined; + /** + * Converts a ToscaGetFunctionType to a ToscaFunctionType + * @param toscaGetFunctionType + */ + static convertToToscaFunctionType(toscaGetFunctionType: ToscaGetFunctionType): ToscaFunctionType { + switch (toscaGetFunctionType) { + case ToscaGetFunctionType.GET_INPUT: + return ToscaFunctionType.GET_INPUT; + case ToscaGetFunctionType.GET_ATTRIBUTE: + return ToscaFunctionType.GET_ATTRIBUTE; + case ToscaGetFunctionType.GET_PROPERTY: + return ToscaFunctionType.GET_PROPERTY; + default: + return undefined; + } - } + } } diff --git a/catalog-ui/src/app/models/tosca-get-function.ts b/catalog-ui/src/app/models/tosca-get-function.ts index 97497fc948..2386338c98 100644 --- a/catalog-ui/src/app/models/tosca-get-function.ts +++ b/catalog-ui/src/app/models/tosca-get-function.ts @@ -21,8 +21,11 @@ import {PropertySource} from "./property-source"; import {ToscaGetFunctionType} from "./tosca-get-function-type"; +import {ToscaFunction} from "./tosca-function"; +import {ToscaFunctionType} from "./tosca-function-type.enum"; -export class ToscaGetFunction { +export class ToscaGetFunction implements ToscaFunction { + type: ToscaFunctionType; propertyUniqueId: string; propertyName: string; propertySource: PropertySource; @@ -30,6 +33,7 @@ export class ToscaGetFunction { sourceName: string; functionType: ToscaGetFunctionType; propertyPathFromSource: Array<string>; + value: any constructor(toscaGetFunction?: ToscaGetFunction) { if (!toscaGetFunction) { @@ -45,4 +49,5 @@ export class ToscaGetFunction { this.propertyPathFromSource = [...toscaGetFunction.propertyPathFromSource]; } } + }
\ No newline at end of file diff --git a/catalog-ui/src/app/models/tosca-string-parameter.ts b/catalog-ui/src/app/models/tosca-string-parameter.ts new file mode 100644 index 0000000000..0f7423582c --- /dev/null +++ b/catalog-ui/src/app/models/tosca-string-parameter.ts @@ -0,0 +1,28 @@ +/* + * - + * ============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========================================================= + */ + +import {ToscaFunctionParameter} from "./tosca-function-parameter"; +import {ToscaFunctionType} from "./tosca-function-type.enum"; + +export class ToscaStringParameter implements ToscaFunctionParameter { + type: ToscaFunctionType = ToscaFunctionType.STRING; + value: string; +}
\ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.page.component.ts b/catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.page.component.ts index 9f721d5cdd..2ae5ce8c09 100644 --- a/catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.page.component.ts +++ b/catalog-ui/src/app/ng2/pages/properties-assignment/properties-assignment.page.component.ts @@ -61,13 +61,12 @@ import {UnsavedChangesComponent} from "app/ng2/components/ui/forms/unsaved-chang import {PropertyCreatorComponent} from "./property-creator/property-creator.component"; import {ModalService} from "../../services/modal.service"; import {DeclareListComponent} from "./declare-list/declare-list.component"; -import {ToscaFunctionComponent} from "./tosca-function/tosca-function.component"; +import {ToscaFunctionComponent, ToscaFunctionValidationEvent} from "./tosca-function/tosca-function.component"; import {CapabilitiesGroup, Capability} from "../../../models/capability"; import {ToscaPresentationData} from "../../../models/tosca-presentation"; import {Observable} from "rxjs"; import {TranslateService} from "../../shared/translator/translate.service"; -import {ToscaGetFunctionDtoBuilder} from '../../../models/tosca-get-function-dto'; -import {ToscaGetFunction} from "../../../models/tosca-get-function"; +import {ToscaFunction} from "../../../models/tosca-function"; const SERVICE_SELF_TITLE = "SELF"; @Component({ @@ -539,36 +538,37 @@ export class PropertiesAssignmentComponent { const modalTitle = this.translateService.translate('TOSCA_FUNCTION_MODAL_TITLE'); const modalButtons = []; let disableSaveButtonFlag = true; + const modal = this.modalService.createCustomModal(new ModalModel( + 'sm', + modalTitle, + null, + modalButtons, + null /* type */ + )); modalButtons.push(new ButtonModel(this.translateService.translate('MODAL_SAVE'), 'blue', () => { - const toscaGetFunction: ToscaGetFunction = modal.instance.dynamicContent.instance.toscaGetFunction; - if (toscaGetFunction.functionType) { - this.updateCheckedInstancePropertyGetFunctionValue(toscaGetFunction); + const toscaGetFunction: ToscaFunction = modal.instance.dynamicContent.instance.toscaFunctionForm.value; + if (toscaGetFunction) { + this.updateCheckedInstancePropertyFunctionValue(toscaGetFunction); } else { this.clearCheckedInstancePropertyValue(); } - modal.instance.close(); + this.modalService.closeCurrentModal(); }, (): boolean => { return disableSaveButtonFlag } )); const checkedInstanceProperty = this.buildCheckedInstanceProperty(); modalButtons.push(new ButtonModel(this.translateService.translate('MODAL_CANCEL'), 'outline grey', () => { - modal.instance.close(); + this.modalService.closeCurrentModal(); })); - const modal = this.modalService.createCustomModal(new ModalModel( - 'sm', - modalTitle, - null, - modalButtons, - null /* type */ - )); + this.modalService.addDynamicContentToModalAndBindInputs(modal, ToscaFunctionComponent, { 'property': checkedInstanceProperty, 'componentInstanceMap': this.componentInstanceMap }); - modal.instance.dynamicContent.instance.onValidityChange.subscribe(isValid => { - disableSaveButtonFlag = !isValid; + modal.instance.dynamicContent.instance.onValidityChange.subscribe((validationEvent: ToscaFunctionValidationEvent) => { + disableSaveButtonFlag = !validationEvent.isValid; }); modal.instance.open(); } @@ -577,23 +577,13 @@ export class PropertiesAssignmentComponent { const checkedInstanceProperty: PropertyBEModel = this.buildCheckedInstanceProperty(); checkedInstanceProperty.getInputValues = null; checkedInstanceProperty.value = null; - checkedInstanceProperty.toscaGetFunction = null; + checkedInstanceProperty.toscaFunction = null; this.updateInstanceProperty(checkedInstanceProperty); } - private updateCheckedInstancePropertyGetFunctionValue(toscaGetFunction: ToscaGetFunction) { - const toscaGetFunctionBuilder: ToscaGetFunctionDtoBuilder = - new ToscaGetFunctionDtoBuilder() - .withPropertyUniqueId(toscaGetFunction.propertyUniqueId) - .withFunctionType(toscaGetFunction.functionType) - .withPropertySource(toscaGetFunction.propertySource) - .withPropertyName(toscaGetFunction.propertyName) - .withSourceName(toscaGetFunction.sourceName) - .withSourceUniqueId(toscaGetFunction.sourceUniqueId) - .withPropertyPathFromSource(toscaGetFunction.propertyPathFromSource); - + private updateCheckedInstancePropertyFunctionValue(toscaFunction: ToscaFunction) { const checkedProperty: PropertyBEModel = this.buildCheckedInstanceProperty(); - checkedProperty.toscaGetFunction = toscaGetFunctionBuilder.build(); + checkedProperty.toscaFunction = toscaFunction; this.updateInstanceProperty(checkedProperty); } diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-concat-function/tosca-concat-function.component.html b/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-concat-function/tosca-concat-function.component.html new file mode 100644 index 0000000000..6320058d9d --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-concat-function/tosca-concat-function.component.html @@ -0,0 +1,48 @@ +<!-- + ~ - + ~ ============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========================================================= + --> + +<div class="component-container"> + <ng-container [formGroup]="formGroup"> + <div formArrayName="concatParameterList"> + <div *ngFor="let parameter of parameters; let idx = index"> + <div *ngIf="idx > 0" class="text-center"><span class="concat-plus-icon"></span></div> + <div class="parameter-card"> + <div class="card-content"> + <ng-container *ngIf="parameter.type === STRING_FUNCTION_TYPE"> + <input type="text" [formControlName]="idx" [value]="parameter.value"/><br/> + </ng-container> + <ng-container *ngIf="parameter.type !== STRING_FUNCTION_TYPE"> + <tosca-function [property]="propertyInputList[idx]" [componentInstanceMap]="componentInstanceMap" [allowClear]="false" + (onValidityChange)="onFunctionValidityChange($event, idx)"> + </tosca-function> + </ng-container> + <div class="buttons-container"> + <span class="delete-icon" (click)="removeParameter(idx)"></span> + </div> + </div> + </div> + </div> + </div> + </ng-container> + <div class="buttons-container"> + <a class="add-link" (click)="addStringParameter()">String Value</a> <a class="add-link" (click)="addFunction()">String Value Expression</a> + </div> +</div> diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-concat-function/tosca-concat-function.component.less b/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-concat-function/tosca-concat-function.component.less new file mode 100644 index 0000000000..b9c59831ad --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-concat-function/tosca-concat-function.component.less @@ -0,0 +1,98 @@ +/* + * - + * ============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========================================================= + */ + +@import "../../../../../../assets/styles/mixins.less"; +@import "../../../../../../assets/styles/sprite.less"; + +.component-container { + max-height: 500px; + overflow: scroll; + padding: 0 5px; + &::-webkit-scrollbar-track { + border: 0; + } +} + +.buttons-container { + display: flex; + flex-direction: row; + justify-content: flex-end; + gap: 10px; + margin-bottom: 10px; + + .add-link { + .f-color.a(); + .f-type._14_m(); + cursor: pointer; + + &:before { + .sprite-new(); + .plus-icon(); + margin-right: 5px; + content: ""; + } + + &:hover { + .f-color.b(); + &:before { + .sprite-new(); + .plus-icon-hover(); + } + } + } + + .delete-icon { + .sprite-new(); + .delete-btn(); + cursor: pointer; + } +} + +.parameter-card { + border: 2px solid @main_color_o; + box-shadow: 0 0 0 0 rgba(0,0,0,0.2); + //padding: 10px; + border-radius: 2px; + transition: 0.3s; + margin-bottom: 5px; + &:hover { + box-shadow: 0 1px 8px 2px rgba(0,0,0,0.2); + } + + .card-content { + padding: 5px 10px; + } + + .text-center { + text-align: center; + } + + input { + border: solid 1px @main_color_o; + } +} + +.concat-plus-icon { + .sprite-new(); + background-position: -216px -1388px; + width: 14px; + height: 14px; +}
\ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-concat-function/tosca-concat-function.component.spec.ts b/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-concat-function/tosca-concat-function.component.spec.ts new file mode 100644 index 0000000000..5c9af47361 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-concat-function/tosca-concat-function.component.spec.ts @@ -0,0 +1,57 @@ +/* + * - + * ============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========================================================= + */ + +import {async, ComponentFixture, TestBed} from '@angular/core/testing'; + +import {ToscaConcatFunctionComponent} from './tosca-concat-function.component'; +import {FormsModule, ReactiveFormsModule} from "@angular/forms"; +import {ToscaFunctionComponent} from "../tosca-function.component"; +import {TranslateModule} from "../../../../shared/translator/translate.module"; +import {ToscaGetFunctionComponent} from "../tosca-get-function/tosca-get-function.component"; +import {UiElementsModule} from "../../../../components/ui/ui-elements.module"; + +describe('ToscaConcatFunctionComponent', () => { + let component: ToscaConcatFunctionComponent; + let fixture: ComponentFixture<ToscaConcatFunctionComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ToscaConcatFunctionComponent, ToscaFunctionComponent, ToscaGetFunctionComponent], + imports: [ + FormsModule, + ReactiveFormsModule, + TranslateModule, + UiElementsModule + ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ToscaConcatFunctionComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-concat-function/tosca-concat-function.component.ts b/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-concat-function/tosca-concat-function.component.ts new file mode 100644 index 0000000000..d808c284a8 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-concat-function/tosca-concat-function.component.ts @@ -0,0 +1,140 @@ +import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core'; +import {FormArray, FormControl, FormGroup, Validators} from "@angular/forms"; +import {ToscaConcatFunction} from "../../../../../models/tosca-concat-function"; +import {ToscaFunctionParameter} from "../../../../../models/tosca-function-parameter"; +import {ToscaStringParameter} from "../../../../../models/tosca-string-parameter"; +import {ToscaFunctionType} from "../../../../../models/tosca-function-type.enum"; +import {PropertyBEModel} from "../../../../../models/properties-inputs/property-be-model"; +import {PROPERTY_TYPES} from "../../../../../utils/constants"; +import {InstanceFeDetails} from "../../../../../models/instance-fe-details"; +import {ToscaFunctionValidationEvent} from "../tosca-function.component"; + +@Component({ + selector: 'app-tosca-concat-function', + templateUrl: './tosca-concat-function.component.html', + styleUrls: ['./tosca-concat-function.component.less'] +}) +export class ToscaConcatFunctionComponent implements OnInit { + + @Input() toscaConcatFunction: ToscaConcatFunction; + @Input() componentInstanceMap: Map<string, InstanceFeDetails> = new Map<string, InstanceFeDetails>(); + @Output() onValidFunction: EventEmitter<ToscaConcatFunction> = new EventEmitter<ToscaConcatFunction>(); + @Output() onValidityChange: EventEmitter<ToscaConcatFunctionValidationEvent> = new EventEmitter<ToscaConcatFunctionValidationEvent>(); + + concatParameterFormArray: FormArray = new FormArray([], Validators.minLength(2)); + formGroup: FormGroup = new FormGroup( + { + 'concatParameterList': this.concatParameterFormArray + } + ); + + parameters: ToscaFunctionParameter[] = []; + propertyInputList: Array<PropertyBEModel> = []; + + stringProperty: PropertyBEModel + + STRING_FUNCTION_TYPE = ToscaFunctionType.STRING + + constructor() { + this.stringProperty = new PropertyBEModel(); + this.stringProperty.type = PROPERTY_TYPES.STRING + } + + ngOnInit() { + this.initForm(); + } + + private initForm() { + this.formGroup.valueChanges.subscribe(() => { + this.onValidityChange.emit({ + isValid: this.formGroup.valid, + toscaConcatFunction: this.formGroup.valid ? this.buildConcatFunctionFromForm() : undefined + }) + if (this.formGroup.valid) { + this.onValidFunction.emit(this.buildConcatFunctionFromForm()); + } + }); + if (!this.toscaConcatFunction) { + return; + } + + if (this.toscaConcatFunction.parameters) { + this.parameters = Array.from(this.toscaConcatFunction.parameters); + for (const parameter of this.parameters) { + if (parameter.type !== PROPERTY_TYPES.STRING) { + this.propertyInputList.push(this.createStringProperty(parameter)); + this.concatParameterFormArray.push( + new FormControl(parameter, [Validators.required, Validators.minLength(1)]) + ); + } else { + this.propertyInputList.push(undefined); + this.concatParameterFormArray.push( + new FormControl(parameter.value, [Validators.required, Validators.minLength(1)]) + ); + } + } + } + } + + private buildConcatFunctionFromForm(): ToscaConcatFunction { + const toscaConcatFunction1 = new ToscaConcatFunction(); + this.concatParameterFormArray.controls.forEach(control => { + const value = control.value; + if (typeof value === 'string') { + const stringParameter = new ToscaStringParameter(); + stringParameter.value = value; + toscaConcatFunction1.parameters.push(stringParameter); + } else { + toscaConcatFunction1.parameters.push(control.value); + } + }); + + return toscaConcatFunction1; + } + + addFunction() { + this.propertyInputList.push(this.createStringProperty()); + this.parameters.push({} as ToscaFunctionParameter); + this.concatParameterFormArray.push( + new FormControl(undefined, [Validators.required, Validators.minLength(1)]) + ); + } + + addStringParameter() { + this.parameters.push({ + type: ToscaFunctionType.STRING, + value: '' + }); + this.propertyInputList.push(undefined); + this.concatParameterFormArray.push( + new FormControl('', [Validators.required, Validators.minLength(1)]) + ); + } + + removeParameter(position) { + this.propertyInputList.splice(position, 1); + this.parameters.splice(position, 1); + this.concatParameterFormArray.removeAt(position); + } + + createStringProperty(toscaFunctionParameter?: ToscaFunctionParameter) { + const property = new PropertyBEModel(); + property.type = PROPERTY_TYPES.STRING; + property.toscaFunction = toscaFunctionParameter ? toscaFunctionParameter : undefined; + property.value = toscaFunctionParameter ? toscaFunctionParameter.value : undefined; + return property; + } + + onFunctionValidityChange(event: ToscaFunctionValidationEvent, index: number) { + if (event.isValid && event.toscaFunction) { + this.concatParameterFormArray.controls[index].setValue(event.toscaFunction) + } else { + this.concatParameterFormArray.controls[index].setValue(undefined); + } + } +} + +export interface ToscaConcatFunctionValidationEvent { + isValid: boolean, + toscaConcatFunction: ToscaConcatFunction, +} 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 b6b313d93c..e98f688eef 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 @@ -18,32 +18,27 @@ --> <div class="tosca-function"> - <loader [display]="isLoading" [loaderDelay]="500" [relative]="true" [size]="'large'"></loader> - <form class="w-sdc-form"> + <div class="w-sdc-form" [formGroup]="formGroup"> <div class="i-sdc-form-item"> <label class="i-sdc-form-label">{{'TOSCA_FUNCTION_LABEL' | translate}}</label> - <select [(ngModel)]="toscaGetFunction.functionType" (change)="onToscaFunctionChange()" name="toscaFunctionType"> + <select formControlName="toscaFunctionType"> <option *ngFor="let toscaFunction of toscaFunctions" [ngValue]="toscaFunction">{{toscaFunction | lowercase}}</option> </select> </div> - <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 *ngIf="isConcatSelected()"> + <app-tosca-concat-function [toscaConcatFunction]="toscaFunction" [componentInstanceMap]="componentInstanceMap" + (onValidityChange)="onConcatFunctionValidityChange($event)"></app-tosca-concat-function> </div> - <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> - </select> + <div *ngIf="isGetFunctionSelected()"> + <app-tosca-get-function [property]="property" [toscaGetFunction]="toscaFunction" + [componentInstanceMap]="componentInstanceMap" + [functionType]="toscaFunctionTypeForm.value" + (onValidityChange)="onGetFunctionValidityChange($event)"></app-tosca-get-function> </div> - <div *ngIf="dropDownErrorMsg">{{dropDownErrorMsg}}</div> <div *ngIf="showClearButton()" class="button-container"> <button (click)="onClearValues()" class="tlv-btn red ng-star-inserted">{{'TOSCA_FUNCTION_CLEAR_VALUE_BUTTON' | translate}}</button> </div> - </form> + </div> <loader [display]="isLoading" [size]="'medium'" [relative]="true"></loader> </div> 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 b71a61dc01..076e1182ad 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,20 +18,18 @@ */ import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core'; -import {AttributeModel, ComponentMetadata, DataTypeModel, PropertyBEModel, PropertyModel} from 'app/models'; +import {ComponentMetadata, PropertyBEModel} from 'app/models'; import {TopologyTemplateService} from "../../../services/component-services/topology-template.service"; import {WorkspaceService} from "../../workspace/workspace.service"; -import {PropertiesService} from "../../../services/properties.service"; -import {PROPERTY_DATA, PROPERTY_TYPES} from "../../../../utils/constants"; -import {DataTypeService} from "../../../services/data-type.service"; import {ToscaGetFunctionType} from "../../../../models/tosca-get-function-type"; -import {TranslateService} from "../../../shared/translator/translate.service"; -import {ComponentGenericResponse} from '../../../services/responses/component-generic-response'; -import {Observable} from 'rxjs/Observable'; -import {PropertySource} from "../../../../models/property-source"; import {InstanceFeDetails} from "../../../../models/instance-fe-details"; import {ToscaGetFunction} from "../../../../models/tosca-get-function"; -import {AbstractControl, FormControl, FormGroup, ValidationErrors, ValidatorFn} from "@angular/forms"; +import {FormControl, FormGroup, Validators} from "@angular/forms"; +import {ToscaFunctionType} from "../../../../models/tosca-function-type.enum"; +import {ToscaGetFunctionValidationEvent} from "./tosca-get-function/tosca-get-function.component"; +import {ToscaFunction} from "../../../../models/tosca-function"; +import {ToscaConcatFunctionValidationEvent} from "./tosca-concat-function/tosca-concat-function.component"; +import {PROPERTY_TYPES} from "../../../../utils/constants"; @Component({ selector: 'tosca-function', @@ -44,418 +42,124 @@ export class ToscaFunctionComponent implements OnInit { @Input() componentInstanceMap: Map<string, InstanceFeDetails> = new Map<string, InstanceFeDetails>(); @Input() allowClear: boolean = true; @Output() onValidFunction: EventEmitter<ToscaGetFunction> = new EventEmitter<ToscaGetFunction>(); - @Output() onValidityChange: EventEmitter<boolean> = new EventEmitter<boolean>(); + @Output() onValidityChange: EventEmitter<ToscaFunctionValidationEvent> = new EventEmitter<ToscaFunctionValidationEvent>(); - toscaGetFunctionValidator: ValidatorFn = (control: AbstractControl): ValidationErrors | null => { - const toscaGetFunction: ToscaGetFunction = control.value; - const hasAnyValue = Object.keys(toscaGetFunction).find(key => toscaGetFunction[key]); - if (!hasAnyValue) { - return null; - } - const errors: ValidationErrors = {}; - if (!toscaGetFunction.sourceName) { - errors.sourceName = { required: true }; - } - if (!toscaGetFunction.functionType) { - errors.functionType = { required: true }; - } - if (!toscaGetFunction.sourceUniqueId) { - errors.sourceUniqueId = { required: true }; - } - if (!toscaGetFunction.sourceName) { - errors.sourceName = { required: true }; - } - if (!toscaGetFunction.propertyPathFromSource) { - errors.propertyPathFromSource = { required: true }; - } - if (!toscaGetFunction.propertyName) { - errors.propertyName = { required: true }; - } - if (!toscaGetFunction.propertySource) { - errors.propertySource = { required: true }; - } - return errors ? errors : null; - }; - - toscaGetFunctionForm: FormControl = new FormControl(new ToscaGetFunction(undefined), [this.toscaGetFunctionValidator]); + toscaFunctionForm: FormControl = new FormControl(undefined, [Validators.required]); + toscaFunctionTypeForm: FormControl = new FormControl(undefined, Validators.required); formGroup: FormGroup = new FormGroup({ - 'toscaGetFunction': this.toscaGetFunctionForm + 'toscaFunction': this.toscaFunctionForm, + 'toscaFunctionType': this.toscaFunctionTypeForm, }); - selectedProperty: PropertyDropdownValue; isLoading: boolean = false; - propertyDropdownList: Array<PropertyDropdownValue> = []; + toscaFunction: ToscaFunction; toscaFunctions: Array<string> = []; - propertySourceList: Array<string> = []; - instanceNameAndIdMap: Map<string, string> = new Map<string, string>(); - dropdownValuesLabel: string; - dropDownErrorMsg: string; - propertySource: string - toscaGetFunction: ToscaGetFunction = new ToscaGetFunction(undefined); + private isInitialized: boolean = false; private componentMetadata: ComponentMetadata; constructor(private topologyTemplateService: TopologyTemplateService, - private workspaceService: WorkspaceService, - private propertiesService: PropertiesService, - private dataTypeService: DataTypeService, - private translateService: TranslateService) { + private workspaceService: WorkspaceService) { } ngOnInit(): void { this.componentMetadata = this.workspaceService.metadata; + this.toscaFunction = this.property.toscaFunction ? this.property.toscaFunction : undefined; this.loadToscaFunctions(); - this.loadPropertySourceDropdown(); - this.initToscaGetFunction(); - } - - private initToscaGetFunction(): void { - this.toscaGetFunctionForm.valueChanges.subscribe(toscaGetFunction => { - this.onValidityChange.emit(this.toscaGetFunctionForm.valid); - if (this.toscaGetFunctionForm.valid) { - this.onValidFunction.emit(toscaGetFunction); - } - }); - if (!this.property.isToscaGetFunction()) { - return; - } - this.toscaGetFunction = new ToscaGetFunction(this.property.toscaGetFunction); - this.toscaGetFunctionForm.setValue(this.toscaGetFunction); - if (this.isGetPropertySelected() || this.isGetAttributeSelected()) { - if (this.toscaGetFunction.propertySource === PropertySource.SELF) { - this.propertySource = PropertySource.SELF; - } else { - this.propertySource = this.toscaGetFunction.sourceName; - } - } - if (this.toscaGetFunction.propertyName) { - this.loadPropertyDropdown(() => { - this.selectedProperty = this.propertyDropdownList.find(property => property.propertyName === this.toscaGetFunction.propertyName) - }); - } - } - - private loadToscaFunctions(): void { - this.toscaFunctions.push(ToscaGetFunctionType.GET_ATTRIBUTE); - this.toscaFunctions.push(ToscaGetFunctionType.GET_INPUT); - this.toscaFunctions.push(ToscaGetFunctionType.GET_PROPERTY); - } - - private loadPropertySourceDropdown(): void { - this.propertySourceList.push(PropertySource.SELF); - this.componentInstanceMap.forEach((value, key) => { - const instanceName = value.name; - this.instanceNameAndIdMap.set(instanceName, key); - if (instanceName !== PropertySource.SELF) { - this.addToPropertySource(instanceName); - } - }); - } - - private addToPropertySource(source: string): void { - this.propertySourceList.push(source); - this.propertySourceList.sort((a, b) => { - if (a === PropertySource.SELF) { - return -1; - } else if (b === PropertySource.SELF) { - return 1; - } - - return a.localeCompare(b); - }); - } - - onToscaFunctionChange(): void { - this.resetPropertySource(); - this.resetPropertyDropdown(); - if (this.isGetInputSelected()) { - this.setSelfPropertySource(); - this.loadPropertyDropdown(); - } - } - - private loadPropertyDropdown(onComplete?: () => any): void { - this.loadPropertyDropdownLabel(); - this.loadPropertyDropdownValues(onComplete); - } - - private resetForm(): void { - this.toscaGetFunction = new ToscaGetFunction(); - this.toscaGetFunctionForm.setValue(new ToscaGetFunction()); - this.propertySource = undefined; - this.selectedProperty = undefined; - } - - private resetPropertySource(): void { - this.toscaGetFunction.propertyUniqueId = undefined; - this.toscaGetFunction.propertyName = undefined; - this.toscaGetFunction.propertySource = undefined; - this.toscaGetFunction.sourceUniqueId = undefined; - this.toscaGetFunction.sourceName = undefined; - this.toscaGetFunction.propertyPathFromSource = undefined; - this.propertySource = undefined; - this.selectedProperty = undefined; - - const toscaGetFunction1 = new ToscaGetFunction(undefined); - toscaGetFunction1.functionType = this.toscaGetFunction.functionType; - this.toscaGetFunctionForm.setValue(toscaGetFunction1); - } - - private loadPropertyDropdownLabel(): void { - if (!this.toscaGetFunction.functionType) { - return; - } - if (this.isGetInputSelected()) { - 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'); - } - } - - private loadPropertyDropdownValues(onComplete?: () => any): void { - if (!this.toscaGetFunction.functionType) { - return; - } - this.resetPropertyDropdown(); - this.fillPropertyDropdownValues(onComplete); - } - - private resetPropertyDropdown(): void { - this.dropDownErrorMsg = undefined; - this.selectedProperty = undefined; - this.propertyDropdownList = []; - } - - private fillPropertyDropdownValues(onComplete?: () => any): void { - this.startLoading(); - const propertiesObservable: Observable<ComponentGenericResponse> = this.getPropertyObservable(); - propertiesObservable.subscribe( (response: ComponentGenericResponse) => { - const properties: Array<PropertyBEModel | AttributeModel> = this.extractProperties(response); - if (!properties || properties.length === 0) { - const msgCode = this.getNotFoundMsgCode(); - this.dropDownErrorMsg = this.translateService.translate(msgCode, {type: this.propertyTypeToString()}); + this.formGroup.valueChanges.subscribe(() => { + if (!this.isInitialized) { return; } - this.addPropertiesToDropdown(properties); - if (this.propertyDropdownList.length == 0) { - 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(); + this.emitValidityChange(); + if (this.formGroup.valid) { + this.onValidFunction.emit(this.toscaFunctionForm.value); } - this.stopLoading(); }); + this.initToscaGetFunction(); + this.emitValidityChange(); + this.isInitialized = true; } - 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}`; - } - return this.property.type; - } - - private extractProperties(componentGenericResponse: ComponentGenericResponse): Array<PropertyBEModel | AttributeModel> { - if (this.isGetInputSelected()) { - return componentGenericResponse.inputs; - } - if (this.isGetPropertySelected()) { - if (this.propertySource === PropertySource.SELF) { - return componentGenericResponse.properties; - } - 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> { - if (this.isGetInputSelected()) { - return this.topologyTemplateService.getComponentInputsValues(this.componentMetadata.componentType, this.componentMetadata.uniqueId); - } - if (this.isGetPropertySelected()) { - if (this.propertySource === PropertySource.SELF) { - return this.topologyTemplateService.findAllComponentProperties(this.componentMetadata.componentType, this.componentMetadata.uniqueId); - } - 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[] { - if (!componentInstanceProperties) { - return []; - } - return componentInstanceProperties.filter(property => - (property.uniqueId !== this.property.uniqueId) || - (property.uniqueId === this.property.uniqueId && property.resourceInstanceUniqueId !== this.property.parentUniqueId) - ); - } - - private addPropertyToDropdown(propertyDropdownValue: PropertyDropdownValue): void { - this.propertyDropdownList.push(propertyDropdownValue); - this.propertyDropdownList.sort((a, b) => a.propertyLabel.localeCompare(b.propertyLabel)); + private validate() { + return (!this.toscaFunctionForm.value && !this.toscaFunctionTypeForm.value) || this.formGroup.valid; } - private addPropertiesToDropdown(properties: Array<PropertyBEModel | AttributeModel>): void { - for (const property of properties) { - if (this.hasSameType(property)) { - this.addPropertyToDropdown({ - propertyName: property.name, - propertyId: property.uniqueId, - propertyLabel: property.name, - propertyPath: [property.name] - }); - } else if (this.isComplexType(property.type)) { - this.fillPropertyDropdownWithMatchingChildProperties(property); - } - } - } - - 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) { + private initToscaGetFunction() { + if (!this.property.isToscaGetFunction()) { return; } - parentPropertyList.push(inputProperty); - dataTypeFound.properties.forEach(dataTypeProperty => { - if (this.hasSameType(dataTypeProperty)) { - this.addPropertyToDropdown({ - propertyName: dataTypeProperty.name, - propertyId: parentPropertyList[0].uniqueId, - propertyLabel: parentPropertyList.map(property => property.name).join('->') + '->' + dataTypeProperty.name, - propertyPath: [...parentPropertyList.map(property => property.name), dataTypeProperty.name] - }); - } else if (this.isComplexType(dataTypeProperty.type)) { - this.fillPropertyDropdownWithMatchingChildProperties(dataTypeProperty, [...parentPropertyList]) - } - }); + this.toscaFunctionForm.setValue(this.property.toscaFunction); + this.toscaFunctionTypeForm.setValue(this.property.toscaFunction.type); } - private hasSameType(property: PropertyBEModel | AttributeModel) { - if (this.typeHasSchema(this.property.type)) { - if (!property.schema || !property.schema.property) { - return false; - } - return property.type === this.property.type && this.property.schema.property.type === property.schema.property.type; + private loadToscaFunctions(): void { + this.toscaFunctions.push(ToscaFunctionType.GET_ATTRIBUTE); + this.toscaFunctions.push(ToscaFunctionType.GET_INPUT); + this.toscaFunctions.push(ToscaFunctionType.GET_PROPERTY); + if (this.property.type === PROPERTY_TYPES.STRING) { + this.toscaFunctions.push(ToscaFunctionType.CONCAT); } + } - return property.type === this.property.type; + private resetForm(): void { + this.formGroup.reset(); + this.toscaFunction = undefined; } private isGetPropertySelected(): boolean { - return this.toscaGetFunction.functionType === ToscaGetFunctionType.GET_PROPERTY; + return this.formGroup.get('toscaFunctionType').value === ToscaGetFunctionType.GET_PROPERTY; } private isGetAttributeSelected(): boolean { - return this.toscaGetFunction.functionType === ToscaGetFunctionType.GET_ATTRIBUTE; + return this.formGroup.get('toscaFunctionType').value === ToscaGetFunctionType.GET_ATTRIBUTE; } private isGetInputSelected(): boolean { - return this.toscaGetFunction.functionType === ToscaGetFunctionType.GET_INPUT; + return this.formGroup.get('toscaFunctionType').value === ToscaGetFunctionType.GET_INPUT; } - private isComplexType(propertyType: string): boolean { - return PROPERTY_DATA.SIMPLE_TYPES.indexOf(propertyType) === -1; + isConcatSelected(): boolean { + return this.formGroup.get('toscaFunctionType').value === ToscaFunctionType.CONCAT; } - private typeHasSchema(propertyType: string): boolean { - return PROPERTY_TYPES.MAP === propertyType || PROPERTY_TYPES.LIST === propertyType; + isGetFunctionSelected(): boolean { + return this.isGetInputSelected() || this.isGetPropertySelected() || this.isGetAttributeSelected(); } - private stopLoading(): void { - this.isLoading = false; + onClearValues() { + this.resetForm(); } - private startLoading(): void { - this.isLoading = true; + showClearButton(): boolean { + return this.allowClear && this.toscaFunctionTypeForm.value; } - showPropertyDropdown(): boolean { - if (this.isGetPropertySelected() || this.isGetAttributeSelected()) { - return this.toscaGetFunction.propertySource && !this.isLoading && !this.dropDownErrorMsg; + onConcatFunctionValidityChange(validationEvent: ToscaConcatFunctionValidationEvent) { + if (validationEvent.isValid) { + this.toscaFunctionForm.setValue(validationEvent.toscaConcatFunction); + } else { + this.toscaFunctionForm.setValue(undefined); } - - return this.toscaGetFunction.functionType && !this.isLoading && !this.dropDownErrorMsg; } - onPropertySourceChange(): void { - if (!this.toscaGetFunction.functionType || !this.propertySource) { - return; - } - this.toscaGetFunction.propertyUniqueId = undefined; - this.toscaGetFunction.propertyName = undefined; - this.toscaGetFunction.propertyPathFromSource = undefined; - if (this.propertySource === PropertySource.SELF) { - this.setSelfPropertySource(); + onGetFunctionValidityChange(validationEvent: ToscaGetFunctionValidationEvent) { + if (validationEvent.isValid) { + this.toscaFunctionForm.setValue(validationEvent.toscaGetFunction); } else { - this.toscaGetFunction.propertySource = PropertySource.INSTANCE; - this.toscaGetFunction.sourceName = this.propertySource; - this.toscaGetFunction.sourceUniqueId = this.instanceNameAndIdMap.get(this.propertySource); + this.toscaFunctionForm.setValue(undefined); } - this.toscaGetFunctionForm.setValue(this.toscaGetFunction); - this.loadPropertyDropdown(); - } - - private setSelfPropertySource(): void { - this.toscaGetFunction.propertySource = PropertySource.SELF; - this.toscaGetFunction.sourceName = this.componentMetadata.name; - this.toscaGetFunction.sourceUniqueId = this.componentMetadata.uniqueId; - this.toscaGetFunctionForm.setValue(this.toscaGetFunction); - } - - onPropertyChange(): void { - this.toscaGetFunction.propertyUniqueId = this.selectedProperty.propertyId; - this.toscaGetFunction.propertyName = this.selectedProperty.propertyName; - this.toscaGetFunction.propertyPathFromSource = this.selectedProperty.propertyPath; - this.toscaGetFunctionForm.setValue(this.toscaGetFunction); - } - - onClearValues() { - this.resetForm(); } - showClearButton(): boolean { - return this.allowClear && this.toscaGetFunction.functionType !== undefined; - } - - showPropertySourceDropdown(): boolean { - return this.isGetPropertySelected() || this.isGetAttributeSelected(); + private emitValidityChange() { + const isValid = this.validate(); + this.onValidityChange.emit({ + isValid: isValid, + toscaFunction: isValid ? this.toscaFunctionForm.value : undefined + }); } } -export interface PropertyDropdownValue { - propertyName: string; - propertyId: string; - propertyLabel: string; - propertyPath: Array<string>; -} +export class ToscaFunctionValidationEvent { + isValid: boolean; + toscaFunction: ToscaFunction; +}
\ No newline at end of file diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-function.module.ts b/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-function.module.ts index efe45c3d27..2db76cf544 100644 --- a/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-function.module.ts +++ b/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-function.module.ts @@ -19,20 +19,25 @@ import { CommonModule } from '@angular/common'; import { NgModule } from '@angular/core'; -import { FormsModule } from '@angular/forms'; +import {FormsModule, ReactiveFormsModule} 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 { ToscaFunctionComponent } from './tosca-function.component'; import { SdcUiComponentsModule } from 'onap-ui-angular'; +import { ToscaGetFunctionComponent } from './tosca-get-function/tosca-get-function.component'; +import { ToscaConcatFunctionComponent } from './tosca-concat-function/tosca-concat-function.component'; @NgModule({ declarations: [ ToscaFunctionComponent, + ToscaGetFunctionComponent, + ToscaConcatFunctionComponent, ], imports: [ CommonModule, FormsModule, + ReactiveFormsModule, FormElementsModule, UiElementsModule, TranslateModule, diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-get-function/tosca-get-function.component.html b/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-get-function/tosca-get-function.component.html new file mode 100644 index 0000000000..6f19d5eff4 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-get-function/tosca-get-function.component.html @@ -0,0 +1,38 @@ +<!-- + ~ ============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="tosca-function"> + <form class="w-sdc-form" [formGroup]="formGroup"> + <div class="i-sdc-form-item" *ngIf="showPropertySourceDropdown()"> + <label class="i-sdc-form-label required">{{'TOSCA_FUNCTION_PROPERTY_SOURCE_LABEL' | translate}}</label> + <select formControlName="propertySource" (change)="onPropertySourceChange()"> + <option *ngFor="let propertySource of propertySourceList" + [ngValue]="propertySource">{{propertySource}}</option> + </select> + </div> + <div *ngIf="showPropertyDropdown()" class="i-sdc-form-item"> + <label class="i-sdc-form-label required">{{dropdownValuesLabel}}</label> + <select formControlName="selectedProperty"> + <option *ngFor="let value of propertyDropdownList" [ngValue]="value">{{value.propertyLabel}}</option> + </select> + </div> + <div *ngIf="dropDownErrorMsg">{{dropDownErrorMsg}}</div> + </form> + <loader [display]="isLoading" [size]="'medium'" [relative]="true"></loader> +</div> diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-get-function/tosca-get-function.component.less b/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-get-function/tosca-get-function.component.less new file mode 100644 index 0000000000..b14edc25e9 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-get-function/tosca-get-function.component.less @@ -0,0 +1,21 @@ +/* + * - + * ============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========================================================= + */ + diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-get-function/tosca-get-function.component.spec.ts b/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-get-function/tosca-get-function.component.spec.ts new file mode 100644 index 0000000000..6c7d986150 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-get-function/tosca-get-function.component.spec.ts @@ -0,0 +1,74 @@ +/* + * - + * ============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========================================================= + */ + +import {async, ComponentFixture, TestBed} from '@angular/core/testing'; +import {ToscaGetFunctionComponent} from './tosca-get-function.component'; +import {FormsModule, ReactiveFormsModule} from "@angular/forms"; +import {TranslateModule} from "../../../../shared/translator/translate.module"; +import {UiElementsModule} from "../../../../components/ui/ui-elements.module"; +import {TopologyTemplateService} from "../../../../services/component-services/topology-template.service"; +import {WorkspaceService} from "../../../workspace/workspace.service"; +import {PropertiesService} from "../../../../services/properties.service"; +import {DataTypeService} from "../../../../services/data-type.service"; +import {TranslateService} from "../../../../shared/translator/translate.service"; +import {ComponentMetadata} from "../../../../../models/component-metadata"; + +describe('ToscaGetFunctionComponent', () => { + let component: ToscaGetFunctionComponent; + let fixture: ComponentFixture<ToscaGetFunctionComponent>; + let topologyTemplateServiceMock: Partial<TopologyTemplateService>; + let workspaceServiceMock: Partial<WorkspaceService> = { + metadata: new ComponentMetadata() + }; + let propertiesServiceMock: Partial<PropertiesService>; + let dataTypeServiceMock: Partial<DataTypeService>; + let translateServiceMock: Partial<TranslateService>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ToscaGetFunctionComponent], + imports: [ + FormsModule, + ReactiveFormsModule, + TranslateModule, + UiElementsModule + ], + providers: [ + {provide: TopologyTemplateService, useValue: topologyTemplateServiceMock}, + {provide: WorkspaceService, useValue: workspaceServiceMock}, + {provide: PropertiesService, useValue: propertiesServiceMock}, + {provide: DataTypeService, useValue: dataTypeServiceMock}, + {provide: TranslateService, useValue: translateServiceMock} + ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ToscaGetFunctionComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-get-function/tosca-get-function.component.ts b/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-get-function/tosca-get-function.component.ts new file mode 100644 index 0000000000..8f50cc14cd --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-get-function/tosca-get-function.component.ts @@ -0,0 +1,443 @@ +/* + * ============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, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges} from '@angular/core'; +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"; +import {PROPERTY_DATA, PROPERTY_TYPES} from "../../../../../utils/constants"; +import {DataTypeService} from "../../../../services/data-type.service"; +import {ToscaGetFunctionType} from "../../../../../models/tosca-get-function-type"; +import {TranslateService} from "../../../../shared/translator/translate.service"; +import {ComponentGenericResponse} from '../../../../services/responses/component-generic-response'; +import {Observable} from 'rxjs/Observable'; +import {PropertySource} from "../../../../../models/property-source"; +import {InstanceFeDetails} from "../../../../../models/instance-fe-details"; +import {ToscaGetFunction} from "../../../../../models/tosca-get-function"; +import {FormControl, FormGroup, Validators} from "@angular/forms"; +import {ToscaGetFunctionTypeConverter} from "../../../../../models/tosca-get-function-type-converter"; + +@Component({ + selector: 'app-tosca-get-function', + templateUrl: './tosca-get-function.component.html', + styleUrls: ['./tosca-get-function.component.less'] +}) +export class ToscaGetFunctionComponent implements OnInit, OnChanges { + + @Input() property: PropertyBEModel; + @Input() toscaGetFunction: ToscaGetFunction; + @Input() componentInstanceMap: Map<string, InstanceFeDetails> = new Map<string, InstanceFeDetails>(); + @Input() functionType: ToscaGetFunctionType; + @Output() onValidFunction: EventEmitter<ToscaGetFunction> = new EventEmitter<ToscaGetFunction>(); + @Output() onValidityChange: EventEmitter<ToscaGetFunctionValidationEvent> = new EventEmitter<ToscaGetFunctionValidationEvent>(); + + formGroup: FormGroup = new FormGroup({ + 'selectedProperty': new FormControl(undefined, Validators.required), + 'propertySource': new FormControl(undefined, Validators.required) + }); + + isLoading: boolean = false; + propertyDropdownList: Array<PropertyDropdownValue> = []; + propertySourceList: Array<string> = []; + instanceNameAndIdMap: Map<string, string> = new Map<string, string>(); + dropdownValuesLabel: string; + dropDownErrorMsg: string; + + private isInitialized: boolean = false; + private componentMetadata: ComponentMetadata; + + constructor(private topologyTemplateService: TopologyTemplateService, + private workspaceService: WorkspaceService, + private propertiesService: PropertiesService, + private dataTypeService: DataTypeService, + private translateService: TranslateService) { + } + + ngOnInit(): void { + this.componentMetadata = this.workspaceService.metadata; + this.formGroup.valueChanges.subscribe(() => { + if (!this.isInitialized) { + return; + } + this.onValidityChange.emit({ + isValid: this.formGroup.valid, + toscaGetFunction: this.formGroup.valid ? this.buildGetFunctionFromForm() : undefined + }); + if (this.formGroup.valid) { + this.onValidFunction.emit(this.buildGetFunctionFromForm()); + } + }); + this.loadPropertySourceDropdown(); + this.loadPropertyDropdownLabel(); + this.initToscaGetFunction().subscribe(() => { + this.isInitialized = true; + }); + + } + + ngOnChanges(_changes: SimpleChanges): void { + if (!this.isInitialized) { + return; + } + this.isInitialized = false; + this.resetForm(); + this.loadPropertySourceDropdown(); + this.loadPropertyDropdownLabel(); + this.initToscaGetFunction().subscribe(() => { + this.isInitialized = true; + }); + } + + private initToscaGetFunction(): Observable<void> { + return new Observable(subscriber => { + if (!this.toscaGetFunction) { + if (this.isGetInput()) { + this.setSelfPropertySource(); + this.loadPropertyDropdown(); + } + subscriber.next(); + return; + } + if (this.toscaGetFunction.propertySource == PropertySource.SELF) { + this.propertySource.setValue(PropertySource.SELF); + } else if (this.toscaGetFunction.propertySource == PropertySource.INSTANCE) { + this.propertySource + .setValue(this.propertySourceList.find(source => this.toscaGetFunction.sourceName === source)); + } + if (this.propertySource.valid) { + this.loadPropertyDropdown(() => { + this.selectedProperty + .setValue(this.propertyDropdownList.find(property => property.propertyName === this.toscaGetFunction.propertyName)); + subscriber.next(); + }); + } else { + subscriber.next(); + } + }); + } + + private buildGetFunctionFromForm() { + const toscaGetFunction = new ToscaGetFunction(); + toscaGetFunction.type = ToscaGetFunctionTypeConverter.convertToToscaFunctionType(this.functionType); + toscaGetFunction.functionType = this.functionType; + const propertySource = this.propertySource.value; + if (this.isPropertySourceSelf()) { + toscaGetFunction.propertySource = propertySource + toscaGetFunction.sourceName = this.componentMetadata.name; + toscaGetFunction.sourceUniqueId = this.componentMetadata.uniqueId; + } else { + toscaGetFunction.propertySource = PropertySource.INSTANCE; + toscaGetFunction.sourceName = propertySource; + toscaGetFunction.sourceUniqueId = this.instanceNameAndIdMap.get(propertySource); + } + + const selectedProperty: PropertyDropdownValue = this.selectedProperty.value; + toscaGetFunction.propertyUniqueId = selectedProperty.propertyId; + toscaGetFunction.propertyName = selectedProperty.propertyName; + toscaGetFunction.propertyPathFromSource = selectedProperty.propertyPath; + + return toscaGetFunction; + } + + private loadPropertySourceDropdown(): void { + if (this.isGetInput()) { + return; + } + this.propertySourceList = []; + this.propertySourceList.push(PropertySource.SELF); + this.componentInstanceMap.forEach((value, key) => { + const instanceName = value.name; + this.instanceNameAndIdMap.set(instanceName, key); + if (instanceName !== PropertySource.SELF) { + this.addToPropertySource(instanceName); + } + }); + } + + private addToPropertySource(source: string): void { + this.propertySourceList.push(source); + this.propertySourceList.sort((a, b) => { + if (a === PropertySource.SELF) { + return -1; + } else if (b === PropertySource.SELF) { + return 1; + } + + return a.localeCompare(b); + }); + } + + private loadPropertyDropdown(onComplete?: () => any): void { + this.loadPropertyDropdownLabel(); + this.loadPropertyDropdownValues(onComplete); + } + + private resetForm(): void { + this.formGroup.reset(); + } + + private loadPropertyDropdownLabel(): void { + if (!this.functionType) { + return; + } + if (this.isGetInput()) { + this.dropdownValuesLabel = this.translateService.translate('INPUT_DROPDOWN_LABEL'); + } else if (this.isGetProperty()) { + this.dropdownValuesLabel = this.translateService.translate('TOSCA_FUNCTION_PROPERTY_DROPDOWN_LABEL'); + } else if (this.isGetAttribute()) { + this.dropdownValuesLabel = this.translateService.translate('TOSCA_FUNCTION_ATTRIBUTE_DROPDOWN_LABEL'); + } + } + + private loadPropertyDropdownValues(onComplete?: () => any): void { + if (!this.functionType) { + return; + } + this.resetPropertyDropdown(); + this.fillPropertyDropdownValues(onComplete); + } + + private resetPropertyDropdown(): void { + this.dropDownErrorMsg = undefined; + this.selectedProperty.reset(); + this.propertyDropdownList = []; + } + + private fillPropertyDropdownValues(onComplete?: () => any): void { + this.startLoading(); + const propertiesObservable: Observable<ComponentGenericResponse> = this.getPropertyObservable(); + propertiesObservable.subscribe( (response: ComponentGenericResponse) => { + const properties: Array<PropertyBEModel | AttributeModel> = this.extractProperties(response); + if (!properties || properties.length === 0) { + 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.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(); + } + this.stopLoading(); + }); + } + + private getNotFoundMsgCode(): string { + if (this.isGetInput()) { + return 'TOSCA_FUNCTION_NO_INPUT_FOUND'; + } + if (this.isGetAttribute()) { + return 'TOSCA_FUNCTION_NO_ATTRIBUTE_FOUND'; + } + if (this.isGetProperty()) { + return 'TOSCA_FUNCTION_NO_PROPERTY_FOUND'; + } + + return undefined; + } + + private propertyTypeToString() { + if (this.property.schemaType) { + return `${this.property.type} of ${this.property.schemaType}`; + } + return this.property.type; + } + + private extractProperties(componentGenericResponse: ComponentGenericResponse): Array<PropertyBEModel | AttributeModel> { + if (this.isGetInput()) { + return componentGenericResponse.inputs; + } + const propertySource = this.propertySource.value; + if (this.isGetProperty()) { + if (this.isPropertySourceSelf()) { + return componentGenericResponse.properties; + } + const componentInstanceProperties: PropertyModel[] = componentGenericResponse.componentInstancesProperties[this.instanceNameAndIdMap.get(propertySource)]; + return this.removeSelectedProperty(componentInstanceProperties); + } + if (this.isPropertySourceSelf()) { + return componentGenericResponse.attributes; + } + return componentGenericResponse.componentInstancesAttributes[this.instanceNameAndIdMap.get(propertySource)]; + } + + private isPropertySourceSelf() { + return this.propertySource.value === PropertySource.SELF; + } + + private getPropertyObservable(): Observable<ComponentGenericResponse> { + if (this.isGetInput()) { + return this.topologyTemplateService.getComponentInputsValues(this.componentMetadata.componentType, this.componentMetadata.uniqueId); + } + if (this.isGetProperty()) { + if (this.isPropertySourceSelf()) { + return this.topologyTemplateService.findAllComponentProperties(this.componentMetadata.componentType, this.componentMetadata.uniqueId); + } + return this.topologyTemplateService.getComponentInstanceProperties(this.componentMetadata.componentType, this.componentMetadata.uniqueId); + } + if (this.isGetAttribute()) { + if (this.isPropertySourceSelf()) { + 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[] { + if (!componentInstanceProperties) { + return []; + } + return componentInstanceProperties.filter(property => + (property.uniqueId !== this.property.uniqueId) || + (property.uniqueId === this.property.uniqueId && property.resourceInstanceUniqueId !== this.property.parentUniqueId) + ); + } + + private addPropertyToDropdown(propertyDropdownValue: PropertyDropdownValue): void { + this.propertyDropdownList.push(propertyDropdownValue); + this.propertyDropdownList.sort((a, b) => a.propertyLabel.localeCompare(b.propertyLabel)); + } + + private addPropertiesToDropdown(properties: Array<PropertyBEModel | AttributeModel>): void { + for (const property of properties) { + if (this.hasSameType(property)) { + this.addPropertyToDropdown({ + propertyName: property.name, + propertyId: property.uniqueId, + propertyLabel: property.name, + propertyPath: [property.name] + }); + } else if (this.isComplexType(property.type)) { + this.fillPropertyDropdownWithMatchingChildProperties(property); + } + } + } + + 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; + } + parentPropertyList.push(inputProperty); + dataTypeFound.properties.forEach(dataTypeProperty => { + if (this.hasSameType(dataTypeProperty)) { + this.addPropertyToDropdown({ + propertyName: dataTypeProperty.name, + propertyId: parentPropertyList[0].uniqueId, + propertyLabel: parentPropertyList.map(property => property.name).join('->') + '->' + dataTypeProperty.name, + propertyPath: [...parentPropertyList.map(property => property.name), dataTypeProperty.name] + }); + } else if (this.isComplexType(dataTypeProperty.type)) { + this.fillPropertyDropdownWithMatchingChildProperties(dataTypeProperty, [...parentPropertyList]) + } + }); + } + + private hasSameType(property: PropertyBEModel | AttributeModel) { + if (this.typeHasSchema(this.property.type)) { + if (!property.schema || !property.schema.property) { + return false; + } + return property.type === this.property.type && this.property.schema.property.type === property.schema.property.type; + } + + return property.type === this.property.type; + } + + private isGetProperty(): boolean { + return this.functionType === ToscaGetFunctionType.GET_PROPERTY; + } + + private isGetAttribute(): boolean { + return this.functionType === ToscaGetFunctionType.GET_ATTRIBUTE; + } + + private isGetInput(): boolean { + return this.functionType === ToscaGetFunctionType.GET_INPUT; + } + + private isComplexType(propertyType: string): boolean { + return PROPERTY_DATA.SIMPLE_TYPES.indexOf(propertyType) === -1; + } + + private typeHasSchema(propertyType: string): boolean { + return PROPERTY_TYPES.MAP === propertyType || PROPERTY_TYPES.LIST === propertyType; + } + + private stopLoading(): void { + this.isLoading = false; + } + + private startLoading(): void { + this.isLoading = true; + } + + showPropertyDropdown(): boolean { + if (this.isGetProperty() || this.isGetAttribute()) { + return this.propertySource.valid && !this.isLoading && !this.dropDownErrorMsg; + } + + return this.functionType && !this.isLoading && !this.dropDownErrorMsg; + } + + onPropertySourceChange(): void { + if (!this.functionType || !this.propertySource.valid) { + return; + } + this.loadPropertyDropdown(); + } + + showPropertySourceDropdown(): boolean { + return this.isGetProperty() || this.isGetAttribute(); + } + + private setSelfPropertySource(): void { + this.propertySource.setValue(PropertySource.SELF); + } + + private get propertySource(): FormControl { + return this.formGroup.get('propertySource') as FormControl; + } + + private get selectedProperty(): FormControl { + return this.formGroup.get('selectedProperty') as FormControl; + } + +} + +export interface PropertyDropdownValue { + propertyName: string; + propertyId: string; + propertyLabel: string; + propertyPath: Array<string>; +} + +export interface ToscaGetFunctionValidationEvent { + isValid: boolean, + toscaGetFunction: ToscaGetFunction, +}
\ No newline at end of file diff --git a/catalog-ui/src/app/view-models/forms/property-forms/component-property-form/property-form-view-model.ts b/catalog-ui/src/app/view-models/forms/property-forms/component-property-form/property-form-view-model.ts index 13460f50bf..008858d43d 100644 --- a/catalog-ui/src/app/view-models/forms/property-forms/component-property-form/property-form-view-model.ts +++ b/catalog-ui/src/app/view-models/forms/property-forms/component-property-form/property-form-view-model.ts @@ -397,7 +397,7 @@ export class PropertyFormViewModel { this.$scope.$watch("forms.editForm.$invalid", (newVal) => { if (this.$scope.editPropertyModel.hasGetFunctionValue) { - this.$scope.footerButtons[0].disabled = newVal || !this.$scope.editPropertyModel.property.toscaGetFunction; + this.$scope.footerButtons[0].disabled = newVal || !this.$scope.editPropertyModel.property.toscaFunction; } else { this.$scope.footerButtons[0].disabled = newVal; } @@ -405,7 +405,7 @@ export class PropertyFormViewModel { this.$scope.$watch("forms.editForm.$valid", (newVal) => { if (this.$scope.editPropertyModel.hasGetFunctionValue) { - this.$scope.footerButtons[0].disabled = !newVal || !this.$scope.editPropertyModel.property.toscaGetFunction; + this.$scope.footerButtons[0].disabled = !newVal || !this.$scope.editPropertyModel.property.toscaFunction; } else { this.$scope.footerButtons[0].disabled = !newVal; } @@ -448,13 +448,13 @@ export class PropertyFormViewModel { if (this.$scope.editPropertyModel.hasGetFunctionValue) { this.$scope.editPropertyModel.isGetFunctionValid = undefined; } else { - this.$scope.editPropertyModel.property.toscaGetFunction = undefined; + this.$scope.editPropertyModel.property.toscaFunction = undefined; this.$scope.editPropertyModel.isGetFunctionValid = true; } } this.$scope.onGetFunctionValidFunction = (toscaGetFunction: ToscaGetFunction): void => { - this.$scope.editPropertyModel.property.toscaGetFunction = toscaGetFunction; + this.$scope.editPropertyModel.property.toscaFunction = toscaGetFunction; } this.$scope.onGetFunctionValidityChange = (isValid: boolean): void => { diff --git a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/CustomYamlFunction.java b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/CustomYamlFunction.java new file mode 100644 index 0000000000..84543e29f7 --- /dev/null +++ b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/CustomYamlFunction.java @@ -0,0 +1,46 @@ +/* + * - + * ============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.datatypes.elements; + +import lombok.Setter; +import org.yaml.snakeyaml.Yaml; + +@Setter +public class CustomYamlFunction implements ToscaFunction, ToscaFunctionParameter { + + private Object yamlValue; + + @Override + public ToscaFunctionType getType() { + return ToscaFunctionType.YAML; + } + + @Override + public String getValue() { + return new Yaml().dump(yamlValue); + } + + @Override + public Object getJsonObjectValue() { + return yamlValue; + } +} diff --git a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/PropertyDataDefinition.java b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/PropertyDataDefinition.java index 845eee808a..f88514ac49 100644 --- a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/PropertyDataDefinition.java +++ b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/PropertyDataDefinition.java @@ -22,6 +22,7 @@ package org.openecomp.sdc.be.datatypes.elements; import static org.apache.commons.collections.CollectionUtils.isNotEmpty; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; @@ -56,11 +57,16 @@ public class PropertyDataDefinition extends ToscaDataDefinition { private Boolean immutable = Boolean.FALSE; private Boolean mappedToComponentProperty = Boolean.TRUE; /** - * @deprecated use {@link #toscaGetFunction#functionType} instead + * @deprecated use {@link #toscaFunction} instead */ @Deprecated private ToscaGetFunctionType toscaGetFunctionType; + /** + * @deprecated use {@link #toscaFunction} instead + */ + @Deprecated private ToscaGetFunctionDataDefinition toscaGetFunction; + private ToscaFunction toscaFunction; private String inputPath; private String status; @@ -115,8 +121,9 @@ public class PropertyDataDefinition extends ToscaDataDefinition { this.setInstanceUniqueId(propertyDataDefinition.getInstanceUniqueId()); this.setModel(propertyDataDefinition.getModel()); this.setPropertyId(propertyDataDefinition.getPropertyId()); - this.setToscaGetFunctionType(propertyDataDefinition.getToscaGetFunctionType()); this.setToscaGetFunction(propertyDataDefinition.getToscaGetFunction()); + this.setToscaGetFunctionType(propertyDataDefinition.getToscaGetFunctionType()); + this.setToscaFunction(propertyDataDefinition.getToscaFunction()); this.parentPropertyType = propertyDataDefinition.getParentPropertyType(); this.subPropertyInputPath = propertyDataDefinition.getSubPropertyInputPath(); if (isNotEmpty(propertyDataDefinition.annotations)) { @@ -166,10 +173,14 @@ public class PropertyDataDefinition extends ToscaDataDefinition { } public ToscaGetFunctionType getToscaGetFunctionType() { - if (toscaGetFunction != null) { - return toscaGetFunction.getFunctionType(); + if (isToscaGetFunction()) { + if (toscaFunction != null) { + return ((ToscaGetFunctionDataDefinition) toscaFunction).getFunctionType(); + } + return toscaGetFunctionType; } - return toscaGetFunctionType; + + return null; } public Boolean isHidden() { @@ -318,12 +329,23 @@ public class PropertyDataDefinition extends ToscaDataDefinition { return (List<Annotation>) getToscaPresentationValue(JsonPresentationFields.ANNOTATIONS); } - public boolean isGetFunction() { - return this.toscaGetFunctionType != null || this.toscaGetFunction != null; + @JsonIgnoreProperties + public boolean isToscaFunction() { + return this.toscaGetFunctionType != null || this.toscaFunction != null; + } + + + @JsonIgnoreProperties + public boolean isToscaGetFunction() { + return this.toscaGetFunctionType != null || (this.toscaFunction != null + && (this.toscaFunction.getType() == ToscaFunctionType.GET_ATTRIBUTE + || this.toscaFunction.getType() == ToscaFunctionType.GET_INPUT + || this.toscaFunction.getType() == ToscaFunctionType.GET_PROPERTY)); } - public boolean hasGetFunction() { - return this.toscaGetFunction != null; + @JsonIgnoreProperties + public boolean hasToscaFunction() { + return this.toscaFunction != null; } } diff --git a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/ToscaConcatFunction.java b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/ToscaConcatFunction.java new file mode 100644 index 0000000000..62307fb4be --- /dev/null +++ b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/ToscaConcatFunction.java @@ -0,0 +1,56 @@ +/* + * - + * ============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.datatypes.elements; + +import com.google.gson.Gson; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class ToscaConcatFunction implements ToscaFunction, ToscaFunctionParameter { + + private List<ToscaFunctionParameter> parameters = new ArrayList<>(); + + @Override + public ToscaFunctionType getType() { + return ToscaFunctionType.CONCAT; + } + + @Override + public String getValue() { + return new Gson().toJson(getJsonObjectValue()); + } + + @Override + public Object getJsonObjectValue() { + return Map.of( + ToscaFunctionType.CONCAT.getName(), + parameters.stream().map(ToscaFunctionParameter::getJsonObjectValue).collect(Collectors.toList()) + ); + } + +} diff --git a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/ToscaFunction.java b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/ToscaFunction.java new file mode 100644 index 0000000000..40664a133c --- /dev/null +++ b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/ToscaFunction.java @@ -0,0 +1,32 @@ +/* + * - + * ============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.datatypes.elements; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +@JsonDeserialize(using = ToscaFunctionJsonDeserializer.class) +public interface ToscaFunction { + + ToscaFunctionType getType(); + String getValue(); + +} diff --git a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/ToscaFunctionJsonDeserializer.java b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/ToscaFunctionJsonDeserializer.java new file mode 100644 index 0000000000..74aed12471 --- /dev/null +++ b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/ToscaFunctionJsonDeserializer.java @@ -0,0 +1,151 @@ +/* + * - + * ============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.datatypes.elements; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import org.apache.commons.lang3.StringUtils; +import org.openecomp.sdc.be.datatypes.enums.PropertySource; +import org.openecomp.sdc.be.datatypes.tosca.ToscaGetFunctionType; +import org.yaml.snakeyaml.Yaml; + +public class ToscaFunctionJsonDeserializer extends StdDeserializer<ToscaFunction> { + + public ToscaFunctionJsonDeserializer() { + this(null); + } + + public ToscaFunctionJsonDeserializer(Class<?> vc) { + super(vc); + } + + @Override + public ToscaFunction deserialize(final JsonParser jsonParser, final DeserializationContext context) throws IOException { + final JsonNode node = jsonParser.getCodec().readTree(jsonParser); + return deserializeToscaFunction(node, context); + } + + private ToscaFunction deserializeToscaFunction(final JsonNode node, final DeserializationContext context) throws IOException { + final String functionType; + if (node.get("type") != null) { + functionType = node.get("type").asText(); + } else if (node.get("functionType") != null) { + //support for legacy tosca function + functionType = node.get("functionType").asText(); + } else { + throw context.instantiationException(ToscaFunction.class, "Attribute type not provided"); + } + final ToscaFunctionType toscaFunctionType = ToscaFunctionType.findType(functionType) + .orElseThrow(() -> context.instantiationException(ToscaFunction.class, + String.format("Invalid function type '%s' or attribute type not provided", functionType)) + ); + if (toscaFunctionType == ToscaFunctionType.GET_INPUT || toscaFunctionType == ToscaFunctionType.GET_ATTRIBUTE + || toscaFunctionType == ToscaFunctionType.GET_PROPERTY) { + return deserializeToscaGetFunction(toscaFunctionType, node, context); + } + + if (toscaFunctionType == ToscaFunctionType.CONCAT) { + return this.deserializeConcatFunction(node, context); + } + + if (toscaFunctionType == ToscaFunctionType.YAML) { + return this.deserializeYamlFunction(node); + } + + return null; + } + + private ToscaFunction deserializeYamlFunction(JsonNode node) { + var yamlFunction = new CustomYamlFunction(); + final Object value = new Yaml().load(node.get("value").asText()); + yamlFunction.setYamlValue(value); + return yamlFunction; + } + + private ToscaGetFunctionDataDefinition deserializeToscaGetFunction(final ToscaFunctionType toscaFunctionType, final JsonNode node, + final DeserializationContext context) throws JsonMappingException { + final ToscaGetFunctionDataDefinition toscaGetFunction = new ToscaGetFunctionDataDefinition(); + toscaGetFunction.setFunctionType(ToscaGetFunctionType.fromToscaFunctionType(toscaFunctionType).orElse(null)); + toscaGetFunction.setSourceName(node.get("sourceName").asText()); + toscaGetFunction.setPropertyUniqueId(node.get("propertyUniqueId").asText()); + final String propertySource = node.get("propertySource").asText(); + if (StringUtils.isNotEmpty(propertySource)) { + final PropertySource propertySource1 = PropertySource.findType(propertySource).orElseThrow(() -> + context.instantiationException(ToscaGetFunctionDataDefinition.class, + String.format("Invalid propertySource '%s'", propertySource)) + ); + toscaGetFunction.setPropertySource(propertySource1); + } + toscaGetFunction.setPropertyName(node.get("propertyName").asText()); + toscaGetFunction.setSourceName(node.get("sourceName").asText()); + toscaGetFunction.setSourceUniqueId(node.get("sourceUniqueId").asText()); + final JsonNode propertyPathFromSourceNode = node.get("propertyPathFromSource"); + if (propertyPathFromSourceNode != null) { + if (!propertyPathFromSourceNode.isArray()) { + throw context.instantiationException(ToscaGetFunctionDataDefinition.class, "Expecting an array for propertyPathFromSource attribute"); + } + final List<String> pathFromSource = new ArrayList<>(); + propertyPathFromSourceNode.forEach(jsonNode -> pathFromSource.add(jsonNode.asText())); + toscaGetFunction.setPropertyPathFromSource(pathFromSource); + } + + return toscaGetFunction; + } + + private ToscaConcatFunction deserializeConcatFunction(final JsonNode concatFunctionJsonNode, + final DeserializationContext context) throws IOException { + final var toscaConcatFunction = new ToscaConcatFunction(); + final List<ToscaFunctionParameter> functionParameterList = new ArrayList<>(); + final JsonNode parametersNode = concatFunctionJsonNode.get("parameters"); + if (!parametersNode.isArray()) { + throw context.instantiationException(List.class, ""); + } + for (final JsonNode parameterNode : parametersNode) { + final JsonNode typeJsonNode = parameterNode.get("type"); + if (typeJsonNode == null) { + throw context.instantiationException(ToscaConcatFunction.class, "TOSCA concat function parameter type attribute not provided"); + } + final String parameterType = typeJsonNode.asText(); + final ToscaFunctionType toscaFunctionType = ToscaFunctionType.findType(parameterType) + .orElseThrow(() -> context.instantiationException(ToscaConcatFunction.class, + String.format("Invalid TOSCA concat function parameter type '%s'", parameterType)) + ); + if (toscaFunctionType == ToscaFunctionType.STRING) { + final ToscaStringParameter toscaStringParameter = new ToscaStringParameter(); + toscaStringParameter.setValue(parameterNode.get("value").asText()); + functionParameterList.add(toscaStringParameter); + } else { + final ToscaFunction toscaFunction = this.deserializeToscaFunction(parameterNode, context); + functionParameterList.add((ToscaFunctionParameter) toscaFunction); + } + } + toscaConcatFunction.setParameters(functionParameterList); + return toscaConcatFunction; + } + +} diff --git a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/ToscaFunctionParameter.java b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/ToscaFunctionParameter.java new file mode 100644 index 0000000000..4d4c7b0a68 --- /dev/null +++ b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/ToscaFunctionParameter.java @@ -0,0 +1,30 @@ +/* + * - + * ============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.datatypes.elements; + +public interface ToscaFunctionParameter { + + String getValue(); + ToscaFunctionType getType(); + Object getJsonObjectValue(); + +} diff --git a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/ToscaFunctionType.java b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/ToscaFunctionType.java new file mode 100644 index 0000000000..4579ac2410 --- /dev/null +++ b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/ToscaFunctionType.java @@ -0,0 +1,45 @@ +/* + * - + * ============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.datatypes.elements; + +import java.util.Arrays; +import java.util.Optional; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@AllArgsConstructor +@Getter +public enum ToscaFunctionType { + + GET_INPUT("get_input"), + GET_PROPERTY("get_property"), + GET_ATTRIBUTE("get_attribute"), + CONCAT("concat"), + YAML("yaml"), + STRING("string"); + + private final String name; + + public static Optional<ToscaFunctionType> findType(final String functionType) { + return Arrays.stream(values()).filter(toscaFunctionType -> toscaFunctionType.getName().equalsIgnoreCase(functionType)).findFirst(); + } +} 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 0741d6849e..f19217e69c 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 @@ -33,7 +33,7 @@ import org.openecomp.sdc.be.datatypes.enums.PropertySource; import org.openecomp.sdc.be.datatypes.tosca.ToscaGetFunctionType; @Data -public class ToscaGetFunctionDataDefinition { +public class ToscaGetFunctionDataDefinition implements ToscaFunction, ToscaFunctionParameter { private String propertyUniqueId; private String propertyName; @@ -55,6 +55,11 @@ public class ToscaGetFunctionDataDefinition { * Builds the value of a property based on the TOSCA get function information. */ public String generatePropertyValue() { + return new Gson().toJson(getJsonObjectValue()); + } + + @Override + public Object getJsonObjectValue() { if (functionType == null) { throw new IllegalStateException("functionType is required in order to generate the get function value"); } @@ -62,12 +67,11 @@ public class ToscaGetFunctionDataDefinition { throw new IllegalStateException("propertyPathFromSource is required in order to generate the get function value"); } - final var gson = new Gson(); if (functionType == ToscaGetFunctionType.GET_PROPERTY || functionType == ToscaGetFunctionType.GET_ATTRIBUTE) { - return gson.toJson(buildFunctionValueWithPropertySource()); + return buildFunctionValueWithPropertySource(); } if (functionType == ToscaGetFunctionType.GET_INPUT) { - return gson.toJson(buildGetInputFunctionValue()); + return buildGetInputFunctionValue(); } throw new UnsupportedOperationException(String.format("ToscaGetFunctionType '%s' is not supported yet", functionType)); @@ -105,4 +109,26 @@ public class ToscaGetFunctionDataDefinition { return Map.of(this.functionType.getFunctionName(), this.propertyPathFromSource); } + @Override + public ToscaFunctionType getType() { + if (functionType == null) { + return null; + } + switch (functionType) { + case GET_INPUT: + return ToscaFunctionType.GET_INPUT; + case GET_PROPERTY: + return ToscaFunctionType.GET_PROPERTY; + case GET_ATTRIBUTE: + return ToscaFunctionType.GET_ATTRIBUTE; + default: + return null; + } + } + + @Override + public String getValue() { + return this.generatePropertyValue(); + } + } diff --git a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/ToscaStringParameter.java b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/ToscaStringParameter.java new file mode 100644 index 0000000000..d6d5d9f8ad --- /dev/null +++ b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/ToscaStringParameter.java @@ -0,0 +1,44 @@ +/* + * - + * ============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.datatypes.elements; + +import lombok.Setter; + +@Setter +public class ToscaStringParameter implements ToscaFunctionParameter { + private String value; + + @Override + public String getValue() { + return value; + } + + @Override + public ToscaFunctionType getType() { + return ToscaFunctionType.STRING; + } + + @Override + public Object getJsonObjectValue() { + return getValue(); + } +} diff --git a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/PropertySource.java b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/PropertySource.java index 8086d22815..d2e15039d3 100644 --- a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/PropertySource.java +++ b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/PropertySource.java @@ -21,6 +21,8 @@ package org.openecomp.sdc.be.datatypes.enums; +import java.util.Arrays; +import java.util.Optional; import lombok.AllArgsConstructor; import lombok.Getter; @@ -31,4 +33,8 @@ public enum PropertySource { private final String name; + public static Optional<PropertySource> findType(final String propertySource) { + return Arrays.stream(values()).filter(propertySource1 -> propertySource1.getName().equalsIgnoreCase(propertySource)).findFirst(); + } + } 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 index bb85ceb0fc..d84c86a38d 100644 --- 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 @@ -19,8 +19,10 @@ package org.openecomp.sdc.be.datatypes.tosca; +import java.util.Optional; import lombok.AllArgsConstructor; import lombok.Getter; +import org.openecomp.sdc.be.datatypes.elements.ToscaFunctionType; @AllArgsConstructor @Getter @@ -31,4 +33,23 @@ public enum ToscaGetFunctionType { private final String functionName; private final String propertyType; + + /** + * Converts a {@link ToscaFunctionType} to a {@link ToscaGetFunctionType} + * @param toscaFunctionType the tosca function type to convert + * @return the respective {@link ToscaGetFunctionType} + */ + public static Optional<ToscaGetFunctionType> fromToscaFunctionType(final ToscaFunctionType toscaFunctionType) { + switch (toscaFunctionType) { + case GET_INPUT: + return Optional.of(GET_INPUT); + case GET_PROPERTY: + return Optional.of(GET_PROPERTY); + case GET_ATTRIBUTE: + return Optional.of(GET_ATTRIBUTE); + default: + return Optional.empty(); + } + } + } diff --git a/common-be/src/test/java/org/openecomp/sdc/be/datatypes/elements/PropertyDataDefinitionTest.java b/common-be/src/test/java/org/openecomp/sdc/be/datatypes/elements/PropertyDataDefinitionTest.java index 2e8b26fcb4..2d73faf41e 100644 --- a/common-be/src/test/java/org/openecomp/sdc/be/datatypes/elements/PropertyDataDefinitionTest.java +++ b/common-be/src/test/java/org/openecomp/sdc/be/datatypes/elements/PropertyDataDefinitionTest.java @@ -20,33 +20,32 @@ package org.openecomp.sdc.be.datatypes.elements; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields; - -import java.util.List; - import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertTrue; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.List; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields; +import org.openecomp.sdc.be.datatypes.tosca.ToscaGetFunctionType; -public class PropertyDataDefinitionTest { +class PropertyDataDefinitionTest { private PropertyDataDefinition propDef; - @Before + @BeforeEach public void setUp() { propDef = new PropertyDataDefinition(); } @Test - public void setStringField() { + void setStringField() { final String name = "name"; assertNull(propDef.getName()); assertNull(propDef.getToscaPresentationValue(JsonPresentationFields.NAME)); @@ -56,7 +55,7 @@ public class PropertyDataDefinitionTest { } @Test - public void setDefaultValue() { + void setDefaultValue() { final String defaultValue = "text"; assertNull(propDef.getDefaultValue()); assertNull(propDef.getToscaPresentationValue(JsonPresentationFields.DEFAULT_VALUE)); @@ -66,7 +65,7 @@ public class PropertyDataDefinitionTest { } @Test - public void setValueNotDefinedInPropDataDefinition() { + void setValueNotDefinedInPropDataDefinition() { final String defaultValue = "VF"; assertNull(propDef.getToscaPresentationValue(JsonPresentationFields.COMPONENT_TYPE)); propDef.setToscaPresentationValue(JsonPresentationFields.COMPONENT_TYPE, defaultValue); @@ -74,7 +73,7 @@ public class PropertyDataDefinitionTest { } @Test - public void setBooleanField() { + void setBooleanField() { assertFalse((Boolean) propDef.getToscaPresentationValue(JsonPresentationFields.PASSWORD)); assertFalse(propDef.isPassword()); propDef.setToscaPresentationValue(JsonPresentationFields.PASSWORD, Boolean.TRUE); @@ -83,7 +82,7 @@ public class PropertyDataDefinitionTest { } @Test - public void mergeDefaultValueWhenItWasNullBeforeMerge() { + void mergeDefaultValueWhenItWasNullBeforeMerge() { final String defaultValue = "12345"; final String type = "1"; PropertyDataDefinition propForMerge = new PropertyDataDefinition(); @@ -99,7 +98,7 @@ public class PropertyDataDefinitionTest { } @Test - public void mergeDefaultValueAndOverrideIt() { + void mergeDefaultValueAndOverrideIt() { final String defaultValue = "12345"; final String defaultValueForOther = "7890"; final String type = "1"; @@ -117,7 +116,7 @@ public class PropertyDataDefinitionTest { } @Test - public void mergeDefaultValueWhenOverridingIsNotAllowed() { + void mergeDefaultValueWhenOverridingIsNotAllowed() { final String defaultValue = "12345"; final String defaultValueForOther = "7890"; final String type = "1"; @@ -139,7 +138,7 @@ public class PropertyDataDefinitionTest { } @Test - public void testConstructor() throws Exception { + void testConstructor() { PropertyDataDefinition testSubject; String result; @@ -149,7 +148,7 @@ public class PropertyDataDefinitionTest { } @Test - public void testGetInputPath() throws Exception { + void testGetInputPath() { PropertyDataDefinition testSubject; String result; @@ -160,7 +159,7 @@ public class PropertyDataDefinitionTest { @Test - public void testSetInputPath() throws Exception { + void testSetInputPath() { PropertyDataDefinition testSubject; String inputPath = ""; @@ -171,7 +170,7 @@ public class PropertyDataDefinitionTest { @Test - public void testGetName() throws Exception { + void testGetName() { PropertyDataDefinition testSubject; String result; @@ -182,7 +181,7 @@ public class PropertyDataDefinitionTest { @Test - public void testSetName() throws Exception { + void testSetName() { PropertyDataDefinition testSubject; String name = ""; @@ -193,7 +192,7 @@ public class PropertyDataDefinitionTest { @Test - public void testGetValue() throws Exception { + void testGetValue() { PropertyDataDefinition testSubject; String result; @@ -204,7 +203,7 @@ public class PropertyDataDefinitionTest { @Test - public void testSetValue() throws Exception { + void testSetValue() { PropertyDataDefinition testSubject; String value = ""; @@ -215,7 +214,7 @@ public class PropertyDataDefinitionTest { @Test - public void testIsDefinition() throws Exception { + void testIsDefinition() { PropertyDataDefinition testSubject; boolean result; @@ -226,7 +225,7 @@ public class PropertyDataDefinitionTest { @Test - public void testSetDefinition() throws Exception { + void testSetDefinition() { PropertyDataDefinition testSubject; boolean definition = false; @@ -237,7 +236,7 @@ public class PropertyDataDefinitionTest { @Test - public void testGetType() throws Exception { + void testGetType() { PropertyDataDefinition testSubject; String result; @@ -248,7 +247,7 @@ public class PropertyDataDefinitionTest { @Test - public void testGetDefaultValue() throws Exception { + void testGetDefaultValue() { PropertyDataDefinition testSubject; String result; @@ -259,7 +258,7 @@ public class PropertyDataDefinitionTest { @Test - public void testSetDefaultValue() throws Exception { + void testSetDefaultValue() { PropertyDataDefinition testSubject; String defaultValue = ""; @@ -270,7 +269,7 @@ public class PropertyDataDefinitionTest { @Test - public void testSetType() throws Exception { + void testSetType() { PropertyDataDefinition testSubject; String type = ""; @@ -281,7 +280,7 @@ public class PropertyDataDefinitionTest { @Test - public void testIsRequired() throws Exception { + void testIsRequired() { PropertyDataDefinition testSubject; Boolean result; @@ -292,7 +291,7 @@ public class PropertyDataDefinitionTest { @Test - public void testSetRequired() throws Exception { + void testSetRequired() { PropertyDataDefinition testSubject; Boolean required = null; @@ -303,7 +302,7 @@ public class PropertyDataDefinitionTest { @Test - public void testGetDescription() throws Exception { + void testGetDescription() { PropertyDataDefinition testSubject; String result; @@ -314,7 +313,7 @@ public class PropertyDataDefinitionTest { @Test - public void testSetDescription() throws Exception { + void testSetDescription() { PropertyDataDefinition testSubject; String description = ""; @@ -325,7 +324,7 @@ public class PropertyDataDefinitionTest { @Test - public void testIsPassword() throws Exception { + void testIsPassword() { PropertyDataDefinition testSubject; boolean result; @@ -336,7 +335,7 @@ public class PropertyDataDefinitionTest { @Test - public void testSetPassword() throws Exception { + void testSetPassword() { PropertyDataDefinition testSubject; boolean password = false; @@ -347,7 +346,7 @@ public class PropertyDataDefinitionTest { @Test - public void testGetUniqueId() throws Exception { + void testGetUniqueId() { PropertyDataDefinition testSubject; String result; @@ -358,7 +357,7 @@ public class PropertyDataDefinitionTest { @Test - public void testSetUniqueId() throws Exception { + void testSetUniqueId() { PropertyDataDefinition testSubject; String uniqueId = ""; @@ -369,7 +368,7 @@ public class PropertyDataDefinitionTest { @Test - public void testGetSchema() throws Exception { + void testGetSchema() { PropertyDataDefinition testSubject; SchemaDefinition result; @@ -380,7 +379,7 @@ public class PropertyDataDefinitionTest { @Test - public void testSetSchema() throws Exception { + void testSetSchema() { PropertyDataDefinition testSubject; SchemaDefinition entrySchema = null; @@ -391,7 +390,7 @@ public class PropertyDataDefinitionTest { @Test - public void testGetLabel() throws Exception { + void testGetLabel() { PropertyDataDefinition testSubject; String result; @@ -402,7 +401,7 @@ public class PropertyDataDefinitionTest { @Test - public void testSetLabel() throws Exception { + void testSetLabel() { PropertyDataDefinition testSubject; String label = ""; @@ -413,7 +412,7 @@ public class PropertyDataDefinitionTest { @Test - public void testIsHidden() throws Exception { + void testIsHidden() { PropertyDataDefinition testSubject; Boolean result; @@ -424,7 +423,7 @@ public class PropertyDataDefinitionTest { @Test - public void testSetHidden() throws Exception { + void testSetHidden() { PropertyDataDefinition testSubject; Boolean hidden = null; @@ -435,7 +434,7 @@ public class PropertyDataDefinitionTest { @Test - public void testIsImmutable() throws Exception { + void testIsImmutable() { PropertyDataDefinition testSubject; Boolean result; @@ -446,7 +445,7 @@ public class PropertyDataDefinitionTest { @Test - public void testSetImmutable() throws Exception { + void testSetImmutable() { PropertyDataDefinition testSubject; Boolean immutable = null; @@ -457,7 +456,7 @@ public class PropertyDataDefinitionTest { @Test - public void testGetParentUniqueId() throws Exception { + void testGetParentUniqueId() { PropertyDataDefinition testSubject; String result; @@ -468,7 +467,7 @@ public class PropertyDataDefinitionTest { @Test - public void testSetParentUniqueId() throws Exception { + void testSetParentUniqueId() { PropertyDataDefinition testSubject; String parentUniqueId = ""; @@ -479,7 +478,7 @@ public class PropertyDataDefinitionTest { @Test - public void testGetGetInputValues() throws Exception { + void testGetGetInputValues() { PropertyDataDefinition testSubject; List<GetInputValueDataDefinition> result; @@ -490,7 +489,7 @@ public class PropertyDataDefinitionTest { @Test - public void testSetGetInputValues() throws Exception { + void testSetGetInputValues() { PropertyDataDefinition testSubject; List<GetInputValueDataDefinition> getInputValues = null; @@ -501,7 +500,7 @@ public class PropertyDataDefinitionTest { @Test - public void testGetStatus() throws Exception { + void testGetStatus() { PropertyDataDefinition testSubject; String result; @@ -512,7 +511,7 @@ public class PropertyDataDefinitionTest { @Test - public void testSetStatus() throws Exception { + void testSetStatus() { PropertyDataDefinition testSubject; String status = ""; @@ -523,7 +522,7 @@ public class PropertyDataDefinitionTest { @Test - public void testGetInputId() throws Exception { + void testGetInputId() { PropertyDataDefinition testSubject; String result; @@ -534,7 +533,7 @@ public class PropertyDataDefinitionTest { @Test - public void testSetInputId() throws Exception { + void testSetInputId() { PropertyDataDefinition testSubject; String inputId = ""; @@ -545,7 +544,7 @@ public class PropertyDataDefinitionTest { @Test - public void testGetInstanceUniqueId() throws Exception { + void testGetInstanceUniqueId() { PropertyDataDefinition testSubject; String result; @@ -556,7 +555,7 @@ public class PropertyDataDefinitionTest { @Test - public void testSetInstanceUniqueId() throws Exception { + void testSetInstanceUniqueId() { PropertyDataDefinition testSubject; String instanceUniqueId = ""; @@ -567,7 +566,7 @@ public class PropertyDataDefinitionTest { @Test - public void testGetPropertyId() throws Exception { + void testGetPropertyId() { PropertyDataDefinition testSubject; String result; @@ -578,7 +577,7 @@ public class PropertyDataDefinitionTest { @Test - public void testSetPropertyId() throws Exception { + void testSetPropertyId() { PropertyDataDefinition testSubject; String propertyId = ""; @@ -589,7 +588,7 @@ public class PropertyDataDefinitionTest { @Test - public void testToString() throws Exception { + void testToString() { PropertyDataDefinition testSubject; String result; @@ -600,7 +599,7 @@ public class PropertyDataDefinitionTest { @Test - public void testHashCode() throws Exception { + void testHashCode() { PropertyDataDefinition testSubject; int result; @@ -611,7 +610,7 @@ public class PropertyDataDefinitionTest { @Test - public void testEquals() throws Exception { + void testEquals() { PropertyDataDefinition testSubject; Object obj = null; boolean result; @@ -620,16 +619,16 @@ public class PropertyDataDefinitionTest { testSubject = createTestSubject(); obj = null; result = testSubject.equals(obj); - Assert.assertEquals(false, result); + assertEquals(false, result); result = testSubject.equals(testSubject); - Assert.assertEquals(true, result); + assertEquals(true, result); PropertyDataDefinition other = createTestSubject(); result = testSubject.equals(other); - Assert.assertEquals(true, result); + assertEquals(true, result); } @Test - public void testConvertPropertyDataToInstancePropertyData() throws Exception { + void testConvertPropertyDataToInstancePropertyData() { PropertyDataDefinition testSubject; // default test @@ -638,7 +637,7 @@ public class PropertyDataDefinitionTest { } @Test - public void testTypeEquals() throws Exception { + void testTypeEquals() { PropertyDataDefinition testSubject; // default test @@ -649,7 +648,7 @@ public class PropertyDataDefinitionTest { } @Test - public void testMergeFunction() throws Exception { + void testMergeFunction() { PropertyDataDefinition testSubject; // default test @@ -659,7 +658,7 @@ public class PropertyDataDefinitionTest { } @Test - public void schemaTypeNullWhenSchemaIsNull() { + void schemaTypeNullWhenSchemaIsNull() { String sampleSchemaType = "sampleSchemaType"; PropertyDataDefinition testSubject = createTestSubject(); testSubject.setSchemaType(sampleSchemaType); @@ -667,7 +666,7 @@ public class PropertyDataDefinitionTest { } @Test - public void schemaTypeIsReturnedWhenSchemaisPresent() { + void schemaTypeIsReturnedWhenSchemaIsPresent() { String sampleSchemaType = "sampleSchemaType"; SchemaDefinition schemaDefinition = new SchemaDefinition(); schemaDefinition.setProperty(new PropertyDataDefinition()); @@ -678,4 +677,62 @@ public class PropertyDataDefinitionTest { assertThat(testSubject.getSchemaType(), is(equalTo(sampleSchemaType))); } + + @Test + void getToscaGetFunctionTypeTest() { + var propertyDataDefinition = new PropertyDataDefinition(); + assertNull(propertyDataDefinition.getToscaGetFunctionType()); + + final var toscaGetFunction = new ToscaGetFunctionDataDefinition(); + propertyDataDefinition.setToscaFunction(toscaGetFunction); + + toscaGetFunction.setFunctionType(ToscaGetFunctionType.GET_INPUT); + assertEquals(ToscaGetFunctionType.GET_INPUT, propertyDataDefinition.getToscaGetFunctionType()); + + toscaGetFunction.setFunctionType(ToscaGetFunctionType.GET_PROPERTY); + assertEquals(ToscaGetFunctionType.GET_PROPERTY, propertyDataDefinition.getToscaGetFunctionType()); + + toscaGetFunction.setFunctionType(ToscaGetFunctionType.GET_ATTRIBUTE); + assertEquals(ToscaGetFunctionType.GET_ATTRIBUTE, propertyDataDefinition.getToscaGetFunctionType()); + + propertyDataDefinition = new PropertyDataDefinition(); + propertyDataDefinition.setToscaGetFunctionType(ToscaGetFunctionType.GET_INPUT); + assertEquals(ToscaGetFunctionType.GET_INPUT, propertyDataDefinition.getToscaGetFunctionType()); + + propertyDataDefinition.setToscaGetFunctionType(ToscaGetFunctionType.GET_PROPERTY); + assertEquals(ToscaGetFunctionType.GET_PROPERTY, propertyDataDefinition.getToscaGetFunctionType()); + + propertyDataDefinition.setToscaGetFunctionType(ToscaGetFunctionType.GET_ATTRIBUTE); + assertEquals(ToscaGetFunctionType.GET_ATTRIBUTE, propertyDataDefinition.getToscaGetFunctionType()); + } + + @Test + void isToscaFunctionTest() { + var propertyDataDefinition = new PropertyDataDefinition(); + assertFalse(propertyDataDefinition.isToscaFunction()); + + propertyDataDefinition.setToscaGetFunctionType(ToscaGetFunctionType.GET_PROPERTY); + assertTrue(propertyDataDefinition.isToscaFunction()); + + propertyDataDefinition = new PropertyDataDefinition(); + propertyDataDefinition.setToscaFunction(new ToscaConcatFunction()); + assertTrue(propertyDataDefinition.isToscaFunction()); + } + + @Test + void isToscaGetFunctionTest() { + var propertyDataDefinition = new PropertyDataDefinition(); + propertyDataDefinition.setToscaGetFunctionType(ToscaGetFunctionType.GET_PROPERTY); + assertTrue(propertyDataDefinition.isToscaGetFunction()); + + propertyDataDefinition = new PropertyDataDefinition(); + final ToscaGetFunctionDataDefinition toscaGetFunction = new ToscaGetFunctionDataDefinition(); + toscaGetFunction.setFunctionType(ToscaGetFunctionType.GET_INPUT); + propertyDataDefinition.setToscaFunction(toscaGetFunction); + assertTrue(propertyDataDefinition.isToscaGetFunction()); + + propertyDataDefinition.setToscaFunction(new ToscaConcatFunction()); + assertFalse(propertyDataDefinition.isToscaGetFunction()); + } + } diff --git a/common-be/src/test/java/org/openecomp/sdc/be/datatypes/elements/ToscaFunctionJsonDeserializerTest.java b/common-be/src/test/java/org/openecomp/sdc/be/datatypes/elements/ToscaFunctionJsonDeserializerTest.java new file mode 100644 index 0000000000..e11b661098 --- /dev/null +++ b/common-be/src/test/java/org/openecomp/sdc/be/datatypes/elements/ToscaFunctionJsonDeserializerTest.java @@ -0,0 +1,156 @@ +/* + * - + * ============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.datatypes.elements; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.exc.ValueInstantiationException; +import java.util.List; +import org.junit.jupiter.api.Test; +import org.openecomp.sdc.be.datatypes.enums.PropertySource; +import org.openecomp.sdc.be.datatypes.tosca.ToscaGetFunctionType; + +class ToscaFunctionJsonDeserializerTest { + + @Test + void testGetInputToscaFunction() throws JsonProcessingException { + final String toscaGetInputFunction = "{\n" + + " \"propertyUniqueId\": \"e57525d7-2115-4934-9ba4-9cebfa22bad2.nf_naming\",\n" + + " \"type\": \"GET_INPUT\",\n" + + " \"propertySource\": \"SELF\",\n" + + " \"propertyName\": \"instance_name\",\n" + + " \"sourceName\": \"ciResVFc26a0b30ec20\",\n" + + " \"sourceUniqueId\": \"aee643c9-6c8e-4a24-af7a-a9aff5c072c0\",\n" + + " \"propertyPathFromSource\": [\n" + + " \"nf_naming\",\n" + + " \"instance_name\"\n" + + " ]\n" + + " }"; + ToscaFunction toscaFunction = parseToscaFunction(toscaGetInputFunction); + assertTrue(toscaFunction instanceof ToscaGetFunctionDataDefinition); + final ToscaGetFunctionDataDefinition toscaGetFunction = (ToscaGetFunctionDataDefinition) toscaFunction; + assertEquals(ToscaFunctionType.GET_INPUT, toscaGetFunction.getType()); + assertEquals(ToscaGetFunctionType.GET_INPUT, toscaGetFunction.getFunctionType()); + assertEquals("e57525d7-2115-4934-9ba4-9cebfa22bad2.nf_naming", toscaGetFunction.getPropertyUniqueId()); + assertEquals(PropertySource.SELF, toscaGetFunction.getPropertySource()); + assertEquals("instance_name", toscaGetFunction.getPropertyName()); + assertEquals("ciResVFc26a0b30ec20", toscaGetFunction.getSourceName()); + assertEquals("aee643c9-6c8e-4a24-af7a-a9aff5c072c0", toscaGetFunction.getSourceUniqueId()); + assertEquals(List.of("nf_naming", "instance_name"), toscaGetFunction.getPropertyPathFromSource()); + } + + @Test + void testGetInputToscaFunctionLegacyConversion() throws JsonProcessingException { + final String toscaGetInputFunction = "{\n" + + " \"propertyUniqueId\": \"e57525d7-2115-4934-9ba4-9cebfa22bad2.nf_naming\",\n" + + " \"functionType\": \"GET_INPUT\",\n" + + " \"propertySource\": \"SELF\",\n" + + " \"propertyName\": \"instance_name\",\n" + + " \"sourceName\": \"ciResVFc26a0b30ec20\",\n" + + " \"sourceUniqueId\": \"aee643c9-6c8e-4a24-af7a-a9aff5c072c0\",\n" + + " \"propertyPathFromSource\": [\n" + + " \"nf_naming\",\n" + + " \"instance_name\"\n" + + " ]\n" + + " }"; + ToscaFunction toscaFunction = parseToscaFunction(toscaGetInputFunction); + assertTrue(toscaFunction instanceof ToscaGetFunctionDataDefinition); + final ToscaGetFunctionDataDefinition toscaGetFunction = (ToscaGetFunctionDataDefinition) toscaFunction; + assertEquals(ToscaFunctionType.GET_INPUT, toscaGetFunction.getType()); + assertEquals(ToscaGetFunctionType.GET_INPUT, toscaGetFunction.getFunctionType()); + } + + @Test + void testNoFunctionTypeProvided() { + final String toscaGetInputFunction = "{\n" + + " \"propertyUniqueId\": \"e57525d7-2115-4934-9ba4-9cebfa22bad2.nf_naming\",\n" + + " \"propertySource\": \"SELF\",\n" + + " \"propertyName\": \"instance_name\",\n" + + " \"sourceName\": \"ciResVFc26a0b30ec20\",\n" + + " \"sourceUniqueId\": \"aee643c9-6c8e-4a24-af7a-a9aff5c072c0\",\n" + + " \"propertyPathFromSource\": [\n" + + " \"nf_naming\",\n" + + " \"instance_name\"\n" + + " ]\n" + + " }"; + final ValueInstantiationException actualException = + assertThrows(ValueInstantiationException.class, () -> parseToscaFunction(toscaGetInputFunction)); + assertTrue(actualException.getMessage().contains("Attribute type not provided")); + } + + @Test + void testConcatToscaFunction() throws JsonProcessingException { + final String toscaGetInputFunction = "{\n" + + " \"type\": \"CONCAT\",\n" + + " \"parameters\": [\n" + + " {\n" + + " \"propertyUniqueId\": \"e57525d7-2115-4934-9ba4-9cebfa22bad2.nf_naming\",\n" + + " \"type\": \"GET_INPUT\",\n" + + " \"propertySource\": \"SELF\",\n" + + " \"propertyName\": \"instance_name\",\n" + + " \"sourceName\": \"ciResVFc26a0b30ec20\",\n" + + " \"sourceUniqueId\": \"aee643c9-6c8e-4a24-af7a-a9aff5c072c0\",\n" + + " \"propertyPathFromSource\": [\n" + + " \"nf_naming\",\n" + + " \"instance_name\"\n" + + " ]\n" + + " }, {\n" + + " \"type\": \"STRING\",\n" + + " \"value\": \"my string\"\n" + + " },\n" + + " {\n" + + " \"type\": \"CONCAT\",\n" + + " \"parameters\": [\n" + + " {\n" + + " \"type\": \"STRING\",\n" + + " \"value\": \"string1\"\n" + + " },\n" + + " {\n" + + " \"type\": \"STRING\",\n" + + " \"value\": \"string2\"\n" + + " }\n" + + " ]\n" + + " }\n" + + " ]\n" + + "}"; + ToscaFunction toscaFunction = parseToscaFunction(toscaGetInputFunction); + assertTrue(toscaFunction instanceof ToscaConcatFunction); + } + + @Test + void testYamlFunction() throws JsonProcessingException { + String yamlFunction = "{\n" + + " \"type\": \"YAML\",\n" + + " \"value\": \"tosca_definitions_version: tosca_simple_yaml_1_0_0\\nnode_types: \\n tosca.nodes.Compute:\\n derived_from: tosca.nodes.Root\\n attributes:\\n private_address:\\n type: string\\n public_address:\\n type: string\\n networks:\\n type: map\\n entry_schema:\\n type: tosca.datatypes.network.NetworkInfo\\n ports:\\n type: map\\n entry_schema:\\n type: tosca.datatypes.network.PortInfo\\n requirements:\\n - local_storage: \\n capability: tosca.capabilities.Attachment\\n node: tosca.nodes.BlockStorage\\n relationship: tosca.relationships.AttachesTo\\n occurrences: [0, UNBOUNDED] \\n capabilities:\\n host: \\n type: tosca.capabilities.Container\\n valid_source_types: [tosca.nodes.SoftwareComponent] \\n endpoint :\\n type: tosca.capabilities.Endpoint.Admin \\n os: \\n type: tosca.capabilities.OperatingSystem\\n scalable:\\n type: tosca.capabilities.Scalable\\n binding:\\n type: tosca.capabilities.network.Bindable\\n\"\n" + + "}"; + ToscaFunction toscaFunction = parseToscaFunction(yamlFunction); + assertTrue(toscaFunction instanceof CustomYamlFunction); + } + + private ToscaFunction parseToscaFunction(final String toscaFunctionJson) throws JsonProcessingException { + return new ObjectMapper().readValue(toscaFunctionJson, ToscaFunction.class); + } +}
\ No newline at end of file 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 a199f5ec97..5daeaa5aad 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 @@ -23,6 +23,7 @@ package org.openecomp.sdc.be.datatypes.elements; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -185,6 +186,18 @@ class ToscaGetFunctionDataDefinitionTest { assertEquals("sourceName is required in order to generate the get_property from INSTANCE value", actualException.getMessage()); } + @Test + void getTypeTest() { + final ToscaGetFunctionDataDefinition toscaGetFunctionDataDefinition = new ToscaGetFunctionDataDefinition(); + assertNull(toscaGetFunctionDataDefinition.getType()); + toscaGetFunctionDataDefinition.setFunctionType(ToscaGetFunctionType.GET_INPUT); + assertEquals(ToscaFunctionType.GET_INPUT, toscaGetFunctionDataDefinition.getType()); + toscaGetFunctionDataDefinition.setFunctionType(ToscaGetFunctionType.GET_ATTRIBUTE); + assertEquals(ToscaFunctionType.GET_ATTRIBUTE, toscaGetFunctionDataDefinition.getType()); + toscaGetFunctionDataDefinition.setFunctionType(ToscaGetFunctionType.GET_PROPERTY); + assertEquals(ToscaFunctionType.GET_PROPERTY, toscaGetFunctionDataDefinition.getType()); + } + private ToscaGetFunctionDataDefinition createGetFunction(final ToscaGetFunctionType toscaGetFunctionType, final PropertySource propertySource, final List<String> propertyPath, String sourceName) { |