# %1 - "Model name"
DATA_TYPES_NOT_LOADED: {
code: 500,
- message: "Error: Could not fetch data types from data base with model %1",
+ message: "Could not fetch data types from data base with model %1",
messageId: "SVC4153"
}
messageId: "SVC4164"
}
+ #---------SVC4165-----------------------------
+ # %1 - input origin
+ TOSCA_GET_FUNCTION_INPUTS_ONLY_SELF_ERROR: {
+ code: 400,
+ message: "Invalid get_input definition. Inputs can only be get from SELF, the given origin was '%1'",
+ messageId: "SVC4165"
+ }
+
+ #---------SVC4166-----------------------------
+ # %1 - input name
+ # %2 - input origin
+ TOSCA_GET_FUNCTION_INPUTS_NOT_FOUND: {
+ code: 404,
+ message: "The given input '%1' was not found on '%2'.",
+ messageId: "SVC4166"
+ }
+
+ #---------SVC4167-----------------------------
+ # %1 - Tosca function
+ # %2 - Referred input type
+ # %3 - Selected property type
+ TOSCA_GET_FUNCTION_TYPE_DIVERGE: {
+ code: 400,
+ message: "Could not set %1. Referred input type '%2' diverges from the selected property type '%3'.",
+ messageId: "SVC4167"
+ }
+
+ #---------SVC4168-----------------------------
+ # %1 - Tosca function
+ # %2 - Referred input schema
+ # %3 - Selected property schema
+ TOSCA_GET_FUNCTION_SCHEMA_DIVERGE: {
+ code: 400,
+ message: "Could not set %1. Referred input schema '%2' diverges from the selected property schema '%3'.",
+ messageId: "SVC4168"
+ }
+
+ #---------SVC4169-----------------------------
+ # %1 - Property type (property|input|attribute)
+ # %1 - Property name
+ # %2 - Property origin
+ TOSCA_GET_FUNCTION_PROPERTY_NOT_FOUND: {
+ code: 404,
+ message: "The given %1 '%2' was not found on '%3'.",
+ messageId: "SVC4169"
+ }
+
+ #---------SVC4170-----------------------------
+ # %1 - Property type (property|input|attribute)
+ # %2 - Property name/path
+ # %3 - Property data type
+ TOSCA_GET_FUNCTION_PROPERTY_DATA_TYPE_NOT_FOUND: {
+ code: 404,
+ message: "The %1 '%2' type '%3' was not found.",
+ messageId: "SVC4170"
+ }
+
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.onap.sdc.tosca.datatypes.model.PropertyType;
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.ToscaGetFunctionExceptionSupplier;
import org.openecomp.sdc.be.components.impl.instance.ComponentInstanceChangeOperationOrchestrator;
import org.openecomp.sdc.be.components.impl.utils.DirectivesUtil;
import org.openecomp.sdc.be.components.merge.instance.ComponentInstanceMergeDataBusinessLogic;
import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
import org.openecomp.sdc.be.datatypes.elements.RequirementDataDefinition;
import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition;
+import org.openecomp.sdc.be.datatypes.elements.ToscaGetFunctionDataDefinition;
import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
+import org.openecomp.sdc.be.datatypes.enums.PropertySource;
import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
import org.openecomp.sdc.be.datatypes.tosca.ToscaGetFunctionType;
import org.openecomp.sdc.be.exception.BusinessException;
private static final String RESTRICTED_OPERATION_ON_COMPONENT = "Restricted operation for user: {} on component {}";
private static final String RESOURCE_INSTANCE = "resource instance";
private static final String SERVICE = "service";
- private static final String UPDATE_PROPERTY_CONTEXT = "UpdatePropertyValueOnComponentInstance";
-
- private ComponentInstanceOperation componentInstanceOperation;
- private ArtifactsBusinessLogic artifactBusinessLogic;
- private ComponentInstanceMergeDataBusinessLogic compInstMergeDataBL;
- private ComponentInstanceChangeOperationOrchestrator onChangeInstanceOperationOrchestrator;
- private ForwardingPathOperation forwardingPathOperation;
- private NodeFilterOperation nodeFilterOperation;
+
+ private final ComponentInstanceOperation componentInstanceOperation;
+ private final ArtifactsBusinessLogic artifactBusinessLogic;
+ private final ComponentInstanceMergeDataBusinessLogic compInstMergeDataBL;
+ private final ComponentInstanceChangeOperationOrchestrator onChangeInstanceOperationOrchestrator;
+ private final ForwardingPathOperation forwardingPathOperation;
+ private final NodeFilterOperation nodeFilterOperation;
@Autowired
private CompositionBusinessLogic compositionBusinessLogic;
@Autowired
ComponentInstanceProperty componentInstanceProperty = validatePropertyExistsOnComponent(property, containerComponent,
foundResourceInstance);
String propertyParentUniqueId = property.getParentUniqueId();
- Either<String, ResponseFormat> updatedPropertyValue = updatePropertyObjectValue(property, false, containerComponent.getModel());
+ if (property.isGetFunction()) {
+ validateToscaGetFunction(property, containerComponent);
+ property.setValue(property.getToscaGetFunction().generatePropertyValue());
+ }
+ Either<String, ResponseFormat> updatedPropertyValue = updatePropertyObjectValue(property, containerComponent.getModel());
if (updatedPropertyValue.isRight()) {
log.error("Failed to update property object value of property: {}",
property);
.get(foundResourceInstance.getUniqueId());
Optional<ComponentInstanceProperty> instanceProperty = instanceProperties.stream().filter(p -> p.getName().equals(property.getName()))
.findAny();
- if (!instanceProperty.isPresent()) {
+ if (instanceProperty.isEmpty()) {
throw new ByActionStatusComponentException(ActionStatus.PROPERTY_NOT_FOUND, property.getName());
}
return instanceProperty.get();
return false;
}
- private <T extends PropertyDefinition> Either<String, ResponseFormat> updatePropertyObjectValue(T property, boolean isInput, final String model) {
+ private <T extends PropertyDefinition> Either<String, ResponseFormat> updatePropertyObjectValue(T property, final String model) {
final Map<String, DataTypeDefinition> allDataTypes = componentsUtils.getAllDataTypes(applicationDataTypeCache, model);
String innerType = null;
String propertyType = property.getType();
log.debug("The type of the property {} is {}", property.getUniqueId(), propertyType);
if (type == ToscaPropertyType.LIST || type == ToscaPropertyType.MAP) {
- SchemaDefinition def = property.getSchema();
- if (def == null) {
+ SchemaDefinition schema = property.getSchema();
+ if (schema == null) {
log.debug("Schema doesn't exists for property of type {}", type);
return Either
.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(StorageOperationStatus.INVALID_VALUE)));
}
- PropertyDataDefinition propDef = def.getProperty();
+ PropertyDataDefinition propDef = schema.getProperty();
if (propDef == null) {
log.debug("Property in Schema Definition inside property of type {} doesn't exist", type);
return Either
// Specific Update Logic
String newValue = property.getValue();
- if (property.getToscaGetFunctionType() != null) {
- validateToscaGetFunction(property);
+ if (property.hasGetFunction()) {
return Either.left(newValue);
}
newValue = object.toString();
}
}
- if (!isInput) {
- ImmutablePair<String, Boolean> pair = propertyOperation
- .validateAndUpdateRules(propertyType, ((ComponentInstanceProperty) property).getRules(), innerType, allDataTypes, true);
- if (pair.getRight() != null && Boolean.FALSE.equals(pair.getRight())) {
- BeEcompErrorManager.getInstance().logBeInvalidValueError("Add property value", pair.getLeft(), property.getName(), propertyType);
- return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(
- DaoStatusConverter.convertJanusGraphStatusToStorageStatus(JanusGraphOperationStatus.ILLEGAL_ARGUMENT))));
- }
+ ImmutablePair<String, Boolean> pair = propertyOperation
+ .validateAndUpdateRules(propertyType, ((ComponentInstanceProperty) property).getRules(), innerType, allDataTypes, true);
+ if (pair.getRight() != null && Boolean.FALSE.equals(pair.getRight())) {
+ BeEcompErrorManager.getInstance().logBeInvalidValueError("Add property value", pair.getLeft(), property.getName(), propertyType);
+ return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(
+ DaoStatusConverter.convertJanusGraphStatusToStorageStatus(JanusGraphOperationStatus.ILLEGAL_ARGUMENT))));
}
return Either.left(newValue);
}
return Either.left(newValue);
}
- private <T extends PropertyDefinition> void validateToscaGetFunction(T property) {
- if (property.getToscaGetFunctionType() == ToscaGetFunctionType.GET_INPUT) {
- final List<GetInputValueDataDefinition> getInputValues = property.getGetInputValues();
- if (CollectionUtils.isEmpty(getInputValues)) {
- log.debug("No input information provided. Cannot set get_input.");
- throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
- }
- if (getInputValues.size() > 1) {
- log.debug("More than one input provided. Cannot set get_input.");
- throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
- }
- final GetInputValueDataDefinition getInputValueDataDefinition = getInputValues.get(0);
+ private <T extends PropertyDefinition> void validateToscaGetFunction(T property, Component parentComponent) {
+ final ToscaGetFunctionDataDefinition toscaGetFunction = property.getToscaGetFunction();
+ if (toscaGetFunction.getFunctionType() == ToscaGetFunctionType.GET_INPUT) {
+ validateGetFunction(property, parentComponent.getInputs(), parentComponent.getModel());
+ return;
+ }
+ if (toscaGetFunction.getFunctionType() == ToscaGetFunctionType.GET_PROPERTY) {
+ validateGetFunction(property, parentComponent.getProperties(), parentComponent.getModel());
+ return;
+ }
- if (!property.getType().equals(getInputValueDataDefinition.getInputType())) {
- log.debug("Input type '{}' diverges from the property type '{}'. Cannot set get_input.",
- getInputValueDataDefinition.getInputType(), property.getType());
- throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
+ throw ToscaGetFunctionExceptionSupplier.functionNotSupported(toscaGetFunction.getFunctionType()).get();
+ }
+
+ private <T extends PropertyDefinition, U extends PropertyDefinition> void validateGetFunction(final T property,
+ final List<U> parentProperties,
+ final String model) {
+ final ToscaGetFunctionDataDefinition toscaGetFunction = property.getToscaGetFunction();
+ if (CollectionUtils.isEmpty(parentProperties)) {
+ throw ToscaGetFunctionExceptionSupplier
+ .propertyNotFoundOnTarget(toscaGetFunction.getPropertyName(), toscaGetFunction.getPropertySource(),
+ toscaGetFunction.getFunctionType()
+ ).get();
+ }
+ validateGetPropertySource(toscaGetFunction.getFunctionType(), toscaGetFunction.getPropertySource());
+ final String getFunctionPropertyUniqueId = toscaGetFunction.getPropertyUniqueId();
+ T referredProperty = (T) parentProperties.stream()
+ .filter(property1 -> getFunctionPropertyUniqueId.equals(property1.getUniqueId()))
+ .findFirst()
+ .orElseThrow(ToscaGetFunctionExceptionSupplier
+ .propertyNotFoundOnTarget(toscaGetFunction.getPropertyName(), toscaGetFunction.getPropertySource()
+ , toscaGetFunction.getFunctionType())
+ );
+ if (toscaGetFunction.isSubProperty()) {
+ referredProperty = findSubProperty(referredProperty, toscaGetFunction, model);
+ }
+
+ if (!property.getType().equals(referredProperty.getType())) {
+ throw ToscaGetFunctionExceptionSupplier
+ .propertyTypeDiverge(toscaGetFunction.getFunctionType(), 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();
+ }
+ }
+
+ private <T extends PropertyDefinition> T findSubProperty(final T referredProperty, final ToscaGetFunctionDataDefinition toscaGetFunction,
+ final String model) {
+ final Map<String, DataTypeDefinition> dataTypeMap = loadDataTypes(model);
+ final List<String> propertyPathFromSource = toscaGetFunction.getPropertyPathFromSource();
+ DataTypeDefinition dataType = dataTypeMap.get(referredProperty.getType());
+ if (dataType == null) {
+ throw ToscaGetFunctionExceptionSupplier
+ .propertyDataTypeNotFound(propertyPathFromSource.get(0), referredProperty.getType(), toscaGetFunction.getFunctionType()).get();
+ }
+ T foundProperty = referredProperty;
+ for (int i = 1; i < propertyPathFromSource.size(); i++) {
+ final String currentPropertyName = propertyPathFromSource.get(i);
+ foundProperty = (T) dataType.getProperties().stream()
+ .filter(propertyDefinition -> currentPropertyName.equals(propertyDefinition.getName())).findFirst()
+ .orElseThrow(
+ ToscaGetFunctionExceptionSupplier
+ .propertyNotFoundOnTarget(propertyPathFromSource.subList(0, i), toscaGetFunction.getPropertySource(),
+ toscaGetFunction.getFunctionType())
+ );
+ dataType = dataTypeMap.get(foundProperty.getType());
+ if (dataType == null) {
+ throw ToscaGetFunctionExceptionSupplier
+ .propertyDataTypeNotFound(propertyPathFromSource.subList(0, i), foundProperty.getType(),
+ toscaGetFunction.getFunctionType()).get();
}
- return;
}
+ return foundProperty;
+ }
+
+ private Map<String, DataTypeDefinition> loadDataTypes(String model) {
+ final Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> dataTypeEither =
+ applicationDataTypeCache.getAll(model);
+ if (dataTypeEither.isRight()) {
+ throw ToscaGetFunctionExceptionSupplier.couldNotLoadDataTypes(model).get();
+ }
+ return dataTypeEither.left().value();
+ }
- throw new ByActionStatusComponentException(ActionStatus.NOT_SUPPORTED,
- "Tosca function " + property.getToscaGetFunctionType().getToscaGetFunctionName());
+ private void validateGetPropertySource(final ToscaGetFunctionType functionType, final PropertySource propertySource) {
+ if (propertySource != PropertySource.SELF) {
+ throw ToscaGetFunctionExceptionSupplier
+ .targetSourceNotSupported(functionType, propertySource).get();
+ }
}
private ResponseFormat updateInputOnContainerComponent(ComponentInstanceInput input, String newValue, Component containerComponent,
return ComponentValidations.validateNameIsUniqueInComponent(oldComponentInstance.getName(), newInstanceName, containerComponent);
}
- private Either<ComponentInstance, StorageOperationStatus> getResourceInstanceById(Component containerComponent, String instanceId) {
- Either<ComponentInstance, StorageOperationStatus> result = Either.right(StorageOperationStatus.NOT_FOUND);
- List<ComponentInstance> instances = containerComponent.getComponentInstances();
- Optional<ComponentInstance> foundInstance = Optional.empty();
- if (!CollectionUtils.isEmpty(instances)) {
- if (result.isRight()) {
- foundInstance = instances.stream().filter(i -> i.getUniqueId().equals(instanceId)).findFirst();
- if (!foundInstance.isPresent()) {
- result = Either.right(StorageOperationStatus.NOT_FOUND);
- }
- }
- if (result.isRight() && foundInstance.isPresent()) {
- result = Either.left(foundInstance.get());
- }
+ private Either<ComponentInstance, StorageOperationStatus> getResourceInstanceById(final Component containerComponent, final String instanceId) {
+ final List<ComponentInstance> instances = containerComponent.getComponentInstances();
+ if (CollectionUtils.isEmpty(instances)) {
+ return Either.right(StorageOperationStatus.NOT_FOUND);
}
- return result;
+
+ final Optional<ComponentInstance> foundInstance = instances.stream().filter(i -> i.getUniqueId().equals(instanceId)).findFirst();
+ if (foundInstance.isEmpty()) {
+ return Either.right(StorageOperationStatus.NOT_FOUND);
+ }
+
+ return Either.left(foundInstance.get());
}
private ComponentInstance buildComponentInstance(ComponentInstance resourceInstanceForUpdate, ComponentInstance origInstanceForUpdate) {
final User user = userValidations.validateUserExists(userId);
userValidations.validateUserRole(user, Arrays.asList(Role.DESIGNER, Role.ADMIN));
}
+
+ public void setCompositionBusinessLogic(CompositionBusinessLogic compositionBusinessLogic) {
+ this.compositionBusinessLogic = compositionBusinessLogic;
+ }
+
+ public void setContainerInstanceTypesData(ContainerInstanceTypesData containerInstanceTypesData) {
+ this.containerInstanceTypesData = containerInstanceTypesData;
+ }
+
}
--- /dev/null
+/*
+ * -
+ * ============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.List;
+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.enums.PropertySource;
+import org.openecomp.sdc.be.datatypes.tosca.ToscaGetFunctionType;
+
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public class ToscaGetFunctionExceptionSupplier {
+
+ public static Supplier<ByActionStatusComponentException> targetSourceNotSupported(final ToscaGetFunctionType toscaGetFunctionType,
+ final PropertySource propertySource) {
+ 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) {
+ return propertyNotFoundOnTarget(List.of(propertyName), propertySource, functionType);
+ }
+
+ public static Supplier<ByActionStatusComponentException> propertyNotFoundOnTarget(final List<String> propertyPathFromSource,
+ final PropertySource propertySource,
+ final ToscaGetFunctionType functionType) {
+ return () -> new ByActionStatusComponentException(ActionStatus.TOSCA_GET_FUNCTION_PROPERTY_NOT_FOUND, functionType.getPropertyType(),
+ String.join("->", propertyPathFromSource), propertySource.getName());
+ }
+
+ public static Supplier<ByActionStatusComponentException> propertyDataTypeNotFound(final String propertyName,
+ final String dataType,
+ final ToscaGetFunctionType functionType) {
+ return propertyDataTypeNotFound(List.of(propertyName), dataType, functionType);
+ }
+
+ public static Supplier<ByActionStatusComponentException> propertyDataTypeNotFound(final List<String> propertyPathFromSource,
+ final String dataType,
+ final ToscaGetFunctionType functionType) {
+ return () -> new ByActionStatusComponentException(
+ ActionStatus.TOSCA_GET_FUNCTION_PROPERTY_DATA_TYPE_NOT_FOUND,
+ functionType.getPropertyType(), String.join("->", propertyPathFromSource), dataType
+ );
+ }
+
+ public static Supplier<ByActionStatusComponentException> couldNotLoadDataTypes(final String model) {
+ return () -> new ByActionStatusComponentException(ActionStatus.DATA_TYPES_NOT_LOADED, model);
+ }
+
+ public static Supplier<ByActionStatusComponentException> functionNotSupported(final ToscaGetFunctionType functionType) {
+ return () -> new ByActionStatusComponentException(ActionStatus.NOT_SUPPORTED, "Tosca function " + functionType.getFunctionName());
+ }
+
+ public static Supplier<ByActionStatusComponentException> propertyTypeDiverge(final ToscaGetFunctionType functionType,
+ final String referredPropertyType,
+ final String propertyType) {
+ return () -> new ByActionStatusComponentException(
+ ActionStatus.TOSCA_GET_FUNCTION_TYPE_DIVERGE,
+ functionType.getFunctionName(), referredPropertyType, propertyType
+ );
+ }
+
+ public static Supplier<ByActionStatusComponentException> propertySchemaDiverge(final ToscaGetFunctionType functionType,
+ final String referredPropertySchemaType,
+ final String propertySchemaType) {
+ return () -> new ByActionStatusComponentException(
+ ActionStatus.TOSCA_GET_FUNCTION_SCHEMA_DIVERGE,
+ functionType.getFunctionName(), referredPropertySchemaType, propertySchemaType
+ );
+ }
+}
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Map.Entry;
import java.util.Optional;
import java.util.Set;
import mockit.Deencapsulation;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
import org.assertj.core.util.Lists;
+import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DynamicTest;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestFactory;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
-import org.mockito.junit.jupiter.MockitoExtension;
-import org.mockito.junit.jupiter.MockitoSettings;
-import org.mockito.quality.Strictness;
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.ToscaGetFunctionExceptionSupplier;
import org.openecomp.sdc.be.components.validation.UserValidations;
import org.openecomp.sdc.be.config.ConfigurationManager;
import org.openecomp.sdc.be.dao.api.ActionStatus;
-import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
import org.openecomp.sdc.be.dao.janusgraph.JanusGraphDao;
+import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
import org.openecomp.sdc.be.datatypes.elements.CapabilityDataDefinition;
import org.openecomp.sdc.be.datatypes.elements.ForwardingPathDataDefinition;
import org.openecomp.sdc.be.datatypes.elements.GetPolicyValueDataDefinition;
import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition;
import org.openecomp.sdc.be.datatypes.elements.RequirementDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition;
+import org.openecomp.sdc.be.datatypes.elements.ToscaGetFunctionDataDefinition;
import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
+import org.openecomp.sdc.be.datatypes.enums.PropertySource;
import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
+import org.openecomp.sdc.be.datatypes.tosca.ToscaGetFunctionType;
import org.openecomp.sdc.be.exception.BusinessException;
import org.openecomp.sdc.be.impl.ComponentsUtils;
import org.openecomp.sdc.be.model.ArtifactDefinition;
import org.openecomp.sdc.be.model.InputDefinition;
import org.openecomp.sdc.be.model.LifecycleStateEnum;
import org.openecomp.sdc.be.model.PolicyDefinition;
+import org.openecomp.sdc.be.model.PropertyDefinition;
import org.openecomp.sdc.be.model.RelationshipImpl;
import org.openecomp.sdc.be.model.RelationshipInfo;
import org.openecomp.sdc.be.model.RequirementCapabilityRelDef;
/**
* The test suite designed for test functionality of ComponentInstanceBusinessLogic class
*/
-
-@ExtendWith(MockitoExtension.class)
-@MockitoSettings(strictness = Strictness.LENIENT)
class ComponentInstanceBusinessLogicTest {
private final static String USER_ID = "jh0003";
private final static String INPUT_ID = "inputId";
private final static String ICON_NAME = "icon";
- private static ConfigurationSource configurationSource = new FSConfigurationSource(
- ExternalConfiguration.getChangeListener(),
- "src/test/resources/config/catalog-be");
- private static ConfigurationManager configurationManager = new ConfigurationManager(configurationSource);
-
- @InjectMocks
- private static ComponentInstanceBusinessLogic componentInstanceBusinessLogic;
+ private ComponentInstanceBusinessLogic componentInstanceBusinessLogic;
@Mock
private ComponentInstancePropInput componentInstancePropInput;
@Mock
private List<ComponentInstanceProperty> ciPropertyList;
private List<ComponentInstanceInput> ciInputList;
+ @BeforeAll
+ static void beforeAll() {
+ initConfig();
+ }
+
+ private static void initConfig() {
+ final ConfigurationSource configurationSource = new FSConfigurationSource(
+ ExternalConfiguration.getChangeListener(),
+ "src/test/resources/config/catalog-be"
+ );
+ new ConfigurationManager(configurationSource);
+ }
+
@BeforeEach
void init() {
MockitoAnnotations.openMocks(this);
+ componentInstanceBusinessLogic = new ComponentInstanceBusinessLogic(null, null, null, null, null, null, null, artifactsBusinessLogic, null,
+ null, forwardingPathOperation, null, null);
+ componentInstanceBusinessLogic.setComponentsUtils(componentsUtils);
+ componentInstanceBusinessLogic.setToscaOperationFacade(toscaOperationFacade);
+ componentInstanceBusinessLogic.setUserValidations(userValidations);
+ componentInstanceBusinessLogic.setGraphLockOperation(graphLockOperation);
+ componentInstanceBusinessLogic.setJanusGraphDao(janusGraphDao);
+ componentInstanceBusinessLogic.setApplicationDataTypeCache(applicationDataTypeCache);
+ componentInstanceBusinessLogic.setPropertyOperation(propertyOperation);
+ componentInstanceBusinessLogic.setContainerInstanceTypesData(containerInstanceTypeData);
+ componentInstanceBusinessLogic.setCompositionBusinessLogic(compositionBusinessLogic);
+
stubMethods();
createComponents();
}
when(toscaOperationFacade.getToscaElement(eq(containerComponentID), any(ComponentParametersView.class)))
.thenReturn(Either.left(component));
when(toscaOperationFacade.validateComponentExists(any(String.class))).thenReturn(Either.left(Boolean.TRUE));
- when(toscaOperationFacade.getToscaFullElement(eq(new_Comp_UID))).thenReturn(Either.left(component2));
+ when(toscaOperationFacade.getToscaFullElement(new_Comp_UID)).thenReturn(Either.left(component2));
Either<Set<String>, ResponseFormat> resultOp = componentInstanceBusinessLogic
.forwardingPathOnVersionChange(containerComponentParam,
assertThat(responseFormatEither.left().value()).isEqualTo(properties);
}
+ @Test
+ void testToscaGetFunctionValidation() {
+ final String userId = "userId";
+ final String containerComponentId = "containerComponentId";
+ final String containerComponentName = "containerComponentName";
+ final String resourceInstanceId = "resourceInstanceId";
+ final String inputName = "myInputToGet";
+ final String inputId = String.format("%s.%s", containerComponentId, inputName);
+ final String schemaType = "string";
+ //creating instance list of string property with get_input value
+ final ComponentInstanceProperty propertyGetInput = new ComponentInstanceProperty();
+ propertyGetInput.setName("getInputProperty");
+ propertyGetInput.setPropertyId(String.format("%s.%s", containerComponentId, "getInputProperty"));
+ propertyGetInput.setValue(String.format("get_input: [\"%s\"]", inputName));
+ propertyGetInput.setType("list");
+ final SchemaDefinition listStringPropertySchema = createSchema(schemaType);
+ propertyGetInput.setSchema(listStringPropertySchema);
+ propertyGetInput.setToscaGetFunction(
+ createGetToscaFunction(inputName, inputId, List.of(propertyGetInput.getName()), PropertySource.SELF, ToscaGetFunctionType.GET_INPUT,
+ containerComponentId, containerComponentName)
+ );
+ //creating instance map of string property with get_input value to a second level property:
+ // get_input: ["property1", "subProperty1", "subProperty2"]
+ final String getPropertyPropertyName = "getPropertyProperty";
+ final List<String> containerPropertyPath = List.of("property1", "subProperty1", "subProperty2");
+ final String containerPropertyId = String.format("%s.%s", containerComponentId, containerPropertyPath.get(0));
+ final String mapToscaType = "map";
+ final ComponentInstanceProperty propertyGetProperty = createComponentInstanceProperty(
+ String.format("%s.%s", containerComponentId, getPropertyPropertyName),
+ getPropertyPropertyName,
+ mapToscaType,
+ "string",
+ String.format("get_property: [\"%s\"]", String.join(",", containerPropertyPath)),
+ createGetToscaFunction(containerPropertyPath.get(containerPropertyPath.size() - 1), containerPropertyId,
+ containerPropertyPath, PropertySource.SELF, ToscaGetFunctionType.GET_PROPERTY, containerComponentId, containerComponentName)
+ );
+
+ //creating component that has the instance properties
+ final Component component = new Service();
+ component.setUniqueId(containerComponentId);
+ component.setName(containerComponentName);
+ component.setLastUpdaterUserId(userId);
+ component.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT);
+ //adding instance properties to the component
+ final List<ComponentInstanceProperty> resourceInstanceProperties = List.of(propertyGetInput, propertyGetProperty);
+ final Map<String, List<ComponentInstanceProperty>> componentInstanceProps = new HashMap<>();
+ componentInstanceProps.put(resourceInstanceId, resourceInstanceProperties);
+ component.setComponentInstancesProperties(componentInstanceProps);
+
+ //creating component input that will be gotten by the get_input instance property
+ final var inputDefinition = new InputDefinition();
+ inputDefinition.setName(inputName);
+ inputDefinition.setUniqueId(inputId);
+ inputDefinition.setType(propertyGetInput.getType());
+ inputDefinition.setSchema(listStringPropertySchema);
+ component.setInputs(List.of(inputDefinition));
+
+ //creating component property that contains the sub property that will be gotten by the get_property instance property
+ final var propertyDefinition = new PropertyDefinition();
+ propertyDefinition.setName(containerPropertyPath.get(0));
+ propertyDefinition.setUniqueId(containerPropertyId);
+ final String property1Type = "property1.datatype";
+ propertyDefinition.setType(property1Type);
+ component.setProperties(List.of(propertyDefinition));
+ //creating resource instance to be added to the component
+ final ComponentInstance resourceInstance = createComponentInstance("resourceInstance");
+ resourceInstance.setUniqueId(resourceInstanceId);
+ component.setComponentInstances(List.of(resourceInstance));
+
+ mockComponentForToscaGetFunctionValidation(component);
+
+ //creating data types for "map", and sub properties
+ final Map<String, DataTypeDefinition> allDataTypesMap = new HashMap<>();
+ allDataTypesMap.put(mapToscaType, new DataTypeDefinition());
+
+ final String subProperty1Type = "subProperty1.datatype";
+ allDataTypesMap.put(property1Type, createDataType(property1Type, Map.of(containerPropertyPath.get(1), subProperty1Type)));
+
+ final var subProperty2Property = new PropertyDefinition();
+ subProperty2Property.setName(containerPropertyPath.get(2));
+ subProperty2Property.setType(propertyGetProperty.getType());
+ subProperty2Property.setSchema(propertyGetProperty.getSchema());
+ allDataTypesMap.put(subProperty1Type, createDataType(subProperty1Type, List.of(subProperty2Property)));
+
+ when(applicationDataTypeCache.getAll(component.getModel())).thenReturn(Either.left(allDataTypesMap));
+ //when
+ final Either<List<ComponentInstanceProperty>, ResponseFormat> actualResponseFormat = componentInstanceBusinessLogic
+ .createOrUpdatePropertiesValues(
+ ComponentTypeEnum.RESOURCE_INSTANCE, containerComponentId, resourceInstanceId, resourceInstanceProperties, userId);
+ //then
+ assertTrue(actualResponseFormat.isLeft());
+ assertThat(actualResponseFormat.left().value()).isEqualTo(resourceInstanceProperties);
+ }
+
+ private DataTypeDefinition createDataType(final String name, final Map<String, String> propertyNameAndTypeMap) {
+ final var dataTypeDefinition = new DataTypeDefinition();
+ dataTypeDefinition.setName(name);
+ if (MapUtils.isNotEmpty(propertyNameAndTypeMap)) {
+ for (final Entry<String, String> propertyEntry : propertyNameAndTypeMap.entrySet()) {
+ final var propertyDefinition = new PropertyDefinition();
+ propertyDefinition.setName(propertyEntry.getKey());
+ propertyDefinition.setType(propertyEntry.getValue());
+ dataTypeDefinition.setProperties(List.of(propertyDefinition));
+ }
+ }
+ return dataTypeDefinition;
+ }
+
+ private DataTypeDefinition createDataType(final String name, final List<PropertyDefinition> propertyList) {
+ final var dataTypeDefinition = new DataTypeDefinition();
+ dataTypeDefinition.setName(name);
+ if (CollectionUtils.isNotEmpty(propertyList)) {
+ dataTypeDefinition.setProperties(propertyList);
+ }
+ return dataTypeDefinition;
+ }
+
+ private ComponentInstanceProperty createComponentInstanceProperty(final String uniqueId, final String name, final String type,
+ final String schemaType, final String value,
+ final ToscaGetFunctionDataDefinition toscaGetFunction) {
+ final var componentInstanceProperty = new ComponentInstanceProperty();
+ componentInstanceProperty.setName(name);
+ componentInstanceProperty.setUniqueId(uniqueId);
+ componentInstanceProperty.setType(type);
+ componentInstanceProperty.setValue(value);
+ if (schemaType != null) {
+ final SchemaDefinition schemaDefinition = createSchema(schemaType);
+ componentInstanceProperty.setSchema(schemaDefinition);
+ }
+ if (toscaGetFunction != null) {
+ componentInstanceProperty.setToscaGetFunction(toscaGetFunction);
+ }
+
+ return componentInstanceProperty;
+ }
+
+ @Test
+ void testToscaGetFunctionValidation_schemaDivergeTest() {
+ final String userId = "userId";
+ final String containerComponentId = "containerComponentId";
+ final String containerComponentName = "containerComponentName";
+ final String resourceInstanceId = "resourceInstanceId";
+ final String inputName = "myInputToGet";
+ final String inputId = String.format("%s.%s", containerComponentId, inputName);
+ final String propertyName = "getInputProperty";
+ final String propertyId = String.format("%s.%s", containerComponentId, propertyName);
+ final String propertyType = "list";
+ final List<ComponentInstanceProperty> properties = new ArrayList<>();
+ final ComponentInstanceProperty propertyGetInput = createComponentInstanceProperty(
+ propertyId,
+ "getInputProperty",
+ propertyType,
+ "string",
+ String.format("get_input: [\"%s\"]", inputName),
+ createGetToscaFunction(inputName, inputId, List.of(propertyName), PropertySource.SELF, ToscaGetFunctionType.GET_INPUT,
+ containerComponentId, containerComponentName)
+ );
+ properties.add(propertyGetInput);
+
+ final Component component = new Service();
+ component.setUniqueId(containerComponentId);
+ component.setName(containerComponentName);
+ component.setLastUpdaterUserId(userId);
+ component.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT);
+
+ var inputDefinition = new InputDefinition();
+ inputDefinition.setName(inputName);
+ inputDefinition.setUniqueId(inputId);
+ inputDefinition.setType(propertyType);
+ inputDefinition.setSchema(createSchema("integer"));
+ component.setInputs(List.of(inputDefinition));
+
+ final Map<String, List<ComponentInstanceProperty>> componentInstanceProps = new HashMap<>();
+ componentInstanceProps.put(resourceInstanceId, properties);
+ component.setComponentInstancesProperties(componentInstanceProps);
+
+ final ComponentInstance resourceInstance = createComponentInstance("componentInstance1");
+ resourceInstance.setUniqueId(resourceInstanceId);
+ component.setComponentInstances(List.of(resourceInstance));
+
+ mockComponentForToscaGetFunctionValidation(component);
+ //when
+ final Either<List<ComponentInstanceProperty>, ResponseFormat> responseFormatEither =
+ componentInstanceBusinessLogic
+ .createOrUpdatePropertiesValues(ComponentTypeEnum.RESOURCE_INSTANCE, containerComponentId, resourceInstanceId, properties, userId);
+ //then
+ assertTrue(responseFormatEither.isRight(), "Expecting an error");
+ final ResponseFormat actualResponse = responseFormatEither.right().value();
+ final ResponseFormat expectedResponse =
+ ToscaGetFunctionExceptionSupplier
+ .propertySchemaDiverge(propertyGetInput.getToscaGetFunction().getFunctionType(), inputDefinition.getSchemaType(),
+ propertyGetInput.getSchemaType())
+ .get().getResponseFormat();
+ assertEquals(expectedResponse.getFormattedMessage(), actualResponse.getFormattedMessage());
+ assertEquals(expectedResponse.getStatus(), actualResponse.getStatus());
+ }
+
+ @Test
+ void testToscaGetFunctionValidation_propertyTypeDivergeTest() {
+ final String userId = "userId";
+ final String containerComponentId = "containerComponentId";
+ final String containerComponentName = "containerComponentName";
+ final String resourceInstanceId = "resourceInstanceId";
+ final String inputName = "myInputToGet";
+ final String inputId = String.format("%s.%s", containerComponentId, inputName);
+ final String propertyName = "getInputProperty";
+ final String propertyId = String.format("%s.%s", containerComponentId, propertyName);
+ final String propertyType = "string";
+ final List<ComponentInstanceProperty> properties = new ArrayList<>();
+ final ComponentInstanceProperty propertyGetInput = createComponentInstanceProperty(
+ propertyId,
+ "getInputProperty",
+ propertyType,
+ "string",
+ String.format("get_input: [\"%s\"]", inputName),
+ createGetToscaFunction(inputName, inputId, List.of(propertyName), PropertySource.SELF, ToscaGetFunctionType.GET_INPUT,
+ containerComponentId, containerComponentName)
+ );
+ properties.add(propertyGetInput);
+
+ final Component component = new Service();
+ component.setName(containerComponentName);
+ component.setUniqueId(containerComponentId);
+ component.setLastUpdaterUserId(userId);
+ component.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT);
+
+ var inputDefinition = new InputDefinition();
+ inputDefinition.setName(inputName);
+ inputDefinition.setUniqueId(inputId);
+ inputDefinition.setType("integer");
+ component.setInputs(List.of(inputDefinition));
+
+ final Map<String, List<ComponentInstanceProperty>> componentInstanceProps = new HashMap<>();
+ componentInstanceProps.put(resourceInstanceId, properties);
+ component.setComponentInstancesProperties(componentInstanceProps);
+
+ final ComponentInstance resourceInstance = createComponentInstance("componentInstance1");
+ resourceInstance.setUniqueId(resourceInstanceId);
+ component.setComponentInstances(List.of(resourceInstance));
+
+ mockComponentForToscaGetFunctionValidation(component);
+ //when
+ final Either<List<ComponentInstanceProperty>, ResponseFormat> responseFormatEither =
+ componentInstanceBusinessLogic
+ .createOrUpdatePropertiesValues(ComponentTypeEnum.RESOURCE_INSTANCE, containerComponentId, resourceInstanceId, properties, userId);
+ //then
+ assertTrue(responseFormatEither.isRight(), "Expecting an error");
+ final ResponseFormat actualResponse = responseFormatEither.right().value();
+ final ResponseFormat expectedResponse =
+ ToscaGetFunctionExceptionSupplier
+ .propertyTypeDiverge(propertyGetInput.getToscaGetFunction().getFunctionType(), inputDefinition.getType(), propertyGetInput.getType())
+ .get().getResponseFormat();
+ assertEquals(expectedResponse.getFormattedMessage(), actualResponse.getFormattedMessage());
+ assertEquals(expectedResponse.getStatus(), actualResponse.getStatus());
+ }
+
+ @Test
+ void testToscaGetFunctionValidation_toscaFunctionNotSupportedTest() {
+ final String userId = "userId";
+ final String containerComponentId = "containerComponentId";
+ final String containerComponentName = "containerComponentName";
+ final String resourceInstanceId = "resourceInstanceId";
+ final List<ComponentInstanceProperty> properties = new ArrayList<>();
+ final ComponentInstanceProperty propertyGetInput = new ComponentInstanceProperty();
+ propertyGetInput.setName("anyName");
+ final var toscaGetFunction = new ToscaGetFunctionDataDefinition();
+ toscaGetFunction.setFunctionType(ToscaGetFunctionType.GET_ATTRIBUTE);
+ propertyGetInput.setToscaGetFunction(toscaGetFunction);
+ properties.add(propertyGetInput);
+
+ final Component component = new Service();
+ component.setName(containerComponentName);
+ component.setUniqueId(containerComponentId);
+ component.setLastUpdaterUserId(userId);
+ component.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT);
+
+ final Map<String, List<ComponentInstanceProperty>> componentInstanceProps = new HashMap<>();
+ componentInstanceProps.put(resourceInstanceId, properties);
+ component.setComponentInstancesProperties(componentInstanceProps);
+
+ final ComponentInstance resourceInstance = createComponentInstance("componentInstance1");
+ resourceInstance.setUniqueId(resourceInstanceId);
+ component.setComponentInstances(List.of(resourceInstance));
+
+ mockComponentForToscaGetFunctionValidation(component);
+ //when
+ final Either<List<ComponentInstanceProperty>, ResponseFormat> responseFormatEither =
+ componentInstanceBusinessLogic
+ .createOrUpdatePropertiesValues(ComponentTypeEnum.RESOURCE_INSTANCE, containerComponentId, resourceInstanceId, properties, userId);
+ //then
+ assertTrue(responseFormatEither.isRight(), "Expecting an error");
+ final ResponseFormat actualResponse = responseFormatEither.right().value();
+ final ResponseFormat expectedResponse =
+ ToscaGetFunctionExceptionSupplier.functionNotSupported(toscaGetFunction.getFunctionType()).get().getResponseFormat();
+ assertEquals(expectedResponse.getFormattedMessage(), actualResponse.getFormattedMessage());
+ assertEquals(expectedResponse.getStatus(), actualResponse.getStatus());
+ }
+
+ @Test
+ void testToscaGetFunctionValidation_propertyNotFoundTest() {
+ final String userId = "userId";
+ final String containerComponentId = "containerComponentId";
+ final String containerComponentName = "containerComponentName";
+ final String resourceInstanceId = "resourceInstanceId";
+ final String inputName = "myInputToGet";
+ final String inputId = String.format("%s.%s", containerComponentId, inputName);
+ final String propertyName = "getInputProperty";
+ final String propertyId = String.format("%s.%s", containerComponentId, propertyName);
+ final String propertyType = "string";
+ final List<ComponentInstanceProperty> properties = new ArrayList<>();
+ final ComponentInstanceProperty propertyGetInput = createComponentInstanceProperty(
+ propertyId,
+ "getInputProperty",
+ propertyType,
+ "string",
+ String.format("get_input: [\"%s\"]", inputName),
+ createGetToscaFunction(inputName, inputId, List.of(propertyName), PropertySource.SELF, ToscaGetFunctionType.GET_INPUT,
+ containerComponentId, containerComponentName)
+ );
+ properties.add(propertyGetInput);
+
+ final Component component = new Service();
+ component.setName(containerComponentName);
+ component.setUniqueId(containerComponentId);
+ component.setLastUpdaterUserId(userId);
+ component.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT);
+
+ final Map<String, List<ComponentInstanceProperty>> componentInstanceProps = new HashMap<>();
+ componentInstanceProps.put(resourceInstanceId, properties);
+ component.setComponentInstancesProperties(componentInstanceProps);
+
+ final ComponentInstance resourceInstance = createComponentInstance("componentInstance1");
+ resourceInstance.setUniqueId(resourceInstanceId);
+ component.setComponentInstances(List.of(resourceInstance));
+
+ mockComponentForToscaGetFunctionValidation(component);
+ //when
+ final Either<List<ComponentInstanceProperty>, ResponseFormat> responseFormatEither =
+ componentInstanceBusinessLogic
+ .createOrUpdatePropertiesValues(ComponentTypeEnum.RESOURCE_INSTANCE, containerComponentId, resourceInstanceId, properties, userId);
+ //then
+ assertTrue(responseFormatEither.isRight(), "Expecting an error");
+ final ResponseFormat actualResponse = responseFormatEither.right().value();
+ final ResponseFormat expectedResponse =
+ ToscaGetFunctionExceptionSupplier
+ .propertyNotFoundOnTarget(inputName, PropertySource.SELF, ToscaGetFunctionType.GET_INPUT)
+ .get().getResponseFormat();
+ assertEquals(expectedResponse.getFormattedMessage(), actualResponse.getFormattedMessage());
+ assertEquals(expectedResponse.getStatus(), actualResponse.getStatus());
+ }
+
@Test
void testCreateOrUpdatePropertiesValuesPropertyNotExists() {
String containerComponentID = "containerId";
component.addForwardingPath(createPath("Path2", "NodeA2", "NodeB2", "2"));
when(toscaOperationFacade.getToscaElement(eq(containerComponentID), any(ComponentParametersView.class)))
.thenReturn(Either.left(component));
- when(toscaOperationFacade.getToscaElement(eq(containerComponentID))).thenReturn(Either.left(component));
+ when(toscaOperationFacade.getToscaElement(containerComponentID)).thenReturn(Either.left(component));
when(forwardingPathOperation.deleteForwardingPath(any(Service.class), anySet()))
.thenReturn(Either.left(new HashSet<>()));
final ComponentInstance ci = new ComponentInstance();
finalDeploymentArtifacts.put(deploymentArtifact3.getArtifactLabel(), deploymentArtifact3);
finalDeploymentArtifacts.put(heatEnvPlaceHolder.getArtifactLabel(), heatEnvPlaceHolder);
finalDeploymentArtifacts.put(heatEnvPlaceHolder2.getArtifactLabel(), heatEnvPlaceHolder2);
-
when(artifactsBusinessLogic.getArtifacts(componentInstance.getComponentUid(), NodeTypeEnum.Resource,
ArtifactGroupTypeEnum.DEPLOYMENT, null)).thenReturn(getResourceDeploymentArtifacts);
when(artifactsBusinessLogic.createHeatEnvPlaceHolder(new ArrayList<>(),
}
private void getServiceRelationByIdUserValidationFailure(Component component) {
- when(userValidations.validateUserExists(eq(USER_ID)))
- .thenThrow(new ByActionStatusComponentException(ActionStatus.USER_NOT_FOUND));
+ doThrow(new ByActionStatusComponentException(ActionStatus.USER_NOT_FOUND)).when(userValidations).validateUserExists(USER_ID);
try {
componentInstanceBusinessLogic
.getRelationById(COMPONENT_ID, RELATION_ID, USER_ID, component.getComponentType());
componentInstanceUniqueId, capabilityType, capabilityName, properties, userId);
assertNotNull(result);
}
-
+
@Test
void testUpdateInstanceRequirement() {
ComponentInstanceBusinessLogic testSubject;
String capabilityType = "";
String capabilityName = "";
RequirementDefinition requirementDef = new RequirementDefinition();
-
+
Either<RequirementDefinition, ResponseFormat> result;
when(toscaOperationFacade.getToscaFullElement(containerComponentId)).thenReturn(Either.left(resource));
.thenReturn(StorageOperationStatus.OK);
when(graphLockOperation.lockComponent(Mockito.anyString(), eq(NodeTypeEnum.Resource)))
.thenReturn(StorageOperationStatus.OK);
-
+
result = testSubject.updateInstanceRequirement(componentTypeEnum, containerComponentId,
componentInstanceUniqueId, requirementDef, userId);
assertEquals(requirementDef, result.left().value());
deleteErrorIds.add(componentInstanceId);
deleteErrorMap.put("deleteFailedIds", deleteErrorIds);
Either<Component, StorageOperationStatus> cont = Either.left(service);
- when(componentsUtils.convertFromStorageResponse(eq(StorageOperationStatus.NOT_FOUND), eq(null)))
+ when(componentsUtils.convertFromStorageResponse(StorageOperationStatus.NOT_FOUND, null))
.thenReturn(ActionStatus.GENERAL_ERROR);
when(toscaOperationFacade.getToscaElement(any(String.class), any(ComponentParametersView.class)))
.thenReturn(cont);
.thenReturn(StorageOperationStatus.OK);
Either<RequirementCapabilityRelDef, StorageOperationStatus> resultEither;
resultEither = Either.right(StorageOperationStatus.OK);
- when(componentsUtils.convertFromStorageResponseForResourceInstance(eq(StorageOperationStatus.OK), eq(true)))
+ when(componentsUtils.convertFromStorageResponseForResourceInstance(StorageOperationStatus.OK, true))
.thenReturn(ActionStatus.GENERAL_ERROR);
when(toscaOperationFacade.dissociateResourceInstances(componentId, ref)).thenReturn(resultEither);
componentInst.setDeploymentArtifacts(component.getDeploymentArtifacts());
return componentInst;
}
-
+
// Prepare ComponentInstance & Resource objects used in createComponentInstance() tests
+
private Pair<ComponentInstance, Resource> prepareResourcesForCreateComponentInstanceTest() {
ComponentInstance instanceToBeCreated = new ComponentInstance();
instanceToBeCreated.setName(COMPONENT_INSTANCE_NAME);
return Pair.of(instanceToBeCreated, originComponent);
}
-
// Common part for testing component instance name validation
+
private void testCreateComponentInstanceNameValidationFailure(String ciName) {
ComponentInstance ci = new ComponentInstance();
ci.setName(ciName);
});
assertEquals(ActionStatus.INVALID_COMPONENT_NAME, e.getActionStatus());
}
-
@TestFactory
Iterable<DynamicTest> testCreateComponentInstanceNameValidationFailureFactory() {
String longName = String.join("", Collections.nCopies(ValidationUtils.COMPONENT_NAME_MAX_LENGTH + 1, "x"));
// Stub for getting component
when(toscaOperationFacade.getToscaElement(eq(COMPONENT_ID), any(ComponentParametersView.class)))
.thenReturn(Either.left(service));
- when(toscaOperationFacade.getToscaFullElement(eq(ORIGIN_COMPONENT_ID)))
+ when(toscaOperationFacade.getToscaFullElement(ORIGIN_COMPONENT_ID))
.thenReturn(Either.right(StorageOperationStatus.NOT_FOUND));
when(componentsUtils.convertFromStorageResponse(StorageOperationStatus.NOT_FOUND, ComponentTypeEnum.RESOURCE))
.thenReturn(ActionStatus.RESOURCE_NOT_FOUND);
// Stub for getting component
when(toscaOperationFacade.getToscaElement(eq(COMPONENT_ID), any(ComponentParametersView.class)))
.thenReturn(Either.left(service));
- when(toscaOperationFacade.getToscaFullElement(eq(ORIGIN_COMPONENT_ID)))
+ when(toscaOperationFacade.getToscaFullElement(ORIGIN_COMPONENT_ID))
.thenReturn(Either.left(originComponent));
ByActionStatusComponentException e = assertThrows(ByActionStatusComponentException.class, () -> {
// Stub for getting component
when(toscaOperationFacade.getToscaElement(eq(COMPONENT_ID), any(ComponentParametersView.class)))
.thenReturn(Either.left(service));
- when(toscaOperationFacade.getToscaFullElement(eq(ORIGIN_COMPONENT_ID)))
+ when(toscaOperationFacade.getToscaFullElement(ORIGIN_COMPONENT_ID))
.thenReturn(Either.left(originComponent));
ByActionStatusComponentException e = assertThrows(ByActionStatusComponentException.class, () -> {
// Stub for getting component
when(toscaOperationFacade.getToscaElement(eq(COMPONENT_ID), any(ComponentParametersView.class)))
.thenReturn(Either.left(service));
- when(toscaOperationFacade.getToscaFullElement(eq(ORIGIN_COMPONENT_ID)))
+ when(toscaOperationFacade.getToscaFullElement(ORIGIN_COMPONENT_ID))
.thenReturn(Either.left(originComponent));
final ByActionStatusComponentException e = assertThrows(ByActionStatusComponentException.class, () -> {
// Stub for getting component
when(toscaOperationFacade.getToscaElement(eq(COMPONENT_ID), any(ComponentParametersView.class)))
.thenReturn(Either.left(service));
- when(toscaOperationFacade.getToscaFullElement(eq(ORIGIN_COMPONENT_ID)))
+ when(toscaOperationFacade.getToscaFullElement(ORIGIN_COMPONENT_ID))
.thenReturn(Either.left(originComponent));
// Assume services cannot contain VF resource
- when(containerInstanceTypeData.isAllowedForServiceComponent(eq(ResourceTypeEnum.VF), eq(null)))
+ when(containerInstanceTypeData.isAllowedForServiceComponent(ResourceTypeEnum.VF, null))
.thenReturn(false);
ByActionStatusComponentException actualException = assertThrows(ByActionStatusComponentException.class, () -> {
componentInstanceBusinessLogic.createComponentInstance(ComponentTypeEnum.SERVICE_PARAM_NAME, COMPONENT_ID, USER_ID, ci);
});
assertThat(actualException.getActionStatus()).isEqualTo(ActionStatus.CONTAINER_CANNOT_CONTAIN_INSTANCE);
- verify(containerInstanceTypeData, times(1)).isAllowedForServiceComponent(eq(ResourceTypeEnum.VF), eq(null));
+ verify(containerInstanceTypeData, times(1)).isAllowedForServiceComponent(ResourceTypeEnum.VF, null);
//given
final Resource resource = createResource();
//when
when(toscaOperationFacade.getToscaElement(eq(COMPONENT_ID), any(ComponentParametersView.class)))
.thenReturn(Either.left(resource));
- when(toscaOperationFacade.getToscaFullElement(eq(ORIGIN_COMPONENT_ID)))
+ when(toscaOperationFacade.getToscaFullElement(ORIGIN_COMPONENT_ID))
.thenReturn(Either.left(originComponent));
- when(containerInstanceTypeData.isAllowedForResourceComponent(eq(ResourceTypeEnum.VF), eq(ResourceTypeEnum.VF)))
+ when(containerInstanceTypeData.isAllowedForResourceComponent(ResourceTypeEnum.VF, ResourceTypeEnum.VF))
.thenReturn(false);
actualException = assertThrows(ByActionStatusComponentException.class, () -> {
componentInstanceBusinessLogic.createComponentInstance(RESOURCE_PARAM_NAME, COMPONENT_ID, USER_ID, ci);
// not to target the internal details too much
when(toscaOperationFacade.getToscaElement(eq(COMPONENT_ID), any(ComponentParametersView.class)))
.thenReturn(Either.left(service));
- when(toscaOperationFacade.getToscaFullElement(eq(ORIGIN_COMPONENT_ID)))
+ when(toscaOperationFacade.getToscaFullElement(ORIGIN_COMPONENT_ID))
.thenReturn(Either.left(originComponent));
- when(containerInstanceTypeData.isAllowedForServiceComponent(eq(ResourceTypeEnum.VF), eq(null)))
+ when(containerInstanceTypeData.isAllowedForServiceComponent(ResourceTypeEnum.VF, null))
.thenReturn(true);
Mockito.doNothing().when(compositionBusinessLogic).validateAndSetDefaultCoordinates(ci);
when(graphLockOperation.lockComponent(COMPONENT_ID, NodeTypeEnum.Service))
componentInstanceBusinessLogic.createComponentInstance(ComponentTypeEnum.SERVICE_PARAM_NAME, COMPONENT_ID, USER_ID, ci);
});
verify(containerInstanceTypeData, times(1))
- .isAllowedForServiceComponent(eq(ResourceTypeEnum.VF), eq(null));
+ .isAllowedForServiceComponent(ResourceTypeEnum.VF, null);
verify(compositionBusinessLogic, times(1)).validateAndSetDefaultCoordinates(ci);
verify(toscaOperationFacade, times(1))
.addComponentInstanceToTopologyTemplate(service, originComponent, ci, false, user);
// not to target the internal details too much
when(toscaOperationFacade.getToscaElement(eq(COMPONENT_ID), any(ComponentParametersView.class)))
.thenReturn(Either.left(service));
- when(toscaOperationFacade.getToscaFullElement(eq(ORIGIN_COMPONENT_ID)))
+ when(toscaOperationFacade.getToscaFullElement(ORIGIN_COMPONENT_ID))
.thenReturn(Either.left(originComponent));
- when(containerInstanceTypeData.isAllowedForServiceComponent(eq(ResourceTypeEnum.VF), eq(null)))
+ when(containerInstanceTypeData.isAllowedForServiceComponent(ResourceTypeEnum.VF, null))
.thenReturn(true);
Mockito.doNothing().when(compositionBusinessLogic).validateAndSetDefaultCoordinates(instanceToBeCreated);
when(graphLockOperation.lockComponent(COMPONENT_ID, NodeTypeEnum.Service))
assertThat(instanceToBeCreated.getComponentVersion()).isEqualTo(originComponent.getVersion());
assertThat(instanceToBeCreated.getIcon()).isEqualTo(originComponent.getIcon());
verify(containerInstanceTypeData, times(1))
- .isAllowedForServiceComponent(eq(ResourceTypeEnum.VF), eq(null));
+ .isAllowedForServiceComponent(ResourceTypeEnum.VF, null);
verify(compositionBusinessLogic, times(1)).validateAndSetDefaultCoordinates(instanceToBeCreated);
verify(toscaOperationFacade, times(1))
.addComponentInstanceToTopologyTemplate(service, originComponent, instanceToBeCreated, false, user);
when(toscaOperationFacade.getToscaElement(eq(COMPONENT_ID), any(ComponentParametersView.class)))
.thenReturn(Either.left(service));
- when(toscaOperationFacade.getToscaFullElement(eq(ORIGIN_COMPONENT_ID)))
+ when(toscaOperationFacade.getToscaFullElement(ORIGIN_COMPONENT_ID))
.thenReturn(Either.left(originService));
when(toscaOperationFacade.getLatestByToscaResourceName(eq(originService.getDerivedFromGenericType()), isNull()))
.thenReturn(Either.left(serviceBaseComponent));
component.setUniqueId("baseComponentId");
return component;
}
+
+ private void mockComponentForToscaGetFunctionValidation(final Component component) {
+ when(toscaOperationFacade.getToscaElement(component.getUniqueId(), JsonParseFlagEnum.ParseAll))
+ .thenReturn(Either.left(component));
+ when(graphLockOperation.lockComponent(component.getUniqueId(), NodeTypeEnum.ResourceInstance))
+ .thenReturn(StorageOperationStatus.OK);
+ when(toscaOperationFacade.updateComponentInstanceMetadataOfTopologyTemplate(component))
+ .thenReturn(Either.left(component));
+ when(janusGraphDao.commit()).thenReturn(JanusGraphOperationStatus.OK);
+ when(graphLockOperation.unlockComponent(component.getUniqueId(), NodeTypeEnum.ResourceInstance))
+ .thenReturn(StorageOperationStatus.OK);
+ }
+
+ private ToscaGetFunctionDataDefinition createGetToscaFunction(final String propertyName, final String propertyUniqueId,
+ final List<String> propertyPathFromSource,
+ final PropertySource propertySource, final ToscaGetFunctionType functionType,
+ final String sourceUniqueId,
+ final String sourceName) {
+ final var toscaGetFunction = new ToscaGetFunctionDataDefinition();
+ toscaGetFunction.setFunctionType(functionType);
+ toscaGetFunction.setPropertyUniqueId(propertyUniqueId);
+ toscaGetFunction.setPropertyName(propertyName);
+ toscaGetFunction.setPropertyPathFromSource(propertyPathFromSource);
+ toscaGetFunction.setPropertySource(propertySource);
+ toscaGetFunction.setSourceName(sourceName);
+ toscaGetFunction.setSourceUniqueId(sourceUniqueId);
+ return toscaGetFunction;
+ }
+
+ private SchemaDefinition createSchema(final String schemaType) {
+ final var schemaDefinition = new SchemaDefinition();
+ final var schemaProperty = new PropertyDefinition();
+ schemaProperty.setType(schemaType);
+ schemaDefinition.setProperty(schemaProperty);
+ return schemaDefinition;
+ }
+
}
+
code: 403,
message: "Component is in use by '%1'",
messageId: "SVC4693"
- }
\ No newline at end of file
+ }
+ #---------SVC4165-----------------------------
+ # %1 - input origin
+ TOSCA_GET_FUNCTION_INPUTS_ONLY_SELF_ERROR: {
+ code: 400,
+ message: "Invalid get_input definition. Inputs can only be get from SELF, the given origin was '%1'",
+ messageId: "SVC4165"
+ }
+
+ #---------SVC4166-----------------------------
+ # %1 - input name
+ # %2 - input origin
+ TOSCA_GET_FUNCTION_INPUTS_NOT_FOUND: {
+ code: 404,
+ message: "The given input '%1' was not found on '%2'.",
+ messageId: "SVC4166"
+ }
+
+ #---------SVC4167-----------------------------
+ # %1 - Tosca function
+ # %2 - Referred input type
+ # %3 - Selected property type
+ TOSCA_GET_FUNCTION_TYPE_DIVERGE: {
+ code: 400,
+ message: "Could not set %1. Referred input type '%2' diverges from the selected property type '%3'.",
+ messageId: "SVC4167"
+ }
+
+ #---------SVC4168-----------------------------
+ # %1 - Tosca function
+ # %2 - Referred input schema
+ # %3 - Selected property schema
+ TOSCA_GET_FUNCTION_SCHEMA_DIVERGE: {
+ code: 400,
+ message: "Could not set %1. Referred input schema '%2' diverges from the selected property schema '%3'.",
+ messageId: "SVC4168"
+ }
+
+ #---------SVC4169-----------------------------
+ # %1 - Property type (property|input|attribute)
+ # %1 - Property name
+ # %2 - Property origin
+ TOSCA_GET_FUNCTION_PROPERTY_NOT_FOUND: {
+ code: 404,
+ message: "The given %1 '%2' was not found on '%3'.",
+ messageId: "SVC4169"
+ }
+
+ #---------SVC4170-----------------------------
+ # %1 - Property type (property|input|attribute)
+ # %2 - Property name/path
+ # %3 - Property data type
+ TOSCA_GET_FUNCTION_PROPERTY_DATA_TYPE_NOT_FOUND: {
+ code: 404,
+ message: "The %1 '%2' type '%3' was not found.",
+ messageId: "SVC4170"
+ }
//TOSCA node types
INVALID_NODE_TYPES_YAML,
//system deployed resources
- CANNOT_DELETE_SYSTEM_DEPLOYED_RESOURCES
+ CANNOT_DELETE_SYSTEM_DEPLOYED_RESOURCES,
+ TOSCA_GET_FUNCTION_INPUTS_ONLY_SELF_ERROR,
+ TOSCA_GET_FUNCTION_INPUTS_NOT_FOUND,
+ TOSCA_GET_FUNCTION_TYPE_DIVERGE,
+ TOSCA_GET_FUNCTION_SCHEMA_DIVERGE,
+ TOSCA_GET_FUNCTION_PROPERTY_DATA_TYPE_NOT_FOUND,
+ TOSCA_GET_FUNCTION_PROPERTY_NOT_FOUND
}
import {ToscaPresentationData} from '../tosca-presentation';
import {PropertyInputDetail} from './property-input-detail';
import {Metadata} from '../metadata';
-import {ToscaGetFunctionType} from "../tosca-get-function-type.enum";
+import {ToscaGetFunctionType} from "../tosca-get-function-type";
+import {ToscaGetFunctionDto} from '../tosca-get-function-dto';
+import {PropertySource} from '../property-source';
export enum DerivedPropertyType {
SIMPLE,
inputPath: string;
toscaPresentation: ToscaPresentationData;
metadata: Metadata;
+ //deprecated
toscaGetFunctionType: ToscaGetFunctionType;
+ toscaGetFunction: ToscaGetFunctionDto;
constructor(property?: PropertyBEModel) {
if (property) {
this.getPolicyValues = property.getPolicyValues;
this.inputPath = property.inputPath;
this.metadata = property.metadata;
- this.toscaGetFunctionType = property.toscaGetFunctionType;
+ 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 (!this.schema || !this.schema.property) {
* Checks whether the property value is a tosca get function (e.g. get_input, get_property, get_attribute)
*/
public isToscaGetFunction(): boolean {
- return this.toscaGetFunctionType != null;
+ return this.toscaGetFunction != null;
}
}
--- /dev/null
+/*
+ * -
+ * ============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=========================================================
+ */
+
+export enum PropertySource {
+ SELF = 'SELF',
+ INSTANCE = 'INSTANCE'
+}
--- /dev/null
+/*
+ * -
+ * ============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 {ToscaGetFunctionType} from './tosca-get-function-type';
+import {PropertySource} from './property-source';
+
+export class ToscaGetFunctionDto {
+ propertyUniqueId: string;
+ propertyName: string;
+ propertySource: PropertySource;
+ sourceUniqueId: string;
+ sourceName: string;
+ 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;
+ }
+}
--- /dev/null
+/*
+ * -
+ * ============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 {ToscaGetFunctionType} from './tosca-get-function-type';
+
+export class ToscaGetFunctionTypeConverter {
+
+ static convertFromString(toscaGetFunction: string): ToscaGetFunctionType {
+ if (!toscaGetFunction) {
+ return;
+ }
+
+ if (ToscaGetFunctionType.GET_INPUT === toscaGetFunction.toUpperCase()) {
+ return ToscaGetFunctionType.GET_INPUT;
+ }
+
+ if (ToscaGetFunctionType.GET_PROPERTY === toscaGetFunction.toUpperCase()) {
+ return ToscaGetFunctionType.GET_PROPERTY;
+ }
+
+ if (ToscaGetFunctionType.GET_ATTRIBUTE === toscaGetFunction.toUpperCase()) {
+ return ToscaGetFunctionType.GET_ATTRIBUTE;
+ }
+
+ return undefined;
+
+ }
+
+}
CLOSE_BUTTON: string;
SAVE_BUTTON: string;
- constructor(private TranslateService: TranslateService) {
- this.TranslateService.languageChangedObservable.subscribe(lang => {
- this.EDIT_TITLE = this.TranslateService.translate('INTERFACE_EDIT_TITLE');
- this.CANCEL_BUTTON = this.TranslateService.translate("INTERFACE_CANCEL_BUTTON");
- this.CLOSE_BUTTON = this.TranslateService.translate("INTERFACE_CLOSE_BUTTON");
- this.SAVE_BUTTON = this.TranslateService.translate("INTERFACE_SAVE_BUTTON");
+ constructor(private translateService: TranslateService) {
+ this.translateService.languageChangedObservable.subscribe(lang => {
+ this.EDIT_TITLE = this.translateService.translate('INTERFACE_EDIT_TITLE');
+ this.CANCEL_BUTTON = this.translateService.translate("INTERFACE_CANCEL_BUTTON");
+ this.CLOSE_BUTTON = this.translateService.translate("INTERFACE_CLOSE_BUTTON");
+ this.SAVE_BUTTON = this.translateService.translate("INTERFACE_SAVE_BUTTON");
});
}
}
constructor(
- private TranslateService: TranslateService,
- private PluginsService: PluginsService,
+ private translateService: TranslateService,
+ private pluginsService: PluginsService,
private topologyTemplateService: TopologyTemplateService,
private toscaArtifactService: ToscaArtifactService,
private modalServiceNg2: ModalService,
private workspaceService: WorkspaceService,
@Inject("Notification") private Notification: any,
) {
- this.modalTranslation = new ModalTranslation(TranslateService);
+ this.modalTranslation = new ModalTranslation(translateService);
}
ngOnInit(): void {
).length === 0;
}
- private enableOrDisableSaveButton = (): boolean => {
- return this.isViewOnly;
+ private enableOrDisableSaveButton = (isValid): boolean => {
+ return isValid;
}
onSelectInterfaceOperation(interfaceModel: UIInterfaceModel, operation: InterfaceOperationModel) {
InputsGroup,
InputModel
} from 'app/models';
-import {ToscaGetFunctionType} from "app/models/tosca-get-function-type.enum";
+import {ToscaGetFunctionType} from "app/models/tosca-get-function-type";
import { CompositionService } from 'app/ng2/pages/composition/composition.service';
import { WorkspaceService } from 'app/ng2/pages/workspace/workspace.service';
import { GroupByPipe } from 'app/ng2/pipes/groupBy.pipe';
*/
import * as _ from "lodash";
-import {Component, Inject, ViewChild, ComponentRef} from "@angular/core";
+import {Component, Inject, ViewChild} from "@angular/core";
import {PropertiesService} from "../../services/properties.service";
import {
ButtonModel,
PolicyInstance,
PropertyBEModel,
PropertyFEModel,
- PropertyInputDetail,
Service,
SimpleFlatProperty
} from "app/models";
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 {PropertyDropdownValue, ToscaFunctionComponent} from "./tosca-function/tosca-function.component";
import {CapabilitiesGroup, Capability} from "../../../models/capability";
import {ToscaPresentationData} from "../../../models/tosca-presentation";
import {Observable} from "rxjs";
-import {ToscaGetFunctionType} from "../../../models/tosca-get-function-type.enum";
+import {ToscaGetFunctionType} from "../../../models/tosca-get-function-type";
import {TranslateService} from "../../shared/translator/translate.service";
-import {ModalComponent} from "../../components/ui/modal/modal.component";
+import {ToscaGetFunctionDtoBuilder} from '../../../models/tosca-get-function-dto';
+import {PropertySource} from '../../../models/property-source';
+import {ToscaGetFunctionTypeConverter} from '../../../models/tosca-get-function-type-converter';
const SERVICE_SELF_TITLE = "SELF";
@Component({
@Inject("$stateParams") _stateParams,
@Inject("$scope") private $scope: ng.IScope,
@Inject("$state") private $state: ng.ui.IStateService,
- @Inject("Notification") private Notification: any,
+ @Inject("Notification") private notification: any,
private componentModeService: ComponentModeService,
- private EventListenerService: EventListenerService,
+ private eventListenerService: EventListenerService,
private ModalServiceSdcUI: SdcUiServices.ModalService,
- private ModalService: ModalService,
+ private modalService: ModalService,
private keysPipe: KeysPipe,
private topologyTemplateService: TopologyTemplateService,
private translateService: TranslateService) {
/* This is the way you can access the component data, please do not use any data except metadata, all other data should be received from the new api calls on the first time
than if the data is already exist, no need to call the api again - Ask orit if you have any questions*/
this.component = _stateParams.component;
- this.EventListenerService.registerObserverCallback(EVENTS.ON_LIFECYCLE_CHANGE, this.onCheckout);
+ this.eventListenerService.registerObserverCallback(EVENTS.ON_LIFECYCLE_CHANGE, this.onCheckout);
this.updateViewMode();
this.changedData = [];
this.updateHasChangedData();
}
ngOnInit() {
- console.log("==>" + this.constructor.name + ": ngOnInit");
+ console.debug("==>" + this.constructor.name + ": ngOnInit");
this.btnToscaFunctionText = this.translateService.translate('TOSCA_FUNCTION_LABEL');
this.loadingInputs = true;
this.loadingPolicies = true;
});
this.loadDataTypesByComponentModel(this.component.model);
- };
+ }
ngOnDestroy() {
- this.EventListenerService.unRegisterObserver(EVENTS.ON_LIFECYCLE_CHANGE);
+ this.eventListenerService.unRegisterObserver(EVENTS.ON_LIFECYCLE_CHANGE);
this.stateChangeStartUnregister();
}
* Handle select node in navigation area, and select the row in table
*/
onPropertySelectedUpdate = ($event) => {
- console.log("==>" + this.constructor.name + ": onPropertySelectedUpdate");
+ console.debug("==>" + this.constructor.name + ": onPropertySelectedUpdate");
this.selectedFlatProperty = $event;
let parentProperty: PropertyFEModel = this.propertiesService.getParentPropertyFEModelFromPath(this.instanceFePropertiesMap[this.selectedFlatProperty.instanceName], this.selectedFlatProperty.path);
parentProperty.expandedChildPropertyId = this.selectedFlatProperty.path;
* When user select row in table, this will prepare the hirarchy object for the tree.
*/
selectPropertyRow = (propertyRowSelectedEvent: PropertyRowSelectedEvent) => {
- console.log("==>" + this.constructor.name + ": selectPropertyRow " + propertyRowSelectedEvent.propertyModel.name);
+ console.debug("==>" + this.constructor.name + ": selectPropertyRow " + propertyRowSelectedEvent.propertyModel.name);
let property = propertyRowSelectedEvent.propertyModel;
let instanceName = propertyRowSelectedEvent.instanceName;
this.propertyStructureHeader = null;
return;
}
- console.log("==>" + this.constructor.name + ": tabChanged " + event);
+ console.debug("==>" + this.constructor.name + ": tabChanged " + event);
this.currentMainTab = this.propertyInputTabs.tabs.find((tab) => tab.title === event.title);
this.isPropertiesTabSelected = this.currentMainTab.title === "Properties";
this.isInputsTabSelected = this.currentMainTab.title === "Inputs";
this.searchQuery = '';
};
- /**Select Tosca function value from defined values**/
+ /**
+ * Select Tosca function value from defined values
+ */
selectToscaFunctionAndValues = (): void => {
- let instancesIds = this.keysPipe.transform(this.instanceFePropertiesMap, []);
- angular.forEach(instancesIds, (instanceId: string): void => {
- let selectedInstanceData: any = this.instances.find(instance => instance.uniqueId == instanceId
- && instance instanceof ComponentInstance);
- if (selectedInstanceData) {
- let checkedProperties: PropertyBEModel[] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
- angular.forEach(checkedProperties, (property: PropertyBEModel) => {
- this.propertiesService.setCheckedPropertyType(property.type);
- if (property.toscaGetFunctionType != null) {
- this.loadingProperties = true;
- property.getInputValues = null;
- property.value = null;
- property.toscaGetFunctionType = null;
- this.updateInstancePropertiesWithInput(checkedProperties, selectedInstanceData);
- } else {
- const modalTitle = 'Set value using TOSCA functions';
- const modal = this.ModalService.createCustomModal(new ModalModel(
- 'sm',
- modalTitle,
- null,
- [
- new ButtonModel('Save', 'blue',
- () => {
- const selectedToscaFunction: string = modal.instance.dynamicContent.instance.selectToscaFunction;
- if (selectedToscaFunction === ToscaGetFunctionType.GET_INPUT.toLowerCase()) {
- this.updateSelectInputValues(modal, property, checkedProperties, selectedInstanceData);
- }
- modal.instance.close();
- }
- ),
- new ButtonModel('Cancel', 'outline grey', () => {
- modal.instance.close();
- }),
- ],
- null /* type */
- )); //modal
- this.ModalService.addDynamicContentToModal(modal, ToscaFunctionComponent);
- modal.instance.open();
+ const selectedInstanceData: ComponentInstance = this.getSelectedComponentInstance();
+ if (!selectedInstanceData) {
+ return;
+ }
+ const property: PropertyBEModel = this.buildCheckedInstanceProperty();
+ if (property.isToscaGetFunction()) {
+ this.clearCheckedInstancePropertyValue();
+ return;
+ }
+ this.openToscaGetFunctionModal();
+ }
+
+ private getSelectedComponentInstance(): ComponentInstance {
+ const instancesIds = this.keysPipe.transform(this.instanceFePropertiesMap, []);
+ const instanceId: string = instancesIds[0];
+ return <ComponentInstance> this.instances.find(instance => instance.uniqueId == instanceId && instance instanceof ComponentInstance);
+ }
+
+ private buildCheckedInstanceProperty(): PropertyBEModel {
+ return this.buildCheckedInstanceProperties()[0];
+ }
+
+ private buildCheckedInstanceProperties(): PropertyBEModel[] {
+ const instancesIds = this.keysPipe.transform(this.instanceFePropertiesMap, []);
+ const instanceId: string = instancesIds[0];
+ return this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
+ }
+
+ private openToscaGetFunctionModal() {
+ const modalTitle = 'Set value using TOSCA functions';
+ const modal = this.modalService.createCustomModal(new ModalModel(
+ 'sm',
+ modalTitle,
+ null,
+ [
+ new ButtonModel(this.translateService.translate('MODAL_SAVE'), 'blue',
+ () => {
+ const selectedToscaFunction = modal.instance.dynamicContent.instance.selectToscaFunction;
+ const selectedPropertyFromModal:PropertyDropdownValue = modal.instance.dynamicContent.instance.selectedProperty;
+ const toscaFunctionType: ToscaGetFunctionType = ToscaGetFunctionTypeConverter.convertFromString(selectedToscaFunction);
+ this.updateCheckedInstancePropertyGetFunctionValue(selectedPropertyFromModal, toscaFunctionType);
+ modal.instance.close();
}
- });
- }
+ ),
+ new ButtonModel(this.translateService.translate('MODAL_CANCEL'), 'outline grey', () => {
+ modal.instance.close();
+ }),
+ ],
+ null /* type */
+ ));
+ const checkedInstanceProperty = this.buildCheckedInstanceProperty();
+ this.modalService.addDynamicContentToModalAndBindInputs(modal, ToscaFunctionComponent, {
+ 'property': checkedInstanceProperty,
});
- };
+ modal.instance.open();
+ }
- private updateSelectInputValues(modal:ComponentRef<ModalComponent>, property:PropertyBEModel, checkedProperties:PropertyBEModel[], selectedInstanceData:any) {
- this.loadingProperties = true;
- let selectInputValue: InputFEModel = modal.instance.dynamicContent.instance.selectValue;
- property.getInputValues = [];
- const propertyInputDetail = new PropertyInputDetail();
- propertyInputDetail.inputId = selectInputValue.uniqueId;
- propertyInputDetail.inputName = selectInputValue.name;
- propertyInputDetail.inputType = selectInputValue.type;
- property.getInputValues.push(propertyInputDetail);
- property.value = selectInputValue.name.indexOf("->") !== -1
- ? '{"get_input":[' + selectInputValue.name.replace("->", ", ") + ']}'
- : '{"get_input":"' + selectInputValue.name+ '"}' ;
- property.toscaGetFunctionType = ToscaGetFunctionType.GET_INPUT;
- this.updateInstancePropertiesWithInput(checkedProperties, selectedInstanceData);
+ private clearCheckedInstancePropertyValue() {
+ const checkedInstanceProperty: PropertyBEModel = this.buildCheckedInstanceProperty();
+ checkedInstanceProperty.getInputValues = null;
+ checkedInstanceProperty.value = null;
+ checkedInstanceProperty.toscaGetFunction = null;
+ this.updateInstanceProperty(checkedInstanceProperty);
+ }
+
+ private updateCheckedInstancePropertyGetFunctionValue(propertyToGet: PropertyDropdownValue, toscaGetFunctionType: ToscaGetFunctionType) {
+ const toscaGetFunctionBuilder: ToscaGetFunctionDtoBuilder =
+ new ToscaGetFunctionDtoBuilder()
+ .withPropertyUniqueId(propertyToGet.propertyId)
+ .withFunctionType(toscaGetFunctionType)
+ .withPropertySource(PropertySource.SELF)
+ .withPropertyName(propertyToGet.propertyName)
+ .withSourceName(this.component.name)
+ .withSourceUniqueId(this.component.uniqueId);
+
+ const checkedProperty: PropertyBEModel = this.buildCheckedInstanceProperty();
+ if (propertyToGet.propertyPath && propertyToGet.propertyPath.length) {
+ toscaGetFunctionBuilder.withPropertyPathFromSource(propertyToGet.propertyPath);
+ }
+ checkedProperty.toscaGetFunction = toscaGetFunctionBuilder.build();
+ this.updateInstanceProperty(checkedProperty);
}
- updateInstancePropertiesWithInput(checkedProperties: PropertyBEModel[], selectedInstanceData: any) {
+ updateInstanceProperty(instanceProperty: PropertyBEModel) {
+ this.loadingProperties = true;
this.componentInstanceServiceNg2.updateInstanceProperties(this.component.componentType, this.component.uniqueId,
- this.selectedInstanceData.uniqueId, checkedProperties)
+ this.selectedInstanceData.uniqueId, [instanceProperty])
.subscribe(() => {
- this.changeSelectedInstance(selectedInstanceData);
+ this.changeSelectedInstance(this.getSelectedComponentInstance());
}, (error) => {
- this.Notification.error({
- message: 'Failed to select/deselect get_input call: ' + error,
- title: 'Failure'
+ const errorMsg =
+ this.translateService.translate('TOSCA_FUNCTION_SELECT_ERROR', {'propertyName': instanceProperty.name, 'error': error});
+ this.notification.error({
+ title: this.translateService.translate('FAILURE_LABEL'),
+ message: errorMsg
});
+ console.error(errorMsg, error);
}, () => {
this.loadingProperties = false;
this.btnToscaFunctionText = this.translateService.translate('TOSCA_FUNCTION_LABEL');
let checkedProperties: PropertyBEModel[] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
angular.forEach(checkedProperties, (property: PropertyBEModel) => {
if(this.checkedPropertiesCount == 1) {
- if (property.toscaGetFunctionType == null) {
- this.btnToscaFunctionText = this.translateService.translate('TOSCA_FUNCTION_LABEL');
+ if (property.isToscaGetFunction()) {
+ this.btnToscaFunctionText = this.translateService.translate('CLEAR_VALUE_LABEL');
} else {
- this.btnToscaFunctionText = this.translateService.translate('DESELECT_INPUT_LABEL');
+ this.btnToscaFunctionText = this.translateService.translate('TOSCA_FUNCTION_LABEL');
}
} else {
this.btnToscaFunctionText = this.translateService.translate('TOSCA_FUNCTION_LABEL');
/*** DECLARE PROPERTIES/INPUTS ***/
declareProperties = (): void => {
- console.log("==>" + this.constructor.name + ": declareProperties");
+ console.debug("==>" + this.constructor.name + ": declareProperties");
let selectedComponentInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
let selectedGroupInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
};
declareListProperties = (): void => {
- console.log('declareListProperties() - enter');
-
// get selected properties
let selectedComponentInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
let selectedGroupInstancesProperties: InstanceBePropertiesMap = new InstanceBePropertiesMap();
let insId :string;
angular.forEach(instancesIds, (instanceId: string): void => {
- console.log("instanceId="+instanceId);
insId = instanceId;
let selectedInstanceData: any = this.instances.find(instance => instance.uniqueId == instanceId);
let checkedProperties: PropertyBEModel[] = this.propertiesService.getCheckedProperties(this.instanceFePropertiesMap[instanceId]);
let inputsToCreate: InstancePropertiesAPIMap = new InstancePropertiesAPIMap(selectedComponentInstancesInputs, selectedComponentInstancesProperties, selectedGroupInstancesProperties, selectedPolicyInstancesProperties);
let modalTitle = 'Declare Properties as List Input';
- const modal = this.ModalService.createCustomModal(new ModalModel(
+ const modal = this.modalService.createCustomModal(new ModalModel(
'sm', /* size */
modalTitle, /* title */
null, /* content */
componentInstInputsMap: content.inputsToCreate,
listInput: reglistInput
};
- console.log("save button clicked. input=", input);
this.topologyTemplateService
.createListInput(this.component, input, this.isSelf())
null /* type */
));
// 3rd arg is passed to DeclareListComponent instance
- this.ModalService.addDynamicContentToModal(modal, DeclareListComponent, {properties: inputsToCreate, propertyNameList: propertyNameList});
+ this.modalService.addDynamicContentToModal(modal, DeclareListComponent, {properties: inputsToCreate, propertyNameList: propertyNameList});
modal.instance.open();
- console.log('declareListProperties() - leave');
};
/*** DECLARE PROPERTIES/POLICIES ***/
const changedProp = <PropertyFEModel>this.changedData.shift();
this.propertiesUtils.resetPropertyValue(changedProp, resInput.value);
});
- console.log('updated instance inputs:', response);
};
} else {
if (this.isSelf()) {
- console.log("changedProperties", changedProperties);
request = this.topologyTemplateService.updateServiceProperties(this.component.uniqueId, _.map(changedProperties, cp => {
delete cp.constraints;
return cp;
this.propertiesUtils.resetPropertyValue(changedProp, resProp.value);
});
resolve(response);
- console.log("updated instance properties: ", response);
};
}
} else if (this.selectedInstanceData instanceof GroupInstance) {
this.propertiesUtils.resetPropertyValue(changedProp, resProp.value);
});
resolve(response);
- console.log("updated group instance properties: ", response);
};
} else if (this.selectedInstanceData instanceof PolicyInstance) {
request = this.componentInstanceServiceNg2
this.propertiesUtils.resetPropertyValue(changedProp, resProp.value);
});
resolve(response);
- console.log("updated policy instance properties: ", response);
};
}
} else if (this.isInputsTabSelected) {
changedInput.required = resInput.required;
changedInput.requiredOrig = resInput.required;
});
- console.log("updated the component inputs and got this response: ", response);
}
}
if (curHasChangedData !== this.hasChangedData) {
this.hasChangedData = curHasChangedData;
if(this.hasChangedData) {
- this.EventListenerService.notifyObservers(EVENTS.ON_WORKSPACE_UNSAVED_CHANGES, this.hasChangedData, this.showUnsavedChangesAlert);
+ this.eventListenerService.notifyObservers(EVENTS.ON_WORKSPACE_UNSAVED_CHANGES, this.hasChangedData, this.showUnsavedChangesAlert);
} else {
- this.EventListenerService.notifyObservers(EVENTS.ON_WORKSPACE_UNSAVED_CHANGES, false);
+ this.eventListenerService.notifyObservers(EVENTS.ON_WORKSPACE_UNSAVED_CHANGES, false);
}
}
return this.hasChangedData;
doSaveChangedData = (onSuccessFunction?:Function, onError?:Function):void => {
this.saveChangedData().then(
() => {
- this.Notification.success({
+ this.notification.success({
message: 'Successfully saved changes',
title: 'Saved'
});
if(onSuccessFunction) onSuccessFunction();
},
() => {
- this.Notification.error({
+ this.notification.error({
message: 'Failed to save changes!',
title: 'Failure'
});
//used for declare button, to keep count of newly checked properties (and ignore declared properties)
updateCheckedPropertyCount = (increment: boolean): void => {
this.checkedPropertiesCount += (increment) ? 1 : -1;
- console.log("CheckedProperties count is now.... " + this.checkedPropertiesCount);
+ console.debug("CheckedProperties count is now.... " + this.checkedPropertiesCount);
this.selectInputBtnLabel();
};
//reset any unsaved changes to the input before deleting it
this.resetUnsavedChangesForInput(input);
- console.log("==>" + this.constructor.name + ": deleteInput");
+ console.debug("==>" + this.constructor.name + ": deleteInput");
let inputToDelete = new InputBEModel(input);
this.componentServiceNg2
.deletePolicy(this.component, policy)
.subscribe((response) => {
this.policies = this.policies.filter(policy => policy.uniqueId !== response.uniqueId);
- //Reload the whole instance for now - TODO: CHANGE THIS after the BE starts returning properties within the response, use commented code below instead!
this.changeSelectedInstance(this.selectedInstanceData);
this.loadingPolicies = false;
});
addProperty = (model: string) => {
this.loadDataTypesByComponentModel(model)
let modalTitle = 'Add Property';
- let modal = this.ModalService.createCustomModal(new ModalModel(
+ let modal = this.modalService.createCustomModal(new ModalModel(
'sm',
modalTitle,
null,
modal.instance.close();
}, (error) => {
modal.instance.dynamicContent.instance.isLoading = false;
- this.Notification.error({
+ this.notification.error({
message: 'Failed to add property:' + error,
title: 'Failure'
});
null
));
modal.instance.open();
- this.ModalService.addDynamicContentToModal(modal, PropertyCreatorComponent, {});
+ this.modalService.addDynamicContentToModal(modal, PropertyCreatorComponent, {});
}
/*** addInput ***/
addInput = () => {
let modalTitle = 'Add Input';
- let modal = this.ModalService.createCustomModal(new ModalModel(
+ let modal = this.modalService.createCustomModal(new ModalModel(
'sm',
modalTitle,
null,
modal.instance.close();
}, (error) => {
modal.instance.dynamicContent.instance.isLoading = false;
- this.Notification.error({
+ this.notification.error({
message: 'Failed to add input:' + error,
title: 'Failure'
});
],
null
));
- this.ModalService.addDynamicContentToModal(modal, PropertyCreatorComponent, {});
+ this.modalService.addDynamicContentToModal(modal, PropertyCreatorComponent, {});
modal.instance.open();
}
[ngValue]="toscaFunction">{{toscaFunction}}</option>
</select>
</div>
- <div *ngIf="selectToscaFunction" class="i-sdc-form-item">
+ <div *ngIf="showDropdown()" class="i-sdc-form-item">
<label class="i-sdc-form-label required">{{dropdownValuesLabel}}</label>
- <select [(ngModel)]="selectValue" name="selectValue">
- <option *ngFor="let value of dropdownValues"
- [ngValue]="value">{{value.name}}</option>
- </select>
+ <select [(ngModel)]="selectedProperty" name="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>
* ============LICENSE_END=========================================================
*/
-import {Component} from '@angular/core';
-import {
- ComponentMetadata, DataTypeModel, PropertyBEModel
-} from 'app/models';
+import {Component, Input} from '@angular/core';
+import {ComponentMetadata, DataTypeModel, 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} from "../../../../utils/constants";
import {DataTypeService} from "../../../services/data-type.service";
-import {ToscaGetFunctionType} from "../../../../models/tosca-get-function-type.enum";
+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';
@Component({
selector: 'tosca-function',
templateUrl: './tosca-function.component.html',
styleUrls: ['./tosca-function.component.less'],
})
-
export class ToscaFunctionComponent {
+ @Input() property: PropertyBEModel;
+
selectToscaFunction;
- selectValue;
- isLoading: boolean;
- propertyType: string;
- dropdownValues: Array<PropertyBEModel> = [];
+ selectedProperty: PropertyDropdownValue;
+ isLoading: boolean = false;
+ propertyDropdownList: Array<PropertyDropdownValue> = [];
toscaFunctions: Array<string> = [];
dropdownValuesLabel: string;
+ dropDownErrorMsg: string;
- private dataTypeProperties: Array<PropertyBEModel> = [];
private componentMetadata: ComponentMetadata;
constructor(private topologyTemplateService: TopologyTemplateService,
ngOnInit() {
this.componentMetadata = this.workspaceService.metadata;
- this.propertyType = this.propertiesService.getCheckedPropertyType();
this.loadToscaFunctions();
}
private loadToscaFunctions(): void {
this.toscaFunctions.push(ToscaGetFunctionType.GET_INPUT.toLowerCase());
+ this.toscaFunctions.push(ToscaGetFunctionType.GET_PROPERTY.toLowerCase());
}
onToscaFunctionChange(): void {
}
private loadDropdownValueLabel(): void {
- if (this.selectToscaFunction) {
- if (this.selectToscaFunction === ToscaGetFunctionType.GET_INPUT.toLowerCase()) {
- this.dropdownValuesLabel = this.translateService.translate('INPUT_DROPDOWN_LABEL');
- }
+ if (!this.selectToscaFunction) {
+ 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');
}
}
private loadDropdownValues(): void {
- if (this.selectToscaFunction) {
- this.dropdownValues = [];
- if (this.selectToscaFunction === ToscaGetFunctionType.GET_INPUT.toLowerCase()) {
- this.loadInputValues(this.propertyType);
- }
+ if (!this.selectToscaFunction) {
+ return;
}
+ this.resetDropDown();
+ this.loadPropertiesInDropdown();
}
- private loadInputValues(propertyType: string): void {
- this.isLoading = true;
- this.topologyTemplateService.getComponentInputsValues(this.componentMetadata.componentType, this.componentMetadata.uniqueId)
- .subscribe((response) => {
- response.inputs.forEach((inputProperty: any) => {
- if (propertyType === inputProperty.type) {
- this.dropdownValues.push(inputProperty);
- } else if (PROPERTY_DATA.SIMPLE_TYPES.indexOf(inputProperty.type) === -1 && inputProperty.type !== propertyType) {
- this.buildInputDataForComplexType(inputProperty, propertyType);
- }
- });
- }, () => {
- //error ignored
- }, () => {
- this.isLoading = false;
- });
+ private resetDropDown() {
+ this.dropDownErrorMsg = undefined;
+ this.propertyDropdownList = [];
}
- private buildInputDataForComplexType(inputProperty: PropertyBEModel, propertyType: string) {
- let dataTypeFound: DataTypeModel = this.dataTypeService.getDataTypeByModelAndTypeName(this.componentMetadata.model, inputProperty.type);
- if (dataTypeFound && dataTypeFound.properties) {
- dataTypeFound.properties.forEach(dataTypeProperty => {
- let inputData = inputProperty.name + "->" + dataTypeProperty.name;
- dataTypeProperty.name = inputData;
- if (this.dataTypeProperties.indexOf(dataTypeProperty) === -1 && dataTypeProperty.type === propertyType) {
- this.dropdownValues.push(dataTypeProperty);
+ private loadPropertiesInDropdown() {
+ this.startLoading();
+ let propertiesObservable: Observable<ComponentGenericResponse>
+ if (this.isGetInputSelected()) {
+ propertiesObservable = this.topologyTemplateService.getComponentInputsValues(this.componentMetadata.componentType, this.componentMetadata.uniqueId);
+ } else if (this.isGetPropertySelected()) {
+ propertiesObservable = this.topologyTemplateService.findAllComponentProperties(this.componentMetadata.componentType, this.componentMetadata.uniqueId);
+ }
+ propertiesObservable
+ .subscribe( (response: ComponentGenericResponse) => {
+ let properties: PropertyBEModel[] = this.isGetInputSelected() ? response.inputs : response.properties;
+ if (!properties || properties.length === 0) {
+ const msgCode = this.isGetInputSelected() ? 'TOSCA_FUNCTION_NO_INPUT_FOUND' : 'TOSCA_FUNCTION_NO_PROPERTY_FOUND';
+ this.dropDownErrorMsg = this.translateService.translate(msgCode, {type: this.property.type});
+ return;
}
+ this.addPropertiesToDropdown(properties);
+ if (this.propertyDropdownList.length == 0) {
+ const msgCode = this.isGetInputSelected() ? 'TOSCA_FUNCTION_NO_INPUT_FOUND' : 'TOSCA_FUNCTION_NO_PROPERTY_FOUND';
+ this.dropDownErrorMsg = this.translateService.translate(msgCode, {type: this.property.type});
+ }
+ }, (error) => {
+ console.error('An error occurred while loading properties.', error);
+ }, () => {
+ this.stopLoading();
});
+ }
+
+ private addPropertyToDropdown(propertyDropdownValue: PropertyDropdownValue) {
+ this.propertyDropdownList.push(propertyDropdownValue);
+ this.propertyDropdownList.sort((a, b) => a.propertyLabel.localeCompare(b.propertyLabel));
+ }
+
+ private addPropertiesToDropdown(properties: PropertyBEModel[]) {
+ for (const property of properties) {
+ if (this.property.type === property.type) {
+ this.addPropertyToDropdown({
+ propertyName: property.name,
+ propertyId: property.uniqueId,
+ propertyLabel: property.name,
+ toscaFunction: this.selectToscaFunction,
+ propertyPath: [property.name]
+ });
+ } else if (this.isComplexType(property.type)) {
+ this.fillPropertyDropdownWithMatchingChildProperties(property);
+ }
}
}
+
+ private fillPropertyDropdownWithMatchingChildProperties(inputProperty: PropertyBEModel, parentPropertyList: Array<PropertyBEModel> = []) {
+ const dataTypeFound: DataTypeModel = this.dataTypeService.getDataTypeByModelAndTypeName(this.componentMetadata.model, inputProperty.type);
+ if (!dataTypeFound || !dataTypeFound.properties) {
+ return;
+ }
+ parentPropertyList.push(inputProperty);
+ dataTypeFound.properties.forEach(dataTypeProperty => {
+ if (dataTypeProperty.type === this.property.type) {
+ this.addPropertyToDropdown({
+ propertyName: dataTypeProperty.name,
+ propertyId: parentPropertyList[0].uniqueId,
+ propertyLabel: parentPropertyList.map(property => property.name).join('->') + '->' + dataTypeProperty.name,
+ toscaFunction: this.selectToscaFunction,
+ propertyPath: [...parentPropertyList.map(property => property.name), dataTypeProperty.name]
+ });
+ } else if (PROPERTY_DATA.SIMPLE_TYPES.indexOf(dataTypeProperty.type) === -1) {
+ this.fillPropertyDropdownWithMatchingChildProperties(dataTypeProperty, [...parentPropertyList])
+ }
+ });
+ }
+
+ private isGetPropertySelected() {
+ return this.selectToscaFunction === ToscaGetFunctionType.GET_PROPERTY.toLowerCase();
+ }
+
+ private isGetInputSelected() {
+ return this.selectToscaFunction === ToscaGetFunctionType.GET_INPUT.toLowerCase();
+ }
+
+ private isComplexType(propertyType: string) {
+ return PROPERTY_DATA.SIMPLE_TYPES.indexOf(propertyType) === -1;
+ }
+
+ private stopLoading() {
+ this.isLoading = false;
+ }
+
+ private startLoading() {
+ this.isLoading = true;
+ }
+
+ showDropdown(): boolean {
+ return this.selectToscaFunction && !this.isLoading && !this.dropDownErrorMsg;
+ }
+
+}
+
+export interface PropertyDropdownValue {
+ propertyName: string;
+ propertyId: string;
+ propertyLabel: string;
+ toscaFunction: ToscaGetFunctionType;
+ propertyPath: Array<string>;
}
}
getComponentProperties(component: Component): Observable<ComponentGenericResponse> {
- return this.getComponentDataByFieldsName(component.componentType, component.uniqueId, [COMPONENT_FIELDS.COMPONENT_PROPERTIES]);
+ return this.findAllComponentProperties(component.componentType, component.uniqueId);
+ }
+
+ findAllComponentProperties(componentType: string, componentUniqueId: string): Observable<ComponentGenericResponse> {
+ return this.getComponentDataByFieldsName(componentType, componentUniqueId, [COMPONENT_FIELDS.COMPONENT_PROPERTIES]);
}
getCapabilitiesAndRequirements(componentType: string, componentId: string): Observable<ComponentGenericResponse> {
//Creates a component dynamically (aka during runtime). If a view container is not specified, it will append the new component to the app root.
//To subscribe to an event from invoking component: componentRef.instance.clicked.subscribe((m) => console.log(m.name));
public createDynamicComponent<T>(componentType: Type<T>, viewContainerRef?:ViewContainerRef): ComponentRef<T> {
-
viewContainerRef = viewContainerRef || this.getRootViewContainerRef();
viewContainerRef.clear();
- let factory: ComponentFactory<T> = this.componentFactoryResolver.resolveComponentFactory(componentType); //Ref: https://angular.io/guide/dynamic-component-loader
- let componentRef: ComponentRef<T> = viewContainerRef.createComponent(factory);
- return componentRef;
+ const factory: ComponentFactory<T> = this.componentFactoryResolver.resolveComponentFactory(componentType); //Ref: https://angular.io/guide/dynamic-component-loader
+ return viewContainerRef.createComponent(factory);
}
private getRootViewContainerRef(): ViewContainerRef {
return this.applicationRef.components[0].instance.viewContainerRef;
}
-};
\ No newline at end of file
+};
return modalInstance;
}
+ public addDynamicContentToModalAndBindInputs = (modalInstance: ComponentRef<ModalComponent>, dynamicComponentType: Type<any>,
+ dynamicComponentInput?: Object) => {
+
+ const dynamicContent = this.dynamicComponentService
+ .createDynamicComponent(dynamicComponentType, modalInstance.instance.dynamicContentContainer);
+ for (const key of Object.keys(dynamicComponentInput)) {
+ dynamicContent.instance[key] = dynamicComponentInput[key];
+ }
+ modalInstance.instance.dynamicContent = dynamicContent;
+ return modalInstance;
+ }
+
public addDynamicTemplateToModal = (modalInstance: ComponentRef<ModalComponent>, templateRef: TemplateRef<void>) => {
modalInstance.instance.dynamicContentContainer.clear();
modalInstance.instance.dynamicContentContainer.createEmbeddedView(templateRef);
@Injectable()
export class PropertiesService {
- checkedPropertyType: string;
-
constructor() {
}
return selectedProps;
}
- setCheckedPropertyType(type: string){
- this.checkedPropertyType = type;
- }
-
- getCheckedPropertyType(){
- return this.checkedPropertyType;
- }
-
}
selectedInstance:ComponentInstance;
selectedComponentInputs:Array<InputModel>;
- public loadDataTypesCache = (modelName: string): void => {
+ public loadDataTypesCache = async (modelName: string): Promise<void> => {
let model;
if (modelName) {
model = {'model': modelName}
}
- this.$http.get(this.baseUrl+"dataTypes", {params: model})
- .then((response:any) => {
+ await this.$http.get(this.baseUrl + "dataTypes", {params: model})
+ .then((response: any) => {
this.dataTypes = response.data;
delete this.dataTypes['tosca.datatypes.Root'];
});
"=========== FAILURE MESSAGES ===========": "",
"DELETE_FAILURE_MESSAGE_TEXT": "Deletion Failed",
"DELETE_FAILURE_MESSAGE_TITLE": "Delete",
+ "FAILURE_LABEL": "Failure",
+ "TOSCA_FUNCTION_SELECT_ERROR": "Failed to select/deselect a TOSCA function from property: {{propertyName}}. Error: {{error}}",
"=========== ON BOARDING MODAL ===========": "",
"ON_BOARDING_MODAL_SUB_TITLE": "Select one of the software product component below:",
"ON_BOARDING_GENERAL_INFO": "Displays a table of VSPs created using Onboarding.\nEach row displays details for a single VSP.\nWhen expanded you can either import CSAR files that are yet to be imported or update CSAR files that were previously imported.",
"DELETE_POLICY_MSG": "Are you sure you want to delete policy '{{policyName}}'?",
"=========== PROPERTIES ASSIGNMENT TOSCA FUNCTION BUTTON ===========": "",
"TOSCA_FUNCTION_LABEL": "TOSCA function",
- "DESELECT_INPUT_LABEL": "Deselect Input",
+ "CLEAR_VALUE_LABEL": "Clear Value",
"INPUT_DROPDOWN_LABEL": "Input",
+ "TOSCA_FUNCTION_PROPERTY_DROPDOWN_LABEL": "Property",
+ "TOSCA_FUNCTION_NO_INPUT_FOUND": "No input found with type {{type}}",
+ "TOSCA_FUNCTION_NO_PROPERTY_FOUND": "No property found with type {{type}}",
"=========== AUTOMATED UPGRADE ===========": "",
"RESOURCE_UPGRADE_TITLE": "Upgrade Services",
"SERVICE_UPGRADE_TITLE": "Update Service References",
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;
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)) {
return null;
}
+ public ToscaGetFunctionType getToscaGetFunctionType() {
+ if (toscaGetFunction != null) {
+ return toscaGetFunction.getFunctionType();
+ }
+ return toscaGetFunctionType;
+ }
+
public Boolean isHidden() {
return hidden;
}
public List<Annotation> getAnnotations() {
return (List<Annotation>) getToscaPresentationValue(JsonPresentationFields.ANNOTATIONS);
}
+
+ public boolean isGetFunction() {
+ return this.toscaGetFunctionType != null || this.toscaGetFunction != null;
+ }
+
+ public boolean hasGetFunction() {
+ return this.toscaGetFunction != null;
+ }
+
}
--- /dev/null
+/*
+ * -
+ * ============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<String> 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<String, Object> 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<String, Object> buildGetInputFunctionValue() {
+ if (this.propertyPathFromSource.size() == 1) {
+ return Map.of(this.functionType.getFunctionName(), this.propertyPathFromSource.get(0));
+ }
+ return Map.of(this.functionType.getFunctionName(), this.propertyPathFromSource);
+ }
+
+}
--- /dev/null
+/*
+ * -
+ * ============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;
+
+}
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;
}
--- /dev/null
+/*
+ * -
+ * ============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<String> 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<String> 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<String> 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
private static final Map<String, PropertyType> M_MAP = Collections.unmodifiableMap(initializeMapping());
private static final Set<String> SIMPLE_PROPERTY_TYPES = Collections.unmodifiableSet(initializeSimplePropertyTypes());
- private String displayName;
+ private final String displayName;
/**
* Initilize property type display name mapping.
public static Set<String> getSimplePropertyTypes() {
return SIMPLE_PROPERTY_TYPES;
}
+
+ public static boolean typeHasSchema(final String type) {
+ return LIST.getDisplayName().equals(type) || MAP.getDisplayName().equals(type);
+ }
}