From b43eb22f91ffdc1e2ba5d82b3dc1a2c4250d06e0 Mon Sep 17 00:00:00 2001 From: "andre.schmid" Date: Wed, 18 May 2022 22:09:25 +0100 Subject: Support of get_property in property assignment Refactors the current way store a get_input function allowing to support different get functions (get_property in this case). The information stored allows recreating and correctly validating the get function. Fix get function schema validation, the schema was being ignored. Improve validation error status and messages. Improve tosca get function dialog. Change-Id: I5de5f96dfba3c7a0fbb458885af5528bea7835aa Issue-ID: SDC-4014 Signed-off-by: andre.schmid --- .../datatypes/elements/PropertyDataDefinition.java | 22 +++ .../elements/ToscaGetFunctionDataDefinition.java | 104 +++++++++++ .../sdc/be/datatypes/enums/PropertySource.java | 34 ++++ .../be/datatypes/tosca/ToscaGetFunctionType.java | 11 +- .../ToscaGetFunctionDataDefinitionTest.java | 198 +++++++++++++++++++++ 5 files changed, 364 insertions(+), 5 deletions(-) create mode 100644 common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/ToscaGetFunctionDataDefinition.java create mode 100644 common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/PropertySource.java create mode 100644 common-be/src/test/java/org/openecomp/sdc/be/datatypes/elements/ToscaGetFunctionDataDefinitionTest.java (limited to 'common-be') 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 c885dbcc46..ff72f1f361 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 @@ -55,7 +55,12 @@ public class PropertyDataDefinition extends ToscaDataDefinition { private String label; private Boolean immutable = Boolean.FALSE; private Boolean mappedToComponentProperty = Boolean.TRUE; + /** + * @deprecated use {@link #toscaGetFunction#functionType} instead + */ + @Deprecated private ToscaGetFunctionType toscaGetFunctionType; + private ToscaGetFunctionDataDefinition toscaGetFunction; private String inputPath; private String status; @@ -114,6 +119,7 @@ public class PropertyDataDefinition extends ToscaDataDefinition { this.setModel(propertyDataDefinition.getModel()); this.setPropertyId(propertyDataDefinition.getPropertyId()); this.setToscaGetFunctionType(propertyDataDefinition.getToscaGetFunctionType()); + this.setToscaGetFunction(propertyDataDefinition.getToscaGetFunction()); this.parentPropertyType = propertyDataDefinition.getParentPropertyType(); this.subPropertyInputPath = propertyDataDefinition.getSubPropertyInputPath(); if (isNotEmpty(propertyDataDefinition.annotations)) { @@ -161,6 +167,13 @@ public class PropertyDataDefinition extends ToscaDataDefinition { return null; } + public ToscaGetFunctionType getToscaGetFunctionType() { + if (toscaGetFunction != null) { + return toscaGetFunction.getFunctionType(); + } + return toscaGetFunctionType; + } + public Boolean isHidden() { return hidden; } @@ -303,4 +316,13 @@ public class PropertyDataDefinition extends ToscaDataDefinition { public List getAnnotations() { return (List) getToscaPresentationValue(JsonPresentationFields.ANNOTATIONS); } + + public boolean isGetFunction() { + return this.toscaGetFunctionType != null || this.toscaGetFunction != null; + } + + public boolean hasGetFunction() { + return this.toscaGetFunction != null; + } + } 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 new file mode 100644 index 0000000000..adc2ad6b44 --- /dev/null +++ b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/ToscaGetFunctionDataDefinition.java @@ -0,0 +1,104 @@ +/* + * - + * ============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 java.util.stream.Stream; +import lombok.Data; +import org.apache.commons.collections4.CollectionUtils; +import org.openecomp.sdc.be.datatypes.enums.PropertySource; +import org.openecomp.sdc.be.datatypes.tosca.ToscaGetFunctionType; + +@Data +public class ToscaGetFunctionDataDefinition { + + private String propertyUniqueId; + private String propertyName; + private PropertySource propertySource; + private String sourceUniqueId; + private String sourceName; + private ToscaGetFunctionType functionType; + private List propertyPathFromSource = new ArrayList<>(); + + public ToscaGetFunctionDataDefinition() { + //necessary for JSON conversions + } + + public boolean isSubProperty() { + return propertyPathFromSource != null && propertyPathFromSource.size() > 1; + } + + /** + * Builds the value of a property based on the TOSCA get function information. + */ + public String generatePropertyValue() { + if (functionType == null) { + throw new IllegalStateException("functionType is required in order to generate the get function value"); + } + if (CollectionUtils.isEmpty(propertyPathFromSource)) { + throw new IllegalStateException("propertyPathFromSource is required in order to generate the get function value"); + } + + final var gson = new Gson(); + if (functionType == ToscaGetFunctionType.GET_PROPERTY) { + return gson.toJson(buildGetPropertyFunctionValue()); + } + if (functionType == ToscaGetFunctionType.GET_INPUT) { + return gson.toJson(buildGetInputFunctionValue()); + } + + throw new UnsupportedOperationException(String.format("ToscaGetFunctionType '%s' is not supported yet", functionType)); + } + + private Map buildGetPropertyFunctionValue() { + if (propertySource == null) { + throw new IllegalStateException("propertySource is required in order to generate the get_property value"); + } + if (propertySource == PropertySource.SELF) { + return Map.of(functionType.getFunctionName(), + Stream.concat(Stream.of(PropertySource.SELF.getName()), propertyPathFromSource.stream()).collect(Collectors.toList()) + ); + } + if (propertySource == PropertySource.INSTANCE) { + if (sourceName == null) { + throw new IllegalStateException("sourceName is required in order to generate the get_property from INSTANCE value"); + } + return Map.of(functionType.getFunctionName(), + Stream.concat(Stream.of(sourceName), propertyPathFromSource.stream()).collect(Collectors.toList()) + ); + } + + throw new UnsupportedOperationException(String.format("Tosca property source '%s' not supported", propertySource)); + } + + private Map buildGetInputFunctionValue() { + if (this.propertyPathFromSource.size() == 1) { + return Map.of(this.functionType.getFunctionName(), this.propertyPathFromSource.get(0)); + } + return Map.of(this.functionType.getFunctionName(), this.propertyPathFromSource); + } + +} 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 new file mode 100644 index 0000000000..8086d22815 --- /dev/null +++ b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/PropertySource.java @@ -0,0 +1,34 @@ +/* + * - + * ============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.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@AllArgsConstructor +@Getter +public enum PropertySource { + SELF("SELF"), INSTANCE("INSTANCE"); + + private final String name; + +} 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 7e4299c73a..bb85ceb0fc 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 @@ -23,11 +23,12 @@ import lombok.AllArgsConstructor; import lombok.Getter; @AllArgsConstructor +@Getter public enum ToscaGetFunctionType { - GET_INPUT("get_input"), - GET_PROPERTY("get_property"), - GET_ATTRIBUTE("get_attribute"); + GET_INPUT("get_input", "input"), + GET_PROPERTY("get_property", "property"), + GET_ATTRIBUTE("get_attribute", "attribute"); - @Getter - private final String toscaGetFunctionName; + private final String functionName; + private final String propertyType; } 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 new file mode 100644 index 0000000000..1c4a678010 --- /dev/null +++ b/common-be/src/test/java/org/openecomp/sdc/be/datatypes/elements/ToscaGetFunctionDataDefinitionTest.java @@ -0,0 +1,198 @@ +/* + * - + * ============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.*; + +import com.google.gson.Gson; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.junit.jupiter.api.Test; +import org.openecomp.sdc.be.datatypes.enums.PropertySource; +import org.openecomp.sdc.be.datatypes.tosca.ToscaGetFunctionType; + +class ToscaGetFunctionDataDefinitionTest { + + @Test + void isSubPropertyTest() { + final var toscaGetFunction = new ToscaGetFunctionDataDefinition(); + assertFalse(toscaGetFunction.isSubProperty()); + toscaGetFunction.setPropertyPathFromSource(List.of("property1")); + assertFalse(toscaGetFunction.isSubProperty()); + toscaGetFunction.setPropertyPathFromSource(List.of("property1", "subProperty1")); + assertTrue(toscaGetFunction.isSubProperty()); + } + + @Test + void generateGetInputSinglePropertyValueTest() { + //given + final String propertyName = "property"; + final var toscaGetFunction = createGetFunction(ToscaGetFunctionType.GET_INPUT, null, List.of(propertyName), null); + //when + final String actualValue = toscaGetFunction.generatePropertyValue(); + //then + final Map getInputJsonAsMap = convertJsonStringToMap(actualValue); + assertTrue(getInputJsonAsMap.containsKey(ToscaGetFunctionType.GET_INPUT.getFunctionName())); + final Object value = getInputJsonAsMap.get(ToscaGetFunctionType.GET_INPUT.getFunctionName()); + assertTrue(value instanceof String); + assertEquals(value, propertyName); + } + + @Test + void generateGetInputMultiplePropertyValueTest() { + //given + final var toscaGetFunction = createGetFunction( + ToscaGetFunctionType.GET_INPUT, + null, + List.of("property", "subProperty", "subSubProperty"), + null + ); + //when + final String actualValue = toscaGetFunction.generatePropertyValue(); + //then + final Map getInputJsonAsMap = convertJsonStringToMap(actualValue); + assertTrue(getInputJsonAsMap.containsKey(ToscaGetFunctionType.GET_INPUT.getFunctionName())); + final Object value = getInputJsonAsMap.get(ToscaGetFunctionType.GET_INPUT.getFunctionName()); + assertTrue(value instanceof List); + assertEquals(value, toscaGetFunction.getPropertyPathFromSource()); + } + + @Test + void generateValueForGetPropertyFromSelfTest() { + //given + final ToscaGetFunctionType toscaFunction = ToscaGetFunctionType.GET_PROPERTY; + final var toscaGetFunction = createGetFunction(toscaFunction, PropertySource.SELF, List.of("property"), null); + //when + String actualValue = toscaGetFunction.generatePropertyValue(); + //then + Map getInputJsonAsMap = convertJsonStringToMap(actualValue); + assertTrue(getInputJsonAsMap.containsKey(toscaFunction.getFunctionName())); + Object actualGetPropertyValue = getInputJsonAsMap.get(toscaFunction.getFunctionName()); + List expectedGetPropertyValue = Stream.concat( + Stream.of(PropertySource.SELF.getName()), + toscaGetFunction.getPropertyPathFromSource().stream()) + .collect(Collectors.toList()); + assertEquals(expectedGetPropertyValue, actualGetPropertyValue); + + //given a sub property path + toscaGetFunction.setPropertyPathFromSource(List.of("property", "subProperty", "subSubProperty")); + //when + actualValue = toscaGetFunction.generatePropertyValue(); + //then + getInputJsonAsMap = convertJsonStringToMap(actualValue); + assertTrue(getInputJsonAsMap.containsKey(toscaFunction.getFunctionName())); + actualGetPropertyValue = getInputJsonAsMap.get(toscaFunction.getFunctionName()); + expectedGetPropertyValue = Stream.concat( + Stream.of(PropertySource.SELF.getName()), + toscaGetFunction.getPropertyPathFromSource().stream()) + .collect(Collectors.toList()); + assertEquals(expectedGetPropertyValue, actualGetPropertyValue); + } + + @Test + void generateValueForGetPropertyFromInstanceTest() { + //given + final ToscaGetFunctionType toscaFunction = ToscaGetFunctionType.GET_PROPERTY; + final var toscaGetFunction = createGetFunction(toscaFunction, PropertySource.INSTANCE, List.of("property"), "sourceName"); + //when + String actualValue = toscaGetFunction.generatePropertyValue(); + //then + Map getInputJsonAsMap = convertJsonStringToMap(actualValue); + assertTrue(getInputJsonAsMap.containsKey(toscaFunction.getFunctionName())); + Object actualGetPropertyValue = getInputJsonAsMap.get(toscaFunction.getFunctionName()); + List expectedGetPropertyValue = Stream.concat( + Stream.of(toscaGetFunction.getSourceName()), + toscaGetFunction.getPropertyPathFromSource().stream()) + .collect(Collectors.toList()); + assertEquals(expectedGetPropertyValue, actualGetPropertyValue); + + //given a sub property path + toscaGetFunction.setPropertyPathFromSource(List.of("property", "subProperty", "subSubProperty")); + //when + actualValue = toscaGetFunction.generatePropertyValue(); + //then + getInputJsonAsMap = convertJsonStringToMap(actualValue); + assertTrue(getInputJsonAsMap.containsKey(toscaFunction.getFunctionName())); + actualGetPropertyValue = getInputJsonAsMap.get(toscaFunction.getFunctionName()); + expectedGetPropertyValue = Stream.concat( + Stream.of(toscaGetFunction.getSourceName()), + toscaGetFunction.getPropertyPathFromSource().stream()) + .collect(Collectors.toList()); + assertEquals(expectedGetPropertyValue, actualGetPropertyValue); + } + + @Test + void generateValueFunctionTypeIsRequiredTest() { + final var toscaGetFunction = createGetFunction(null, null, List.of("property"), null); + toscaGetFunction.setPropertyPathFromSource(List.of("property")); + final IllegalStateException actualException = assertThrows(IllegalStateException.class, toscaGetFunction::generatePropertyValue); + assertEquals("functionType is required in order to generate the get function value", actualException.getMessage()); + } + + @Test + void generateValuePropertyPathIsRequiredTest() { + final var toscaGetFunction = createGetFunction(ToscaGetFunctionType.GET_INPUT, null, null, null); + final IllegalStateException actualException = assertThrows(IllegalStateException.class, toscaGetFunction::generatePropertyValue); + assertEquals("propertyPathFromSource is required in order to generate the get function value", actualException.getMessage()); + } + + @Test + void generateValuePropertySourceIsRequiredForGetPropertyTest() { + final var toscaGetFunction = createGetFunction( + ToscaGetFunctionType.GET_PROPERTY, + null, + List.of("property"), + null); + final IllegalStateException actualException = assertThrows(IllegalStateException.class, toscaGetFunction::generatePropertyValue); + assertEquals("propertySource is required in order to generate the get_property value", actualException.getMessage()); + } + + @Test + void generateValueSourceNameIsRequiredForGetInstancePropertyTest() { + final ToscaGetFunctionDataDefinition toscaGetFunction = createGetFunction( + ToscaGetFunctionType.GET_PROPERTY, + PropertySource.INSTANCE, + List.of("property"), + null); + final IllegalStateException actualException = assertThrows(IllegalStateException.class, toscaGetFunction::generatePropertyValue); + + assertEquals("sourceName is required in order to generate the get_property from INSTANCE value", actualException.getMessage()); + } + + private ToscaGetFunctionDataDefinition createGetFunction(final ToscaGetFunctionType toscaGetFunctionType, + final PropertySource propertySource, + final List propertyPath, String sourceName) { + final var toscaGetFunction = new ToscaGetFunctionDataDefinition(); + toscaGetFunction.setFunctionType(toscaGetFunctionType); + toscaGetFunction.setPropertySource(propertySource); + toscaGetFunction.setPropertyPathFromSource(propertyPath); + toscaGetFunction.setSourceName(sourceName); + return toscaGetFunction; + } + + private Map convertJsonStringToMap(final String actualValue) { + final Gson gson = new Gson(); + return gson.fromJson(actualValue, Map.class); + } +} \ No newline at end of file -- cgit 1.2.3-korg