aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorfranciscovila <javier.paradela.vila@est.tech>2023-02-15 17:14:59 +0000
committerMichael Morris <michael.morris@est.tech>2023-05-16 15:05:13 +0000
commit8183ade590e367f28e13484201d2c9526be221dc (patch)
tree735d600ec26ed9caea7657f7224a7e5f6f05cb62
parent5768f2e5a056df6b23f7f8a87529d5ca00063c68 (diff)
Support additional operands for node filters
Issue-ID: SDC-4395 Signed-off-by: franciscovila <javier.paradela.vila@est.tech> Change-Id: I66b172d100ffd2757de88bc7640761f31fd20c28
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/components/validation/NodeFilterValidator.java237
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaExportHandler.java42
-rw-r--r--catalog-model/src/main/java/org/openecomp/sdc/be/model/dto/FilterConstraintDto.java15
-rw-r--r--catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/ListValidator.java21
-rw-r--r--catalog-model/src/main/java/org/openecomp/sdc/be/ui/mapper/FilterConstraintMapper.java24
-rw-r--r--catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/UIConstraint.java1
-rw-r--r--catalog-ui/src/app/models/filter-constraint.ts2
-rw-r--r--catalog-ui/src/app/models/ui-models/property-filter-constraint-ui.ts3
-rw-r--r--catalog-ui/src/app/ng2/components/logic/properties-table/dynamic-property/dynamic-property.component.html2
-rw-r--r--catalog-ui/src/app/ng2/components/logic/properties-table/dynamic-property/dynamic-property.component.ts1
-rw-r--r--catalog-ui/src/app/ng2/components/logic/service-dependencies/service-dependencies.component.ts10
-rw-r--r--catalog-ui/src/app/ng2/components/ui/dynamic-element/dynamic-element.component.ts51
-rw-r--r--catalog-ui/src/app/ng2/components/ui/form-components/form-elements.module.ts6
-rw-r--r--catalog-ui/src/app/ng2/components/ui/form-components/integer-input/ui-element-integer-input.component.html2
-rw-r--r--catalog-ui/src/app/ng2/components/ui/form-components/range-input/ui-element-range-input.component.html81
-rw-r--r--catalog-ui/src/app/ng2/components/ui/form-components/range-input/ui-element-range-input.component.less37
-rw-r--r--catalog-ui/src/app/ng2/components/ui/form-components/range-input/ui-element-range-input.component.ts112
-rw-r--r--catalog-ui/src/app/ng2/components/ui/form-components/valid-values-input/ui-element-valid-values-input.component.html39
-rw-r--r--catalog-ui/src/app/ng2/components/ui/form-components/valid-values-input/ui-element-valid-values-input.component.less37
-rw-r--r--catalog-ui/src/app/ng2/components/ui/form-components/valid-values-input/ui-element-valid-values-input.component.ts102
-rw-r--r--catalog-ui/src/app/ng2/pages/properties-assignment/services/properties.utils.ts2
-rw-r--r--catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-function.component.html1
-rw-r--r--catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-function.component.ts17
-rw-r--r--catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-get-function/tosca-get-function.component.ts8
-rw-r--r--catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.html96
-rw-r--r--catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.ts244
-rw-r--r--catalog-ui/src/app/utils/constants.ts5
-rw-r--r--catalog-ui/src/app/utils/filter-constraint-helper.ts15
-rw-r--r--common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/PropertyFilterConstraintDataDefinition.java1
-rw-r--r--common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/PropertyFilterConstraintDataDefinitionJsonDeserializer.java25
-rw-r--r--common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/ConstraintType.java8
-rw-r--r--common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/FilterValueType.java3
32 files changed, 1105 insertions, 145 deletions
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/validation/NodeFilterValidator.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/validation/NodeFilterValidator.java
index 86cedf26d7..30fe3dcad1 100644
--- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/validation/NodeFilterValidator.java
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/validation/NodeFilterValidator.java
@@ -21,6 +21,7 @@ package org.openecomp.sdc.be.components.validation;
import com.google.gson.Gson;
import fj.data.Either;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
@@ -32,6 +33,7 @@ import org.apache.commons.lang3.StringUtils;
import org.openecomp.sdc.be.dao.api.ActionStatus;
import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
import org.openecomp.sdc.be.datatypes.elements.ToscaGetFunctionDataDefinition;
+import org.openecomp.sdc.be.datatypes.enums.ConstraintType;
import org.openecomp.sdc.be.datatypes.enums.PropertyFilterTargetType;
import org.openecomp.sdc.be.datatypes.enums.PropertySource;
import org.openecomp.sdc.be.impl.ComponentsUtils;
@@ -139,26 +141,64 @@ public class NodeFilterValidator {
private Either<Boolean, ResponseFormat> validatePropertyConstraint(final Component parentComponent, final String componentInstanceId,
final FilterConstraintDto filterConstraint, final String capabilityName) {
String source = SOURCE;
+ ResponseFormat responseFormat = null;
+ List<ToscaGetFunctionDataDefinition> toscaGetFunctionDataDefinitionList = new ArrayList<>();
final ToscaGetFunctionDataDefinition toscaGetFunction = filterConstraint.getAsToscaGetFunction().orElse(null);
if (toscaGetFunction == null || !(filterConstraint.getValue() instanceof ToscaGetFunctionDataDefinition)) {
- return Either.right(componentsUtils.getResponseFormat(ActionStatus.TOSCA_FUNCTION_EXPECTED_ERROR));
+ final List<ToscaGetFunctionDataDefinition> toscaGetFunctionList = filterConstraint.getAsListToscaGetFunction().orElse(null);
+ if (toscaGetFunctionList == null || toscaGetFunctionList.isEmpty() || !(filterConstraint.getValue() instanceof List)) {
+ return Either.right(componentsUtils.getResponseFormat(ActionStatus.TOSCA_FUNCTION_EXPECTED_ERROR));
+ }
+ else {
+ toscaGetFunctionDataDefinitionList = toscaGetFunctionList;
+ }
}
- final Optional<? extends ToscaPropertyData> sourceSelectedProperty = findPropertyFromGetFunction(parentComponent, toscaGetFunction);
- if (sourceSelectedProperty.isPresent()) {
- Optional<? extends PropertyDefinition> targetComponentInstanceProperty =
- getInstanceProperties(parentComponent, componentInstanceId, capabilityName, filterConstraint.getPropertyName());
+ else{
+ toscaGetFunctionDataDefinitionList.add(toscaGetFunction);
+ }
+ Boolean allGood = true;
+ for (ToscaGetFunctionDataDefinition _toscaGetFunction: toscaGetFunctionDataDefinitionList) {
+
+ final Optional<? extends ToscaPropertyData> sourceSelectedProperty =
+ findPropertyFromGetFunction(parentComponent, _toscaGetFunction);
+ if (sourceSelectedProperty.isPresent()) {
+ Optional<? extends PropertyDefinition> targetComponentInstanceProperty =
+ getInstanceProperties(parentComponent, componentInstanceId, capabilityName,
+ filterConstraint.getPropertyName());
+
+ source = targetComponentInstanceProperty.isEmpty() ? TARGET : SOURCE;
+ if (targetComponentInstanceProperty.isPresent()) {
+ responseFormat =
+ validatePropertyData(sourceSelectedProperty.get(), targetComponentInstanceProperty.get(),
+ filterConstraint.getOperator().isLengthConstraint());
+ if (responseFormat != null) {
+ allGood = false;
+ break;
+ }
- source = targetComponentInstanceProperty.isEmpty() ? TARGET : SOURCE;
- if (targetComponentInstanceProperty.isPresent()) {
- final ResponseFormat responseFormat = validatePropertyData(sourceSelectedProperty.get(), targetComponentInstanceProperty.get());
- if (responseFormat != null) {
- return Either.right(responseFormat);
}
- return Either.left(true);
+ else {
+ allGood = false;
+ final String missingProperty =
+ SOURCE.equals(source) ? filterConstraint.getValue().toString() : filterConstraint.getPropertyName();
+ responseFormat =
+ componentsUtils.getResponseFormat(ActionStatus.FILTER_PROPERTY_NOT_FOUND, source, missingProperty);
+ break;
+ }
+ }
+ else {
+ allGood = false;
+ final String missingProperty =
+ SOURCE.equals(source) ? filterConstraint.getValue().toString() : filterConstraint.getPropertyName();
+ responseFormat =
+ componentsUtils.getResponseFormat(ActionStatus.FILTER_PROPERTY_NOT_FOUND, source, missingProperty);
+ break;
}
}
- final String missingProperty = SOURCE.equals(source) ? filterConstraint.getValue().toString() : filterConstraint.getPropertyName();
- return Either.right(componentsUtils.getResponseFormat(ActionStatus.FILTER_PROPERTY_NOT_FOUND, source, missingProperty));
+ if (allGood) {
+ return Either.left(true);
+ }
+ return Either.right(responseFormat);
}
private Optional<? extends ToscaPropertyData> findPropertyFromGetFunction(final Component parentComponent,
@@ -276,80 +316,118 @@ public class NodeFilterValidator {
return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_DOES_NOT_HAVE_INPUTS, parentComponent.getName()));
}
if (!(filterConstraint.getValue() instanceof ToscaGetFunctionDataDefinition)) {
- return Either.right(componentsUtils.getResponseFormat(ActionStatus.TOSCA_FUNCTION_EXPECTED_ERROR));
- }
- final ToscaGetFunctionDataDefinition getFunction = (ToscaGetFunctionDataDefinition) filterConstraint.getValue();
- final List<String> propertyPathFromSource = getFunction.getPropertyPathFromSource();
- Optional<? extends PropertyDefinition> sourceSelectedProperty =
- sourceInputDefinition.stream().filter(input -> input.getName().equals(propertyPathFromSource.get(0))).findFirst();
- if (sourceSelectedProperty.isEmpty()) {
- LOGGER.debug(INPUT_NOT_FOUND_LOG,
- propertyPathFromSource.get(0), parentComponent.getName(), parentComponent.getUniqueId());
- return Either.right(
- componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INPUT_NOT_FOUND, propertyPathFromSource.get(0), parentComponent.getName())
- );
- }
- if (propertyPathFromSource.size() > 1) {
- final Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> allDataTypesEither =
- applicationDataTypeCache.getAll(parentComponent.getModel());
- if (allDataTypesEither.isRight()) {
- LOGGER.error("Could not load data types for model {}", parentComponent.getModel());
- return Either.right(componentsUtils.getResponseFormat(ActionStatus.DATA_TYPES_NOT_LOADED, parentComponent.getModel()));
+ if (filterConstraint.getValue() instanceof List) {
+ Optional optValid = ((List<?>) filterConstraint.getValue()).stream().filter(filterConstraintValue ->
+ !(filterConstraintValue instanceof ToscaGetFunctionDataDefinition)).findAny();
+ if (optValid.isPresent()) {
+ return Either.right(componentsUtils.getResponseFormat(ActionStatus.TOSCA_FUNCTION_EXPECTED_ERROR));
+ }
+ }
+ else {
+ return Either.right(componentsUtils.getResponseFormat(ActionStatus.TOSCA_FUNCTION_EXPECTED_ERROR));
}
- sourceSelectedProperty =
- findSubProperty(propertyPathFromSource.subList(1, propertyPathFromSource.size()), sourceSelectedProperty.get().getType(),
- allDataTypesEither.left().value());
- }
- final Optional<? extends PropertyDefinition> targetComponentInstanceProperty;
- if (PropertyFilterTargetType.CAPABILITY.equals(filterConstraint.getTargetType())) {
- final CapabilityDefinition capability = parentComponent.getComponentInstances().stream()
- .filter(componentInstance -> componentInstance.getUniqueId().equals(componentInstanceId))
- .map(componentInstance -> componentInstance.getCapabilities().values())
- .flatMap(Collection::stream)
- .flatMap(Collection::stream)
- .filter(capabilityDefinition -> capabilityDefinition.getName().equals(filterConstraint.getCapabilityName()))
- .findFirst().orElse(null);
- if (capability == null) {
+ }
+ if (filterConstraint.getValue() instanceof ToscaGetFunctionDataDefinition) {
+ final ToscaGetFunctionDataDefinition getFunction =
+ (ToscaGetFunctionDataDefinition) filterConstraint.getValue();
+ final List<String> propertyPathFromSource = getFunction.getPropertyPathFromSource();
+ Optional<? extends PropertyDefinition> sourceSelectedProperty =
+ sourceInputDefinition.stream().filter(input -> input.getName().equals(propertyPathFromSource.get(0)))
+ .findFirst();
+ if (sourceSelectedProperty.isEmpty()) {
+ LOGGER.debug(INPUT_NOT_FOUND_LOG,
+ propertyPathFromSource.get(0), parentComponent.getName(), parentComponent.getUniqueId());
return Either.right(
- componentsUtils.getResponseFormat(ActionStatus.CAPABILITY_NOT_FOUND_IN_COMPONENT,
- filterConstraint.getCapabilityName(), parentComponent.getComponentType().getValue(), parentComponent.getName())
+ componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INPUT_NOT_FOUND,
+ propertyPathFromSource.get(0), parentComponent.getName())
);
}
- targetComponentInstanceProperty = capability.getProperties().stream()
- .filter(property -> filterConstraint.getPropertyName().equals(property.getName()))
- .findFirst();
- } else {
- targetComponentInstanceProperty =
- parentComponent.getComponentInstancesProperties()
- .get(componentInstanceId).stream()
+ if (propertyPathFromSource.size() > 1) {
+ final Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> allDataTypesEither =
+ applicationDataTypeCache.getAll(parentComponent.getModel());
+ if (allDataTypesEither.isRight()) {
+ LOGGER.error("Could not load data types for model {}", parentComponent.getModel());
+ return Either.right(componentsUtils.getResponseFormat(ActionStatus.DATA_TYPES_NOT_LOADED,
+ parentComponent.getModel()));
+ }
+ sourceSelectedProperty =
+ findSubProperty(propertyPathFromSource.subList(1, propertyPathFromSource.size()),
+ sourceSelectedProperty.get().getType(),
+ allDataTypesEither.left().value());
+ }
+ final Optional<? extends PropertyDefinition> targetComponentInstanceProperty;
+ if (PropertyFilterTargetType.CAPABILITY.equals(filterConstraint.getTargetType())) {
+ final CapabilityDefinition capability = parentComponent.getComponentInstances().stream()
+ .filter(componentInstance -> componentInstance.getUniqueId().equals(componentInstanceId))
+ .map(componentInstance -> componentInstance.getCapabilities().values())
+ .flatMap(Collection::stream)
+ .flatMap(Collection::stream)
+ .filter(capabilityDefinition -> capabilityDefinition.getName()
+ .equals(filterConstraint.getCapabilityName()))
+ .findFirst().orElse(null);
+ if (capability == null) {
+ return Either.right(
+ componentsUtils.getResponseFormat(ActionStatus.CAPABILITY_NOT_FOUND_IN_COMPONENT,
+ filterConstraint.getCapabilityName(), parentComponent.getComponentType().getValue(),
+ parentComponent.getName())
+ );
+ }
+ targetComponentInstanceProperty = capability.getProperties().stream()
.filter(property -> filterConstraint.getPropertyName().equals(property.getName()))
.findFirst();
- }
- if (sourceSelectedProperty.isPresent() && targetComponentInstanceProperty.isPresent()) {
- final ResponseFormat responseFormat = validatePropertyData(sourceSelectedProperty.get(), targetComponentInstanceProperty.get());
- if (responseFormat != null) {
- return Either.right(responseFormat);
+ } else {
+ targetComponentInstanceProperty =
+ parentComponent.getComponentInstancesProperties()
+ .get(componentInstanceId).stream()
+ .filter(property -> filterConstraint.getPropertyName().equals(property.getName()))
+ .findFirst();
+ }
+ if (sourceSelectedProperty.isPresent() && targetComponentInstanceProperty.isPresent()) {
+ final ResponseFormat responseFormat =
+ validatePropertyData(sourceSelectedProperty.get(), targetComponentInstanceProperty.get(),
+ filterConstraint.getOperator().isLengthConstraint());
+ if (responseFormat != null) {
+ return Either.right(responseFormat);
+ }
+ return Either.left(true);
}
- return Either.left(true);
- }
- return Either.right(componentsUtils.getResponseFormat(ActionStatus.INPUTS_NOT_FOUND));
+ return Either.right(componentsUtils.getResponseFormat(ActionStatus.INPUTS_NOT_FOUND));
+ }
+ return Either.left(true);
}
private <T extends ToscaPropertyData> ResponseFormat validatePropertyData(final T sourcePropDefinition,
- final T targetPropDefinition) {
+ final T targetPropDefinition,
+ final boolean isLengthConstraint) {
final String sourceType = sourcePropDefinition.getType();
final String targetType = targetPropDefinition.getType();
- if (sourceType.equals(targetType)) {
- if (TYPES_WITH_SCHEMA.contains(sourceType)) {
- final String sourceSchemaType = sourcePropDefinition.getSchemaType();
- final String targetSchemaType = targetPropDefinition.getSchemaType();
- if (sourceSchemaType != null && !sourceSchemaType.equals(targetSchemaType)) {
- return componentsUtils.getResponseFormat(ActionStatus.SOURCE_TARGET_SCHEMA_MISMATCH,
- targetPropDefinition.getName(), targetSchemaType, sourcePropDefinition.getName(), sourceSchemaType);
+ if (!isLengthConstraint) {
+ if (sourceType.equals(targetType)) {
+ if (TYPES_WITH_SCHEMA.contains(sourceType)) {
+ final String sourceSchemaType = sourcePropDefinition.getSchemaType();
+ final String targetSchemaType = targetPropDefinition.getSchemaType();
+ if (sourceSchemaType != null && !sourceSchemaType.equals(targetSchemaType)) {
+ return componentsUtils.getResponseFormat(ActionStatus.SOURCE_TARGET_SCHEMA_MISMATCH,
+ targetPropDefinition.getName(), targetSchemaType, sourcePropDefinition.getName(),
+ sourceSchemaType);
+ }
}
+ return null;
+ }
+ }
+ else {
+ if (sourceType.equalsIgnoreCase("integer")) {
+ if (TYPES_WITH_SCHEMA.contains(sourceType)) {
+ final String sourceSchemaType = sourcePropDefinition.getSchemaType();
+ if (sourceSchemaType != null && !sourceSchemaType.equalsIgnoreCase("integer")) {
+ return componentsUtils.getResponseFormat(ActionStatus.SOURCE_TARGET_SCHEMA_MISMATCH,
+ targetPropDefinition.getName(), "integer", sourcePropDefinition.getName(),
+ sourceSchemaType);
+ }
+ }
+ return null;
}
- return null;
}
return componentsUtils.getResponseFormat(ActionStatus.SOURCE_TARGET_PROPERTY_TYPE_MISMATCH,
sourcePropDefinition.getName(), sourcePropDefinition.getType(), targetPropDefinition.getName(), targetPropDefinition.getType());
@@ -369,6 +447,13 @@ public class NodeFilterValidator {
return Either.right(componentsUtils.getResponseFormat(ActionStatus.UNSUPPORTED_OPERATOR_PROVIDED, filterConstraint.getPropertyName(),
filterConstraint.getOperator().getType()));
}
+ if (filterConstraint.getOperator().equals(ConstraintType.VALID_VALUES) || filterConstraint.getOperator().equals(ConstraintType.IN_RANGE)) {
+ return isValidValueCheck("list", componentInstanceProperty.getType(), parentComponent.getModel(),
+ filterConstraint.getValue(), filterConstraint.getPropertyName());
+ }
+ if (filterConstraint.getOperator().isLengthConstraint() && componentInstanceProperty.getType().equals("list")) {
+ return Either.left(true);
+ }
return isValidValueCheck(componentInstanceProperty.getType(), componentInstanceProperty.getSchemaType(), parentComponent.getModel(),
filterConstraint.getValue(), filterConstraint.getPropertyName());
}
@@ -386,6 +471,10 @@ public class NodeFilterValidator {
return Either.right(componentsUtils.getResponseFormat(ActionStatus.UNSUPPORTED_OPERATOR_PROVIDED, filterConstraint.getPropertyName(),
filterConstraint.getOperator().getType()));
}
+ if (filterConstraint.getOperator().equals(ConstraintType.VALID_VALUES) || filterConstraint.getOperator().equals(ConstraintType.IN_RANGE)) {
+ return isValidValueCheck("list", componentProperty.getType(), component.getModel(),
+ filterConstraint.getValue(), filterConstraint.getPropertyName());
+ }
return isValidValueCheck(componentProperty.getType(), componentProperty.getSchemaType(), component.getModel(),
filterConstraint.getValue(), filterConstraint.getPropertyName());
}
@@ -517,7 +606,9 @@ public class NodeFilterValidator {
String.join("->", toscaGetFunction.getPropertyPathFromSource())));
}
- final ResponseFormat responseFormat = validatePropertyData(sourceSelectedProperty.get(), targetComponentProperty.get());
+ final ResponseFormat responseFormat =
+ validatePropertyData(sourceSelectedProperty.get(), targetComponentProperty.get(),
+ filterConstraint.getOperator().isLengthConstraint());
if (responseFormat != null) {
return Either.right(responseFormat);
}
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaExportHandler.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaExportHandler.java
index 6c1f4e3211..4b8249823e 100644
--- a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaExportHandler.java
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaExportHandler.java
@@ -82,6 +82,7 @@ import org.openecomp.sdc.be.datatypes.elements.SubstitutionFilterPropertyDataDef
import org.openecomp.sdc.be.datatypes.elements.ToscaArtifactDataDefinition;
import org.openecomp.sdc.be.datatypes.elements.ToscaFunction;
import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
+import org.openecomp.sdc.be.datatypes.enums.ConstraintType;
import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
@@ -114,6 +115,7 @@ import org.openecomp.sdc.be.model.jsonjanusgraph.utils.ModelConverter;
import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation;
import org.openecomp.sdc.be.model.operations.impl.ModelOperation;
+import org.openecomp.sdc.be.model.tosca.ToscaType;
import org.openecomp.sdc.be.model.tosca.converters.ToscaMapValueConverter;
import org.openecomp.sdc.be.tosca.PropertyConvertor.PropertyType;
import org.openecomp.sdc.be.tosca.builder.ToscaRelationshipBuilder;
@@ -225,14 +227,6 @@ public class ToscaExportHandler {
.forEach(operations -> operations.values().forEach(operation -> operation.setImplementation(null)));
}
- private static Object buildNodeFilterValue(final PropertyFilterConstraintDataDefinition filterConstraint) {
- if (filterConstraint.getValue() instanceof ToscaFunction) {
- return Map.of(filterConstraint.getOperator().getType(), ((ToscaFunction) filterConstraint.getValue()).getJsonObjectValue());
- } else {
- return Map.of(filterConstraint.getOperator().getType(), filterConstraint.getValue());
- }
- }
-
public Either<ToscaRepresentation, ToscaError> exportComponent(Component component) {
return convertToToscaTemplate(component).left().map(this::createToscaRepresentation);
}
@@ -1776,6 +1770,38 @@ public class ToscaExportHandler {
return propertiesCopy;
}
+ private static Object buildNodeFilterValue(final PropertyFilterConstraintDataDefinition filterConstraint) {
+ if (filterConstraint.getValue() instanceof ToscaFunction) {
+ return Map.of(filterConstraint.getOperator().getType(), ((ToscaFunction) filterConstraint.getValue()).getJsonObjectValue());
+ }
+ if (filterConstraint.getValue() instanceof List) {
+ if (((List<?>) filterConstraint.getValue()).get(0) instanceof ToscaFunction) {
+ List<Object> toscaFunctionList = new ArrayList<>();
+ ((List<?>) filterConstraint.getValue()).forEach(toscaFunctionValue -> toscaFunctionList.add(
+ ((ToscaFunction) toscaFunctionValue).getJsonObjectValue()));
+ return Map.of(filterConstraint.getOperator().getType(), toscaFunctionList);
+ }
+ }
+ if (doesTypeNeedConvertingToIntOrFloat(filterConstraint.getOriginalType(), filterConstraint.getValue())) {
+ ToscaType toscaType = ToscaType.getToscaType(
+ filterConstraint.getValue() instanceof List ? ToscaType.LIST.getType() : filterConstraint.getOriginalType());
+ filterConstraint.setValue(toscaType.convert(String.valueOf(filterConstraint.getValue())));
+ }
+ else if (ConstraintType.LENGTH.getType().equals(filterConstraint.getOperator().getType()) ||
+ ConstraintType.MIN_LENGTH.getType().equals(filterConstraint.getOperator().getType()) ||
+ ConstraintType.MAX_LENGTH.getType().equals(filterConstraint.getOperator().getType())) {
+ filterConstraint.setValue(Integer.valueOf(String.valueOf(filterConstraint.getValue())));
+ }
+ return Map.of(filterConstraint.getOperator().getType(), filterConstraint.getValue());
+ }
+
+ private static boolean doesTypeNeedConvertingToIntOrFloat(String propertyType, Object value) {
+ if (value instanceof List && ((List<?>) value).get(0) instanceof LinkedHashMap && ((LinkedHashMap) ((List<?>) value).get(0)).get("type") != null ) {
+ return false;
+ }
+ return ToscaType.INTEGER.getType().equals(propertyType) || ToscaType.FLOAT.getType().equals(propertyType);
+ }
+
private Map<String, String[]> buildSubstitutionMappingPropertyMapping(final Component component) {
if (component == null || CollectionUtils.isEmpty(component.getInputs())) {
return Collections.emptyMap();
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/dto/FilterConstraintDto.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/dto/FilterConstraintDto.java
index b9ceb11276..4800c020d2 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/dto/FilterConstraintDto.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/dto/FilterConstraintDto.java
@@ -22,6 +22,8 @@
package org.openecomp.sdc.be.model.dto;
import com.fasterxml.jackson.databind.ObjectMapper;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Optional;
import lombok.Data;
import org.openecomp.sdc.be.datatypes.elements.ToscaGetFunctionDataDefinition;
@@ -38,6 +40,7 @@ public class FilterConstraintDto {
private ConstraintType operator;
private FilterValueType valueType;
private Object value;
+ private String originalType;
public boolean isCapabilityPropertyFilter() {
return capabilityName != null;
@@ -53,6 +56,18 @@ public class FilterConstraintDto {
return Optional.empty();
}
}
+ public Optional<List<ToscaGetFunctionDataDefinition>> getAsListToscaGetFunction() {
+ List<ToscaGetFunctionDataDefinition> toscaGetFunctionDataDefinitionList = new ArrayList<>();
+ if (value instanceof List) {
+ try {
+ ((List<?>) value).forEach(toscaValue -> toscaGetFunctionDataDefinitionList.add(new ObjectMapper().convertValue(toscaValue, ToscaGetFunctionDataDefinition.class)));
+ return Optional.of(toscaGetFunctionDataDefinitionList);
+ } catch (final Exception ignored) {
+ return Optional.empty();
+ }
+ }
+ return Optional.empty();
+ }
}
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/ListValidator.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/ListValidator.java
index 20d927f483..46fd44d786 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/ListValidator.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/ListValidator.java
@@ -72,6 +72,27 @@ public class ListValidator implements PropertyTypeValidator {
case MAP:
innerValidator = ToscaPropertyType.MAP.getValidator();
break;
+ case RANGE:
+ innerValidator = ToscaPropertyType.RANGE.getValidator();
+ break;
+ case SCALAR_UNIT_BITRATE:
+ innerValidator = ToscaPropertyType.SCALAR_UNIT_BITRATE.getValidator();
+ break;
+ case SCALAR_UNIT_FREQUENCY:
+ innerValidator = ToscaPropertyType.SCALAR_UNIT_FREQUENCY.getValidator();
+ break;
+ case SCALAR_UNIT_TIME:
+ innerValidator = ToscaPropertyType.SCALAR_UNIT_TIME.getValidator();
+ break;
+ case SCALAR_UNIT_SIZE:
+ innerValidator = ToscaPropertyType.SCALAR_UNIT_SIZE.getValidator();
+ break;
+ case SCALAR_UNIT:
+ innerValidator = ToscaPropertyType.SCALAR_UNIT.getValidator();
+ break;
+ case TIMESTAMP:
+ innerValidator = ToscaPropertyType.TIMESTAMP.getValidator();
+ break;
default:
log.debug("inner Tosca Type is unknown. {}", innerToscaType);
return false;
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/ui/mapper/FilterConstraintMapper.java b/catalog-model/src/main/java/org/openecomp/sdc/be/ui/mapper/FilterConstraintMapper.java
index 9c1b6c9f48..59d7ef074f 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/ui/mapper/FilterConstraintMapper.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/ui/mapper/FilterConstraintMapper.java
@@ -23,6 +23,7 @@ package org.openecomp.sdc.be.ui.mapper;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;
+import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@@ -49,6 +50,7 @@ public class FilterConstraintMapper {
filterConstraint.setTargetType(StringUtils.isEmpty(uiConstraint.getCapabilityName()) ? PropertyFilterTargetType.PROPERTY : PropertyFilterTargetType.CAPABILITY);
FilterValueType.findByName(uiConstraint.getSourceType()).ifPresent(filterConstraint::setValueType);
filterConstraint.setValue(mapValueFrom(uiConstraint));
+ filterConstraint.setOriginalType(uiConstraint.getOriginalType());
return filterConstraint;
}
@@ -95,6 +97,7 @@ public class FilterConstraintMapper {
propertyFilterConstraint.setOperator(filterConstraintDto.getOperator());
propertyFilterConstraint.setValueType(filterConstraintDto.getValueType());
propertyFilterConstraint.setValue(filterConstraintDto.getValue());
+ propertyFilterConstraint.setOriginalType(filterConstraintDto.getOriginalType());
return propertyFilterConstraint;
}
@@ -106,13 +109,32 @@ public class FilterConstraintMapper {
uiConstraint.setServicePropertyName(filterConstraintDto.getPropertyName());
uiConstraint.setSourceType(filterConstraintDto.getValueType().getName());
uiConstraint.setSourceName(uiConstraint.getSourceType());
+ uiConstraint.setOriginalType(uiConstraint.getOriginalType());
return uiConstraint;
}
private Object parseValueFromUiConstraint(final Object value) {
- if (!(value instanceof Map || value instanceof String)) {
+ if (!(value instanceof Map || value instanceof List || value instanceof String)) {
return value;
}
+ if (value instanceof List) {
+ List<ToscaFunction> listValue = new ArrayList<>();
+ ToscaFunction valueObject;
+ for (Object obj: (List)value) {
+ try {
+ valueObject = (ToscaFunction) getValueObject(obj);
+ }
+ catch (Exception e) {
+ return value;
+ }
+ listValue.add(valueObject);
+ }
+ return listValue;
+ }
+ return getValueObject(value);
+ }
+
+ private Object getValueObject(Object value) {
final Map<?, ?> valueAsMap;
if (value instanceof String) {
try {
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/UIConstraint.java b/catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/UIConstraint.java
index 401de95e71..acb0c81d35 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/UIConstraint.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/UIConstraint.java
@@ -35,6 +35,7 @@ public class UIConstraint implements Serializable {
private String sourceType;
private String sourceName;
private Object value;
+ private String originalType;
public UIConstraint() {
}
diff --git a/catalog-ui/src/app/models/filter-constraint.ts b/catalog-ui/src/app/models/filter-constraint.ts
index 69ad90cb90..5f4a9432cf 100644
--- a/catalog-ui/src/app/models/filter-constraint.ts
+++ b/catalog-ui/src/app/models/filter-constraint.ts
@@ -26,6 +26,7 @@ export class FilterConstraint {
sourceType: string;
sourceName: string;
value: any;
+ originalType: string;
constructor(input?: any) {
if (input) {
@@ -35,6 +36,7 @@ export class FilterConstraint {
this.sourceType = input.sourceType;
this.sourceName = input.sourceName;
this.value = input.value;
+ this.originalType = input.originalType;
}
}
}
diff --git a/catalog-ui/src/app/models/ui-models/property-filter-constraint-ui.ts b/catalog-ui/src/app/models/ui-models/property-filter-constraint-ui.ts
index f47677bf5a..c1acbee07e 100644
--- a/catalog-ui/src/app/models/ui-models/property-filter-constraint-ui.ts
+++ b/catalog-ui/src/app/models/ui-models/property-filter-constraint-ui.ts
@@ -20,6 +20,9 @@
*/
import {FilterConstraint} from "../filter-constraint";
+import {ConstraintOperatorType} from "../../utils/filter-constraint-helper";
+import {ToscaGetFunction} from "../tosca-get-function";
+import {ToscaFunction} from "../tosca-function";
export class PropertyFilterConstraintUi extends FilterConstraint {
isValidValue: boolean;
diff --git a/catalog-ui/src/app/ng2/components/logic/properties-table/dynamic-property/dynamic-property.component.html b/catalog-ui/src/app/ng2/components/logic/properties-table/dynamic-property/dynamic-property.component.html
index 58303a9319..c4a3893423 100644
--- a/catalog-ui/src/app/ng2/components/logic/properties-table/dynamic-property/dynamic-property.component.html
+++ b/catalog-ui/src/app/ng2/components/logic/properties-table/dynamic-property/dynamic-property.component.html
@@ -44,7 +44,7 @@
<!-- RIGHT CELL OR FULL WIDTH CELL-->
<ng-container *ngIf="propType == derivedPropertyTypes.SIMPLE || property.isDeclared || (property.isToscaFunction() && !property.isChildOfListOrMap) || (property.isChildOfListOrMap && propType == derivedPropertyTypes.MAP && property.schema.property.isSimpleType)">
<div class="table-cell">
- <checkbox class="{{propType == derivedPropertyTypes.MAP ? 'inline-checkBox' : 'inline-checkBox-List'}}" *ngIf="(property.isChildOfListOrMap && property.schema.property.isSimpleType)" [(checked)]="property.isSelected" [disabled]="property.isDisabled || readonly || property.mapKey == '' || checkboxDisabled" (checkedChange)="toggleTosca.emit(property)" ></checkbox>
+ <checkbox class="{{propType == derivedPropertyTypes.MAP ? 'inline-checkBox' : 'inline-checkBox-List'}}" *ngIf="hideCheckBox === false && (property.isChildOfListOrMap && property.schema.property.isSimpleType)" [(checked)]="property.isSelected" [disabled]="property.isDisabled || readonly || property.mapKey == '' || checkboxDisabled" (checkedChange)="toggleTosca.emit(property)" ></checkbox>
<dynamic-element class="value-input"
pattern="validationUtils.getValidationPattern(property.type)"
[value]="(property.isDeclared || property.isToscaFunction()) ? property.value : property.valueObj"
diff --git a/catalog-ui/src/app/ng2/components/logic/properties-table/dynamic-property/dynamic-property.component.ts b/catalog-ui/src/app/ng2/components/logic/properties-table/dynamic-property/dynamic-property.component.ts
index b632dddf6f..82c5af4ada 100644
--- a/catalog-ui/src/app/ng2/components/logic/properties-table/dynamic-property/dynamic-property.component.ts
+++ b/catalog-ui/src/app/ng2/components/logic/properties-table/dynamic-property/dynamic-property.component.ts
@@ -55,6 +55,7 @@ export class DynamicPropertyComponent {
@Input() hasChildren: boolean;
@Input() hasDeclareOption:boolean;
@Input() disablePropertyValue: boolean;
+ @Input() hideCheckBox: boolean;
@Input() rootProperty: PropertyFEModel;
@Output('propertyChanged') emitter: EventEmitter<void> = new EventEmitter<void>();
diff --git a/catalog-ui/src/app/ng2/components/logic/service-dependencies/service-dependencies.component.ts b/catalog-ui/src/app/ng2/components/logic/service-dependencies/service-dependencies.component.ts
index 50ea60e4ea..9a63dff739 100644
--- a/catalog-ui/src/app/ng2/components/logic/service-dependencies/service-dependencies.component.ts
+++ b/catalog-ui/src/app/ng2/components/logic/service-dependencies/service-dependencies.component.ts
@@ -33,7 +33,8 @@ import {ConstraintOperatorType, FilterConstraintHelper} from "../../../../utils/
export enum SourceType {
STATIC = 'static',
- TOSCA_FUNCTION = 'tosca_function'
+ TOSCA_FUNCTION = 'tosca_function',
+ TOSCA_FUNCTION_LIST = 'tosca_function_list'
}
class I18nTexts {
@@ -125,7 +126,12 @@ export class ServiceDependenciesComponent implements OnInit, OnChanges {
{label: FilterConstraintHelper.convertToSymbol(ConstraintOperatorType.LESS_THAN), value: ConstraintOperatorType.LESS_THAN},
{label: FilterConstraintHelper.convertToSymbol(ConstraintOperatorType.EQUAL), value: ConstraintOperatorType.EQUAL},
{label: FilterConstraintHelper.convertToSymbol(ConstraintOperatorType.GREATER_OR_EQUAL), value: ConstraintOperatorType.GREATER_OR_EQUAL},
- {label: FilterConstraintHelper.convertToSymbol(ConstraintOperatorType.LESS_OR_EQUAL), value: ConstraintOperatorType.LESS_OR_EQUAL}
+ {label: FilterConstraintHelper.convertToSymbol(ConstraintOperatorType.LESS_OR_EQUAL), value: ConstraintOperatorType.LESS_OR_EQUAL},
+ {label: FilterConstraintHelper.convertToSymbol(ConstraintOperatorType.LENGTH), value: ConstraintOperatorType.LENGTH},
+ {label: FilterConstraintHelper.convertToSymbol(ConstraintOperatorType.IN_RANGE), value: ConstraintOperatorType.IN_RANGE},
+ {label: FilterConstraintHelper.convertToSymbol(ConstraintOperatorType.MIN_LENGTH), value: ConstraintOperatorType.MIN_LENGTH},
+ {label: FilterConstraintHelper.convertToSymbol(ConstraintOperatorType.MAX_LENGTH), value: ConstraintOperatorType.MAX_LENGTH},
+ {label: FilterConstraintHelper.convertToSymbol(ConstraintOperatorType.PATTERN), value: ConstraintOperatorType.PATTERN}
];
this.topologyTemplateService.getComponentInputsWithProperties(this.compositeService.componentType, this.compositeService.uniqueId)
.subscribe((result: ComponentGenericResponse) => {
diff --git a/catalog-ui/src/app/ng2/components/ui/dynamic-element/dynamic-element.component.ts b/catalog-ui/src/app/ng2/components/ui/dynamic-element/dynamic-element.component.ts
index 50c77d3f53..2cf3c79e11 100644
--- a/catalog-ui/src/app/ng2/components/ui/dynamic-element/dynamic-element.component.ts
+++ b/catalog-ui/src/app/ng2/components/ui/dynamic-element/dynamic-element.component.ts
@@ -22,13 +22,15 @@
import * as _ from "lodash";
import { Component, Compiler, EventEmitter, ViewContainerRef, ViewChild, Input, Output, ElementRef, ComponentRef, ComponentFactoryResolver } from '@angular/core'
-import {ValidationConfiguration, PropertyFEModel} from "app/models";
+import {ValidationConfiguration} from "app/models";
import {IUiElementChangeEvent} from "../form-components/ui-element-base.component";
import {UiElementInputComponent} from "../form-components/input/ui-element-input.component";
import {UiElementPopoverInputComponent} from "../form-components/popover-input/ui-element-popover-input.component";
import {UiElementIntegerInputComponent} from "../form-components/integer-input/ui-element-integer-input.component";
import {UiElementDropDownComponent, DropdownValue} from "../form-components/dropdown/ui-element-dropdown.component";
import {PROPERTY_DATA, PROPERTY_TYPES} from "../../../../utils/constants";
+import {UiElementValidValuesInputComponent} from "../form-components/valid-values-input/ui-element-valid-values-input.component";
+import {UiElementRangeInputComponent} from "../form-components/range-input/ui-element-range-input.component";
enum DynamicElementComponentCreatorIdentifier {
STRING,
@@ -39,7 +41,9 @@ enum DynamicElementComponentCreatorIdentifier {
ENUM,
LIST,
DEFAULT,
- TIMESTAMP
+ TIMESTAMP,
+ RANGE,
+ VALID_VALUES
}
@Component({
@@ -51,13 +55,16 @@ enum DynamicElementComponentCreatorIdentifier {
UiElementInputComponent,
UiElementDropDownComponent,
UiElementPopoverInputComponent,
- UiElementIntegerInputComponent
+ UiElementIntegerInputComponent,
+ UiElementRangeInputComponent,
+ UiElementValidValuesInputComponent
]
})
export class DynamicElementComponent {
@ViewChild('target', { read: ViewContainerRef }) target: any;
@Input() type: any;
+ @Input() operator: any;
@Input() childType: any;
@Input() name: string;
@Input() testId: string;
@@ -92,28 +99,37 @@ export class DynamicElementComponent {
// Factory to create component based on type or other property attributes.
const prevElementCreatorIdentifier: DynamicElementComponentCreatorIdentifier = this.elementCreatorIdentifier;
switch(true) {
- case this.path && this.path.toUpperCase().indexOf("SUBNETPOOLID") !== -1:
+ case this.path && this.path.toUpperCase().indexOf("SUBNETPOOLID") !== -1 && this.operator != 'valid_values':
this.elementCreatorIdentifier = DynamicElementComponentCreatorIdentifier.SUBNETPOOLID;
break;
case this.getValidValues() !== undefined && this.getValidValues() !== null:
this.elementCreatorIdentifier = DynamicElementComponentCreatorIdentifier.ENUM;
break;
- case this.type === 'integer':
+ case this.operator === 'length' || this.operator === 'min_length' || this.operator === 'max_length':
this.elementCreatorIdentifier = DynamicElementComponentCreatorIdentifier.INTEGER;
break;
- case this.type === 'float':
+ case this.type === 'integer' && this.operator != 'valid_values' && this.operator != 'in_range':
+ this.elementCreatorIdentifier = DynamicElementComponentCreatorIdentifier.INTEGER;
+ break;
+ case this.type === 'float' && this.operator != 'valid_values' && this.operator != 'in_range':
this.elementCreatorIdentifier = DynamicElementComponentCreatorIdentifier.FLOAT;
break;
- case PROPERTY_DATA.SCALAR_TYPES.indexOf(this.type) > -1:
- case this.type === 'string':
+ case PROPERTY_DATA.SCALAR_TYPES.indexOf(this.type) > -1 && this.operator != 'valid_values' && this.operator != 'in_range':
+ case this.type === 'string' && this.operator != 'valid_values' && this.operator != 'in_range' && this.operator != 'length' && this.operator != 'min_length' && this.operator != 'max_length':
this.elementCreatorIdentifier = DynamicElementComponentCreatorIdentifier.STRING;
break;
- case this.type === PROPERTY_TYPES.TIMESTAMP:
+ case this.type === PROPERTY_TYPES.TIMESTAMP && this.operator != 'valid_values' && this.operator != 'in_range':
this.elementCreatorIdentifier = DynamicElementComponentCreatorIdentifier.TIMESTAMP;
break;
- case this.type === 'boolean':
+ case this.type === 'boolean' && this.operator != 'valid_values':
this.elementCreatorIdentifier = DynamicElementComponentCreatorIdentifier.BOOLEAN;
break;
+ case this.type === 'range' || this.operator === 'in_range':
+ this.elementCreatorIdentifier = DynamicElementComponentCreatorIdentifier.RANGE;
+ break;
+ case this.operator === 'valid_values':
+ this.elementCreatorIdentifier = DynamicElementComponentCreatorIdentifier.VALID_VALUES;
+ break;
case this.type === 'map':
this.createElementCreatorIdentifierForChild();
break;
@@ -156,6 +172,12 @@ export class DynamicElementComponent {
case 'boolean':
this.elementCreatorIdentifier = DynamicElementComponentCreatorIdentifier.BOOLEAN;
break;
+ case 'range':
+ this.elementCreatorIdentifier = DynamicElementComponentCreatorIdentifier.RANGE;
+ break;
+ case 'valid-values':
+ this.elementCreatorIdentifier = DynamicElementComponentCreatorIdentifier.VALID_VALUES;
+ break;
default:
this.elementCreatorIdentifier = DynamicElementComponentCreatorIdentifier.DEFAULT;
}
@@ -201,6 +223,15 @@ export class DynamicElementComponent {
this.createComponent(UiElementInputComponent);
break;
+ case DynamicElementComponentCreatorIdentifier.RANGE:
+ this.createComponent(UiElementRangeInputComponent);
+ break;
+
+ case DynamicElementComponentCreatorIdentifier.VALID_VALUES:
+ this.createComponent(UiElementValidValuesInputComponent);
+ this.cmpRef.instance.type = this.type;
+ break;
+
case DynamicElementComponentCreatorIdentifier.BOOLEAN:
this.createComponent(UiElementDropDownComponent);
diff --git a/catalog-ui/src/app/ng2/components/ui/form-components/form-elements.module.ts b/catalog-ui/src/app/ng2/components/ui/form-components/form-elements.module.ts
index b35d3ae3f4..d7f134b008 100644
--- a/catalog-ui/src/app/ng2/components/ui/form-components/form-elements.module.ts
+++ b/catalog-ui/src/app/ng2/components/ui/form-components/form-elements.module.ts
@@ -14,6 +14,8 @@ import { UiElementIntegerInputComponent } from './integer-input/ui-element-integ
import { UiElementPopoverInputComponent } from './popover-input/ui-element-popover-input.component';
import { RadioButtonComponent } from './radio-buttons/radio-buttons.component';
import { UiElementBase } from './ui-element-base.component';
+import {UiElementRangeInputComponent} from "./range-input/ui-element-range-input.component";
+import {UiElementValidValuesInputComponent} from "./valid-values-input/ui-element-valid-values-input.component";
@NgModule({
imports: [
@@ -29,12 +31,16 @@ import { UiElementBase } from './ui-element-base.component';
UiElementInputComponent,
UiElementIntegerInputComponent,
UiElementPopoverInputComponent,
+ UiElementRangeInputComponent,
+ UiElementValidValuesInputComponent,
UiElementBase,
RadioButtonComponent],
exports: [UiElementDropDownComponent,
UiElementInputComponent,
UiElementIntegerInputComponent,
+ UiElementRangeInputComponent,
+ UiElementValidValuesInputComponent,
UiElementPopoverInputComponent,
RadioButtonComponent,
TooltipModule,
diff --git a/catalog-ui/src/app/ng2/components/ui/form-components/integer-input/ui-element-integer-input.component.html b/catalog-ui/src/app/ng2/components/ui/form-components/integer-input/ui-element-integer-input.component.html
index d5ef08b126..4ab0a689a8 100644
--- a/catalog-ui/src/app/ng2/components/ui/form-components/integer-input/ui-element-integer-input.component.html
+++ b/catalog-ui/src/app/ng2/components/ui/form-components/integer-input/ui-element-integer-input.component.html
@@ -17,7 +17,7 @@
<input
class="value-input"
[ngClass]="{'error': control.invalid, 'disabled':readonly}"
- type="text"
+ type="{{type === 'integer' ? 'number' : 'text' }}"
[name]="name"
[(ngModel)]="value"
(input)="onChange()"
diff --git a/catalog-ui/src/app/ng2/components/ui/form-components/range-input/ui-element-range-input.component.html b/catalog-ui/src/app/ng2/components/ui/form-components/range-input/ui-element-range-input.component.html
new file mode 100644
index 0000000000..970492ebf5
--- /dev/null
+++ b/catalog-ui/src/app/ng2/components/ui/form-components/range-input/ui-element-range-input.component.html
@@ -0,0 +1,81 @@
+<!--
+* ============LICENSE_START=======================================================
+* Copyright (C) 2023 Nordix Foundation.
+* ================================================================================
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+* SPDX-License-Identifier: Apache-2.0
+* ============LICENSE_END=========================================================
+ -->
+<div class="w-sdc-form-columns-wrapper">
+ <div class="w-sdc-form-column">
+
+ <input *ngIf="isFloatType()"
+ class="value-input"
+ [ngClass]="{'error': control.invalid, 'disabled':readonly}"
+ type="number"
+ step="0.01"
+ [name]="name"
+ [(ngModel)]="lowerBound"
+ [value]="getInRangeValue(0)"
+ (input)="onChangeMin()"
+ [attr.maxlength]="validation.propertyValue.max"
+ [attr.minlength]="validation.propertyValue.min"
+ [formControl]="control"
+ [attr.data-tests-id]="'valueMin-' + testId"
+ />
+ <input *ngIf="isIntegerType()"
+ class="value-input"
+ [ngClass]="{'error': control.invalid, 'disabled':readonly}"
+ type="number"
+ [name]="name"
+ [(ngModel)]="lowerBound"
+ [value]="getInRangeValue(0)"
+ (input)="onChangeMin()"
+ [attr.maxlength]="validation.propertyValue.max"
+ [attr.minlength]="validation.propertyValue.min"
+ [formControl]="control"
+ [attr.data-tests-id]="'valueMin-' + testId"
+ />
+ <input *ngIf="isStringType()"
+ class="value-input"
+ [ngClass]="{'error': control.invalid, 'disabled':readonly}"
+ type="text"
+ [name]="name"
+ [(ngModel)]="lowerBound"
+ [value]="getInRangeValue(0)"
+ (input)="onChangeMin()"
+ [attr.maxlength]="validation.propertyValue.max"
+ [attr.minlength]="validation.propertyValue.min"
+ [formControl]="control"
+ [attr.data-tests-id]="'valueMin-' + testId"
+ />
+ </div>
+ <div class="w-sdc-form-column">
+ <input
+ class="value-input"
+ [ngClass]="{'error': control.invalid, 'disabled':readonly}"
+ [type]="isIntegerType() || isFloatType() ? 'number' : 'text'"
+ [name]="name"
+ [(ngModel)]="upperBound"
+ [value]="getInRangeValue(1)"
+ (input)="onChangeMax()"
+ [attr.maxlength]="validation.propertyValue.max"
+ [attr.minlength]="validation.propertyValue.min"
+
+ [formControl]="control"
+ [attr.data-tests-id]="'valueMax-' + testId"
+ />
+
+ </div>
+</div> \ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/components/ui/form-components/range-input/ui-element-range-input.component.less b/catalog-ui/src/app/ng2/components/ui/form-components/range-input/ui-element-range-input.component.less
new file mode 100644
index 0000000000..c393024899
--- /dev/null
+++ b/catalog-ui/src/app/ng2/components/ui/form-components/range-input/ui-element-range-input.component.less
@@ -0,0 +1,37 @@
+/*
+ * -
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2023 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+@import '../../../../../../assets/styles/variables';
+
+/deep/ ui-element-range-input {
+
+ input {
+ text-indent: 6px;
+ border: solid 1px @main_color_o;
+ }
+
+ .error {
+ border: solid 1px @func_color_q;
+ color: @func_color_q;
+ outline: none;
+ box-sizing: border-box;
+ }
+
+}
diff --git a/catalog-ui/src/app/ng2/components/ui/form-components/range-input/ui-element-range-input.component.ts b/catalog-ui/src/app/ng2/components/ui/form-components/range-input/ui-element-range-input.component.ts
new file mode 100644
index 0000000000..65c5bd72e3
--- /dev/null
+++ b/catalog-ui/src/app/ng2/components/ui/form-components/range-input/ui-element-range-input.component.ts
@@ -0,0 +1,112 @@
+/*
+ * -
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2023 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+import {Component, Input} from '@angular/core';
+import { UiElementBase, UiElementBaseInterface } from './../ui-element-base.component';
+import {PROPERTY_DATA} from "../../../../../utils/constants";
+
+@Component({
+ selector: 'ui-element-range-input',
+ templateUrl: './ui-element-range-input.component.html',
+ styleUrls: ['./ui-element-range-input.component.less'],
+})
+export class UiElementRangeInputComponent extends UiElementBase implements UiElementBaseInterface {
+ @Input() lowerBound: any;
+ @Input() upperBound: any;
+ step: number;
+ constructor() {
+ super();
+ this.pattern = this.validation.validationPatterns.comment;
+ this.value = new Array(2);
+ this.value[0] = this.lowerBound;
+ this.value[1] = this.upperBound;
+ }
+
+ ngOnInit(){
+ this.step = 0;
+ if (this.type === 'float') {
+ this.step = 0.01;
+ }
+ if (this.type === 'integer') {
+ this.step = 0;
+ }
+ }
+
+ isFloatType(): boolean {
+ return this.type === 'float';
+ }
+
+ isIntegerType(): boolean {
+ return this.type === 'integer' || this.type === 'range' || this.type === 'timestamp';
+ }
+
+ isStringType(): boolean {
+ return this.type === 'string' || PROPERTY_DATA.SCALAR_TYPES.indexOf(this.type) > -1;
+ }
+
+ onChangeMin() {
+ if (!this.value) {
+ this.value = new Array(2);
+ }
+ this.value.splice(0, 1, this.lowerBound);
+ this.baseEmitter.emit({
+ value: this.value ,
+ isValid: this.isValidRange()
+ });
+ }
+
+ onChangeMax() {
+ if (!this.value) {
+ this.value = new Array(2);
+ }
+ this.value.splice(1, 1, this.upperBound);
+ this.baseEmitter.emit({
+ value: this.value,
+ isValid: this.isValidRange()
+ });
+ }
+
+ getInRangeValue(valueIndex: number): string {
+ if(!this.value || !this.value[valueIndex]) {
+ return "";
+ }
+ return this.value[valueIndex];
+ }
+
+ isNumber(value: string | number): boolean
+ {
+ return ((value != undefined) &&
+ (value != null) &&
+ (value !== '') &&
+ !isNaN(Number(value.toString())));
+ }
+
+ isValidRange(): boolean
+ {
+ if (this.isStringType()) {
+ return this.getInRangeValue(0) <= this.getInRangeValue(1);
+ }
+ return this.isNumber(this.value[0])
+ && (this.getInRangeValue(1) === "UNBOUNDED"
+ || (this.isNumber(this.value[1])
+ && this.getInRangeValue(0) <= this.getInRangeValue(1)));
+ }
+}
diff --git a/catalog-ui/src/app/ng2/components/ui/form-components/valid-values-input/ui-element-valid-values-input.component.html b/catalog-ui/src/app/ng2/components/ui/form-components/valid-values-input/ui-element-valid-values-input.component.html
new file mode 100644
index 0000000000..ff4d6d1353
--- /dev/null
+++ b/catalog-ui/src/app/ng2/components/ui/form-components/valid-values-input/ui-element-valid-values-input.component.html
@@ -0,0 +1,39 @@
+<!--
+* ============LICENSE_START=======================================================
+* Copyright (C) 2023 Nordix Foundation.
+* ================================================================================
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+* SPDX-License-Identifier: Apache-2.0
+* ============LICENSE_END=========================================================
+ -->
+
+ <div class="add-btn"
+ (click)="addToList()">Add to List
+ </div>
+ <div class="w-sdc-form-columns-wrapper" *ngFor="let val of value; let valueIndex = index; trackBy:trackByFn">
+ <div class="w-sdc-form-column">
+ <input type="text" class="i-sdc-form-input" *ngIf="showStringField()"
+ [value]="val"
+ (input)="onChangeConstrainValueIndex($event.target.value, valueIndex)"/>
+ <input type="number" class="i-sdc-form-input" *ngIf="showIntegerField()"
+ [value]="val"
+ (input)="onChangeConstrainValueIndex($event.target.value, valueIndex)"/>
+ <input type="number" class="i-sdc-form-input" step="0.01" *ngIf="type == 'float'"
+ [value]="val"
+ (input)="onChangeConstrainValueIndex($event.target.value, valueIndex)"/>
+ </div>
+ <div class="w-sdc-form-column">
+ <span class="sprite-new delete-btn" (click)="removeFromList(valueIndex)"></span>
+ </div>
+ </div>
diff --git a/catalog-ui/src/app/ng2/components/ui/form-components/valid-values-input/ui-element-valid-values-input.component.less b/catalog-ui/src/app/ng2/components/ui/form-components/valid-values-input/ui-element-valid-values-input.component.less
new file mode 100644
index 0000000000..c393024899
--- /dev/null
+++ b/catalog-ui/src/app/ng2/components/ui/form-components/valid-values-input/ui-element-valid-values-input.component.less
@@ -0,0 +1,37 @@
+/*
+ * -
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2023 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+@import '../../../../../../assets/styles/variables';
+
+/deep/ ui-element-range-input {
+
+ input {
+ text-indent: 6px;
+ border: solid 1px @main_color_o;
+ }
+
+ .error {
+ border: solid 1px @func_color_q;
+ color: @func_color_q;
+ outline: none;
+ box-sizing: border-box;
+ }
+
+}
diff --git a/catalog-ui/src/app/ng2/components/ui/form-components/valid-values-input/ui-element-valid-values-input.component.ts b/catalog-ui/src/app/ng2/components/ui/form-components/valid-values-input/ui-element-valid-values-input.component.ts
new file mode 100644
index 0000000000..079fdeba1c
--- /dev/null
+++ b/catalog-ui/src/app/ng2/components/ui/form-components/valid-values-input/ui-element-valid-values-input.component.ts
@@ -0,0 +1,102 @@
+/*
+ * -
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2023 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+import {Component, Output, EventEmitter} from '@angular/core';
+import { UiElementBase, UiElementBaseInterface } from './../ui-element-base.component';
+import {ConstraintTypes} from "../../../../pages/properties-assignment/constraints/constraints.component";
+import {PROPERTY_DATA, PROPERTY_TYPES} from "../../../../../utils/constants";
+
+@Component({
+ selector: 'ui-element-valid-values-input',
+ templateUrl: './ui-element-valid-values-input.component.html',
+ styleUrls: ['./ui-element-valid-values-input.component.less'],
+})
+export class UiElementValidValuesInputComponent extends UiElementBase implements UiElementBaseInterface {
+ @Output() onConstraintChange: EventEmitter<any> = new EventEmitter<any>();
+ constructor() {
+ super();
+ this.pattern = this.validation.validationPatterns.comment;
+ }
+
+ showStringField(): boolean {
+ return this.type === PROPERTY_TYPES.STRING || PROPERTY_DATA.SCALAR_TYPES.indexOf(this.type) > -1;
+ }
+
+ showIntegerField(): boolean {
+ return this.type === PROPERTY_TYPES.INTEGER || this.type === PROPERTY_TYPES.TIMESTAMP;
+ }
+
+ addToList(){
+ if (!this.value) {
+ this.value = new Array();
+ }
+ this.value.push("");
+ this.baseEmitter.emit({
+ value: this.value,
+ isValid: false
+ });
+ this.emitOnConstraintChange()
+ }
+
+ onChangeConstrainValueIndex(newValue: any, valueIndex: number) {
+ if(!this.value) {
+ this.value = new Array();
+ }
+ this.value[valueIndex] = newValue;
+ this.baseEmitter.emit({
+ value: this.value,
+ isValid: newValue != "" && !this.doesArrayContaintEmptyValues(this.value)
+ });
+ this.emitOnConstraintChange();
+ }
+
+ private emitOnConstraintChange(): void {
+ this.onConstraintChange.emit({
+ valid: this.validateConstraints()
+ });
+ }
+ private validateConstraints(): boolean {
+ if (Array.isArray(this.value)) {
+ return !(this.value.length == 0 || this.doesArrayContaintEmptyValues(this.value));
+ }
+ return this.value && this.type != ConstraintTypes.null
+ }
+
+ removeFromList(valueIndex: number){
+ this.value.splice(valueIndex, 1);
+ this.baseEmitter.emit({
+ value: this.value,
+ isValid: !this.doesArrayContaintEmptyValues(this.value)
+ });
+ this.emitOnConstraintChange()
+ }
+
+ trackByFn(index) {
+ return index;
+ }
+
+ private doesArrayContaintEmptyValues(arr) {
+ for(const element of arr) {
+ if(element === "") return true;
+ }
+ return false;
+ }
+}
diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/services/properties.utils.ts b/catalog-ui/src/app/ng2/pages/properties-assignment/services/properties.utils.ts
index 8dd4ca96ec..6a27622638 100644
--- a/catalog-ui/src/app/ng2/pages/properties-assignment/services/properties.utils.ts
+++ b/catalog-ui/src/app/ng2/pages/properties-assignment/services/properties.utils.ts
@@ -181,6 +181,8 @@ export class PropertiesUtils {
property.childPropUpdated(childProp);
});
+ } else if (property.derivedDataType === DerivedPropertyType.RANGE) {
+ property.valueObj = JSON.stringify(property.getValueObj());
}
}
property.updateValueObjOrig();
diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-function.component.html b/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-function.component.html
index 898b189746..65a024cde4 100644
--- a/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-function.component.html
+++ b/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-function.component.html
@@ -43,6 +43,7 @@
</div>
<div *ngIf="isGetFunctionSelected()">
<app-tosca-get-function [property]="property" [toscaGetFunction]="toscaFunction"
+ [overridingType] = "overridingType"
[componentInstanceMap]="componentInstanceMap"
[functionType]="toscaFunctionTypeForm.value"
[compositionMap]="compositionMap"
diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-function.component.ts b/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-function.component.ts
index 81696944c7..ecaff252d3 100644
--- a/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-function.component.ts
+++ b/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-function.component.ts
@@ -30,7 +30,7 @@ import {ToscaGetFunctionValidationEvent} from "./tosca-get-function/tosca-get-fu
import {ToscaFunction} from "../../../../models/tosca-function";
import {ToscaConcatFunctionValidationEvent} from "./tosca-concat-function/tosca-concat-function.component";
import {ToscaCustomFunctionValidationEvent} from "./tosca-custom-function/tosca-custom-function.component";
-import {PROPERTY_TYPES, PROPERTY_DATA} from "../../../../utils/constants";
+import {PROPERTY_TYPES} from "../../../../utils/constants";
import {YamlFunctionValidationEvent} from "./yaml-function/yaml-function.component";
import {ToscaConcatFunction} from "../../../../models/tosca-concat-function";
import {ToscaCustomFunction} from "../../../../models/tosca-custom-function";
@@ -45,6 +45,8 @@ import {CustomToscaFunction} from "../../../../models/default-custom-functions";
export class ToscaFunctionComponent implements OnInit, OnChanges {
@Input() property: PropertyBEModel;
+ @Input() overridingType: PROPERTY_TYPES;
+ @Input() inToscaFunction: ToscaFunction;
@Input() componentInstanceMap: Map<string, InstanceFeDetails> = new Map<string, InstanceFeDetails>();
@Input() customToscaFunctions: Array<CustomToscaFunction> = [];
@Input() allowClear: boolean = true;
@@ -74,7 +76,7 @@ export class ToscaFunctionComponent implements OnInit, OnChanges {
ngOnInit(): void {
this.componentMetadata = this.workspaceService.metadata;
- this.toscaFunction = this.property.toscaFunction ? this.property.toscaFunction : undefined;
+ this.toscaFunction = this.inToscaFunction ? this.inToscaFunction : this.property.toscaFunction ? this.property.toscaFunction : undefined;
this.loadToscaFunctions();
this.formGroup.valueChanges.subscribe(() => {
if (!this.isInitialized) {
@@ -93,7 +95,7 @@ export class ToscaFunctionComponent implements OnInit, OnChanges {
ngOnChanges(changes: SimpleChanges): void {
if (changes.property) {
this.resetForm();
- this.toscaFunction = this.property.toscaFunction ? this.property.toscaFunction : undefined;
+ this.toscaFunction = this.inToscaFunction ? this.inToscaFunction : this.property.toscaFunction ? this.property.toscaFunction : undefined;
this.initToscaFunction();
this.loadToscaFunctions();
this.emitValidityChange();
@@ -130,11 +132,11 @@ export class ToscaFunctionComponent implements OnInit, OnChanges {
return;
}
}
-
if (!this.property.isToscaFunction()) {
return;
}
- this.toscaFunctionForm.setValue(this.property.toscaFunction);
+
+ this.toscaFunctionForm.setValue(this.inToscaFunction ? this.inToscaFunction : this.property.toscaFunction);
let type = this.property.toscaFunction.type;
if (type == ToscaFunctionType.CUSTOM) {
let name = (this.property.toscaFunction as ToscaCustomFunction).name;
@@ -145,7 +147,7 @@ export class ToscaFunctionComponent implements OnInit, OnChanges {
this.toscaFunctionTypeForm.setValue("other");
}
} else {
- this.toscaFunctionTypeForm.setValue(type);
+ this.toscaFunctionTypeForm.setValue(this.inToscaFunction ? this.inToscaFunction.type : type);
}
}
@@ -159,6 +161,9 @@ export class ToscaFunctionComponent implements OnInit, OnChanges {
this.toscaFunctions.push(ToscaFunctionType.GET_INPUT);
this.toscaFunctions.push(ToscaFunctionType.GET_PROPERTY);
if (this.property.type === PROPERTY_TYPES.STRING || this.property.type === PROPERTY_TYPES.ANY) {
+ this.toscaFunctions.push(ToscaFunctionType.CUSTOM);
+ }
+ if ((this.property.type === PROPERTY_TYPES.STRING || this.property.type === PROPERTY_TYPES.ANY) && this.overridingType === undefined) {
this.toscaFunctions.push(ToscaFunctionType.CONCAT);
}
this.loadCustomToscaFunctions();
diff --git a/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-get-function/tosca-get-function.component.ts b/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-get-function/tosca-get-function.component.ts
index fe6f2f143c..284c559c55 100644
--- a/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-get-function/tosca-get-function.component.ts
+++ b/catalog-ui/src/app/ng2/pages/properties-assignment/tosca-function/tosca-get-function/tosca-get-function.component.ts
@@ -42,6 +42,7 @@ import {ToscaGetFunctionTypeConverter} from "../../../../../models/tosca-get-fun
export class ToscaGetFunctionComponent implements OnInit, OnChanges {
@Input() property: PropertyBEModel;
+ @Input() overridingType: PROPERTY_TYPES;
@Input() toscaGetFunction: ToscaGetFunction;
@Input() componentInstanceMap: Map<string, InstanceFeDetails> = new Map<string, InstanceFeDetails>();
@Input() functionType: ToscaGetFunctionType;
@@ -243,13 +244,13 @@ export class ToscaGetFunctionComponent implements OnInit, OnChanges {
const properties: Array<PropertyBEModel | AttributeBEModel> = this.extractProperties(response);
if (!properties || properties.length === 0) {
const msgCode = this.getNotFoundMsgCode();
- this.dropDownErrorMsg = this.translateService.translate(msgCode, {type: this.propertyTypeToString()});
+ this.dropDownErrorMsg = this.translateService.translate(msgCode, {type: this.overridingType != undefined ? this.overridingType : this.propertyTypeToString()});
return;
}
this.addPropertiesToDropdown(properties);
if (this.propertyDropdownList.length == 0) {
const msgCode = this.getNotFoundMsgCode();
- this.dropDownErrorMsg = this.translateService.translate(msgCode, {type: this.propertyTypeToString()});
+ this.dropDownErrorMsg = this.translateService.translate(msgCode, {type: this.overridingType != undefined ? this.overridingType : this.propertyTypeToString()});
}
}, (error) => {
console.error('An error occurred while loading properties.', error);
@@ -403,6 +404,9 @@ export class ToscaGetFunctionComponent implements OnInit, OnChanges {
}
private hasSameType(property: PropertyBEModel | AttributeBEModel): boolean {
+ if (this.overridingType != undefined) {
+ return property.type === this.overridingType;
+ }
if (this.property.type === PROPERTY_TYPES.ANY) {
return true;
}
diff --git a/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.html b/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.html
index 8024eb1615..c90cfd8210 100644
--- a/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.html
+++ b/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.html
@@ -51,7 +51,10 @@
<label class="i-sdc-form-label required">{{"OPERATOR_LABEL" | translate}}</label>
<ui-element-dropdown class="i-sdc-form-select" data-tests-id="constraintOperator"
[testId]="'constraintOperator'"
- [values]="operatorTypes" [(value)]="currentRule.constraintOperator"></ui-element-dropdown>
+ (change)="onSourceTypeChange()"
+ [values]="operatorTypes" [(value)]="currentRule.constraintOperator"
+ >
+ </ui-element-dropdown>
</div>
</div>
<div class="rule-builder-content">
@@ -61,17 +64,28 @@
data-tests-id="value-type-static"
[(ngModel)]="selectedSourceType"
[value]="SOURCE_TYPES.STATIC.value"
- (ngModelChange)="onSourceTypeChange()"/> {{"VALUE_LABEL" | translate}}
+ (ngModelChange)="onSourceTypeChange($event)"/> {{"VALUE_LABEL" | translate}}
<input type="radio" name="sourceType"
data-tests-id="value-type-tosca-function"
[(ngModel)]="selectedSourceType"
- [value]="SOURCE_TYPES.TOSCA_FUNCTION.value"
- (ngModelChange)="onSourceTypeChange()"/> {{"VALUE_EXPRESSION_LABEL" | translate}}
+ [value]="isValidValuesOperator() || isRangeType() || isInRangeOperator() ? SOURCE_TYPES.TOSCA_FUNCTION_LIST.value: SOURCE_TYPES.TOSCA_FUNCTION.value"
+ (ngModelChange)="onSourceTypeChange($event)"/> {{"VALUE_EXPRESSION_LABEL" | translate}}
</div>
</div>
<div class="rule-builder-content" *ngIf="isToscaFunctionSource() && selectedProperty">
<div class="i-sdc-form-item rule-input-field">
<tosca-function [property]="selectedProperty"
+ [overridingType] = "isLengthOperator() ? overridingType : undefined"
+ [componentInstanceMap]="componentInstanceMap"
+ [allowClear]="false"
+ (onValidityChange)="onToscaFunctionValidityChange($event)"
+ >
+ </tosca-function>
+ </div>
+ </div>
+ <div class="rule-builder-content" *ngIf="isToscaFunctionSource() && selectedProperty && (isRangeType() || isInRangeOperator())">
+ <div class="i-sdc-form-item rule-input-field">
+ <tosca-function [property]="selectedProperty"
[componentInstanceMap]="componentInstanceMap"
[customToscaFunctions]="customToscaFunctions"
[allowClear]="false"
@@ -80,29 +94,97 @@
</tosca-function>
</div>
</div>
+
+ <div class="rule-builder-content" *ngIf="isToscaFunctionListSource() && selectedProperty && (isRangeType() || isInRangeOperator())">
+
+ <div class="i-sdc-form-item rule-input-field">
+ <div class="w-sdc-form-columns-wrapper" *ngFor="let val of rangeToscaFunctionList; let valueIndex = index; trackBy:trackByFn">
+ <div class="w-sdc-form-column" style="border-width:3px; border-style:solid; border-color:#009fdb; padding: 1em;">
+ <tosca-function [property]="selectedProperty"
+ [inToscaFunction]="val"
+ [componentInstanceMap]="componentInstanceMap"
+ [allowClear]="false"
+ (onValidityChange)="onToscaRangeFunctionListValidityChange($event, valueIndex)"
+ >
+ </tosca-function>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <div class="rule-builder-content" *ngIf="isToscaFunctionListSource() && selectedProperty && isValidValuesOperator()">
+
+ <div class="i-sdc-form-item rule-input-field">
+ <div class="add-btn"
+ (click)="addToList()">Add to List
+ </div>
+ <div class="w-sdc-form-columns-wrapper" *ngFor="let val of this.validValuesToscaFunctionList; let valueIndex = index; trackBy:trackByFn">
+ <div class="w-sdc-form-column" style="border-width:3px; border-style:solid; border-color:#009fdb; padding: 1em;">
+ <tosca-function [property]="selectedProperty"
+ [inToscaFunction]="val"
+ [componentInstanceMap]="componentInstanceMap"
+ [allowClear]="false"
+ (onValidityChange)="onToscaFunctionListValidityChange($event, valueIndex)"
+ >
+ </tosca-function>
+ </div>
+ <div class="w-sdc-form-column">
+ <span class="sprite-new delete-btn" (click)="removeFromList(valueIndex)"></span>
+ </div>
+ </div>
+ </div>
+ </div>
<div *ngIf="isToscaFunctionSource() && !selectedProperty">
{{"NODE_FILTER_SELECT_PROPERTY" | translate}}
</div>
<div class="rule-builder-content" *ngIf="isStaticSource()">
<div class="i-sdc-form-item rule-input-field complex-input-field">
<dynamic-property
- *ngIf="isComplexListMapType()"
+ *ngIf="isComplexListMapType() && !isRangeType() && !isValidValuesOperator() && !isLengthOperator()"
[selectedPropertyId]="selectedProperty.uniqueId"
[property]="selectedProperty"
[expandedChildId]="selectedProperty.expandedChildPropertyId ?
selectedProperty.expandedChildPropertyId : selectedProperty.name"
[canBeDeclared]="true"
+ [hideCheckBox]="true"
(propertyChanged)="updateComplexListMapTypeRuleValue()"
[rootProperty]="selectedProperty"
(expandChild)="selectedProperty.updateExpandedChildPropertyId($event)">
</dynamic-property>
<dynamic-element
- *ngIf="!isComplexListMapType()"
+ *ngIf="!isComplexListMapType() && !isValidValuesOperator()"
[(value)]="currentRule.value"
class="rule-assigned-value"
data-tests-id="ruleAssignedValue"
(elementChanged)="onValueChange($event.isValid)"
- [type]="selectedProperty ? selectedProperty.type : 'string'">
+ [type]="isLengthOperator() ? 'integer' : selectedProperty ? selectedProperty.type : 'string'"
+ [operator]="currentRule.constraintOperator">
+ </dynamic-element>
+ <dynamic-element
+ *ngIf="isComplexListMapType() && isLengthOperator()"
+ [(value)]="currentRule.value"
+ class="rule-assigned-value"
+ data-tests-id="ruleAssignedValue"
+ (elementChanged)="onValueChange($event.isValid)"
+ [type]="isLengthOperator() ? 'integer' : selectedProperty ? selectedProperty.type : 'string'"
+ [operator]="currentRule.constraintOperator">
+ </dynamic-element>
+ <dynamic-element
+ *ngIf="isRangeType()"
+ [(value)]="currentRule.value"
+ class="rule-assigned-value"
+ data-tests-id="ruleAssignedValue"
+ (elementChanged)="onValueChange($event.isValid)"
+ [type]="selectedProperty ? selectedProperty.type : 'string'">
+ </dynamic-element>
+ <dynamic-element
+ *ngIf="isValidValuesOperator()"
+ [(value)]="currentRule.value"
+ class="rule-assigned-value"
+ data-tests-id="ruleAssignedValue"
+ (elementChanged)="onValueChange($event.isValid)"
+ [type]="selectedProperty ? selectedProperty.type : 'string'"
+ [operator]="currentRule.constraintOperator">
</dynamic-element>
</div>
</div>
diff --git a/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.ts b/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.ts
index 39609a5fbd..5897f272b3 100644
--- a/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.ts
+++ b/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.ts
@@ -19,7 +19,7 @@ import {InputBEModel, PropertyBEModel, PropertyFEModel, PropertyModel} from 'app
import {SourceType} from 'app/ng2/components/logic/service-dependencies/service-dependencies.component';
import {DropdownValue} from 'app/ng2/components/ui/form-components/dropdown/ui-element-dropdown.component';
import {ServiceServiceNg2} from 'app/ng2/services/component-services/service.service';
-import {PROPERTY_DATA} from 'app/utils';
+import {PROPERTY_DATA, PROPERTY_TYPES} from 'app/utils';
import {PropertiesUtils} from '../properties-assignment/services/properties.utils';
import {ToscaFunctionValidationEvent} from "../properties-assignment/tosca-function/tosca-function.component";
import {InstanceFeDetails} from "../../../models/instance-fe-details";
@@ -30,7 +30,7 @@ import {ConstraintOperatorType, FilterConstraintHelper} from "../../../utils/fil
import {ToscaFunctionHelper} from "../../../utils/tosca-function-helper";
import {TopologyTemplateService} from "app/ng2/services/component-services/topology-template.service";
import {CustomToscaFunction} from "../../../models/default-custom-functions";
-import {ToscaFunctionType} from "../../../models/tosca-function-type.enum";
+import {ToscaFunction} from "../../../models/tosca-function";
@Component({
selector: 'service-dependencies-editor',
@@ -52,8 +52,23 @@ export class ServiceDependenciesEditorComponent implements OnInit {
ConstraintOperatorType.LESS_THAN,
ConstraintOperatorType.EQUAL,
ConstraintOperatorType.GREATER_OR_EQUAL,
- ConstraintOperatorType.LESS_OR_EQUAL
+ ConstraintOperatorType.LESS_OR_EQUAL,
+ ConstraintOperatorType.IN_RANGE,
+ ConstraintOperatorType.VALID_VALUES,
+ ConstraintOperatorType.LENGTH,
+ ConstraintOperatorType.MIN_LENGTH,
+ ConstraintOperatorType.MAX_LENGTH,
+ ConstraintOperatorType.PATTERN
];
+ @Input() comparableAllowedOperators: ConstraintOperatorType[] = [
+ ConstraintOperatorType.GREATER_THAN,
+ ConstraintOperatorType.LESS_THAN,
+ ConstraintOperatorType.EQUAL,
+ ConstraintOperatorType.GREATER_OR_EQUAL,
+ ConstraintOperatorType.LESS_OR_EQUAL,
+ ConstraintOperatorType.IN_RANGE,
+ ConstraintOperatorType.VALID_VALUES,
+ ];
@Input() capabilityNameAndPropertiesMap: Map<string, PropertyModel[]>;
@Input() filterType: FilterType;
@Input() filterConstraint: PropertyFilterConstraintUi;
@@ -62,6 +77,13 @@ export class ServiceDependenciesEditorComponent implements OnInit {
FILTER_TYPE_CAPABILITY: FilterType = FilterType.CAPABILITY
+ listAllowedOperators: ConstraintOperatorType[] = [
+ ConstraintOperatorType.EQUAL,
+ ConstraintOperatorType.LENGTH,
+ ConstraintOperatorType.MIN_LENGTH,
+ ConstraintOperatorType.MAX_LENGTH
+ ];
+
operatorTypes: DropdownValue[] = [
{label: FilterConstraintHelper.convertToSymbol(ConstraintOperatorType.GREATER_THAN), value: ConstraintOperatorType.GREATER_THAN},
{label: FilterConstraintHelper.convertToSymbol(ConstraintOperatorType.LESS_THAN), value: ConstraintOperatorType.LESS_THAN},
@@ -69,6 +91,9 @@ export class ServiceDependenciesEditorComponent implements OnInit {
{label: FilterConstraintHelper.convertToSymbol(ConstraintOperatorType.GREATER_OR_EQUAL), value: ConstraintOperatorType.GREATER_OR_EQUAL},
{label: FilterConstraintHelper.convertToSymbol(ConstraintOperatorType.LESS_OR_EQUAL), value: ConstraintOperatorType.LESS_OR_EQUAL}
];
+ lengthArray: string[] = [ConstraintOperatorType.LENGTH,
+ ConstraintOperatorType.MIN_LENGTH,
+ ConstraintOperatorType.MAX_LENGTH];
servicePropertyDropdownList: DropdownValue[];
isLoading: false;
@@ -77,10 +102,14 @@ export class ServiceDependenciesEditorComponent implements OnInit {
componentInstanceMap: Map<string, InstanceFeDetails> = new Map<string, InstanceFeDetails>();
customToscaFunctions: Array<CustomToscaFunction>;
capabilityDropdownList: DropdownValue[] = [];
+ validValuesToscaFunctionList: ToscaFunction[];
+ rangeToscaFunctionList: ToscaFunction[];
+ overridingType = PROPERTY_TYPES.INTEGER;
SOURCE_TYPES = {
STATIC: {label: 'Static', value: SourceType.STATIC},
- TOSCA_FUNCTION: {label: 'Tosca Function', value: SourceType.TOSCA_FUNCTION}
+ TOSCA_FUNCTION: {label: 'Tosca Function', value: SourceType.TOSCA_FUNCTION},
+ TOSCA_FUNCTION_LIST: {label: 'Tosca Function List', value: SourceType.TOSCA_FUNCTION_LIST}
};
constructor(private propertiesUtils: PropertiesUtils, private compositionService: CompositionService, private topologyTemplateService: TopologyTemplateService) {}
@@ -100,6 +129,7 @@ export class ServiceDependenciesEditorComponent implements OnInit {
this.initSelectedSourceType();
this.initPropertyDropdown();
this.syncRuleData();
+ this.generateRangeToscaFunctionList();
}
private initCustomToscaFunctions() {
@@ -138,43 +168,87 @@ export class ServiceDependenciesEditorComponent implements OnInit {
this.servicePropertyDropdownList = [new DropdownValue(undefined, selectLabel), ...propertyList.map(prop => new DropdownValue(prop.name, prop.name)).sort((prop1, prop2) => prop1.value.localeCompare(prop2.value))];
}
- private initConstraintOperatorOptions(): void {
- if (!this.selectedProperty) {
- this.operatorTypes = [new DropdownValue(undefined, 'Select a Property')];
- return;
+ private initConstraintOperatorOptions(): void {
+ if (!this.selectedProperty) {
+ this.operatorTypes = [this.setOperatorDropdownValue(undefined)];
+ return;
+ }
+ const operatorList: DropdownValue[] = [];
+ switch (true) {
+ case this.selectedProperty.type === PROPERTY_TYPES.RANGE:
+ if (this.currentRule.constraintOperator !== ConstraintOperatorType.IN_RANGE) {
+ this.currentRule.constraintOperator = ConstraintOperatorType.IN_RANGE;
+ }
+ this.operatorTypes = [this.setOperatorDropdownValue(ConstraintOperatorType.IN_RANGE)];
+ break;
+ case this.selectedProperty.type === PROPERTY_TYPES.STRING:
+ this.allowedOperators.forEach(constraintOperatorType =>
+ operatorList.push(this.setOperatorDropdownValue(constraintOperatorType))
+ );
+ this.operatorTypes = operatorList;
+ break;
+ case this.selectedProperty.type != PROPERTY_TYPES.STRING &&
+ ((PROPERTY_DATA.SIMPLE_TYPES_COMPARABLE.indexOf(this.selectedProperty.type) > -1) ||
+ (PROPERTY_DATA.COMPARABLE_TYPES.indexOf(this.selectedProperty.type) > -1)):
+ this.comparableAllowedOperators.forEach(constraintOperatorType =>
+ operatorList.push(this.setOperatorDropdownValue(constraintOperatorType))
+ );
+ this.operatorTypes = operatorList;
+ break;
+ case this.selectedProperty.type === PROPERTY_TYPES.LIST:
+ this.listAllowedOperators.forEach(constraintOperatorType =>
+ operatorList.push(this.setOperatorDropdownValue(constraintOperatorType))
+ );
+ this.operatorTypes = operatorList;
+ break;
+ default:
+ if (this.currentRule.constraintOperator !== ConstraintOperatorType.EQUAL) {
+ this.currentRule.constraintOperator = ConstraintOperatorType.EQUAL;
+ }
+ this.operatorTypes = [this.setOperatorDropdownValue(ConstraintOperatorType.EQUAL)];
+ break;
+ }
}
- if (PROPERTY_DATA.SIMPLE_TYPES_COMPARABLE.indexOf(this.selectedProperty.type) === -1) {
- if (this.currentRule.constraintOperator !== ConstraintOperatorType.EQUAL) {
- this.currentRule.constraintOperator = ConstraintOperatorType.EQUAL;
- }
- this.operatorTypes = [new DropdownValue(ConstraintOperatorType.EQUAL, FilterConstraintHelper.convertToSymbol(ConstraintOperatorType.EQUAL))];
- } else {
- const operatorList: DropdownValue[] = [];
- this.allowedOperators.forEach(constraintOperatorType =>
- operatorList.push(new DropdownValue(constraintOperatorType, FilterConstraintHelper.convertToSymbol(constraintOperatorType)))
- );
- this.operatorTypes = operatorList;
+ private setOperatorDropdownValue(constraintOperatorType: ConstraintOperatorType) {
+ if (constraintOperatorType === undefined) {
+ return new DropdownValue(undefined, 'Select a Property');
+ }
+ return new DropdownValue(constraintOperatorType, FilterConstraintHelper.convertToSymbol(constraintOperatorType));
}
- }
- private initSelectedSourceType(): void {
+ private initSelectedSourceType(): void {
if (!this.currentRule.sourceType || this.currentRule.sourceType === SourceType.STATIC) {
this.selectedSourceType = SourceType.STATIC;
} else {
- this.selectedSourceType = SourceType.TOSCA_FUNCTION;
+ if (!this.isValidValuesOperator() && !this.isRangeType() && !this.isInRangeOperator()){
+ this.selectedSourceType = SourceType.TOSCA_FUNCTION;
+ }
+ else {
+ this.selectedSourceType = SourceType.TOSCA_FUNCTION_LIST;
+ }
}
}
private initCurrentRule(): void {
+ let propertyList: PropertyBEModel[] = [];
+ if (this.filterType == FilterType.CAPABILITY) {
+ if (this.currentRule.capabilityName) {
+ propertyList = this.capabilityNameAndPropertiesMap.get(this.currentRule.capabilityName);
+ }
+ } else {
+ propertyList = this.selectedInstanceProperties;
+ }
if (this.filterConstraint) {
+ this.filterConstraint.originalType = propertyList.find(prop=>prop.name==this.filterConstraint.servicePropertyName).type;
this.currentRule = new PropertyFilterConstraintUi(this.filterConstraint);
} else {
this.currentRule = new PropertyFilterConstraintUi({
sourceName: SourceType.STATIC,
sourceType: SourceType.STATIC,
constraintOperator: ConstraintOperatorType.EQUAL,
- value: undefined
+ value: undefined,
+ originalType: undefined
});
}
}
@@ -223,18 +297,26 @@ export class ServiceDependenciesEditorComponent implements OnInit {
}
newProperty.value = undefined;
newProperty.toscaFunction = undefined;
+
if (typeof this.currentRule.value === 'string') {
newProperty.value = this.currentRule.value;
this.propertiesUtils.initValueObjectRef(newProperty);
} else if (ToscaFunctionHelper.isValueToscaFunction(this.currentRule.value)) {
newProperty.toscaFunction = ToscaFunctionHelper.convertObjectToToscaFunction(this.currentRule.value);
newProperty.value = newProperty.toscaFunction.buildValueString();
+ } else if (Array.isArray(this.currentRule.value) &&
+ typeof this.currentRule.value[0] === "object" &&
+ this.currentRule.value[0]['propertySource'] != undefined) {
+ this.validValuesToscaFunctionList = this.currentRule.value;
+ this.rangeToscaFunctionList = this.currentRule.value;
+ newProperty.toscaFunction = this.currentRule.value;
} else {
newProperty.value = JSON.stringify(this.currentRule.value);
this.propertiesUtils.initValueObjectRef(newProperty);
}
this.selectedProperty = newProperty;
+ this.currentRule.originalType = this.selectedProperty.type;
}
updateSelectedProperty(): void {
@@ -256,6 +338,7 @@ export class ServiceDependenciesEditorComponent implements OnInit {
this.propertiesUtils.initValueObjectRef(newProperty);
this.selectedProperty = newProperty;
+ this.currentRule.originalType = this.selectedProperty.type;
}
isStaticSource(): boolean {
@@ -266,10 +349,30 @@ export class ServiceDependenciesEditorComponent implements OnInit {
return this.selectedSourceType === SourceType.TOSCA_FUNCTION
}
+ isToscaFunctionListSource(): boolean {
+ return this.selectedSourceType === SourceType.TOSCA_FUNCTION_LIST
+ }
+
isComplexListMapType(): boolean {
return this.selectedProperty && this.selectedProperty.derivedDataType > 0;
}
+ isRangeType(): boolean {
+ return this.selectedProperty && this.selectedProperty.derivedDataType == 4;
+ }
+
+ isLengthOperator(): boolean {
+ return this.lengthArray.indexOf(this.currentRule.constraintOperator) > -1;
+ }
+
+ isInRangeOperator(): boolean {
+ return this.currentRule.constraintOperator && this.currentRule.constraintOperator === ConstraintOperatorType.IN_RANGE;
+ }
+
+ isValidValuesOperator(): boolean {
+ return this.currentRule.constraintOperator && this.currentRule.constraintOperator === ConstraintOperatorType.VALID_VALUES;
+ }
+
updateComplexListMapTypeRuleValue(): void {
this.currentRule.value = PropertyFEModel.cleanValueObj(this.selectedProperty.valueObj);
this.onValueChange(this.selectedProperty.valueObjIsValid);
@@ -277,11 +380,23 @@ export class ServiceDependenciesEditorComponent implements OnInit {
onToscaFunctionValidityChange(validationEvent: ToscaFunctionValidationEvent): void {
if (validationEvent.isValid && validationEvent.toscaFunction) {
- this.currentRule.value = validationEvent.toscaFunction;
- this.currentRule.sourceType = validationEvent.toscaFunction.type
- if (validationEvent.toscaFunction instanceof ToscaGetFunction) {
- this.currentRule.sourceName = validationEvent.toscaFunction.sourceName;
- }
+ if (this.isValidValuesOperator()) {
+ this.currentRule.value = this.validValuesToscaFunctionList;
+ this.currentRule.sourceType = SourceType.TOSCA_FUNCTION_LIST;
+ if (validationEvent.toscaFunction instanceof ToscaGetFunction) {
+ this.currentRule.sourceName = SourceType.TOSCA_FUNCTION_LIST;
+ }
+ }
+ else {
+ if (this.isLengthOperator()) {
+ this.overridingType = PROPERTY_TYPES.INTEGER;
+ }
+ this.currentRule.value = validationEvent.toscaFunction;
+ this.currentRule.sourceType = validationEvent.toscaFunction.type
+ if (validationEvent.toscaFunction instanceof ToscaGetFunction) {
+ this.currentRule.sourceName = validationEvent.toscaFunction.sourceName;
+ }
+ }
} else {
this.currentRule.updateValidity(false);
this.currentRule.value = undefined;
@@ -290,12 +405,50 @@ export class ServiceDependenciesEditorComponent implements OnInit {
}
}
+ onToscaFunctionListValidityChange(validationEvent: ToscaFunctionValidationEvent, valueIndex: number): void {
+ if (validationEvent.isValid && validationEvent.toscaFunction) {
+ this.validValuesToscaFunctionList.splice(this.validValuesToscaFunctionList.length -1, 1, validationEvent.toscaFunction);
+ this.currentRule.value = this.validValuesToscaFunctionList;
+ this.currentRule.sourceType = 'SEVERAL';
+ if (validationEvent.toscaFunction instanceof ToscaGetFunction) {
+ this.currentRule.sourceName = validationEvent.toscaFunction.sourceName;
+ }
+ } else {
+ this.currentRule.updateValidity(false);
+ this.currentRule.value = undefined;
+ this.currentRule.sourceType = undefined;
+ this.currentRule.sourceName = undefined;
+ }
+ }
+
+ onToscaRangeFunctionListValidityChange(validationEvent: ToscaFunctionValidationEvent, valueIndex: number): void {
+ if (validationEvent.isValid && validationEvent.toscaFunction) {
+ this.rangeToscaFunctionList.splice(valueIndex, 1, validationEvent.toscaFunction);
+ this.currentRule.value = this.rangeToscaFunctionList;
+ this.currentRule.sourceType = 'SEVERAL';
+ if (validationEvent.toscaFunction instanceof ToscaGetFunction) {
+ this.currentRule.sourceName = validationEvent.toscaFunction.sourceName;
+ }
+ } else {
+ this.currentRule.updateValidity(false);
+ this.currentRule.value = undefined;
+ this.currentRule.sourceType = undefined;
+ this.currentRule.sourceName = undefined;
+ }
+ }
+
onSourceTypeChange(): void {
this.currentRule.value = undefined;
+ if (!this.isStaticSource() && (this.isValidValuesOperator() || this.isRangeType() || this.isInRangeOperator())) {
+ this.selectedSourceType = SourceType.TOSCA_FUNCTION_LIST;
+ }
this.currentRule.sourceType = this.selectedSourceType;
if (this.isStaticSource()) {
this.currentRule.sourceName = SourceType.STATIC;
}
+ if (this.isToscaFunctionListSource()) {
+ this.currentRule.sourceName = SourceType.TOSCA_FUNCTION_LIST;
+ }
this.updateSelectedProperty();
}
@@ -305,6 +458,41 @@ export class ServiceDependenciesEditorComponent implements OnInit {
this.onPropertyChange();
}
+ addToList(){
+ if (!this.validValuesToscaFunctionList) {
+ this.validValuesToscaFunctionList = new Array();
+ }
+ this.validValuesToscaFunctionList.push(ToscaFunctionHelper.convertObjectToToscaFunction(undefined));
+ }
+
+ generateRangeToscaFunctionList() {
+ if (!this.rangeToscaFunctionList) {
+ this.rangeToscaFunctionList = new Array();
+ this.rangeToscaFunctionList.push(ToscaFunctionHelper.convertObjectToToscaFunction(undefined));
+ this.rangeToscaFunctionList.push(ToscaFunctionHelper.convertObjectToToscaFunction(undefined));
+ }
+ }
+
+ trackByFn(index) {
+ return index;
+ }
+
+ removeFromList(valueIndex: number){
+ this.validValuesToscaFunctionList.splice(valueIndex, 1);
+ this.currentRule.updateValidity(!this.doesArrayContainsEmptyValues(this.validValuesToscaFunctionList) && !(this.validValuesToscaFunctionList.length === 0));
+ if (this.doesArrayContainsEmptyValues(this.validValuesToscaFunctionList) || (this.validValuesToscaFunctionList.length === 0)) {
+ this.currentRule.value = undefined;
+ this.currentRule.sourceType = undefined;
+ this.currentRule.sourceName = undefined;
+ }
+ }
+
+ private doesArrayContainsEmptyValues(arr) {
+ for(const element of arr) {
+ if(element === undefined) return true;
+ }
+ return false;
+ }
}
export enum FilterType {
diff --git a/catalog-ui/src/app/utils/constants.ts b/catalog-ui/src/app/utils/constants.ts
index 927c778df6..8c62cec739 100644
--- a/catalog-ui/src/app/utils/constants.ts
+++ b/catalog-ui/src/app/utils/constants.ts
@@ -164,6 +164,7 @@ export class PROPERTY_TYPES {
public static SCALAR_FREQUENCY = 'scalar-unit.frequency';
public static SCALAR_SIZE = 'scalar-unit.size';
public static SCALAR_TIME = 'scalar-unit.time';
+ public static SCALAR_UNIT = 'scalar-unit';
}
export class SOURCES {
@@ -177,12 +178,12 @@ export class PROPERTY_DATA {
public static SIMPLE_TYPES = [PROPERTY_TYPES.STRING, PROPERTY_TYPES.INTEGER, PROPERTY_TYPES.TIMESTAMP, PROPERTY_TYPES.FLOAT, PROPERTY_TYPES.BOOLEAN, PROPERTY_TYPES.JSON, PROPERTY_TYPES.SCALAR_BITRATE, PROPERTY_TYPES.SCALAR_FREQUENCY, PROPERTY_TYPES.SCALAR_SIZE, PROPERTY_TYPES.SCALAR_TIME];
public static SIMPLE_TYPES_COMPARABLE = [PROPERTY_TYPES.STRING, PROPERTY_TYPES.INTEGER, PROPERTY_TYPES.FLOAT];
public static SCHEMA_TYPES = [PROPERTY_TYPES.LIST, PROPERTY_TYPES.MAP];
- public static SCALAR_TYPES = [PROPERTY_TYPES.SCALAR_BITRATE, PROPERTY_TYPES.SCALAR_FREQUENCY, PROPERTY_TYPES.SCALAR_SIZE, PROPERTY_TYPES.SCALAR_TIME];
+ public static SCALAR_TYPES = [PROPERTY_TYPES.SCALAR_BITRATE, PROPERTY_TYPES.SCALAR_FREQUENCY, PROPERTY_TYPES.SCALAR_SIZE, PROPERTY_TYPES.SCALAR_TIME, PROPERTY_TYPES.SCALAR_UNIT];
public static ROOT_DATA_TYPE = "tosca.datatypes.Root";
public static OPENECOMP_ROOT = "org.openecomp.datatypes.Root";
public static SUPPLEMENTAL_DATA = "supplemental_data";
public static SOURCES = [SOURCES.A_AND_AI, SOURCES.ORDER, SOURCES.RUNTIME];
- public static COMPARABLE_TYPES = [PROPERTY_TYPES.STRING, PROPERTY_TYPES.INTEGER, PROPERTY_TYPES.FLOAT, PROPERTY_TYPES.TIMESTAMP, PROPERTY_TYPES.SCALAR_BITRATE, PROPERTY_TYPES.SCALAR_FREQUENCY, PROPERTY_TYPES.SCALAR_SIZE, PROPERTY_TYPES.SCALAR_TIME];
+ public static COMPARABLE_TYPES = [PROPERTY_TYPES.STRING, PROPERTY_TYPES.INTEGER, PROPERTY_TYPES.FLOAT, PROPERTY_TYPES.TIMESTAMP, PROPERTY_TYPES.SCALAR_BITRATE, PROPERTY_TYPES.SCALAR_FREQUENCY, PROPERTY_TYPES.SCALAR_SIZE, PROPERTY_TYPES.SCALAR_TIME, PROPERTY_TYPES.SCALAR_UNIT];
}
export class PROPERTY_VALUE_CONSTRAINTS {
diff --git a/catalog-ui/src/app/utils/filter-constraint-helper.ts b/catalog-ui/src/app/utils/filter-constraint-helper.ts
index f1207084a7..7ee9d27efe 100644
--- a/catalog-ui/src/app/utils/filter-constraint-helper.ts
+++ b/catalog-ui/src/app/utils/filter-constraint-helper.ts
@@ -50,9 +50,14 @@ export class FilterConstraintHelper {
case ConstraintOperatorType.GREATER_THAN: return '>';
case ConstraintOperatorType.GREATER_OR_EQUAL: return '>=';
case ConstraintOperatorType.LESS_OR_EQUAL: return '<=';
+ case ConstraintOperatorType.IN_RANGE: return 'in range';
+ case ConstraintOperatorType.VALID_VALUES: return 'valid values';
+ case ConstraintOperatorType.LENGTH: return 'length';
+ case ConstraintOperatorType.MIN_LENGTH: return 'minimum length';
+ case ConstraintOperatorType.MAX_LENGTH: return 'maximum length';
+ case ConstraintOperatorType.PATTERN: return 'pattern';
}
}
-
}
export enum ConstraintOperatorType {
@@ -60,6 +65,12 @@ export enum ConstraintOperatorType {
GREATER_THAN = 'greater_than',
LESS_THAN = 'less_than',
GREATER_OR_EQUAL = 'greater_or_equal',
- LESS_OR_EQUAL = 'less_or_equal'
+ LESS_OR_EQUAL = 'less_or_equal',
+ IN_RANGE = 'in_range',
+ VALID_VALUES = 'valid_values',
+ LENGTH = 'length',
+ MIN_LENGTH = 'min_length',
+ MAX_LENGTH = 'max_length',
+ PATTERN = 'pattern'
}
diff --git a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/PropertyFilterConstraintDataDefinition.java b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/PropertyFilterConstraintDataDefinition.java
index 9284b530eb..3dc11248f2 100644
--- a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/PropertyFilterConstraintDataDefinition.java
+++ b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/PropertyFilterConstraintDataDefinition.java
@@ -38,4 +38,5 @@ public class PropertyFilterConstraintDataDefinition {
private ConstraintType operator;
private FilterValueType valueType;
private Object value;
+ private String originalType;
}
diff --git a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/PropertyFilterConstraintDataDefinitionJsonDeserializer.java b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/PropertyFilterConstraintDataDefinitionJsonDeserializer.java
index a767133a4c..894b54b291 100644
--- a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/PropertyFilterConstraintDataDefinitionJsonDeserializer.java
+++ b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/PropertyFilterConstraintDataDefinitionJsonDeserializer.java
@@ -22,11 +22,13 @@
package org.openecomp.sdc.be.datatypes.elements;
import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.openecomp.sdc.be.datatypes.enums.ConstraintType;
@@ -73,6 +75,9 @@ public class PropertyFilterConstraintDataDefinitionJsonDeserializer extends StdD
if (node.get("valueType") != null) {
propertyFilterConstraint.setValueType(FilterValueType.valueOf(node.get("valueType").asText()));
}
+ if (node.get("originalType") != null) {
+ propertyFilterConstraint.setOriginalType(node.get("originalType").asText());
+ }
propertyFilterConstraint.setValue(deserializeValue(node.get("value")));
return propertyFilterConstraint;
@@ -91,7 +96,25 @@ public class PropertyFilterConstraintDataDefinitionJsonDeserializer extends StdD
LOGGER.debug(COULD_NOT_PARSE_CLASS, PropertyFilterConstraintDataDefinition.class.getName(), Map.class.getName(), e);
}
try {
- return objectMapper.treeToValue(value, List.class);
+ if (value.isArray()) {
+ try {
+ objectMapper.treeToValue(value.get(0), ToscaFunction.class);
+ } catch (JsonProcessingException e) {
+ return objectMapper.treeToValue(value, List.class);
+ }
+ List<ToscaFunction> listToscaFunction = new ArrayList<>();
+ value.forEach(nodeListValue -> {
+ try {
+ listToscaFunction.add(objectMapper.treeToValue(nodeListValue, ToscaFunction.class));
+ } catch (JsonProcessingException e) {
+ LOGGER.debug(COULD_NOT_PARSE_CLASS, PropertyFilterConstraintDataDefinition.class.getName(), List.class.getName(), e);
+ }
+ });
+ return listToscaFunction;
+ }
+ else {
+ return objectMapper.treeToValue(value, List.class);
+ }
} catch (final Exception e) {
LOGGER.debug(COULD_NOT_PARSE_CLASS, PropertyFilterConstraintDataDefinition.class.getName(), List.class.getName(), e);
}
diff --git a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/ConstraintType.java b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/ConstraintType.java
index 2963b6bcd1..263bd70ab7 100644
--- a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/ConstraintType.java
+++ b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/ConstraintType.java
@@ -48,6 +48,10 @@ public enum ConstraintType {
ConstraintType.GREATER_OR_EQUAL,
ConstraintType.LESS_OR_EQUAL,
ConstraintType.LESS_THAN);
+ private static final Set<ConstraintType> lengthConstraints = Set.of(
+ ConstraintType.LENGTH,
+ ConstraintType.MIN_LENGTH,
+ ConstraintType.MAX_LENGTH);
private final String type;
private final List<String> typeAlias;
@@ -74,4 +78,8 @@ public enum ConstraintType {
return comparableConstraints.contains(this);
}
+ public boolean isLengthConstraint() {
+ return lengthConstraints.contains(this);
+ }
+
}
diff --git a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/FilterValueType.java b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/FilterValueType.java
index cacc4b1bac..62a19b8041 100644
--- a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/FilterValueType.java
+++ b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/FilterValueType.java
@@ -35,7 +35,8 @@ public enum FilterValueType {
GET_INPUT("get_input", "service_input"),
GET_ATTRIBUTE("get_attribute", null),
YAML("yaml", null),
- CONCAT("concat", null);
+ CONCAT("concat", null),
+ SEVERAL("several", null);
private final String name;
private final String legacyName;